2 * Copyright (C) 2004-2013 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.
27 #include <isc/mutex.h>
29 #include <isc/print.h>
30 #include <isc/random.h>
31 #include <isc/ratelimiter.h>
32 #include <isc/refcount.h>
33 #include <isc/rwlock.h>
34 #include <isc/serial.h>
35 #include <isc/stats.h>
36 #include <isc/stdtime.h>
37 #include <isc/strerror.h>
38 #include <isc/string.h>
39 #include <isc/taskpool.h>
40 #include <isc/timer.h>
43 #include <dns/acache.h>
46 #include <dns/callbacks.h>
48 #include <dns/dbiterator.h>
49 #include <dns/dnssec.h>
50 #include <dns/events.h>
51 #include <dns/journal.h>
52 #include <dns/keydata.h>
53 #include <dns/keytable.h>
54 #include <dns/keyvalues.h>
56 #include <dns/master.h>
57 #include <dns/masterdump.h>
58 #include <dns/message.h>
61 #include <dns/nsec3.h>
63 #include <dns/private.h>
65 #include <dns/rcode.h>
66 #include <dns/rdata.h>
67 #include <dns/rdataclass.h>
68 #include <dns/rdatalist.h>
69 #include <dns/rdataset.h>
70 #include <dns/rdatasetiter.h>
71 #include <dns/rdatastruct.h>
72 #include <dns/rdatatype.h>
73 #include <dns/request.h>
74 #include <dns/resolver.h>
75 #include <dns/result.h>
76 #include <dns/rriterator.h>
79 #include <dns/stats.h>
82 #include <dns/update.h>
83 #include <dns/xfrin.h>
89 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
90 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
92 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
93 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
95 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
96 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
98 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
99 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
101 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
102 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
104 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
105 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
107 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
108 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
111 * Ensure 'a' is at least 'min' but not more than 'max'.
113 #define RANGE(a, min, max) \
114 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
116 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
121 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
122 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
123 #define ALG(x) dst_key_alg(x)
128 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
129 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
130 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
131 #define RESIGN_DELAY 3600 /*%< 1 hour */
133 #ifndef DNS_MAX_EXPIRE
134 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
137 #ifndef DNS_DUMP_DELAY
138 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
141 typedef struct dns_notify dns_notify_t;
142 typedef struct dns_stub dns_stub_t;
143 typedef struct dns_load dns_load_t;
144 typedef struct dns_forward dns_forward_t;
145 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
146 typedef struct dns_io dns_io_t;
147 typedef ISC_LIST(dns_io_t) dns_iolist_t;
148 typedef struct dns_signing dns_signing_t;
149 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
150 typedef struct dns_nsec3chain dns_nsec3chain_t;
151 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
152 typedef struct dns_keyfetch dns_keyfetch_t;
153 typedef struct dns_asyncload dns_asyncload_t;
155 #define DNS_ZONE_CHECKLOCK
156 #ifdef DNS_ZONE_CHECKLOCK
157 #define LOCK_ZONE(z) \
158 do { LOCK(&(z)->lock); \
159 INSIST((z)->locked == ISC_FALSE); \
160 (z)->locked = ISC_TRUE; \
162 #define UNLOCK_ZONE(z) \
163 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
164 #define LOCKED_ZONE(z) ((z)->locked)
166 #define LOCK_ZONE(z) LOCK(&(z)->lock)
167 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
168 #define LOCKED_ZONE(z) ISC_TRUE
171 #ifdef ISC_RWLOCK_USEATOMIC
172 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
173 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
174 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
175 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
177 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
178 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
179 #define ZONEDB_LOCK(l, t) LOCK(l)
180 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
187 #ifdef DNS_ZONE_CHECKLOCK
188 isc_boolean_t locked;
191 isc_refcount_t erefs;
193 #ifdef ISC_RWLOCK_USEATOMIC
198 dns_db_t *db; /* Locked by dblock */
202 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
207 dns_masterformat_t masterformat;
209 isc_int32_t journalsize;
210 dns_rdataclass_t rdclass;
213 unsigned int options;
214 unsigned int db_argc;
216 isc_time_t expiretime;
217 isc_time_t refreshtime;
220 isc_time_t notifytime;
221 isc_time_t resigntime;
222 isc_time_t keywarntime;
223 isc_time_t signingtime;
224 isc_time_t nsec3chaintime;
225 isc_time_t refreshkeytime;
226 isc_uint32_t refreshkeyinterval;
227 isc_uint32_t refreshkeycount;
228 isc_uint32_t refresh;
231 isc_uint32_t minimum;
232 isc_stdtime_t key_expiry;
233 isc_stdtime_t log_key_expired_timer;
236 isc_uint32_t maxrefresh;
237 isc_uint32_t minrefresh;
238 isc_uint32_t maxretry;
239 isc_uint32_t minretry;
241 isc_sockaddr_t *masters;
242 dns_name_t **masterkeynames;
243 isc_boolean_t *mastersok;
244 unsigned int masterscnt;
245 unsigned int curmaster;
246 isc_sockaddr_t masteraddr;
247 dns_notifytype_t notifytype;
248 isc_sockaddr_t *notify;
249 dns_name_t **notifykeynames;
250 unsigned int notifycnt;
251 isc_sockaddr_t notifyfrom;
253 isc_task_t *loadtask;
254 isc_sockaddr_t notifysrc4;
255 isc_sockaddr_t notifysrc6;
256 isc_sockaddr_t xfrsource4;
257 isc_sockaddr_t xfrsource6;
258 isc_sockaddr_t altxfrsource4;
259 isc_sockaddr_t altxfrsource6;
260 isc_sockaddr_t sourceaddr;
261 dns_xfrin_ctx_t *xfr; /* task locked */
262 dns_tsigkey_t *tsigkey; /* key used for xfr */
263 /* Access Control Lists */
264 dns_acl_t *update_acl;
265 dns_acl_t *forward_acl;
266 dns_acl_t *notify_acl;
267 dns_acl_t *query_acl;
268 dns_acl_t *queryon_acl;
270 isc_boolean_t update_disabled;
271 isc_boolean_t zero_no_soa_ttl;
272 dns_severity_t check_names;
273 ISC_LIST(dns_notify_t) notifies;
274 dns_request_t *request;
279 isc_uint32_t maxxfrin;
280 isc_uint32_t maxxfrout;
282 isc_uint32_t idleout;
283 isc_event_t ctlevent;
284 dns_ssutable_t *ssutable;
285 isc_uint32_t sigvalidityinterval;
286 isc_uint32_t sigresigninginterval;
288 dns_acache_t *acache;
289 dns_checkmxfunc_t checkmx;
290 dns_checksrvfunc_t checksrv;
291 dns_checknsfunc_t checkns;
293 * Zones in certain states such as "waiting for zone transfer"
294 * or "zone transfer in progress" are kept on per-state linked lists
295 * in the zone manager using the 'statelink' field. The 'statelist'
296 * field points at the list the zone is currently on. It the zone
297 * is not on any such list, statelist is NULL.
299 ISC_LINK(dns_zone_t) statelink;
300 dns_zonelist_t *statelist;
302 * Statistics counters about zone management.
306 * Optional per-zone statistics counters. Counted outside of this
309 dns_zonestat_level_t statlevel;
310 isc_boolean_t requeststats_on;
311 isc_stats_t *requeststats;
312 dns_stats_t *rcvquerystats;
313 isc_uint32_t notifydelay;
314 dns_isselffunc_t isself;
323 * Serial number for deferred journal compaction.
325 isc_uint32_t compact_serial;
327 * Keys that are signing the zone for the first time.
329 dns_signinglist_t signing;
330 dns_nsec3chainlist_t nsec3chain;
332 * Signing / re-signing quantum stopping parameters.
334 isc_uint32_t signatures;
336 dns_rdatatype_t privatetype;
339 * Autosigning/key-maintenance options
341 isc_uint32_t keyopts;
344 * True if added by "rndc addzone"
349 * whether this is a response policy zone
351 isc_boolean_t is_rpz;
354 * Serial number update method.
356 dns_updatemethod_t updatemethod;
359 * whether ixfr is requested
361 isc_boolean_t requestixfr;
364 * Outstanding forwarded UPDATE requests.
366 dns_forwardlist_t forwards;
371 isc_boolean_t sourceserialset;
372 isc_uint32_t sourceserial;
377 isc_boolean_t offline;
380 #define zonediff_init(z, d) \
382 zonediff_t *_z = (z); \
384 (_z)->offline = ISC_FALSE; \
387 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
388 #define DNS_ZONE_SETFLAG(z,f) do { \
389 INSIST(LOCKED_ZONE(z)); \
392 #define DNS_ZONE_CLRFLAG(z,f) do { \
393 INSIST(LOCKED_ZONE(z)); \
394 (z)->flags &= ~(f); \
396 /* XXX MPA these may need to go back into zone.h */
397 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
398 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
399 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
400 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
401 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
402 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
403 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
404 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
405 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
406 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
408 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
410 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
412 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
413 * zone with no masters
415 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
416 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
417 * from SOA (if not set, we
419 * default timer values) */
420 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
421 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
422 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
423 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
424 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
425 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
426 #define DNS_ZONEFLG_FLUSH 0x00200000U
427 #define DNS_ZONEFLG_NOEDNS 0x00400000U
428 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
429 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
430 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
431 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
432 #define DNS_ZONEFLG_THAW 0x08000000U
433 #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
434 #define DNS_ZONEFLG_NODELAY 0x20000000U
435 #define DNS_ZONEFLG_SENDSECURE 0x40000000U
437 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
438 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
440 /* Flags for zone_load() */
441 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
442 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
445 #define UNREACH_CHACHE_SIZE 10U
446 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
449 do { result = (op); \
450 if (result != ISC_R_SUCCESS) goto failure; \
453 struct dns_unreachable {
454 isc_sockaddr_t remote;
455 isc_sockaddr_t local;
463 int refs; /* Locked by rwlock */
464 isc_taskmgr_t * taskmgr;
465 isc_timermgr_t * timermgr;
466 isc_socketmgr_t * socketmgr;
467 isc_taskpool_t * zonetasks;
468 isc_taskpool_t * loadtasks;
470 isc_pool_t * mctxpool;
471 isc_ratelimiter_t * rl;
476 /* Locked by rwlock. */
477 dns_zonelist_t zones;
478 dns_zonelist_t waiting_for_xfrin;
479 dns_zonelist_t xfrin_in_progress;
481 /* Configuration data. */
482 isc_uint32_t transfersin;
483 isc_uint32_t transfersperns;
484 unsigned int serialqueryrate;
486 /* Locked by iolock */
487 isc_uint32_t iolimit;
488 isc_uint32_t ioactive;
492 /* Locked by urlock. */
494 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
506 dns_request_t *request;
510 ISC_LINK(dns_notify_t) link;
513 #define DNS_NOTIFY_NOSOA 0x0001U
516 * dns_stub holds state while performing a 'stub' transfer.
517 * 'db' is the zone's 'db' or a new one if this is the initial
526 dns_dbversion_t *version;
538 dns_rdatacallbacks_t callbacks;
542 * Hold forward state.
548 isc_buffer_t *msgbuf;
549 dns_request_t *request;
552 dns_updatecallback_t callback;
554 ISC_LINK(dns_forward_t) link;
558 * Hold IO request state.
565 ISC_LINK(dns_io_t) link;
570 * Hold state for when we are signing a zone with a new
571 * DNSKEY as result of an update.
576 dns_dbiterator_t *dbiterator;
577 dns_secalg_t algorithm;
579 isc_boolean_t delete;
581 ISC_LINK(dns_signing_t) link;
584 struct dns_nsec3chain {
587 dns_dbiterator_t *dbiterator;
588 dns_rdata_nsec3param_t nsec3param;
589 unsigned char salt[255];
591 isc_boolean_t seen_nsec;
592 isc_boolean_t delete_nsec;
593 isc_boolean_t save_delete_nsec;
594 ISC_LINK(dns_nsec3chain_t) link;
597 * 'dbiterator' contains a iterator for the database. If we are creating
598 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
599 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
602 * 'nsec3param' contains the parameters of the NSEC3 chain being created
605 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
607 * 'seen_nsec' will be set to true if, while iterating the zone to create a
608 * NSEC3 chain, a NSEC record is seen.
610 * 'delete_nsec' will be set to true if, at the completion of the creation
611 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
612 * are in the process of deleting the NSEC chain.
614 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
615 * so it can be recovered in the event of a error.
618 struct dns_keyfetch {
619 dns_fixedname_t name;
620 dns_rdataset_t keydataset;
621 dns_rdataset_t dnskeyset;
622 dns_rdataset_t dnskeysigset;
629 * Hold state for an asynchronous load
631 struct dns_asyncload {
633 dns_zt_zoneloaded_t loaded;
638 #define DAY (24*HOUR)
639 #define MONTH (30*DAY)
641 #define SEND_BUFFER_SIZE 2048
643 static void zone_settimer(dns_zone_t *, isc_time_t *);
644 static void cancel_refresh(dns_zone_t *);
645 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
646 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
647 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
648 ISC_FORMAT_PRINTF(3, 4);
649 static void queue_xfrin(dns_zone_t *zone);
650 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
651 dns_diff_t *diff, dns_diffop_t op,
652 dns_name_t *name, dns_ttl_t ttl,
654 static void zone_unload(dns_zone_t *zone);
655 static void zone_expire(dns_zone_t *zone);
656 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
657 static void zone_idetach(dns_zone_t **zonep);
658 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
660 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
661 static inline void zone_detachdb(dns_zone_t *zone);
662 static isc_result_t default_journal(dns_zone_t *zone);
663 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
664 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
665 isc_time_t loadtime, isc_result_t result);
666 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
667 static void zone_shutdown(isc_task_t *, isc_event_t *);
668 static void zone_loaddone(void *arg, isc_result_t result);
669 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
670 isc_time_t loadtime);
671 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
672 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
673 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
674 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
675 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
676 isc_boolean_t secure_locked,
677 isc_uint32_t serial);
680 /* ondestroy example */
681 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
684 static void refresh_callback(isc_task_t *, isc_event_t *);
685 static void stub_callback(isc_task_t *, isc_event_t *);
686 static void queue_soa_query(dns_zone_t *zone);
687 static void soa_query(isc_task_t *, isc_event_t *);
688 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
690 static int message_count(dns_message_t *msg, dns_section_t section,
691 dns_rdatatype_t type);
692 static void notify_cancel(dns_zone_t *zone);
693 static void notify_find_address(dns_notify_t *notify);
694 static void notify_send(dns_notify_t *notify);
695 static isc_result_t notify_createmessage(dns_zone_t *zone,
697 dns_message_t **messagep);
698 static void notify_done(isc_task_t *task, isc_event_t *event);
699 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
700 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
701 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
702 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
704 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
705 static void zonemgr_free(dns_zonemgr_t *zmgr);
706 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
707 isc_task_t *task, isc_taskaction_t action,
708 void *arg, dns_io_t **iop);
709 static void zonemgr_putio(dns_io_t **iop);
710 static void zonemgr_cancelio(dns_io_t *io);
713 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
714 unsigned int *soacount, isc_uint32_t *serial,
715 isc_uint32_t *refresh, isc_uint32_t *retry,
716 isc_uint32_t *expire, isc_uint32_t *minimum,
717 unsigned int *errors);
719 static void zone_freedbargs(dns_zone_t *zone);
720 static void forward_callback(isc_task_t *task, isc_event_t *event);
721 static void zone_saveunique(dns_zone_t *zone, const char *path,
722 const char *templat);
723 static void zone_maintenance(dns_zone_t *zone);
724 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
725 static void dump_done(void *arg, isc_result_t result);
726 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
727 isc_uint16_t keyid, isc_boolean_t delete);
728 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
729 dns_dbnode_t *node, dns_name_t *name,
731 static void zone_rekey(dns_zone_t *zone);
732 static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr,
733 dst_key_t **keys, unsigned int nkeys);
734 static isc_result_t zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked,
737 #define ENTER zone_debuglog(zone, me, 1, "enter")
739 static const unsigned int dbargc_default = 1;
740 static const char *dbargv_default[] = { "rbt" };
742 #define DNS_ZONE_JITTER_ADD(a, b, c) \
746 _j = isc_random_jitter((b), (b)/4); \
747 isc_interval_set(&_i, _j, 0); \
748 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
749 dns_zone_log(zone, ISC_LOG_WARNING, \
750 "epoch approaching: upgrade required: " \
751 "now + %s failed", #b); \
752 isc_interval_set(&_i, _j/2, 0); \
753 (void)isc_time_add((a), &_i, (c)); \
757 #define DNS_ZONE_TIME_ADD(a, b, c) \
760 isc_interval_set(&_i, (b), 0); \
761 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
762 dns_zone_log(zone, ISC_LOG_WARNING, \
763 "epoch approaching: upgrade required: " \
764 "now + %s failed", #b); \
765 isc_interval_set(&_i, (b)/2, 0); \
766 (void)isc_time_add((a), &_i, (c)); \
771 * Increment resolver-related statistics counters. Zone must be locked.
774 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
775 if (zone->stats != NULL)
776 isc_stats_increment(zone->stats, counter);
780 *** Public functions.
784 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
789 REQUIRE(zonep != NULL && *zonep == NULL);
790 REQUIRE(mctx != NULL);
793 zone = isc_mem_get(mctx, sizeof(*zone));
795 return (ISC_R_NOMEMORY);
798 isc_mem_attach(mctx, &zone->mctx);
800 result = isc_mutex_init(&zone->lock);
801 if (result != ISC_R_SUCCESS)
804 result = ZONEDB_INITLOCK(&zone->dblock);
805 if (result != ISC_R_SUCCESS)
808 /* XXX MPA check that all elements are initialised */
809 #ifdef DNS_ZONE_CHECKLOCK
810 zone->locked = ISC_FALSE;
814 ISC_LINK_INIT(zone, link);
815 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
816 if (result != ISC_R_SUCCESS)
819 dns_name_init(&zone->origin, NULL);
820 zone->strnamerd = NULL;
821 zone->strname = NULL;
822 zone->strrdclass = NULL;
823 zone->strviewname = NULL;
824 zone->masterfile = NULL;
825 zone->masterformat = dns_masterformat_none;
826 zone->keydirectory = NULL;
827 zone->journalsize = -1;
828 zone->journal = NULL;
829 zone->rdclass = dns_rdataclass_none;
830 zone->type = dns_zone_none;
835 zone->db_argv = NULL;
836 isc_time_settoepoch(&zone->expiretime);
837 isc_time_settoepoch(&zone->refreshtime);
838 isc_time_settoepoch(&zone->dumptime);
839 isc_time_settoepoch(&zone->loadtime);
840 zone->notifytime = now;
841 isc_time_settoepoch(&zone->resigntime);
842 isc_time_settoepoch(&zone->keywarntime);
843 isc_time_settoepoch(&zone->signingtime);
844 isc_time_settoepoch(&zone->nsec3chaintime);
845 isc_time_settoepoch(&zone->refreshkeytime);
846 zone->refreshkeyinterval = 0;
847 zone->refreshkeycount = 0;
848 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
849 zone->retry = DNS_ZONE_DEFAULTRETRY;
852 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
853 zone->minrefresh = DNS_ZONE_MINREFRESH;
854 zone->maxretry = DNS_ZONE_MAXRETRY;
855 zone->minretry = DNS_ZONE_MINRETRY;
856 zone->masters = NULL;
857 zone->masterkeynames = NULL;
858 zone->mastersok = NULL;
859 zone->masterscnt = 0;
862 zone->notifykeynames = NULL;
863 zone->notifytype = dns_notifytype_yes;
866 zone->loadtask = NULL;
867 zone->update_acl = NULL;
868 zone->forward_acl = NULL;
869 zone->notify_acl = NULL;
870 zone->query_acl = NULL;
871 zone->queryon_acl = NULL;
872 zone->xfr_acl = NULL;
873 zone->update_disabled = ISC_FALSE;
874 zone->zero_no_soa_ttl = ISC_TRUE;
875 zone->check_names = dns_severity_ignore;
876 zone->request = NULL;
880 zone->writeio = NULL;
882 zone->idlein = DNS_DEFAULT_IDLEIN;
883 zone->idleout = DNS_DEFAULT_IDLEOUT;
884 zone->log_key_expired_timer = 0;
885 ISC_LIST_INIT(zone->notifies);
886 isc_sockaddr_any(&zone->notifysrc4);
887 isc_sockaddr_any6(&zone->notifysrc6);
888 isc_sockaddr_any(&zone->xfrsource4);
889 isc_sockaddr_any6(&zone->xfrsource6);
890 isc_sockaddr_any(&zone->altxfrsource4);
891 isc_sockaddr_any6(&zone->altxfrsource6);
893 zone->tsigkey = NULL;
894 zone->maxxfrin = MAX_XFER_TIME;
895 zone->maxxfrout = MAX_XFER_TIME;
896 zone->ssutable = NULL;
897 zone->sigvalidityinterval = 30 * 24 * 3600;
898 zone->sigresigninginterval = 7 * 24 * 3600;
901 zone->checkmx = NULL;
902 zone->checksrv = NULL;
903 zone->checkns = NULL;
904 ISC_LINK_INIT(zone, statelink);
905 zone->statelist = NULL;
907 zone->requeststats_on = ISC_FALSE;
908 zone->statlevel = dns_zonestat_none;
909 zone->requeststats = NULL;
910 zone->rcvquerystats = NULL;
911 zone->notifydelay = 5;
913 zone->isselfarg = NULL;
914 ISC_LIST_INIT(zone->signing);
915 ISC_LIST_INIT(zone->nsec3chain);
916 zone->signatures = 10;
918 zone->privatetype = (dns_rdatatype_t)0xffffU;
919 zone->added = ISC_FALSE;
920 zone->is_rpz = ISC_FALSE;
921 ISC_LIST_INIT(zone->forwards);
924 zone->sourceserial = 0;
925 zone->sourceserialset = ISC_FALSE;
927 zone->magic = ZONE_MAGIC;
929 /* Must be after magic is set. */
930 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
931 if (result != ISC_R_SUCCESS)
934 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
935 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
938 return (ISC_R_SUCCESS);
941 isc_refcount_decrement(&zone->erefs, NULL);
942 isc_refcount_destroy(&zone->erefs);
945 ZONEDB_DESTROYLOCK(&zone->dblock);
948 DESTROYLOCK(&zone->lock);
951 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
956 * Free a zone. Because we require that there be no more
957 * outstanding events or references, no locking is necessary.
960 zone_free(dns_zone_t *zone) {
961 isc_mem_t *mctx = NULL;
962 dns_signing_t *signing;
963 dns_nsec3chain_t *nsec3chain;
965 REQUIRE(DNS_ZONE_VALID(zone));
966 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
967 REQUIRE(zone->irefs == 0);
968 REQUIRE(!LOCKED_ZONE(zone));
969 REQUIRE(zone->timer == NULL);
972 * Managed objects. Order is important.
974 if (zone->request != NULL)
975 dns_request_destroy(&zone->request); /* XXXMPA */
976 INSIST(zone->readio == NULL);
977 INSIST(zone->statelist == NULL);
978 INSIST(zone->writeio == NULL);
980 if (zone->task != NULL)
981 isc_task_detach(&zone->task);
982 if (zone->loadtask != NULL)
983 isc_task_detach(&zone->loadtask);
984 if (zone->zmgr != NULL)
985 dns_zonemgr_releasezone(zone->zmgr, zone);
987 /* Unmanaged objects */
988 for (signing = ISC_LIST_HEAD(zone->signing);
990 signing = ISC_LIST_HEAD(zone->signing)) {
991 ISC_LIST_UNLINK(zone->signing, signing, link);
992 dns_db_detach(&signing->db);
993 dns_dbiterator_destroy(&signing->dbiterator);
994 isc_mem_put(zone->mctx, signing, sizeof *signing);
996 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
998 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
999 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
1000 dns_db_detach(&nsec3chain->db);
1001 dns_dbiterator_destroy(&nsec3chain->dbiterator);
1002 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
1004 if (zone->masterfile != NULL)
1005 isc_mem_free(zone->mctx, zone->masterfile);
1006 zone->masterfile = NULL;
1007 if (zone->keydirectory != NULL)
1008 isc_mem_free(zone->mctx, zone->keydirectory);
1009 zone->keydirectory = NULL;
1010 zone->journalsize = -1;
1011 if (zone->journal != NULL)
1012 isc_mem_free(zone->mctx, zone->journal);
1013 zone->journal = NULL;
1014 if (zone->stats != NULL)
1015 isc_stats_detach(&zone->stats);
1016 if (zone->requeststats != NULL)
1017 isc_stats_detach(&zone->requeststats);
1018 if(zone->rcvquerystats != NULL )
1019 dns_stats_detach(&zone->rcvquerystats);
1020 if (zone->db != NULL)
1021 zone_detachdb(zone);
1022 if (zone->acache != NULL)
1023 dns_acache_detach(&zone->acache);
1024 zone_freedbargs(zone);
1025 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
1027 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
1029 zone->check_names = dns_severity_ignore;
1030 if (zone->update_acl != NULL)
1031 dns_acl_detach(&zone->update_acl);
1032 if (zone->forward_acl != NULL)
1033 dns_acl_detach(&zone->forward_acl);
1034 if (zone->notify_acl != NULL)
1035 dns_acl_detach(&zone->notify_acl);
1036 if (zone->query_acl != NULL)
1037 dns_acl_detach(&zone->query_acl);
1038 if (zone->queryon_acl != NULL)
1039 dns_acl_detach(&zone->queryon_acl);
1040 if (zone->xfr_acl != NULL)
1041 dns_acl_detach(&zone->xfr_acl);
1042 if (dns_name_dynamic(&zone->origin))
1043 dns_name_free(&zone->origin, zone->mctx);
1044 if (zone->strnamerd != NULL)
1045 isc_mem_free(zone->mctx, zone->strnamerd);
1046 if (zone->strname != NULL)
1047 isc_mem_free(zone->mctx, zone->strname);
1048 if (zone->strrdclass != NULL)
1049 isc_mem_free(zone->mctx, zone->strrdclass);
1050 if (zone->strviewname != NULL)
1051 isc_mem_free(zone->mctx, zone->strviewname);
1052 if (zone->ssutable != NULL)
1053 dns_ssutable_detach(&zone->ssutable);
1056 ZONEDB_DESTROYLOCK(&zone->dblock);
1057 DESTROYLOCK(&zone->lock);
1058 isc_refcount_destroy(&zone->erefs);
1061 isc_mem_put(mctx, zone, sizeof(*zone));
1062 isc_mem_detach(&mctx);
1066 * Returns ISC_TRUE iff this the signed side of an inline-signing zone.
1067 * Caller should hold zone lock.
1069 static inline isc_boolean_t
1070 inline_secure(dns_zone_t *zone) {
1071 REQUIRE(DNS_ZONE_VALID(zone));
1072 if (zone->raw != NULL)
1078 * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone
1079 * Caller should hold zone lock.
1081 static inline isc_boolean_t
1082 inline_raw(dns_zone_t *zone) {
1083 REQUIRE(DNS_ZONE_VALID(zone));
1084 if (zone->secure != NULL)
1093 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1096 REQUIRE(DNS_ZONE_VALID(zone));
1097 REQUIRE(rdclass != dns_rdataclass_none);
1103 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1104 zone->rdclass == rdclass);
1105 zone->rdclass = rdclass;
1107 if (zone->strnamerd != NULL)
1108 isc_mem_free(zone->mctx, zone->strnamerd);
1109 if (zone->strrdclass != NULL)
1110 isc_mem_free(zone->mctx, zone->strrdclass);
1112 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1113 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1114 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1115 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1117 if (inline_secure(zone))
1118 dns_zone_setclass(zone->raw, rdclass);
1123 dns_zone_getclass(dns_zone_t *zone) {
1124 REQUIRE(DNS_ZONE_VALID(zone));
1126 return (zone->rdclass);
1130 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1131 REQUIRE(DNS_ZONE_VALID(zone));
1134 zone->notifytype = notifytype;
1139 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1140 isc_result_t result;
1141 unsigned int soacount;
1143 REQUIRE(DNS_ZONE_VALID(zone));
1144 REQUIRE(serialp != NULL);
1147 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1148 if (zone->db != NULL) {
1149 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
1150 serialp, NULL, NULL, NULL, NULL,
1152 if (result == ISC_R_SUCCESS && soacount == 0)
1153 result = ISC_R_FAILURE;
1155 result = DNS_R_NOTLOADED;
1156 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1163 dns_zone_getserial(dns_zone_t *zone) {
1164 isc_result_t result;
1165 isc_uint32_t serial;
1167 result = dns_zone_getserial2(zone, &serial);
1168 if (result != ISC_R_SUCCESS)
1169 serial = 0; /* XXX: not really correct, but no other choice */
1178 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1181 REQUIRE(DNS_ZONE_VALID(zone));
1182 REQUIRE(type != dns_zone_none);
1188 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1191 if (zone->strnamerd != NULL)
1192 isc_mem_free(zone->mctx, zone->strnamerd);
1194 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1195 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1200 zone_freedbargs(dns_zone_t *zone) {
1203 /* Free the old database argument list. */
1204 if (zone->db_argv != NULL) {
1205 for (i = 0; i < zone->db_argc; i++)
1206 isc_mem_free(zone->mctx, zone->db_argv[i]);
1207 isc_mem_put(zone->mctx, zone->db_argv,
1208 zone->db_argc * sizeof(*zone->db_argv));
1211 zone->db_argv = NULL;
1215 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1218 isc_result_t result = ISC_R_SUCCESS;
1222 REQUIRE(DNS_ZONE_VALID(zone));
1223 REQUIRE(argv != NULL && *argv == NULL);
1226 size = (zone->db_argc + 1) * sizeof(char *);
1227 for (i = 0; i < zone->db_argc; i++)
1228 size += strlen(zone->db_argv[i]) + 1;
1229 mem = isc_mem_allocate(mctx, size);
1233 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1234 for (i = 0; i < zone->db_argc; i++) {
1236 strcpy(tmp2, zone->db_argv[i]);
1237 tmp2 += strlen(tmp2) + 1;
1241 result = ISC_R_NOMEMORY;
1248 dns_zone_setdbtype(dns_zone_t *zone,
1249 unsigned int dbargc, const char * const *dbargv) {
1250 isc_result_t result = ISC_R_SUCCESS;
1254 REQUIRE(DNS_ZONE_VALID(zone));
1255 REQUIRE(dbargc >= 1);
1256 REQUIRE(dbargv != NULL);
1260 /* Set up a new database argument list. */
1261 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1264 for (i = 0; i < dbargc; i++)
1266 for (i = 0; i < dbargc; i++) {
1267 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1272 /* Free the old list. */
1273 zone_freedbargs(zone);
1275 zone->db_argc = dbargc;
1276 zone->db_argv = new;
1277 result = ISC_R_SUCCESS;
1282 for (i = 0; i < dbargc; i++)
1284 isc_mem_free(zone->mctx, new[i]);
1285 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1287 result = ISC_R_NOMEMORY;
1295 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1297 REQUIRE(DNS_ZONE_VALID(zone));
1300 if (zone->view != NULL)
1301 dns_view_weakdetach(&zone->view);
1302 dns_view_weakattach(view, &zone->view);
1304 if (zone->strviewname != NULL)
1305 isc_mem_free(zone->mctx, zone->strviewname);
1306 if (zone->strnamerd != NULL)
1307 isc_mem_free(zone->mctx, zone->strnamerd);
1309 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1310 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1311 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1312 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1314 if (inline_secure(zone))
1315 dns_zone_setview(zone->raw, view);
1321 dns_zone_getview(dns_zone_t *zone) {
1322 REQUIRE(DNS_ZONE_VALID(zone));
1324 return (zone->view);
1329 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1330 isc_result_t result;
1333 REQUIRE(DNS_ZONE_VALID(zone));
1334 REQUIRE(origin != NULL);
1337 if (dns_name_dynamic(&zone->origin)) {
1338 dns_name_free(&zone->origin, zone->mctx);
1339 dns_name_init(&zone->origin, NULL);
1341 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1343 if (zone->strnamerd != NULL)
1344 isc_mem_free(zone->mctx, zone->strnamerd);
1345 if (zone->strname != NULL)
1346 isc_mem_free(zone->mctx, zone->strname);
1348 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1349 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1350 zone_name_tostr(zone, namebuf, sizeof namebuf);
1351 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1353 if (result == ISC_R_SUCCESS && inline_secure(zone))
1354 result = dns_zone_setorigin(zone->raw, origin);
1360 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1361 REQUIRE(DNS_ZONE_VALID(zone));
1362 REQUIRE(acache != NULL);
1365 if (zone->acache != NULL)
1366 dns_acache_detach(&zone->acache);
1367 dns_acache_attach(acache, &zone->acache);
1368 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1369 if (zone->db != NULL) {
1370 isc_result_t result;
1373 * If the zone reuses an existing DB, the DB needs to be
1374 * set in the acache explicitly. We can safely ignore the
1375 * case where the DB is already set. If other error happens,
1376 * the acache will not work effectively.
1378 result = dns_acache_setdb(acache, zone->db);
1379 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1380 UNEXPECTED_ERROR(__FILE__, __LINE__,
1381 "dns_acache_setdb() failed: %s",
1382 isc_result_totext(result));
1385 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1390 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1393 if (value != NULL) {
1394 copy = isc_mem_strdup(zone->mctx, value);
1396 return (ISC_R_NOMEMORY);
1402 isc_mem_free(zone->mctx, *field);
1405 return (ISC_R_SUCCESS);
1409 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1410 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1414 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1415 dns_masterformat_t format) {
1416 isc_result_t result = ISC_R_SUCCESS;
1418 REQUIRE(DNS_ZONE_VALID(zone));
1421 result = dns_zone_setstring(zone, &zone->masterfile, file);
1422 if (result == ISC_R_SUCCESS) {
1423 zone->masterformat = format;
1424 result = default_journal(zone);
1432 dns_zone_getfile(dns_zone_t *zone) {
1433 REQUIRE(DNS_ZONE_VALID(zone));
1435 return (zone->masterfile);
1439 default_journal(dns_zone_t *zone) {
1440 isc_result_t result;
1443 REQUIRE(DNS_ZONE_VALID(zone));
1444 REQUIRE(LOCKED_ZONE(zone));
1446 if (zone->masterfile != NULL) {
1447 /* Calculate string length including '\0'. */
1448 int len = strlen(zone->masterfile) + sizeof(".jnl");
1449 journal = isc_mem_allocate(zone->mctx, len);
1450 if (journal == NULL)
1451 return (ISC_R_NOMEMORY);
1452 strcpy(journal, zone->masterfile);
1453 strcat(journal, ".jnl");
1457 result = dns_zone_setstring(zone, &zone->journal, journal);
1458 if (journal != NULL)
1459 isc_mem_free(zone->mctx, journal);
1464 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1465 isc_result_t result = ISC_R_SUCCESS;
1467 REQUIRE(DNS_ZONE_VALID(zone));
1470 result = dns_zone_setstring(zone, &zone->journal, journal);
1477 dns_zone_getjournal(dns_zone_t *zone) {
1478 REQUIRE(DNS_ZONE_VALID(zone));
1480 return (zone->journal);
1484 * Return true iff the zone is "dynamic", in the sense that the zone's
1485 * master file (if any) is written by the server, rather than being
1486 * updated manually and read by the server.
1488 * This is true for slave zones, stub zones, key zones, and zones that
1489 * allow dynamic updates either by having an update policy ("ssutable")
1490 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1493 dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) {
1494 REQUIRE(DNS_ZONE_VALID(zone));
1496 if (zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1497 zone->type == dns_zone_key ||
1498 (zone->type == dns_zone_redirect && zone->masters != NULL))
1501 /* If !ignore_freeze, we need check whether updates are disabled. */
1502 if (zone->type == dns_zone_master &&
1503 (!zone->update_disabled || ignore_freeze) &&
1504 ((zone->ssutable != NULL) ||
1505 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
1513 * Set the response policy index and information for a zone.
1516 dns_zone_rpz_enable(dns_zone_t *zone) {
1518 * Only RBTDB zones can be used for response policy zones,
1519 * because only they have the code to load the create the summary data.
1520 * Only zones that are loaded instead of mmap()ed create the
1521 * summary data and so can be policy zones.
1523 if (strcmp(zone->db_argv[0], "rbt") != 0 &&
1524 strcmp(zone->db_argv[0], "rbt64") != 0)
1525 return (ISC_R_NOTIMPLEMENTED);
1527 zone->is_rpz = ISC_TRUE;
1529 return (ISC_R_SUCCESS);
1533 dns_zone_get_rpz(dns_zone_t *zone) {
1534 return (zone->is_rpz);
1538 zone_load(dns_zone_t *zone, unsigned int flags) {
1539 isc_result_t result;
1541 isc_time_t loadtime, filetime;
1542 dns_db_t *db = NULL;
1543 isc_boolean_t rbt, hasraw;
1545 REQUIRE(DNS_ZONE_VALID(zone));
1548 hasraw = inline_secure(zone);
1550 result = zone_load(zone->raw, flags);
1551 if (result != ISC_R_SUCCESS) {
1555 LOCK_ZONE(zone->raw);
1560 INSIST(zone->type != dns_zone_none);
1562 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1563 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1564 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1565 result = DNS_R_CONTINUE;
1569 INSIST(zone->db_argc >= 1);
1571 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1572 strcmp(zone->db_argv[0], "rbt64") == 0;
1574 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1576 * The zone has no master file configured.
1578 result = ISC_R_SUCCESS;
1582 if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) {
1584 * This is a slave, stub, or dynamically updated
1585 * zone being reloaded. Do nothing - the database
1586 * we already have is guaranteed to be up-to-date.
1588 if (zone->type == dns_zone_master)
1589 result = DNS_R_DYNAMIC;
1591 result = ISC_R_SUCCESS;
1596 * Store the current time before the zone is loaded, so that if the
1597 * file changes between the time of the load and the time that
1598 * zone->loadtime is set, then the file will still be reloaded
1599 * the next time dns_zone_load is called.
1601 TIME_NOW(&loadtime);
1604 * Don't do the load if the file that stores the zone is older
1605 * than the last time the zone was loaded. If the zone has not
1606 * been loaded yet, zone->loadtime will be the epoch.
1608 if (zone->masterfile != NULL) {
1610 * The file is already loaded. If we are just doing a
1611 * "rndc reconfig", we are done.
1613 if (!isc_time_isepoch(&zone->loadtime) &&
1614 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1615 result = ISC_R_SUCCESS;
1619 result = isc_file_getmodtime(zone->masterfile, &filetime);
1620 if (result == ISC_R_SUCCESS) {
1621 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1622 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1623 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1624 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1625 "skipping load: master file "
1626 "older than last load");
1627 result = DNS_R_UPTODATE;
1630 loadtime = filetime;
1635 * Built in zones (with the exception of empty zones) don't need
1638 if (zone->type == dns_zone_master &&
1639 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1640 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1641 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1642 result = ISC_R_SUCCESS;
1646 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1647 (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
1649 if (zone->masterfile == NULL ||
1650 !isc_file_exists(zone->masterfile)) {
1651 if (zone->masterfile != NULL) {
1652 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1655 zone->refreshtime = now;
1656 if (zone->task != NULL)
1657 zone_settimer(zone, &now);
1658 result = ISC_R_SUCCESS;
1663 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1665 result = dns_db_create(zone->mctx, zone->db_argv[0],
1666 &zone->origin, (zone->type == dns_zone_stub) ?
1667 dns_dbtype_stub : dns_dbtype_zone,
1669 zone->db_argc - 1, zone->db_argv + 1,
1672 if (result != ISC_R_SUCCESS) {
1673 dns_zone_log(zone, ISC_LOG_ERROR,
1674 "loading zone: creating database: %s",
1675 isc_result_totext(result));
1678 dns_db_settask(db, zone->task);
1680 if (! dns_db_ispersistent(db)) {
1681 if (zone->masterfile != NULL) {
1682 result = zone_startload(db, zone, loadtime);
1684 result = DNS_R_NOMASTERFILE;
1685 if (zone->type == dns_zone_master ||
1686 (zone->type == dns_zone_redirect &&
1687 zone->masters == NULL)) {
1688 dns_zone_log(zone, ISC_LOG_ERROR,
1690 "no master file configured");
1693 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1694 "no master file configured: continuing");
1698 if (result == DNS_R_CONTINUE) {
1699 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1700 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1701 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1705 result = zone_postload(zone, db, loadtime, result);
1709 UNLOCK_ZONE(zone->raw);
1717 dns_zone_load(dns_zone_t *zone) {
1718 return (zone_load(zone, 0));
1722 dns_zone_loadnew(dns_zone_t *zone) {
1723 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1727 zone_asyncload(isc_task_t *task, isc_event_t *event) {
1728 dns_asyncload_t *asl = event->ev_arg;
1729 dns_zone_t *zone = asl->zone;
1730 isc_result_t result = ISC_R_SUCCESS;
1734 REQUIRE(DNS_ZONE_VALID(zone));
1736 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1737 result = ISC_R_CANCELED;
1738 isc_event_free(&event);
1739 if (result == ISC_R_CANCELED ||
1740 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
1746 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
1749 /* Inform the zone table we've finished loading */
1750 if (asl->loaded != NULL)
1751 (asl->loaded)(asl->loaded_arg, zone, task);
1754 isc_mem_put(zone->mctx, asl, sizeof (*asl));
1755 dns_zone_idetach(&zone);
1759 dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
1761 dns_asyncload_t *asl = NULL;
1762 isc_result_t result = ISC_R_SUCCESS;
1764 REQUIRE(DNS_ZONE_VALID(zone));
1766 if (zone->zmgr == NULL)
1767 return (ISC_R_FAILURE);
1769 asl = isc_mem_get(zone->mctx, sizeof (*asl));
1771 CHECK(ISC_R_NOMEMORY);
1775 asl->loaded_arg = arg;
1777 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
1779 zone_asyncload, asl,
1780 sizeof(isc_event_t));
1782 CHECK(ISC_R_NOMEMORY);
1785 zone_iattach(zone, &asl->zone);
1786 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
1787 isc_task_send(zone->loadtask, &e);
1790 return (ISC_R_SUCCESS);
1794 isc_mem_put(zone->mctx, asl, sizeof (*asl));
1799 dns__zone_loadpending(dns_zone_t *zone) {
1800 REQUIRE(DNS_ZONE_VALID(zone));
1802 return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)));
1806 dns_zone_loadandthaw(dns_zone_t *zone) {
1807 isc_result_t result;
1809 if (inline_raw(zone))
1810 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW);
1812 result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1815 case DNS_R_CONTINUE:
1816 /* Deferred thaw. */
1818 case DNS_R_UPTODATE:
1820 case DNS_R_SEENINCLUDE:
1821 zone->update_disabled = ISC_FALSE;
1823 case DNS_R_NOMASTERFILE:
1824 zone->update_disabled = ISC_FALSE;
1827 /* Error, remain in disabled state. */
1834 get_master_options(dns_zone_t *zone) {
1835 unsigned int options;
1837 options = DNS_MASTER_ZONE;
1838 if (zone->type == dns_zone_slave ||
1839 (zone->type == dns_zone_redirect && zone->masters == NULL))
1840 options |= DNS_MASTER_SLAVE;
1841 if (zone->type == dns_zone_key)
1842 options |= DNS_MASTER_KEY;
1843 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1844 options |= DNS_MASTER_CHECKNS;
1845 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1846 options |= DNS_MASTER_FATALNS;
1847 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1848 options |= DNS_MASTER_CHECKNAMES;
1849 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1850 options |= DNS_MASTER_CHECKNAMESFAIL;
1851 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1852 options |= DNS_MASTER_CHECKMX;
1853 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1854 options |= DNS_MASTER_CHECKMXFAIL;
1855 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1856 options |= DNS_MASTER_CHECKWILDCARD;
1857 if (inline_secure(zone) || (zone->type == dns_zone_master &&
1858 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1859 zone->ssutable != NULL)))
1860 options |= DNS_MASTER_RESIGN;
1865 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1866 dns_load_t *load = event->ev_arg;
1867 isc_result_t result = ISC_R_SUCCESS;
1868 unsigned int options;
1870 REQUIRE(DNS_LOAD_VALID(load));
1872 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1873 result = ISC_R_CANCELED;
1874 isc_event_free(&event);
1875 if (result == ISC_R_CANCELED)
1878 options = get_master_options(load->zone);
1880 result = dns_master_loadfileinc3(load->zone->masterfile,
1881 dns_db_origin(load->db),
1882 dns_db_origin(load->db),
1883 load->zone->rdclass, options,
1884 load->zone->sigresigninginterval,
1885 &load->callbacks, task,
1886 zone_loaddone, load,
1887 &load->zone->lctx, load->zone->mctx,
1888 load->zone->masterformat);
1889 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1890 result != DNS_R_SEENINCLUDE)
1895 zone_loaddone(load, result);
1899 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
1900 isc_result_t result;
1901 unsigned int soacount;
1904 if (raw->db != NULL) {
1905 result = zone_get_from_db(raw, raw->db, NULL, &soacount,
1906 &rawdata->sourceserial,
1907 NULL, NULL, NULL, NULL,
1909 if (result == ISC_R_SUCCESS && soacount > 0U)
1910 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
1916 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1917 const char me[] = "zone_gotwritehandle";
1918 dns_zone_t *zone = event->ev_arg;
1919 isc_result_t result = ISC_R_SUCCESS;
1920 dns_dbversion_t *version = NULL;
1921 dns_masterrawheader_t rawdata;
1923 REQUIRE(DNS_ZONE_VALID(zone));
1924 INSIST(task == zone->task);
1927 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1928 result = ISC_R_CANCELED;
1929 isc_event_free(&event);
1930 if (result == ISC_R_CANCELED)
1934 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1935 if (zone->db != NULL) {
1936 dns_db_currentversion(zone->db, &version);
1937 dns_master_initrawheader(&rawdata);
1938 if (inline_secure(zone))
1939 get_raw_serial(zone->raw, &rawdata);
1940 result = dns_master_dumpinc3(zone->mctx, zone->db, version,
1941 &dns_master_style_default,
1942 zone->masterfile, zone->task,
1943 dump_done, zone, &zone->dctx,
1944 zone->masterformat, &rawdata);
1945 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1947 result = ISC_R_CANCELED;
1948 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1950 if (result != DNS_R_CONTINUE)
1955 dump_done(zone, result);
1959 * Save the raw serial number for inline-signing zones.
1960 * (XXX: Other information from the header will be used
1961 * for other purposes in the future, but for now this is
1962 * all we're interested in.)
1965 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
1966 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
1969 zone->sourceserial = header->sourceserial;
1970 zone->sourceserialset = ISC_TRUE;
1974 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
1979 zone_setrawdata(zone, header);
1984 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1986 isc_result_t result;
1987 isc_result_t tresult;
1988 unsigned int options;
1992 result = dns_db_rpz_enabled(db, NULL);
1993 if (result != ISC_R_SUCCESS)
1998 options = get_master_options(zone);
1999 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
2000 options |= DNS_MASTER_MANYERRORS;
2002 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
2003 load = isc_mem_get(zone->mctx, sizeof(*load));
2005 return (ISC_R_NOMEMORY);
2010 load->loadtime = loadtime;
2011 load->magic = LOAD_MAGIC;
2013 isc_mem_attach(zone->mctx, &load->mctx);
2014 zone_iattach(zone, &load->zone);
2015 dns_db_attach(db, &load->db);
2016 dns_rdatacallbacks_init(&load->callbacks);
2017 load->callbacks.rawdata = zone_setrawdata;
2018 zone_iattach(zone, &load->callbacks.zone);
2019 result = dns_db_beginload(db, &load->callbacks.add,
2020 &load->callbacks.add_private);
2021 if (result != ISC_R_SUCCESS)
2023 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask,
2024 zone_gotreadhandle, load,
2026 if (result != ISC_R_SUCCESS) {
2028 * We can't report multiple errors so ignore
2029 * the result of dns_db_endload().
2031 (void)dns_db_endload(load->db,
2032 &load->callbacks.add_private);
2035 result = DNS_R_CONTINUE;
2037 dns_rdatacallbacks_t callbacks;
2039 dns_rdatacallbacks_init(&callbacks);
2040 callbacks.rawdata = zone_setrawdata;
2041 zone_iattach(zone, &callbacks.zone);
2042 result = dns_db_beginload(db, &callbacks.add,
2043 &callbacks.add_private);
2044 if (result != ISC_R_SUCCESS) {
2045 zone_idetach(&callbacks.zone);
2048 result = dns_master_loadfile3(zone->masterfile,
2049 &zone->origin, &zone->origin,
2050 zone->rdclass, options,
2051 zone->sigresigninginterval,
2052 &callbacks, zone->mctx,
2053 zone->masterformat);
2054 tresult = dns_db_endload(db, &callbacks.add_private);
2055 if (result == ISC_R_SUCCESS)
2057 zone_idetach(&callbacks.zone);
2064 dns_db_detach(&load->db);
2065 zone_idetach(&load->zone);
2066 zone_idetach(&load->callbacks.zone);
2067 isc_mem_detach(&load->mctx);
2068 isc_mem_put(zone->mctx, load, sizeof(*load));
2072 static isc_boolean_t
2073 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2076 isc_result_t result;
2077 char ownerbuf[DNS_NAME_FORMATSIZE];
2078 char namebuf[DNS_NAME_FORMATSIZE];
2079 char altbuf[DNS_NAME_FORMATSIZE];
2080 dns_fixedname_t fixed;
2081 dns_name_t *foundname;
2085 * "." means the services does not exist.
2087 if (dns_name_equal(name, dns_rootname))
2093 if (!dns_name_issubdomain(name, &zone->origin)) {
2094 if (zone->checkmx != NULL)
2095 return ((zone->checkmx)(zone, name, owner));
2099 if (zone->type == dns_zone_master)
2100 level = ISC_LOG_ERROR;
2102 level = ISC_LOG_WARNING;
2104 dns_fixedname_init(&fixed);
2105 foundname = dns_fixedname_name(&fixed);
2107 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2108 0, 0, NULL, foundname, NULL, NULL);
2109 if (result == ISC_R_SUCCESS)
2112 if (result == DNS_R_NXRRSET) {
2113 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2114 0, 0, NULL, foundname, NULL, NULL);
2115 if (result == ISC_R_SUCCESS)
2119 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2120 dns_name_format(name, namebuf, sizeof namebuf);
2121 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2122 result == DNS_R_EMPTYNAME) {
2123 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
2124 level = ISC_LOG_WARNING;
2125 dns_zone_log(zone, level,
2126 "%s/MX '%s' has no address records (A or AAAA)",
2128 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2131 if (result == DNS_R_CNAME) {
2132 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2133 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2134 level = ISC_LOG_WARNING;
2135 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2136 dns_zone_log(zone, level,
2137 "%s/MX '%s' is a CNAME (illegal)",
2139 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2142 if (result == DNS_R_DNAME) {
2143 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2144 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2145 level = ISC_LOG_WARNING;
2146 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
2147 dns_name_format(foundname, altbuf, sizeof altbuf);
2148 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
2149 " '%s' (illegal)", ownerbuf, namebuf,
2152 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2155 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
2156 return ((zone->checkmx)(zone, name, owner));
2161 static isc_boolean_t
2162 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2165 isc_result_t result;
2166 char ownerbuf[DNS_NAME_FORMATSIZE];
2167 char namebuf[DNS_NAME_FORMATSIZE];
2168 char altbuf[DNS_NAME_FORMATSIZE];
2169 dns_fixedname_t fixed;
2170 dns_name_t *foundname;
2174 * "." means the services does not exist.
2176 if (dns_name_equal(name, dns_rootname))
2182 if (!dns_name_issubdomain(name, &zone->origin)) {
2183 if (zone->checksrv != NULL)
2184 return ((zone->checksrv)(zone, name, owner));
2188 if (zone->type == dns_zone_master)
2189 level = ISC_LOG_ERROR;
2191 level = ISC_LOG_WARNING;
2193 dns_fixedname_init(&fixed);
2194 foundname = dns_fixedname_name(&fixed);
2196 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2197 0, 0, NULL, foundname, NULL, NULL);
2198 if (result == ISC_R_SUCCESS)
2201 if (result == DNS_R_NXRRSET) {
2202 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2203 0, 0, NULL, foundname, NULL, NULL);
2204 if (result == ISC_R_SUCCESS)
2208 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2209 dns_name_format(name, namebuf, sizeof namebuf);
2210 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2211 result == DNS_R_EMPTYNAME) {
2212 dns_zone_log(zone, level,
2213 "%s/SRV '%s' has no address records (A or AAAA)",
2215 /* XXX950 make fatal for 9.5.0. */
2219 if (result == DNS_R_CNAME) {
2220 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2221 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2222 level = ISC_LOG_WARNING;
2223 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2224 dns_zone_log(zone, level,
2225 "%s/SRV '%s' is a CNAME (illegal)",
2227 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2230 if (result == DNS_R_DNAME) {
2231 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2232 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2233 level = ISC_LOG_WARNING;
2234 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
2235 dns_name_format(foundname, altbuf, sizeof altbuf);
2236 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
2237 "DNAME '%s' (illegal)", ownerbuf, namebuf,
2240 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2243 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
2244 return ((zone->checksrv)(zone, name, owner));
2249 static isc_boolean_t
2250 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2253 isc_boolean_t answer = ISC_TRUE;
2254 isc_result_t result, tresult;
2255 char ownerbuf[DNS_NAME_FORMATSIZE];
2256 char namebuf[DNS_NAME_FORMATSIZE];
2257 char altbuf[DNS_NAME_FORMATSIZE];
2258 dns_fixedname_t fixed;
2259 dns_name_t *foundname;
2261 dns_rdataset_t aaaa;
2267 if (!dns_name_issubdomain(name, &zone->origin)) {
2268 if (zone->checkns != NULL)
2269 return ((zone->checkns)(zone, name, owner, NULL, NULL));
2273 if (zone->type == dns_zone_master)
2274 level = ISC_LOG_ERROR;
2276 level = ISC_LOG_WARNING;
2278 dns_fixedname_init(&fixed);
2279 foundname = dns_fixedname_name(&fixed);
2280 dns_rdataset_init(&a);
2281 dns_rdataset_init(&aaaa);
2283 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2284 DNS_DBFIND_GLUEOK, 0, NULL,
2285 foundname, &a, NULL);
2287 if (result == ISC_R_SUCCESS) {
2288 dns_rdataset_disassociate(&a);
2290 } else if (result == DNS_R_DELEGATION)
2291 dns_rdataset_disassociate(&a);
2293 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
2294 result == DNS_R_GLUE) {
2295 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2296 DNS_DBFIND_GLUEOK, 0, NULL,
2297 foundname, &aaaa, NULL);
2298 if (tresult == ISC_R_SUCCESS) {
2299 dns_rdataset_disassociate(&aaaa);
2302 if (tresult == DNS_R_DELEGATION)
2303 dns_rdataset_disassociate(&aaaa);
2304 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2306 * Check glue against child zone.
2308 if (zone->checkns != NULL)
2309 answer = (zone->checkns)(zone, name, owner,
2311 if (dns_rdataset_isassociated(&a))
2312 dns_rdataset_disassociate(&a);
2313 if (dns_rdataset_isassociated(&aaaa))
2314 dns_rdataset_disassociate(&aaaa);
2319 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2320 dns_name_format(name, namebuf, sizeof namebuf);
2321 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2322 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2324 isc_boolean_t required = ISC_FALSE;
2325 if (dns_name_issubdomain(name, owner)) {
2326 what = "REQUIRED GLUE ";
2327 required = ISC_TRUE;
2328 } else if (result == DNS_R_DELEGATION)
2329 what = "SIBLING GLUE ";
2333 if (result != DNS_R_DELEGATION || required ||
2334 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2335 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2336 "address records (A or AAAA)",
2337 ownerbuf, namebuf, what);
2339 * Log missing address record.
2341 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2342 (void)(zone->checkns)(zone, name, owner,
2344 /* XXX950 make fatal for 9.5.0. */
2345 /* answer = ISC_FALSE; */
2347 } else if (result == DNS_R_CNAME) {
2348 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2350 /* XXX950 make fatal for 9.5.0. */
2351 /* answer = ISC_FALSE; */
2352 } else if (result == DNS_R_DNAME) {
2353 dns_name_format(foundname, altbuf, sizeof altbuf);
2354 dns_zone_log(zone, level,
2355 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2356 ownerbuf, namebuf, altbuf);
2357 /* XXX950 make fatal for 9.5.0. */
2358 /* answer = ISC_FALSE; */
2361 if (dns_rdataset_isassociated(&a))
2362 dns_rdataset_disassociate(&a);
2363 if (dns_rdataset_isassociated(&aaaa))
2364 dns_rdataset_disassociate(&aaaa);
2368 static isc_boolean_t
2369 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2370 dns_rdataset_t *rdataset)
2372 dns_rdataset_t tmprdataset;
2373 isc_result_t result;
2374 isc_boolean_t answer = ISC_TRUE;
2375 isc_boolean_t format = ISC_TRUE;
2376 int level = ISC_LOG_WARNING;
2377 char ownerbuf[DNS_NAME_FORMATSIZE];
2378 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2379 unsigned int count1 = 0;
2381 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2382 level = ISC_LOG_ERROR;
2384 dns_rdataset_init(&tmprdataset);
2385 for (result = dns_rdataset_first(rdataset);
2386 result == ISC_R_SUCCESS;
2387 result = dns_rdataset_next(rdataset)) {
2388 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2389 unsigned int count2 = 0;
2392 dns_rdataset_current(rdataset, &rdata1);
2393 dns_rdataset_clone(rdataset, &tmprdataset);
2394 for (result = dns_rdataset_first(&tmprdataset);
2395 result == ISC_R_SUCCESS;
2396 result = dns_rdataset_next(&tmprdataset)) {
2397 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2399 if (count1 >= count2)
2401 dns_rdataset_current(&tmprdataset, &rdata2);
2402 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2404 dns_name_format(owner, ownerbuf,
2406 dns_rdatatype_format(rdata1.type,
2411 dns_zone_log(zone, level, "%s/%s has "
2412 "semantically identical records",
2414 if (level == ISC_LOG_ERROR)
2419 dns_rdataset_disassociate(&tmprdataset);
2426 static isc_boolean_t
2427 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2428 dns_dbiterator_t *dbiterator = NULL;
2429 dns_dbnode_t *node = NULL;
2430 dns_fixedname_t fixed;
2432 dns_rdataset_t rdataset;
2433 dns_rdatasetiter_t *rdsit = NULL;
2434 isc_boolean_t ok = ISC_TRUE;
2435 isc_result_t result;
2437 dns_fixedname_init(&fixed);
2438 name = dns_fixedname_name(&fixed);
2439 dns_rdataset_init(&rdataset);
2441 result = dns_db_createiterator(db, 0, &dbiterator);
2442 if (result != ISC_R_SUCCESS)
2445 for (result = dns_dbiterator_first(dbiterator);
2446 result == ISC_R_SUCCESS;
2447 result = dns_dbiterator_next(dbiterator)) {
2448 result = dns_dbiterator_current(dbiterator, &node, name);
2449 if (result != ISC_R_SUCCESS)
2452 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2453 if (result != ISC_R_SUCCESS)
2456 for (result = dns_rdatasetiter_first(rdsit);
2457 result == ISC_R_SUCCESS;
2458 result = dns_rdatasetiter_next(rdsit)) {
2459 dns_rdatasetiter_current(rdsit, &rdataset);
2460 if (!zone_rrset_check_dup(zone, name, &rdataset))
2462 dns_rdataset_disassociate(&rdataset);
2464 dns_rdatasetiter_destroy(&rdsit);
2465 dns_db_detachnode(db, &node);
2469 dns_db_detachnode(db, &node);
2470 dns_dbiterator_destroy(&dbiterator);
2475 static isc_boolean_t
2476 isspf(const dns_rdata_t *rdata) {
2478 const unsigned char *data = rdata->data;
2479 unsigned int rdl = rdata->length, i = 0, tl, len;
2486 if (len > sizeof(buf) - i - 1)
2487 len = sizeof(buf) - i - 1;
2488 memcpy(buf + i, data, len);
2498 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
2503 static isc_boolean_t
2504 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2505 dns_dbiterator_t *dbiterator = NULL;
2506 dns_dbnode_t *node = NULL;
2507 dns_rdataset_t rdataset;
2508 dns_fixedname_t fixed;
2509 dns_fixedname_t fixedbottom;
2512 dns_rdata_in_srv_t srv;
2516 isc_result_t result;
2517 isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
2519 dns_fixedname_init(&fixed);
2520 name = dns_fixedname_name(&fixed);
2521 dns_fixedname_init(&fixedbottom);
2522 bottom = dns_fixedname_name(&fixedbottom);
2523 dns_rdataset_init(&rdataset);
2524 dns_rdata_init(&rdata);
2526 result = dns_db_createiterator(db, 0, &dbiterator);
2527 if (result != ISC_R_SUCCESS)
2530 result = dns_dbiterator_first(dbiterator);
2531 while (result == ISC_R_SUCCESS) {
2532 result = dns_dbiterator_current(dbiterator, &node, name);
2533 if (result != ISC_R_SUCCESS)
2537 * Is this name visible in the zone?
2539 if (!dns_name_issubdomain(name, &zone->origin) ||
2540 (dns_name_countlabels(bottom) > 0 &&
2541 dns_name_issubdomain(name, bottom)))
2545 * Don't check the NS records at the origin.
2547 if (dns_name_equal(name, &zone->origin))
2550 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2551 0, 0, &rdataset, NULL);
2552 if (result != ISC_R_SUCCESS)
2555 * Remember bottom of zone.
2557 dns_name_copy(name, bottom, NULL);
2559 result = dns_rdataset_first(&rdataset);
2560 while (result == ISC_R_SUCCESS) {
2561 dns_rdataset_current(&rdataset, &rdata);
2562 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2563 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2564 if (!zone_check_glue(zone, db, &ns.name, name))
2566 dns_rdata_reset(&rdata);
2567 result = dns_rdataset_next(&rdataset);
2569 dns_rdataset_disassociate(&rdataset);
2573 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2574 0, 0, &rdataset, NULL);
2575 if (result != ISC_R_SUCCESS)
2577 result = dns_rdataset_first(&rdataset);
2578 while (result == ISC_R_SUCCESS) {
2579 dns_rdataset_current(&rdataset, &rdata);
2580 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2581 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2582 if (!zone_check_mx(zone, db, &mx.mx, name))
2584 dns_rdata_reset(&rdata);
2585 result = dns_rdataset_next(&rdataset);
2587 dns_rdataset_disassociate(&rdataset);
2590 if (zone->rdclass != dns_rdataclass_in)
2592 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2593 0, 0, &rdataset, NULL);
2594 if (result != ISC_R_SUCCESS)
2596 result = dns_rdataset_first(&rdataset);
2597 while (result == ISC_R_SUCCESS) {
2598 dns_rdataset_current(&rdataset, &rdata);
2599 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2600 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2601 if (!zone_check_srv(zone, db, &srv.target, name))
2603 dns_rdata_reset(&rdata);
2604 result = dns_rdataset_next(&rdataset);
2606 dns_rdataset_disassociate(&rdataset);
2610 * Check if there is a type TXT spf record without a type SPF
2611 * RRset being present.
2613 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
2615 if (zone->rdclass != dns_rdataclass_in)
2617 have_spf = have_txt = ISC_FALSE;
2618 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
2619 0, 0, &rdataset, NULL);
2620 if (result == ISC_R_SUCCESS) {
2621 dns_rdataset_disassociate(&rdataset);
2622 have_spf = ISC_TRUE;
2624 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
2625 0, 0, &rdataset, NULL);
2626 if (result != ISC_R_SUCCESS)
2628 result = dns_rdataset_first(&rdataset);
2629 while (result == ISC_R_SUCCESS) {
2630 dns_rdataset_current(&rdataset, &rdata);
2631 have_txt = isspf(&rdata);
2632 dns_rdata_reset(&rdata);
2635 result = dns_rdataset_next(&rdataset);
2637 dns_rdataset_disassociate(&rdataset);
2640 if (have_spf != have_txt) {
2641 char namebuf[DNS_NAME_FORMATSIZE];
2642 const char *found = have_txt ? "TXT" : "SPF";
2643 const char *need = have_txt ? "SPF" : "TXT";
2645 dns_name_format(name, namebuf, sizeof(namebuf));
2646 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s "
2647 "record but no SPF/%s record found, add "
2648 "matching type %s record", namebuf, found,
2653 dns_db_detachnode(db, &node);
2654 result = dns_dbiterator_next(dbiterator);
2659 dns_db_detachnode(db, &node);
2660 dns_dbiterator_destroy(&dbiterator);
2666 * OpenSSL verification of RSA keys with exponent 3 is known to be
2667 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2668 * if they are in use.
2671 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2672 dns_dbnode_t *node = NULL;
2673 dns_dbversion_t *version = NULL;
2674 dns_rdata_dnskey_t dnskey;
2675 dns_rdata_t rdata = DNS_RDATA_INIT;
2676 dns_rdataset_t rdataset;
2677 isc_result_t result;
2678 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2679 const char *algorithm;
2681 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2682 if (result != ISC_R_SUCCESS)
2685 dns_db_currentversion(db, &version);
2686 dns_rdataset_init(&rdataset);
2687 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2688 dns_rdatatype_none, 0, &rdataset, NULL);
2689 if (result != ISC_R_SUCCESS)
2692 for (result = dns_rdataset_first(&rdataset);
2693 result == ISC_R_SUCCESS;
2694 result = dns_rdataset_next(&rdataset))
2696 dns_rdataset_current(&rdataset, &rdata);
2697 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2698 INSIST(result == ISC_R_SUCCESS);
2700 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2701 dnskey.algorithm == DST_ALG_RSAMD5) &&
2702 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2703 dnskey.data[1] == 3)
2705 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2707 foundrsa = ISC_TRUE;
2708 algorithm = "RSASHA1";
2711 foundmd5 = ISC_TRUE;
2712 algorithm = "RSAMD5";
2715 dns_zone_log(zone, ISC_LOG_WARNING,
2716 "weak %s (%u) key found "
2717 "(exponent=3)", algorithm,
2719 if (foundrsa && foundmd5)
2722 dns_rdata_reset(&rdata);
2724 dns_rdataset_disassociate(&rdataset);
2728 dns_db_detachnode(db, &node);
2729 if (version != NULL)
2730 dns_db_closeversion(db, &version, ISC_FALSE);
2734 resume_signingwithkey(dns_zone_t *zone) {
2735 dns_dbnode_t *node = NULL;
2736 dns_dbversion_t *version = NULL;
2737 dns_rdata_t rdata = DNS_RDATA_INIT;
2738 dns_rdataset_t rdataset;
2739 isc_result_t result;
2741 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2742 if (result != ISC_R_SUCCESS)
2745 dns_db_currentversion(zone->db, &version);
2746 dns_rdataset_init(&rdataset);
2747 result = dns_db_findrdataset(zone->db, node, version,
2749 dns_rdatatype_none, 0,
2751 if (result != ISC_R_SUCCESS) {
2752 INSIST(!dns_rdataset_isassociated(&rdataset));
2756 for (result = dns_rdataset_first(&rdataset);
2757 result == ISC_R_SUCCESS;
2758 result = dns_rdataset_next(&rdataset))
2760 dns_rdataset_current(&rdataset, &rdata);
2761 if (rdata.length != 5 ||
2762 rdata.data[0] == 0 || rdata.data[4] != 0) {
2763 dns_rdata_reset(&rdata);
2767 result = zone_signwithkey(zone, rdata.data[0],
2768 (rdata.data[1] << 8) | rdata.data[2],
2769 ISC_TF(rdata.data[3]));
2770 if (result != ISC_R_SUCCESS) {
2771 dns_zone_log(zone, ISC_LOG_ERROR,
2772 "zone_signwithkey failed: %s",
2773 dns_result_totext(result));
2775 dns_rdata_reset(&rdata);
2777 dns_rdataset_disassociate(&rdataset);
2781 dns_db_detachnode(zone->db, &node);
2782 if (version != NULL)
2783 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2787 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2788 dns_nsec3chain_t *nsec3chain, *current;
2789 dns_dbversion_t *version = NULL;
2790 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
2791 isc_result_t result;
2793 unsigned int options = 0;
2794 char saltbuf[255*2+1];
2795 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
2798 dns_db_currentversion(zone->db, &version);
2799 result = dns_nsec_nseconly(zone->db, version, &nseconly);
2800 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
2801 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2802 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0)
2803 return (ISC_R_SUCCESS);
2805 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2806 if (nsec3chain == NULL)
2807 return (ISC_R_NOMEMORY);
2809 nsec3chain->magic = 0;
2810 nsec3chain->done = ISC_FALSE;
2811 nsec3chain->db = NULL;
2812 nsec3chain->dbiterator = NULL;
2813 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2814 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2815 nsec3chain->nsec3param.hash = nsec3param->hash;
2816 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2817 nsec3chain->nsec3param.flags = nsec3param->flags;
2818 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2819 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2820 nsec3chain->nsec3param.salt = nsec3chain->salt;
2821 nsec3chain->seen_nsec = ISC_FALSE;
2822 nsec3chain->delete_nsec = ISC_FALSE;
2823 nsec3chain->save_delete_nsec = ISC_FALSE;
2825 if (nsec3param->flags == 0)
2826 strlcpy(flags, "NONE", sizeof(flags));
2829 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
2830 strlcat(flags, "REMOVE", sizeof(flags));
2831 if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) {
2832 if (flags[0] == '\0')
2833 strlcpy(flags, "INITIAL", sizeof(flags));
2835 strlcat(flags, "|INITIAL", sizeof(flags));
2837 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
2838 if (flags[0] == '\0')
2839 strlcpy(flags, "CREATE", sizeof(flags));
2841 strlcat(flags, "|CREATE", sizeof(flags));
2843 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
2844 if (flags[0] == '\0')
2845 strlcpy(flags, "NONSEC", sizeof(flags));
2847 strlcat(flags, "|NONSEC", sizeof(flags));
2849 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
2850 if (flags[0] == '\0')
2851 strlcpy(flags, "OPTOUT", sizeof(flags));
2853 strlcat(flags, "|OPTOUT", sizeof(flags));
2856 if (nsec3param->salt_length == 0)
2857 strlcpy(saltbuf, "-", sizeof(saltbuf));
2859 for (i = 0; i < nsec3param->salt_length; i++)
2860 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
2861 dns_zone_log(zone, ISC_LOG_INFO,
2862 "zone_addnsec3chain(%u,%s,%u,%s)",
2863 nsec3param->hash, flags, nsec3param->iterations,
2866 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2868 current = ISC_LIST_NEXT(current, link)) {
2869 if (current->db == zone->db &&
2870 current->nsec3param.hash == nsec3param->hash &&
2871 current->nsec3param.iterations == nsec3param->iterations &&
2872 current->nsec3param.salt_length == nsec3param->salt_length
2873 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2874 nsec3param->salt_length))
2875 current->done = ISC_TRUE;
2878 if (zone->db != NULL) {
2879 dns_db_attach(zone->db, &nsec3chain->db);
2880 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2881 options = DNS_DB_NONSEC3;
2882 result = dns_db_createiterator(nsec3chain->db, options,
2883 &nsec3chain->dbiterator);
2884 if (result == ISC_R_SUCCESS)
2885 dns_dbiterator_first(nsec3chain->dbiterator);
2886 if (result == ISC_R_SUCCESS) {
2887 dns_dbiterator_pause(nsec3chain->dbiterator);
2888 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2891 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2893 zone->nsec3chaintime = now;
2894 if (zone->task != NULL)
2895 zone_settimer(zone, &now);
2899 result = ISC_R_NOTFOUND;
2901 if (nsec3chain != NULL) {
2902 if (nsec3chain->db != NULL)
2903 dns_db_detach(&nsec3chain->db);
2904 if (nsec3chain->dbiterator != NULL)
2905 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2906 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2912 resume_addnsec3chain(dns_zone_t *zone) {
2913 dns_dbnode_t *node = NULL;
2914 dns_dbversion_t *version = NULL;
2915 dns_rdataset_t rdataset;
2916 isc_result_t result;
2917 dns_rdata_nsec3param_t nsec3param;
2918 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
2920 if (zone->privatetype == 0)
2923 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2924 if (result != ISC_R_SUCCESS)
2927 dns_db_currentversion(zone->db, &version);
2929 result = dns_nsec_nseconly(zone->db, version, &nseconly);
2930 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
2932 dns_rdataset_init(&rdataset);
2933 result = dns_db_findrdataset(zone->db, node, version,
2934 zone->privatetype, dns_rdatatype_none,
2935 0, &rdataset, NULL);
2936 if (result != ISC_R_SUCCESS) {
2937 INSIST(!dns_rdataset_isassociated(&rdataset));
2941 for (result = dns_rdataset_first(&rdataset);
2942 result == ISC_R_SUCCESS;
2943 result = dns_rdataset_next(&rdataset))
2945 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
2946 dns_rdata_t rdata = DNS_RDATA_INIT;
2947 dns_rdata_t private = DNS_RDATA_INIT;
2949 dns_rdataset_current(&rdataset, &private);
2950 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
2953 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2954 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2955 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
2956 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
2958 result = zone_addnsec3chain(zone, &nsec3param);
2959 if (result != ISC_R_SUCCESS) {
2960 dns_zone_log(zone, ISC_LOG_ERROR,
2961 "zone_addnsec3chain failed: %s",
2962 dns_result_totext(result));
2966 dns_rdataset_disassociate(&rdataset);
2969 dns_db_detachnode(zone->db, &node);
2970 if (version != NULL)
2971 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2975 set_resigntime(dns_zone_t *zone) {
2976 dns_rdataset_t rdataset;
2977 dns_fixedname_t fixed;
2978 unsigned int resign;
2979 isc_result_t result;
2980 isc_uint32_t nanosecs;
2982 dns_rdataset_init(&rdataset);
2983 dns_fixedname_init(&fixed);
2984 result = dns_db_getsigningtime(zone->db, &rdataset,
2985 dns_fixedname_name(&fixed));
2986 if (result != ISC_R_SUCCESS) {
2987 isc_time_settoepoch(&zone->resigntime);
2990 resign = rdataset.resign;
2991 dns_rdataset_disassociate(&rdataset);
2992 isc_random_get(&nanosecs);
2993 nanosecs %= 1000000000;
2994 isc_time_set(&zone->resigntime, resign, nanosecs);
2998 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2999 dns_dbnode_t *node = NULL;
3000 dns_rdataset_t rdataset;
3001 dns_dbversion_t *version = NULL;
3002 dns_rdata_nsec3param_t nsec3param;
3003 isc_boolean_t ok = ISC_FALSE;
3004 isc_result_t result;
3005 dns_rdata_t rdata = DNS_RDATA_INIT;
3006 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
3007 dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE;
3009 dns_rdataset_init(&rdataset);
3010 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3011 if (result != ISC_R_SUCCESS) {
3012 dns_zone_log(zone, ISC_LOG_ERROR,
3013 "nsec3param lookup failure: %s",
3014 dns_result_totext(result));
3017 dns_db_currentversion(db, &version);
3019 result = dns_db_findrdataset(db, node, version,
3020 dns_rdatatype_nsec3param,
3021 dns_rdatatype_none, 0, &rdataset, NULL);
3022 if (result == ISC_R_NOTFOUND) {
3023 INSIST(!dns_rdataset_isassociated(&rdataset));
3024 result = ISC_R_SUCCESS;
3027 if (result != ISC_R_SUCCESS) {
3028 INSIST(!dns_rdataset_isassociated(&rdataset));
3029 dns_zone_log(zone, ISC_LOG_ERROR,
3030 "nsec3param lookup failure: %s",
3031 dns_result_totext(result));
3036 * For dynamic zones we must support every algorithm so we can
3037 * regenerate all the NSEC3 chains.
3038 * For non-dynamic zones we only need to find a supported algorithm.
3040 for (result = dns_rdataset_first(&rdataset);
3041 result == ISC_R_SUCCESS;
3042 result = dns_rdataset_next(&rdataset))
3044 dns_rdataset_current(&rdataset, &rdata);
3045 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3046 dns_rdata_reset(&rdata);
3047 INSIST(result == ISC_R_SUCCESS);
3048 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
3049 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
3051 dns_zone_log(zone, ISC_LOG_WARNING,
3052 "nsec3 test \"unknown\" hash algorithm found: %u",
3055 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
3057 dns_zone_log(zone, ISC_LOG_ERROR,
3058 "unsupported nsec3 hash algorithm"
3059 " in dynamic zone: %u",
3061 result = DNS_R_BADZONE;
3062 /* Stop second error message. */
3066 dns_zone_log(zone, ISC_LOG_WARNING,
3067 "unsupported nsec3 hash algorithm: %u",
3072 if (result == ISC_R_NOMORE)
3073 result = ISC_R_SUCCESS;
3076 result = DNS_R_BADZONE;
3077 dns_zone_log(zone, ISC_LOG_ERROR,
3078 "no supported nsec3 hash algorithm");
3082 if (dns_rdataset_isassociated(&rdataset))
3083 dns_rdataset_disassociate(&rdataset);
3084 dns_db_closeversion(db, &version, ISC_FALSE);
3085 dns_db_detachnode(db, &node);
3090 * Set the timer for refreshing the key zone to the soonest future time
3091 * of the set (current timer, keydata->refresh, keydata->addhd,
3092 * keydata->removehd).
3095 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
3098 const char me[] = "set_refreshkeytimer";
3100 isc_time_t timenow, timethen;
3104 then = key->refresh;
3105 if (key->addhd > now && key->addhd < then)
3107 if (key->removehd > now && key->removehd < then)
3108 then = key->removehd;
3112 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
3115 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
3116 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
3117 zone->refreshkeytime = timethen;
3119 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
3120 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
3121 zone_settimer(zone, &timenow);
3125 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
3126 * If the key zone is changed, set '*changed' to ISC_TRUE.
3129 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3130 dns_diff_t *diff, dns_keytable_t *keytable,
3131 dns_keynode_t **keynodep, isc_boolean_t *changed)
3133 const char me[] = "create_keydata";
3134 isc_result_t result = ISC_R_SUCCESS;
3135 isc_buffer_t keyb, dstb;
3136 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
3137 dns_rdata_keydata_t keydata;
3138 dns_rdata_dnskey_t dnskey;
3139 dns_rdata_t rdata = DNS_RDATA_INIT;
3140 dns_keynode_t *keynode;
3145 REQUIRE(keynodep != NULL);
3146 keynode = *keynodep;
3149 isc_stdtime_get(&now);
3151 /* Loop in case there's more than one key. */
3152 while (result == ISC_R_SUCCESS) {
3153 dns_keynode_t *nextnode = NULL;
3155 key = dns_keynode_key(keynode);
3159 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
3160 CHECK(dst_key_todns(key, &dstb));
3162 /* Convert DST key to DNSKEY. */
3163 dns_rdata_reset(&rdata);
3164 isc_buffer_usedregion(&dstb, &r);
3165 dns_rdata_fromregion(&rdata, dst_key_class(key),
3166 dns_rdatatype_dnskey, &r);
3168 /* DSTKEY to KEYDATA. */
3169 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3170 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
3173 /* KEYDATA to rdata. */
3174 dns_rdata_reset(&rdata);
3175 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
3176 CHECK(dns_rdata_fromstruct(&rdata,
3177 zone->rdclass, dns_rdatatype_keydata,
3180 /* Add rdata to zone. */
3181 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
3182 dst_key_name(key), 0, &rdata));
3183 *changed = ISC_TRUE;
3184 /* Refresh new keys from the zone apex as soon as possible. */
3185 set_refreshkeytimer(zone, &keydata, now);
3188 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
3189 if (result != ISC_R_NOTFOUND) {
3190 dns_keytable_detachkeynode(keytable, &keynode);
3195 if (keynode != NULL)
3196 dns_keytable_detachkeynode(keytable, &keynode);
3199 return (ISC_R_SUCCESS);
3206 * Remove from the key zone all the KEYDATA records found in rdataset.
3209 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3210 dns_name_t *name, dns_rdataset_t *rdataset)
3212 dns_rdata_t rdata = DNS_RDATA_INIT;
3213 isc_result_t result, uresult;
3215 for (result = dns_rdataset_first(rdataset);
3216 result == ISC_R_SUCCESS;
3217 result = dns_rdataset_next(rdataset)) {
3218 dns_rdata_reset(&rdata);
3219 dns_rdataset_current(rdataset, &rdata);
3220 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3222 if (uresult != ISC_R_SUCCESS)
3225 if (result == ISC_R_NOMORE)
3226 result = ISC_R_SUCCESS;
3231 * Compute the DNSSEC key ID for a DNSKEY record.
3234 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
3237 isc_result_t result;
3238 dns_rdata_t rdata = DNS_RDATA_INIT;
3239 unsigned char data[4096];
3240 isc_buffer_t buffer;
3241 dst_key_t *dstkey = NULL;
3243 isc_buffer_init(&buffer, data, sizeof(data));
3244 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3245 dns_rdatatype_dnskey, dnskey, &buffer);
3247 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
3248 if (result == ISC_R_SUCCESS)
3249 *tag = dst_key_id(dstkey);
3250 dst_key_free(&dstkey);
3256 * Add key to the security roots.
3259 trust_key(dns_zone_t *zone, dns_name_t *keyname,
3260 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
3261 isc_result_t result;
3262 dns_rdata_t rdata = DNS_RDATA_INIT;
3263 unsigned char data[4096];
3264 isc_buffer_t buffer;
3265 dns_keytable_t *sr = NULL;
3266 dst_key_t *dstkey = NULL;
3268 /* Convert dnskey to DST key. */
3269 isc_buffer_init(&buffer, data, sizeof(data));
3270 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3271 dns_rdatatype_dnskey, dnskey, &buffer);
3273 result = dns_view_getsecroots(zone->view, &sr);
3274 if (result != ISC_R_SUCCESS)
3277 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
3278 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
3279 dns_keytable_detach(&sr);
3283 dst_key_free(&dstkey);
3285 dns_keytable_detach(&sr);
3290 * Add a null key to the security roots for so that all queries
3291 * to the zone will fail.
3294 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
3295 isc_result_t result;
3296 dns_keytable_t *sr = NULL;
3298 result = dns_view_getsecroots(zone->view, &sr);
3299 if (result == ISC_R_SUCCESS) {
3300 dns_keytable_marksecure(sr, keyname);
3301 dns_keytable_detach(&sr);
3306 * Scan a set of KEYDATA records from the key zone. The ones that are
3307 * valid (i.e., the add holddown timer has expired) become trusted keys.
3310 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
3311 isc_result_t result;
3312 dns_rdata_t rdata = DNS_RDATA_INIT;
3313 dns_rdata_keydata_t keydata;
3314 dns_rdata_dnskey_t dnskey;
3315 isc_mem_t *mctx = zone->mctx;
3316 int trusted = 0, revoked = 0, pending = 0;
3318 dns_keytable_t *sr = NULL;
3320 isc_stdtime_get(&now);
3322 result = dns_view_getsecroots(zone->view, &sr);
3323 if (result == ISC_R_SUCCESS) {
3324 dns_keytable_delete(sr, name);
3325 dns_keytable_detach(&sr);
3328 /* Now insert all the accepted trust anchors from this keydata set. */
3329 for (result = dns_rdataset_first(rdataset);
3330 result == ISC_R_SUCCESS;
3331 result = dns_rdataset_next(rdataset)) {
3332 dns_rdata_reset(&rdata);
3333 dns_rdataset_current(rdataset, &rdata);
3335 /* Convert rdata to keydata. */
3336 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
3337 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3339 /* Set the key refresh timer. */
3340 set_refreshkeytimer(zone, &keydata, now);
3342 /* If the removal timer is nonzero, this key was revoked. */
3343 if (keydata.removehd != 0) {
3349 * If the add timer is still pending, this key is not
3352 if (now < keydata.addhd) {
3357 /* Convert keydata to dnskey. */
3358 dns_keydata_todnskey(&keydata, &dnskey, NULL);
3360 /* Add to keytables. */
3362 trust_key(zone, name, &dnskey, mctx);
3365 if (trusted == 0 && pending != 0) {
3366 char namebuf[DNS_NAME_FORMATSIZE];
3367 dns_name_format(name, namebuf, sizeof namebuf);
3368 dns_zone_log(zone, ISC_LOG_ERROR,
3369 "No valid trust anchors for '%s'!", namebuf);
3370 dns_zone_log(zone, ISC_LOG_ERROR,
3371 "%d key(s) revoked, %d still pending",
3373 dns_zone_log(zone, ISC_LOG_ERROR,
3374 "All queries to '%s' will fail", namebuf);
3375 fail_secure(zone, name);
3380 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3383 dns_diff_t temp_diff;
3384 isc_result_t result;
3387 * Create a singleton diff.
3389 dns_diff_init(diff->mctx, &temp_diff);
3390 temp_diff.resign = diff->resign;
3391 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3394 * Apply it to the database.
3396 result = dns_diff_apply(&temp_diff, db, ver);
3397 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3398 if (result != ISC_R_SUCCESS) {
3399 dns_difftuple_free(tuple);
3404 * Merge it into the current pending journal entry.
3406 dns_diff_appendminimal(diff, tuple);
3409 * Do not clear temp_diff.
3411 return (ISC_R_SUCCESS);
3415 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3416 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3419 dns_difftuple_t *tuple = NULL;
3420 isc_result_t result;
3421 result = dns_difftuple_create(diff->mctx, op,
3422 name, ttl, rdata, &tuple);
3423 if (result != ISC_R_SUCCESS)
3425 return (do_one_tuple(&tuple, db, ver, diff));
3429 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3430 isc_mem_t *mctx, dns_updatemethod_t method) {
3431 dns_difftuple_t *deltuple = NULL;
3432 dns_difftuple_t *addtuple = NULL;
3433 isc_uint32_t serial;
3434 isc_result_t result;
3436 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3437 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3438 addtuple->op = DNS_DIFFOP_ADD;
3440 serial = dns_soa_getserial(&addtuple->rdata);
3441 serial = dns_update_soaserial(serial, method);
3442 dns_soa_setserial(serial, &addtuple->rdata);
3443 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3444 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3445 result = ISC_R_SUCCESS;
3448 if (addtuple != NULL)
3449 dns_difftuple_free(&addtuple);
3450 if (deltuple != NULL)
3451 dns_difftuple_free(&deltuple);
3456 * Write all transactions in 'diff' to the zone journal file.
3459 zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
3462 const char me[] = "zone_journal";
3463 const char *journalfile;
3464 isc_result_t result = ISC_R_SUCCESS;
3465 dns_journal_t *journal = NULL;
3466 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
3469 journalfile = dns_zone_getjournal(zone);
3470 if (journalfile != NULL) {
3471 result = dns_journal_open(zone->mctx, journalfile, mode,
3473 if (result != ISC_R_SUCCESS) {
3474 dns_zone_log(zone, ISC_LOG_ERROR,
3475 "%s:dns_journal_open -> %s",
3476 caller, dns_result_totext(result));
3480 if (sourceserial != NULL)
3481 dns_journal_set_sourceserial(journal, *sourceserial);
3483 result = dns_journal_write_transaction(journal, diff);
3484 if (result != ISC_R_SUCCESS) {
3485 dns_zone_log(zone, ISC_LOG_ERROR,
3486 "%s:dns_journal_write_transaction -> %s",
3487 caller, dns_result_totext(result));
3489 dns_journal_destroy(&journal);
3496 * Create an SOA record for a newly-created zone
3499 add_soa(dns_zone_t *zone, dns_db_t *db) {
3500 isc_result_t result;
3501 dns_rdata_t rdata = DNS_RDATA_INIT;
3502 unsigned char buf[DNS_SOA_BUFFERSIZE];
3503 dns_dbversion_t *ver = NULL;
3506 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
3508 dns_diff_init(zone->mctx, &diff);
3509 result = dns_db_newversion(db, &ver);
3510 if (result != ISC_R_SUCCESS) {
3511 dns_zone_log(zone, ISC_LOG_ERROR,
3512 "add_soa:dns_db_newversion -> %s",
3513 dns_result_totext(result));
3517 /* Build SOA record */
3518 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
3519 0, 0, 0, 0, 0, buf, &rdata);
3520 if (result != ISC_R_SUCCESS) {
3521 dns_zone_log(zone, ISC_LOG_ERROR,
3522 "add_soa:dns_soa_buildrdata -> %s",
3523 dns_result_totext(result));
3527 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
3528 &zone->origin, 0, &rdata);
3531 dns_diff_clear(&diff);
3533 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
3539 * Synchronize the set of initializing keys found in managed-keys {}
3540 * statements with the set of trust anchors found in the managed-keys.bind
3541 * zone. If a domain is no longer named in managed-keys, delete all keys
3542 * from that domain from the key zone. If a domain is mentioned in in
3543 * managed-keys but there are no references to it in the key zone, load
3544 * the key zone with the initializing key(s) for that domain.
3547 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
3548 isc_result_t result = ISC_R_SUCCESS;
3549 isc_boolean_t changed = ISC_FALSE;
3550 isc_boolean_t commit = ISC_FALSE;
3551 dns_rbtnodechain_t chain;
3553 dns_name_t foundname, *origin;
3554 dns_keynode_t *keynode = NULL;
3555 dns_view_t *view = zone->view;
3556 dns_keytable_t *sr = NULL;
3557 dns_dbversion_t *ver = NULL;
3559 dns_rriterator_t rrit;
3561 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3563 dns_name_init(&foundname, NULL);
3564 dns_fixedname_init(&fn);
3565 origin = dns_fixedname_name(&fn);
3567 dns_diff_init(zone->mctx, &diff);
3569 CHECK(dns_view_getsecroots(view, &sr));
3571 result = dns_db_newversion(db, &ver);
3572 if (result != ISC_R_SUCCESS) {
3573 dns_zone_log(zone, ISC_LOG_ERROR,
3574 "sync_keyzone:dns_db_newversion -> %s",
3575 dns_result_totext(result));
3580 * Walk the zone DB. If we find any keys whose names are no longer
3581 * in managed-keys (or *are* in trusted-keys, meaning they are
3582 * permanent and not RFC5011-maintained), delete them from the
3583 * zone. Otherwise call load_secroots(), which loads keys into
3584 * secroots as appropriate.
3586 dns_rriterator_init(&rrit, db, ver, 0);
3587 for (result = dns_rriterator_first(&rrit);
3588 result == ISC_R_SUCCESS;
3589 result = dns_rriterator_nextrrset(&rrit)) {
3590 dns_rdataset_t *rdataset = NULL;
3591 dns_name_t *rrname = NULL;
3594 dns_rriterator_current(&rrit, &rrname, &ttl,
3596 if (!dns_rdataset_isassociated(rdataset)) {
3597 dns_rriterator_destroy(&rrit);
3601 if (rdataset->type != dns_rdatatype_keydata)
3604 result = dns_keytable_find(sr, rrname, &keynode);
3605 if ((result != ISC_R_SUCCESS &&
3606 result != DNS_R_PARTIALMATCH) ||
3607 dns_keynode_managed(keynode) == ISC_FALSE) {
3608 CHECK(delete_keydata(db, ver, &diff,
3612 load_secroots(zone, rrname, rdataset);
3615 if (keynode != NULL)
3616 dns_keytable_detachkeynode(sr, &keynode);
3618 dns_rriterator_destroy(&rrit);
3621 * Now walk secroots to find any managed keys that aren't
3622 * in the zone. If we find any, we add them to the zone.
3624 RWLOCK(&sr->rwlock, isc_rwlocktype_write);
3625 dns_rbtnodechain_init(&chain, zone->mctx);
3626 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
3627 if (result == ISC_R_NOTFOUND)
3628 result = ISC_R_NOMORE;
3629 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
3630 dns_rbtnode_t *rbtnode = NULL;
3632 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
3633 if (rbtnode->data == NULL)
3636 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
3637 if (dns_keynode_managed(keynode)) {
3638 dns_fixedname_t fname;
3639 dns_name_t *keyname;
3642 key = dns_keynode_key(keynode);
3643 dns_fixedname_init(&fname);
3645 if (key == NULL) /* fail_secure() was called. */
3648 keyname = dst_key_name(key);
3649 result = dns_db_find(db, keyname, ver,
3650 dns_rdatatype_keydata,
3651 DNS_DBFIND_NOWILD, 0, NULL,
3652 dns_fixedname_name(&fname),
3654 if (result != ISC_R_SUCCESS)
3655 result = create_keydata(zone, db, ver, &diff,
3656 sr, &keynode, &changed);
3657 if (result != ISC_R_SUCCESS)
3661 result = dns_rbtnodechain_next(&chain, &foundname, origin);
3662 if (keynode != NULL)
3663 dns_keytable_detachkeynode(sr, &keynode);
3665 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
3667 if (result == ISC_R_NOMORE)
3668 result = ISC_R_SUCCESS;
3671 /* Write changes to journal file. */
3672 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
3673 zone->updatemethod));
3674 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
3676 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
3677 zone_needdump(zone, 30);
3682 if (result != ISC_R_SUCCESS &&
3683 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3684 dns_zone_log(zone, ISC_LOG_ERROR,
3685 "unable to synchronize managed keys: %s",
3686 dns_result_totext(result));
3687 isc_time_settoepoch(&zone->refreshkeytime);
3689 if (keynode != NULL)
3690 dns_keytable_detachkeynode(sr, &keynode);
3692 dns_keytable_detach(&sr);
3694 dns_db_closeversion(db, &ver, commit);
3695 dns_diff_clear(&diff);
3701 dns_zone_synckeyzone(dns_zone_t *zone) {
3702 isc_result_t result;
3703 dns_db_t *db = NULL;
3705 if (zone->type != dns_zone_key)
3706 return (DNS_R_BADZONE);
3708 CHECK(dns_zone_getdb(zone, &db));
3711 result = sync_keyzone(zone, db);
3721 maybe_send_secure(dns_zone_t *zone) {
3722 isc_result_t result;
3725 * We've finished loading, or else failed to load, an inline-signing
3726 * 'secure' zone. We now need information about the status of the
3727 * 'raw' zone. If we failed to load, then we need it to send a
3728 * copy of its database; if we succeeded, we need it to send its
3729 * serial number so that we can sync with it. If it has not yet
3730 * loaded, we set a flag so that it will send the necessary
3731 * information when it has finished loading.
3733 if (zone->raw->db != NULL) {
3734 if (zone->db != NULL) {
3735 isc_uint32_t serial;
3736 unsigned int soacount;
3738 result = zone_get_from_db(zone->raw, zone->raw->db,
3739 NULL, &soacount, &serial, NULL,
3740 NULL, NULL, NULL, NULL);
3741 if (result == ISC_R_SUCCESS && soacount > 0U)
3742 zone_send_secureserial(zone->raw, ISC_TRUE, serial);
3744 zone_send_securedb(zone->raw, ISC_TRUE, zone->raw->db);
3747 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
3750 static isc_boolean_t
3751 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
3752 isc_result_t result;
3753 isc_boolean_t answer = ISC_FALSE;
3756 dns_diff_init(mctx, &diff);
3757 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
3758 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
3760 dns_diff_clear(&diff);
3765 * The zone is presumed to be locked.
3768 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
3769 isc_result_t result)
3771 unsigned int soacount = 0;
3772 unsigned int nscount = 0;
3773 unsigned int errors = 0;
3774 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
3776 isc_boolean_t needdump = ISC_FALSE;
3777 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3778 isc_boolean_t nomaster = ISC_FALSE;
3779 unsigned int options;
3784 * Initiate zone transfer? We may need a error code that
3785 * indicates that the "permanent" form does not exist.
3786 * XXX better error feedback to log.
3788 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
3789 if (zone->type == dns_zone_slave ||
3790 zone->type == dns_zone_stub ||
3791 (zone->type == dns_zone_redirect &&
3792 zone->masters == NULL)) {
3793 if (result == ISC_R_FILENOTFOUND)
3794 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3796 else if (result != DNS_R_NOMASTERFILE)
3797 dns_zone_log(zone, ISC_LOG_ERROR,
3798 "loading from master file %s "
3801 dns_result_totext(result));
3802 } else if (zone->type == dns_zone_master &&
3803 inline_secure(zone) && result == ISC_R_FILENOTFOUND)
3805 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3806 "no master file, requesting db");
3807 maybe_send_secure(zone);
3809 int level = ISC_LOG_ERROR;
3810 if (zone->type == dns_zone_key &&
3811 result == ISC_R_FILENOTFOUND)
3812 level = ISC_LOG_DEBUG(1);
3813 dns_zone_log(zone, level,
3814 "loading from master file %s failed: %s",
3816 dns_result_totext(result));
3817 nomaster = ISC_TRUE;
3820 if (zone->type != dns_zone_key)
3824 dns_zone_log(zone, ISC_LOG_DEBUG(2),
3825 "number of nodes in database: %u",
3826 dns_db_nodecount(db));
3828 if (result == DNS_R_SEENINCLUDE)
3829 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3831 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3834 * If there's no master file for a key zone, then the zone is new:
3835 * create an SOA record. (We do this now, instead of later, so that
3836 * if there happens to be a journal file, we can roll forward from
3837 * a sane starting point.)
3839 if (nomaster && zone->type == dns_zone_key) {
3840 result = add_soa(zone, db);
3841 if (result != ISC_R_SUCCESS)
3846 * Apply update log, if any, on initial load.
3848 if (zone->journal != NULL &&
3849 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
3850 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
3852 if (zone->type == dns_zone_master &&
3853 (zone->update_acl != NULL || zone->ssutable != NULL))
3854 options = DNS_JOURNALOPT_RESIGN;
3857 result = dns_journal_rollforward2(zone->mctx, db, options,
3858 zone->sigresigninginterval,
3860 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
3861 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
3862 result != ISC_R_RANGE) {
3863 dns_zone_log(zone, ISC_LOG_ERROR,
3864 "journal rollforward failed: %s",
3865 dns_result_totext(result));
3870 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
3871 dns_zone_log(zone, ISC_LOG_ERROR,
3872 "journal rollforward failed: "
3873 "journal out of sync with zone");
3876 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3877 "journal rollforward completed "
3879 dns_result_totext(result));
3880 if (result == ISC_R_SUCCESS)
3881 needdump = ISC_TRUE;
3885 * Obtain ns, soa and cname counts for top of zone.
3888 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
3889 &refresh, &retry, &expire, &minimum,
3891 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
3892 dns_zone_log(zone, ISC_LOG_ERROR,
3893 "could not find NS and/or SOA records");
3897 * Check to make sure the journal is up to date, and remove the
3898 * journal file if it isn't, as we wouldn't be able to apply
3899 * updates otherwise.
3901 if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) &&
3902 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
3903 isc_uint32_t jserial;
3904 dns_journal_t *journal = NULL;
3906 result = dns_journal_open(zone->mctx, zone->journal,
3907 DNS_JOURNAL_READ, &journal);
3908 if (result == ISC_R_SUCCESS) {
3909 jserial = dns_journal_last_serial(journal);
3910 dns_journal_destroy(&journal);
3913 result = ISC_R_SUCCESS;
3916 if (jserial != serial) {
3917 dns_zone_log(zone, ISC_LOG_INFO,
3918 "journal file is out of date: "
3919 "removing journal file");
3920 if (remove(zone->journal) < 0 && errno != ENOENT) {
3921 char strbuf[ISC_STRERRORSIZE];
3922 isc__strerror(errno, strbuf, sizeof(strbuf));
3923 isc_log_write(dns_lctx,
3924 DNS_LOGCATEGORY_GENERAL,
3927 "unable to remove journal "
3929 zone->journal, strbuf);
3934 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
3937 * Master / Slave / Stub zones require both NS and SOA records at
3938 * the top of the zone.
3941 switch (zone->type) {
3943 case dns_zone_master:
3944 case dns_zone_slave:
3946 case dns_zone_redirect:
3947 if (soacount != 1) {
3948 dns_zone_log(zone, ISC_LOG_ERROR,
3949 "has %d SOA records", soacount);
3950 result = DNS_R_BADZONE;
3953 dns_zone_log(zone, ISC_LOG_ERROR,
3954 "has no NS records");
3955 result = DNS_R_BADZONE;
3957 if (result != ISC_R_SUCCESS)
3959 if (zone->type == dns_zone_master && errors != 0) {
3960 result = DNS_R_BADZONE;
3963 if (zone->type != dns_zone_stub &&
3964 zone->type != dns_zone_redirect) {
3965 result = check_nsec3param(zone, db);
3966 if (result != ISC_R_SUCCESS)
3969 if (zone->type == dns_zone_master &&
3970 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
3971 !integrity_checks(zone, db)) {
3972 result = DNS_R_BADZONE;
3975 if (zone->type == dns_zone_master &&
3976 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
3977 !zone_check_dup(zone, db)) {
3978 result = DNS_R_BADZONE;
3982 if (zone->db != NULL) {
3983 unsigned int oldsoacount;
3986 * This is checked in zone_replacedb() for slave zones
3987 * as they don't reload from disk.
3989 result = zone_get_from_db(zone, zone->db, NULL,
3990 &oldsoacount, &oldserial,
3991 NULL, NULL, NULL, NULL,
3993 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3994 RUNTIME_CHECK(soacount > 0U);
3995 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
3996 !isc_serial_gt(serial, oldserial)) {
3997 isc_uint32_t serialmin, serialmax;
3999 INSIST(zone->type == dns_zone_master);
4001 if (serial == oldserial &&
4002 zone_unchanged(zone->db, db, zone->mctx)) {
4003 dns_zone_log(zone, ISC_LOG_INFO,
4004 "ixfr-from-differences: "
4006 return(ISC_R_SUCCESS);
4009 serialmin = (oldserial + 1) & 0xffffffffU;
4010 serialmax = (oldserial + 0x7fffffffU) &
4012 dns_zone_log(zone, ISC_LOG_ERROR,
4013 "ixfr-from-differences: "
4014 "new serial (%u) out of range "
4015 "[%u - %u]", serial, serialmin,
4017 result = DNS_R_BADZONE;
4019 } else if (!isc_serial_ge(serial, oldserial))
4020 dns_zone_log(zone, ISC_LOG_ERROR,
4021 "zone serial (%u/%u) has gone "
4022 "backwards", serial, oldserial);
4023 else if (serial == oldserial && !hasinclude &&
4024 strcmp(zone->db_argv[0], "_builtin") != 0)
4025 dns_zone_log(zone, ISC_LOG_ERROR,
4026 "zone serial (%u) unchanged. "
4027 "zone may fail to transfer "
4028 "to slaves.", serial);
4031 if (zone->type == dns_zone_master &&
4032 (zone->update_acl != NULL || zone->ssutable != NULL) &&
4033 zone->sigresigninginterval < (3 * refresh) &&
4034 dns_db_issecure(db))
4036 dns_zone_log(zone, ISC_LOG_WARNING,
4037 "sig-re-signing-interval less than "
4041 zone->refresh = RANGE(refresh,
4042 zone->minrefresh, zone->maxrefresh);
4043 zone->retry = RANGE(retry,
4044 zone->minretry, zone->maxretry);
4045 zone->expire = RANGE(expire, zone->refresh + zone->retry,
4047 zone->minimum = minimum;
4048 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
4050 if (zone->type == dns_zone_slave ||
4051 zone->type == dns_zone_stub ||
4052 (zone->type == dns_zone_redirect &&
4053 zone->masters != NULL)) {
4057 result = isc_file_getmodtime(zone->journal, &t);
4058 if (result != ISC_R_SUCCESS)
4059 result = isc_file_getmodtime(zone->masterfile,
4061 if (result == ISC_R_SUCCESS)
4062 DNS_ZONE_TIME_ADD(&t, zone->expire,
4065 DNS_ZONE_TIME_ADD(&now, zone->retry,
4068 delay = isc_random_jitter(zone->retry,
4069 (zone->retry * 3) / 4);
4070 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
4071 if (isc_time_compare(&zone->refreshtime,
4072 &zone->expiretime) >= 0)
4073 zone->refreshtime = now;
4079 result = sync_keyzone(zone, db);
4080 if (result != ISC_R_SUCCESS)
4085 UNEXPECTED_ERROR(__FILE__, __LINE__,
4086 "unexpected zone type %d", zone->type);
4087 result = ISC_R_UNEXPECTED;
4092 * Check for weak DNSKEY's.
4094 if (zone->type == dns_zone_master)
4095 zone_check_dnskeys(zone, db);
4098 * Schedule DNSSEC key refresh.
4100 if (zone->type == dns_zone_master &&
4101 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
4102 zone->refreshkeytime = now;
4105 /* destroy notification example. */
4107 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
4108 DNS_EVENT_DBDESTROYED,
4109 dns_zonemgr_dbdestroyed,
4111 sizeof(isc_event_t));
4112 dns_db_ondestroy(db, zone->task, &e);
4116 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4117 if (zone->db != NULL) {
4118 result = zone_replacedb(zone, db, ISC_FALSE);
4119 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4120 if (result != ISC_R_SUCCESS)
4123 zone_attachdb(zone, db);
4124 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4125 DNS_ZONE_SETFLAG(zone,
4126 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
4127 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
4130 if (zone->secure->db == NULL)
4131 zone_send_securedb(zone, ISC_FALSE, db);
4133 zone_send_secureserial(zone, ISC_FALSE, serial);
4138 * Finished loading inline-signing zone; need to get status
4139 * from the raw side now.
4141 if (zone->type == dns_zone_master && inline_secure(zone))
4142 maybe_send_secure(zone);
4145 result = ISC_R_SUCCESS;
4148 if (zone->type == dns_zone_key)
4149 zone_needdump(zone, 30);
4151 zone_needdump(zone, DNS_DUMP_DELAY);
4154 if (zone->task != NULL) {
4155 if (zone->type == dns_zone_master) {
4156 set_resigntime(zone);
4157 resume_signingwithkey(zone);
4158 resume_addnsec3chain(zone);
4161 if (zone->type == dns_zone_master &&
4162 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
4163 dns_zone_isdynamic(zone, ISC_FALSE) &&
4164 dns_db_issecure(db)) {
4166 dns_fixedname_t fixed;
4167 dns_rdataset_t next;
4169 dns_rdataset_init(&next);
4170 dns_fixedname_init(&fixed);
4171 name = dns_fixedname_name(&fixed);
4173 result = dns_db_getsigningtime(db, &next, name);
4174 if (result == ISC_R_SUCCESS) {
4175 isc_stdtime_t timenow;
4176 char namebuf[DNS_NAME_FORMATSIZE];
4177 char typebuf[DNS_RDATATYPE_FORMATSIZE];
4179 isc_stdtime_get(&timenow);
4180 dns_name_format(name, namebuf, sizeof(namebuf));
4181 dns_rdatatype_format(next.covers,
4182 typebuf, sizeof(typebuf));
4183 dns_zone_log(zone, ISC_LOG_DEBUG(3),
4184 "next resign: %s/%s in %d seconds",
4186 next.resign - timenow);
4187 dns_rdataset_disassociate(&next);
4189 dns_zone_log(zone, ISC_LOG_WARNING,
4190 "signed dynamic zone has no "
4191 "resign event scheduled");
4194 zone_settimer(zone, &now);
4197 if (! dns_db_ispersistent(db))
4198 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
4199 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
4201 zone->loadtime = loadtime;
4202 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
4206 if (zone->type == dns_zone_slave ||
4207 zone->type == dns_zone_stub ||
4208 zone->type == dns_zone_key ||
4209 (zone->type == dns_zone_redirect && zone->masters != NULL)) {
4210 if (zone->journal != NULL)
4211 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
4212 if (zone->masterfile != NULL)
4213 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
4215 /* Mark the zone for immediate refresh. */
4216 zone->refreshtime = now;
4217 if (zone->task != NULL)
4218 zone_settimer(zone, &now);
4219 result = ISC_R_SUCCESS;
4220 } else if (zone->type == dns_zone_master ||
4221 zone->type == dns_zone_redirect) {
4222 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND))
4223 dns_zone_log(zone, ISC_LOG_ERROR,
4224 "not loaded due to errors.");
4225 else if (zone->type == dns_zone_master)
4226 result = ISC_R_SUCCESS;
4232 static isc_boolean_t
4233 exit_check(dns_zone_t *zone) {
4235 REQUIRE(LOCKED_ZONE(zone));
4237 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
4241 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
4243 INSIST(isc_refcount_current(&zone->erefs) == 0);
4249 static isc_boolean_t
4250 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
4251 dns_name_t *name, isc_boolean_t logit)
4253 isc_result_t result;
4254 char namebuf[DNS_NAME_FORMATSIZE];
4255 char altbuf[DNS_NAME_FORMATSIZE];
4256 dns_fixedname_t fixed;
4257 dns_name_t *foundname;
4260 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
4263 if (zone->type == dns_zone_master)
4264 level = ISC_LOG_ERROR;
4266 level = ISC_LOG_WARNING;
4268 dns_fixedname_init(&fixed);
4269 foundname = dns_fixedname_name(&fixed);
4271 result = dns_db_find(db, name, version, dns_rdatatype_a,
4272 0, 0, NULL, foundname, NULL, NULL);
4273 if (result == ISC_R_SUCCESS)
4276 if (result == DNS_R_NXRRSET) {
4277 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
4278 0, 0, NULL, foundname, NULL, NULL);
4279 if (result == ISC_R_SUCCESS)
4283 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
4284 result == DNS_R_EMPTYNAME) {
4286 dns_name_format(name, namebuf, sizeof namebuf);
4287 dns_zone_log(zone, level, "NS '%s' has no address "
4288 "records (A or AAAA)", namebuf);
4293 if (result == DNS_R_CNAME) {
4295 dns_name_format(name, namebuf, sizeof namebuf);
4296 dns_zone_log(zone, level, "NS '%s' is a CNAME "
4297 "(illegal)", namebuf);
4302 if (result == DNS_R_DNAME) {
4304 dns_name_format(name, namebuf, sizeof namebuf);
4305 dns_name_format(foundname, altbuf, sizeof altbuf);
4306 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
4307 "'%s' (illegal)", namebuf, altbuf);
4316 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
4317 dns_dbversion_t *version, unsigned int *nscount,
4318 unsigned int *errors, isc_boolean_t logit)
4320 isc_result_t result;
4321 unsigned int count = 0;
4322 unsigned int ecount = 0;
4323 dns_rdataset_t rdataset;
4327 dns_rdataset_init(&rdataset);
4328 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
4329 dns_rdatatype_none, 0, &rdataset, NULL);
4330 if (result == ISC_R_NOTFOUND) {
4331 INSIST(!dns_rdataset_isassociated(&rdataset));
4334 if (result != ISC_R_SUCCESS) {
4335 INSIST(!dns_rdataset_isassociated(&rdataset));
4336 goto invalidate_rdataset;
4339 result = dns_rdataset_first(&rdataset);
4340 while (result == ISC_R_SUCCESS) {
4341 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
4342 (zone->type == dns_zone_master ||
4343 zone->type == dns_zone_slave)) {
4344 dns_rdata_init(&rdata);
4345 dns_rdataset_current(&rdataset, &rdata);
4346 result = dns_rdata_tostruct(&rdata, &ns, NULL);
4347 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4348 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
4349 !zone_check_ns(zone, db, version, &ns.name, logit))
4353 result = dns_rdataset_next(&rdataset);
4355 dns_rdataset_disassociate(&rdataset);
4358 if (nscount != NULL)
4363 result = ISC_R_SUCCESS;
4365 invalidate_rdataset:
4366 dns_rdataset_invalidate(&rdataset);
4372 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4373 unsigned int *soacount,
4374 isc_uint32_t *serial, isc_uint32_t *refresh,
4375 isc_uint32_t *retry, isc_uint32_t *expire,
4376 isc_uint32_t *minimum)
4378 isc_result_t result;
4380 dns_rdataset_t rdataset;
4381 dns_rdata_t rdata = DNS_RDATA_INIT;
4382 dns_rdata_soa_t soa;
4384 dns_rdataset_init(&rdataset);
4385 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
4386 dns_rdatatype_none, 0, &rdataset, NULL);
4387 if (result == ISC_R_NOTFOUND) {
4388 INSIST(!dns_rdataset_isassociated(&rdataset));
4389 if (soacount != NULL)
4393 if (refresh != NULL)
4399 if (minimum != NULL)
4401 result = ISC_R_SUCCESS;
4402 goto invalidate_rdataset;
4404 if (result != ISC_R_SUCCESS) {
4405 INSIST(!dns_rdataset_isassociated(&rdataset));
4406 goto invalidate_rdataset;
4410 result = dns_rdataset_first(&rdataset);
4411 while (result == ISC_R_SUCCESS) {
4412 dns_rdata_init(&rdata);
4413 dns_rdataset_current(&rdataset, &rdata);
4416 result = dns_rdata_tostruct(&rdata, &soa, NULL);
4417 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4420 result = dns_rdataset_next(&rdataset);
4421 dns_rdata_reset(&rdata);
4423 dns_rdataset_disassociate(&rdataset);
4425 if (soacount != NULL)
4430 *serial = soa.serial;
4431 if (refresh != NULL)
4432 *refresh = soa.refresh;
4436 *expire = soa.expire;
4437 if (minimum != NULL)
4438 *minimum = soa.minimum;
4440 if (soacount != NULL)
4444 if (refresh != NULL)
4450 if (minimum != NULL)
4454 result = ISC_R_SUCCESS;
4456 invalidate_rdataset:
4457 dns_rdataset_invalidate(&rdataset);
4463 * zone must be locked.
4466 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
4467 unsigned int *soacount, isc_uint32_t *serial,
4468 isc_uint32_t *refresh, isc_uint32_t *retry,
4469 isc_uint32_t *expire, isc_uint32_t *minimum,
4470 unsigned int *errors)
4472 isc_result_t result;
4473 isc_result_t answer = ISC_R_SUCCESS;
4474 dns_dbversion_t *version = NULL;
4477 REQUIRE(db != NULL);
4478 REQUIRE(zone != NULL);
4480 dns_db_currentversion(db, &version);
4483 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
4484 if (result != ISC_R_SUCCESS) {
4489 if (nscount != NULL || errors != NULL) {
4490 result = zone_count_ns_rr(zone, db, node, version,
4491 nscount, errors, ISC_TRUE);
4492 if (result != ISC_R_SUCCESS)
4496 if (soacount != NULL || serial != NULL || refresh != NULL
4497 || retry != NULL || expire != NULL || minimum != NULL) {
4498 result = zone_load_soa_rr(db, node, version, soacount,
4499 serial, refresh, retry, expire,
4501 if (result != ISC_R_SUCCESS)
4505 dns_db_detachnode(db, &node);
4507 dns_db_closeversion(db, &version, ISC_FALSE);
4513 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
4514 REQUIRE(DNS_ZONE_VALID(source));
4515 REQUIRE(target != NULL && *target == NULL);
4516 isc_refcount_increment(&source->erefs, NULL);
4521 dns_zone_detach(dns_zone_t **zonep) {
4523 dns_zone_t *raw = NULL;
4524 dns_zone_t *secure = NULL;
4526 isc_boolean_t free_now = ISC_FALSE;
4528 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4532 isc_refcount_decrement(&zone->erefs, &refs);
4537 * We just detached the last external reference.
4539 if (zone->task != NULL) {
4541 * This zone is being managed. Post
4542 * its control event and let it clean
4543 * up synchronously in the context of
4546 isc_event_t *ev = &zone->ctlevent;
4547 isc_task_send(zone->task, &ev);
4550 * This zone is not being managed; it has
4551 * no task and can have no outstanding
4552 * events. Free it immediately.
4555 * Unmanaged zones should not have non-null views;
4556 * we have no way of detaching from the view here
4557 * without causing deadlock because this code is called
4558 * with the view already locked.
4560 INSIST(zone->view == NULL);
4561 free_now = ISC_TRUE;
4564 secure = zone->secure;
4565 zone->secure = NULL;
4572 dns_zone_detach(&raw);
4574 dns_zone_idetach(&secure);
4580 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4581 REQUIRE(DNS_ZONE_VALID(source));
4582 REQUIRE(target != NULL && *target == NULL);
4584 zone_iattach(source, target);
4585 UNLOCK_ZONE(source);
4589 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4592 * 'source' locked by caller.
4594 REQUIRE(LOCKED_ZONE(source));
4595 REQUIRE(DNS_ZONE_VALID(source));
4596 REQUIRE(target != NULL && *target == NULL);
4597 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
4599 INSIST(source->irefs != 0);
4604 zone_idetach(dns_zone_t **zonep) {
4608 * 'zone' locked by caller.
4610 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4612 REQUIRE(LOCKED_ZONE(*zonep));
4615 INSIST(zone->irefs > 0);
4617 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
4621 dns_zone_idetach(dns_zone_t **zonep) {
4623 isc_boolean_t free_needed;
4625 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4630 INSIST(zone->irefs > 0);
4632 free_needed = exit_check(zone);
4639 dns_zone_getmctx(dns_zone_t *zone) {
4640 REQUIRE(DNS_ZONE_VALID(zone));
4642 return (zone->mctx);
4646 dns_zone_getmgr(dns_zone_t *zone) {
4647 REQUIRE(DNS_ZONE_VALID(zone));
4649 return (zone->zmgr);
4653 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
4654 REQUIRE(DNS_ZONE_VALID(zone));
4658 DNS_ZONE_SETFLAG(zone, flags);
4660 DNS_ZONE_CLRFLAG(zone, flags);
4665 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
4667 REQUIRE(DNS_ZONE_VALID(zone));
4671 zone->options |= option;
4673 zone->options &= ~option;
4678 dns_zone_getoptions(dns_zone_t *zone) {
4680 REQUIRE(DNS_ZONE_VALID(zone));
4682 return (zone->options);
4686 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
4688 REQUIRE(DNS_ZONE_VALID(zone));
4692 zone->keyopts |= keyopt;
4694 zone->keyopts &= ~keyopt;
4699 dns_zone_getkeyopts(dns_zone_t *zone) {
4701 REQUIRE(DNS_ZONE_VALID(zone));
4703 return (zone->keyopts);
4707 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4708 REQUIRE(DNS_ZONE_VALID(zone));
4711 zone->xfrsource4 = *xfrsource;
4714 return (ISC_R_SUCCESS);
4718 dns_zone_getxfrsource4(dns_zone_t *zone) {
4719 REQUIRE(DNS_ZONE_VALID(zone));
4720 return (&zone->xfrsource4);
4724 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4725 REQUIRE(DNS_ZONE_VALID(zone));
4728 zone->xfrsource6 = *xfrsource;
4731 return (ISC_R_SUCCESS);
4735 dns_zone_getxfrsource6(dns_zone_t *zone) {
4736 REQUIRE(DNS_ZONE_VALID(zone));
4737 return (&zone->xfrsource6);
4741 dns_zone_setaltxfrsource4(dns_zone_t *zone,
4742 const isc_sockaddr_t *altxfrsource)
4744 REQUIRE(DNS_ZONE_VALID(zone));
4747 zone->altxfrsource4 = *altxfrsource;
4750 return (ISC_R_SUCCESS);
4754 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
4755 REQUIRE(DNS_ZONE_VALID(zone));
4756 return (&zone->altxfrsource4);
4760 dns_zone_setaltxfrsource6(dns_zone_t *zone,
4761 const isc_sockaddr_t *altxfrsource)
4763 REQUIRE(DNS_ZONE_VALID(zone));
4766 zone->altxfrsource6 = *altxfrsource;
4769 return (ISC_R_SUCCESS);
4773 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
4774 REQUIRE(DNS_ZONE_VALID(zone));
4775 return (&zone->altxfrsource6);
4779 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4780 REQUIRE(DNS_ZONE_VALID(zone));
4783 zone->notifysrc4 = *notifysrc;
4786 return (ISC_R_SUCCESS);
4790 dns_zone_getnotifysrc4(dns_zone_t *zone) {
4791 REQUIRE(DNS_ZONE_VALID(zone));
4792 return (&zone->notifysrc4);
4796 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4797 REQUIRE(DNS_ZONE_VALID(zone));
4800 zone->notifysrc6 = *notifysrc;
4803 return (ISC_R_SUCCESS);
4807 dns_zone_getnotifysrc6(dns_zone_t *zone) {
4808 REQUIRE(DNS_ZONE_VALID(zone));
4809 return (&zone->notifysrc6);
4812 static isc_boolean_t
4813 same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
4818 for (i = 0; i < count; i++)
4819 if (!isc_sockaddr_equal(&old[i], &new[i]))
4824 static isc_boolean_t
4825 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
4828 if (old == NULL && new == NULL)
4830 if (old == NULL || new == NULL)
4833 for (i = 0; i < count; i++) {
4834 if (old[i] == NULL && new[i] == NULL)
4836 if (old[i] == NULL || new[i] == NULL ||
4837 !dns_name_equal(old[i], new[i]))
4844 clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp,
4845 unsigned int *countp, isc_mem_t *mctx)
4848 isc_sockaddr_t *addrs;
4849 dns_name_t **keynames;
4851 REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL);
4857 keynames = *keynamesp;
4861 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
4863 if (keynames != NULL) {
4865 for (i = 0; i < count; i++) {
4866 if (keynames[i] != NULL) {
4867 dns_name_free(keynames[i], mctx);
4868 isc_mem_put(mctx, keynames[i],
4869 sizeof(dns_name_t));
4873 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
4878 set_addrkeylist(unsigned int count,
4879 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
4880 dns_name_t **names, dns_name_t ***newnamesp,
4883 isc_result_t result;
4884 isc_sockaddr_t *newaddrs = NULL;
4885 dns_name_t **newnames = NULL;
4888 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
4889 REQUIRE(newnamesp != NULL && *newnamesp == NULL);
4891 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
4892 if (newaddrs == NULL)
4893 return (ISC_R_NOMEMORY);
4894 memcpy(newaddrs, addrs, count * sizeof(*newaddrs));
4897 if (names != NULL) {
4898 newnames = isc_mem_get(mctx, count * sizeof(*newnames));
4899 if (newnames == NULL) {
4900 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
4901 return (ISC_R_NOMEMORY);
4903 for (i = 0; i < count; i++)
4905 for (i = 0; i < count; i++) {
4906 if (names[i] != NULL) {
4907 newnames[i] = isc_mem_get(mctx,
4908 sizeof(dns_name_t));
4909 if (newnames[i] == NULL)
4911 dns_name_init(newnames[i], NULL);
4912 result = dns_name_dup(names[i], mctx,
4914 if (result != ISC_R_SUCCESS) {
4916 for (i = 0; i < count; i++)
4917 if (newnames[i] != NULL)
4921 isc_mem_put(mctx, newaddrs,
4922 count * sizeof(*newaddrs));
4923 isc_mem_put(mctx, newnames,
4924 count * sizeof(*newnames));
4925 return (ISC_R_NOMEMORY);
4931 *newaddrsp = newaddrs;
4932 *newnamesp = newnames;
4933 return (ISC_R_SUCCESS);
4937 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
4940 return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count));
4944 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
4945 dns_name_t **keynames, isc_uint32_t count)
4947 isc_result_t result;
4948 isc_sockaddr_t *newaddrs = NULL;
4949 dns_name_t **newnames = NULL;
4951 REQUIRE(DNS_ZONE_VALID(zone));
4952 REQUIRE(count == 0 || notify != NULL);
4953 if (keynames != NULL)
4954 REQUIRE(count != 0);
4958 if (count == zone->notifycnt &&
4959 same_addrs(zone->notify, notify, count) &&
4960 same_keynames(zone->notifykeynames, keynames, count))
4963 clear_addresskeylist(&zone->notify, &zone->notifykeynames,
4964 &zone->notifycnt, zone->mctx);
4970 * Set up the notify and notifykey lists
4972 result = set_addrkeylist(count, notify, &newaddrs,
4973 keynames, &newnames, zone->mctx);
4974 if (result != ISC_R_SUCCESS)
4978 * Everything is ok so attach to the zone.
4980 zone->notify = newaddrs;
4981 zone->notifykeynames = newnames;
4982 zone->notifycnt = count;
4985 return (ISC_R_SUCCESS);
4989 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
4992 isc_result_t result;
4994 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
4999 dns_zone_setmasterswithkeys(dns_zone_t *zone,
5000 const isc_sockaddr_t *masters,
5001 dns_name_t **keynames,
5004 isc_result_t result = ISC_R_SUCCESS;
5005 isc_sockaddr_t *newaddrs = NULL;
5006 dns_name_t **newnames = NULL;
5007 isc_boolean_t *newok;
5010 REQUIRE(DNS_ZONE_VALID(zone));
5011 REQUIRE(count == 0 || masters != NULL);
5012 if (keynames != NULL) {
5013 REQUIRE(count != 0);
5018 * The refresh code assumes that 'masters' wouldn't change under it.
5019 * If it will change then kill off any current refresh in progress
5020 * and update the masters info. If it won't change then we can just
5023 if (count != zone->masterscnt ||
5024 !same_addrs(zone->masters, masters, count) ||
5025 !same_keynames(zone->masterkeynames, keynames, count)) {
5026 if (zone->request != NULL)
5027 dns_request_cancel(zone->request);
5032 * This needs to happen before clear_addresskeylist() sets
5033 * zone->masterscnt to 0:
5035 if (zone->mastersok != NULL) {
5036 isc_mem_put(zone->mctx, zone->mastersok,
5037 zone->masterscnt * sizeof(isc_boolean_t));
5038 zone->mastersok = NULL;
5040 clear_addresskeylist(&zone->masters, &zone->masterkeynames,
5041 &zone->masterscnt, zone->mctx);
5043 * If count == 0, don't allocate any space for masters, mastersok or
5044 * keynames so internally, those pointers are NULL if count == 0
5050 * mastersok must contain count elements
5052 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
5053 if (newok == NULL) {
5054 result = ISC_R_NOMEMORY;
5055 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
5058 for (i = 0; i < count; i++)
5059 newok[i] = ISC_FALSE;
5062 * Now set up the masters and masterkey lists
5064 result = set_addrkeylist(count, masters, &newaddrs,
5065 keynames, &newnames, zone->mctx);
5066 if (result != ISC_R_SUCCESS) {
5067 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
5072 * Everything is ok so attach to the zone.
5074 zone->curmaster = 0;
5075 zone->mastersok = newok;
5076 zone->masters = newaddrs;
5077 zone->masterkeynames = newnames;
5078 zone->masterscnt = count;
5079 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
5087 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
5088 isc_result_t result = ISC_R_SUCCESS;
5090 REQUIRE(DNS_ZONE_VALID(zone));
5092 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5093 if (zone->db == NULL)
5094 result = DNS_R_NOTLOADED;
5096 dns_db_attach(zone->db, dpb);
5097 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5103 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
5104 REQUIRE(DNS_ZONE_VALID(zone));
5105 REQUIRE(zone->type == dns_zone_staticstub);
5107 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
5108 REQUIRE(zone->db == NULL);
5109 dns_db_attach(db, &zone->db);
5110 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
5114 * Co-ordinates the starting of routine jobs.
5118 dns_zone_maintenance(dns_zone_t *zone) {
5119 const char me[] = "dns_zone_maintenance";
5122 REQUIRE(DNS_ZONE_VALID(zone));
5127 zone_settimer(zone, &now);
5131 static inline isc_boolean_t
5132 was_dumping(dns_zone_t *zone) {
5133 isc_boolean_t dumping;
5135 REQUIRE(LOCKED_ZONE(zone));
5137 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
5138 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
5140 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
5141 isc_time_settoepoch(&zone->dumptime);
5147 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
5148 isc_mem_t *mctx, unsigned int maxkeys,
5149 dst_key_t **keys, unsigned int *nkeys)
5151 isc_result_t result;
5152 dns_dbnode_t *node = NULL;
5153 const char *directory = dns_zone_getkeydirectory(zone);
5155 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
5156 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
5157 directory, mctx, maxkeys, keys,
5159 if (result == ISC_R_NOTFOUND)
5160 result = ISC_R_SUCCESS;
5163 dns_db_detachnode(db, &node);
5168 offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
5169 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
5171 isc_result_t result;
5173 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
5174 return (ISC_R_SUCCESS);
5175 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
5177 if (result != ISC_R_SUCCESS)
5179 rdata->flags |= DNS_RDATA_OFFLINE;
5180 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
5182 zonediff->offline = ISC_TRUE;
5187 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
5192 zone->key_expiry = when;
5194 dns_zone_log(zone, ISC_LOG_ERROR,
5195 "DNSKEY RRSIG(s) have expired");
5196 isc_time_settoepoch(&zone->keywarntime);
5197 } else if (when < now + 7 * 24 * 3600) {
5199 isc_time_set(&t, when, 0);
5200 isc_time_formattimestamp(&t, timebuf, 80);
5201 dns_zone_log(zone, ISC_LOG_WARNING,
5202 "DNSKEY RRSIG(s) will expire within 7 days: %s",
5205 delta--; /* loop prevention */
5206 delta /= 24 * 3600; /* to whole days */
5207 delta *= 24 * 3600; /* to seconds */
5208 isc_time_set(&zone->keywarntime, when - delta, 0);
5210 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
5211 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
5212 dns_zone_log(zone, ISC_LOG_NOTICE,
5213 "setting keywarntime to %s", timebuf);
5218 * Helper function to del_sigs(). We don't want to delete RRSIGs that
5221 static isc_boolean_t
5222 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) {
5226 * It's okay to delete a signature if there is an active ZSK
5227 * with the same algorithm
5229 for (i = 0; i < nkeys; i++) {
5230 if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) &&
5231 (dst_key_isprivate(keys[i])) && !KSK(keys[i]))
5236 * Failing that, it is *not* okay to delete a signature
5237 * if the associated public key is still in the DNSKEY RRset
5239 for (i = 0; i < nkeys; i++) {
5240 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
5241 (rrsig_ptr->keyid == dst_key_id(keys[i])))
5246 * But if the key is gone, then go ahead.
5252 * Delete expired RRsigs and any RRsigs we are about to re-sign.
5253 * See also update.c:del_keysigs().
5256 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5257 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
5258 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
5260 isc_result_t result;
5261 dns_dbnode_t *node = NULL;
5262 dns_rdataset_t rdataset;
5264 dns_rdata_rrsig_t rrsig;
5265 isc_boolean_t found, changed;
5266 isc_int64_t warn = 0, maybe = 0;
5268 dns_rdataset_init(&rdataset);
5270 if (type == dns_rdatatype_nsec3)
5271 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5273 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5274 if (result == ISC_R_NOTFOUND)
5275 return (ISC_R_SUCCESS);
5276 if (result != ISC_R_SUCCESS)
5278 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
5279 (isc_stdtime_t) 0, &rdataset, NULL);
5280 dns_db_detachnode(db, &node);
5282 if (result == ISC_R_NOTFOUND) {
5283 INSIST(!dns_rdataset_isassociated(&rdataset));
5284 return (ISC_R_SUCCESS);
5286 if (result != ISC_R_SUCCESS) {
5287 INSIST(!dns_rdataset_isassociated(&rdataset));
5291 changed = ISC_FALSE;
5292 for (result = dns_rdataset_first(&rdataset);
5293 result == ISC_R_SUCCESS;
5294 result = dns_rdataset_next(&rdataset)) {
5295 dns_rdata_t rdata = DNS_RDATA_INIT;
5297 dns_rdataset_current(&rdataset, &rdata);
5298 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5299 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5301 if (type != dns_rdatatype_dnskey) {
5302 if (delsig_ok(&rrsig, keys, nkeys)) {
5303 result = update_one_rr(db, ver, zonediff->diff,
5304 DNS_DIFFOP_DELRESIGN, name,
5305 rdataset.ttl, &rdata);
5308 if (result != ISC_R_SUCCESS)
5312 * At this point, we've got an RRSIG,
5313 * which is signed by an inactive key.
5314 * An administrator needs to provide a new
5315 * key/alg, but until that time, we want to
5316 * keep the old RRSIG. Marking the key as
5317 * offline will prevent us spinning waiting
5318 * for the private part.
5321 result = offline(db, ver, zonediff,
5325 if (result != ISC_R_SUCCESS)
5330 * Log the key id and algorithm of
5331 * the inactive key with no replacement
5333 if (zone->log_key_expired_timer <= now) {
5334 char origin[DNS_NAME_FORMATSIZE];
5335 char algbuf[DNS_NAME_FORMATSIZE];
5336 dns_name_format(&zone->origin, origin,
5338 dns_secalg_format(rrsig.algorithm,
5341 dns_zone_log(zone, ISC_LOG_WARNING,
5343 "missing or inactive "
5344 "and has no replacement: "
5345 "retaining signatures.",
5348 zone->log_key_expired_timer = now +
5356 * RRSIG(DNSKEY) requires special processing.
5359 for (i = 0; i < nkeys; i++) {
5360 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
5361 rrsig.keyid == dst_key_id(keys[i])) {
5364 * Mark offline RRSIG(DNSKEY).
5365 * We want the earliest offline expire time
5366 * iff there is a new offline signature.
5368 if (!dst_key_isprivate(keys[i])) {
5369 isc_int64_t timeexpire =
5370 dns_time64_from32(rrsig.timeexpire);
5371 if (warn != 0 && warn > timeexpire)
5373 if (rdata.flags & DNS_RDATA_OFFLINE) {
5381 if (warn == 0 || warn > timeexpire)
5383 result = offline(db, ver, zonediff,
5388 result = update_one_rr(db, ver, zonediff->diff,
5389 DNS_DIFFOP_DELRESIGN,
5397 * If there is not a matching DNSKEY then
5401 result = update_one_rr(db, ver, zonediff->diff,
5402 DNS_DIFFOP_DELRESIGN, name,
5403 rdataset.ttl, &rdata);
5404 if (result != ISC_R_SUCCESS)
5408 if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0)
5409 dns_db_resigned(db, &rdataset, ver);
5411 dns_rdataset_disassociate(&rdataset);
5412 if (result == ISC_R_NOMORE)
5413 result = ISC_R_SUCCESS;
5415 #if defined(STDTIME_ON_32BITS)
5416 isc_stdtime_t stdwarn = (isc_stdtime_t)warn;
5417 if (warn == stdwarn)
5419 set_key_expiry_warning(zone, (isc_stdtime_t)warn, now);
5420 #if defined(STDTIME_ON_32BITS)
5422 dns_zone_log(zone, ISC_LOG_ERROR,
5423 "key expiry warning time out of range");
5428 dns_db_detachnode(db, &node);
5433 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5434 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
5435 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
5436 isc_stdtime_t expire, isc_boolean_t check_ksk,
5437 isc_boolean_t keyset_kskonly)
5439 isc_result_t result;
5440 dns_dbnode_t *node = NULL;
5441 dns_rdataset_t rdataset;
5442 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
5443 unsigned char data[1024]; /* XXX */
5444 isc_buffer_t buffer;
5447 dns_rdataset_init(&rdataset);
5448 isc_buffer_init(&buffer, data, sizeof(data));
5450 if (type == dns_rdatatype_nsec3)
5451 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5453 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5454 if (result == ISC_R_NOTFOUND)
5455 return (ISC_R_SUCCESS);
5456 if (result != ISC_R_SUCCESS)
5458 result = dns_db_findrdataset(db, node, ver, type, 0,
5459 (isc_stdtime_t) 0, &rdataset, NULL);
5460 dns_db_detachnode(db, &node);
5461 if (result == ISC_R_NOTFOUND) {
5462 INSIST(!dns_rdataset_isassociated(&rdataset));
5463 return (ISC_R_SUCCESS);
5465 if (result != ISC_R_SUCCESS) {
5466 INSIST(!dns_rdataset_isassociated(&rdataset));
5470 for (i = 0; i < nkeys; i++) {
5471 isc_boolean_t both = ISC_FALSE;
5473 if (!dst_key_isprivate(keys[i]))
5476 if (check_ksk && !REVOKE(keys[i])) {
5477 isc_boolean_t have_ksk, have_nonksk;
5479 have_ksk = ISC_TRUE;
5480 have_nonksk = ISC_FALSE;
5482 have_ksk = ISC_FALSE;
5483 have_nonksk = ISC_TRUE;
5485 for (j = 0; j < nkeys; j++) {
5486 if (j == i || ALG(keys[i]) != ALG(keys[j]))
5488 if (REVOKE(keys[j]))
5491 have_ksk = ISC_TRUE;
5493 have_nonksk = ISC_TRUE;
5494 both = have_ksk && have_nonksk;
5500 if (type == dns_rdatatype_dnskey) {
5501 if (!KSK(keys[i]) && keyset_kskonly)
5503 } else if (KSK(keys[i]))
5505 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
5508 /* Calculate the signature, creating a RRSIG RDATA. */
5509 isc_buffer_clear(&buffer);
5510 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
5511 &inception, &expire,
5512 mctx, &buffer, &sig_rdata));
5513 /* Update the database and journal with the RRSIG. */
5514 /* XXX inefficient - will cause dataset merging */
5515 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
5516 name, rdataset.ttl, &sig_rdata));
5517 dns_rdata_reset(&sig_rdata);
5518 isc_buffer_init(&buffer, data, sizeof(data));
5522 if (dns_rdataset_isassociated(&rdataset))
5523 dns_rdataset_disassociate(&rdataset);
5525 dns_db_detachnode(db, &node);
5530 zone_resigninc(dns_zone_t *zone) {
5531 const char *me = "zone_resigninc";
5532 dns_db_t *db = NULL;
5533 dns_dbversion_t *version = NULL;
5534 dns_diff_t _sig_diff;
5535 zonediff_t zonediff;
5536 dns_fixedname_t fixed;
5538 dns_rdataset_t rdataset;
5539 dns_rdatatype_t covers;
5540 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
5541 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
5542 isc_result_t result;
5543 isc_stdtime_t now, inception, soaexpire, expire, stop;
5544 isc_uint32_t jitter;
5546 unsigned int nkeys = 0;
5547 unsigned int resign;
5551 dns_rdataset_init(&rdataset);
5552 dns_fixedname_init(&fixed);
5553 dns_diff_init(zone->mctx, &_sig_diff);
5554 _sig_diff.resign = zone->sigresigninginterval;
5555 zonediff_init(&zonediff, &_sig_diff);
5558 * Zone is frozen or automatic resigning is disabled.
5559 * Pause for 5 minutes.
5561 if (zone->update_disabled ||
5562 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
5564 result = ISC_R_FAILURE;
5568 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5569 dns_db_attach(zone->db, &db);
5570 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5572 result = dns_db_newversion(db, &version);
5573 if (result != ISC_R_SUCCESS) {
5574 dns_zone_log(zone, ISC_LOG_ERROR,
5575 "zone_resigninc:dns_db_newversion -> %s",
5576 dns_result_totext(result));
5580 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
5582 if (result != ISC_R_SUCCESS) {
5583 dns_zone_log(zone, ISC_LOG_ERROR,
5584 "zone_resigninc:find_zone_keys -> %s",
5585 dns_result_totext(result));
5589 isc_stdtime_get(&now);
5590 inception = now - 3600; /* Allow for clock skew. */
5591 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5593 * Spread out signatures over time if they happen to be
5594 * clumped. We don't do this for each add_sigs() call as
5595 * we still want some clustering to occur.
5597 isc_random_get(&jitter);
5598 expire = soaexpire - jitter % 3600;
5601 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5602 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
5604 name = dns_fixedname_name(&fixed);
5605 result = dns_db_getsigningtime(db, &rdataset, name);
5606 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
5607 dns_zone_log(zone, ISC_LOG_ERROR,
5608 "zone_resigninc:dns_db_getsigningtime -> %s",
5609 dns_result_totext(result));
5613 while (result == ISC_R_SUCCESS) {
5614 resign = rdataset.resign;
5615 covers = rdataset.covers;
5616 dns_rdataset_disassociate(&rdataset);
5619 * Stop if we hit the SOA as that means we have walked the
5620 * entire zone. The SOA record should always be the most
5623 /* XXXMPA increase number of RRsets signed pre call */
5624 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
5628 result = del_sigs(zone, db, version, name, covers, &zonediff,
5629 zone_keys, nkeys, now, ISC_TRUE);
5630 if (result != ISC_R_SUCCESS) {
5631 dns_zone_log(zone, ISC_LOG_ERROR,
5632 "zone_resigninc:del_sigs -> %s",
5633 dns_result_totext(result));
5637 result = add_sigs(db, version, name, covers, zonediff.diff,
5638 zone_keys, nkeys, zone->mctx, inception,
5639 expire, check_ksk, keyset_kskonly);
5640 if (result != ISC_R_SUCCESS) {
5641 dns_zone_log(zone, ISC_LOG_ERROR,
5642 "zone_resigninc:add_sigs -> %s",
5643 dns_result_totext(result));
5646 result = dns_db_getsigningtime(db, &rdataset,
5647 dns_fixedname_name(&fixed));
5648 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
5649 result = ISC_R_SUCCESS;
5652 if (result != ISC_R_SUCCESS)
5653 dns_zone_log(zone, ISC_LOG_ERROR,
5654 "zone_resigninc:dns_db_getsigningtime -> %s",
5655 dns_result_totext(result));
5658 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
5661 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5662 &zonediff, zone_keys, nkeys, now, ISC_TRUE);
5663 if (result != ISC_R_SUCCESS) {
5664 dns_zone_log(zone, ISC_LOG_ERROR,
5665 "zone_resigninc:del_sigs -> %s",
5666 dns_result_totext(result));
5671 * Did we change anything in the zone?
5673 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
5675 * Commit the changes if any key has been marked as offline. */
5676 if (zonediff.offline)
5677 dns_db_closeversion(db, &version, ISC_TRUE);
5681 /* Increment SOA serial if we have made changes */
5682 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
5683 zone->updatemethod);
5684 if (result != ISC_R_SUCCESS) {
5685 dns_zone_log(zone, ISC_LOG_ERROR,
5686 "zone_resigninc:update_soa_serial -> %s",
5687 dns_result_totext(result));
5692 * Generate maximum life time signatures so that the above loop
5693 * termination is sensible.
5695 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5696 zonediff.diff, zone_keys, nkeys, zone->mctx,
5697 inception, soaexpire, check_ksk, keyset_kskonly);
5698 if (result != ISC_R_SUCCESS) {
5699 dns_zone_log(zone, ISC_LOG_ERROR,
5700 "zone_resigninc:add_sigs -> %s",
5701 dns_result_totext(result));
5705 /* Write changes to journal file. */
5706 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
5708 /* Everything has succeeded. Commit the changes. */
5709 dns_db_closeversion(db, &version, ISC_TRUE);
5712 dns_diff_clear(&_sig_diff);
5713 for (i = 0; i < nkeys; i++)
5714 dst_key_free(&zone_keys[i]);
5715 if (version != NULL) {
5716 dns_db_closeversion(zone->db, &version, ISC_FALSE);
5718 } else if (db != NULL)
5720 if (result == ISC_R_SUCCESS) {
5721 set_resigntime(zone);
5723 zone_needdump(zone, DNS_DUMP_DELAY);
5724 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5728 * Something failed. Retry in 5 minutes.
5730 isc_interval_t ival;
5731 isc_interval_set(&ival, 300, 0);
5732 isc_time_nowplusinterval(&zone->resigntime, &ival);
5737 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
5738 dns_name_t *newname, isc_boolean_t bottom)
5740 isc_result_t result;
5741 dns_dbiterator_t *dbit = NULL;
5742 dns_rdatasetiter_t *rdsit = NULL;
5743 dns_dbnode_t *node = NULL;
5745 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
5746 CHECK(dns_dbiterator_seek(dbit, oldname));
5748 result = dns_dbiterator_next(dbit);
5749 if (result == ISC_R_NOMORE)
5750 CHECK(dns_dbiterator_first(dbit));
5751 CHECK(dns_dbiterator_current(dbit, &node, newname));
5752 if (bottom && dns_name_issubdomain(newname, oldname) &&
5753 !dns_name_equal(newname, oldname)) {
5754 dns_db_detachnode(db, &node);
5758 * Is this node empty?
5760 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
5761 result = dns_rdatasetiter_first(rdsit);
5762 dns_db_detachnode(db, &node);
5763 dns_rdatasetiter_destroy(&rdsit);
5764 if (result != ISC_R_NOMORE)
5769 dns_db_detachnode(db, &node);
5771 dns_dbiterator_destroy(&dbit);
5775 static isc_boolean_t
5776 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5777 dns_rdatatype_t type, dst_key_t *key)
5779 isc_result_t result;
5780 dns_rdataset_t rdataset;
5781 dns_rdata_t rdata = DNS_RDATA_INIT;
5782 dns_rdata_rrsig_t rrsig;
5784 dns_rdataset_init(&rdataset);
5785 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
5786 type, 0, &rdataset, NULL);
5787 if (result != ISC_R_SUCCESS) {
5788 INSIST(!dns_rdataset_isassociated(&rdataset));
5791 for (result = dns_rdataset_first(&rdataset);
5792 result == ISC_R_SUCCESS;
5793 result = dns_rdataset_next(&rdataset)) {
5794 dns_rdataset_current(&rdataset, &rdata);
5795 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5796 INSIST(result == ISC_R_SUCCESS);
5797 if (rrsig.algorithm == dst_key_alg(key) &&
5798 rrsig.keyid == dst_key_id(key)) {
5799 dns_rdataset_disassociate(&rdataset);
5802 dns_rdata_reset(&rdata);
5804 dns_rdataset_disassociate(&rdataset);
5809 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5810 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
5813 dns_fixedname_t fixed;
5815 dns_rdata_t rdata = DNS_RDATA_INIT;
5816 isc_result_t result;
5817 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
5819 dns_fixedname_init(&fixed);
5820 next = dns_fixedname_name(&fixed);
5822 CHECK(next_active(db, version, name, next, bottom));
5823 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
5825 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
5832 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
5833 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5834 isc_boolean_t build_nsec, dst_key_t *key,
5835 isc_stdtime_t inception, isc_stdtime_t expire,
5836 unsigned int minimum, isc_boolean_t is_ksk,
5837 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
5838 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
5840 isc_result_t result;
5841 dns_rdatasetiter_t *iterator = NULL;
5842 dns_rdataset_t rdataset;
5843 dns_rdata_t rdata = DNS_RDATA_INIT;
5844 isc_buffer_t buffer;
5845 unsigned char data[1024];
5846 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
5847 seen_nsec3, seen_ds;
5848 isc_boolean_t bottom;
5850 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5851 if (result != ISC_R_SUCCESS) {
5852 if (result == ISC_R_NOTFOUND)
5853 result = ISC_R_SUCCESS;
5857 dns_rdataset_init(&rdataset);
5858 isc_buffer_init(&buffer, data, sizeof(data));
5859 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
5860 seen_nsec3 = seen_ds = ISC_FALSE;
5861 for (result = dns_rdatasetiter_first(iterator);
5862 result == ISC_R_SUCCESS;
5863 result = dns_rdatasetiter_next(iterator)) {
5864 dns_rdatasetiter_current(iterator, &rdataset);
5865 if (rdataset.type == dns_rdatatype_soa)
5866 seen_soa = ISC_TRUE;
5867 else if (rdataset.type == dns_rdatatype_ns)
5869 else if (rdataset.type == dns_rdatatype_ds)
5871 else if (rdataset.type == dns_rdatatype_dname)
5872 seen_dname = ISC_TRUE;
5873 else if (rdataset.type == dns_rdatatype_nsec)
5874 seen_nsec = ISC_TRUE;
5875 else if (rdataset.type == dns_rdatatype_nsec3)
5876 seen_nsec3 = ISC_TRUE;
5877 if (rdataset.type != dns_rdatatype_rrsig)
5879 dns_rdataset_disassociate(&rdataset);
5881 if (result != ISC_R_NOMORE)
5883 if (seen_ns && !seen_soa)
5884 *delegation = ISC_TRUE;
5886 * Going from insecure to NSEC3.
5887 * Don't generate NSEC3 records for NSEC3 records.
5889 if (build_nsec3 && !seen_nsec3 && seen_rr) {
5890 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
5891 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
5896 * Going from insecure to NSEC.
5897 * Don't generate NSEC records for NSEC3 records.
5899 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
5900 /* Build and add NSEC. */
5901 bottom = (seen_ns && !seen_soa) || seen_dname;
5903 * Build a NSEC record except at the origin.
5905 if (!dns_name_equal(name, dns_db_origin(db))) {
5906 CHECK(add_nsec(db, version, name, node, minimum,
5908 /* Count a NSEC generation as a signature generation. */
5912 result = dns_rdatasetiter_first(iterator);
5913 while (result == ISC_R_SUCCESS) {
5914 dns_rdatasetiter_current(iterator, &rdataset);
5915 if (rdataset.type == dns_rdatatype_soa ||
5916 rdataset.type == dns_rdatatype_rrsig)
5918 if (rdataset.type == dns_rdatatype_dnskey) {
5919 if (!is_ksk && keyset_kskonly)
5924 rdataset.type != dns_rdatatype_ds &&
5925 rdataset.type != dns_rdatatype_nsec)
5927 if (signed_with_key(db, node, version, rdataset.type, key))
5929 /* Calculate the signature, creating a RRSIG RDATA. */
5930 isc_buffer_clear(&buffer);
5931 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
5932 &expire, mctx, &buffer, &rdata));
5933 /* Update the database and journal with the RRSIG. */
5934 /* XXX inefficient - will cause dataset merging */
5935 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
5936 name, rdataset.ttl, &rdata));
5937 dns_rdata_reset(&rdata);
5940 dns_rdataset_disassociate(&rdataset);
5941 result = dns_rdatasetiter_next(iterator);
5943 if (result == ISC_R_NOMORE)
5944 result = ISC_R_SUCCESS;
5946 *delegation = ISC_TRUE;
5948 if (dns_rdataset_isassociated(&rdataset))
5949 dns_rdataset_disassociate(&rdataset);
5950 if (iterator != NULL)
5951 dns_rdatasetiter_destroy(&iterator);
5956 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
5959 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5960 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
5962 isc_result_t result;
5963 dns_rdataset_t rdataset;
5964 dns_dbnode_t *node = NULL;
5966 CHECK(dns_db_getoriginnode(db, &node));
5968 dns_rdataset_init(&rdataset);
5969 result = dns_db_findrdataset(db, node, version,
5972 0, &rdataset, NULL);
5973 if (dns_rdataset_isassociated(&rdataset))
5974 dns_rdataset_disassociate(&rdataset);
5975 if (result == ISC_R_NOTFOUND)
5977 if (result != ISC_R_SUCCESS)
5980 CHECK(delete_nsec(db, version, node, name, diff));
5981 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
5983 result = ISC_R_SUCCESS;
5986 dns_db_detachnode(db, &node);
5991 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
5992 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5993 dns_ttl_t minimum, dns_diff_t *diff)
5995 isc_result_t result;
5996 dns_dbnode_t *node = NULL;
5997 dns_rdataset_t rdataset;
5998 dns_rdata_t rdata = DNS_RDATA_INIT;
5999 unsigned char data[5];
6000 isc_boolean_t seen_done = ISC_FALSE;
6001 isc_boolean_t have_rr = ISC_FALSE;
6003 dns_rdataset_init(&rdataset);
6004 result = dns_db_getoriginnode(signing->db, &node);
6005 if (result != ISC_R_SUCCESS)
6008 result = dns_db_findrdataset(signing->db, node, version,
6009 zone->privatetype, dns_rdatatype_none,
6010 0, &rdataset, NULL);
6011 if (result == ISC_R_NOTFOUND) {
6012 INSIST(!dns_rdataset_isassociated(&rdataset));
6013 result = ISC_R_SUCCESS;
6016 if (result != ISC_R_SUCCESS) {
6017 INSIST(!dns_rdataset_isassociated(&rdataset));
6020 for (result = dns_rdataset_first(&rdataset);
6021 result == ISC_R_SUCCESS;
6022 result = dns_rdataset_next(&rdataset)) {
6023 dns_rdataset_current(&rdataset, &rdata);
6025 * If we don't match the algorithm or keyid skip the record.
6027 if (rdata.length != 5 ||
6028 rdata.data[0] != signing->algorithm ||
6029 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
6030 rdata.data[2] != (signing->keyid & 0xff)) {
6032 dns_rdata_reset(&rdata);
6036 * We have a match. If we were signing (!signing->delete)
6037 * and we already have a record indicating that we have
6038 * finished signing (rdata.data[4] != 0) then keep it.
6039 * Otherwise it needs to be deleted as we have removed all
6040 * the signatures (signing->delete), so any record indicating
6041 * completion is now out of date, or we have finished signing
6042 * with the new record so we no longer need to remember that
6043 * we need to sign the zone with the matching key across a
6044 * nameserver re-start.
6046 if (!signing->delete && rdata.data[4] != 0) {
6047 seen_done = ISC_TRUE;
6050 CHECK(update_one_rr(signing->db, version, diff,
6051 DNS_DIFFOP_DEL, &zone->origin,
6052 rdataset.ttl, &rdata));
6053 dns_rdata_reset(&rdata);
6055 if (result == ISC_R_NOMORE)
6056 result = ISC_R_SUCCESS;
6057 if (!signing->delete && !seen_done) {
6059 * If we were signing then we need to indicate that we have
6060 * finished signing the zone with this key. If it is already
6061 * there we don't need to add it a second time.
6063 data[0] = signing->algorithm;
6064 data[1] = (signing->keyid >> 8) & 0xff;
6065 data[2] = signing->keyid & 0xff;
6068 rdata.length = sizeof(data);
6070 rdata.type = zone->privatetype;
6071 rdata.rdclass = dns_db_class(signing->db);
6072 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
6073 &zone->origin, rdataset.ttl, &rdata));
6074 } else if (!have_rr) {
6075 dns_name_t *origin = dns_db_origin(signing->db);
6077 * Rebuild the NSEC/NSEC3 record for the origin as we no
6078 * longer have any private records.
6081 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
6082 minimum, ISC_FALSE, diff));
6083 CHECK(updatesecure(signing->db, version, origin, minimum,
6088 if (dns_rdataset_isassociated(&rdataset))
6089 dns_rdataset_disassociate(&rdataset);
6091 dns_db_detachnode(signing->db, &node);
6096 * If 'active' is set then we are not done with the chain yet so only
6097 * delete the nsec3param record which indicates a full chain exists
6101 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
6102 isc_boolean_t active, dns_rdatatype_t privatetype,
6105 dns_dbnode_t *node = NULL;
6106 dns_name_t *name = dns_db_origin(db);
6107 dns_rdata_t rdata = DNS_RDATA_INIT;
6108 dns_rdataset_t rdataset;
6109 dns_rdata_nsec3param_t nsec3param;
6110 isc_result_t result;
6111 isc_buffer_t buffer;
6112 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
6114 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
6116 dns_rdataset_init(&rdataset);
6118 result = dns_db_getoriginnode(db, &node);
6119 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6120 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6121 0, 0, &rdataset, NULL);
6122 if (result == ISC_R_NOTFOUND)
6124 if (result != ISC_R_SUCCESS)
6128 * Preserve the existing ttl.
6133 * Delete all NSEC3PARAM records which match that in nsec3chain.
6135 for (result = dns_rdataset_first(&rdataset);
6136 result == ISC_R_SUCCESS;
6137 result = dns_rdataset_next(&rdataset)) {
6139 dns_rdataset_current(&rdataset, &rdata);
6140 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6142 if (nsec3param.hash != chain->nsec3param.hash ||
6143 (active && nsec3param.flags != 0) ||
6144 nsec3param.iterations != chain->nsec3param.iterations ||
6145 nsec3param.salt_length != chain->nsec3param.salt_length ||
6146 memcmp(nsec3param.salt, chain->nsec3param.salt,
6147 nsec3param.salt_length)) {
6148 dns_rdata_reset(&rdata);
6152 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6153 name, rdataset.ttl, &rdata));
6154 dns_rdata_reset(&rdata);
6156 if (result != ISC_R_NOMORE)
6159 dns_rdataset_disassociate(&rdataset);
6166 result = dns_nsec_nseconly(db, ver, &nseconly);
6167 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
6170 * Delete all private records which match that in nsec3chain.
6172 result = dns_db_findrdataset(db, node, ver, privatetype,
6173 0, 0, &rdataset, NULL);
6174 if (result == ISC_R_NOTFOUND)
6176 if (result != ISC_R_SUCCESS)
6179 for (result = dns_rdataset_first(&rdataset);
6180 result == ISC_R_SUCCESS;
6181 result = dns_rdataset_next(&rdataset)) {
6182 dns_rdata_t private = DNS_RDATA_INIT;
6183 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
6185 dns_rdataset_current(&rdataset, &private);
6186 if (!dns_nsec3param_fromprivate(&private, &rdata,
6189 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6192 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
6193 nsec3param.hash != chain->nsec3param.hash ||
6194 nsec3param.iterations != chain->nsec3param.iterations ||
6195 nsec3param.salt_length != chain->nsec3param.salt_length ||
6196 memcmp(nsec3param.salt, chain->nsec3param.salt,
6197 nsec3param.salt_length)) {
6198 dns_rdata_reset(&rdata);
6202 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6203 name, rdataset.ttl, &private));
6204 dns_rdata_reset(&rdata);
6206 if (result != ISC_R_NOMORE)
6210 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
6211 result = ISC_R_SUCCESS;
6216 * Add a NSEC3PARAM record which matches that in nsec3chain but
6217 * with all flags bits cleared.
6219 * Note: we do not clear chain->nsec3param.flags as this change
6222 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
6223 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
6224 dns_rdatatype_nsec3param,
6225 &chain->nsec3param, &buffer));
6226 rdata.data[1] = 0; /* Clear flag bits. */
6227 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
6230 dns_db_detachnode(db, &node);
6231 if (dns_rdataset_isassociated(&rdataset))
6232 dns_rdataset_disassociate(&rdataset);
6237 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6238 dns_name_t *name, dns_diff_t *diff)
6240 dns_rdataset_t rdataset;
6241 isc_result_t result;
6243 dns_rdataset_init(&rdataset);
6245 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6246 0, 0, &rdataset, NULL);
6247 if (result == ISC_R_NOTFOUND)
6248 return (ISC_R_SUCCESS);
6249 if (result != ISC_R_SUCCESS)
6251 for (result = dns_rdataset_first(&rdataset);
6252 result == ISC_R_SUCCESS;
6253 result = dns_rdataset_next(&rdataset)) {
6254 dns_rdata_t rdata = DNS_RDATA_INIT;
6256 dns_rdataset_current(&rdataset, &rdata);
6257 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6258 rdataset.ttl, &rdata));
6260 if (result == ISC_R_NOMORE)
6261 result = ISC_R_SUCCESS;
6263 dns_rdataset_disassociate(&rdataset);
6268 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6269 dns_name_t *name, const dns_rdata_nsec3param_t *param,
6272 dns_rdataset_t rdataset;
6273 dns_rdata_nsec3_t nsec3;
6274 isc_result_t result;
6276 dns_rdataset_init(&rdataset);
6277 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
6278 0, 0, &rdataset, NULL);
6279 if (result == ISC_R_NOTFOUND)
6280 return (ISC_R_SUCCESS);
6281 if (result != ISC_R_SUCCESS)
6284 for (result = dns_rdataset_first(&rdataset);
6285 result == ISC_R_SUCCESS;
6286 result = dns_rdataset_next(&rdataset)) {
6287 dns_rdata_t rdata = DNS_RDATA_INIT;
6289 dns_rdataset_current(&rdataset, &rdata);
6290 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
6291 if (nsec3.hash != param->hash ||
6292 nsec3.iterations != param->iterations ||
6293 nsec3.salt_length != param->salt_length ||
6294 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
6296 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6297 rdataset.ttl, &rdata));
6299 if (result == ISC_R_NOMORE)
6300 result = ISC_R_SUCCESS;
6302 dns_rdataset_disassociate(&rdataset);
6307 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
6308 const dns_rdata_nsec3param_t *param,
6309 isc_boolean_t *answer)
6311 dns_dbnode_t *node = NULL;
6312 dns_rdata_t rdata = DNS_RDATA_INIT;
6313 dns_rdata_nsec3param_t myparam;
6314 dns_rdataset_t rdataset;
6315 isc_result_t result;
6317 *answer = ISC_FALSE;
6319 result = dns_db_getoriginnode(db, &node);
6320 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6322 dns_rdataset_init(&rdataset);
6324 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6325 0, 0, &rdataset, NULL);
6326 if (result == ISC_R_SUCCESS) {
6327 dns_rdataset_disassociate(&rdataset);
6328 dns_db_detachnode(db, &node);
6331 if (result != ISC_R_NOTFOUND) {
6332 dns_db_detachnode(db, &node);
6336 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6337 0, 0, &rdataset, NULL);
6338 if (result == ISC_R_NOTFOUND) {
6340 dns_db_detachnode(db, &node);
6341 return (ISC_R_SUCCESS);
6343 if (result != ISC_R_SUCCESS) {
6344 dns_db_detachnode(db, &node);
6348 for (result = dns_rdataset_first(&rdataset);
6349 result == ISC_R_SUCCESS;
6350 result = dns_rdataset_next(&rdataset)) {
6351 dns_rdataset_current(&rdataset, &rdata);
6352 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
6353 dns_rdata_reset(&rdata);
6355 * Ignore any NSEC3PARAM removals.
6357 if (NSEC3REMOVE(myparam.flags))
6360 * Ignore the chain that we are in the process of deleting.
6362 if (myparam.hash == param->hash &&
6363 myparam.iterations == param->iterations &&
6364 myparam.salt_length == param->salt_length &&
6365 !memcmp(myparam.salt, param->salt, myparam.salt_length))
6368 * Found an active NSEC3 chain.
6372 if (result == ISC_R_NOMORE) {
6374 result = ISC_R_SUCCESS;
6378 if (dns_rdataset_isassociated(&rdataset))
6379 dns_rdataset_disassociate(&rdataset);
6380 dns_db_detachnode(db, &node);
6385 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
6386 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
6387 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
6388 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
6389 zonediff_t *zonediff)
6391 dns_difftuple_t *tuple;
6392 isc_result_t result;
6394 for (tuple = ISC_LIST_HEAD(diff->tuples);
6396 tuple = ISC_LIST_HEAD(diff->tuples)) {
6397 result = del_sigs(zone, db, version, &tuple->name,
6398 tuple->rdata.type, zonediff,
6399 zone_keys, nkeys, now, ISC_FALSE);
6400 if (result != ISC_R_SUCCESS) {
6401 dns_zone_log(zone, ISC_LOG_ERROR,
6402 "update_sigs:del_sigs -> %s",
6403 dns_result_totext(result));
6406 result = add_sigs(db, version, &tuple->name,
6407 tuple->rdata.type, zonediff->diff,
6408 zone_keys, nkeys, zone->mctx, inception,
6409 expire, check_ksk, keyset_kskonly);
6410 if (result != ISC_R_SUCCESS) {
6411 dns_zone_log(zone, ISC_LOG_ERROR,
6412 "update_sigs:add_sigs -> %s",
6413 dns_result_totext(result));
6418 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
6419 while (next != NULL &&
6420 (tuple->rdata.type != next->rdata.type ||
6421 !dns_name_equal(&tuple->name, &next->name)))
6422 next = ISC_LIST_NEXT(next, link);
6423 ISC_LIST_UNLINK(diff->tuples, tuple, link);
6424 dns_diff_appendminimal(zonediff->diff, &tuple);
6425 INSIST(tuple == NULL);
6427 } while (tuple != NULL);
6429 return (ISC_R_SUCCESS);
6433 * Incrementally build and sign a new NSEC3 chain using the parameters
6437 zone_nsec3chain(dns_zone_t *zone) {
6438 const char *me = "zone_nsec3chain";
6439 dns_db_t *db = NULL;
6440 dns_dbnode_t *node = NULL;
6441 dns_dbversion_t *version = NULL;
6442 dns_diff_t _sig_diff;
6443 dns_diff_t nsec_diff;
6444 dns_diff_t nsec3_diff;
6445 dns_diff_t param_diff;
6446 zonediff_t zonediff;
6447 dns_fixedname_t fixed;
6448 dns_fixedname_t nextfixed;
6449 dns_name_t *name, *nextname;
6450 dns_rdataset_t rdataset;
6451 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
6452 dns_nsec3chainlist_t cleanup;
6453 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6454 isc_int32_t signatures;
6455 isc_boolean_t check_ksk, keyset_kskonly;
6456 isc_boolean_t delegation;
6457 isc_boolean_t first;
6458 isc_result_t result;
6459 isc_stdtime_t now, inception, soaexpire, expire;
6460 isc_uint32_t jitter;
6462 unsigned int nkeys = 0;
6464 isc_boolean_t unsecure = ISC_FALSE;
6465 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
6466 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
6467 dns_rdatasetiter_t *iterator = NULL;
6468 isc_boolean_t buildnsecchain;
6469 isc_boolean_t updatensec = ISC_FALSE;
6470 dns_rdatatype_t privatetype = zone->privatetype;
6474 dns_rdataset_init(&rdataset);
6475 dns_fixedname_init(&fixed);
6476 name = dns_fixedname_name(&fixed);
6477 dns_fixedname_init(&nextfixed);
6478 nextname = dns_fixedname_name(&nextfixed);
6479 dns_diff_init(zone->mctx, ¶m_diff);
6480 dns_diff_init(zone->mctx, &nsec3_diff);
6481 dns_diff_init(zone->mctx, &nsec_diff);
6482 dns_diff_init(zone->mctx, &_sig_diff);
6483 _sig_diff.resign = zone->sigresigninginterval;
6484 zonediff_init(&zonediff, &_sig_diff);
6485 ISC_LIST_INIT(cleanup);
6488 * Updates are disabled. Pause for 5 minutes.
6490 if (zone->update_disabled) {
6491 result = ISC_R_FAILURE;
6495 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6496 dns_db_attach(zone->db, &db);
6497 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6499 result = dns_db_newversion(db, &version);
6500 if (result != ISC_R_SUCCESS) {
6501 dns_zone_log(zone, ISC_LOG_ERROR,
6502 "zone_nsec3chain:dns_db_newversion -> %s",
6503 dns_result_totext(result));
6507 result = find_zone_keys(zone, db, version, zone->mctx,
6508 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6509 if (result != ISC_R_SUCCESS) {
6510 dns_zone_log(zone, ISC_LOG_ERROR,
6511 "zone_nsec3chain:find_zone_keys -> %s",
6512 dns_result_totext(result));
6516 isc_stdtime_get(&now);
6517 inception = now - 3600; /* Allow for clock skew. */
6518 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6521 * Spread out signatures over time if they happen to be
6522 * clumped. We don't do this for each add_sigs() call as
6523 * we still want some clustering to occur.
6525 isc_random_get(&jitter);
6526 expire = soaexpire - jitter % 3600;
6528 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6529 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6532 * We keep pulling nodes off each iterator in turn until
6533 * we have no more nodes to pull off or we reach the limits
6536 nodes = zone->nodes;
6537 signatures = zone->signatures;
6539 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6543 if (nsec3chain != NULL)
6544 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6546 * Generate new NSEC3 chains first.
6548 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6550 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6552 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6553 if (nsec3chain->done || nsec3chain->db != zone->db) {
6554 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
6555 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6557 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6559 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
6563 * Possible future db.
6565 if (nsec3chain->db != db) {
6569 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
6572 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6574 if (nsec3chain->delete_nsec) {
6575 delegation = ISC_FALSE;
6576 dns_dbiterator_pause(nsec3chain->dbiterator);
6577 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
6581 * On the first pass we need to check if the current node
6582 * has not been obscured.
6584 delegation = ISC_FALSE;
6585 unsecure = ISC_FALSE;
6587 dns_fixedname_t ffound;
6589 dns_fixedname_init(&ffound);
6590 found = dns_fixedname_name(&ffound);
6591 result = dns_db_find(db, name, version,
6593 DNS_DBFIND_NOWILD, 0, NULL, found,
6595 if ((result == DNS_R_DELEGATION ||
6596 result == DNS_R_DNAME) &&
6597 !dns_name_equal(name, found)) {
6599 * Remember the obscuring name so that
6600 * we skip all obscured names.
6602 dns_name_copy(found, name, NULL);
6603 delegation = ISC_TRUE;
6609 * Check to see if this is a bottom of zone node.
6611 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6612 if (result == ISC_R_NOTFOUND) /* Empty node? */
6614 if (result != ISC_R_SUCCESS)
6617 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
6619 for (result = dns_rdatasetiter_first(iterator);
6620 result == ISC_R_SUCCESS;
6621 result = dns_rdatasetiter_next(iterator)) {
6622 dns_rdatasetiter_current(iterator, &rdataset);
6623 INSIST(rdataset.type != dns_rdatatype_nsec3);
6624 if (rdataset.type == dns_rdatatype_soa)
6625 seen_soa = ISC_TRUE;
6626 else if (rdataset.type == dns_rdatatype_ns)
6628 else if (rdataset.type == dns_rdatatype_dname)
6629 seen_dname = ISC_TRUE;
6630 else if (rdataset.type == dns_rdatatype_ds)
6632 else if (rdataset.type == dns_rdatatype_nsec)
6633 seen_nsec = ISC_TRUE;
6634 dns_rdataset_disassociate(&rdataset);
6636 dns_rdatasetiter_destroy(&iterator);
6638 * Is there a NSEC chain than needs to be cleaned up?
6641 nsec3chain->seen_nsec = ISC_TRUE;
6642 if (seen_ns && !seen_soa && !seen_ds)
6643 unsecure = ISC_TRUE;
6644 if ((seen_ns && !seen_soa) || seen_dname)
6645 delegation = ISC_TRUE;
6650 dns_dbiterator_pause(nsec3chain->dbiterator);
6651 result = dns_nsec3_addnsec3(db, version, name,
6652 &nsec3chain->nsec3param,
6653 zone->minimum, unsecure,
6655 if (result != ISC_R_SUCCESS) {
6656 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6657 "dns_nsec3_addnsec3 -> %s",
6658 dns_result_totext(result));
6663 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
6664 * two signatures. Additionally there will, in general, be
6665 * two signature generated below.
6667 * If we are only changing the optout flag the cost is half
6668 * that of the cost of generating a completely new chain.
6673 * Go onto next node.
6677 dns_db_detachnode(db, &node);
6679 result = dns_dbiterator_next(nsec3chain->dbiterator);
6681 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
6682 dns_dbiterator_pause(nsec3chain->dbiterator);
6683 CHECK(fixup_nsec3param(db, version, nsec3chain,
6684 ISC_FALSE, privatetype,
6687 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6690 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6693 if (result == ISC_R_NOMORE) {
6694 dns_dbiterator_pause(nsec3chain->dbiterator);
6695 if (nsec3chain->seen_nsec) {
6696 CHECK(fixup_nsec3param(db, version,
6701 nsec3chain->delete_nsec = ISC_TRUE;
6704 CHECK(fixup_nsec3param(db, version, nsec3chain,
6705 ISC_FALSE, privatetype,
6708 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6711 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6713 } else if (result != ISC_R_SUCCESS) {
6714 dns_zone_log(zone, ISC_LOG_ERROR,
6716 "dns_dbiterator_next -> %s",
6717 dns_result_totext(result));
6719 } else if (delegation) {
6720 dns_dbiterator_current(nsec3chain->dbiterator,
6722 dns_db_detachnode(db, &node);
6723 if (!dns_name_issubdomain(nextname, name))
6731 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6736 dns_dbiterator_pause(nsec3chain->dbiterator);
6737 nsec3chain = nextnsec3chain;
6739 if (nsec3chain != NULL)
6740 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6747 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6750 buildnsecchain = ISC_FALSE;
6751 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6753 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6756 if (nsec3chain->db != db)
6757 goto next_removechain;
6759 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
6760 goto next_removechain;
6763 * Work out if we need to build a NSEC chain as a consequence
6764 * of removing this NSEC3 chain.
6766 if (first && !updatensec &&
6767 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
6769 result = need_nsec_chain(db, version,
6770 &nsec3chain->nsec3param,
6772 if (result != ISC_R_SUCCESS) {
6773 dns_zone_log(zone, ISC_LOG_ERROR,
6775 "need_nsec_chain -> %s",
6776 dns_result_totext(result));
6782 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
6783 "buildnsecchain = %u\n", buildnsecchain);
6785 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6786 delegation = ISC_FALSE;
6788 if (!buildnsecchain) {
6790 * Delete the NSECPARAM record that matches this chain.
6793 result = fixup_nsec3param(db, version,
6795 ISC_TRUE, privatetype,
6797 if (result != ISC_R_SUCCESS) {
6798 dns_zone_log(zone, ISC_LOG_ERROR,
6800 "fixup_nsec3param -> %s",
6801 dns_result_totext(result));
6807 * Delete the NSEC3 records.
6809 result = deletematchingnsec3(db, version, node, name,
6810 &nsec3chain->nsec3param,
6812 if (result != ISC_R_SUCCESS) {
6813 dns_zone_log(zone, ISC_LOG_ERROR,
6815 "deletematchingnsec3 -> %s",
6816 dns_result_totext(result));
6819 goto next_removenode;
6823 dns_fixedname_t ffound;
6825 dns_fixedname_init(&ffound);
6826 found = dns_fixedname_name(&ffound);
6827 result = dns_db_find(db, name, version,
6829 DNS_DBFIND_NOWILD, 0, NULL, found,
6831 if ((result == DNS_R_DELEGATION ||
6832 result == DNS_R_DNAME) &&
6833 !dns_name_equal(name, found)) {
6835 * Remember the obscuring name so that
6836 * we skip all obscured names.
6838 dns_name_copy(found, name, NULL);
6839 delegation = ISC_TRUE;
6840 goto next_removenode;
6845 * Check to see if this is a bottom of zone node.
6847 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6848 if (result == ISC_R_NOTFOUND) /* Empty node? */
6849 goto next_removenode;
6850 if (result != ISC_R_SUCCESS)
6853 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
6854 seen_rr = ISC_FALSE;
6855 for (result = dns_rdatasetiter_first(iterator);
6856 result == ISC_R_SUCCESS;
6857 result = dns_rdatasetiter_next(iterator)) {
6858 dns_rdatasetiter_current(iterator, &rdataset);
6859 if (rdataset.type == dns_rdatatype_soa)
6860 seen_soa = ISC_TRUE;
6861 else if (rdataset.type == dns_rdatatype_ns)
6863 else if (rdataset.type == dns_rdatatype_dname)
6864 seen_dname = ISC_TRUE;
6865 else if (rdataset.type == dns_rdatatype_nsec)
6866 seen_nsec = ISC_TRUE;
6867 else if (rdataset.type == dns_rdatatype_nsec3)
6868 seen_nsec3 = ISC_TRUE;
6869 if (rdataset.type != dns_rdatatype_rrsig)
6871 dns_rdataset_disassociate(&rdataset);
6873 dns_rdatasetiter_destroy(&iterator);
6875 if (!seen_rr || seen_nsec3 || seen_nsec)
6876 goto next_removenode;
6877 if ((seen_ns && !seen_soa) || seen_dname)
6878 delegation = ISC_TRUE;
6881 * Add a NSEC record except at the origin.
6883 if (!dns_name_equal(name, dns_db_origin(db))) {
6884 dns_dbiterator_pause(nsec3chain->dbiterator);
6885 CHECK(add_nsec(db, version, name, node, zone->minimum,
6886 delegation, &nsec_diff));
6891 dns_db_detachnode(db, &node);
6893 result = dns_dbiterator_next(nsec3chain->dbiterator);
6894 if (result == ISC_R_NOMORE && buildnsecchain) {
6896 * The NSEC chain should now be built.
6897 * We can now remove the NSEC3 chain.
6899 updatensec = ISC_TRUE;
6900 goto same_removechain;
6902 if (result == ISC_R_NOMORE) {
6904 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6907 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6908 dns_dbiterator_pause(nsec3chain->dbiterator);
6909 result = fixup_nsec3param(db, version,
6910 nsec3chain, ISC_FALSE,
6913 if (result != ISC_R_SUCCESS) {
6914 dns_zone_log(zone, ISC_LOG_ERROR,
6916 "fixup_nsec3param -> %s",
6917 dns_result_totext(result));
6920 goto next_removechain;
6921 } else if (result != ISC_R_SUCCESS) {
6922 dns_zone_log(zone, ISC_LOG_ERROR,
6924 "dns_dbiterator_next -> %s",
6925 dns_result_totext(result));
6927 } else if (delegation) {
6928 dns_dbiterator_current(nsec3chain->dbiterator,
6930 dns_db_detachnode(db, &node);
6931 if (!dns_name_issubdomain(nextname, name))
6939 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6940 buildnsecchain = ISC_FALSE;
6945 dns_dbiterator_pause(nsec3chain->dbiterator);
6946 nsec3chain = nextnsec3chain;
6951 * We may need to update the NSEC/NSEC3 records for the zone apex.
6953 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
6954 isc_boolean_t rebuild_nsec = ISC_FALSE,
6955 rebuild_nsec3 = ISC_FALSE;
6956 result = dns_db_getoriginnode(db, &node);
6957 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6958 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6959 if (result != ISC_R_SUCCESS) {
6960 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6961 "dns_db_allrdatasets -> %s",
6962 dns_result_totext(result));
6965 for (result = dns_rdatasetiter_first(iterator);
6966 result == ISC_R_SUCCESS;
6967 result = dns_rdatasetiter_next(iterator)) {
6968 dns_rdatasetiter_current(iterator, &rdataset);
6969 if (rdataset.type == dns_rdatatype_nsec)
6970 rebuild_nsec = ISC_TRUE;
6971 if (rdataset.type == dns_rdatatype_nsec3param)
6972 rebuild_nsec3 = ISC_TRUE;
6973 dns_rdataset_disassociate(&rdataset);
6975 dns_rdatasetiter_destroy(&iterator);
6976 dns_db_detachnode(db, &node);
6979 if (nsec3chain != NULL)
6980 dns_dbiterator_pause(nsec3chain->dbiterator);
6982 result = updatesecure(db, version, &zone->origin,
6983 zone->minimum, ISC_TRUE,
6985 if (result != ISC_R_SUCCESS) {
6986 dns_zone_log(zone, ISC_LOG_ERROR,
6988 "updatesecure -> %s",
6989 dns_result_totext(result));
6994 if (rebuild_nsec3) {
6995 if (nsec3chain != NULL)
6996 dns_dbiterator_pause(nsec3chain->dbiterator);
6998 result = dns_nsec3_addnsec3s(db, version,
7000 zone->minimum, ISC_FALSE,
7002 if (result != ISC_R_SUCCESS) {
7003 dns_zone_log(zone, ISC_LOG_ERROR,
7005 "dns_nsec3_addnsec3s -> %s",
7006 dns_result_totext(result));
7012 if (nsec3chain != NULL)
7013 dns_dbiterator_pause(nsec3chain->dbiterator);
7016 * Add / update signatures for the NSEC3 records.
7018 if (nsec3chain != NULL)
7019 dns_dbiterator_pause(nsec3chain->dbiterator);
7020 result = update_sigs(&nsec3_diff, db, version, zone_keys,
7021 nkeys, zone, inception, expire, now,
7022 check_ksk, keyset_kskonly, &zonediff);
7023 if (result != ISC_R_SUCCESS) {
7024 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7025 "update_sigs -> %s", dns_result_totext(result));
7030 * We have changed the NSEC3PARAM or private RRsets
7031 * above so we need to update the signatures.
7033 result = update_sigs(¶m_diff, db, version, zone_keys,
7034 nkeys, zone, inception, expire, now,
7035 check_ksk, keyset_kskonly, &zonediff);
7036 if (result != ISC_R_SUCCESS) {
7037 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7038 "update_sigs -> %s", dns_result_totext(result));
7043 result = updatesecure(db, version, &zone->origin,
7044 zone->minimum, ISC_FALSE, &nsec_diff);
7045 if (result != ISC_R_SUCCESS) {
7046 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7047 "updatesecure -> %s",
7048 dns_result_totext(result));
7053 result = update_sigs(&nsec_diff, db, version, zone_keys,
7054 nkeys, zone, inception, expire, now,
7055 check_ksk, keyset_kskonly, &zonediff);
7056 if (result != ISC_R_SUCCESS) {
7057 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7058 "update_sigs -> %s", dns_result_totext(result));
7063 * If we made no effective changes to the zone then we can just
7064 * cleanup otherwise we need to increment the serial.
7066 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7068 * No need to call dns_db_closeversion() here as it is
7069 * called with commit = ISC_TRUE below.
7074 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7075 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7076 if (result != ISC_R_SUCCESS) {
7077 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7078 "del_sigs -> %s", dns_result_totext(result));
7082 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7083 zone->updatemethod);
7084 if (result != ISC_R_SUCCESS) {
7085 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7086 "update_soa_serial -> %s",
7087 dns_result_totext(result));
7091 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7092 zonediff.diff, zone_keys, nkeys, zone->mctx,
7093 inception, soaexpire, check_ksk, keyset_kskonly);
7094 if (result != ISC_R_SUCCESS) {
7095 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7096 "add_sigs -> %s", dns_result_totext(result));
7100 /* Write changes to journal file. */
7101 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
7104 zone_needdump(zone, DNS_DUMP_DELAY);
7105 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7110 * Pause all iterators so that dns_db_closeversion() can succeed.
7113 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7115 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7116 dns_dbiterator_pause(nsec3chain->dbiterator);
7120 * Everything has succeeded. Commit the changes.
7121 * Unconditionally commit as zonediff.offline not checked above.
7123 dns_db_closeversion(db, &version, ISC_TRUE);
7126 * Everything succeeded so we can clean these up now.
7128 nsec3chain = ISC_LIST_HEAD(cleanup);
7129 while (nsec3chain != NULL) {
7130 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7131 dns_db_detach(&nsec3chain->db);
7132 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7133 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7134 nsec3chain = ISC_LIST_HEAD(cleanup);
7137 set_resigntime(zone);
7140 if (result != ISC_R_SUCCESS)
7141 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
7142 dns_result_totext(result));
7144 * On error roll back the current nsec3chain.
7146 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
7147 if (nsec3chain->done) {
7148 dns_db_detach(&nsec3chain->db);
7149 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7150 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7152 result = dns_dbiterator_first(nsec3chain->dbiterator);
7153 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7154 dns_dbiterator_pause(nsec3chain->dbiterator);
7155 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7160 * Rollback the cleanup list.
7162 nsec3chain = ISC_LIST_TAIL(cleanup);
7163 while (nsec3chain != NULL) {
7164 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7165 if (nsec3chain->done) {
7166 dns_db_detach(&nsec3chain->db);
7167 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7168 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7171 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
7173 result = dns_dbiterator_first(nsec3chain->dbiterator);
7174 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7175 dns_dbiterator_pause(nsec3chain->dbiterator);
7176 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7178 nsec3chain = ISC_LIST_TAIL(cleanup);
7182 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7184 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7185 dns_dbiterator_pause(nsec3chain->dbiterator);
7188 dns_diff_clear(¶m_diff);
7189 dns_diff_clear(&nsec3_diff);
7190 dns_diff_clear(&nsec_diff);
7191 dns_diff_clear(&_sig_diff);
7193 if (iterator != NULL)
7194 dns_rdatasetiter_destroy(&iterator);
7196 for (i = 0; i < nkeys; i++)
7197 dst_key_free(&zone_keys[i]);
7200 dns_db_detachnode(db, &node);
7201 if (version != NULL) {
7202 dns_db_closeversion(db, &version, ISC_FALSE);
7204 } else if (db != NULL)
7208 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
7210 if (zone->update_disabled || result != ISC_R_SUCCESS)
7211 isc_interval_set(&i, 60, 0); /* 1 minute */
7213 isc_interval_set(&i, 0, 10000000); /* 10 ms */
7214 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
7216 isc_time_settoepoch(&zone->nsec3chaintime);
7221 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
7222 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
7223 isc_uint16_t keyid, dns_diff_t *diff)
7225 dns_rdata_rrsig_t rrsig;
7226 dns_rdataset_t rdataset;
7227 dns_rdatasetiter_t *iterator = NULL;
7228 isc_result_t result;
7230 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7231 if (result != ISC_R_SUCCESS) {
7232 if (result == ISC_R_NOTFOUND)
7233 result = ISC_R_SUCCESS;
7237 dns_rdataset_init(&rdataset);
7238 for (result = dns_rdatasetiter_first(iterator);
7239 result == ISC_R_SUCCESS;
7240 result = dns_rdatasetiter_next(iterator)) {
7241 dns_rdatasetiter_current(iterator, &rdataset);
7242 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
7243 for (result = dns_rdataset_first(&rdataset);
7244 result == ISC_R_SUCCESS;
7245 result = dns_rdataset_next(&rdataset)) {
7246 dns_rdata_t rdata = DNS_RDATA_INIT;
7247 dns_rdataset_current(&rdataset, &rdata);
7248 CHECK(update_one_rr(db, version, diff,
7249 DNS_DIFFOP_DEL, name,
7250 rdataset.ttl, &rdata));
7252 if (result != ISC_R_NOMORE)
7254 dns_rdataset_disassociate(&rdataset);
7257 if (rdataset.type != dns_rdatatype_rrsig) {
7258 dns_rdataset_disassociate(&rdataset);
7261 for (result = dns_rdataset_first(&rdataset);
7262 result == ISC_R_SUCCESS;
7263 result = dns_rdataset_next(&rdataset)) {
7264 dns_rdata_t rdata = DNS_RDATA_INIT;
7265 dns_rdataset_current(&rdataset, &rdata);
7266 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
7267 if (rrsig.algorithm != algorithm ||
7268 rrsig.keyid != keyid)
7270 CHECK(update_one_rr(db, version, diff,
7271 DNS_DIFFOP_DELRESIGN, name,
7272 rdataset.ttl, &rdata));
7274 dns_rdataset_disassociate(&rdataset);
7275 if (result != ISC_R_NOMORE)
7278 if (result == ISC_R_NOMORE)
7279 result = ISC_R_SUCCESS;
7281 if (dns_rdataset_isassociated(&rdataset))
7282 dns_rdataset_disassociate(&rdataset);
7283 dns_rdatasetiter_destroy(&iterator);
7288 * Incrementally sign the zone using the keys requested.
7289 * Builds the NSEC chain if required.
7292 zone_sign(dns_zone_t *zone) {
7293 const char *me = "zone_sign";
7294 dns_db_t *db = NULL;
7295 dns_dbnode_t *node = NULL;
7296 dns_dbversion_t *version = NULL;
7297 dns_diff_t _sig_diff;
7298 dns_diff_t post_diff;
7299 zonediff_t zonediff;
7300 dns_fixedname_t fixed;
7301 dns_fixedname_t nextfixed;
7302 dns_name_t *name, *nextname;
7303 dns_rdataset_t rdataset;
7304 dns_signing_t *signing, *nextsigning;
7305 dns_signinglist_t cleanup;
7306 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
7307 isc_int32_t signatures;
7308 isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
7309 isc_boolean_t commit = ISC_FALSE;
7310 isc_boolean_t delegation;
7311 isc_boolean_t build_nsec = ISC_FALSE;
7312 isc_boolean_t build_nsec3 = ISC_FALSE;
7313 isc_boolean_t first;
7314 isc_result_t result;
7315 isc_stdtime_t now, inception, soaexpire, expire;
7316 isc_uint32_t jitter;
7318 unsigned int nkeys = 0;
7323 dns_rdataset_init(&rdataset);
7324 dns_fixedname_init(&fixed);
7325 name = dns_fixedname_name(&fixed);
7326 dns_fixedname_init(&nextfixed);
7327 nextname = dns_fixedname_name(&nextfixed);
7328 dns_diff_init(zone->mctx, &_sig_diff);
7329 _sig_diff.resign = zone->sigresigninginterval;
7330 dns_diff_init(zone->mctx, &post_diff);
7331 zonediff_init(&zonediff, &_sig_diff);
7332 ISC_LIST_INIT(cleanup);
7335 * Updates are disabled. Pause for 5 minutes.
7337 if (zone->update_disabled) {
7338 result = ISC_R_FAILURE;
7342 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7343 dns_db_attach(zone->db, &db);
7344 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7346 result = dns_db_newversion(db, &version);
7347 if (result != ISC_R_SUCCESS) {
7348 dns_zone_log(zone, ISC_LOG_ERROR,
7349 "zone_sign:dns_db_newversion -> %s",
7350 dns_result_totext(result));
7354 result = find_zone_keys(zone, db, version, zone->mctx,
7355 DNS_MAXZONEKEYS, zone_keys, &nkeys);
7356 if (result != ISC_R_SUCCESS) {
7357 dns_zone_log(zone, ISC_LOG_ERROR,
7358 "zone_sign:find_zone_keys -> %s",
7359 dns_result_totext(result));
7363 isc_stdtime_get(&now);
7364 inception = now - 3600; /* Allow for clock skew. */
7365 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
7368 * Spread out signatures over time if they happen to be
7369 * clumped. We don't do this for each add_sigs() call as
7370 * we still want some clustering to occur.
7372 isc_random_get(&jitter);
7373 expire = soaexpire - jitter % 3600;
7376 * We keep pulling nodes off each iterator in turn until
7377 * we have no more nodes to pull off or we reach the limits
7380 nodes = zone->nodes;
7381 signatures = zone->signatures;
7382 signing = ISC_LIST_HEAD(zone->signing);
7385 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
7386 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
7388 /* Determine which type of chain to build */
7389 CHECK(dns_private_chains(db, version, zone->privatetype,
7390 &build_nsec, &build_nsec3));
7392 /* If neither chain is found, default to NSEC */
7393 if (!build_nsec && !build_nsec3)
7394 build_nsec = ISC_TRUE;
7396 while (signing != NULL && nodes-- > 0 && signatures > 0) {
7397 nextsigning = ISC_LIST_NEXT(signing, link);
7399 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7400 if (signing->done || signing->db != zone->db) {
7402 * The zone has been reloaded. We will have
7403 * created new signings as part of the reload
7404 * process so we can destroy this one.
7406 ISC_LIST_UNLINK(zone->signing, signing, link);
7407 ISC_LIST_APPEND(cleanup, signing, link);
7408 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7411 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7413 if (signing->db != db)
7416 delegation = ISC_FALSE;
7418 if (first && signing->delete) {
7420 * Remove the key we are deleting from consideration.
7422 for (i = 0, j = 0; i < nkeys; i++) {
7424 * Find the key we want to remove.
7426 if (ALG(zone_keys[i]) == signing->algorithm &&
7427 dst_key_id(zone_keys[i]) == signing->keyid)
7429 if (KSK(zone_keys[i]))
7430 dst_key_free(&zone_keys[i]);
7433 zone_keys[j] = zone_keys[i];
7439 dns_dbiterator_current(signing->dbiterator, &node, name);
7441 if (signing->delete) {
7442 dns_dbiterator_pause(signing->dbiterator);
7443 CHECK(del_sig(db, version, name, node, nkeys,
7444 signing->algorithm, signing->keyid,
7449 * On the first pass we need to check if the current node
7450 * has not been obscured.
7453 dns_fixedname_t ffound;
7455 dns_fixedname_init(&ffound);
7456 found = dns_fixedname_name(&ffound);
7457 result = dns_db_find(db, name, version,
7459 DNS_DBFIND_NOWILD, 0, NULL, found,
7461 if ((result == DNS_R_DELEGATION ||
7462 result == DNS_R_DNAME) &&
7463 !dns_name_equal(name, found)) {
7465 * Remember the obscuring name so that
7466 * we skip all obscured names.
7468 dns_name_copy(found, name, NULL);
7469 delegation = ISC_TRUE;
7477 dns_dbiterator_pause(signing->dbiterator);
7478 for (i = 0; i < nkeys; i++) {
7479 isc_boolean_t both = ISC_FALSE;
7482 * Find the keys we want to sign with.
7484 if (!dst_key_isprivate(zone_keys[i]))
7488 * When adding look for the specific key.
7490 if (!signing->delete &&
7491 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
7492 dst_key_id(zone_keys[i]) != signing->keyid))
7496 * When deleting make sure we are properly signed
7497 * with the algorithm that was being removed.
7499 if (signing->delete &&
7500 ALG(zone_keys[i]) != signing->algorithm)
7504 * Do we do KSK processing?
7506 if (check_ksk && !REVOKE(zone_keys[i])) {
7507 isc_boolean_t have_ksk, have_nonksk;
7508 if (KSK(zone_keys[i])) {
7509 have_ksk = ISC_TRUE;
7510 have_nonksk = ISC_FALSE;
7512 have_ksk = ISC_FALSE;
7513 have_nonksk = ISC_TRUE;
7515 for (j = 0; j < nkeys; j++) {
7517 ALG(zone_keys[i]) !=
7520 if (REVOKE(zone_keys[j]))
7522 if (KSK(zone_keys[j]))
7523 have_ksk = ISC_TRUE;
7525 have_nonksk = ISC_TRUE;
7526 both = have_ksk && have_nonksk;
7531 if (both || REVOKE(zone_keys[i]))
7532 is_ksk = KSK(zone_keys[i]);
7536 CHECK(sign_a_node(db, name, node, version, build_nsec3,
7537 build_nsec, zone_keys[i], inception,
7538 expire, zone->minimum, is_ksk,
7539 ISC_TF(both && keyset_kskonly),
7540 &delegation, zonediff.diff,
7541 &signatures, zone->mctx));
7543 * If we are adding we are done. Look for other keys
7544 * of the same algorithm if deleting.
7546 if (!signing->delete)
7551 * Go onto next node.
7555 dns_db_detachnode(db, &node);
7557 result = dns_dbiterator_next(signing->dbiterator);
7558 if (result == ISC_R_NOMORE) {
7559 ISC_LIST_UNLINK(zone->signing, signing, link);
7560 ISC_LIST_APPEND(cleanup, signing, link);
7561 dns_dbiterator_pause(signing->dbiterator);
7562 if (nkeys != 0 && build_nsec) {
7564 * We have finished regenerating the
7565 * zone with a zone signing key.
7566 * The NSEC chain is now complete and
7567 * there is a full set of signatures
7568 * for the zone. We can now clear the
7569 * OPT bit from the NSEC record.
7571 result = updatesecure(db, version,
7576 if (result != ISC_R_SUCCESS) {
7579 "updatesecure -> %s",
7580 dns_result_totext(result));
7584 result = updatesignwithkey(zone, signing,
7589 if (result != ISC_R_SUCCESS) {
7590 dns_zone_log(zone, ISC_LOG_ERROR,
7591 "updatesignwithkey -> %s",
7592 dns_result_totext(result));
7595 build_nsec = ISC_FALSE;
7597 } else if (result != ISC_R_SUCCESS) {
7598 dns_zone_log(zone, ISC_LOG_ERROR,
7599 "zone_sign:dns_dbiterator_next -> %s",
7600 dns_result_totext(result));
7602 } else if (delegation) {
7603 dns_dbiterator_current(signing->dbiterator,
7605 dns_db_detachnode(db, &node);
7606 if (!dns_name_issubdomain(nextname, name))
7614 dns_dbiterator_pause(signing->dbiterator);
7615 signing = nextsigning;
7619 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
7620 result = update_sigs(&post_diff, db, version, zone_keys,
7621 nkeys, zone, inception, expire, now,
7622 check_ksk, keyset_kskonly, &zonediff);
7623 if (result != ISC_R_SUCCESS) {
7624 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
7625 "update_sigs -> %s",
7626 dns_result_totext(result));
7632 * Have we changed anything?
7634 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7635 if (zonediff.offline)
7637 result = ISC_R_SUCCESS;
7643 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7644 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7645 if (result != ISC_R_SUCCESS) {
7646 dns_zone_log(zone, ISC_LOG_ERROR,
7647 "zone_sign:del_sigs -> %s",
7648 dns_result_totext(result));
7652 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7653 zone->updatemethod);
7654 if (result != ISC_R_SUCCESS) {
7655 dns_zone_log(zone, ISC_LOG_ERROR,
7656 "zone_sign:update_soa_serial -> %s",
7657 dns_result_totext(result));
7662 * Generate maximum life time signatures so that the above loop
7663 * termination is sensible.
7665 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7666 zonediff.diff, zone_keys, nkeys, zone->mctx,
7667 inception, soaexpire, check_ksk, keyset_kskonly);
7668 if (result != ISC_R_SUCCESS) {
7669 dns_zone_log(zone, ISC_LOG_ERROR,
7670 "zone_sign:add_sigs -> %s",
7671 dns_result_totext(result));
7676 * Write changes to journal file.
7678 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
7682 * Pause all iterators so that dns_db_closeversion() can succeed.
7684 for (signing = ISC_LIST_HEAD(zone->signing);
7686 signing = ISC_LIST_NEXT(signing, link))
7687 dns_dbiterator_pause(signing->dbiterator);
7689 for (signing = ISC_LIST_HEAD(cleanup);
7691 signing = ISC_LIST_NEXT(signing, link))
7692 dns_dbiterator_pause(signing->dbiterator);
7695 * Everything has succeeded. Commit the changes.
7697 dns_db_closeversion(db, &version, commit);
7700 * Everything succeeded so we can clean these up now.
7702 signing = ISC_LIST_HEAD(cleanup);
7703 while (signing != NULL) {
7704 ISC_LIST_UNLINK(cleanup, signing, link);
7705 dns_db_detach(&signing->db);
7706 dns_dbiterator_destroy(&signing->dbiterator);
7707 isc_mem_put(zone->mctx, signing, sizeof *signing);
7708 signing = ISC_LIST_HEAD(cleanup);
7711 set_resigntime(zone);
7715 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7716 zone_needdump(zone, DNS_DUMP_DELAY);
7722 * Rollback the cleanup list.
7724 signing = ISC_LIST_HEAD(cleanup);
7725 while (signing != NULL) {
7726 ISC_LIST_UNLINK(cleanup, signing, link);
7727 ISC_LIST_PREPEND(zone->signing, signing, link);
7728 dns_dbiterator_first(signing->dbiterator);
7729 dns_dbiterator_pause(signing->dbiterator);
7730 signing = ISC_LIST_HEAD(cleanup);
7733 for (signing = ISC_LIST_HEAD(zone->signing);
7735 signing = ISC_LIST_NEXT(signing, link))
7736 dns_dbiterator_pause(signing->dbiterator);
7738 dns_diff_clear(&_sig_diff);
7740 for (i = 0; i < nkeys; i++)
7741 dst_key_free(&zone_keys[i]);
7744 dns_db_detachnode(db, &node);
7746 if (version != NULL) {
7747 dns_db_closeversion(db, &version, ISC_FALSE);
7749 } else if (db != NULL)
7752 if (ISC_LIST_HEAD(zone->signing) != NULL) {
7754 if (zone->update_disabled || result != ISC_R_SUCCESS)
7755 isc_interval_set(&i, 60, 0); /* 1 minute */
7757 isc_interval_set(&i, 0, 10000000); /* 10 ms */
7758 isc_time_nowplusinterval(&zone->signingtime, &i);
7760 isc_time_settoepoch(&zone->signingtime);
7764 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
7765 unsigned char *data, int size) {
7766 dns_rdata_dnskey_t dnskey;
7767 dns_rdata_keydata_t keydata;
7769 isc_result_t result;
7771 dns_rdata_reset(target);
7772 isc_buffer_init(&buf, data, size);
7775 case dns_rdatatype_dnskey:
7776 result = dns_rdata_tostruct(rr, &dnskey, NULL);
7777 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7778 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
7779 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7782 case dns_rdatatype_keydata:
7783 result = dns_rdata_tostruct(rr, &keydata, NULL);
7784 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7785 dns_keydata_todnskey(&keydata, &dnskey, NULL);
7786 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7795 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
7796 * a KEYDATA rdataset from the key zone.
7798 * 'rr' contains either a DNSKEY record, or a KEYDATA record
7800 * After normalizing keys to the same format (DNSKEY, with revoke bit
7801 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
7802 * 'rdset', or ISC_FALSE if not.
7805 static isc_boolean_t
7806 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
7807 unsigned char data1[4096], data2[4096];
7808 dns_rdata_t rdata, rdata1, rdata2;
7809 isc_result_t result;
7811 dns_rdata_init(&rdata);
7812 dns_rdata_init(&rdata1);
7813 dns_rdata_init(&rdata2);
7815 normalize_key(rr, &rdata1, data1, sizeof(data1));
7817 for (result = dns_rdataset_first(rdset);
7818 result == ISC_R_SUCCESS;
7819 result = dns_rdataset_next(rdset)) {
7820 dns_rdata_reset(&rdata);
7821 dns_rdataset_current(rdset, &rdata);
7822 normalize_key(&rdata, &rdata2, data2, sizeof(data2));
7823 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
7831 * Calculate the refresh interval for a keydata zone, per
7832 * RFC5011: MAX(1 hr,
7835 * 1/2 * RRSigExpirationInterval))
7836 * or for retries: MAX(1 hr,
7839 * 1/10 * RRSigExpirationInterval))
7841 static inline isc_stdtime_t
7842 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
7843 isc_result_t result;
7845 dns_rdataset_t *rdset;
7846 dns_rdata_t sigrr = DNS_RDATA_INIT;
7847 dns_rdata_sig_t sig;
7850 isc_stdtime_get(&now);
7852 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7853 rdset = &kfetch->dnskeysigset;
7855 return (now + HOUR);
7857 result = dns_rdataset_first(rdset);
7858 if (result != ISC_R_SUCCESS)
7859 return (now + HOUR);
7861 dns_rdataset_current(rdset, &sigrr);
7862 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7863 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7866 t = sig.originalttl / 2;
7868 if (isc_serial_gt(sig.timeexpire, now)) {
7869 isc_uint32_t exp = (sig.timeexpire - now) / 2;
7880 t = sig.originalttl / 10;
7882 if (isc_serial_gt(sig.timeexpire, now)) {
7883 isc_uint32_t exp = (sig.timeexpire - now) / 10;
7899 * This routine is called when no changes are needed in a KEYDATA
7900 * record except to simply update the refresh timer. Caller should
7904 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
7906 isc_result_t result;
7908 unsigned char key_buf[4096];
7909 dns_rdata_t rdata = DNS_RDATA_INIT;
7910 dns_rdata_keydata_t keydata;
7912 dns_zone_t *zone = kfetch->zone;
7915 name = dns_fixedname_name(&kfetch->name);
7916 isc_stdtime_get(&now);
7918 for (result = dns_rdataset_first(&kfetch->keydataset);
7919 result == ISC_R_SUCCESS;
7920 result = dns_rdataset_next(&kfetch->keydataset)) {
7921 dns_rdata_reset(&rdata);
7922 dns_rdataset_current(&kfetch->keydataset, &rdata);
7924 /* Delete old version */
7925 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
7928 /* Update refresh timer */
7929 CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL));
7930 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
7931 set_refreshkeytimer(zone, &keydata, now);
7933 dns_rdata_reset(&rdata);
7934 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7935 CHECK(dns_rdata_fromstruct(&rdata,
7936 zone->rdclass, dns_rdatatype_keydata,
7939 /* Insert updated version */
7940 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
7943 result = ISC_R_SUCCESS;
7949 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
7951 static isc_boolean_t
7952 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
7953 isc_result_t result;
7954 dns_name_t *keyname;
7956 dns_rdata_t sigrr = DNS_RDATA_INIT;
7957 dns_rdata_t rr = DNS_RDATA_INIT;
7958 dns_rdata_rrsig_t sig;
7959 dns_rdata_dnskey_t dnskey;
7960 dst_key_t *dstkey = NULL;
7961 unsigned char key_buf[4096];
7963 isc_boolean_t answer = ISC_FALSE;
7965 REQUIRE(kfetch != NULL && keydata != NULL);
7966 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
7968 keyname = dns_fixedname_name(&kfetch->name);
7969 mctx = kfetch->zone->view->mctx;
7971 /* Generate a key from keydata */
7972 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7973 dns_keydata_todnskey(keydata, &dnskey, NULL);
7974 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
7976 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
7977 if (result != ISC_R_SUCCESS)
7980 /* See if that key generated any of the signatures */
7981 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7982 result == ISC_R_SUCCESS;
7983 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7984 dns_fixedname_t fixed;
7985 dns_fixedname_init(&fixed);
7987 dns_rdata_reset(&sigrr);
7988 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7989 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7990 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7992 if (dst_key_alg(dstkey) == sig.algorithm &&
7993 (dst_key_id(dstkey) == sig.keyid ||
7994 dst_key_rid(dstkey) == sig.keyid)) {
7995 result = dns_dnssec_verify2(keyname,
7997 dstkey, ISC_FALSE, mctx, &sigrr,
7998 dns_fixedname_name(&fixed));
8000 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
8001 "Confirm revoked DNSKEY is self-signed: "
8002 "%s", dns_result_totext(result));
8004 if (result == ISC_R_SUCCESS) {
8011 dst_key_free(&dstkey);
8016 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
8017 * anchors are being managed; scan the keyset, and update the key zone and the
8018 * local trust anchors according to RFC5011.
8021 keyfetch_done(isc_task_t *task, isc_event_t *event) {
8022 isc_result_t result, eresult;
8023 dns_fetchevent_t *devent;
8024 dns_keyfetch_t *kfetch;
8026 isc_mem_t *mctx = NULL;
8027 dns_keytable_t *secroots = NULL;
8028 dns_dbversion_t *ver = NULL;
8030 isc_boolean_t alldone = ISC_FALSE;
8031 isc_boolean_t commit = ISC_FALSE;
8032 dns_name_t *keyname;
8033 dns_rdata_t sigrr = DNS_RDATA_INIT;
8034 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
8035 dns_rdata_t keydatarr = DNS_RDATA_INIT;
8036 dns_rdata_rrsig_t sig;
8037 dns_rdata_dnskey_t dnskey;
8038 dns_rdata_keydata_t keydata;
8039 isc_boolean_t initializing;
8040 char namebuf[DNS_NAME_FORMATSIZE];
8041 unsigned char key_buf[4096];
8046 isc_boolean_t secure;
8047 isc_boolean_t free_needed;
8050 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
8051 INSIST(event->ev_arg != NULL);
8053 kfetch = event->ev_arg;
8054 zone = kfetch->zone;
8055 isc_mem_attach(zone->mctx, &mctx);
8056 keyname = dns_fixedname_name(&kfetch->name);
8058 devent = (dns_fetchevent_t *) event;
8059 eresult = devent->result;
8061 /* Free resources which are not of interest */
8062 if (devent->node != NULL)
8063 dns_db_detachnode(devent->db, &devent->node);
8064 if (devent->db != NULL)
8065 dns_db_detach(&devent->db);
8066 isc_event_free(&event);
8067 dns_resolver_destroyfetch(&kfetch->fetch);
8070 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
8073 isc_stdtime_get(&now);
8074 dns_name_format(keyname, namebuf, sizeof(namebuf));
8076 result = dns_view_getsecroots(zone->view, &secroots);
8077 INSIST(result == ISC_R_SUCCESS);
8079 dns_diff_init(mctx, &diff);
8080 diff.resign = zone->sigresigninginterval;
8082 CHECK(dns_db_newversion(kfetch->db, &ver));
8084 zone->refreshkeycount--;
8085 alldone = ISC_TF(zone->refreshkeycount == 0);
8088 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8091 if (eresult != ISC_R_SUCCESS ||
8092 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
8093 dns_zone_log(zone, ISC_LOG_WARNING,
8094 "Unable to fetch DNSKEY set "
8095 "'%s': %s", namebuf, dns_result_totext(eresult));
8096 CHECK(minimal_update(kfetch, ver, &diff));
8100 /* No RRSIGs found */
8101 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
8102 dns_zone_log(zone, ISC_LOG_WARNING,
8103 "No DNSKEY RRSIGs found for "
8104 "'%s': %s", namebuf, dns_result_totext(eresult));
8105 CHECK(minimal_update(kfetch, ver, &diff));
8110 * Validate the dnskeyset against the current trusted keys.
8112 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8113 result == ISC_R_SUCCESS;
8114 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
8115 dns_keynode_t *keynode = NULL;
8117 dns_rdata_reset(&sigrr);
8118 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8119 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8120 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8122 result = dns_keytable_find(secroots, keyname, &keynode);
8123 while (result == ISC_R_SUCCESS) {
8124 dns_keynode_t *nextnode = NULL;
8125 dns_fixedname_t fixed;
8126 dns_fixedname_init(&fixed);
8128 dstkey = dns_keynode_key(keynode);
8129 if (dstkey == NULL) /* fail_secure() was called */
8132 if (dst_key_alg(dstkey) == sig.algorithm &&
8133 dst_key_id(dstkey) == sig.keyid) {
8134 result = dns_dnssec_verify2(keyname,
8137 zone->view->mctx, &sigrr,
8138 dns_fixedname_name(&fixed));
8140 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8141 "Verifying DNSKEY set for zone "
8142 "'%s': %s", namebuf,
8143 dns_result_totext(result));
8145 if (result == ISC_R_SUCCESS) {
8146 kfetch->dnskeyset.trust =
8148 kfetch->dnskeysigset.trust =
8150 dns_keytable_detachkeynode(secroots,
8156 result = dns_keytable_nextkeynode(secroots,
8157 keynode, &nextnode);
8158 dns_keytable_detachkeynode(secroots, &keynode);
8162 if (kfetch->dnskeyset.trust == dns_trust_secure)
8167 * If we were not able to verify the answer using the current
8168 * trusted keys then all we can do is look at any revoked keys.
8170 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
8173 * First scan keydataset to find keys that are not in dnskeyset
8174 * - Missing keys which are not scheduled for removal,
8176 * - Missing keys which are scheduled for removal and
8177 * the remove hold-down timer has completed should
8178 * be removed from the key zone
8179 * - Missing keys whose acceptance timers have not yet
8180 * completed, log a warning and reset the acceptance
8181 * timer to 30 days in the future
8182 * - All keys not being removed have their refresh timers
8185 initializing = ISC_TRUE;
8186 for (result = dns_rdataset_first(&kfetch->keydataset);
8187 result == ISC_R_SUCCESS;
8188 result = dns_rdataset_next(&kfetch->keydataset)) {
8189 dns_rdata_reset(&keydatarr);
8190 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8191 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8192 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8195 * If any keydata record has a nonzero add holddown, then
8196 * there was a pre-existing trust anchor for this domain;
8197 * that means we are *not* initializing it and shouldn't
8198 * automatically trust all the keys we find at the zone apex.
8200 initializing = initializing && ISC_TF(keydata.addhd == 0);
8202 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
8203 isc_boolean_t deletekey = ISC_FALSE;
8206 if (now > keydata.removehd)
8207 deletekey = ISC_TRUE;
8208 } else if (now < keydata.addhd) {
8209 dns_zone_log(zone, ISC_LOG_WARNING,
8210 "Pending key unexpectedly missing "
8211 "from %s; restarting acceptance "
8213 keydata.addhd = now + MONTH;
8214 keydata.refresh = refresh_time(kfetch,
8216 } else if (keydata.addhd == 0) {
8217 keydata.addhd = now;
8218 } else if (keydata.removehd == 0) {
8219 dns_zone_log(zone, ISC_LOG_WARNING,
8220 "Active key unexpectedly missing "
8221 "from %s", namebuf);
8222 keydata.refresh = now + HOUR;
8223 } else if (now > keydata.removehd) {
8224 deletekey = ISC_TRUE;
8226 keydata.refresh = refresh_time(kfetch,
8230 if (secure || deletekey) {
8231 /* Delete old version */
8232 CHECK(update_one_rr(kfetch->db, ver, &diff,
8233 DNS_DIFFOP_DEL, keyname, 0,
8237 if (!secure || deletekey)
8240 dns_rdata_reset(&keydatarr);
8241 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8242 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8243 dns_rdatatype_keydata,
8246 /* Insert updated version */
8247 CHECK(update_one_rr(kfetch->db, ver, &diff,
8248 DNS_DIFFOP_ADD, keyname, 0,
8251 set_refreshkeytimer(zone, &keydata, now);
8256 * Next scan dnskeyset:
8257 * - If new keys are found (i.e., lacking a match in keydataset)
8258 * add them to the key zone and set the acceptance timer
8259 * to 30 days in the future (or to immediately if we've
8260 * determined that we're initializing the zone for the
8262 * - Previously-known keys that have been revoked
8263 * must be scheduled for removal from the key zone (or,
8264 * if they hadn't been accepted as trust anchors yet
8265 * anyway, removed at once)
8266 * - Previously-known unrevoked keys whose acceptance timers
8267 * have completed are promoted to trust anchors
8268 * - All keys not being removed have their refresh
8271 for (result = dns_rdataset_first(&kfetch->dnskeyset);
8272 result == ISC_R_SUCCESS;
8273 result = dns_rdataset_next(&kfetch->dnskeyset)) {
8274 isc_boolean_t revoked = ISC_FALSE;
8275 isc_boolean_t newkey = ISC_FALSE;
8276 isc_boolean_t updatekey = ISC_FALSE;
8277 isc_boolean_t deletekey = ISC_FALSE;
8278 isc_boolean_t trustkey = ISC_FALSE;
8280 dns_rdata_reset(&dnskeyrr);
8281 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
8282 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8283 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8286 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
8289 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
8291 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
8292 dns_rdata_reset(&keydatarr);
8293 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8294 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8295 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8297 if (revoked && revocable(kfetch, &keydata)) {
8298 if (keydata.addhd > now) {
8300 * Key wasn't trusted yet, and now
8301 * it's been revoked? Just remove it
8303 deletekey = ISC_TRUE;
8304 } else if (keydata.removehd == 0) {
8305 /* Remove from secroots */
8306 dns_view_untrust(zone->view, keyname,
8309 /* If initializing, delete now */
8310 if (keydata.addhd == 0)
8311 deletekey = ISC_TRUE;
8313 keydata.removehd = now + MONTH;
8314 } else if (keydata.removehd < now) {
8315 /* Scheduled for removal */
8316 deletekey = ISC_TRUE;
8318 } else if (revoked) {
8319 if (secure && keydata.removehd == 0) {
8320 dns_zone_log(zone, ISC_LOG_WARNING,
8321 "Active key for zone "
8322 "'%s' is revoked but "
8323 "did not self-sign; "
8324 "ignoring.", namebuf);
8327 } else if (secure) {
8328 if (keydata.removehd != 0) {
8330 * Key isn't revoked--but it
8331 * seems it used to be.
8332 * Remove it now and add it
8333 * back as if it were a fresh key.
8335 deletekey = ISC_TRUE;
8337 } else if (keydata.addhd > now)
8339 else if (keydata.addhd == 0)
8340 keydata.addhd = now;
8342 if (keydata.addhd <= now)
8343 trustkey = ISC_TRUE;
8346 if (!deletekey && !newkey)
8347 updatekey = ISC_TRUE;
8348 } else if (secure) {
8350 * Key wasn't in the key zone but it's
8351 * revoked now anyway, so just skip it
8356 /* Key wasn't in the key zone: add it */
8360 dns_keytag_t tag = 0;
8361 CHECK(compute_tag(keyname, &dnskey,
8363 dns_zone_log(zone, ISC_LOG_WARNING,
8364 "Initializing automatic trust "
8365 "anchor management for zone '%s'; "
8366 "DNSKEY ID %d is now trusted, "
8367 "waiving the normal 30-day "
8370 trustkey = ISC_TRUE;
8374 /* Delete old version */
8375 if (deletekey || !newkey)
8376 CHECK(update_one_rr(kfetch->db, ver, &diff,
8377 DNS_DIFFOP_DEL, keyname, 0,
8381 /* Set refresh timer */
8382 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
8383 dns_rdata_reset(&keydatarr);
8384 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8385 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8386 dns_rdatatype_keydata,
8389 /* Insert updated version */
8390 CHECK(update_one_rr(kfetch->db, ver, &diff,
8391 DNS_DIFFOP_ADD, keyname, 0,
8393 } else if (newkey) {
8394 /* Convert DNSKEY to KEYDATA */
8395 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8396 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8397 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
8399 keydata.addhd = initializing ? now : now + MONTH;
8400 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
8401 dns_rdata_reset(&keydatarr);
8402 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8403 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8404 dns_rdatatype_keydata,
8407 /* Insert into key zone */
8408 CHECK(update_one_rr(kfetch->db, ver, &diff,
8409 DNS_DIFFOP_ADD, keyname, 0,
8414 /* Trust this key. */
8415 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8416 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8417 trust_key(zone, keyname, &dnskey, mctx);
8421 set_refreshkeytimer(zone, &keydata, now);
8425 * RFC5011 says, "A trust point that has all of its trust anchors
8426 * revoked is considered deleted and is treated as if the trust
8427 * point was never configured." But if someone revoked their
8428 * active key before the standby was trusted, that would mean the
8429 * zone would suddenly be nonsecured. We avoid this by checking to
8430 * see if there's pending keydata. If so, we put a null key in
8431 * the security roots; then all queries to the zone will fail.
8434 fail_secure(zone, keyname);
8438 if (!ISC_LIST_EMPTY(diff.tuples)) {
8439 /* Write changes to journal file. */
8440 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
8441 zone->updatemethod));
8442 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
8445 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8446 zone_needdump(zone, 30);
8451 dns_diff_clear(&diff);
8453 dns_db_closeversion(kfetch->db, &ver, commit);
8456 dns_db_detach(&kfetch->db);
8458 INSIST(zone->irefs > 0);
8460 kfetch->zone = NULL;
8462 if (dns_rdataset_isassociated(&kfetch->keydataset))
8463 dns_rdataset_disassociate(&kfetch->keydataset);
8464 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
8465 dns_rdataset_disassociate(&kfetch->dnskeyset);
8466 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8467 dns_rdataset_disassociate(&kfetch->dnskeysigset);
8469 dns_name_free(keyname, mctx);
8470 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
8471 isc_mem_detach(&mctx);
8473 if (secroots != NULL)
8474 dns_keytable_detach(&secroots);
8476 free_needed = exit_check(zone);
8483 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
8484 * records from the zone apex.
8487 zone_refreshkeys(dns_zone_t *zone) {
8488 const char me[] = "zone_refreshkeys";
8489 isc_result_t result;
8490 dns_rriterator_t rrit;
8491 dns_db_t *db = NULL;
8492 dns_dbversion_t *ver = NULL;
8494 dns_rdata_t rdata = DNS_RDATA_INIT;
8495 dns_rdata_keydata_t kd;
8497 isc_boolean_t commit = ISC_FALSE;
8498 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
8501 REQUIRE(zone->db != NULL);
8503 isc_stdtime_get(&now);
8506 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
8507 isc_time_settoepoch(&zone->refreshkeytime);
8512 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8513 dns_db_attach(zone->db, &db);
8514 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8516 dns_diff_init(zone->mctx, &diff);
8518 CHECK(dns_db_newversion(db, &ver));
8520 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
8522 dns_rriterator_init(&rrit, db, ver, 0);
8523 for (result = dns_rriterator_first(&rrit);
8524 result == ISC_R_SUCCESS;
8525 result = dns_rriterator_nextrrset(&rrit)) {
8526 isc_stdtime_t timer = 0xffffffff;
8527 dns_name_t *name = NULL, *kname = NULL;
8528 dns_rdataset_t *kdset = NULL;
8529 dns_keyfetch_t *kfetch;
8532 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
8533 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
8534 !dns_rdataset_isassociated(kdset))
8538 * Scan the stored keys looking for ones that need
8539 * removal or refreshing
8541 for (result = dns_rdataset_first(kdset);
8542 result == ISC_R_SUCCESS;
8543 result = dns_rdataset_next(kdset)) {
8544 dns_rdata_reset(&rdata);
8545 dns_rdataset_current(kdset, &rdata);
8546 result = dns_rdata_tostruct(&rdata, &kd, NULL);
8547 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8549 /* Removal timer expired? */
8550 if (kd.removehd != 0 && kd.removehd < now) {
8551 CHECK(update_one_rr(db, ver, &diff,
8552 DNS_DIFFOP_DEL, name, ttl,
8557 /* Acceptance timer expired? */
8558 if (kd.addhd != 0 && kd.addhd < now)
8561 /* Or do we just need to refresh the keyset? */
8562 if (timer > kd.refresh)
8569 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
8570 if (kfetch == NULL) {
8571 fetch_err = ISC_TRUE;
8575 zone->refreshkeycount++;
8576 kfetch->zone = zone;
8578 INSIST(zone->irefs != 0);
8579 dns_fixedname_init(&kfetch->name);
8580 kname = dns_fixedname_name(&kfetch->name);
8581 dns_name_dup(name, zone->mctx, kname);
8582 dns_rdataset_init(&kfetch->dnskeyset);
8583 dns_rdataset_init(&kfetch->dnskeysigset);
8584 dns_rdataset_init(&kfetch->keydataset);
8585 dns_rdataset_clone(kdset, &kfetch->keydataset);
8587 dns_db_attach(db, &kfetch->db);
8588 kfetch->fetch = NULL;
8590 result = dns_resolver_createfetch(zone->view->resolver,
8591 kname, dns_rdatatype_dnskey,
8593 DNS_FETCHOPT_NOVALIDATE,
8595 keyfetch_done, kfetch,
8597 &kfetch->dnskeysigset,
8599 if (result == ISC_R_SUCCESS)
8600 fetching = ISC_TRUE;
8602 zone->refreshkeycount--;
8604 dns_db_detach(&kfetch->db);
8605 dns_rdataset_disassociate(&kfetch->keydataset);
8606 dns_name_free(kname, zone->mctx);
8607 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
8608 dns_zone_log(zone, ISC_LOG_WARNING,
8609 "Failed to create fetch for "
8611 fetch_err = ISC_TRUE;
8614 if (!ISC_LIST_EMPTY(diff.tuples)) {
8615 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
8616 zone->updatemethod));
8617 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
8619 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8620 zone_needdump(zone, 30);
8626 * Error during a key fetch; retry in an hour.
8628 isc_time_t timenow, timethen;
8632 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
8633 zone->refreshkeytime = timethen;
8634 zone_settimer(zone, &timenow);
8636 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
8637 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
8641 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8646 dns_diff_clear(&diff);
8648 dns_rriterator_destroy(&rrit);
8649 dns_db_closeversion(db, &ver, commit);
8655 zone_maintenance(dns_zone_t *zone) {
8656 const char me[] = "zone_maintenance";
8658 isc_result_t result;
8659 isc_boolean_t dumping;
8661 REQUIRE(DNS_ZONE_VALID(zone));
8665 * Are we pending load/reload?
8667 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
8671 * Configuring the view of this zone may have
8672 * failed, for example because the config file
8673 * had a syntax error. In that case, the view
8674 * adb or resolver will be NULL, and we had better not try
8675 * to do further maintenance on it.
8677 if (zone->view == NULL || zone->view->adb == NULL)
8685 switch (zone->type) {
8686 case dns_zone_redirect:
8687 if (zone->masters == NULL)
8689 case dns_zone_slave:
8692 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
8693 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8695 zone->refreshtime = now;
8706 switch (zone->type) {
8707 case dns_zone_redirect:
8708 if (zone->masters == NULL)
8710 case dns_zone_slave:
8712 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
8713 isc_time_compare(&now, &zone->refreshtime) >= 0)
8714 dns_zone_refresh(zone);
8721 * Slaves send notifies before backing up to disk, masters after.
8723 if (zone->type == dns_zone_slave &&
8724 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8725 isc_time_compare(&now, &zone->notifytime) >= 0)
8726 zone_notify(zone, &now);
8729 * Do we need to consolidate the backing store?
8731 switch (zone->type) {
8732 case dns_zone_master:
8733 case dns_zone_slave:
8735 case dns_zone_redirect:
8738 if (zone->masterfile != NULL &&
8739 isc_time_compare(&now, &zone->dumptime) >= 0 &&
8740 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8741 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
8742 dumping = was_dumping(zone);
8747 result = zone_dump(zone, ISC_TRUE); /* task locked */
8748 if (result != ISC_R_SUCCESS)
8749 dns_zone_log(zone, ISC_LOG_WARNING,
8751 dns_result_totext(result));
8759 * Master/redirect zones send notifies now, if needed
8761 switch (zone->type) {
8762 case dns_zone_master:
8763 case dns_zone_redirect:
8764 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8765 isc_time_compare(&now, &zone->notifytime) >= 0)
8766 zone_notify(zone, &now);
8772 * Do we need to refresh keys?
8774 switch (zone->type) {
8776 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
8777 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8778 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
8779 zone_refreshkeys(zone);
8783 case dns_zone_master:
8784 if (!isc_time_isepoch(&zone->refreshkeytime) &&
8785 isc_time_compare(&now, &zone->refreshkeytime) >= 0)
8791 switch (zone->type) {
8792 case dns_zone_master:
8793 case dns_zone_redirect:
8794 case dns_zone_slave:
8796 * Do we need to sign/resign some RRsets?
8798 if (!isc_time_isepoch(&zone->signingtime) &&
8799 isc_time_compare(&now, &zone->signingtime) >= 0)
8801 else if (!isc_time_isepoch(&zone->resigntime) &&
8802 isc_time_compare(&now, &zone->resigntime) >= 0)
8803 zone_resigninc(zone);
8804 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
8805 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
8806 zone_nsec3chain(zone);
8808 * Do we need to issue a key expiry warning?
8810 if (!isc_time_isepoch(&zone->keywarntime) &&
8811 isc_time_compare(&now, &zone->keywarntime) >= 0)
8812 set_key_expiry_warning(zone, zone->key_expiry,
8813 isc_time_seconds(&now));
8819 zone_settimer(zone, &now);
8823 dns_zone_markdirty(dns_zone_t *zone) {
8824 isc_uint32_t serial;
8825 isc_result_t result = ISC_R_SUCCESS;
8828 if (zone->type == dns_zone_master) {
8829 if (inline_raw(zone)) {
8830 unsigned int soacount;
8832 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8833 if (zone->db != NULL) {
8834 result = zone_get_from_db(zone, zone->db, NULL,
8839 result = DNS_R_NOTLOADED;
8840 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8841 if (result == ISC_R_SUCCESS && soacount > 0U)
8842 zone_send_secureserial(zone, ISC_FALSE, serial);
8845 /* XXXMPA make separate call back */
8846 if (result == ISC_R_SUCCESS)
8847 set_resigntime(zone);
8849 zone_needdump(zone, DNS_DUMP_DELAY);
8854 dns_zone_expire(dns_zone_t *zone) {
8855 REQUIRE(DNS_ZONE_VALID(zone));
8863 zone_expire(dns_zone_t *zone) {
8865 * 'zone' locked by caller.
8868 REQUIRE(LOCKED_ZONE(zone));
8870 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
8872 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
8873 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
8874 zone->retry = DNS_ZONE_DEFAULTRETRY;
8875 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
8880 dns_zone_refresh(dns_zone_t *zone) {
8882 isc_uint32_t oldflags;
8884 isc_result_t result;
8886 REQUIRE(DNS_ZONE_VALID(zone));
8888 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8892 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
8893 * in progress at a time.
8897 oldflags = zone->flags;
8898 if (zone->masterscnt == 0) {
8899 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
8900 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
8901 dns_zone_log(zone, ISC_LOG_ERROR,
8902 "cannot refresh: no masters");
8905 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
8906 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
8907 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
8908 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
8912 * Set the next refresh time as if refresh check has failed.
8913 * Setting this to the retry time will do that. XXXMLG
8914 * If we are successful it will be reset using zone->refresh.
8916 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
8918 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
8919 if (result != ISC_R_SUCCESS)
8920 dns_zone_log(zone, ISC_LOG_WARNING,
8921 "isc_time_nowplusinterval() failed: %s",
8922 dns_result_totext(result));
8925 * When lacking user-specified timer values from the SOA,
8926 * do exponential backoff of the retry time up to a
8927 * maximum of six hours.
8929 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
8930 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
8932 zone->curmaster = 0;
8933 for (j = 0; j < zone->masterscnt; j++)
8934 zone->mastersok[j] = ISC_FALSE;
8935 /* initiate soa query */
8936 queue_soa_query(zone);
8942 dns_zone_flush(dns_zone_t *zone) {
8943 isc_result_t result = ISC_R_SUCCESS;
8944 isc_boolean_t dumping;
8946 REQUIRE(DNS_ZONE_VALID(zone));
8949 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
8950 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8951 zone->masterfile != NULL) {
8952 result = ISC_R_ALREADYRUNNING;
8953 dumping = was_dumping(zone);
8958 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8963 dns_zone_dump(dns_zone_t *zone) {
8964 isc_result_t result = ISC_R_ALREADYRUNNING;
8965 isc_boolean_t dumping;
8967 REQUIRE(DNS_ZONE_VALID(zone));
8970 dumping = was_dumping(zone);
8973 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8978 zone_needdump(dns_zone_t *zone, unsigned int delay) {
8979 const char me[] = "zone_needdump";
8980 isc_time_t dumptime;
8984 * 'zone' locked by caller
8987 REQUIRE(DNS_ZONE_VALID(zone));
8988 REQUIRE(LOCKED_ZONE(zone));
8992 * Do we have a place to dump to and are we loaded?
8994 if (zone->masterfile == NULL ||
8995 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
8999 /* add some noise */
9000 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
9002 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9003 if (isc_time_isepoch(&zone->dumptime) ||
9004 isc_time_compare(&zone->dumptime, &dumptime) > 0)
9005 zone->dumptime = dumptime;
9006 if (zone->task != NULL)
9007 zone_settimer(zone, &now);
9011 dump_done(void *arg, isc_result_t result) {
9012 const char me[] = "dump_done";
9013 dns_zone_t *zone = arg;
9015 dns_dbversion_t *version;
9016 isc_boolean_t again = ISC_FALSE;
9017 isc_boolean_t compact = ISC_FALSE;
9018 isc_uint32_t serial;
9019 isc_result_t tresult;
9021 REQUIRE(DNS_ZONE_VALID(zone));
9025 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
9026 zone->journalsize != -1) {
9029 * We don't own these, zone->dctx must stay valid.
9031 db = dns_dumpctx_db(zone->dctx);
9032 version = dns_dumpctx_version(zone->dctx);
9034 tresult = dns_db_getsoaserial(db, version, &serial);
9036 * If there is a secure version of this zone
9037 * use its serial if it is less than ours.
9039 if (tresult == ISC_R_SUCCESS && inline_raw(zone) &&
9040 zone->secure->db != NULL)
9042 isc_uint32_t sserial;
9043 isc_result_t mresult;
9045 mresult = dns_db_getsoaserial(zone->secure->db,
9047 if (mresult == ISC_R_SUCCESS &&
9048 isc_serial_lt(sserial, serial))
9052 * Note: we are task locked here so we can test
9055 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
9056 tresult = dns_journal_compact(zone->mctx,
9063 case ISC_R_NOTFOUND:
9064 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9065 "dns_journal_compact: %s",
9066 dns_result_totext(tresult));
9069 dns_zone_log(zone, ISC_LOG_ERROR,
9070 "dns_journal_compact failed: %s",
9071 dns_result_totext(tresult));
9074 } else if (tresult == ISC_R_SUCCESS) {
9076 zone->compact_serial = serial;
9081 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9083 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9084 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
9086 * Try again in a short while.
9088 zone_needdump(zone, DNS_DUMP_DELAY);
9089 } else if (result == ISC_R_SUCCESS &&
9090 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9091 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9092 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9093 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9094 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9095 isc_time_settoepoch(&zone->dumptime);
9097 } else if (result == ISC_R_SUCCESS)
9098 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9100 if (zone->dctx != NULL)
9101 dns_dumpctx_detach(&zone->dctx);
9102 zonemgr_putio(&zone->writeio);
9105 (void)zone_dump(zone, ISC_FALSE);
9106 dns_zone_idetach(&zone);
9110 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
9111 const char me[] = "zone_dump";
9112 isc_result_t result;
9113 dns_dbversion_t *version = NULL;
9114 isc_boolean_t again;
9115 dns_db_t *db = NULL;
9116 char *masterfile = NULL;
9117 dns_masterformat_t masterformat = dns_masterformat_none;
9120 * 'compact' MUST only be set if we are task locked.
9123 REQUIRE(DNS_ZONE_VALID(zone));
9127 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9128 if (zone->db != NULL)
9129 dns_db_attach(zone->db, &db);
9130 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9132 if (zone->masterfile != NULL) {
9133 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
9134 masterformat = zone->masterformat;
9138 result = DNS_R_NOTLOADED;
9141 if (masterfile == NULL) {
9142 result = DNS_R_NOMASTERFILE;
9146 if (compact && zone->type != dns_zone_stub) {
9147 dns_zone_t *dummy = NULL;
9149 zone_iattach(zone, &dummy);
9150 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
9151 zone_gotwritehandle, zone,
9153 if (result != ISC_R_SUCCESS)
9154 zone_idetach(&dummy);
9156 result = DNS_R_CONTINUE;
9159 dns_masterrawheader_t rawdata;
9160 dns_db_currentversion(db, &version);
9161 dns_master_initrawheader(&rawdata);
9162 if (inline_secure(zone))
9163 get_raw_serial(zone->raw, &rawdata);
9164 result = dns_master_dump3(zone->mctx, db, version,
9165 &dns_master_style_default,
9166 masterfile, masterformat,
9168 dns_db_closeversion(db, &version, ISC_FALSE);
9173 if (masterfile != NULL)
9174 isc_mem_free(zone->mctx, masterfile);
9177 if (result == DNS_R_CONTINUE)
9178 return (ISC_R_SUCCESS); /* XXXMPA */
9182 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9183 if (result != ISC_R_SUCCESS) {
9185 * Try again in a short while.
9187 zone_needdump(zone, DNS_DUMP_DELAY);
9188 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9189 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9190 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9191 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9192 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9193 isc_time_settoepoch(&zone->dumptime);
9196 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9205 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
9206 dns_masterformat_t format, const isc_uint32_t rawversion)
9208 isc_result_t result;
9209 dns_dbversion_t *version = NULL;
9210 dns_db_t *db = NULL;
9211 dns_masterrawheader_t rawdata;
9213 REQUIRE(DNS_ZONE_VALID(zone));
9215 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9216 if (zone->db != NULL)
9217 dns_db_attach(zone->db, &db);
9218 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9220 return (DNS_R_NOTLOADED);
9222 dns_db_currentversion(db, &version);
9223 dns_master_initrawheader(&rawdata);
9224 if (rawversion == 0)
9225 rawdata.flags |= DNS_MASTERRAW_COMPAT;
9226 else if (inline_secure(zone))
9227 get_raw_serial(zone->raw, &rawdata);
9228 else if (zone->sourceserialset) {
9229 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
9230 rawdata.sourceserial = zone->sourceserial;
9232 result = dns_master_dumptostream3(zone->mctx, db, version, style,
9233 format, &rawdata, fd);
9234 dns_db_closeversion(db, &version, ISC_FALSE);
9240 dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9241 const dns_master_style_t *style,
9242 const isc_uint32_t rawversion)
9244 return (dumptostream(zone, fd, style, format, rawversion));
9248 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9249 const dns_master_style_t *style) {
9250 return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
9254 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
9255 return (dumptostream(zone, fd, &dns_master_style_default,
9256 dns_masterformat_text, 0));
9260 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
9261 return (dumptostream(zone, fd, &dns_master_style_full,
9262 dns_masterformat_text, 0));
9266 dns_zone_unload(dns_zone_t *zone) {
9267 REQUIRE(DNS_ZONE_VALID(zone));
9275 notify_cancel(dns_zone_t *zone) {
9276 dns_notify_t *notify;
9279 * 'zone' locked by caller.
9282 REQUIRE(LOCKED_ZONE(zone));
9284 for (notify = ISC_LIST_HEAD(zone->notifies);
9286 notify = ISC_LIST_NEXT(notify, link)) {
9287 if (notify->find != NULL)
9288 dns_adb_cancelfind(notify->find);
9289 if (notify->request != NULL)
9290 dns_request_cancel(notify->request);
9295 forward_cancel(dns_zone_t *zone) {
9296 dns_forward_t *forward;
9299 * 'zone' locked by caller.
9302 REQUIRE(LOCKED_ZONE(zone));
9304 for (forward = ISC_LIST_HEAD(zone->forwards);
9306 forward = ISC_LIST_NEXT(forward, link)) {
9307 if (forward->request != NULL)
9308 dns_request_cancel(forward->request);
9313 zone_unload(dns_zone_t *zone) {
9316 * 'zone' locked by caller.
9319 REQUIRE(LOCKED_ZONE(zone));
9321 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
9322 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
9323 if (zone->writeio != NULL)
9324 zonemgr_cancelio(zone->writeio);
9326 if (zone->dctx != NULL)
9327 dns_dumpctx_cancel(zone->dctx);
9329 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9330 zone_detachdb(zone);
9331 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9332 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
9333 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9337 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
9338 REQUIRE(DNS_ZONE_VALID(zone));
9341 zone->minrefresh = val;
9345 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
9346 REQUIRE(DNS_ZONE_VALID(zone));
9349 zone->maxrefresh = val;
9353 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
9354 REQUIRE(DNS_ZONE_VALID(zone));
9357 zone->minretry = val;
9361 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
9362 REQUIRE(DNS_ZONE_VALID(zone));
9365 zone->maxretry = val;
9368 static isc_boolean_t
9369 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
9370 dns_notify_t *notify;
9372 for (notify = ISC_LIST_HEAD(zone->notifies);
9374 notify = ISC_LIST_NEXT(notify, link)) {
9375 if (notify->request != NULL)
9377 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
9378 dns_name_equal(name, ¬ify->ns))
9380 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
9386 static isc_boolean_t
9387 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
9388 dns_tsigkey_t *key = NULL;
9391 isc_boolean_t isself;
9392 isc_netaddr_t dstaddr;
9393 isc_result_t result;
9395 if (zone->view == NULL || zone->isself == NULL)
9398 switch (isc_sockaddr_pf(dst)) {
9400 src = zone->notifysrc4;
9401 isc_sockaddr_any(&any);
9404 src = zone->notifysrc6;
9405 isc_sockaddr_any6(&any);
9412 * When sending from any the kernel will assign a source address
9413 * that matches the destination address.
9415 if (isc_sockaddr_eqaddr(&any, &src))
9418 isc_netaddr_fromsockaddr(&dstaddr, dst);
9419 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
9420 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
9422 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
9425 dns_tsigkey_detach(&key);
9430 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
9434 * Caller holds zone lock.
9436 REQUIRE(DNS_NOTIFY_VALID(notify));
9438 if (notify->zone != NULL) {
9440 LOCK_ZONE(notify->zone);
9441 REQUIRE(LOCKED_ZONE(notify->zone));
9442 if (ISC_LINK_LINKED(notify, link))
9443 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
9445 UNLOCK_ZONE(notify->zone);
9447 zone_idetach(¬ify->zone);
9449 dns_zone_idetach(¬ify->zone);
9451 if (notify->find != NULL)
9452 dns_adb_destroyfind(¬ify->find);
9453 if (notify->request != NULL)
9454 dns_request_destroy(¬ify->request);
9455 if (dns_name_dynamic(¬ify->ns))
9456 dns_name_free(¬ify->ns, notify->mctx);
9457 if (notify->key != NULL)
9458 dns_tsigkey_detach(¬ify->key);
9459 mctx = notify->mctx;
9460 isc_mem_put(notify->mctx, notify, sizeof(*notify));
9461 isc_mem_detach(&mctx);
9465 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
9466 dns_notify_t *notify;
9468 REQUIRE(notifyp != NULL && *notifyp == NULL);
9470 notify = isc_mem_get(mctx, sizeof(*notify));
9472 return (ISC_R_NOMEMORY);
9474 notify->mctx = NULL;
9475 isc_mem_attach(mctx, ¬ify->mctx);
9476 notify->flags = flags;
9477 notify->zone = NULL;
9478 notify->find = NULL;
9479 notify->request = NULL;
9481 isc_sockaddr_any(¬ify->dst);
9482 dns_name_init(¬ify->ns, NULL);
9483 ISC_LINK_INIT(notify, link);
9484 notify->magic = NOTIFY_MAGIC;
9486 return (ISC_R_SUCCESS);
9490 * XXXAG should check for DNS_ZONEFLG_EXITING
9493 process_adb_event(isc_task_t *task, isc_event_t *ev) {
9494 dns_notify_t *notify;
9495 isc_eventtype_t result;
9499 notify = ev->ev_arg;
9500 REQUIRE(DNS_NOTIFY_VALID(notify));
9501 INSIST(task == notify->zone->task);
9502 result = ev->ev_type;
9503 isc_event_free(&ev);
9504 if (result == DNS_EVENT_ADBMOREADDRESSES) {
9505 dns_adb_destroyfind(¬ify->find);
9506 notify_find_address(notify);
9509 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
9510 LOCK_ZONE(notify->zone);
9511 notify_send(notify);
9512 UNLOCK_ZONE(notify->zone);
9514 notify_destroy(notify, ISC_FALSE);
9518 notify_find_address(dns_notify_t *notify) {
9519 isc_result_t result;
9520 unsigned int options;
9522 REQUIRE(DNS_NOTIFY_VALID(notify));
9523 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
9524 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
9526 if (notify->zone->view->adb == NULL)
9529 result = dns_adb_createfind(notify->zone->view->adb,
9531 process_adb_event, notify,
9532 ¬ify->ns, dns_rootname, 0,
9534 notify->zone->view->dstport,
9537 /* Something failed? */
9538 if (result != ISC_R_SUCCESS)
9541 /* More addresses pending? */
9542 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
9545 /* We have as many addresses as we can get. */
9546 LOCK_ZONE(notify->zone);
9547 notify_send(notify);
9548 UNLOCK_ZONE(notify->zone);
9551 notify_destroy(notify, ISC_FALSE);
9556 notify_send_queue(dns_notify_t *notify) {
9558 isc_result_t result;
9560 e = isc_event_allocate(notify->mctx, NULL,
9561 DNS_EVENT_NOTIFYSENDTOADDR,
9563 notify, sizeof(isc_event_t));
9565 return (ISC_R_NOMEMORY);
9567 e->ev_sender = NULL;
9568 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
9569 notify->zone->task, &e);
9570 if (result != ISC_R_SUCCESS)
9576 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
9577 dns_notify_t *notify;
9578 isc_result_t result;
9579 dns_message_t *message = NULL;
9580 isc_netaddr_t dstip;
9581 dns_tsigkey_t *key = NULL;
9582 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9585 isc_boolean_t have_notifysource = ISC_FALSE;
9587 notify = event->ev_arg;
9588 REQUIRE(DNS_NOTIFY_VALID(notify));
9592 LOCK_ZONE(notify->zone);
9594 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
9595 result = ISC_R_CANCELED;
9599 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
9600 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
9601 notify->zone->view->requestmgr == NULL ||
9602 notify->zone->db == NULL) {
9603 result = ISC_R_CANCELED;
9608 * The raw IPv4 address should also exist. Don't send to the
9611 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
9612 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
9613 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9614 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9615 "notify: ignoring IPv6 mapped IPV4 address: %s",
9617 result = ISC_R_CANCELED;
9621 result = notify_createmessage(notify->zone, notify->flags, &message);
9622 if (result != ISC_R_SUCCESS)
9625 if (notify->key != NULL) {
9626 /* Transfer ownership of key */
9630 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
9631 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9632 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
9633 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
9634 notify_log(notify->zone, ISC_LOG_ERROR,
9635 "NOTIFY to %s not sent. "
9636 "Peer TSIG key lookup failure.", addrbuf);
9637 goto cleanup_message;
9641 /* XXX: should we log the tsig key too? */
9642 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
9644 if (notify->zone->view->peers != NULL) {
9645 dns_peer_t *peer = NULL;
9646 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
9648 if (result == ISC_R_SUCCESS) {
9649 result = dns_peer_getnotifysource(peer, &src);
9650 if (result == ISC_R_SUCCESS)
9651 have_notifysource = ISC_TRUE;
9654 switch (isc_sockaddr_pf(¬ify->dst)) {
9656 if (!have_notifysource)
9657 src = notify->zone->notifysrc4;
9660 if (!have_notifysource)
9661 src = notify->zone->notifysrc6;
9664 result = ISC_R_NOTIMPLEMENTED;
9668 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
9670 result = dns_request_createvia2(notify->zone->view->requestmgr,
9671 message, &src, ¬ify->dst, 0, key,
9672 timeout * 3, timeout,
9673 notify->zone->task, notify_done,
9674 notify, ¬ify->request);
9675 if (result == ISC_R_SUCCESS) {
9676 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
9677 inc_stats(notify->zone,
9678 dns_zonestatscounter_notifyoutv4);
9680 inc_stats(notify->zone,
9681 dns_zonestatscounter_notifyoutv6);
9687 dns_tsigkey_detach(&key);
9689 dns_message_destroy(&message);
9691 UNLOCK_ZONE(notify->zone);
9692 isc_event_free(&event);
9693 if (result != ISC_R_SUCCESS)
9694 notify_destroy(notify, ISC_FALSE);
9698 notify_send(dns_notify_t *notify) {
9699 dns_adbaddrinfo_t *ai;
9701 isc_result_t result;
9702 dns_notify_t *new = NULL;
9705 * Zone lock held by caller.
9707 REQUIRE(DNS_NOTIFY_VALID(notify));
9708 REQUIRE(LOCKED_ZONE(notify->zone));
9710 for (ai = ISC_LIST_HEAD(notify->find->list);
9712 ai = ISC_LIST_NEXT(ai, publink)) {
9714 if (notify_isqueued(notify->zone, NULL, &dst))
9716 if (notify_isself(notify->zone, &dst))
9719 result = notify_create(notify->mctx,
9720 (notify->flags & DNS_NOTIFY_NOSOA),
9722 if (result != ISC_R_SUCCESS)
9724 zone_iattach(notify->zone, &new->zone);
9725 ISC_LIST_APPEND(new->zone->notifies, new, link);
9727 result = notify_send_queue(new);
9728 if (result != ISC_R_SUCCESS)
9735 notify_destroy(new, ISC_TRUE);
9739 dns_zone_notify(dns_zone_t *zone) {
9742 REQUIRE(DNS_ZONE_VALID(zone));
9745 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9748 zone_settimer(zone, &now);
9753 zone_notify(dns_zone_t *zone, isc_time_t *now) {
9754 dns_dbnode_t *node = NULL;
9755 dns_db_t *zonedb = NULL;
9756 dns_dbversion_t *version = NULL;
9757 dns_name_t *origin = NULL;
9760 dns_rdata_soa_t soa;
9761 isc_uint32_t serial;
9762 dns_rdata_t rdata = DNS_RDATA_INIT;
9763 dns_rdataset_t nsrdset;
9764 dns_rdataset_t soardset;
9765 isc_result_t result;
9766 dns_notify_t *notify = NULL;
9769 isc_boolean_t isqueued;
9770 dns_notifytype_t notifytype;
9771 unsigned int flags = 0;
9772 isc_boolean_t loggednotify = ISC_FALSE;
9774 REQUIRE(DNS_ZONE_VALID(zone));
9777 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9778 notifytype = zone->notifytype;
9779 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
9782 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
9785 if (notifytype == dns_notifytype_no)
9788 if (notifytype == dns_notifytype_masteronly &&
9789 zone->type != dns_zone_master)
9792 origin = &zone->origin;
9795 * If the zone is dialup we are done as we don't want to send
9796 * the current soa so as to force a refresh query.
9798 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
9799 flags |= DNS_NOTIFY_NOSOA;
9804 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9805 if (zone->db != NULL)
9806 dns_db_attach(zone->db, &zonedb);
9807 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9810 dns_db_currentversion(zonedb, &version);
9811 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
9812 if (result != ISC_R_SUCCESS)
9815 dns_rdataset_init(&soardset);
9816 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
9817 dns_rdatatype_none, 0, &soardset, NULL);
9818 if (result != ISC_R_SUCCESS)
9822 * Find serial and master server's name.
9824 dns_name_init(&master, NULL);
9825 result = dns_rdataset_first(&soardset);
9826 if (result != ISC_R_SUCCESS)
9828 dns_rdataset_current(&soardset, &rdata);
9829 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9830 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9831 dns_rdata_reset(&rdata);
9832 result = dns_name_dup(&soa.origin, zone->mctx, &master);
9833 serial = soa.serial;
9834 dns_rdataset_disassociate(&soardset);
9835 if (result != ISC_R_SUCCESS)
9839 * Enqueue notify requests for 'also-notify' servers.
9842 for (i = 0; i < zone->notifycnt; i++) {
9843 dns_tsigkey_t *key = NULL;
9845 dst = zone->notify[i];
9846 if (notify_isqueued(zone, NULL, &dst))
9849 result = notify_create(zone->mctx, flags, ¬ify);
9850 if (result != ISC_R_SUCCESS)
9853 zone_iattach(zone, ¬ify->zone);
9856 if ((zone->notifykeynames != NULL) &&
9857 (zone->notifykeynames[i] != NULL)) {
9858 dns_view_t *view = dns_zone_getview(zone);
9859 dns_name_t *keyname = zone->notifykeynames[i];
9860 result = dns_view_gettsig(view, keyname, &key);
9861 if (result == ISC_R_SUCCESS) {
9867 ISC_LIST_APPEND(zone->notifies, notify, link);
9868 result = notify_send_queue(notify);
9869 if (result != ISC_R_SUCCESS)
9870 notify_destroy(notify, ISC_TRUE);
9871 if (!loggednotify) {
9872 notify_log(zone, ISC_LOG_INFO,
9873 "sending notifies (serial %u)",
9875 loggednotify = ISC_TRUE;
9881 if (notifytype == dns_notifytype_explicit)
9885 * Process NS RRset to generate notifies.
9888 dns_rdataset_init(&nsrdset);
9889 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
9890 dns_rdatatype_none, 0, &nsrdset, NULL);
9891 if (result != ISC_R_SUCCESS)
9894 result = dns_rdataset_first(&nsrdset);
9895 while (result == ISC_R_SUCCESS) {
9896 dns_rdataset_current(&nsrdset, &rdata);
9897 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9898 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9899 dns_rdata_reset(&rdata);
9901 * Don't notify the master server unless explicitly
9902 * configured to do so.
9904 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
9905 dns_name_compare(&master, &ns.name) == 0) {
9906 result = dns_rdataset_next(&nsrdset);
9910 if (!loggednotify) {
9911 notify_log(zone, ISC_LOG_INFO,
9912 "sending notifies (serial %u)",
9914 loggednotify = ISC_TRUE;
9918 isqueued = notify_isqueued(zone, &ns.name, NULL);
9921 result = dns_rdataset_next(&nsrdset);
9924 result = notify_create(zone->mctx, flags, ¬ify);
9925 if (result != ISC_R_SUCCESS)
9927 dns_zone_iattach(zone, ¬ify->zone);
9928 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
9929 if (result != ISC_R_SUCCESS) {
9931 notify_destroy(notify, ISC_TRUE);
9936 ISC_LIST_APPEND(zone->notifies, notify, link);
9938 notify_find_address(notify);
9940 result = dns_rdataset_next(&nsrdset);
9942 dns_rdataset_disassociate(&nsrdset);
9945 if (dns_name_dynamic(&master))
9946 dns_name_free(&master, zone->mctx);
9948 dns_db_detachnode(zonedb, &node);
9950 dns_db_closeversion(zonedb, &version, ISC_FALSE);
9951 dns_db_detach(&zonedb);
9958 static inline isc_result_t
9959 save_nsrrset(dns_message_t *message, dns_name_t *name,
9960 dns_db_t *db, dns_dbversion_t *version)
9962 dns_rdataset_t *nsrdataset = NULL;
9963 dns_rdataset_t *rdataset = NULL;
9964 dns_dbnode_t *node = NULL;
9966 isc_result_t result;
9967 dns_rdata_t rdata = DNS_RDATA_INIT;
9970 * Extract NS RRset from message.
9972 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
9973 dns_rdatatype_ns, dns_rdatatype_none,
9975 if (result != ISC_R_SUCCESS)
9981 result = dns_db_findnode(db, name, ISC_TRUE, &node);
9982 if (result != ISC_R_SUCCESS)
9984 result = dns_db_addrdataset(db, node, version, 0,
9985 nsrdataset, 0, NULL);
9986 dns_db_detachnode(db, &node);
9987 if (result != ISC_R_SUCCESS)
9990 * Add glue rdatasets.
9992 for (result = dns_rdataset_first(nsrdataset);
9993 result == ISC_R_SUCCESS;
9994 result = dns_rdataset_next(nsrdataset)) {
9995 dns_rdataset_current(nsrdataset, &rdata);
9996 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9997 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9998 dns_rdata_reset(&rdata);
9999 if (!dns_name_issubdomain(&ns.name, name))
10002 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10003 &ns.name, dns_rdatatype_aaaa,
10004 dns_rdatatype_none, NULL,
10006 if (result == ISC_R_SUCCESS) {
10007 result = dns_db_findnode(db, &ns.name,
10009 if (result != ISC_R_SUCCESS)
10011 result = dns_db_addrdataset(db, node, version, 0,
10012 rdataset, 0, NULL);
10013 dns_db_detachnode(db, &node);
10014 if (result != ISC_R_SUCCESS)
10018 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10019 &ns.name, dns_rdatatype_a,
10020 dns_rdatatype_none, NULL,
10022 if (result == ISC_R_SUCCESS) {
10023 result = dns_db_findnode(db, &ns.name,
10025 if (result != ISC_R_SUCCESS)
10027 result = dns_db_addrdataset(db, node, version, 0,
10028 rdataset, 0, NULL);
10029 dns_db_detachnode(db, &node);
10030 if (result != ISC_R_SUCCESS)
10034 if (result != ISC_R_NOMORE)
10037 return (ISC_R_SUCCESS);
10044 stub_callback(isc_task_t *task, isc_event_t *event) {
10045 const char me[] = "stub_callback";
10046 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10047 dns_stub_t *stub = NULL;
10048 dns_message_t *msg = NULL;
10049 dns_zone_t *zone = NULL;
10050 char master[ISC_SOCKADDR_FORMATSIZE];
10051 char source[ISC_SOCKADDR_FORMATSIZE];
10052 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
10053 isc_result_t result;
10055 isc_boolean_t exiting = ISC_FALSE;
10057 unsigned int j, soacount;
10059 stub = revent->ev_arg;
10060 INSIST(DNS_STUB_VALID(stub));
10072 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10073 zone_debuglog(zone, me, 1, "exiting");
10074 exiting = ISC_TRUE;
10078 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10079 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10081 if (revent->result != ISC_R_SUCCESS) {
10082 if (revent->result == ISC_R_TIMEDOUT &&
10083 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10084 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10085 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10086 "refreshing stub: timeout retrying "
10087 " without EDNS master %s (source %s)",
10091 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
10092 &zone->sourceaddr, &now);
10093 dns_zone_log(zone, ISC_LOG_INFO,
10094 "could not refresh stub from master %s"
10095 " (source %s): %s", master, source,
10096 dns_result_totext(revent->result));
10100 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10101 if (result != ISC_R_SUCCESS)
10104 result = dns_request_getresponse(revent->request, msg, 0);
10105 if (result != ISC_R_SUCCESS)
10109 * Unexpected rcode.
10111 if (msg->rcode != dns_rcode_noerror) {
10115 isc_buffer_init(&rb, rcode, sizeof(rcode));
10116 (void)dns_rcode_totext(msg->rcode, &rb);
10118 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10119 (msg->rcode == dns_rcode_servfail ||
10120 msg->rcode == dns_rcode_notimp ||
10121 msg->rcode == dns_rcode_formerr)) {
10122 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10123 "refreshing stub: rcode (%.*s) retrying "
10124 "without EDNS master %s (source %s)",
10125 (int)rb.used, rcode, master, source);
10126 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10130 dns_zone_log(zone, ISC_LOG_INFO,
10131 "refreshing stub: "
10132 "unexpected rcode (%.*s) from %s (source %s)",
10133 (int)rb.used, rcode, master, source);
10138 * We need complete messages.
10140 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10141 if (dns_request_usedtcp(revent->request)) {
10142 dns_zone_log(zone, ISC_LOG_INFO,
10143 "refreshing stub: truncated TCP "
10144 "response from master %s (source %s)",
10148 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10153 * If non-auth log and next master.
10155 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10156 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10157 "non-authoritative answer from "
10158 "master %s (source %s)", master, source);
10165 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10166 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
10168 if (cnamecnt != 0) {
10169 dns_zone_log(zone, ISC_LOG_INFO,
10170 "refreshing stub: unexpected CNAME response "
10171 "from master %s (source %s)", master, source);
10176 dns_zone_log(zone, ISC_LOG_INFO,
10177 "refreshing stub: no NS records in response "
10178 "from master %s (source %s)", master, source);
10185 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
10186 if (result != ISC_R_SUCCESS) {
10187 dns_zone_log(zone, ISC_LOG_INFO,
10188 "refreshing stub: unable to save NS records "
10189 "from master %s (source %s)", master, source);
10196 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
10197 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
10198 if (zone->db == NULL)
10199 zone_attachdb(zone, stub->db);
10200 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
10201 &refresh, &retry, &expire, NULL, NULL);
10202 if (result == ISC_R_SUCCESS && soacount > 0U) {
10203 zone->refresh = RANGE(refresh, zone->minrefresh,
10205 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
10206 zone->expire = RANGE(expire, zone->refresh + zone->retry,
10208 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
10210 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
10211 dns_db_detach(&stub->db);
10213 dns_message_destroy(&msg);
10214 isc_event_free(&event);
10215 dns_request_destroy(&zone->request);
10217 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10218 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
10219 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10220 isc_interval_set(&i, zone->expire, 0);
10221 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10223 if (zone->masterfile != NULL)
10224 zone_needdump(zone, 0);
10226 zone_settimer(zone, &now);
10230 if (stub->version != NULL)
10231 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
10232 if (stub->db != NULL)
10233 dns_db_detach(&stub->db);
10235 dns_message_destroy(&msg);
10236 isc_event_free(&event);
10237 dns_request_destroy(&zone->request);
10239 * Skip to next failed / untried master.
10243 } while (zone->curmaster < zone->masterscnt &&
10244 zone->mastersok[zone->curmaster]);
10245 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10246 if (exiting || zone->curmaster >= zone->masterscnt) {
10247 isc_boolean_t done = ISC_TRUE;
10249 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10250 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10252 * Did we get a good answer from all the masters?
10254 for (j = 0; j < zone->masterscnt; j++)
10255 if (zone->mastersok[j] == ISC_FALSE) {
10262 zone->curmaster = 0;
10264 * Find the next failed master.
10266 while (zone->curmaster < zone->masterscnt &&
10267 zone->mastersok[zone->curmaster])
10269 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10271 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10273 zone_settimer(zone, &now);
10277 queue_soa_query(zone);
10282 dns_message_destroy(&msg);
10283 isc_event_free(&event);
10284 dns_request_destroy(&zone->request);
10285 ns_query(zone, NULL, stub);
10292 dns_zone_idetach(&stub->zone);
10293 INSIST(stub->db == NULL);
10294 INSIST(stub->version == NULL);
10295 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10298 INSIST(event == NULL);
10303 * An SOA query has finished (successfully or not).
10306 refresh_callback(isc_task_t *task, isc_event_t *event) {
10307 const char me[] = "refresh_callback";
10308 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10310 dns_message_t *msg = NULL;
10311 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
10313 char master[ISC_SOCKADDR_FORMATSIZE];
10314 char source[ISC_SOCKADDR_FORMATSIZE];
10315 dns_rdataset_t *rdataset = NULL;
10316 dns_rdata_t rdata = DNS_RDATA_INIT;
10317 dns_rdata_soa_t soa;
10318 isc_result_t result;
10319 isc_uint32_t serial, oldserial = 0;
10321 isc_boolean_t do_queue_xfrin = ISC_FALSE;
10323 zone = revent->ev_arg;
10324 INSIST(DNS_ZONE_VALID(zone));
10335 * if timeout log and next master;
10338 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10339 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10341 if (revent->result != ISC_R_SUCCESS) {
10342 if (revent->result == ISC_R_TIMEDOUT &&
10343 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10344 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10345 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10346 "refresh: timeout retrying without EDNS "
10347 "master %s (source %s)", master, source);
10350 if (revent->result == ISC_R_TIMEDOUT &&
10351 !dns_request_usedtcp(revent->request)) {
10352 dns_zone_log(zone, ISC_LOG_INFO,
10353 "refresh: retry limit for "
10354 "master %s exceeded (source %s)",
10356 /* Try with slave with TCP. */
10357 if ((zone->type == dns_zone_slave ||
10358 zone->type == dns_zone_redirect) &&
10359 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
10360 if (!dns_zonemgr_unreachable(zone->zmgr,
10365 DNS_ZONE_SETFLAG(zone,
10366 DNS_ZONEFLG_SOABEFOREAXFR);
10369 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10370 "refresh: skipped tcp fallback "
10371 "as master %s (source %s) is "
10372 "unreachable (cached)",
10376 dns_zone_log(zone, ISC_LOG_INFO,
10377 "refresh: failure trying master "
10378 "%s (source %s): %s", master, source,
10379 dns_result_totext(revent->result));
10383 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10384 if (result != ISC_R_SUCCESS)
10386 result = dns_request_getresponse(revent->request, msg, 0);
10387 if (result != ISC_R_SUCCESS) {
10388 dns_zone_log(zone, ISC_LOG_INFO,
10389 "refresh: failure trying master "
10390 "%s (source %s): %s", master, source,
10391 dns_result_totext(result));
10396 * Unexpected rcode.
10398 if (msg->rcode != dns_rcode_noerror) {
10402 isc_buffer_init(&rb, rcode, sizeof(rcode));
10403 (void)dns_rcode_totext(msg->rcode, &rb);
10405 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10406 (msg->rcode == dns_rcode_servfail ||
10407 msg->rcode == dns_rcode_notimp ||
10408 msg->rcode == dns_rcode_formerr)) {
10409 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10410 "refresh: rcode (%.*s) retrying without "
10411 "EDNS master %s (source %s)",
10412 (int)rb.used, rcode, master, source);
10413 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10416 dns_zone_log(zone, ISC_LOG_INFO,
10417 "refresh: unexpected rcode (%.*s) from "
10418 "master %s (source %s)", (int)rb.used, rcode,
10421 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
10423 if (msg->rcode == dns_rcode_refused &&
10424 (zone->type == dns_zone_slave ||
10425 zone->type == dns_zone_redirect))
10431 * If truncated punt to zone transfer which will query again.
10433 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10434 if (zone->type == dns_zone_slave ||
10435 zone->type == dns_zone_redirect) {
10436 dns_zone_log(zone, ISC_LOG_INFO,
10437 "refresh: truncated UDP answer, "
10438 "initiating TCP zone xfer "
10439 "for master %s (source %s)",
10441 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
10444 INSIST(zone->type == dns_zone_stub);
10445 if (dns_request_usedtcp(revent->request)) {
10446 dns_zone_log(zone, ISC_LOG_INFO,
10447 "refresh: truncated TCP response "
10448 "from master %s (source %s)",
10452 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10458 * if non-auth log and next master;
10460 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10461 dns_zone_log(zone, ISC_LOG_INFO,
10462 "refresh: non-authoritative answer from "
10463 "master %s (source %s)", master, source);
10467 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10468 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
10469 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
10470 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
10471 dns_rdatatype_soa);
10474 * There should not be a CNAME record at top of zone.
10476 if (cnamecnt != 0) {
10477 dns_zone_log(zone, ISC_LOG_INFO,
10478 "refresh: CNAME at top of zone "
10479 "in master %s (source %s)", master, source);
10484 * if referral log and next master;
10486 if (soacnt == 0 && soacount == 0 && nscount != 0) {
10487 dns_zone_log(zone, ISC_LOG_INFO,
10488 "refresh: referral response "
10489 "from master %s (source %s)", master, source);
10494 * if nodata log and next master;
10496 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
10497 dns_zone_log(zone, ISC_LOG_INFO,
10498 "refresh: NODATA response "
10499 "from master %s (source %s)", master, source);
10504 * Only one soa at top of zone.
10507 dns_zone_log(zone, ISC_LOG_INFO,
10508 "refresh: answer SOA count (%d) != 1 "
10509 "from master %s (source %s)",
10510 soacnt, master, source);
10518 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
10519 dns_rdatatype_soa, dns_rdatatype_none,
10521 if (result != ISC_R_SUCCESS) {
10522 dns_zone_log(zone, ISC_LOG_INFO,
10523 "refresh: unable to get SOA record "
10524 "from master %s (source %s)", master, source);
10528 result = dns_rdataset_first(rdataset);
10529 if (result != ISC_R_SUCCESS) {
10530 dns_zone_log(zone, ISC_LOG_INFO,
10531 "refresh: dns_rdataset_first() failed");
10535 dns_rdataset_current(rdataset, &rdata);
10536 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10537 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10539 serial = soa.serial;
10540 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10541 unsigned int soacount;
10542 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
10543 &oldserial, NULL, NULL, NULL, NULL,
10545 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10546 RUNTIME_CHECK(soacount > 0U);
10547 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
10548 serial, oldserial);
10550 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
10553 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
10554 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
10555 isc_serial_gt(serial, oldserial)) {
10556 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10557 &zone->sourceaddr, &now))
10559 dns_zone_log(zone, ISC_LOG_INFO,
10560 "refresh: skipping %s as master %s "
10561 "(source %s) is unreachable (cached)",
10562 (zone->type == dns_zone_slave ||
10563 zone->type == dns_zone_redirect) ?
10564 "zone transfer" : "NS query",
10569 isc_event_free(&event);
10570 dns_request_destroy(&zone->request);
10571 if (zone->type == dns_zone_slave ||
10572 zone->type == dns_zone_redirect) {
10573 do_queue_xfrin = ISC_TRUE;
10575 INSIST(zone->type == dns_zone_stub);
10576 ns_query(zone, rdataset, NULL);
10579 dns_message_destroy(&msg);
10580 } else if (isc_serial_eq(soa.serial, oldserial)) {
10581 if (zone->masterfile != NULL) {
10582 result = ISC_R_FAILURE;
10583 if (zone->journal != NULL)
10584 result = isc_file_settime(zone->journal, &now);
10585 if (result == ISC_R_SUCCESS &&
10586 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10587 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10588 result = isc_file_settime(zone->masterfile,
10590 } else if (result != ISC_R_SUCCESS)
10591 result = isc_file_settime(zone->masterfile,
10593 /* Someone removed the file from underneath us! */
10594 if (result == ISC_R_FILENOTFOUND) {
10595 zone_needdump(zone, DNS_DUMP_DELAY);
10596 } else if (result != ISC_R_SUCCESS)
10597 dns_zone_log(zone, ISC_LOG_ERROR,
10598 "refresh: could not set file "
10599 "modification time of '%s': %s",
10601 dns_result_totext(result));
10603 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10604 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10605 zone->mastersok[zone->curmaster] = ISC_TRUE;
10608 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
10609 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
10610 "received from master %s < ours (%u)",
10611 soa.serial, master, oldserial);
10613 zone_debuglog(zone, me, 1, "ahead");
10614 zone->mastersok[zone->curmaster] = ISC_TRUE;
10618 dns_message_destroy(&msg);
10623 dns_message_destroy(&msg);
10624 isc_event_free(&event);
10625 dns_request_destroy(&zone->request);
10627 * Skip to next failed / untried master.
10631 } while (zone->curmaster < zone->masterscnt &&
10632 zone->mastersok[zone->curmaster]);
10633 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10634 if (zone->curmaster >= zone->masterscnt) {
10635 isc_boolean_t done = ISC_TRUE;
10636 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10637 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10639 * Did we get a good answer from all the masters?
10641 for (j = 0; j < zone->masterscnt; j++)
10642 if (zone->mastersok[j] == ISC_FALSE) {
10649 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10650 zone->curmaster = 0;
10652 * Find the next failed master.
10654 while (zone->curmaster < zone->masterscnt &&
10655 zone->mastersok[zone->curmaster])
10659 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10660 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
10661 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
10662 zone->refreshtime = now;
10664 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10665 zone_settimer(zone, &now);
10670 queue_soa_query(zone);
10675 dns_message_destroy(&msg);
10676 isc_event_free(&event);
10677 dns_request_destroy(&zone->request);
10678 queue_soa_query(zone);
10682 if (do_queue_xfrin)
10684 dns_zone_idetach(&zone);
10689 queue_soa_query(dns_zone_t *zone) {
10690 const char me[] = "queue_soa_query";
10692 dns_zone_t *dummy = NULL;
10693 isc_result_t result;
10699 REQUIRE(LOCKED_ZONE(zone));
10701 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10702 cancel_refresh(zone);
10706 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
10707 soa_query, zone, sizeof(isc_event_t));
10709 cancel_refresh(zone);
10714 * Attach so that we won't clean up
10715 * until the event is delivered.
10717 zone_iattach(zone, &dummy);
10720 e->ev_sender = NULL;
10721 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
10722 if (result != ISC_R_SUCCESS) {
10723 zone_idetach(&dummy);
10724 isc_event_free(&e);
10725 cancel_refresh(zone);
10729 static inline isc_result_t
10730 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
10731 dns_message_t **messagep)
10733 dns_message_t *message = NULL;
10734 dns_name_t *qname = NULL;
10735 dns_rdataset_t *qrdataset = NULL;
10736 isc_result_t result;
10738 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10740 if (result != ISC_R_SUCCESS)
10743 message->opcode = dns_opcode_query;
10744 message->rdclass = zone->rdclass;
10746 result = dns_message_gettempname(message, &qname);
10747 if (result != ISC_R_SUCCESS)
10750 result = dns_message_gettemprdataset(message, &qrdataset);
10751 if (result != ISC_R_SUCCESS)
10757 dns_name_init(qname, NULL);
10758 dns_name_clone(&zone->origin, qname);
10759 dns_rdataset_init(qrdataset);
10760 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
10761 ISC_LIST_APPEND(qname->list, qrdataset, link);
10762 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
10764 *messagep = message;
10765 return (ISC_R_SUCCESS);
10769 dns_message_puttempname(message, &qname);
10770 if (qrdataset != NULL)
10771 dns_message_puttemprdataset(message, &qrdataset);
10772 if (message != NULL)
10773 dns_message_destroy(&message);
10777 static isc_result_t
10778 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
10779 dns_rdataset_t *rdataset = NULL;
10780 dns_rdatalist_t *rdatalist = NULL;
10781 dns_rdata_t *rdata = NULL;
10782 isc_result_t result;
10784 result = dns_message_gettemprdatalist(message, &rdatalist);
10785 if (result != ISC_R_SUCCESS)
10787 result = dns_message_gettemprdata(message, &rdata);
10788 if (result != ISC_R_SUCCESS)
10790 result = dns_message_gettemprdataset(message, &rdataset);
10791 if (result != ISC_R_SUCCESS)
10793 dns_rdataset_init(rdataset);
10795 rdatalist->type = dns_rdatatype_opt;
10796 rdatalist->covers = 0;
10799 * Set Maximum UDP buffer size.
10801 rdatalist->rdclass = udpsize;
10804 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
10806 rdatalist->ttl = 0;
10808 /* Set EDNS options if applicable */
10810 unsigned char data[4];
10813 isc_buffer_init(&buf, data, sizeof(data));
10814 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
10815 isc_buffer_putuint16(&buf, 0);
10816 rdata->data = data;
10817 rdata->length = sizeof(data);
10819 rdata->data = NULL;
10823 rdata->rdclass = rdatalist->rdclass;
10824 rdata->type = rdatalist->type;
10827 ISC_LIST_INIT(rdatalist->rdata);
10828 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
10829 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
10832 return (dns_message_setopt(message, rdataset));
10835 if (rdatalist != NULL)
10836 dns_message_puttemprdatalist(message, &rdatalist);
10837 if (rdataset != NULL)
10838 dns_message_puttemprdataset(message, &rdataset);
10840 dns_message_puttemprdata(message, &rdata);
10846 soa_query(isc_task_t *task, isc_event_t *event) {
10847 const char me[] = "soa_query";
10848 isc_result_t result = ISC_R_FAILURE;
10849 dns_message_t *message = NULL;
10850 dns_zone_t *zone = event->ev_arg;
10851 dns_zone_t *dummy = NULL;
10852 isc_netaddr_t masterip;
10853 dns_tsigkey_t *key = NULL;
10854 isc_uint32_t options;
10855 isc_boolean_t cancel = ISC_TRUE;
10857 isc_boolean_t have_xfrsource, reqnsid;
10858 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10860 REQUIRE(DNS_ZONE_VALID(zone));
10867 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
10868 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
10869 zone->view->requestmgr == NULL) {
10870 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10871 cancel = ISC_FALSE;
10876 * XXX Optimisation: Create message when zone is setup and reuse.
10878 result = create_query(zone, dns_rdatatype_soa, &message);
10879 if (result != ISC_R_SUCCESS)
10883 INSIST(zone->masterscnt > 0);
10884 INSIST(zone->curmaster < zone->masterscnt);
10886 zone->masteraddr = zone->masters[zone->curmaster];
10888 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10890 * First, look for a tsig key in the master statement, then
10891 * try for a server key.
10893 if ((zone->masterkeynames != NULL) &&
10894 (zone->masterkeynames[zone->curmaster] != NULL)) {
10895 dns_view_t *view = dns_zone_getview(zone);
10896 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10897 result = dns_view_gettsig(view, keyname, &key);
10898 if (result != ISC_R_SUCCESS) {
10899 char namebuf[DNS_NAME_FORMATSIZE];
10900 dns_name_format(keyname, namebuf, sizeof(namebuf));
10901 dns_zone_log(zone, ISC_LOG_ERROR,
10902 "unable to find key: %s", namebuf);
10907 result = dns_view_getpeertsig(zone->view, &masterip, &key);
10908 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10909 char addrbuf[ISC_NETADDR_FORMATSIZE];
10910 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
10911 dns_zone_log(zone, ISC_LOG_ERROR,
10912 "unable to find TSIG key for %s", addrbuf);
10917 have_xfrsource = ISC_FALSE;
10918 reqnsid = zone->view->requestnsid;
10919 if (zone->view->peers != NULL) {
10920 dns_peer_t *peer = NULL;
10921 isc_boolean_t edns;
10922 result = dns_peerlist_peerbyaddr(zone->view->peers,
10924 if (result == ISC_R_SUCCESS) {
10925 result = dns_peer_getsupportedns(peer, &edns);
10926 if (result == ISC_R_SUCCESS && !edns)
10927 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10928 result = dns_peer_gettransfersource(peer,
10929 &zone->sourceaddr);
10930 if (result == ISC_R_SUCCESS)
10931 have_xfrsource = ISC_TRUE;
10932 if (zone->view->resolver != NULL)
10934 dns_resolver_getudpsize(zone->view->resolver);
10935 (void)dns_peer_getudpsize(peer, &udpsize);
10936 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10940 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10942 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10943 if (isc_sockaddr_equal(&zone->altxfrsource4,
10944 &zone->xfrsource4))
10946 zone->sourceaddr = zone->altxfrsource4;
10947 } else if (!have_xfrsource)
10948 zone->sourceaddr = zone->xfrsource4;
10951 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10952 if (isc_sockaddr_equal(&zone->altxfrsource6,
10953 &zone->xfrsource6))
10955 zone->sourceaddr = zone->altxfrsource6;
10956 } else if (!have_xfrsource)
10957 zone->sourceaddr = zone->xfrsource6;
10960 result = ISC_R_NOTIMPLEMENTED;
10964 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
10965 DNS_REQUESTOPT_TCP : 0;
10967 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10968 result = add_opt(message, udpsize, reqnsid);
10969 if (result != ISC_R_SUCCESS)
10970 zone_debuglog(zone, me, 1,
10971 "unable to add opt record: %s",
10972 dns_result_totext(result));
10975 zone_iattach(zone, &dummy);
10977 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10979 result = dns_request_createvia2(zone->view->requestmgr, message,
10980 &zone->sourceaddr, &zone->masteraddr,
10981 options, key, timeout * 3, timeout,
10982 zone->task, refresh_callback, zone,
10984 if (result != ISC_R_SUCCESS) {
10985 zone_idetach(&dummy);
10986 zone_debuglog(zone, me, 1,
10987 "dns_request_createvia2() failed: %s",
10988 dns_result_totext(result));
10991 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
10992 inc_stats(zone, dns_zonestatscounter_soaoutv4);
10994 inc_stats(zone, dns_zonestatscounter_soaoutv6);
10996 cancel = ISC_FALSE;
11000 dns_tsigkey_detach(&key);
11001 if (result != ISC_R_SUCCESS)
11002 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11003 if (message != NULL)
11004 dns_message_destroy(&message);
11006 cancel_refresh(zone);
11007 isc_event_free(&event);
11009 dns_zone_idetach(&zone);
11014 dns_tsigkey_detach(&key);
11016 * Skip to next failed / untried master.
11020 } while (zone->curmaster < zone->masterscnt &&
11021 zone->mastersok[zone->curmaster]);
11022 if (zone->curmaster < zone->masterscnt)
11024 zone->curmaster = 0;
11029 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
11030 const char me[] = "ns_query";
11031 isc_result_t result;
11032 dns_message_t *message = NULL;
11033 isc_netaddr_t masterip;
11034 dns_tsigkey_t *key = NULL;
11035 dns_dbnode_t *node = NULL;
11037 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
11038 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11040 REQUIRE(DNS_ZONE_VALID(zone));
11041 REQUIRE(LOCKED_ZONE(zone));
11042 REQUIRE((soardataset != NULL && stub == NULL) ||
11043 (soardataset == NULL && stub != NULL));
11044 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
11048 if (stub == NULL) {
11049 stub = isc_mem_get(zone->mctx, sizeof(*stub));
11052 stub->magic = STUB_MAGIC;
11053 stub->mctx = zone->mctx;
11056 stub->version = NULL;
11059 * Attach so that the zone won't disappear from under us.
11061 zone_iattach(zone, &stub->zone);
11064 * If a db exists we will update it, otherwise we create a
11065 * new one and attach it to the zone once we have the NS
11068 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11069 if (zone->db != NULL) {
11070 dns_db_attach(zone->db, &stub->db);
11071 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11073 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11075 INSIST(zone->db_argc >= 1);
11076 result = dns_db_create(zone->mctx, zone->db_argv[0],
11077 &zone->origin, dns_dbtype_stub,
11082 if (result != ISC_R_SUCCESS) {
11083 dns_zone_log(zone, ISC_LOG_ERROR,
11084 "refreshing stub: "
11085 "could not create "
11087 dns_result_totext(result));
11090 dns_db_settask(stub->db, zone->task);
11093 result = dns_db_newversion(stub->db, &stub->version);
11094 if (result != ISC_R_SUCCESS) {
11095 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11096 "dns_db_newversion() failed: %s",
11097 dns_result_totext(result));
11102 * Update SOA record.
11104 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
11106 if (result != ISC_R_SUCCESS) {
11107 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11108 "dns_db_findnode() failed: %s",
11109 dns_result_totext(result));
11113 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
11114 soardataset, 0, NULL);
11115 dns_db_detachnode(stub->db, &node);
11116 if (result != ISC_R_SUCCESS) {
11117 dns_zone_log(zone, ISC_LOG_INFO,
11118 "refreshing stub: "
11119 "dns_db_addrdataset() failed: %s",
11120 dns_result_totext(result));
11126 * XXX Optimisation: Create message when zone is setup and reuse.
11128 result = create_query(zone, dns_rdatatype_ns, &message);
11129 INSIST(result == ISC_R_SUCCESS);
11131 INSIST(zone->masterscnt > 0);
11132 INSIST(zone->curmaster < zone->masterscnt);
11133 zone->masteraddr = zone->masters[zone->curmaster];
11135 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11137 * First, look for a tsig key in the master statement, then
11138 * try for a server key.
11140 if ((zone->masterkeynames != NULL) &&
11141 (zone->masterkeynames[zone->curmaster] != NULL)) {
11142 dns_view_t *view = dns_zone_getview(zone);
11143 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11144 result = dns_view_gettsig(view, keyname, &key);
11145 if (result != ISC_R_SUCCESS) {
11146 char namebuf[DNS_NAME_FORMATSIZE];
11147 dns_name_format(keyname, namebuf, sizeof(namebuf));
11148 dns_zone_log(zone, ISC_LOG_ERROR,
11149 "unable to find key: %s", namebuf);
11153 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
11155 reqnsid = zone->view->requestnsid;
11156 if (zone->view->peers != NULL) {
11157 dns_peer_t *peer = NULL;
11158 isc_boolean_t edns;
11159 result = dns_peerlist_peerbyaddr(zone->view->peers,
11161 if (result == ISC_R_SUCCESS) {
11162 result = dns_peer_getsupportedns(peer, &edns);
11163 if (result == ISC_R_SUCCESS && !edns)
11164 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11165 result = dns_peer_gettransfersource(peer,
11166 &zone->sourceaddr);
11167 if (result == ISC_R_SUCCESS)
11168 have_xfrsource = ISC_TRUE;
11169 if (zone->view->resolver != NULL)
11171 dns_resolver_getudpsize(zone->view->resolver);
11172 (void)dns_peer_getudpsize(peer, &udpsize);
11173 (void)dns_peer_getrequestnsid(peer, &reqnsid);
11177 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11178 result = add_opt(message, udpsize, reqnsid);
11179 if (result != ISC_R_SUCCESS)
11180 zone_debuglog(zone, me, 1,
11181 "unable to add opt record: %s",
11182 dns_result_totext(result));
11186 * Always use TCP so that we shouldn't truncate in additional section.
11188 switch (isc_sockaddr_pf(&zone->masteraddr)) {
11190 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
11191 zone->sourceaddr = zone->altxfrsource4;
11192 else if (!have_xfrsource)
11193 zone->sourceaddr = zone->xfrsource4;
11196 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
11197 zone->sourceaddr = zone->altxfrsource6;
11198 else if (!have_xfrsource)
11199 zone->sourceaddr = zone->xfrsource6;
11202 result = ISC_R_NOTIMPLEMENTED;
11207 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11209 result = dns_request_createvia2(zone->view->requestmgr, message,
11210 &zone->sourceaddr, &zone->masteraddr,
11211 DNS_REQUESTOPT_TCP, key, timeout * 3,
11212 timeout, zone->task, stub_callback,
11213 stub, &zone->request);
11214 if (result != ISC_R_SUCCESS) {
11215 zone_debuglog(zone, me, 1,
11216 "dns_request_createvia() failed: %s",
11217 dns_result_totext(result));
11220 dns_message_destroy(&message);
11224 cancel_refresh(zone);
11225 if (stub != NULL) {
11227 if (stub->version != NULL)
11228 dns_db_closeversion(stub->db, &stub->version,
11230 if (stub->db != NULL)
11231 dns_db_detach(&stub->db);
11232 if (stub->zone != NULL)
11233 zone_idetach(&stub->zone);
11234 isc_mem_put(stub->mctx, stub, sizeof(*stub));
11236 if (message != NULL)
11237 dns_message_destroy(&message);
11240 dns_tsigkey_detach(&key);
11245 * Handle the control event. Note that although this event causes the zone
11246 * to shut down, it is not a shutdown event in the sense of the task library.
11249 zone_shutdown(isc_task_t *task, isc_event_t *event) {
11250 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
11251 isc_boolean_t free_needed, linked = ISC_FALSE;
11252 dns_zone_t *raw = NULL, *secure = NULL;
11255 REQUIRE(DNS_ZONE_VALID(zone));
11256 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
11257 INSIST(isc_refcount_current(&zone->erefs) == 0);
11259 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
11262 * Stop things being restarted after we cancel them below.
11265 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
11269 * If we were waiting for xfrin quota, step out of
11271 * If there's no zone manager, we can't be waiting for the
11274 if (zone->zmgr != NULL) {
11275 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11276 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
11277 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
11280 zone->statelist = NULL;
11282 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11286 * In task context, no locking required. See zone_xfrdone().
11288 if (zone->xfr != NULL)
11289 dns_xfrin_shutdown(zone->xfr);
11293 INSIST(zone->irefs > 0);
11296 if (zone->request != NULL) {
11297 dns_request_cancel(zone->request);
11300 if (zone->readio != NULL)
11301 zonemgr_cancelio(zone->readio);
11303 if (zone->lctx != NULL)
11304 dns_loadctx_cancel(zone->lctx);
11306 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
11307 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11308 if (zone->writeio != NULL)
11309 zonemgr_cancelio(zone->writeio);
11311 if (zone->dctx != NULL)
11312 dns_dumpctx_cancel(zone->dctx);
11315 notify_cancel(zone);
11317 forward_cancel(zone);
11319 if (zone->timer != NULL) {
11320 isc_timer_detach(&zone->timer);
11321 INSIST(zone->irefs > 0);
11325 if (zone->view != NULL)
11326 dns_view_weakdetach(&zone->view);
11329 * We have now canceled everything set the flag to allow exit_check()
11330 * to succeed. We must not unlock between setting this flag and
11331 * calling exit_check().
11333 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
11334 free_needed = exit_check(zone);
11335 if (inline_secure(zone)) {
11339 if (inline_raw(zone)) {
11340 secure = zone->secure;
11341 zone->secure = NULL;
11345 dns_zone_detach(&raw);
11346 if (secure != NULL)
11347 dns_zone_idetach(&secure);
11353 zone_timer(isc_task_t *task, isc_event_t *event) {
11354 const char me[] = "zone_timer";
11355 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
11358 REQUIRE(DNS_ZONE_VALID(zone));
11362 zone_maintenance(zone);
11364 isc_event_free(&event);
11368 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
11369 const char me[] = "zone_settimer";
11371 isc_result_t result;
11374 REQUIRE(DNS_ZONE_VALID(zone));
11375 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11378 isc_time_settoepoch(&next);
11380 switch (zone->type) {
11381 case dns_zone_redirect:
11382 if (zone->masters != NULL)
11383 goto treat_as_slave;
11386 case dns_zone_master:
11387 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
11388 next = zone->notifytime;
11389 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11390 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11391 INSIST(!isc_time_isepoch(&zone->dumptime));
11392 if (isc_time_isepoch(&next) ||
11393 isc_time_compare(&zone->dumptime, &next) < 0)
11394 next = zone->dumptime;
11396 if (zone->type == dns_zone_redirect)
11398 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
11399 !isc_time_isepoch(&zone->refreshkeytime)) {
11400 if (isc_time_isepoch(&next) ||
11401 isc_time_compare(&zone->refreshkeytime, &next) < 0)
11402 next = zone->refreshkeytime;
11404 if (!isc_time_isepoch(&zone->resigntime)) {
11405 if (isc_time_isepoch(&next) ||
11406 isc_time_compare(&zone->resigntime, &next) < 0)
11407 next = zone->resigntime;
11409 if (!isc_time_isepoch(&zone->keywarntime)) {
11410 if (isc_time_isepoch(&next) ||
11411 isc_time_compare(&zone->keywarntime, &next) < 0)
11412 next = zone->keywarntime;
11414 if (!isc_time_isepoch(&zone->signingtime)) {
11415 if (isc_time_isepoch(&next) ||
11416 isc_time_compare(&zone->signingtime, &next) < 0)
11417 next = zone->signingtime;
11419 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
11420 if (isc_time_isepoch(&next) ||
11421 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
11422 next = zone->nsec3chaintime;
11426 case dns_zone_slave:
11428 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
11429 next = zone->notifytime;
11432 case dns_zone_stub:
11433 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
11434 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
11435 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
11436 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
11437 INSIST(!isc_time_isepoch(&zone->refreshtime));
11438 if (isc_time_isepoch(&next) ||
11439 isc_time_compare(&zone->refreshtime, &next) < 0)
11440 next = zone->refreshtime;
11442 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
11443 INSIST(!isc_time_isepoch(&zone->expiretime));
11444 if (isc_time_isepoch(&next) ||
11445 isc_time_compare(&zone->expiretime, &next) < 0)
11446 next = zone->expiretime;
11448 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11449 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11450 INSIST(!isc_time_isepoch(&zone->dumptime));
11451 if (isc_time_isepoch(&next) ||
11452 isc_time_compare(&zone->dumptime, &next) < 0)
11453 next = zone->dumptime;
11458 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11459 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11460 INSIST(!isc_time_isepoch(&zone->dumptime));
11461 if (isc_time_isepoch(&next) ||
11462 isc_time_compare(&zone->dumptime, &next) < 0)
11463 next = zone->dumptime;
11465 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
11466 if (isc_time_isepoch(&next) ||
11467 (!isc_time_isepoch(&zone->refreshkeytime) &&
11468 isc_time_compare(&zone->refreshkeytime, &next) < 0))
11469 next = zone->refreshkeytime;
11477 if (isc_time_isepoch(&next)) {
11478 zone_debuglog(zone, me, 10, "settimer inactive");
11479 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
11480 NULL, NULL, ISC_TRUE);
11481 if (result != ISC_R_SUCCESS)
11482 dns_zone_log(zone, ISC_LOG_ERROR,
11483 "could not deactivate zone timer: %s",
11484 isc_result_totext(result));
11486 if (isc_time_compare(&next, now) <= 0)
11488 result = isc_timer_reset(zone->timer, isc_timertype_once,
11489 &next, NULL, ISC_TRUE);
11490 if (result != ISC_R_SUCCESS)
11491 dns_zone_log(zone, ISC_LOG_ERROR,
11492 "could not reset zone timer: %s",
11493 isc_result_totext(result));
11498 cancel_refresh(dns_zone_t *zone) {
11499 const char me[] = "cancel_refresh";
11503 * 'zone' locked by caller.
11506 REQUIRE(DNS_ZONE_VALID(zone));
11507 REQUIRE(LOCKED_ZONE(zone));
11511 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11513 zone_settimer(zone, &now);
11516 static isc_result_t
11517 notify_createmessage(dns_zone_t *zone, unsigned int flags,
11518 dns_message_t **messagep)
11520 dns_db_t *zonedb = NULL;
11521 dns_dbnode_t *node = NULL;
11522 dns_dbversion_t *version = NULL;
11523 dns_message_t *message = NULL;
11524 dns_rdataset_t rdataset;
11525 dns_rdata_t rdata = DNS_RDATA_INIT;
11527 dns_name_t *tempname = NULL;
11528 dns_rdata_t *temprdata = NULL;
11529 dns_rdatalist_t *temprdatalist = NULL;
11530 dns_rdataset_t *temprdataset = NULL;
11532 isc_result_t result;
11534 isc_buffer_t *b = NULL;
11536 REQUIRE(DNS_ZONE_VALID(zone));
11537 REQUIRE(messagep != NULL && *messagep == NULL);
11539 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
11541 if (result != ISC_R_SUCCESS)
11544 message->opcode = dns_opcode_notify;
11545 message->flags |= DNS_MESSAGEFLAG_AA;
11546 message->rdclass = zone->rdclass;
11548 result = dns_message_gettempname(message, &tempname);
11549 if (result != ISC_R_SUCCESS)
11552 result = dns_message_gettemprdataset(message, &temprdataset);
11553 if (result != ISC_R_SUCCESS)
11559 dns_name_init(tempname, NULL);
11560 dns_name_clone(&zone->origin, tempname);
11561 dns_rdataset_init(temprdataset);
11562 dns_rdataset_makequestion(temprdataset, zone->rdclass,
11563 dns_rdatatype_soa);
11564 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11565 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
11567 temprdataset = NULL;
11569 if ((flags & DNS_NOTIFY_NOSOA) != 0)
11572 result = dns_message_gettempname(message, &tempname);
11573 if (result != ISC_R_SUCCESS)
11575 result = dns_message_gettemprdata(message, &temprdata);
11576 if (result != ISC_R_SUCCESS)
11578 result = dns_message_gettemprdataset(message, &temprdataset);
11579 if (result != ISC_R_SUCCESS)
11581 result = dns_message_gettemprdatalist(message, &temprdatalist);
11582 if (result != ISC_R_SUCCESS)
11585 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11586 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
11587 dns_db_attach(zone->db, &zonedb);
11588 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11590 dns_name_init(tempname, NULL);
11591 dns_name_clone(&zone->origin, tempname);
11592 dns_db_currentversion(zonedb, &version);
11593 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
11594 if (result != ISC_R_SUCCESS)
11597 dns_rdataset_init(&rdataset);
11598 result = dns_db_findrdataset(zonedb, node, version,
11600 dns_rdatatype_none, 0, &rdataset,
11602 if (result != ISC_R_SUCCESS)
11604 result = dns_rdataset_first(&rdataset);
11605 if (result != ISC_R_SUCCESS)
11607 dns_rdataset_current(&rdataset, &rdata);
11608 dns_rdata_toregion(&rdata, &r);
11609 result = isc_buffer_allocate(zone->mctx, &b, r.length);
11610 if (result != ISC_R_SUCCESS)
11612 isc_buffer_putmem(b, r.base, r.length);
11613 isc_buffer_usedregion(b, &r);
11614 dns_rdata_init(temprdata);
11615 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
11616 dns_message_takebuffer(message, &b);
11617 result = dns_rdataset_next(&rdataset);
11618 dns_rdataset_disassociate(&rdataset);
11619 if (result != ISC_R_NOMORE)
11621 temprdatalist->rdclass = rdata.rdclass;
11622 temprdatalist->type = rdata.type;
11623 temprdatalist->covers = 0;
11624 temprdatalist->ttl = rdataset.ttl;
11625 ISC_LIST_INIT(temprdatalist->rdata);
11626 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
11628 dns_rdataset_init(temprdataset);
11629 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
11630 if (result != ISC_R_SUCCESS)
11633 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11634 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
11635 temprdatalist = NULL;
11636 temprdataset = NULL;
11642 dns_db_detachnode(zonedb, &node);
11643 if (version != NULL)
11644 dns_db_closeversion(zonedb, &version, ISC_FALSE);
11645 if (zonedb != NULL)
11646 dns_db_detach(&zonedb);
11647 if (tempname != NULL)
11648 dns_message_puttempname(message, &tempname);
11649 if (temprdata != NULL)
11650 dns_message_puttemprdata(message, &temprdata);
11651 if (temprdataset != NULL)
11652 dns_message_puttemprdataset(message, &temprdataset);
11653 if (temprdatalist != NULL)
11654 dns_message_puttemprdatalist(message, &temprdatalist);
11657 *messagep = message;
11658 return (ISC_R_SUCCESS);
11661 if (tempname != NULL)
11662 dns_message_puttempname(message, &tempname);
11663 if (temprdataset != NULL)
11664 dns_message_puttemprdataset(message, &temprdataset);
11665 dns_message_destroy(&message);
11670 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
11671 dns_message_t *msg)
11674 dns_rdata_soa_t soa;
11675 dns_rdataset_t *rdataset = NULL;
11676 dns_rdata_t rdata = DNS_RDATA_INIT;
11677 isc_result_t result;
11678 char fromtext[ISC_SOCKADDR_FORMATSIZE];
11680 isc_netaddr_t netaddr;
11681 isc_sockaddr_t local, remote;
11683 REQUIRE(DNS_ZONE_VALID(zone));
11686 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
11690 * Check that 'from' is a valid notify source, (zone->masters).
11691 * Return DNS_R_REFUSED if not.
11693 * If the notify message contains a serial number check it
11694 * against the zones serial and return if <= current serial
11696 * If a refresh check is progress, if so just record the
11697 * fact we received a NOTIFY and from where and return.
11698 * We will perform a new refresh check when the current one
11699 * completes. Return ISC_R_SUCCESS.
11701 * Otherwise initiate a refresh check using 'from' as the
11702 * first address to check. Return ISC_R_SUCCESS.
11705 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
11708 * Notify messages are processed by the raw zone.
11711 if (inline_secure(zone)) {
11712 result = dns_zone_notifyreceive(zone->raw, from, msg);
11717 * We only handle NOTIFY (SOA) at the present.
11719 if (isc_sockaddr_pf(from) == PF_INET)
11720 inc_stats(zone, dns_zonestatscounter_notifyinv4);
11722 inc_stats(zone, dns_zonestatscounter_notifyinv6);
11723 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
11724 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
11725 dns_rdatatype_soa, dns_rdatatype_none,
11726 NULL, NULL) != ISC_R_SUCCESS) {
11728 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
11729 dns_zone_log(zone, ISC_LOG_NOTICE,
11731 "question section from: %s", fromtext);
11732 return (DNS_R_FORMERR);
11734 dns_zone_log(zone, ISC_LOG_NOTICE,
11735 "NOTIFY zone does not match");
11736 return (DNS_R_NOTIMP);
11740 * If we are a master zone just succeed.
11742 if (zone->type == dns_zone_master) {
11744 return (ISC_R_SUCCESS);
11747 isc_netaddr_fromsockaddr(&netaddr, from);
11748 for (i = 0; i < zone->masterscnt; i++) {
11749 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
11751 if (zone->view->aclenv.match_mapped &&
11752 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
11753 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
11754 isc_netaddr_t na1, na2;
11755 isc_netaddr_fromv4mapped(&na1, &netaddr);
11756 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
11757 if (isc_netaddr_equal(&na1, &na2))
11763 * Accept notify requests from non masters if they are on
11764 * 'zone->notify_acl'.
11766 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
11767 dns_acl_match(&netaddr, NULL, zone->notify_acl,
11768 &zone->view->aclenv,
11769 &match, NULL) == ISC_R_SUCCESS &&
11772 /* Accept notify. */
11773 } else if (i >= zone->masterscnt) {
11775 dns_zone_log(zone, ISC_LOG_INFO,
11776 "refused notify from non-master: %s", fromtext);
11777 inc_stats(zone, dns_zonestatscounter_notifyrej);
11778 return (DNS_R_REFUSED);
11782 * If the zone is loaded and there are answers check the serial
11783 * to see if we need to do a refresh. Do not worry about this
11784 * check if we are a dialup zone as we use the notify request
11785 * to trigger a refresh check.
11787 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
11788 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
11789 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
11790 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
11793 dns_rdatatype_none, NULL,
11795 if (result == ISC_R_SUCCESS)
11796 result = dns_rdataset_first(rdataset);
11797 if (result == ISC_R_SUCCESS) {
11798 isc_uint32_t serial = 0, oldserial;
11799 unsigned int soacount;
11801 dns_rdataset_current(rdataset, &rdata);
11802 result = dns_rdata_tostruct(&rdata, &soa, NULL);
11803 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11804 serial = soa.serial;
11806 * The following should safely be performed without DB
11807 * lock and succeed in this context.
11809 result = zone_get_from_db(zone, zone->db, NULL,
11810 &soacount, &oldserial, NULL,
11811 NULL, NULL, NULL, NULL);
11812 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11813 RUNTIME_CHECK(soacount > 0U);
11814 if (isc_serial_le(serial, oldserial)) {
11818 "zone is up to date",
11821 return (ISC_R_SUCCESS);
11827 * If we got this far and there was a refresh in progress just
11828 * let it complete. Record where we got the notify from so we
11829 * can perform a refresh check when the current one completes
11831 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
11832 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11833 zone->notifyfrom = *from;
11835 dns_zone_log(zone, ISC_LOG_INFO,
11836 "notify from %s: refresh in progress, "
11837 "refresh check queued",
11839 return (ISC_R_SUCCESS);
11841 zone->notifyfrom = *from;
11842 local = zone->masteraddr;
11843 remote = zone->sourceaddr;
11845 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
11846 dns_zone_refresh(zone);
11847 return (ISC_R_SUCCESS);
11851 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
11853 REQUIRE(DNS_ZONE_VALID(zone));
11856 if (zone->notify_acl != NULL)
11857 dns_acl_detach(&zone->notify_acl);
11858 dns_acl_attach(acl, &zone->notify_acl);
11863 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
11865 REQUIRE(DNS_ZONE_VALID(zone));
11868 if (zone->query_acl != NULL)
11869 dns_acl_detach(&zone->query_acl);
11870 dns_acl_attach(acl, &zone->query_acl);
11875 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
11877 REQUIRE(DNS_ZONE_VALID(zone));
11880 if (zone->queryon_acl != NULL)
11881 dns_acl_detach(&zone->queryon_acl);
11882 dns_acl_attach(acl, &zone->queryon_acl);
11887 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
11889 REQUIRE(DNS_ZONE_VALID(zone));
11892 if (zone->update_acl != NULL)
11893 dns_acl_detach(&zone->update_acl);
11894 dns_acl_attach(acl, &zone->update_acl);
11899 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
11901 REQUIRE(DNS_ZONE_VALID(zone));
11904 if (zone->forward_acl != NULL)
11905 dns_acl_detach(&zone->forward_acl);
11906 dns_acl_attach(acl, &zone->forward_acl);
11911 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
11913 REQUIRE(DNS_ZONE_VALID(zone));
11916 if (zone->xfr_acl != NULL)
11917 dns_acl_detach(&zone->xfr_acl);
11918 dns_acl_attach(acl, &zone->xfr_acl);
11923 dns_zone_getnotifyacl(dns_zone_t *zone) {
11925 REQUIRE(DNS_ZONE_VALID(zone));
11927 return (zone->notify_acl);
11931 dns_zone_getqueryacl(dns_zone_t *zone) {
11933 REQUIRE(DNS_ZONE_VALID(zone));
11935 return (zone->query_acl);
11939 dns_zone_getqueryonacl(dns_zone_t *zone) {
11941 REQUIRE(DNS_ZONE_VALID(zone));
11943 return (zone->queryon_acl);
11947 dns_zone_getupdateacl(dns_zone_t *zone) {
11949 REQUIRE(DNS_ZONE_VALID(zone));
11951 return (zone->update_acl);
11955 dns_zone_getforwardacl(dns_zone_t *zone) {
11957 REQUIRE(DNS_ZONE_VALID(zone));
11959 return (zone->forward_acl);
11963 dns_zone_getxfracl(dns_zone_t *zone) {
11965 REQUIRE(DNS_ZONE_VALID(zone));
11967 return (zone->xfr_acl);
11971 dns_zone_clearupdateacl(dns_zone_t *zone) {
11973 REQUIRE(DNS_ZONE_VALID(zone));
11976 if (zone->update_acl != NULL)
11977 dns_acl_detach(&zone->update_acl);
11982 dns_zone_clearforwardacl(dns_zone_t *zone) {
11984 REQUIRE(DNS_ZONE_VALID(zone));
11987 if (zone->forward_acl != NULL)
11988 dns_acl_detach(&zone->forward_acl);
11993 dns_zone_clearnotifyacl(dns_zone_t *zone) {
11995 REQUIRE(DNS_ZONE_VALID(zone));
11998 if (zone->notify_acl != NULL)
11999 dns_acl_detach(&zone->notify_acl);
12004 dns_zone_clearqueryacl(dns_zone_t *zone) {
12006 REQUIRE(DNS_ZONE_VALID(zone));
12009 if (zone->query_acl != NULL)
12010 dns_acl_detach(&zone->query_acl);
12015 dns_zone_clearqueryonacl(dns_zone_t *zone) {
12017 REQUIRE(DNS_ZONE_VALID(zone));
12020 if (zone->queryon_acl != NULL)
12021 dns_acl_detach(&zone->queryon_acl);
12026 dns_zone_clearxfracl(dns_zone_t *zone) {
12028 REQUIRE(DNS_ZONE_VALID(zone));
12031 if (zone->xfr_acl != NULL)
12032 dns_acl_detach(&zone->xfr_acl);
12037 dns_zone_getupdatedisabled(dns_zone_t *zone) {
12038 REQUIRE(DNS_ZONE_VALID(zone));
12039 return (zone->update_disabled);
12044 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
12045 REQUIRE(DNS_ZONE_VALID(zone));
12046 zone->update_disabled = state;
12050 dns_zone_getzeronosoattl(dns_zone_t *zone) {
12051 REQUIRE(DNS_ZONE_VALID(zone));
12052 return (zone->zero_no_soa_ttl);
12057 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
12058 REQUIRE(DNS_ZONE_VALID(zone));
12059 zone->zero_no_soa_ttl = state;
12063 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
12065 REQUIRE(DNS_ZONE_VALID(zone));
12067 zone->check_names = severity;
12071 dns_zone_getchecknames(dns_zone_t *zone) {
12073 REQUIRE(DNS_ZONE_VALID(zone));
12075 return (zone->check_names);
12079 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
12081 REQUIRE(DNS_ZONE_VALID(zone));
12083 zone->journalsize = size;
12087 dns_zone_getjournalsize(dns_zone_t *zone) {
12089 REQUIRE(DNS_ZONE_VALID(zone));
12091 return (zone->journalsize);
12095 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
12096 isc_result_t result = ISC_R_FAILURE;
12097 isc_buffer_t buffer;
12099 REQUIRE(buf != NULL);
12100 REQUIRE(length > 1U);
12103 * Leave space for terminating '\0'.
12105 isc_buffer_init(&buffer, buf, length - 1);
12106 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
12107 if (dns_name_dynamic(&zone->origin))
12108 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12109 if (result != ISC_R_SUCCESS &&
12110 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12111 isc_buffer_putstr(&buffer, "<UNKNOWN>");
12113 if (isc_buffer_availablelength(&buffer) > 0)
12114 isc_buffer_putstr(&buffer, "/");
12115 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
12118 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
12119 strcmp(zone->view->name, "_default") != 0 &&
12120 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
12121 isc_buffer_putstr(&buffer, "/");
12122 isc_buffer_putstr(&buffer, zone->view->name);
12124 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
12125 isc_buffer_putstr(&buffer, " (signed)");
12126 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
12127 isc_buffer_putstr(&buffer, " (unsigned)");
12129 buf[isc_buffer_usedlength(&buffer)] = '\0';
12133 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
12134 isc_result_t result = ISC_R_FAILURE;
12135 isc_buffer_t buffer;
12137 REQUIRE(buf != NULL);
12138 REQUIRE(length > 1U);
12141 * Leave space for terminating '\0'.
12143 isc_buffer_init(&buffer, buf, length - 1);
12144 if (dns_name_dynamic(&zone->origin))
12145 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12146 if (result != ISC_R_SUCCESS &&
12147 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12148 isc_buffer_putstr(&buffer, "<UNKNOWN>");
12150 buf[isc_buffer_usedlength(&buffer)] = '\0';
12154 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
12155 isc_buffer_t buffer;
12157 REQUIRE(buf != NULL);
12158 REQUIRE(length > 1U);
12161 * Leave space for terminating '\0'.
12163 isc_buffer_init(&buffer, buf, length - 1);
12164 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
12166 buf[isc_buffer_usedlength(&buffer)] = '\0';
12170 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
12171 isc_buffer_t buffer;
12173 REQUIRE(buf != NULL);
12174 REQUIRE(length > 1U);
12178 * Leave space for terminating '\0'.
12180 isc_buffer_init(&buffer, buf, length - 1);
12182 if (zone->view == NULL) {
12183 isc_buffer_putstr(&buffer, "_none");
12184 } else if (strlen(zone->view->name)
12185 < isc_buffer_availablelength(&buffer)) {
12186 isc_buffer_putstr(&buffer, zone->view->name);
12188 isc_buffer_putstr(&buffer, "_toolong");
12191 buf[isc_buffer_usedlength(&buffer)] = '\0';
12195 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
12196 REQUIRE(DNS_ZONE_VALID(zone));
12197 REQUIRE(buf != NULL);
12198 zone_namerd_tostr(zone, buf, length);
12202 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12204 char message[4096];
12206 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12210 vsnprintf(message, sizeof(message), fmt, ap);
12212 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
12213 level, "zone %s: %s", zone->strnamerd, message);
12217 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
12218 int level, const char *fmt, ...) {
12220 char message[4096];
12222 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12226 vsnprintf(message, sizeof(message), fmt, ap);
12228 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
12229 level, "%s%s: %s", (zone->type == dns_zone_key) ?
12230 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
12231 "redirect-zone" : "zone ", zone->strnamerd, message);
12235 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12237 char message[4096];
12239 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12243 vsnprintf(message, sizeof(message), fmt, ap);
12245 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
12246 level, "%s%s: %s", (zone->type == dns_zone_key) ?
12247 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
12248 "redirect-zone" : "zone ", zone->strnamerd, message);
12252 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
12253 const char *fmt, ...)
12256 char message[4096];
12257 int level = ISC_LOG_DEBUG(debuglevel);
12260 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12264 vsnprintf(message, sizeof(message), fmt, ap);
12267 switch (zone->type) {
12269 zstr = "managed-keys-zone";
12271 case dns_zone_redirect:
12272 zstr = "redirect-zone";
12278 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
12279 level, "%s: %s %s: %s", me, zstr, zone->strnamerd,
12284 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
12286 isc_result_t result;
12288 dns_rdataset_t *curr;
12291 result = dns_message_firstname(msg, section);
12292 while (result == ISC_R_SUCCESS) {
12294 dns_message_currentname(msg, section, &name);
12296 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
12297 curr = ISC_LIST_PREV(curr, link)) {
12298 if (curr->type == type)
12301 result = dns_message_nextname(msg, section);
12308 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
12309 REQUIRE(DNS_ZONE_VALID(zone));
12311 zone->maxxfrin = maxxfrin;
12315 dns_zone_getmaxxfrin(dns_zone_t *zone) {
12316 REQUIRE(DNS_ZONE_VALID(zone));
12318 return (zone->maxxfrin);
12322 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
12323 REQUIRE(DNS_ZONE_VALID(zone));
12324 zone->maxxfrout = maxxfrout;
12328 dns_zone_getmaxxfrout(dns_zone_t *zone) {
12329 REQUIRE(DNS_ZONE_VALID(zone));
12331 return (zone->maxxfrout);
12335 dns_zone_gettype(dns_zone_t *zone) {
12336 REQUIRE(DNS_ZONE_VALID(zone));
12338 return (zone->type);
12342 dns_zone_getorigin(dns_zone_t *zone) {
12343 REQUIRE(DNS_ZONE_VALID(zone));
12345 return (&zone->origin);
12349 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
12350 REQUIRE(DNS_ZONE_VALID(zone));
12353 if (zone->task != NULL)
12354 isc_task_detach(&zone->task);
12355 isc_task_attach(task, &zone->task);
12356 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12357 if (zone->db != NULL)
12358 dns_db_settask(zone->db, zone->task);
12359 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12364 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
12365 REQUIRE(DNS_ZONE_VALID(zone));
12366 isc_task_attach(zone->task, target);
12370 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
12371 REQUIRE(DNS_ZONE_VALID(zone));
12374 idlein = DNS_DEFAULT_IDLEIN;
12375 zone->idlein = idlein;
12379 dns_zone_getidlein(dns_zone_t *zone) {
12380 REQUIRE(DNS_ZONE_VALID(zone));
12382 return (zone->idlein);
12386 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
12387 REQUIRE(DNS_ZONE_VALID(zone));
12389 zone->idleout = idleout;
12393 dns_zone_getidleout(dns_zone_t *zone) {
12394 REQUIRE(DNS_ZONE_VALID(zone));
12396 return (zone->idleout);
12400 notify_done(isc_task_t *task, isc_event_t *event) {
12401 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12402 dns_notify_t *notify;
12403 isc_result_t result;
12404 dns_message_t *message = NULL;
12407 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
12411 notify = event->ev_arg;
12412 REQUIRE(DNS_NOTIFY_VALID(notify));
12413 INSIST(task == notify->zone->task);
12415 isc_buffer_init(&buf, rcode, sizeof(rcode));
12416 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
12418 result = revent->result;
12419 if (result == ISC_R_SUCCESS)
12420 result = dns_message_create(notify->zone->mctx,
12421 DNS_MESSAGE_INTENTPARSE, &message);
12422 if (result == ISC_R_SUCCESS)
12423 result = dns_request_getresponse(revent->request, message,
12424 DNS_MESSAGEPARSE_PRESERVEORDER);
12425 if (result == ISC_R_SUCCESS)
12426 result = dns_rcode_totext(message->rcode, &buf);
12427 if (result == ISC_R_SUCCESS)
12428 notify_log(notify->zone, ISC_LOG_DEBUG(3),
12429 "notify response from %s: %.*s",
12430 addrbuf, (int)buf.used, rcode);
12432 notify_log(notify->zone, ISC_LOG_DEBUG(2),
12433 "notify to %s failed: %s", addrbuf,
12434 dns_result_totext(result));
12437 * Old bind's return formerr if they see a soa record. Retry w/o
12438 * the soa if we see a formerr and had sent a SOA.
12440 isc_event_free(&event);
12441 if (message != NULL && message->rcode == dns_rcode_formerr &&
12442 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
12443 notify->flags |= DNS_NOTIFY_NOSOA;
12444 dns_request_destroy(¬ify->request);
12445 result = notify_send_queue(notify);
12446 if (result != ISC_R_SUCCESS)
12447 notify_destroy(notify, ISC_FALSE);
12449 if (result == ISC_R_TIMEDOUT)
12450 notify_log(notify->zone, ISC_LOG_DEBUG(1),
12451 "notify to %s: retries exceeded", addrbuf);
12452 notify_destroy(notify, ISC_FALSE);
12454 if (message != NULL)
12455 dns_message_destroy(&message);
12458 struct secure_event {
12461 isc_uint32_t serial;
12465 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
12467 dns_zone_log(zone, level, "%s", message);
12470 static isc_result_t
12471 sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal,
12472 isc_uint32_t start, isc_uint32_t end,
12473 dns_difftuple_t **soatuplep, dns_diff_t *diff)
12475 isc_result_t result;
12476 dns_difftuple_t *tuple = NULL;
12477 dns_diffop_t op = DNS_DIFFOP_ADD;
12480 REQUIRE(soatuplep != NULL);
12483 return (DNS_R_UNCHANGED);
12485 CHECK(dns_journal_iter_init(journal, start, end));
12486 for (result = dns_journal_first_rr(journal);
12487 result == ISC_R_SUCCESS;
12488 result = dns_journal_next_rr(journal))
12490 dns_name_t *name = NULL;
12492 dns_rdata_t *rdata = NULL;
12493 dns_journal_current_rr(journal, &name, &ttl, &rdata);
12495 if (rdata->type == dns_rdatatype_soa) {
12499 * Save the latest raw SOA record.
12501 if (*soatuplep != NULL)
12502 dns_difftuple_free(soatuplep);
12503 CHECK(dns_difftuple_create(diff->mctx,
12515 dns_zone_log(zone->raw, ISC_LOG_ERROR,
12516 "corrupt journal file: '%s'\n",
12517 zone->raw->journal);
12518 return (ISC_R_FAILURE);
12521 if (zone->privatetype != 0 &&
12522 rdata->type == zone->privatetype)
12525 if (rdata->type == dns_rdatatype_nsec ||
12526 rdata->type == dns_rdatatype_rrsig ||
12527 rdata->type == dns_rdatatype_nsec3 ||
12528 rdata->type == dns_rdatatype_dnskey ||
12529 rdata->type == dns_rdatatype_nsec3param)
12532 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
12534 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
12536 dns_diff_appendminimal(diff, &tuple);
12538 if (result == ISC_R_NOMORE)
12539 result = ISC_R_SUCCESS;
12545 static isc_result_t
12546 sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb,
12547 dns_dbversion_t *secver, dns_difftuple_t **soatuple,
12550 isc_result_t result;
12551 dns_db_t *rawdb = NULL;
12552 dns_dbversion_t *rawver = NULL;
12553 dns_difftuple_t *tuple = NULL, *next;
12554 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
12555 dns_rdata_soa_t oldsoa, newsoa;
12557 REQUIRE(DNS_ZONE_VALID(seczone));
12558 REQUIRE(inline_secure(seczone));
12559 REQUIRE(soatuple != NULL && *soatuple == NULL);
12561 if (!seczone->sourceserialset)
12562 return (DNS_R_UNCHANGED);
12564 dns_db_attach(seczone->raw->db, &rawdb);
12565 dns_db_currentversion(rawdb, &rawver);
12566 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
12567 dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
12568 dns_db_detach(&rawdb);
12570 if (result != ISC_R_SUCCESS)
12573 for (tuple = ISC_LIST_HEAD(diff->tuples);
12577 next = ISC_LIST_NEXT(tuple, link);
12578 if (tuple->rdata.type == dns_rdatatype_nsec ||
12579 tuple->rdata.type == dns_rdatatype_rrsig ||
12580 tuple->rdata.type == dns_rdatatype_dnskey ||
12581 tuple->rdata.type == dns_rdatatype_nsec3 ||
12582 tuple->rdata.type == dns_rdatatype_nsec3param)
12584 ISC_LIST_UNLINK(diff->tuples, tuple, link);
12585 dns_difftuple_free(&tuple);
12588 if (tuple->rdata.type == dns_rdatatype_soa) {
12589 if (tuple->op == DNS_DIFFOP_DEL) {
12590 INSIST(oldtuple == NULL);
12593 if (tuple->op == DNS_DIFFOP_ADD) {
12594 INSIST(newtuple == NULL);
12600 if (oldtuple != NULL && newtuple != NULL) {
12602 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
12603 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12605 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
12606 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12609 * If the SOA records are the same except for the serial
12610 * remove them from the diff.
12612 if (oldsoa.refresh == newsoa.refresh &&
12613 oldsoa.retry == newsoa.retry &&
12614 oldsoa.minimum == newsoa.minimum &&
12615 oldsoa.expire == newsoa.expire &&
12616 dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
12617 dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
12618 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
12619 dns_difftuple_free(&oldtuple);
12620 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
12621 dns_difftuple_free(&newtuple);
12625 if (ISC_LIST_EMPTY(diff->tuples))
12626 return (DNS_R_UNCHANGED);
12629 * If there are still SOA records in the diff they can now be removed
12630 * saving the new SOA record.
12632 if (oldtuple != NULL) {
12633 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
12634 dns_difftuple_free(&oldtuple);
12637 if (newtuple != NULL) {
12638 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
12639 *soatuple = newtuple;
12642 return (ISC_R_SUCCESS);
12646 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
12647 isc_result_t result;
12648 dns_journal_t *rjournal = NULL;
12649 isc_uint32_t start, end;
12651 dns_db_t *db = NULL;
12652 dns_dbversion_t *newver = NULL, *oldver = NULL;
12654 dns_difftuple_t *tuple = NULL, *soatuple = NULL;
12655 dns_update_log_t log = { update_log_cb, NULL };
12656 isc_time_t timenow;
12658 zone = event->ev_arg;
12659 end = ((struct secure_event *)event)->serial;
12660 isc_event_free(&event);
12664 dns_diff_init(zone->mctx, &diff);
12669 * zone->db may be NULL if the load from disk failed.
12671 if (zone->db == NULL || !inline_secure(zone)) {
12672 result = ISC_R_FAILURE;
12677 * We first attempt to sync the raw zone to the secure zone
12678 * by using the raw zone's journal, applying all the deltas
12679 * from the latest source-serial of the secure zone up to
12680 * the current serial number of the raw zone.
12682 * If that fails, then we'll fall back to a direct comparison
12683 * between raw and secure zones.
12685 result = dns_journal_open(zone->raw->mctx, zone->raw->journal,
12686 DNS_JOURNAL_WRITE, &rjournal);
12687 if (result != ISC_R_SUCCESS)
12690 dns_journal_t *sjournal = NULL;
12692 result = dns_journal_open(zone->mctx, zone->journal,
12693 DNS_JOURNAL_READ, &sjournal);
12694 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
12697 if (!dns_journal_get_sourceserial(rjournal, &start)) {
12698 start = dns_journal_first_serial(rjournal);
12699 dns_journal_set_sourceserial(rjournal, start);
12701 if (sjournal != NULL) {
12702 isc_uint32_t serial;
12704 * We read the secure journal first, if that exists
12705 * use its value provided it is greater that from the
12708 if (dns_journal_get_sourceserial(sjournal, &serial)) {
12709 if (isc_serial_gt(serial, start))
12712 dns_journal_destroy(&sjournal);
12716 dns_db_attach(zone->db, &db);
12717 dns_db_currentversion(db, &oldver);
12718 CHECK(dns_db_newversion(db, &newver));
12721 * Try to apply diffs from the raw zone's journal to the secure
12722 * zone. If that fails, we recover by syncing up the databases
12725 result = sync_secure_journal(zone, rjournal, start, end,
12727 if (result == DNS_R_UNCHANGED)
12729 else if (result != ISC_R_SUCCESS)
12730 CHECK(sync_secure_db(zone, db, oldver, &soatuple, &diff));
12732 CHECK(dns_diff_apply(&diff, db, newver));
12734 if (soatuple != NULL) {
12735 isc_uint32_t oldserial, newserial, desired;
12737 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
12738 DNS_DIFFOP_DEL, &tuple));
12739 oldserial = dns_soa_getserial(&tuple->rdata);
12740 newserial = desired = dns_soa_getserial(&soatuple->rdata);
12741 if (!isc_serial_gt(newserial, oldserial)) {
12742 newserial = oldserial + 1;
12743 if (newserial == 0)
12745 dns_soa_setserial(newserial, &soatuple->rdata);
12747 CHECK(do_one_tuple(&tuple, db, newver, &diff));
12748 CHECK(do_one_tuple(&soatuple, db, newver, &diff));
12749 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
12750 newserial, desired);
12752 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
12753 zone->updatemethod));
12755 CHECK(dns_update_signatures(&log, zone, db, oldver, newver,
12756 &diff, zone->sigvalidityinterval));
12758 CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial"));
12760 dns_journal_set_sourceserial(rjournal, end);
12761 dns_journal_commit(rjournal);
12763 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
12765 zone->sourceserial = end;
12766 zone->sourceserialset = ISC_TRUE;
12767 zone_needdump(zone, DNS_DUMP_DELAY);
12769 TIME_NOW(&timenow);
12770 zone_settimer(zone, &timenow);
12772 dns_db_closeversion(db, &oldver, ISC_FALSE);
12773 dns_db_closeversion(db, &newver, ISC_TRUE);
12777 if (result != ISC_R_SUCCESS)
12778 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
12779 dns_result_totext(result));
12781 dns_difftuple_free(&tuple);
12782 if (soatuple != NULL)
12783 dns_difftuple_free(&soatuple);
12785 if (oldver != NULL)
12786 dns_db_closeversion(db, &oldver, ISC_FALSE);
12787 if (newver != NULL)
12788 dns_db_closeversion(db, &newver, ISC_FALSE);
12789 dns_db_detach(&db);
12791 if (rjournal != NULL)
12792 dns_journal_destroy(&rjournal);
12793 dns_diff_clear(&diff);
12794 dns_zone_idetach(&zone);
12797 static isc_result_t
12798 zone_send_secureserial(dns_zone_t *zone, isc_boolean_t locked,
12799 isc_uint32_t serial)
12802 dns_zone_t *dummy = NULL;
12804 e = isc_event_allocate(zone->secure->mctx, zone,
12805 DNS_EVENT_ZONESECURESERIAL,
12806 receive_secure_serial, zone->secure,
12807 sizeof(struct secure_event));
12809 return (ISC_R_NOMEMORY);
12810 ((struct secure_event *)e)->serial = serial;
12812 zone_iattach(zone->secure, &dummy);
12814 dns_zone_iattach(zone->secure, &dummy);
12815 isc_task_send(zone->secure->task, &e);
12817 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
12818 return (ISC_R_SUCCESS);
12821 static isc_result_t
12822 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
12823 dns_rdataset_t *rdataset, isc_uint32_t oldserial)
12825 dns_rdata_soa_t soa;
12826 dns_rdata_t rdata = DNS_RDATA_INIT;
12827 dns_rdatalist_t temprdatalist;
12828 dns_rdataset_t temprdataset;
12830 isc_result_t result;
12831 unsigned char buf[DNS_SOA_BUFFERSIZE];
12833 result = dns_rdataset_first(rdataset);
12834 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12835 dns_rdataset_current(rdataset, &rdata);
12836 result = dns_rdata_tostruct(&rdata, &soa, NULL);
12837 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12839 if (isc_serial_gt(soa.serial, oldserial))
12840 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
12843 * Always bump the serial.
12846 if (oldserial == 0)
12848 soa.serial = oldserial;
12851 * Construct a replacement rdataset.
12853 dns_rdata_reset(&rdata);
12854 isc_buffer_init(&b, buf, sizeof(buf));
12855 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
12856 dns_rdatatype_soa, &soa, &b);
12857 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12858 temprdatalist.rdclass = rdata.rdclass;
12859 temprdatalist.type = rdata.type;
12860 temprdatalist.covers = 0;
12861 temprdatalist.ttl = rdataset->ttl;
12862 ISC_LIST_INIT(temprdatalist.rdata);
12863 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
12865 dns_rdataset_init(&temprdataset);
12866 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
12867 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12868 return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
12873 receive_secure_db(isc_task_t *task, isc_event_t *event) {
12874 isc_result_t result;
12876 dns_db_t *rawdb, *db = NULL;
12877 dns_dbnode_t *rawnode = NULL, *node = NULL;
12878 dns_fixedname_t fname;
12880 dns_dbiterator_t *dbiterator = NULL;
12881 dns_rdatasetiter_t *rdsit = NULL;
12882 dns_rdataset_t rdataset;
12883 dns_dbversion_t *version = NULL;
12884 isc_time_t loadtime;
12885 unsigned int oldserial = 0;
12886 isc_boolean_t have_oldserial = ISC_FALSE;
12890 zone = event->ev_arg;
12891 rawdb = ((struct secure_event *)event)->db;
12892 isc_event_free(&event);
12894 REQUIRE(inline_secure(zone));
12896 dns_fixedname_init(&fname);
12897 name = dns_fixedname_name(&fname);
12898 dns_rdataset_init(&rdataset);
12900 TIME_NOW(&loadtime);
12901 if (zone->db != NULL) {
12902 result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
12903 if (result == ISC_R_SUCCESS)
12904 have_oldserial = ISC_TRUE;
12907 result = dns_db_create(zone->mctx, zone->db_argv[0],
12908 &zone->origin, dns_dbtype_zone, zone->rdclass,
12909 zone->db_argc - 1, zone->db_argv + 1, &db);
12910 if (result != ISC_R_SUCCESS)
12913 result = dns_db_newversion(db, &version);
12914 if (result != ISC_R_SUCCESS)
12917 result = dns_db_createiterator(rawdb, 0, &dbiterator);
12918 if (result != ISC_R_SUCCESS)
12921 for (result = dns_dbiterator_first(dbiterator);
12922 result == ISC_R_SUCCESS;
12923 result = dns_dbiterator_next(dbiterator)) {
12924 result = dns_dbiterator_current(dbiterator, &rawnode, name);
12925 if (result != ISC_R_SUCCESS)
12928 result = dns_db_findnode(db, name, ISC_TRUE, &node);
12929 if (result != ISC_R_SUCCESS)
12932 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
12933 if (result != ISC_R_SUCCESS)
12936 for (result = dns_rdatasetiter_first(rdsit);
12937 result == ISC_R_SUCCESS;
12938 result = dns_rdatasetiter_next(rdsit)) {
12939 dns_rdatasetiter_current(rdsit, &rdataset);
12940 if (rdataset.type == dns_rdatatype_nsec ||
12941 rdataset.type == dns_rdatatype_rrsig ||
12942 rdataset.type == dns_rdatatype_nsec3 ||
12943 rdataset.type == dns_rdatatype_dnskey ||
12944 rdataset.type == dns_rdatatype_nsec3param) {
12945 dns_rdataset_disassociate(&rdataset);
12948 if (rdataset.type == dns_rdatatype_soa &&
12950 result = checkandaddsoa(db, node, version,
12951 &rdataset, oldserial);
12953 result = dns_db_addrdataset(db, node, version,
12956 if (result != ISC_R_SUCCESS)
12959 dns_rdataset_disassociate(&rdataset);
12961 dns_rdatasetiter_destroy(&rdsit);
12962 dns_db_detachnode(rawdb, &rawnode);
12963 dns_db_detachnode(db, &node);
12966 dns_db_closeversion(db, &version, ISC_TRUE);
12968 * Lock hierarchy: zmgr, zone, raw.
12971 if (inline_secure(zone))
12972 LOCK_ZONE(zone->raw);
12973 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
12974 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
12975 zone_needdump(zone, 0); /* XXXMPA */
12976 if (inline_secure(zone))
12977 UNLOCK_ZONE(zone->raw);
12981 if (result != ISC_R_SUCCESS)
12982 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
12983 dns_result_totext(result));
12985 if (dns_rdataset_isassociated(&rdataset))
12986 dns_rdataset_disassociate(&rdataset);
12989 dns_db_detachnode(db, &node);
12990 dns_db_detach(&db);
12992 if (rawnode != NULL)
12993 dns_db_detachnode(rawdb, &rawnode);
12994 dns_db_detach(&rawdb);
12995 if (dbiterator != NULL)
12996 dns_dbiterator_destroy(&dbiterator);
12997 dns_zone_idetach(&zone);
13000 static isc_result_t
13001 zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked, dns_db_t *db) {
13003 dns_db_t *dummy = NULL;
13004 dns_zone_t *secure = NULL;
13006 e = isc_event_allocate(zone->secure->mctx, zone,
13007 DNS_EVENT_ZONESECUREDB,
13008 receive_secure_db, zone->secure,
13009 sizeof(struct secure_event));
13011 return (ISC_R_NOMEMORY);
13012 dns_db_attach(db, &dummy);
13013 ((struct secure_event *)e)->db = dummy;
13015 zone_iattach(zone->secure, &secure);
13017 dns_zone_iattach(zone->secure, &secure);
13019 isc_task_send(zone->secure->task, &e);
13020 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
13021 return (ISC_R_SUCCESS);
13025 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
13026 isc_result_t result;
13028 REQUIRE(DNS_ZONE_VALID(zone));
13030 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
13031 result = zone_replacedb(zone, db, dump);
13032 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
13037 static isc_result_t
13038 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
13039 dns_dbversion_t *ver;
13040 isc_result_t result;
13041 unsigned int soacount = 0;
13042 unsigned int nscount = 0;
13045 * 'zone' and 'zonedb' locked by caller.
13047 REQUIRE(DNS_ZONE_VALID(zone));
13048 REQUIRE(LOCKED_ZONE(zone));
13050 result = zone_get_from_db(zone, db, &nscount, &soacount,
13051 NULL, NULL, NULL, NULL, NULL, NULL);
13052 if (result == ISC_R_SUCCESS) {
13053 if (soacount != 1) {
13054 dns_zone_log(zone, ISC_LOG_ERROR,
13055 "has %d SOA records", soacount);
13056 result = DNS_R_BADZONE;
13058 if (nscount == 0 && zone->type != dns_zone_key) {
13059 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
13060 result = DNS_R_BADZONE;
13062 if (result != ISC_R_SUCCESS)
13065 dns_zone_log(zone, ISC_LOG_ERROR,
13066 "retrieving SOA and NS records failed: %s",
13067 dns_result_totext(result));
13071 result = check_nsec3param(zone, db);
13072 if (result != ISC_R_SUCCESS)
13076 dns_db_currentversion(db, &ver);
13079 * The initial version of a slave zone is always dumped;
13080 * subsequent versions may be journaled instead if this
13081 * is enabled in the configuration.
13083 if (zone->db != NULL && zone->journal != NULL &&
13084 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
13085 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
13087 isc_uint32_t serial, oldserial;
13088 unsigned int soacount;
13090 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
13092 result = dns_db_getsoaserial(db, ver, &serial);
13093 if (result != ISC_R_SUCCESS) {
13094 dns_zone_log(zone, ISC_LOG_ERROR,
13095 "ixfr-from-differences: unable to get "
13101 * This is checked in zone_postload() for master zones.
13103 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
13104 &oldserial, NULL, NULL, NULL, NULL,
13106 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13107 RUNTIME_CHECK(soacount > 0U);
13108 if ((zone->type == dns_zone_slave ||
13109 (zone->type == dns_zone_redirect &&
13110 zone->masters != NULL))
13111 && !isc_serial_gt(serial, oldserial)) {
13112 isc_uint32_t serialmin, serialmax;
13113 serialmin = (oldserial + 1) & 0xffffffffU;
13114 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
13115 dns_zone_log(zone, ISC_LOG_ERROR,
13116 "ixfr-from-differences: failed: "
13117 "new serial (%u) out of range [%u - %u]",
13118 serial, serialmin, serialmax);
13119 result = ISC_R_RANGE;
13123 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
13125 if (result != ISC_R_SUCCESS)
13128 zone_needdump(zone, DNS_DUMP_DELAY);
13129 else if (zone->journalsize != -1) {
13130 result = dns_journal_compact(zone->mctx, zone->journal,
13131 serial, zone->journalsize);
13133 case ISC_R_SUCCESS:
13134 case ISC_R_NOSPACE:
13135 case ISC_R_NOTFOUND:
13136 dns_zone_log(zone, ISC_LOG_DEBUG(3),
13137 "dns_journal_compact: %s",
13138 dns_result_totext(result));
13141 dns_zone_log(zone, ISC_LOG_ERROR,
13142 "dns_journal_compact failed: %s",
13143 dns_result_totext(result));
13147 if (zone->type == dns_zone_master && inline_raw(zone))
13148 zone_send_secureserial(zone, ISC_FALSE, serial);
13150 if (dump && zone->masterfile != NULL) {
13152 * If DNS_ZONEFLG_FORCEXFER was set we don't want
13153 * to keep the old masterfile.
13155 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
13156 remove(zone->masterfile) < 0 && errno != ENOENT) {
13157 char strbuf[ISC_STRERRORSIZE];
13158 isc__strerror(errno, strbuf, sizeof(strbuf));
13159 isc_log_write(dns_lctx,
13160 DNS_LOGCATEGORY_GENERAL,
13161 DNS_LOGMODULE_ZONE,
13163 "unable to remove masterfile "
13165 zone->masterfile, strbuf);
13167 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
13168 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
13170 zone_needdump(zone, 0);
13172 if (dump && zone->journal != NULL) {
13174 * The in-memory database just changed, and
13175 * because 'dump' is set, it didn't change by
13176 * being loaded from disk. Also, we have not
13177 * journaled diffs for this change.
13178 * Therefore, the on-disk journal is missing
13179 * the deltas for this change. Since it can
13180 * no longer be used to bring the zone
13181 * up-to-date, it is useless and should be
13184 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13185 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13186 "removing journal file");
13187 if (remove(zone->journal) < 0 && errno != ENOENT) {
13188 char strbuf[ISC_STRERRORSIZE];
13189 isc__strerror(errno, strbuf, sizeof(strbuf));
13190 isc_log_write(dns_lctx,
13191 DNS_LOGCATEGORY_GENERAL,
13192 DNS_LOGMODULE_ZONE,
13194 "unable to remove journal "
13196 zone->journal, strbuf);
13200 if (inline_raw(zone))
13201 zone_send_securedb(zone, ISC_FALSE, db);
13204 dns_db_closeversion(db, &ver, ISC_FALSE);
13206 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
13208 if (zone->db != NULL)
13209 zone_detachdb(zone);
13210 zone_attachdb(zone, db);
13211 dns_db_settask(zone->db, zone->task);
13212 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
13213 return (ISC_R_SUCCESS);
13216 dns_db_closeversion(db, &ver, ISC_FALSE);
13220 /* The caller must hold the dblock as a writer. */
13222 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
13223 REQUIRE(zone->db == NULL && db != NULL);
13225 dns_db_attach(db, &zone->db);
13226 if (zone->acache != NULL) {
13227 isc_result_t result;
13228 result = dns_acache_setdb(zone->acache, db);
13229 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
13230 UNEXPECTED_ERROR(__FILE__, __LINE__,
13231 "dns_acache_setdb() failed: %s",
13232 isc_result_totext(result));
13237 /* The caller must hold the dblock as a writer. */
13239 zone_detachdb(dns_zone_t *zone) {
13240 REQUIRE(zone->db != NULL);
13242 if (zone->acache != NULL)
13243 (void)dns_acache_putdb(zone->acache, zone->db);
13244 dns_db_detach(&zone->db);
13248 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
13250 isc_boolean_t again = ISC_FALSE;
13251 unsigned int soacount;
13252 unsigned int nscount;
13253 isc_uint32_t serial, refresh, retry, expire, minimum;
13254 isc_result_t xfrresult = result;
13255 isc_boolean_t free_needed;
13257 REQUIRE(DNS_ZONE_VALID(zone));
13259 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13260 "zone transfer finished: %s", dns_result_totext(result));
13263 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
13264 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
13265 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
13269 case ISC_R_SUCCESS:
13270 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13272 case DNS_R_UPTODATE:
13273 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13275 * Has the zone expired underneath us?
13277 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13278 if (zone->db == NULL) {
13279 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13284 * Update the zone structure's data from the actual
13289 INSIST(zone->db != NULL);
13290 result = zone_get_from_db(zone, zone->db, &nscount,
13291 &soacount, &serial, &refresh,
13292 &retry, &expire, &minimum, NULL);
13293 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13294 if (result == ISC_R_SUCCESS) {
13296 dns_zone_log(zone, ISC_LOG_ERROR,
13297 "transferred zone "
13298 "has %d SOA record%s", soacount,
13299 (soacount != 0) ? "s" : "");
13300 if (nscount == 0) {
13301 dns_zone_log(zone, ISC_LOG_ERROR,
13302 "transferred zone "
13303 "has no NS records");
13304 if (DNS_ZONE_FLAG(zone,
13305 DNS_ZONEFLG_HAVETIMERS)) {
13306 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
13307 zone->retry = DNS_ZONE_DEFAULTRETRY;
13309 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
13313 zone->refresh = RANGE(refresh, zone->minrefresh,
13315 zone->retry = RANGE(retry, zone->minretry,
13317 zone->expire = RANGE(expire,
13318 zone->refresh + zone->retry,
13320 zone->minimum = minimum;
13321 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
13325 * Set our next update/expire times.
13327 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
13328 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
13329 zone->refreshtime = now;
13330 DNS_ZONE_TIME_ADD(&now, zone->expire,
13331 &zone->expiretime);
13333 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
13334 &zone->refreshtime);
13335 DNS_ZONE_TIME_ADD(&now, zone->expire,
13336 &zone->expiretime);
13338 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
13339 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
13340 if (zone->tsigkey != NULL) {
13341 char namebuf[DNS_NAME_FORMATSIZE];
13342 dns_name_format(&zone->tsigkey->name, namebuf,
13344 snprintf(buf, sizeof(buf), ": TSIG '%s'",
13348 dns_zone_log(zone, ISC_LOG_INFO,
13349 "transferred serial %u%s",
13351 if (inline_raw(zone))
13352 zone_send_secureserial(zone, ISC_FALSE, serial);
13356 * This is not necessary if we just performed a AXFR
13357 * however it is necessary for an IXFR / UPTODATE and
13358 * won't hurt with an AXFR.
13360 if (zone->masterfile != NULL || zone->journal != NULL) {
13361 unsigned int delay = DNS_DUMP_DELAY;
13363 result = ISC_R_FAILURE;
13364 if (zone->journal != NULL)
13365 result = isc_file_settime(zone->journal, &now);
13366 if (result != ISC_R_SUCCESS &&
13367 zone->masterfile != NULL)
13368 result = isc_file_settime(zone->masterfile,
13371 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
13372 result == ISC_R_FILENOTFOUND)
13375 if ((result == ISC_R_SUCCESS ||
13376 result == ISC_R_FILENOTFOUND) &&
13377 zone->masterfile != NULL)
13378 zone_needdump(zone, delay);
13379 else if (result != ISC_R_SUCCESS)
13380 dns_zone_log(zone, ISC_LOG_ERROR,
13381 "transfer: could not set file "
13382 "modification time of '%s': %s",
13384 dns_result_totext(result));
13386 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
13387 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
13390 case DNS_R_BADIXFR:
13391 /* Force retry with AXFR. */
13392 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
13398 * Skip to next failed / untried master.
13402 } while (zone->curmaster < zone->masterscnt &&
13403 zone->mastersok[zone->curmaster]);
13406 if (zone->curmaster >= zone->masterscnt) {
13407 zone->curmaster = 0;
13408 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
13409 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
13410 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
13411 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
13412 while (zone->curmaster < zone->masterscnt &&
13413 zone->mastersok[zone->curmaster])
13417 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
13419 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
13422 inc_stats(zone, dns_zonestatscounter_xfrfail);
13425 zone_settimer(zone, &now);
13428 * If creating the transfer object failed, zone->xfr is NULL.
13429 * Otherwise, we are called as the done callback of a zone
13430 * transfer object that just entered its shutting-down
13431 * state. Since we are no longer responsible for shutting
13432 * it down, we can detach our reference.
13434 if (zone->xfr != NULL)
13435 dns_xfrin_detach(&zone->xfr);
13437 if (zone->tsigkey != NULL)
13438 dns_tsigkey_detach(&zone->tsigkey);
13441 * Handle any deferred journal compaction.
13443 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
13444 result = dns_journal_compact(zone->mctx, zone->journal,
13445 zone->compact_serial,
13446 zone->journalsize);
13448 case ISC_R_SUCCESS:
13449 case ISC_R_NOSPACE:
13450 case ISC_R_NOTFOUND:
13451 dns_zone_log(zone, ISC_LOG_DEBUG(3),
13452 "dns_journal_compact: %s",
13453 dns_result_totext(result));
13456 dns_zone_log(zone, ISC_LOG_ERROR,
13457 "dns_journal_compact failed: %s",
13458 dns_result_totext(result));
13461 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
13465 * This transfer finishing freed up a transfer quota slot.
13466 * Let any other zones waiting for quota have it.
13469 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
13470 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
13471 zone->statelist = NULL;
13472 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
13473 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
13477 * Retry with a different server if necessary.
13479 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
13480 queue_soa_query(zone);
13482 INSIST(zone->irefs > 0);
13484 free_needed = exit_check(zone);
13491 zone_loaddone(void *arg, isc_result_t result) {
13492 static char me[] = "zone_loaddone";
13493 dns_load_t *load = arg;
13495 isc_result_t tresult;
13497 REQUIRE(DNS_LOAD_VALID(load));
13502 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
13503 if (tresult != ISC_R_SUCCESS &&
13504 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
13508 * Lock hierarchy: zmgr, zone, raw.
13511 if (inline_secure(zone))
13512 LOCK_ZONE(zone->raw);
13513 (void)zone_postload(zone, load->db, load->loadtime, result);
13514 zonemgr_putio(&zone->readio);
13515 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
13516 zone_idetach(&load->callbacks.zone);
13518 * Leave the zone frozen if the reload fails.
13520 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
13521 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
13522 zone->update_disabled = ISC_FALSE;
13523 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
13524 if (inline_secure(zone))
13525 UNLOCK_ZONE(zone->raw);
13529 dns_db_detach(&load->db);
13530 if (load->zone->lctx != NULL)
13531 dns_loadctx_detach(&load->zone->lctx);
13532 dns_zone_idetach(&load->zone);
13533 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
13537 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
13538 REQUIRE(DNS_ZONE_VALID(zone));
13539 REQUIRE(table != NULL);
13540 REQUIRE(*table == NULL);
13543 if (zone->ssutable != NULL)
13544 dns_ssutable_attach(zone->ssutable, table);
13549 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
13550 REQUIRE(DNS_ZONE_VALID(zone));
13553 if (zone->ssutable != NULL)
13554 dns_ssutable_detach(&zone->ssutable);
13556 dns_ssutable_attach(table, &zone->ssutable);
13561 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
13562 REQUIRE(DNS_ZONE_VALID(zone));
13564 zone->sigvalidityinterval = interval;
13568 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
13569 REQUIRE(DNS_ZONE_VALID(zone));
13571 return (zone->sigvalidityinterval);
13575 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
13576 REQUIRE(DNS_ZONE_VALID(zone));
13578 zone->sigresigninginterval = interval;
13582 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
13583 REQUIRE(DNS_ZONE_VALID(zone));
13585 return (zone->sigresigninginterval);
13589 queue_xfrin(dns_zone_t *zone) {
13590 const char me[] = "queue_xfrin";
13591 isc_result_t result;
13592 dns_zonemgr_t *zmgr = zone->zmgr;
13596 INSIST(zone->statelist == NULL);
13598 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13599 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
13603 zone->statelist = &zmgr->waiting_for_xfrin;
13604 result = zmgr_start_xfrin_ifquota(zmgr, zone);
13605 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13607 if (result == ISC_R_QUOTA) {
13608 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
13609 "zone transfer deferred due to quota");
13610 } else if (result != ISC_R_SUCCESS) {
13611 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
13612 "starting zone transfer: %s",
13613 isc_result_totext(result));
13618 * This event callback is called when a zone has received
13619 * any necessary zone transfer quota. This is the time
13620 * to go ahead and start the transfer.
13623 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
13624 isc_result_t result = ISC_R_SUCCESS;
13625 dns_peer_t *peer = NULL;
13626 char master[ISC_SOCKADDR_FORMATSIZE];
13627 char source[ISC_SOCKADDR_FORMATSIZE];
13628 dns_rdatatype_t xfrtype;
13629 dns_zone_t *zone = event->ev_arg;
13630 isc_netaddr_t masterip;
13631 isc_sockaddr_t sourceaddr;
13632 isc_sockaddr_t masteraddr;
13634 const char *soa_before = "";
13638 INSIST(task == zone->task);
13640 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
13641 result = ISC_R_CANCELED;
13647 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
13648 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
13649 &zone->sourceaddr, &now))
13651 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
13652 dns_zone_log(zone, ISC_LOG_INFO,
13653 "got_transfer_quota: skipping zone transfer as "
13654 "master %s (source %s) is unreachable (cached)",
13656 result = ISC_R_CANCELED;
13660 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
13661 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
13663 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
13664 soa_before = "SOA before ";
13666 * Decide whether we should request IXFR or AXFR.
13668 if (zone->db == NULL) {
13669 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13670 "no database exists yet, requesting AXFR of "
13671 "initial version from %s", master);
13672 xfrtype = dns_rdatatype_axfr;
13673 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
13674 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13675 "forced reload, requesting AXFR of "
13676 "initial version from %s", master);
13677 xfrtype = dns_rdatatype_axfr;
13678 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
13679 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13680 "retrying with AXFR from %s due to "
13681 "previous IXFR failure", master);
13682 xfrtype = dns_rdatatype_axfr;
13684 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
13687 isc_boolean_t use_ixfr = ISC_TRUE;
13689 result = dns_peer_getrequestixfr(peer, &use_ixfr);
13690 if (peer == NULL || result != ISC_R_SUCCESS)
13691 use_ixfr = zone->requestixfr;
13692 if (use_ixfr == ISC_FALSE) {
13693 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13694 "IXFR disabled, requesting %sAXFR from %s",
13695 soa_before, master);
13696 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
13697 xfrtype = dns_rdatatype_soa;
13699 xfrtype = dns_rdatatype_axfr;
13701 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13702 "requesting IXFR from %s", master);
13703 xfrtype = dns_rdatatype_ixfr;
13708 * Determine if we should attempt to sign the request with TSIG.
13710 result = ISC_R_NOTFOUND;
13712 * First, look for a tsig key in the master statement, then
13713 * try for a server key.
13715 if ((zone->masterkeynames != NULL) &&
13716 (zone->masterkeynames[zone->curmaster] != NULL)) {
13717 dns_view_t *view = dns_zone_getview(zone);
13718 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
13719 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
13721 if (zone->tsigkey == NULL)
13722 result = dns_view_getpeertsig(zone->view, &masterip,
13725 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
13726 dns_zone_log(zone, ISC_LOG_ERROR,
13727 "could not get TSIG key for zone transfer: %s",
13728 isc_result_totext(result));
13732 masteraddr = zone->masteraddr;
13733 sourceaddr = zone->sourceaddr;
13735 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
13736 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
13737 zone->tsigkey, zone->mctx,
13738 zone->zmgr->timermgr, zone->zmgr->socketmgr,
13739 zone->task, zone_xfrdone, &zone->xfr);
13740 if (result == ISC_R_SUCCESS) {
13742 if (xfrtype == dns_rdatatype_axfr) {
13743 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
13744 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
13746 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
13747 } else if (xfrtype == dns_rdatatype_ixfr) {
13748 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
13749 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
13751 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
13757 * Any failure in this function is handled like a failed
13758 * zone transfer. This ensures that we get removed from
13759 * zmgr->xfrin_in_progress.
13761 if (result != ISC_R_SUCCESS)
13762 zone_xfrdone(zone, result);
13764 isc_event_free(&event);
13768 * Update forwarding support.
13772 forward_destroy(dns_forward_t *forward) {
13774 forward->magic = 0;
13775 if (forward->request != NULL)
13776 dns_request_destroy(&forward->request);
13777 if (forward->msgbuf != NULL)
13778 isc_buffer_free(&forward->msgbuf);
13779 if (forward->zone != NULL) {
13780 LOCK(&forward->zone->lock);
13781 if (ISC_LINK_LINKED(forward, link))
13782 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
13783 UNLOCK(&forward->zone->lock);
13784 dns_zone_idetach(&forward->zone);
13786 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
13789 static isc_result_t
13790 sendtomaster(dns_forward_t *forward) {
13791 isc_result_t result;
13792 isc_sockaddr_t src;
13794 LOCK_ZONE(forward->zone);
13796 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
13797 UNLOCK_ZONE(forward->zone);
13798 return (ISC_R_CANCELED);
13801 if (forward->which >= forward->zone->masterscnt) {
13802 UNLOCK_ZONE(forward->zone);
13803 return (ISC_R_NOMORE);
13806 forward->addr = forward->zone->masters[forward->which];
13808 * Always use TCP regardless of whether the original update
13810 * XXX The timeout may but a bit small if we are far down a
13811 * transfer graph and the master has to try several masters.
13813 switch (isc_sockaddr_pf(&forward->addr)) {
13815 src = forward->zone->xfrsource4;
13818 src = forward->zone->xfrsource6;
13821 result = ISC_R_NOTIMPLEMENTED;
13824 result = dns_request_createraw(forward->zone->view->requestmgr,
13826 &src, &forward->addr,
13827 DNS_REQUESTOPT_TCP, 15 /* XXX */,
13828 forward->zone->task,
13829 forward_callback, forward,
13830 &forward->request);
13831 if (result == ISC_R_SUCCESS) {
13832 if (!ISC_LINK_LINKED(forward, link))
13833 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
13837 UNLOCK_ZONE(forward->zone);
13842 forward_callback(isc_task_t *task, isc_event_t *event) {
13843 const char me[] = "forward_callback";
13844 dns_requestevent_t *revent = (dns_requestevent_t *)event;
13845 dns_message_t *msg = NULL;
13846 char master[ISC_SOCKADDR_FORMATSIZE];
13847 isc_result_t result;
13848 dns_forward_t *forward;
13853 forward = revent->ev_arg;
13854 INSIST(DNS_FORWARD_VALID(forward));
13855 zone = forward->zone;
13856 INSIST(DNS_ZONE_VALID(zone));
13860 isc_sockaddr_format(&forward->addr, master, sizeof(master));
13862 if (revent->result != ISC_R_SUCCESS) {
13863 dns_zone_log(zone, ISC_LOG_INFO,
13864 "could not forward dynamic update to %s: %s",
13865 master, dns_result_totext(revent->result));
13869 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
13870 if (result != ISC_R_SUCCESS)
13873 result = dns_request_getresponse(revent->request, msg,
13874 DNS_MESSAGEPARSE_PRESERVEORDER |
13875 DNS_MESSAGEPARSE_CLONEBUFFER);
13876 if (result != ISC_R_SUCCESS)
13879 switch (msg->rcode) {
13881 * Pass these rcodes back to client.
13883 case dns_rcode_noerror:
13884 case dns_rcode_yxdomain:
13885 case dns_rcode_yxrrset:
13886 case dns_rcode_nxrrset:
13887 case dns_rcode_refused:
13888 case dns_rcode_nxdomain:
13891 /* These should not occur if the masters/zone are valid. */
13892 case dns_rcode_notzone:
13893 case dns_rcode_notauth: {
13897 isc_buffer_init(&rb, rcode, sizeof(rcode));
13898 (void)dns_rcode_totext(msg->rcode, &rb);
13899 dns_zone_log(zone, ISC_LOG_WARNING,
13900 "forwarding dynamic update: "
13901 "unexpected response: master %s returned: %.*s",
13902 master, (int)rb.used, rcode);
13906 /* Try another server for these rcodes. */
13907 case dns_rcode_formerr:
13908 case dns_rcode_servfail:
13909 case dns_rcode_notimp:
13910 case dns_rcode_badvers:
13915 /* call callback */
13916 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
13918 dns_request_destroy(&forward->request);
13919 forward_destroy(forward);
13920 isc_event_free(&event);
13925 dns_message_destroy(&msg);
13926 isc_event_free(&event);
13928 dns_request_destroy(&forward->request);
13929 result = sendtomaster(forward);
13930 if (result != ISC_R_SUCCESS) {
13931 /* call callback */
13932 dns_zone_log(zone, ISC_LOG_DEBUG(3),
13933 "exhausted dynamic update forwarder list");
13934 (forward->callback)(forward->callback_arg, result, NULL);
13935 forward_destroy(forward);
13940 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
13941 dns_updatecallback_t callback, void *callback_arg)
13943 dns_forward_t *forward;
13944 isc_result_t result;
13947 REQUIRE(DNS_ZONE_VALID(zone));
13948 REQUIRE(msg != NULL);
13949 REQUIRE(callback != NULL);
13951 forward = isc_mem_get(zone->mctx, sizeof(*forward));
13952 if (forward == NULL)
13953 return (ISC_R_NOMEMORY);
13955 forward->request = NULL;
13956 forward->zone = NULL;
13957 forward->msgbuf = NULL;
13958 forward->which = 0;
13960 forward->callback = callback;
13961 forward->callback_arg = callback_arg;
13962 ISC_LINK_INIT(forward, link);
13963 forward->magic = FORWARD_MAGIC;
13965 mr = dns_message_getrawmessage(msg);
13967 result = ISC_R_UNEXPECTEDEND;
13971 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
13972 if (result != ISC_R_SUCCESS)
13974 result = isc_buffer_copyregion(forward->msgbuf, mr);
13975 if (result != ISC_R_SUCCESS)
13978 isc_mem_attach(zone->mctx, &forward->mctx);
13979 dns_zone_iattach(zone, &forward->zone);
13980 result = sendtomaster(forward);
13983 if (result != ISC_R_SUCCESS) {
13984 forward_destroy(forward);
13990 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
13991 REQUIRE(DNS_ZONE_VALID(zone));
13992 REQUIRE(next != NULL && *next == NULL);
13994 *next = ISC_LIST_NEXT(zone, link);
13996 return (ISC_R_NOMORE);
13998 return (ISC_R_SUCCESS);
14002 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
14003 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14004 REQUIRE(first != NULL && *first == NULL);
14006 *first = ISC_LIST_HEAD(zmgr->zones);
14007 if (*first == NULL)
14008 return (ISC_R_NOMORE);
14010 return (ISC_R_SUCCESS);
14018 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
14019 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
14020 dns_zonemgr_t **zmgrp)
14022 dns_zonemgr_t *zmgr;
14023 isc_result_t result;
14024 isc_interval_t interval;
14026 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
14028 return (ISC_R_NOMEMORY);
14031 isc_mem_attach(mctx, &zmgr->mctx);
14032 zmgr->taskmgr = taskmgr;
14033 zmgr->timermgr = timermgr;
14034 zmgr->socketmgr = socketmgr;
14035 zmgr->zonetasks = NULL;
14036 zmgr->loadtasks = NULL;
14037 zmgr->mctxpool = NULL;
14040 ISC_LIST_INIT(zmgr->zones);
14041 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
14042 ISC_LIST_INIT(zmgr->xfrin_in_progress);
14043 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
14044 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
14045 if (result != ISC_R_SUCCESS)
14048 zmgr->transfersin = 10;
14049 zmgr->transfersperns = 2;
14051 /* Unreachable lock. */
14052 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
14053 if (result != ISC_R_SUCCESS)
14056 /* Create a single task for queueing of SOA queries. */
14057 result = isc_task_create(taskmgr, 1, &zmgr->task);
14058 if (result != ISC_R_SUCCESS)
14061 isc_task_setname(zmgr->task, "zmgr", zmgr);
14062 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14064 if (result != ISC_R_SUCCESS)
14067 /* default to 20 refresh queries / notifies per second. */
14068 isc_interval_set(&interval, 0, 1000000000/2);
14069 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
14070 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14071 isc_ratelimiter_setpertic(zmgr->rl, 10);
14074 zmgr->ioactive = 0;
14075 ISC_LIST_INIT(zmgr->high);
14076 ISC_LIST_INIT(zmgr->low);
14078 result = isc_mutex_init(&zmgr->iolock);
14079 if (result != ISC_R_SUCCESS)
14082 zmgr->magic = ZONEMGR_MAGIC;
14085 return (ISC_R_SUCCESS);
14089 DESTROYLOCK(&zmgr->iolock);
14092 isc_ratelimiter_detach(&zmgr->rl);
14094 isc_task_detach(&zmgr->task);
14096 isc_rwlock_destroy(&zmgr->urlock);
14098 isc_rwlock_destroy(&zmgr->rwlock);
14100 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
14101 isc_mem_detach(&mctx);
14106 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
14107 isc_result_t result;
14108 isc_mem_t *mctx = NULL;
14109 dns_zone_t *zone = NULL;
14112 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14113 REQUIRE(zonep != NULL && *zonep == NULL);
14115 if (zmgr->mctxpool == NULL)
14116 return (ISC_R_FAILURE);
14118 item = isc_pool_get(zmgr->mctxpool);
14120 return (ISC_R_FAILURE);
14122 isc_mem_attach((isc_mem_t *) item, &mctx);
14123 result = dns_zone_create(&zone, mctx);
14124 isc_mem_detach(&mctx);
14126 if (result == ISC_R_SUCCESS)
14133 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14134 isc_result_t result;
14136 REQUIRE(DNS_ZONE_VALID(zone));
14137 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14139 if (zmgr->zonetasks == NULL)
14140 return (ISC_R_FAILURE);
14142 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14144 REQUIRE(zone->task == NULL);
14145 REQUIRE(zone->timer == NULL);
14146 REQUIRE(zone->zmgr == NULL);
14148 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
14149 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
14152 * Set the task name. The tag will arbitrarily point to one
14153 * of the zones sharing the task (in practice, the one
14154 * to be managed last).
14156 isc_task_setname(zone->task, "zone", zone);
14157 isc_task_setname(zone->loadtask, "loadzone", zone);
14159 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
14161 zone->task, zone_timer, zone,
14164 if (result != ISC_R_SUCCESS)
14165 goto cleanup_tasks;
14168 * The timer "holds" a iref.
14171 INSIST(zone->irefs != 0);
14173 ISC_LIST_APPEND(zmgr->zones, zone, link);
14180 isc_task_detach(&zone->loadtask);
14181 isc_task_detach(&zone->task);
14185 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14190 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14191 isc_boolean_t free_now = ISC_FALSE;
14193 REQUIRE(DNS_ZONE_VALID(zone));
14194 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14195 REQUIRE(zone->zmgr == zmgr);
14197 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14200 ISC_LIST_UNLINK(zmgr->zones, zone, link);
14203 if (zmgr->refs == 0)
14204 free_now = ISC_TRUE;
14207 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14210 zonemgr_free(zmgr);
14211 ENSURE(zone->zmgr == NULL);
14215 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
14216 REQUIRE(DNS_ZONEMGR_VALID(source));
14217 REQUIRE(target != NULL && *target == NULL);
14219 RWLOCK(&source->rwlock, isc_rwlocktype_write);
14220 REQUIRE(source->refs > 0);
14222 INSIST(source->refs > 0);
14223 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
14228 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
14229 dns_zonemgr_t *zmgr;
14230 isc_boolean_t free_now = ISC_FALSE;
14232 REQUIRE(zmgrp != NULL);
14234 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14236 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14238 if (zmgr->refs == 0)
14239 free_now = ISC_TRUE;
14240 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14243 zonemgr_free(zmgr);
14248 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
14251 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14253 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
14254 for (p = ISC_LIST_HEAD(zmgr->zones);
14256 p = ISC_LIST_NEXT(p, link))
14258 dns_zone_maintenance(p);
14260 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
14263 * Recent configuration changes may have increased the
14264 * amount of available transfers quota. Make sure any
14265 * transfers currently blocked on quota get started if
14268 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14269 zmgr_resume_xfrs(zmgr, ISC_TRUE);
14270 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14271 return (ISC_R_SUCCESS);
14275 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
14277 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14279 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14280 zmgr_resume_xfrs(zmgr, ISC_TRUE);
14281 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14285 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
14288 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14290 isc_ratelimiter_shutdown(zmgr->rl);
14292 if (zmgr->task != NULL)
14293 isc_task_destroy(&zmgr->task);
14294 if (zmgr->zonetasks != NULL)
14295 isc_taskpool_destroy(&zmgr->zonetasks);
14296 if (zmgr->loadtasks != NULL)
14297 isc_taskpool_destroy(&zmgr->loadtasks);
14298 if (zmgr->mctxpool != NULL)
14299 isc_pool_destroy(&zmgr->mctxpool);
14301 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
14302 for (zone = ISC_LIST_HEAD(zmgr->zones);
14304 zone = ISC_LIST_NEXT(zone, link))
14307 forward_cancel(zone);
14310 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
14313 static isc_result_t
14314 mctxinit(void **target, void *arg) {
14315 isc_result_t result;
14316 isc_mem_t *mctx = NULL;
14320 REQUIRE(target != NULL && *target == NULL);
14322 result = isc_mem_create(0, 0, &mctx);
14323 if (result != ISC_R_SUCCESS)
14325 isc_mem_setname(mctx, "zonemgr-pool", NULL);
14328 return (ISC_R_SUCCESS);
14332 mctxfree(void **target) {
14333 isc_mem_t *mctx = *(isc_mem_t **) target;
14334 isc_mem_detach(&mctx);
14338 #define ZONES_PER_TASK 100
14339 #define ZONES_PER_MCTX 1000
14342 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
14343 isc_result_t result;
14344 int ntasks = num_zones / ZONES_PER_TASK;
14345 int nmctx = num_zones / ZONES_PER_MCTX;
14346 isc_taskpool_t *pool = NULL;
14347 isc_pool_t *mctxpool = NULL;
14349 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14352 * For anything fewer than 1000 zones we use 10 tasks in
14353 * the task pools. More than that, and we'll scale at one
14354 * task per 100 zones. Similarly, for anything smaller than
14355 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
14362 /* Create or resize the zone task pools. */
14363 if (zmgr->zonetasks == NULL)
14364 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
14367 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
14369 if (result == ISC_R_SUCCESS)
14370 zmgr->zonetasks = pool;
14373 if (zmgr->loadtasks == NULL)
14374 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
14377 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
14379 if (result == ISC_R_SUCCESS)
14380 zmgr->loadtasks = pool;
14384 * We always set all tasks in the zone-load task pool to
14385 * privileged. This prevents other tasks in the system from
14386 * running while the server task manager is in privileged
14389 * NOTE: If we start using task privileges for any other
14390 * part of the system than zone tasks, then this will need to be
14391 * revisted. In that case we'd want to turn on privileges for
14392 * zone tasks only when we were loading, and turn them off the
14393 * rest of the time. For now, however, it's okay to just
14394 * set it and forget it.
14396 isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE);
14399 /* Create or resize the zone memory context pool. */
14400 if (zmgr->mctxpool == NULL)
14401 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
14402 mctxinit, NULL, &mctxpool);
14404 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
14406 if (result == ISC_R_SUCCESS)
14407 zmgr->mctxpool = mctxpool;
14413 zonemgr_free(dns_zonemgr_t *zmgr) {
14416 INSIST(zmgr->refs == 0);
14417 INSIST(ISC_LIST_EMPTY(zmgr->zones));
14421 DESTROYLOCK(&zmgr->iolock);
14422 isc_ratelimiter_detach(&zmgr->rl);
14424 isc_rwlock_destroy(&zmgr->urlock);
14425 isc_rwlock_destroy(&zmgr->rwlock);
14427 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
14428 isc_mem_detach(&mctx);
14432 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
14433 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14435 zmgr->transfersin = value;
14439 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
14440 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14442 return (zmgr->transfersin);
14446 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
14447 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14449 zmgr->transfersperns = value;
14453 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
14454 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14456 return (zmgr->transfersperns);
14460 * Try to start a new incoming zone transfer to fill a quota
14461 * slot that was just vacated.
14464 * The zone manager is locked by the caller.
14467 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
14471 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
14475 isc_result_t result;
14476 next = ISC_LIST_NEXT(zone, statelink);
14477 result = zmgr_start_xfrin_ifquota(zmgr, zone);
14478 if (result == ISC_R_SUCCESS) {
14482 * We successfully filled the slot. We're done.
14485 } else if (result == ISC_R_QUOTA) {
14487 * Not enough quota. This is probably the per-server
14488 * quota, because we usually get called when a unit of
14489 * global quota has just been freed. Try the next
14490 * zone, it may succeed if it uses another master.
14494 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14495 "starting zone transfer: %s",
14496 isc_result_totext(result));
14503 * Try to start an incoming zone transfer for 'zone', quota permitting.
14506 * The zone manager is locked by the caller.
14509 * ISC_R_SUCCESS There was enough quota and we attempted to
14510 * start a transfer. zone_xfrdone() has been or will
14512 * ISC_R_QUOTA Not enough quota.
14515 static isc_result_t
14516 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14517 dns_peer_t *peer = NULL;
14518 isc_netaddr_t masterip;
14519 isc_uint32_t nxfrsin, nxfrsperns;
14521 isc_uint32_t maxtransfersin, maxtransfersperns;
14525 * If we are exiting just pretend we got quota so the zone will
14526 * be cleaned up in the zone's task context.
14529 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
14535 * Find any configured information about the server we'd
14536 * like to transfer this zone from.
14538 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
14539 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
14543 * Determine the total maximum number of simultaneous
14544 * transfers allowed, and the maximum for this specific
14547 maxtransfersin = zmgr->transfersin;
14548 maxtransfersperns = zmgr->transfersperns;
14550 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
14553 * Count the total number of transfers that are in progress,
14554 * and the number of transfers in progress from this master.
14555 * We linearly scan a list of all transfers; if this turns
14556 * out to be too slow, we could hash on the master address.
14558 nxfrsin = nxfrsperns = 0;
14559 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
14561 x = ISC_LIST_NEXT(x, statelink))
14566 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
14570 if (isc_netaddr_equal(&xip, &masterip))
14574 /* Enforce quota. */
14575 if (nxfrsin >= maxtransfersin)
14576 return (ISC_R_QUOTA);
14578 if (nxfrsperns >= maxtransfersperns)
14579 return (ISC_R_QUOTA);
14583 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
14584 * list and send it an event to let it start the actual transfer in the
14585 * context of its own task.
14587 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
14588 got_transfer_quota, zone, sizeof(isc_event_t));
14590 return (ISC_R_NOMEMORY);
14593 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
14594 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
14595 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
14596 zone->statelist = &zmgr->xfrin_in_progress;
14597 isc_task_send(zone->task, &e);
14598 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
14601 return (ISC_R_SUCCESS);
14605 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
14607 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14608 REQUIRE(iolimit > 0);
14610 zmgr->iolimit = iolimit;
14614 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
14616 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14618 return (zmgr->iolimit);
14622 * Get permission to request a file handle from the OS.
14623 * An event will be sent to action when one is available.
14624 * There are two queues available (high and low), the high
14625 * queue will be serviced before the low one.
14627 * zonemgr_putio() must be called after the event is delivered to
14631 static isc_result_t
14632 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
14633 isc_task_t *task, isc_taskaction_t action, void *arg,
14637 isc_boolean_t queue;
14639 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14640 REQUIRE(iop != NULL && *iop == NULL);
14642 io = isc_mem_get(zmgr->mctx, sizeof(*io));
14644 return (ISC_R_NOMEMORY);
14646 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
14647 action, arg, sizeof(*io->event));
14648 if (io->event == NULL) {
14649 isc_mem_put(zmgr->mctx, io, sizeof(*io));
14650 return (ISC_R_NOMEMORY);
14656 isc_task_attach(task, &io->task);
14657 ISC_LINK_INIT(io, link);
14658 io->magic = IO_MAGIC;
14660 LOCK(&zmgr->iolock);
14662 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
14665 ISC_LIST_APPEND(zmgr->high, io, link);
14667 ISC_LIST_APPEND(zmgr->low, io, link);
14669 UNLOCK(&zmgr->iolock);
14673 isc_task_send(io->task, &io->event);
14674 return (ISC_R_SUCCESS);
14678 zonemgr_putio(dns_io_t **iop) {
14681 dns_zonemgr_t *zmgr;
14683 REQUIRE(iop != NULL);
14685 REQUIRE(DNS_IO_VALID(io));
14689 INSIST(!ISC_LINK_LINKED(io, link));
14690 INSIST(io->event == NULL);
14693 isc_task_detach(&io->task);
14695 isc_mem_put(zmgr->mctx, io, sizeof(*io));
14697 LOCK(&zmgr->iolock);
14698 INSIST(zmgr->ioactive > 0);
14700 next = HEAD(zmgr->high);
14702 next = HEAD(zmgr->low);
14703 if (next != NULL) {
14705 ISC_LIST_UNLINK(zmgr->high, next, link);
14707 ISC_LIST_UNLINK(zmgr->low, next, link);
14708 INSIST(next->event != NULL);
14710 UNLOCK(&zmgr->iolock);
14712 isc_task_send(next->task, &next->event);
14716 zonemgr_cancelio(dns_io_t *io) {
14717 isc_boolean_t send_event = ISC_FALSE;
14719 REQUIRE(DNS_IO_VALID(io));
14722 * If we are queued to be run then dequeue.
14724 LOCK(&io->zmgr->iolock);
14725 if (ISC_LINK_LINKED(io, link)) {
14727 ISC_LIST_UNLINK(io->zmgr->high, io, link);
14729 ISC_LIST_UNLINK(io->zmgr->low, io, link);
14731 send_event = ISC_TRUE;
14732 INSIST(io->event != NULL);
14734 UNLOCK(&io->zmgr->iolock);
14736 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
14737 isc_task_send(io->task, &io->event);
14742 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
14745 isc_result_t result;
14747 buflen = strlen(path) + strlen(templat) + 2;
14749 buf = isc_mem_get(zone->mctx, buflen);
14753 result = isc_file_template(path, templat, buf, buflen);
14754 if (result != ISC_R_SUCCESS)
14757 result = isc_file_renameunique(path, buf);
14758 if (result != ISC_R_SUCCESS)
14761 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
14762 "renaming file to '%s' for failure analysis and "
14763 "retransferring.", path, buf);
14766 isc_mem_put(zone->mctx, buf, buflen);
14770 /* Hook for ondestroy notification from a database. */
14773 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
14774 dns_db_t *db = event->sender;
14777 isc_event_free(&event);
14779 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
14780 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
14781 "database (%p) destroyed", (void*) db);
14786 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
14787 isc_interval_t interval;
14788 isc_uint32_t s, ns;
14789 isc_uint32_t pertic;
14790 isc_result_t result;
14792 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14801 } else if (value <= 10) {
14803 ns = 1000000000 / value;
14807 ns = (1000000000 / value) * 10;
14811 isc_interval_set(&interval, s, ns);
14812 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
14813 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14814 isc_ratelimiter_setpertic(zmgr->rl, pertic);
14816 zmgr->serialqueryrate = value;
14820 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
14821 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14823 return (zmgr->serialqueryrate);
14827 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
14828 isc_sockaddr_t *local, isc_time_t *now)
14831 isc_rwlocktype_t locktype;
14832 isc_result_t result;
14833 isc_uint32_t seconds = isc_time_seconds(now);
14835 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14837 locktype = isc_rwlocktype_read;
14838 RWLOCK(&zmgr->urlock, locktype);
14839 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
14840 if (zmgr->unreachable[i].expire >= seconds &&
14841 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
14842 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
14843 result = isc_rwlock_tryupgrade(&zmgr->urlock);
14844 if (result == ISC_R_SUCCESS) {
14845 locktype = isc_rwlocktype_write;
14846 zmgr->unreachable[i].last = seconds;
14851 RWUNLOCK(&zmgr->urlock, locktype);
14852 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
14856 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
14857 isc_sockaddr_t *local)
14860 isc_rwlocktype_t locktype;
14861 isc_result_t result;
14863 char master[ISC_SOCKADDR_FORMATSIZE];
14864 char source[ISC_SOCKADDR_FORMATSIZE];
14866 isc_sockaddr_format(remote, master, sizeof(master));
14867 isc_sockaddr_format(local, source, sizeof(source));
14869 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14871 locktype = isc_rwlocktype_read;
14872 RWLOCK(&zmgr->urlock, locktype);
14873 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
14874 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
14875 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
14876 if (zmgr->unreachable[i].expire == 0)
14878 result = isc_rwlock_tryupgrade(&zmgr->urlock);
14879 if (result == ISC_R_SUCCESS) {
14880 locktype = isc_rwlocktype_write;
14881 zmgr->unreachable[i].expire = 0;
14882 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
14883 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
14884 "master %s (source %s) deleted "
14885 "from unreachable cache",
14891 RWUNLOCK(&zmgr->urlock, locktype);
14895 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
14896 isc_sockaddr_t *local, isc_time_t *now)
14898 isc_uint32_t seconds = isc_time_seconds(now);
14899 isc_uint32_t last = seconds;
14900 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
14902 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14904 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
14905 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
14906 /* Existing entry? */
14907 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
14908 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
14911 if (zmgr->unreachable[i].expire < seconds)
14913 /* Least recently used slot? */
14914 if (zmgr->unreachable[i].last < last) {
14915 last = zmgr->unreachable[i].last;
14919 if (i < UNREACH_CHACHE_SIZE) {
14921 * Found a existing entry. Update the expire timer and
14922 * last usage timestamps.
14924 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
14925 zmgr->unreachable[i].last = seconds;
14926 } else if (slot != UNREACH_CHACHE_SIZE) {
14928 * Found a empty slot. Add a new entry to the cache.
14930 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
14931 zmgr->unreachable[slot].last = seconds;
14932 zmgr->unreachable[slot].remote = *remote;
14933 zmgr->unreachable[slot].local = *local;
14936 * Replace the least recently used entry in the cache.
14938 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
14939 zmgr->unreachable[oldest].last = seconds;
14940 zmgr->unreachable[oldest].remote = *remote;
14941 zmgr->unreachable[oldest].local = *local;
14943 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
14947 dns_zone_forcereload(dns_zone_t *zone) {
14948 REQUIRE(DNS_ZONE_VALID(zone));
14950 if (zone->type == dns_zone_master ||
14951 (zone->type == dns_zone_redirect && zone->masters == NULL))
14955 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
14957 dns_zone_refresh(zone);
14961 dns_zone_isforced(dns_zone_t *zone) {
14962 REQUIRE(DNS_ZONE_VALID(zone));
14964 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
14968 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
14970 * This function is obsoleted.
14974 return (ISC_R_NOTIMPLEMENTED);
14978 dns_zone_getstatscounters(dns_zone_t *zone) {
14980 * This function is obsoleted.
14987 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
14988 REQUIRE(DNS_ZONE_VALID(zone));
14989 REQUIRE(zone->stats == NULL);
14992 zone->stats = NULL;
14993 isc_stats_attach(stats, &zone->stats);
14998 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
15000 REQUIRE(DNS_ZONE_VALID(zone));
15003 if (zone->requeststats_on && stats == NULL)
15004 zone->requeststats_on = ISC_FALSE;
15005 else if (!zone->requeststats_on && stats != NULL) {
15006 if (zone->requeststats == NULL) {
15007 isc_stats_attach(stats, &zone->requeststats);
15008 zone->requeststats_on = ISC_TRUE;
15016 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
15018 REQUIRE(DNS_ZONE_VALID(zone));
15021 if (zone->requeststats_on && stats != NULL) {
15022 if (zone->rcvquerystats == NULL) {
15023 dns_stats_attach(stats, &zone->rcvquerystats);
15024 zone->requeststats_on = ISC_TRUE;
15032 dns_zone_getrequeststats(dns_zone_t *zone) {
15034 * We don't lock zone for efficiency reason. This is not catastrophic
15035 * because requeststats must always be valid when requeststats_on is
15037 * Some counters may be incremented while requeststats_on is becoming
15038 * false, or some cannot be incremented just after the statistics are
15039 * installed, but it shouldn't matter much in practice.
15041 if (zone->requeststats_on)
15042 return (zone->requeststats);
15049 * Return the received query stats bucket
15050 * see note from dns_zone_getrequeststats()
15053 dns_zone_getrcvquerystats(dns_zone_t *zone) {
15054 if (zone->requeststats_on)
15055 return (zone->rcvquerystats);
15062 dns_zone_dialup(dns_zone_t *zone) {
15064 REQUIRE(DNS_ZONE_VALID(zone));
15066 zone_debuglog(zone, "dns_zone_dialup", 3,
15067 "notify = %d, refresh = %d",
15068 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
15069 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
15071 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
15072 dns_zone_notify(zone);
15073 if (zone->type != dns_zone_master && zone->masters != NULL &&
15074 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
15075 dns_zone_refresh(zone);
15079 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
15080 REQUIRE(DNS_ZONE_VALID(zone));
15083 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
15084 DNS_ZONEFLG_DIALREFRESH |
15085 DNS_ZONEFLG_NOREFRESH);
15087 case dns_dialuptype_no:
15089 case dns_dialuptype_yes:
15090 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
15091 DNS_ZONEFLG_DIALREFRESH |
15092 DNS_ZONEFLG_NOREFRESH));
15094 case dns_dialuptype_notify:
15095 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
15097 case dns_dialuptype_notifypassive:
15098 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
15099 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15101 case dns_dialuptype_refresh:
15102 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
15103 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15105 case dns_dialuptype_passive:
15106 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15115 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
15116 isc_result_t result = ISC_R_SUCCESS;
15118 REQUIRE(DNS_ZONE_VALID(zone));
15121 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
15128 dns_zone_getkeydirectory(dns_zone_t *zone) {
15129 REQUIRE(DNS_ZONE_VALID(zone));
15131 return (zone->keydirectory);
15135 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
15137 unsigned int count = 0;
15139 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15141 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15143 case DNS_ZONESTATE_XFERRUNNING:
15144 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15146 zone = ISC_LIST_NEXT(zone, statelink))
15149 case DNS_ZONESTATE_XFERDEFERRED:
15150 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
15152 zone = ISC_LIST_NEXT(zone, statelink))
15155 case DNS_ZONESTATE_SOAQUERY:
15156 for (zone = ISC_LIST_HEAD(zmgr->zones);
15158 zone = ISC_LIST_NEXT(zone, link))
15159 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
15162 case DNS_ZONESTATE_ANY:
15163 for (zone = ISC_LIST_HEAD(zmgr->zones);
15165 zone = ISC_LIST_NEXT(zone, link)) {
15166 dns_view_t *view = zone->view;
15167 if (view != NULL && strcmp(view->name, "_bind") == 0)
15176 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15182 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
15183 isc_boolean_t ok = ISC_TRUE;
15184 isc_boolean_t fail = ISC_FALSE;
15185 char namebuf[DNS_NAME_FORMATSIZE];
15186 char namebuf2[DNS_NAME_FORMATSIZE];
15187 char typebuf[DNS_RDATATYPE_FORMATSIZE];
15188 int level = ISC_LOG_WARNING;
15191 REQUIRE(DNS_ZONE_VALID(zone));
15193 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
15194 return (ISC_R_SUCCESS);
15196 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
15197 level = ISC_LOG_ERROR;
15201 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
15203 dns_name_format(name, namebuf, sizeof(namebuf));
15204 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
15205 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
15206 dns_result_totext(DNS_R_BADOWNERNAME));
15208 return (DNS_R_BADOWNERNAME);
15211 dns_name_init(&bad, NULL);
15212 ok = dns_rdata_checknames(rdata, name, &bad);
15214 dns_name_format(name, namebuf, sizeof(namebuf));
15215 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
15216 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
15217 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
15218 namebuf2, dns_result_totext(DNS_R_BADNAME));
15220 return (DNS_R_BADNAME);
15223 return (ISC_R_SUCCESS);
15227 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
15228 REQUIRE(DNS_ZONE_VALID(zone));
15229 zone->checkmx = checkmx;
15233 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
15234 REQUIRE(DNS_ZONE_VALID(zone));
15235 zone->checksrv = checksrv;
15239 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
15240 REQUIRE(DNS_ZONE_VALID(zone));
15241 zone->checkns = checkns;
15245 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
15246 REQUIRE(DNS_ZONE_VALID(zone));
15249 zone->isself = isself;
15250 zone->isselfarg = arg;
15255 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
15256 REQUIRE(DNS_ZONE_VALID(zone));
15259 zone->notifydelay = delay;
15264 dns_zone_getnotifydelay(dns_zone_t *zone) {
15265 REQUIRE(DNS_ZONE_VALID(zone));
15267 return (zone->notifydelay);
15271 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
15272 isc_uint16_t keyid, isc_boolean_t delete)
15274 isc_result_t result;
15275 REQUIRE(DNS_ZONE_VALID(zone));
15277 dns_zone_log(zone, ISC_LOG_NOTICE,
15278 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
15281 result = zone_signwithkey(zone, algorithm, keyid, delete);
15287 static const char *hex = "0123456789ABCDEF";
15290 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
15291 isc_result_t result;
15292 char salt[255*2+1];
15295 REQUIRE(DNS_ZONE_VALID(zone));
15297 if (nsec3param->salt_length != 0) {
15298 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
15299 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
15300 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
15301 salt[j++] = hex[nsec3param->salt[i] & 0xf];
15306 dns_zone_log(zone, ISC_LOG_NOTICE,
15307 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
15308 nsec3param->hash, nsec3param->iterations,
15311 result = zone_addnsec3chain(zone, nsec3param);
15318 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
15319 REQUIRE(DNS_ZONE_VALID(zone));
15323 zone->nodes = nodes;
15327 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
15328 REQUIRE(DNS_ZONE_VALID(zone));
15331 * We treat signatures as a signed value so explicitly
15332 * limit its range here.
15334 if (signatures > ISC_INT32_MAX)
15335 signatures = ISC_INT32_MAX;
15336 else if (signatures == 0)
15338 zone->signatures = signatures;
15342 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
15343 REQUIRE(DNS_ZONE_VALID(zone));
15344 zone->privatetype = type;
15348 dns_zone_getprivatetype(dns_zone_t *zone) {
15349 REQUIRE(DNS_ZONE_VALID(zone));
15350 return (zone->privatetype);
15353 static isc_result_t
15354 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
15355 isc_boolean_t delete)
15357 dns_signing_t *signing;
15358 dns_signing_t *current;
15359 isc_result_t result = ISC_R_SUCCESS;
15362 signing = isc_mem_get(zone->mctx, sizeof *signing);
15363 if (signing == NULL)
15364 return (ISC_R_NOMEMORY);
15366 signing->magic = 0;
15367 signing->db = NULL;
15368 signing->dbiterator = NULL;
15369 signing->algorithm = algorithm;
15370 signing->keyid = keyid;
15371 signing->delete = delete;
15372 signing->done = ISC_FALSE;
15376 for (current = ISC_LIST_HEAD(zone->signing);
15378 current = ISC_LIST_NEXT(current, link)) {
15379 if (current->db == zone->db &&
15380 current->algorithm == signing->algorithm &&
15381 current->keyid == signing->keyid) {
15382 if (current->delete != signing->delete)
15383 current->done = ISC_TRUE;
15389 if (zone->db != NULL) {
15390 dns_db_attach(zone->db, &signing->db);
15391 result = dns_db_createiterator(signing->db, 0,
15392 &signing->dbiterator);
15394 if (result == ISC_R_SUCCESS)
15395 result = dns_dbiterator_first(signing->dbiterator);
15396 if (result == ISC_R_SUCCESS) {
15397 dns_dbiterator_pause(signing->dbiterator);
15398 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
15400 if (isc_time_isepoch(&zone->signingtime)) {
15401 zone->signingtime = now;
15402 if (zone->task != NULL)
15403 zone_settimer(zone, &now);
15407 result = ISC_R_NOTFOUND;
15410 if (signing != NULL) {
15411 if (signing->db != NULL)
15412 dns_db_detach(&signing->db);
15413 if (signing->dbiterator != NULL)
15414 dns_dbiterator_destroy(&signing->dbiterator);
15415 isc_mem_put(zone->mctx, signing, sizeof *signing);
15421 logmsg(const char *format, ...) {
15423 va_start(args, format);
15424 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
15425 ISC_LOG_DEBUG(1), format, args);
15430 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
15431 dns_dnsseckey_t *key;
15432 while (!ISC_LIST_EMPTY(*list)) {
15433 key = ISC_LIST_HEAD(*list);
15434 ISC_LIST_UNLINK(*list, key, link);
15435 dns_dnsseckey_destroy(mctx, &key);
15439 /* Called once; *timep should be set to the current time. */
15440 static isc_result_t
15441 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
15442 isc_result_t result;
15443 isc_stdtime_t now, then = 0, event;
15448 for (i = 0; i <= DST_MAX_TIMES; i++) {
15449 result = dst_key_gettime(key, i, &event);
15450 if (result == ISC_R_SUCCESS && event > now &&
15451 (then == 0 || event < then))
15457 return (ISC_R_SUCCESS);
15460 return (ISC_R_NOTFOUND);
15463 static isc_result_t
15464 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
15465 const dns_rdata_t *rdata, isc_boolean_t *flag)
15467 dns_rdataset_t rdataset;
15468 dns_dbnode_t *node = NULL;
15469 isc_result_t result;
15471 dns_rdataset_init(&rdataset);
15472 if (rdata->type == dns_rdatatype_nsec3)
15473 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
15475 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
15476 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
15477 (isc_stdtime_t) 0, &rdataset, NULL);
15478 if (result == ISC_R_NOTFOUND) {
15480 result = ISC_R_SUCCESS;
15484 for (result = dns_rdataset_first(&rdataset);
15485 result == ISC_R_SUCCESS;
15486 result = dns_rdataset_next(&rdataset)) {
15487 dns_rdata_t myrdata = DNS_RDATA_INIT;
15488 dns_rdataset_current(&rdataset, &myrdata);
15489 if (!dns_rdata_compare(&myrdata, rdata))
15492 dns_rdataset_disassociate(&rdataset);
15493 if (result == ISC_R_SUCCESS) {
15495 } else if (result == ISC_R_NOMORE) {
15497 result = ISC_R_SUCCESS;
15502 dns_db_detachnode(db, &node);
15507 * Add records to signal the state of signing or of key removal.
15509 static isc_result_t
15510 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
15511 dns_dbversion_t *ver, dns_diff_t *diff,
15512 isc_boolean_t sign_all)
15514 dns_difftuple_t *tuple, *newtuple = NULL;
15515 dns_rdata_dnskey_t dnskey;
15516 dns_rdata_t rdata = DNS_RDATA_INIT;
15517 isc_boolean_t flag;
15519 isc_result_t result = ISC_R_SUCCESS;
15520 isc_uint16_t keyid;
15521 unsigned char buf[5];
15522 dns_name_t *name = dns_db_origin(db);
15524 for (tuple = ISC_LIST_HEAD(diff->tuples);
15526 tuple = ISC_LIST_NEXT(tuple, link)) {
15527 if (tuple->rdata.type != dns_rdatatype_dnskey)
15530 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
15531 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15532 if ((dnskey.flags &
15533 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
15534 != DNS_KEYOWNER_ZONE)
15537 dns_rdata_toregion(&tuple->rdata, &r);
15539 keyid = dst_region_computeid(&r, dnskey.algorithm);
15541 buf[0] = dnskey.algorithm;
15542 buf[1] = (keyid & 0xff00) >> 8;
15543 buf[2] = (keyid & 0xff);
15544 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
15547 rdata.length = sizeof(buf);
15548 rdata.type = privatetype;
15549 rdata.rdclass = tuple->rdata.rdclass;
15551 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
15552 CHECK(rr_exists(db, ver, name, &rdata, &flag));
15555 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
15556 name, 0, &rdata, &newtuple));
15557 CHECK(do_one_tuple(&newtuple, db, ver, diff));
15558 INSIST(newtuple == NULL);
15562 * Remove any record which says this operation has already
15566 CHECK(rr_exists(db, ver, name, &rdata, &flag));
15568 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
15569 name, 0, &rdata, &newtuple));
15570 CHECK(do_one_tuple(&newtuple, db, ver, diff));
15571 INSIST(newtuple == NULL);
15578 static isc_result_t
15579 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
15580 dns_diff_t *diff, zonediff_t *zonediff)
15582 isc_result_t result;
15583 isc_stdtime_t now, inception, soaexpire;
15584 isc_boolean_t check_ksk, keyset_kskonly;
15585 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
15586 unsigned int nkeys = 0, i;
15587 dns_difftuple_t *tuple;
15589 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
15590 zone_keys, &nkeys);
15591 if (result != ISC_R_SUCCESS) {
15592 dns_zone_log(zone, ISC_LOG_ERROR,
15593 "sign_apex:find_zone_keys -> %s",
15594 dns_result_totext(result));
15598 isc_stdtime_get(&now);
15599 inception = now - 3600; /* Allow for clock skew. */
15600 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
15602 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
15603 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
15606 * See if update_sigs will update DNSKEY signature and if not
15607 * cause them to sign so that so that newly activated keys
15610 for (tuple = ISC_LIST_HEAD(diff->tuples);
15612 tuple = ISC_LIST_NEXT(tuple, link)) {
15613 if (tuple->rdata.type == dns_rdatatype_dnskey &&
15614 dns_name_equal(&tuple->name, &zone->origin))
15618 if (tuple == NULL) {
15619 result = del_sigs(zone, db, ver, &zone->origin,
15620 dns_rdatatype_dnskey, zonediff,
15621 zone_keys, nkeys, now, ISC_FALSE);
15622 if (result != ISC_R_SUCCESS) {
15623 dns_zone_log(zone, ISC_LOG_ERROR,
15624 "sign_apex:del_sigs -> %s",
15625 dns_result_totext(result));
15628 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
15629 zonediff->diff, zone_keys, nkeys, zone->mctx,
15630 inception, soaexpire, check_ksk,
15632 if (result != ISC_R_SUCCESS) {
15633 dns_zone_log(zone, ISC_LOG_ERROR,
15634 "sign_apex:add_sigs -> %s",
15635 dns_result_totext(result));
15640 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
15641 inception, soaexpire, now, check_ksk,
15642 keyset_kskonly, zonediff);
15644 if (result != ISC_R_SUCCESS) {
15645 dns_zone_log(zone, ISC_LOG_ERROR,
15646 "sign_apex:update_sigs -> %s",
15647 dns_result_totext(result));
15652 for (i = 0; i < nkeys; i++)
15653 dst_key_free(&zone_keys[i]);
15658 * Prevent the zone entering a inconsistent state where
15659 * NSEC only DNSKEYs are present with NSEC3 chains.
15660 * See update.c:check_dnssec()
15662 static isc_boolean_t
15663 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
15666 isc_result_t result;
15667 dns_difftuple_t *tuple;
15668 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
15669 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
15671 /* Scan the tuples for an NSEC-only DNSKEY */
15672 for (tuple = ISC_LIST_HEAD(diff->tuples);
15674 tuple = ISC_LIST_NEXT(tuple, link)) {
15676 if (tuple->rdata.type != dns_rdatatype_dnskey ||
15677 tuple->op != DNS_DIFFOP_ADD)
15680 alg = tuple->rdata.data[3];
15681 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
15682 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
15683 nseconly = ISC_TRUE;
15688 /* Check existing DB for NSEC-only DNSKEY */
15690 result = dns_nsec_nseconly(db, ver, &nseconly);
15691 if (result == ISC_R_NOTFOUND)
15692 result = ISC_R_SUCCESS;
15696 /* Check existing DB for NSEC3 */
15698 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
15699 privatetype, &nsec3));
15701 /* Refuse to allow NSEC3 with NSEC-only keys */
15702 if (nseconly && nsec3) {
15703 dns_zone_log(zone, ISC_LOG_ERROR,
15704 "NSEC only DNSKEYs and NSEC3 chains not allowed");
15711 return (ISC_FALSE);
15714 static isc_result_t
15715 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
15718 isc_result_t result;
15719 dns_dbnode_t *node = NULL;
15720 dns_rdataset_t rdataset;
15722 dns_rdataset_init(&rdataset);
15723 CHECK(dns_db_getoriginnode(db, &node));
15725 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
15726 dns_rdatatype_none, 0, &rdataset, NULL);
15727 if (dns_rdataset_isassociated(&rdataset))
15728 dns_rdataset_disassociate(&rdataset);
15729 if (result != ISC_R_NOTFOUND)
15732 result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff);
15736 dns_db_detachnode(db, &node);
15741 * Given an RRSIG rdataset and an algorithm, determine whether there
15742 * are any signatures using that algorithm.
15744 static isc_boolean_t
15745 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
15746 dns_rdata_t rdata = DNS_RDATA_INIT;
15747 dns_rdata_rrsig_t rrsig;
15748 isc_result_t result;
15750 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
15751 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
15752 return (ISC_FALSE);
15755 for (result = dns_rdataset_first(rdataset);
15756 result == ISC_R_SUCCESS;
15757 result = dns_rdataset_next(rdataset))
15759 dns_rdataset_current(rdataset, &rdata);
15760 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
15761 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15762 dns_rdata_reset(&rdata);
15763 if (rrsig.algorithm == alg)
15767 return (ISC_FALSE);
15770 static isc_result_t
15771 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
15774 dns_name_t *origin;
15775 isc_boolean_t build_nsec3;
15776 isc_result_t result;
15778 origin = dns_db_origin(db);
15779 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
15782 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
15783 ISC_FALSE, zone->privatetype, diff));
15784 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
15791 zone_rekey(dns_zone_t *zone) {
15792 isc_result_t result;
15793 dns_db_t *db = NULL;
15794 dns_dbnode_t *node = NULL;
15795 dns_dbversion_t *ver = NULL;
15796 dns_rdataset_t soaset, soasigs, keyset, keysigs;
15797 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
15798 dns_dnsseckey_t *key;
15799 dns_diff_t diff, _sig_diff;
15800 zonediff_t zonediff;
15801 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
15802 isc_boolean_t newalg = ISC_FALSE;
15803 isc_boolean_t fullsign;
15804 dns_ttl_t ttl = 3600;
15808 isc_time_t timenow;
15809 isc_interval_t ival;
15812 REQUIRE(DNS_ZONE_VALID(zone));
15814 ISC_LIST_INIT(dnskeys);
15815 ISC_LIST_INIT(keys);
15816 ISC_LIST_INIT(rmkeys);
15817 dns_rdataset_init(&soaset);
15818 dns_rdataset_init(&soasigs);
15819 dns_rdataset_init(&keyset);
15820 dns_rdataset_init(&keysigs);
15821 dir = dns_zone_getkeydirectory(zone);
15823 dns_diff_init(mctx, &diff);
15824 dns_diff_init(mctx, &_sig_diff);
15825 _sig_diff.resign = zone->sigresigninginterval;
15826 zonediff_init(&zonediff, &_sig_diff);
15828 CHECK(dns_zone_getdb(zone, &db));
15829 CHECK(dns_db_newversion(db, &ver));
15830 CHECK(dns_db_getoriginnode(db, &node));
15832 TIME_NOW(&timenow);
15833 now = isc_time_seconds(&timenow);
15835 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
15837 /* Get the SOA record's TTL */
15838 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
15839 dns_rdatatype_none, 0, &soaset, &soasigs));
15841 dns_rdataset_disassociate(&soaset);
15843 /* Get the DNSKEY rdataset */
15844 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
15845 dns_rdatatype_none, 0, &keyset, &keysigs);
15846 if (result == ISC_R_SUCCESS) {
15848 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
15850 &keysigs, &soasigs,
15851 ISC_FALSE, ISC_FALSE,
15853 } else if (result != ISC_R_NOTFOUND)
15857 * True when called from "rndc sign". Indicates the zone should be
15858 * fully signed now.
15860 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
15862 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
15863 if (result == ISC_R_SUCCESS) {
15864 isc_boolean_t check_ksk;
15865 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
15867 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
15868 &zone->origin, ttl, &diff,
15869 ISC_TF(!check_ksk),
15872 /* Keys couldn't be updated for some reason;
15873 * try again later. */
15874 if (result != ISC_R_SUCCESS) {
15875 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
15876 "couldn't update zone keys: %s",
15877 isc_result_totext(result));
15882 * See if any pre-existing keys have newly become active;
15883 * also, see if any new key is for a new algorithm, as in that
15884 * event, we need to sign the zone fully. (If there's a new
15885 * key, but it's for an already-existing algorithm, then
15886 * the zone signing can be handled incrementally.)
15888 for (key = ISC_LIST_HEAD(dnskeys);
15890 key = ISC_LIST_NEXT(key, link)) {
15891 if (!key->first_sign)
15894 newactive = ISC_TRUE;
15896 if (!dns_rdataset_isassociated(&keysigs)) {
15901 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
15903 * This isn't a new algorithm; clear
15904 * first_sign so we won't sign the
15905 * whole zone with this key later
15907 key->first_sign = ISC_FALSE;
15914 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
15915 dnskey_sane(zone, db, ver, &diff)) {
15916 CHECK(dns_diff_apply(&diff, db, ver));
15917 CHECK(clean_nsec3param(zone, db, ver, &diff));
15918 CHECK(add_signing_records(db, zone->privatetype,
15920 ISC_TF(newalg || fullsign)));
15921 CHECK(update_soa_serial(db, ver, &diff, mctx,
15922 zone->updatemethod));
15923 CHECK(add_chains(zone, db, ver, &diff));
15924 CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
15925 CHECK(zone_journal(zone, zonediff.diff, NULL,
15931 dns_db_closeversion(db, &ver, ISC_TRUE);
15934 dns_difftuple_t *tuple;
15937 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
15939 zone_needdump(zone, DNS_DUMP_DELAY);
15941 zone_settimer(zone, &timenow);
15943 /* Remove any signatures from removed keys. */
15944 if (!ISC_LIST_EMPTY(rmkeys)) {
15945 for (key = ISC_LIST_HEAD(rmkeys);
15947 key = ISC_LIST_NEXT(key, link)) {
15948 result = zone_signwithkey(zone,
15949 dst_key_alg(key->key),
15950 dst_key_id(key->key),
15952 if (result != ISC_R_SUCCESS) {
15953 dns_zone_log(zone, ISC_LOG_ERROR,
15954 "zone_signwithkey failed: %s",
15955 dns_result_totext(result));
15962 * "rndc sign" was called, so we now sign the zone
15963 * with all active keys, whether they're new or not.
15965 for (key = ISC_LIST_HEAD(dnskeys);
15967 key = ISC_LIST_NEXT(key, link)) {
15968 if (!key->force_sign && !key->hint_sign)
15971 result = zone_signwithkey(zone,
15972 dst_key_alg(key->key),
15973 dst_key_id(key->key),
15975 if (result != ISC_R_SUCCESS) {
15976 dns_zone_log(zone, ISC_LOG_ERROR,
15977 "zone_signwithkey failed: %s",
15978 dns_result_totext(result));
15981 } else if (newalg) {
15983 * We haven't been told to sign fully, but a new
15984 * algorithm was added to the DNSKEY. We sign
15985 * the full zone, but only with newly active
15988 for (key = ISC_LIST_HEAD(dnskeys);
15990 key = ISC_LIST_NEXT(key, link)) {
15991 if (!key->first_sign)
15994 result = zone_signwithkey(zone,
15995 dst_key_alg(key->key),
15996 dst_key_id(key->key),
15998 if (result != ISC_R_SUCCESS) {
15999 dns_zone_log(zone, ISC_LOG_ERROR,
16000 "zone_signwithkey failed: %s",
16001 dns_result_totext(result));
16007 * Clear fullsign flag, if it was set, so we don't do
16008 * another full signing next time
16010 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
16013 * Cause the zone to add/delete NSEC3 chains for the
16014 * deferred NSEC3PARAM changes.
16016 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
16018 tuple = ISC_LIST_NEXT(tuple, link)) {
16019 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
16020 dns_rdata_t rdata = DNS_RDATA_INIT;
16021 dns_rdata_nsec3param_t nsec3param;
16023 if (tuple->rdata.type != zone->privatetype ||
16024 tuple->op != DNS_DIFFOP_ADD)
16027 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
16030 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
16031 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16032 if (nsec3param.flags == 0)
16035 result = zone_addnsec3chain(zone, &nsec3param);
16036 if (result != ISC_R_SUCCESS) {
16037 dns_zone_log(zone, ISC_LOG_ERROR,
16038 "zone_addnsec3chain failed: %s",
16039 dns_result_totext(result));
16044 * Activate any NSEC3 chain updates that may have
16045 * been scheduled before this rekey.
16047 if (fullsign || newalg)
16048 resume_addnsec3chain(zone);
16051 * Schedule the next resigning event
16053 set_resigntime(zone);
16057 isc_time_settoepoch(&zone->refreshkeytime);
16060 * If we're doing key maintenance, set the key refresh timer to
16061 * the next scheduled key event or to 'dnssec-loadkeys-interval'
16062 * seconds in the future, whichever is sooner.
16064 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
16065 isc_time_t timethen;
16066 isc_stdtime_t then;
16069 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
16071 zone->refreshkeytime = timethen;
16074 for (key = ISC_LIST_HEAD(dnskeys);
16076 key = ISC_LIST_NEXT(key, link)) {
16078 result = next_keyevent(key->key, &then);
16079 if (result != ISC_R_SUCCESS)
16082 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
16084 if (isc_time_compare(&timethen,
16085 &zone->refreshkeytime) < 0) {
16086 zone->refreshkeytime = timethen;
16091 zone_settimer(zone, &timenow);
16093 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
16094 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
16098 dns_diff_clear(&diff);
16099 dns_diff_clear(&_sig_diff);
16101 clear_keylist(&dnskeys, mctx);
16102 clear_keylist(&keys, mctx);
16103 clear_keylist(&rmkeys, mctx);
16106 dns_db_closeversion(db, &ver, ISC_FALSE);
16107 if (dns_rdataset_isassociated(&keyset))
16108 dns_rdataset_disassociate(&keyset);
16109 if (dns_rdataset_isassociated(&keysigs))
16110 dns_rdataset_disassociate(&keysigs);
16111 if (dns_rdataset_isassociated(&soasigs))
16112 dns_rdataset_disassociate(&soasigs);
16114 dns_db_detachnode(db, &node);
16116 dns_db_detach(&db);
16121 * Something went wrong; try again in ten minutes or
16122 * after a key refresh interval, whichever is shorter.
16124 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
16125 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
16130 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
16133 if (zone->type == dns_zone_master && zone->task != NULL) {
16137 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
16140 zone->refreshkeytime = now;
16141 zone_settimer(zone, &now);
16148 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
16149 unsigned int *errors)
16151 isc_result_t result;
16152 dns_dbnode_t *node = NULL;
16154 REQUIRE(DNS_ZONE_VALID(zone));
16155 REQUIRE(errors != NULL);
16157 result = dns_db_getoriginnode(db, &node);
16158 if (result != ISC_R_SUCCESS)
16160 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
16162 dns_db_detachnode(db, &node);
16167 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
16168 REQUIRE(DNS_ZONE_VALID(zone));
16170 zone->added = added;
16175 dns_zone_getadded(dns_zone_t *zone) {
16176 REQUIRE(DNS_ZONE_VALID(zone));
16177 return (zone->added);
16181 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
16183 isc_time_t loadtime;
16184 isc_result_t result;
16186 TIME_NOW(&loadtime);
16189 * Lock hierarchy: zmgr, zone, raw.
16192 if (inline_secure(zone))
16193 LOCK_ZONE(zone->raw);
16194 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
16195 if (inline_secure(zone))
16196 UNLOCK_ZONE(zone->raw);
16202 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) {
16203 REQUIRE(DNS_ZONE_VALID(zone));
16205 return (ISC_R_RANGE);
16206 /* Maximum value: 24 hours (3600 minutes) */
16207 if (interval > (24 * 60))
16208 interval = (24 * 60);
16209 /* Multiply by 60 for seconds */
16210 zone->refreshkeyinterval = interval * 60;
16211 return (ISC_R_SUCCESS);
16215 dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) {
16216 REQUIRE(DNS_ZONE_VALID(zone));
16217 zone->requestixfr = flag;
16221 dns_zone_getrequestixfr(dns_zone_t *zone) {
16222 REQUIRE(DNS_ZONE_VALID(zone));
16223 return (zone->requestixfr);
16227 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
16228 REQUIRE(DNS_ZONE_VALID(zone));
16229 zone->updatemethod = method;
16233 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
16234 REQUIRE(DNS_ZONE_VALID(zone));
16235 return(zone->updatemethod);
16239 * Lock hierarchy: zmgr, zone, raw.
16242 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
16243 isc_result_t result;
16244 dns_zonemgr_t *zmgr;
16246 REQUIRE(DNS_ZONE_VALID(zone));
16247 REQUIRE(zone->zmgr != NULL);
16248 REQUIRE(zone->task != NULL);
16249 REQUIRE(zone->loadtask != NULL);
16250 REQUIRE(zone->raw == NULL);
16252 REQUIRE(DNS_ZONE_VALID(raw));
16253 REQUIRE(raw->zmgr == NULL);
16254 REQUIRE(raw->task == NULL);
16255 REQUIRE(raw->loadtask == NULL);
16256 REQUIRE(raw->secure == NULL);
16259 * Lock hierarchy: zmgr, zone, raw.
16262 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16266 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
16267 NULL, NULL, zone->task, zone_timer, raw,
16269 if (result != ISC_R_SUCCESS)
16273 * The timer "holds" a iref.
16276 INSIST(raw->irefs != 0);
16279 /* dns_zone_attach(raw, &zone->raw); */
16280 isc_refcount_increment(&raw->erefs, NULL);
16283 /* dns_zone_iattach(zone, &raw->secure); */
16284 zone_iattach(zone, &raw->secure);
16286 isc_task_attach(zone->task, &raw->task);
16287 isc_task_attach(zone->loadtask, &raw->loadtask);
16289 ISC_LIST_APPEND(zmgr->zones, raw, link);
16296 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16301 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
16302 REQUIRE(DNS_ZONE_VALID(zone));
16303 REQUIRE(raw != NULL && *raw == NULL);
16306 if (zone->raw != NULL)
16307 dns_zone_attach(zone->raw, raw);
16308 UNLOCK(&zone->lock);
16314 unsigned char data[5];
16317 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
16320 keydone(isc_task_t *task, isc_event_t *event) {
16321 const char *me = "keydone";
16322 isc_boolean_t commit = ISC_FALSE;
16323 isc_result_t result;
16324 dns_rdata_t rdata = DNS_RDATA_INIT;
16325 dns_dbversion_t *oldver = NULL, *newver = NULL;
16327 dns_db_t *db = NULL;
16328 dns_dbnode_t *node = NULL;
16329 dns_rdataset_t rdataset;
16331 struct keydone *keydone = (struct keydone *)event;
16332 dns_update_log_t log = { update_log_cb, NULL };
16333 isc_boolean_t clear_pending = ISC_FALSE;
16337 zone = event->ev_arg;
16338 INSIST(DNS_ZONE_VALID(zone));
16342 dns_rdataset_init(&rdataset);
16343 dns_diff_init(zone->mctx, &diff);
16345 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
16346 if (zone->db != NULL) {
16347 dns_db_attach(zone->db, &db);
16348 dns_db_currentversion(db, &oldver);
16349 result = dns_db_newversion(db, &newver);
16350 if (result != ISC_R_SUCCESS) {
16351 dns_zone_log(zone, ISC_LOG_ERROR,
16352 "keydone:dns_db_newversion -> %s",
16353 dns_result_totext(result));
16357 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
16361 result = dns_db_getoriginnode(db, &node);
16362 if (result != ISC_R_SUCCESS)
16365 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
16366 dns_rdatatype_none, 0, &rdataset, NULL);
16367 if (result == ISC_R_NOTFOUND) {
16368 INSIST(!dns_rdataset_isassociated(&rdataset));
16371 if (result != ISC_R_SUCCESS) {
16372 INSIST(!dns_rdataset_isassociated(&rdataset));
16376 for (result = dns_rdataset_first(&rdataset);
16377 result == ISC_R_SUCCESS;
16378 result = dns_rdataset_next(&rdataset)) {
16379 isc_boolean_t found = ISC_FALSE;
16381 dns_rdataset_current(&rdataset, &rdata);
16383 if (keydone->all) {
16384 if (rdata.length == 5 && rdata.data[0] != 0 &&
16385 rdata.data[3] == 0 && rdata.data[4] == 1)
16387 else if (rdata.data[0] == 0 &&
16388 (rdata.data[2] & PENDINGFLAGS) != 0) {
16390 clear_pending = ISC_TRUE;
16392 } else if (rdata.length == 5 &&
16393 memcmp(rdata.data, keydone->data, 5) == 0)
16397 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
16398 &zone->origin, rdataset.ttl,
16400 dns_rdata_reset(&rdata);
16403 if (!ISC_LIST_EMPTY(diff.tuples)) {
16404 /* Write changes to journal file. */
16405 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
16406 zone->updatemethod));
16408 result = dns_update_signatures(&log, zone, db,
16409 oldver, newver, &diff,
16410 zone->sigvalidityinterval);
16411 if (!clear_pending)
16414 CHECK(zone_journal(zone, &diff, NULL, "keydone"));
16418 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
16419 zone_needdump(zone, 30);
16424 if (dns_rdataset_isassociated(&rdataset))
16425 dns_rdataset_disassociate(&rdataset);
16428 dns_db_detachnode(db, &node);
16429 if (oldver != NULL)
16430 dns_db_closeversion(db, &oldver, ISC_FALSE);
16431 if (newver != NULL)
16432 dns_db_closeversion(db, &newver, commit);
16433 dns_db_detach(&db);
16435 dns_diff_clear(&diff);
16436 isc_event_free(&event);
16437 dns_zone_idetach(&zone);
16441 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
16442 isc_result_t result = ISC_R_SUCCESS;
16445 dns_zone_t *dummy = NULL;
16446 struct keydone *kd;
16448 REQUIRE(DNS_ZONE_VALID(zone));
16452 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
16453 zone, sizeof(struct keydone));
16455 result = ISC_R_NOMEMORY;
16459 kd = (struct keydone *) e;
16460 if (strcasecmp(keystr, "all") == 0)
16461 kd->all = ISC_TRUE;
16463 isc_textregion_t r;
16465 dns_keytag_t keyid;
16469 kd->all = ISC_FALSE;
16471 n = sscanf(keystr, "%hd/", &keyid);
16473 CHECK(ISC_R_FAILURE);
16475 algstr = strchr(keystr, '/');
16476 if (algstr != NULL)
16479 CHECK(ISC_R_FAILURE);
16481 n = sscanf(algstr, "%hhd", &alg);
16483 DE_CONST(algstr, r.base);
16484 r.length = strlen(algstr);
16485 CHECK(dns_secalg_fromtext(&alg, &r));
16488 /* construct a private-type rdata */
16489 isc_buffer_init(&b, kd->data, sizeof(kd->data));
16490 isc_buffer_putuint8(&b, alg);
16491 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
16492 isc_buffer_putuint8(&b, (keyid & 0xff));
16493 isc_buffer_putuint8(&b, 0);
16494 isc_buffer_putuint8(&b, 1);
16497 zone_iattach(zone, &dummy);
16498 isc_task_send(zone->task, &e);
16502 isc_event_free(&e);
16507 struct nsec3param {
16509 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
16510 unsigned int length;
16511 isc_boolean_t nsec;
16512 isc_boolean_t replace;
16516 setnsec3param(isc_task_t *task, isc_event_t *event) {
16517 const char *me = "setnsec3param";
16518 isc_boolean_t commit = ISC_FALSE;
16519 isc_result_t result;
16520 dns_dbversion_t *oldver = NULL, *newver = NULL;
16522 dns_db_t *db = NULL;
16523 dns_dbnode_t *node = NULL;
16524 dns_rdataset_t prdataset, nrdataset;
16526 struct nsec3param *np = (struct nsec3param *)event;
16527 dns_update_log_t log = { update_log_cb, NULL };
16529 isc_boolean_t nseconly;
16530 isc_boolean_t exists = ISC_FALSE;
16534 zone = event->ev_arg;
16535 INSIST(DNS_ZONE_VALID(zone));
16539 dns_rdataset_init(&prdataset);
16540 dns_rdataset_init(&nrdataset);
16541 dns_diff_init(zone->mctx, &diff);
16543 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
16544 if (zone->db != NULL) {
16545 dns_db_attach(zone->db, &db);
16546 dns_db_currentversion(db, &oldver);
16547 result = dns_db_newversion(db, &newver);
16548 if (result != ISC_R_SUCCESS) {
16549 dns_zone_log(zone, ISC_LOG_ERROR,
16550 "setnsec3param:dns_db_newversion -> %s",
16551 dns_result_totext(result));
16555 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
16559 CHECK(dns_db_getoriginnode(db, &node));
16562 * Does a private-type record already exist for this chain?
16564 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
16565 dns_rdatatype_none, 0, &prdataset, NULL);
16566 if (result == ISC_R_SUCCESS) {
16567 for (result = dns_rdataset_first(&prdataset);
16568 result == ISC_R_SUCCESS;
16569 result = dns_rdataset_next(&prdataset)) {
16570 dns_rdata_init(&rdata);
16571 dns_rdataset_current(&prdataset, &rdata);
16573 if (np->length == rdata.length &&
16574 memcmp(rdata.data, np->data, np->length) == 0) {
16579 } else if (result != ISC_R_NOTFOUND) {
16580 INSIST(!dns_rdataset_isassociated(&prdataset));
16585 * Does the chain already exist?
16587 result = dns_db_findrdataset(db, node, newver,
16588 dns_rdatatype_nsec3param,
16589 dns_rdatatype_none, 0, &nrdataset, NULL);
16590 if (result == ISC_R_SUCCESS) {
16591 for (result = dns_rdataset_first(&nrdataset);
16592 result == ISC_R_SUCCESS;
16593 result = dns_rdataset_next(&nrdataset)) {
16594 dns_rdata_init(&rdata);
16595 dns_rdataset_current(&nrdataset, &rdata);
16597 if (np->length == (rdata.length + 1) &&
16598 memcmp(rdata.data, np->data + 1,
16599 np->length - 1) == 0)
16605 } else if (result != ISC_R_NOTFOUND) {
16606 INSIST(!dns_rdataset_isassociated(&nrdataset));
16612 * We need to remove any existing NSEC3 chains.
16614 if (!exists && np->replace && (np->length != 0 || np->nsec))
16615 CHECK(dns_nsec3param_deletechains(db, newver, zone,
16616 !np->nsec, &diff));
16618 if (!exists && np->length != 0) {
16620 * We're creating an NSEC3 chain.
16622 * If the zone is not currently capable of supporting
16623 * an NSEC3 chain, add the INITIAL flag, so these
16624 * parameters can be used later when NSEC3 becomes
16627 dns_rdata_init(&rdata);
16629 np->data[2] |= DNS_NSEC3FLAG_CREATE;
16630 result = dns_nsec_nseconly(db, newver, &nseconly);
16631 if (result == ISC_R_NOTFOUND || nseconly)
16632 np->data[2] |= DNS_NSEC3FLAG_INITIAL;
16634 rdata.length = np->length;
16635 rdata.data = np->data;
16636 rdata.type = zone->privatetype;
16637 rdata.rdclass = zone->rdclass;
16638 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
16639 &zone->origin, 0, &rdata));
16642 if (!ISC_LIST_EMPTY(diff.tuples)) {
16643 /* Write changes to journal file. */
16644 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
16645 zone->updatemethod));
16646 result = dns_update_signatures(&log, zone, db,
16647 oldver, newver, &diff,
16648 zone->sigvalidityinterval);
16649 if (result != ISC_R_NOTFOUND)
16651 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
16655 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
16656 zone_needdump(zone, 30);
16661 if (dns_rdataset_isassociated(&prdataset))
16662 dns_rdataset_disassociate(&prdataset);
16663 if (dns_rdataset_isassociated(&nrdataset))
16664 dns_rdataset_disassociate(&nrdataset);
16666 dns_db_detachnode(db, &node);
16667 if (oldver != NULL)
16668 dns_db_closeversion(db, &oldver, ISC_FALSE);
16669 if (newver != NULL)
16670 dns_db_closeversion(db, &newver, commit);
16672 dns_db_detach(&db);
16674 resume_addnsec3chain(zone);
16675 dns_diff_clear(&diff);
16676 isc_event_free(&event);
16677 dns_zone_idetach(&zone);
16681 dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
16682 isc_uint16_t iter, isc_uint8_t saltlen,
16683 unsigned char *salt, isc_boolean_t replace)
16685 isc_result_t result = ISC_R_SUCCESS;
16686 dns_rdata_nsec3param_t param;
16687 dns_rdata_t nrdata = DNS_RDATA_INIT;
16688 dns_rdata_t prdata = DNS_RDATA_INIT;
16689 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
16690 struct nsec3param *np;
16691 dns_zone_t *dummy = NULL;
16695 REQUIRE(DNS_ZONE_VALID(zone));
16696 REQUIRE(salt != NULL);
16700 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
16701 setnsec3param, zone, sizeof(struct nsec3param));
16703 result = ISC_R_NOMEMORY;
16707 np = (struct nsec3param *) e;
16708 np->replace = replace;
16711 np->nsec = ISC_TRUE;
16713 param.common.rdclass = zone->rdclass;
16714 param.common.rdtype = dns_rdatatype_nsec3param;
16715 ISC_LINK_INIT(¶m.common, link);
16718 param.flags = flags;
16719 param.iterations = iter;
16720 param.salt_length = saltlen;
16722 isc_buffer_init(&b, nbuf, sizeof(nbuf));
16723 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
16724 dns_rdatatype_nsec3param,
16726 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
16727 np->data, sizeof(np->data));
16728 np->length = prdata.length;
16731 zone_iattach(zone, &dummy);
16732 isc_task_send(zone->task, &e);
16736 isc_event_free(&e);
16742 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
16743 REQUIRE(DNS_ZONE_VALID(zone));
16745 zone->statlevel = level;
16748 dns_zonestat_level_t
16749 dns_zone_getstatlevel(dns_zone_t *zone) {
16750 REQUIRE(DNS_ZONE_VALID(zone));
16752 return (zone->statlevel);