2 * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
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/thread.h>
41 #include <isc/timer.h>
44 #include <dns/acache.h>
47 #include <dns/callbacks.h>
49 #include <dns/dbiterator.h>
50 #include <dns/dnssec.h>
51 #include <dns/events.h>
52 #include <dns/journal.h>
53 #include <dns/keydata.h>
54 #include <dns/keytable.h>
55 #include <dns/keyvalues.h>
57 #include <dns/master.h>
58 #include <dns/masterdump.h>
59 #include <dns/message.h>
62 #include <dns/nsec3.h>
64 #include <dns/private.h>
66 #include <dns/rcode.h>
67 #include <dns/rdata.h>
68 #include <dns/rdataclass.h>
69 #include <dns/rdatalist.h>
70 #include <dns/rdataset.h>
71 #include <dns/rdatasetiter.h>
72 #include <dns/rdatastruct.h>
73 #include <dns/rdatatype.h>
74 #include <dns/request.h>
75 #include <dns/resolver.h>
76 #include <dns/result.h>
77 #include <dns/rriterator.h>
80 #include <dns/stats.h>
83 #include <dns/update.h>
84 #include <dns/xfrin.h>
90 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
91 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
93 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
94 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
96 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
97 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
99 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
100 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
102 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
103 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
105 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
106 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
108 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
109 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
112 * Ensure 'a' is at least 'min' but not more than 'max'.
114 #define RANGE(a, min, max) \
115 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
117 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
122 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
123 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
124 #define ALG(x) dst_key_alg(x)
129 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
130 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
131 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
132 #define RESIGN_DELAY 3600 /*%< 1 hour */
134 #ifndef DNS_MAX_EXPIRE
135 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
138 #ifndef DNS_DUMP_DELAY
139 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
142 typedef struct dns_notify dns_notify_t;
143 typedef struct dns_stub dns_stub_t;
144 typedef struct dns_load dns_load_t;
145 typedef struct dns_forward dns_forward_t;
146 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
147 typedef struct dns_io dns_io_t;
148 typedef ISC_LIST(dns_io_t) dns_iolist_t;
149 typedef struct dns_signing dns_signing_t;
150 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
151 typedef struct dns_nsec3chain dns_nsec3chain_t;
152 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
153 typedef struct dns_keyfetch dns_keyfetch_t;
154 typedef struct dns_asyncload dns_asyncload_t;
156 #define DNS_ZONE_CHECKLOCK
157 #ifdef DNS_ZONE_CHECKLOCK
158 #define LOCK_ZONE(z) \
159 do { LOCK(&(z)->lock); \
160 INSIST((z)->locked == ISC_FALSE); \
161 (z)->locked = ISC_TRUE; \
163 #define UNLOCK_ZONE(z) \
164 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
165 #define LOCKED_ZONE(z) ((z)->locked)
166 #define TRYLOCK_ZONE(result, z) \
168 result = isc_mutex_trylock(&(z)->lock); \
169 if (result == ISC_R_SUCCESS) { \
170 INSIST((z)->locked == ISC_FALSE); \
171 (z)->locked = ISC_TRUE; \
175 #define LOCK_ZONE(z) LOCK(&(z)->lock)
176 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
177 #define LOCKED_ZONE(z) ISC_TRUE
178 #define TRYLOCK_ZONE(result, z) \
179 do { result = isc_mutex_trylock(&(z)->lock); } while (0)
182 #ifdef ISC_RWLOCK_USEATOMIC
183 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
184 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
185 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
186 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
188 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
189 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
190 #define ZONEDB_LOCK(l, t) LOCK(l)
191 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
198 #ifdef DNS_ZONE_CHECKLOCK
199 isc_boolean_t locked;
202 isc_refcount_t erefs;
204 #ifdef ISC_RWLOCK_USEATOMIC
209 dns_db_t *db; /* Locked by dblock */
213 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
218 dns_masterformat_t masterformat;
220 isc_int32_t journalsize;
221 dns_rdataclass_t rdclass;
224 unsigned int options;
225 unsigned int db_argc;
227 isc_time_t expiretime;
228 isc_time_t refreshtime;
231 isc_time_t notifytime;
232 isc_time_t resigntime;
233 isc_time_t keywarntime;
234 isc_time_t signingtime;
235 isc_time_t nsec3chaintime;
236 isc_time_t refreshkeytime;
237 isc_uint32_t refreshkeyinterval;
238 isc_uint32_t refreshkeycount;
239 isc_uint32_t refresh;
242 isc_uint32_t minimum;
243 isc_stdtime_t key_expiry;
244 isc_stdtime_t log_key_expired_timer;
247 isc_uint32_t maxrefresh;
248 isc_uint32_t minrefresh;
249 isc_uint32_t maxretry;
250 isc_uint32_t minretry;
252 isc_sockaddr_t *masters;
253 dns_name_t **masterkeynames;
254 isc_boolean_t *mastersok;
255 unsigned int masterscnt;
256 unsigned int curmaster;
257 isc_sockaddr_t masteraddr;
258 dns_notifytype_t notifytype;
259 isc_sockaddr_t *notify;
260 dns_name_t **notifykeynames;
261 unsigned int notifycnt;
262 isc_sockaddr_t notifyfrom;
264 isc_task_t *loadtask;
265 isc_sockaddr_t notifysrc4;
266 isc_sockaddr_t notifysrc6;
267 isc_sockaddr_t xfrsource4;
268 isc_sockaddr_t xfrsource6;
269 isc_sockaddr_t altxfrsource4;
270 isc_sockaddr_t altxfrsource6;
271 isc_sockaddr_t sourceaddr;
272 dns_xfrin_ctx_t *xfr; /* task locked */
273 dns_tsigkey_t *tsigkey; /* key used for xfr */
274 /* Access Control Lists */
275 dns_acl_t *update_acl;
276 dns_acl_t *forward_acl;
277 dns_acl_t *notify_acl;
278 dns_acl_t *query_acl;
279 dns_acl_t *queryon_acl;
281 isc_boolean_t update_disabled;
282 isc_boolean_t zero_no_soa_ttl;
283 dns_severity_t check_names;
284 ISC_LIST(dns_notify_t) notifies;
285 dns_request_t *request;
290 isc_uint32_t maxxfrin;
291 isc_uint32_t maxxfrout;
293 isc_uint32_t idleout;
294 isc_event_t ctlevent;
295 dns_ssutable_t *ssutable;
296 isc_uint32_t sigvalidityinterval;
297 isc_uint32_t sigresigninginterval;
299 dns_acache_t *acache;
300 dns_checkmxfunc_t checkmx;
301 dns_checksrvfunc_t checksrv;
302 dns_checknsfunc_t checkns;
304 * Zones in certain states such as "waiting for zone transfer"
305 * or "zone transfer in progress" are kept on per-state linked lists
306 * in the zone manager using the 'statelink' field. The 'statelist'
307 * field points at the list the zone is currently on. It the zone
308 * is not on any such list, statelist is NULL.
310 ISC_LINK(dns_zone_t) statelink;
311 dns_zonelist_t *statelist;
313 * Statistics counters about zone management.
317 * Optional per-zone statistics counters. Counted outside of this
320 dns_zonestat_level_t statlevel;
321 isc_boolean_t requeststats_on;
322 isc_stats_t *requeststats;
323 dns_stats_t *rcvquerystats;
324 isc_uint32_t notifydelay;
325 dns_isselffunc_t isself;
334 * Serial number for deferred journal compaction.
336 isc_uint32_t compact_serial;
338 * Keys that are signing the zone for the first time.
340 dns_signinglist_t signing;
341 dns_nsec3chainlist_t nsec3chain;
343 * Signing / re-signing quantum stopping parameters.
345 isc_uint32_t signatures;
347 dns_rdatatype_t privatetype;
350 * Autosigning/key-maintenance options
352 isc_uint32_t keyopts;
355 * True if added by "rndc addzone"
360 * whether this is a response policy zone
362 isc_boolean_t is_rpz;
365 * Serial number update method.
367 dns_updatemethod_t updatemethod;
370 * whether ixfr is requested
372 isc_boolean_t requestixfr;
375 * Outstanding forwarded UPDATE requests.
377 dns_forwardlist_t forwards;
382 isc_boolean_t sourceserialset;
383 isc_uint32_t sourceserial;
388 isc_boolean_t offline;
391 #define zonediff_init(z, d) \
393 zonediff_t *_z = (z); \
395 (_z)->offline = ISC_FALSE; \
398 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
399 #define DNS_ZONE_SETFLAG(z,f) do { \
400 INSIST(LOCKED_ZONE(z)); \
403 #define DNS_ZONE_CLRFLAG(z,f) do { \
404 INSIST(LOCKED_ZONE(z)); \
405 (z)->flags &= ~(f); \
407 /* XXX MPA these may need to go back into zone.h */
408 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
409 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
410 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
411 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
412 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
413 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
414 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
415 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
416 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
417 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
419 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
421 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
423 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
424 * zone with no masters
426 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
427 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
428 * from SOA (if not set, we
430 * default timer values) */
431 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
432 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
433 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
434 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
435 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
436 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
437 #define DNS_ZONEFLG_FLUSH 0x00200000U
438 #define DNS_ZONEFLG_NOEDNS 0x00400000U
439 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
440 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
441 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
442 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
443 #define DNS_ZONEFLG_THAW 0x08000000U
444 #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
445 #define DNS_ZONEFLG_NODELAY 0x20000000U
446 #define DNS_ZONEFLG_SENDSECURE 0x40000000U
448 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
449 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
451 /* Flags for zone_load() */
452 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
453 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
456 #define UNREACH_CHACHE_SIZE 10U
457 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
460 do { result = (op); \
461 if (result != ISC_R_SUCCESS) goto failure; \
464 struct dns_unreachable {
465 isc_sockaddr_t remote;
466 isc_sockaddr_t local;
475 int refs; /* Locked by rwlock */
476 isc_taskmgr_t * taskmgr;
477 isc_timermgr_t * timermgr;
478 isc_socketmgr_t * socketmgr;
479 isc_taskpool_t * zonetasks;
480 isc_taskpool_t * loadtasks;
482 isc_pool_t * mctxpool;
483 isc_ratelimiter_t * notifyrl;
484 isc_ratelimiter_t * refreshrl;
489 /* Locked by rwlock. */
490 dns_zonelist_t zones;
491 dns_zonelist_t waiting_for_xfrin;
492 dns_zonelist_t xfrin_in_progress;
494 /* Configuration data. */
495 isc_uint32_t transfersin;
496 isc_uint32_t transfersperns;
497 unsigned int serialqueryrate;
499 /* Locked by iolock */
500 isc_uint32_t iolimit;
501 isc_uint32_t ioactive;
505 /* Locked by urlock. */
507 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
519 dns_request_t *request;
523 ISC_LINK(dns_notify_t) link;
526 #define DNS_NOTIFY_NOSOA 0x0001U
529 * dns_stub holds state while performing a 'stub' transfer.
530 * 'db' is the zone's 'db' or a new one if this is the initial
539 dns_dbversion_t *version;
551 dns_rdatacallbacks_t callbacks;
555 * Hold forward state.
561 isc_buffer_t *msgbuf;
562 dns_request_t *request;
565 dns_updatecallback_t callback;
567 ISC_LINK(dns_forward_t) link;
571 * Hold IO request state.
578 ISC_LINK(dns_io_t) link;
583 * Hold state for when we are signing a zone with a new
584 * DNSKEY as result of an update.
589 dns_dbiterator_t *dbiterator;
590 dns_secalg_t algorithm;
592 isc_boolean_t delete;
594 ISC_LINK(dns_signing_t) link;
597 struct dns_nsec3chain {
600 dns_dbiterator_t *dbiterator;
601 dns_rdata_nsec3param_t nsec3param;
602 unsigned char salt[255];
604 isc_boolean_t seen_nsec;
605 isc_boolean_t delete_nsec;
606 isc_boolean_t save_delete_nsec;
607 ISC_LINK(dns_nsec3chain_t) link;
610 * 'dbiterator' contains a iterator for the database. If we are creating
611 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
612 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
615 * 'nsec3param' contains the parameters of the NSEC3 chain being created
618 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
620 * 'seen_nsec' will be set to true if, while iterating the zone to create a
621 * NSEC3 chain, a NSEC record is seen.
623 * 'delete_nsec' will be set to true if, at the completion of the creation
624 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
625 * are in the process of deleting the NSEC chain.
627 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
628 * so it can be recovered in the event of a error.
631 struct dns_keyfetch {
632 dns_fixedname_t name;
633 dns_rdataset_t keydataset;
634 dns_rdataset_t dnskeyset;
635 dns_rdataset_t dnskeysigset;
642 * Hold state for an asynchronous load
644 struct dns_asyncload {
646 dns_zt_zoneloaded_t loaded;
651 #define DAY (24*HOUR)
652 #define MONTH (30*DAY)
654 #define SEND_BUFFER_SIZE 2048
656 static void zone_settimer(dns_zone_t *, isc_time_t *);
657 static void cancel_refresh(dns_zone_t *);
658 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
659 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
660 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
661 ISC_FORMAT_PRINTF(3, 4);
662 static void queue_xfrin(dns_zone_t *zone);
663 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
664 dns_diff_t *diff, dns_diffop_t op,
665 dns_name_t *name, dns_ttl_t ttl,
667 static void zone_unload(dns_zone_t *zone);
668 static void zone_expire(dns_zone_t *zone);
669 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
670 static void zone_idetach(dns_zone_t **zonep);
671 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
673 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
674 static inline void zone_detachdb(dns_zone_t *zone);
675 static isc_result_t default_journal(dns_zone_t *zone);
676 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
677 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
678 isc_time_t loadtime, isc_result_t result);
679 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
680 static void zone_shutdown(isc_task_t *, isc_event_t *);
681 static void zone_loaddone(void *arg, isc_result_t result);
682 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
683 isc_time_t loadtime);
684 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
685 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
686 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
687 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
688 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
689 isc_uint32_t serial);
692 /* ondestroy example */
693 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
696 static void refresh_callback(isc_task_t *, isc_event_t *);
697 static void stub_callback(isc_task_t *, isc_event_t *);
698 static void queue_soa_query(dns_zone_t *zone);
699 static void soa_query(isc_task_t *, isc_event_t *);
700 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
702 static int message_count(dns_message_t *msg, dns_section_t section,
703 dns_rdatatype_t type);
704 static void notify_cancel(dns_zone_t *zone);
705 static void notify_find_address(dns_notify_t *notify);
706 static void notify_send(dns_notify_t *notify);
707 static isc_result_t notify_createmessage(dns_zone_t *zone,
709 dns_message_t **messagep);
710 static void notify_done(isc_task_t *task, isc_event_t *event);
711 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
712 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
713 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
714 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
716 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
717 static void zonemgr_free(dns_zonemgr_t *zmgr);
718 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
719 isc_task_t *task, isc_taskaction_t action,
720 void *arg, dns_io_t **iop);
721 static void zonemgr_putio(dns_io_t **iop);
722 static void zonemgr_cancelio(dns_io_t *io);
725 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
726 unsigned int *soacount, isc_uint32_t *serial,
727 isc_uint32_t *refresh, isc_uint32_t *retry,
728 isc_uint32_t *expire, isc_uint32_t *minimum,
729 unsigned int *errors);
731 static void zone_freedbargs(dns_zone_t *zone);
732 static void forward_callback(isc_task_t *task, isc_event_t *event);
733 static void zone_saveunique(dns_zone_t *zone, const char *path,
734 const char *templat);
735 static void zone_maintenance(dns_zone_t *zone);
736 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
737 static void dump_done(void *arg, isc_result_t result);
738 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
739 isc_uint16_t keyid, isc_boolean_t delete);
740 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
741 dns_dbnode_t *node, dns_name_t *name,
743 static void zone_rekey(dns_zone_t *zone);
744 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
746 #define ENTER zone_debuglog(zone, me, 1, "enter")
748 static const unsigned int dbargc_default = 1;
749 static const char *dbargv_default[] = { "rbt" };
751 #define DNS_ZONE_JITTER_ADD(a, b, c) \
755 _j = isc_random_jitter((b), (b)/4); \
756 isc_interval_set(&_i, _j, 0); \
757 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
758 dns_zone_log(zone, ISC_LOG_WARNING, \
759 "epoch approaching: upgrade required: " \
760 "now + %s failed", #b); \
761 isc_interval_set(&_i, _j/2, 0); \
762 (void)isc_time_add((a), &_i, (c)); \
766 #define DNS_ZONE_TIME_ADD(a, b, c) \
769 isc_interval_set(&_i, (b), 0); \
770 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
771 dns_zone_log(zone, ISC_LOG_WARNING, \
772 "epoch approaching: upgrade required: " \
773 "now + %s failed", #b); \
774 isc_interval_set(&_i, (b)/2, 0); \
775 (void)isc_time_add((a), &_i, (c)); \
779 typedef struct nsec3param nsec3param_t;
781 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
784 isc_boolean_t replace;
785 ISC_LINK(nsec3param_t) link;
787 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
794 * Increment resolver-related statistics counters. Zone must be locked.
797 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
798 if (zone->stats != NULL)
799 isc_stats_increment(zone->stats, counter);
803 *** Public functions.
807 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
812 REQUIRE(zonep != NULL && *zonep == NULL);
813 REQUIRE(mctx != NULL);
816 zone = isc_mem_get(mctx, sizeof(*zone));
818 return (ISC_R_NOMEMORY);
821 isc_mem_attach(mctx, &zone->mctx);
823 result = isc_mutex_init(&zone->lock);
824 if (result != ISC_R_SUCCESS)
827 result = ZONEDB_INITLOCK(&zone->dblock);
828 if (result != ISC_R_SUCCESS)
831 /* XXX MPA check that all elements are initialised */
832 #ifdef DNS_ZONE_CHECKLOCK
833 zone->locked = ISC_FALSE;
837 ISC_LINK_INIT(zone, link);
838 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
839 if (result != ISC_R_SUCCESS)
842 dns_name_init(&zone->origin, NULL);
843 zone->strnamerd = NULL;
844 zone->strname = NULL;
845 zone->strrdclass = NULL;
846 zone->strviewname = NULL;
847 zone->masterfile = NULL;
848 zone->masterformat = dns_masterformat_none;
849 zone->keydirectory = NULL;
850 zone->journalsize = -1;
851 zone->journal = NULL;
852 zone->rdclass = dns_rdataclass_none;
853 zone->type = dns_zone_none;
858 zone->db_argv = NULL;
859 isc_time_settoepoch(&zone->expiretime);
860 isc_time_settoepoch(&zone->refreshtime);
861 isc_time_settoepoch(&zone->dumptime);
862 isc_time_settoepoch(&zone->loadtime);
863 zone->notifytime = now;
864 isc_time_settoepoch(&zone->resigntime);
865 isc_time_settoepoch(&zone->keywarntime);
866 isc_time_settoepoch(&zone->signingtime);
867 isc_time_settoepoch(&zone->nsec3chaintime);
868 isc_time_settoepoch(&zone->refreshkeytime);
869 zone->refreshkeyinterval = 0;
870 zone->refreshkeycount = 0;
871 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
872 zone->retry = DNS_ZONE_DEFAULTRETRY;
875 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
876 zone->minrefresh = DNS_ZONE_MINREFRESH;
877 zone->maxretry = DNS_ZONE_MAXRETRY;
878 zone->minretry = DNS_ZONE_MINRETRY;
879 zone->masters = NULL;
880 zone->masterkeynames = NULL;
881 zone->mastersok = NULL;
882 zone->masterscnt = 0;
885 zone->notifykeynames = NULL;
886 zone->notifytype = dns_notifytype_yes;
889 zone->loadtask = NULL;
890 zone->update_acl = NULL;
891 zone->forward_acl = NULL;
892 zone->notify_acl = NULL;
893 zone->query_acl = NULL;
894 zone->queryon_acl = NULL;
895 zone->xfr_acl = NULL;
896 zone->update_disabled = ISC_FALSE;
897 zone->zero_no_soa_ttl = ISC_TRUE;
898 zone->check_names = dns_severity_ignore;
899 zone->request = NULL;
903 zone->writeio = NULL;
905 zone->idlein = DNS_DEFAULT_IDLEIN;
906 zone->idleout = DNS_DEFAULT_IDLEOUT;
907 zone->log_key_expired_timer = 0;
908 ISC_LIST_INIT(zone->notifies);
909 isc_sockaddr_any(&zone->notifysrc4);
910 isc_sockaddr_any6(&zone->notifysrc6);
911 isc_sockaddr_any(&zone->xfrsource4);
912 isc_sockaddr_any6(&zone->xfrsource6);
913 isc_sockaddr_any(&zone->altxfrsource4);
914 isc_sockaddr_any6(&zone->altxfrsource6);
916 zone->tsigkey = NULL;
917 zone->maxxfrin = MAX_XFER_TIME;
918 zone->maxxfrout = MAX_XFER_TIME;
919 zone->ssutable = NULL;
920 zone->sigvalidityinterval = 30 * 24 * 3600;
921 zone->sigresigninginterval = 7 * 24 * 3600;
924 zone->checkmx = NULL;
925 zone->checksrv = NULL;
926 zone->checkns = NULL;
927 ISC_LINK_INIT(zone, statelink);
928 zone->statelist = NULL;
930 zone->requeststats_on = ISC_FALSE;
931 zone->statlevel = dns_zonestat_none;
932 zone->requeststats = NULL;
933 zone->rcvquerystats = NULL;
934 zone->notifydelay = 5;
936 zone->isselfarg = NULL;
937 ISC_LIST_INIT(zone->signing);
938 ISC_LIST_INIT(zone->nsec3chain);
939 zone->signatures = 10;
941 zone->privatetype = (dns_rdatatype_t)0xffffU;
942 zone->added = ISC_FALSE;
943 zone->is_rpz = ISC_FALSE;
944 ISC_LIST_INIT(zone->forwards);
947 zone->sourceserial = 0;
948 zone->sourceserialset = ISC_FALSE;
950 zone->magic = ZONE_MAGIC;
952 /* Must be after magic is set. */
953 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
954 if (result != ISC_R_SUCCESS)
957 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
958 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
961 return (ISC_R_SUCCESS);
964 isc_refcount_decrement(&zone->erefs, NULL);
965 isc_refcount_destroy(&zone->erefs);
968 ZONEDB_DESTROYLOCK(&zone->dblock);
971 DESTROYLOCK(&zone->lock);
974 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
979 * Free a zone. Because we require that there be no more
980 * outstanding events or references, no locking is necessary.
983 zone_free(dns_zone_t *zone) {
984 isc_mem_t *mctx = NULL;
985 dns_signing_t *signing;
986 dns_nsec3chain_t *nsec3chain;
988 REQUIRE(DNS_ZONE_VALID(zone));
989 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
990 REQUIRE(zone->irefs == 0);
991 REQUIRE(!LOCKED_ZONE(zone));
992 REQUIRE(zone->timer == NULL);
993 REQUIRE(zone->zmgr == NULL);
996 * Managed objects. Order is important.
998 if (zone->request != NULL)
999 dns_request_destroy(&zone->request); /* XXXMPA */
1000 INSIST(zone->readio == NULL);
1001 INSIST(zone->statelist == NULL);
1002 INSIST(zone->writeio == NULL);
1004 if (zone->task != NULL)
1005 isc_task_detach(&zone->task);
1006 if (zone->loadtask != NULL)
1007 isc_task_detach(&zone->loadtask);
1009 /* Unmanaged objects */
1010 for (signing = ISC_LIST_HEAD(zone->signing);
1012 signing = ISC_LIST_HEAD(zone->signing)) {
1013 ISC_LIST_UNLINK(zone->signing, signing, link);
1014 dns_db_detach(&signing->db);
1015 dns_dbiterator_destroy(&signing->dbiterator);
1016 isc_mem_put(zone->mctx, signing, sizeof *signing);
1018 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
1020 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
1021 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
1022 dns_db_detach(&nsec3chain->db);
1023 dns_dbiterator_destroy(&nsec3chain->dbiterator);
1024 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
1026 if (zone->masterfile != NULL)
1027 isc_mem_free(zone->mctx, zone->masterfile);
1028 zone->masterfile = NULL;
1029 if (zone->keydirectory != NULL)
1030 isc_mem_free(zone->mctx, zone->keydirectory);
1031 zone->keydirectory = NULL;
1032 zone->journalsize = -1;
1033 if (zone->journal != NULL)
1034 isc_mem_free(zone->mctx, zone->journal);
1035 zone->journal = NULL;
1036 if (zone->stats != NULL)
1037 isc_stats_detach(&zone->stats);
1038 if (zone->requeststats != NULL)
1039 isc_stats_detach(&zone->requeststats);
1040 if(zone->rcvquerystats != NULL )
1041 dns_stats_detach(&zone->rcvquerystats);
1042 if (zone->db != NULL)
1043 zone_detachdb(zone);
1044 if (zone->acache != NULL)
1045 dns_acache_detach(&zone->acache);
1046 zone_freedbargs(zone);
1047 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
1049 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
1051 zone->check_names = dns_severity_ignore;
1052 if (zone->update_acl != NULL)
1053 dns_acl_detach(&zone->update_acl);
1054 if (zone->forward_acl != NULL)
1055 dns_acl_detach(&zone->forward_acl);
1056 if (zone->notify_acl != NULL)
1057 dns_acl_detach(&zone->notify_acl);
1058 if (zone->query_acl != NULL)
1059 dns_acl_detach(&zone->query_acl);
1060 if (zone->queryon_acl != NULL)
1061 dns_acl_detach(&zone->queryon_acl);
1062 if (zone->xfr_acl != NULL)
1063 dns_acl_detach(&zone->xfr_acl);
1064 if (dns_name_dynamic(&zone->origin))
1065 dns_name_free(&zone->origin, zone->mctx);
1066 if (zone->strnamerd != NULL)
1067 isc_mem_free(zone->mctx, zone->strnamerd);
1068 if (zone->strname != NULL)
1069 isc_mem_free(zone->mctx, zone->strname);
1070 if (zone->strrdclass != NULL)
1071 isc_mem_free(zone->mctx, zone->strrdclass);
1072 if (zone->strviewname != NULL)
1073 isc_mem_free(zone->mctx, zone->strviewname);
1074 if (zone->ssutable != NULL)
1075 dns_ssutable_detach(&zone->ssutable);
1078 ZONEDB_DESTROYLOCK(&zone->dblock);
1079 DESTROYLOCK(&zone->lock);
1080 isc_refcount_destroy(&zone->erefs);
1083 isc_mem_put(mctx, zone, sizeof(*zone));
1084 isc_mem_detach(&mctx);
1088 * Returns ISC_TRUE iff this the signed side of an inline-signing zone.
1089 * Caller should hold zone lock.
1091 static inline isc_boolean_t
1092 inline_secure(dns_zone_t *zone) {
1093 REQUIRE(DNS_ZONE_VALID(zone));
1094 if (zone->raw != NULL)
1100 * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone
1101 * Caller should hold zone lock.
1103 static inline isc_boolean_t
1104 inline_raw(dns_zone_t *zone) {
1105 REQUIRE(DNS_ZONE_VALID(zone));
1106 if (zone->secure != NULL)
1115 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1118 REQUIRE(DNS_ZONE_VALID(zone));
1119 REQUIRE(rdclass != dns_rdataclass_none);
1125 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1126 zone->rdclass == rdclass);
1127 zone->rdclass = rdclass;
1129 if (zone->strnamerd != NULL)
1130 isc_mem_free(zone->mctx, zone->strnamerd);
1131 if (zone->strrdclass != NULL)
1132 isc_mem_free(zone->mctx, zone->strrdclass);
1134 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1135 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1136 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1137 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1139 if (inline_secure(zone))
1140 dns_zone_setclass(zone->raw, rdclass);
1145 dns_zone_getclass(dns_zone_t *zone) {
1146 REQUIRE(DNS_ZONE_VALID(zone));
1148 return (zone->rdclass);
1152 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1153 REQUIRE(DNS_ZONE_VALID(zone));
1156 zone->notifytype = notifytype;
1161 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1162 isc_result_t result;
1163 unsigned int soacount;
1165 REQUIRE(DNS_ZONE_VALID(zone));
1166 REQUIRE(serialp != NULL);
1169 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1170 if (zone->db != NULL) {
1171 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
1172 serialp, NULL, NULL, NULL, NULL,
1174 if (result == ISC_R_SUCCESS && soacount == 0)
1175 result = ISC_R_FAILURE;
1177 result = DNS_R_NOTLOADED;
1178 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1185 dns_zone_getserial(dns_zone_t *zone) {
1186 isc_result_t result;
1187 isc_uint32_t serial;
1189 result = dns_zone_getserial2(zone, &serial);
1190 if (result != ISC_R_SUCCESS)
1191 serial = 0; /* XXX: not really correct, but no other choice */
1200 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1203 REQUIRE(DNS_ZONE_VALID(zone));
1204 REQUIRE(type != dns_zone_none);
1210 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1213 if (zone->strnamerd != NULL)
1214 isc_mem_free(zone->mctx, zone->strnamerd);
1216 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1217 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1222 zone_freedbargs(dns_zone_t *zone) {
1225 /* Free the old database argument list. */
1226 if (zone->db_argv != NULL) {
1227 for (i = 0; i < zone->db_argc; i++)
1228 isc_mem_free(zone->mctx, zone->db_argv[i]);
1229 isc_mem_put(zone->mctx, zone->db_argv,
1230 zone->db_argc * sizeof(*zone->db_argv));
1233 zone->db_argv = NULL;
1237 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1240 isc_result_t result = ISC_R_SUCCESS;
1244 REQUIRE(DNS_ZONE_VALID(zone));
1245 REQUIRE(argv != NULL && *argv == NULL);
1248 size = (zone->db_argc + 1) * sizeof(char *);
1249 for (i = 0; i < zone->db_argc; i++)
1250 size += strlen(zone->db_argv[i]) + 1;
1251 mem = isc_mem_allocate(mctx, size);
1255 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1256 for (i = 0; i < zone->db_argc; i++) {
1258 strcpy(tmp2, zone->db_argv[i]);
1259 tmp2 += strlen(tmp2) + 1;
1263 result = ISC_R_NOMEMORY;
1270 dns_zone_setdbtype(dns_zone_t *zone,
1271 unsigned int dbargc, const char * const *dbargv) {
1272 isc_result_t result = ISC_R_SUCCESS;
1276 REQUIRE(DNS_ZONE_VALID(zone));
1277 REQUIRE(dbargc >= 1);
1278 REQUIRE(dbargv != NULL);
1282 /* Set up a new database argument list. */
1283 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1286 for (i = 0; i < dbargc; i++)
1288 for (i = 0; i < dbargc; i++) {
1289 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1294 /* Free the old list. */
1295 zone_freedbargs(zone);
1297 zone->db_argc = dbargc;
1298 zone->db_argv = new;
1299 result = ISC_R_SUCCESS;
1304 for (i = 0; i < dbargc; i++)
1306 isc_mem_free(zone->mctx, new[i]);
1307 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1309 result = ISC_R_NOMEMORY;
1317 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1319 REQUIRE(DNS_ZONE_VALID(zone));
1322 if (zone->view != NULL)
1323 dns_view_weakdetach(&zone->view);
1324 dns_view_weakattach(view, &zone->view);
1326 if (zone->strviewname != NULL)
1327 isc_mem_free(zone->mctx, zone->strviewname);
1328 if (zone->strnamerd != NULL)
1329 isc_mem_free(zone->mctx, zone->strnamerd);
1331 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1332 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1333 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1334 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1336 if (inline_secure(zone))
1337 dns_zone_setview(zone->raw, view);
1343 dns_zone_getview(dns_zone_t *zone) {
1344 REQUIRE(DNS_ZONE_VALID(zone));
1346 return (zone->view);
1351 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1352 isc_result_t result;
1355 REQUIRE(DNS_ZONE_VALID(zone));
1356 REQUIRE(origin != NULL);
1359 if (dns_name_dynamic(&zone->origin)) {
1360 dns_name_free(&zone->origin, zone->mctx);
1361 dns_name_init(&zone->origin, NULL);
1363 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1365 if (zone->strnamerd != NULL)
1366 isc_mem_free(zone->mctx, zone->strnamerd);
1367 if (zone->strname != NULL)
1368 isc_mem_free(zone->mctx, zone->strname);
1370 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1371 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1372 zone_name_tostr(zone, namebuf, sizeof namebuf);
1373 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1375 if (result == ISC_R_SUCCESS && inline_secure(zone))
1376 result = dns_zone_setorigin(zone->raw, origin);
1382 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1383 REQUIRE(DNS_ZONE_VALID(zone));
1384 REQUIRE(acache != NULL);
1387 if (zone->acache != NULL)
1388 dns_acache_detach(&zone->acache);
1389 dns_acache_attach(acache, &zone->acache);
1390 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1391 if (zone->db != NULL) {
1392 isc_result_t result;
1395 * If the zone reuses an existing DB, the DB needs to be
1396 * set in the acache explicitly. We can safely ignore the
1397 * case where the DB is already set. If other error happens,
1398 * the acache will not work effectively.
1400 result = dns_acache_setdb(acache, zone->db);
1401 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1402 UNEXPECTED_ERROR(__FILE__, __LINE__,
1403 "dns_acache_setdb() failed: %s",
1404 isc_result_totext(result));
1407 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1412 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1415 if (value != NULL) {
1416 copy = isc_mem_strdup(zone->mctx, value);
1418 return (ISC_R_NOMEMORY);
1424 isc_mem_free(zone->mctx, *field);
1427 return (ISC_R_SUCCESS);
1431 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1432 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1436 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1437 dns_masterformat_t format) {
1438 isc_result_t result = ISC_R_SUCCESS;
1440 REQUIRE(DNS_ZONE_VALID(zone));
1443 result = dns_zone_setstring(zone, &zone->masterfile, file);
1444 if (result == ISC_R_SUCCESS) {
1445 zone->masterformat = format;
1446 result = default_journal(zone);
1454 dns_zone_getfile(dns_zone_t *zone) {
1455 REQUIRE(DNS_ZONE_VALID(zone));
1457 return (zone->masterfile);
1461 default_journal(dns_zone_t *zone) {
1462 isc_result_t result;
1465 REQUIRE(DNS_ZONE_VALID(zone));
1466 REQUIRE(LOCKED_ZONE(zone));
1468 if (zone->masterfile != NULL) {
1469 /* Calculate string length including '\0'. */
1470 int len = strlen(zone->masterfile) + sizeof(".jnl");
1471 journal = isc_mem_allocate(zone->mctx, len);
1472 if (journal == NULL)
1473 return (ISC_R_NOMEMORY);
1474 strcpy(journal, zone->masterfile);
1475 strcat(journal, ".jnl");
1479 result = dns_zone_setstring(zone, &zone->journal, journal);
1480 if (journal != NULL)
1481 isc_mem_free(zone->mctx, journal);
1486 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1487 isc_result_t result = ISC_R_SUCCESS;
1489 REQUIRE(DNS_ZONE_VALID(zone));
1492 result = dns_zone_setstring(zone, &zone->journal, journal);
1499 dns_zone_getjournal(dns_zone_t *zone) {
1500 REQUIRE(DNS_ZONE_VALID(zone));
1502 return (zone->journal);
1506 * Return true iff the zone is "dynamic", in the sense that the zone's
1507 * master file (if any) is written by the server, rather than being
1508 * updated manually and read by the server.
1510 * This is true for slave zones, stub zones, key zones, and zones that
1511 * allow dynamic updates either by having an update policy ("ssutable")
1512 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1515 dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) {
1516 REQUIRE(DNS_ZONE_VALID(zone));
1518 if (zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1519 zone->type == dns_zone_key ||
1520 (zone->type == dns_zone_redirect && zone->masters != NULL))
1523 /* If !ignore_freeze, we need check whether updates are disabled. */
1524 if (zone->type == dns_zone_master &&
1525 (!zone->update_disabled || ignore_freeze) &&
1526 ((zone->ssutable != NULL) ||
1527 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
1535 * Set the response policy index and information for a zone.
1538 dns_zone_rpz_enable(dns_zone_t *zone) {
1540 * Only RBTDB zones can be used for response policy zones,
1541 * because only they have the code to load the create the summary data.
1542 * Only zones that are loaded instead of mmap()ed create the
1543 * summary data and so can be policy zones.
1545 if (strcmp(zone->db_argv[0], "rbt") != 0 &&
1546 strcmp(zone->db_argv[0], "rbt64") != 0)
1547 return (ISC_R_NOTIMPLEMENTED);
1549 zone->is_rpz = ISC_TRUE;
1551 return (ISC_R_SUCCESS);
1555 dns_zone_get_rpz(dns_zone_t *zone) {
1556 return (zone->is_rpz);
1560 * If a zone is a response policy zone, mark its new database.
1563 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1566 return (dns_db_rpz_enabled(db, NULL));
1568 return (ISC_R_SUCCESS);
1572 zone_load(dns_zone_t *zone, unsigned int flags) {
1573 isc_result_t result;
1575 isc_time_t loadtime, filetime;
1576 dns_db_t *db = NULL;
1577 isc_boolean_t rbt, hasraw;
1579 REQUIRE(DNS_ZONE_VALID(zone));
1582 hasraw = inline_secure(zone);
1584 result = zone_load(zone->raw, flags);
1585 if (result != ISC_R_SUCCESS) {
1589 LOCK_ZONE(zone->raw);
1594 INSIST(zone->type != dns_zone_none);
1596 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1597 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1598 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1599 result = DNS_R_CONTINUE;
1603 INSIST(zone->db_argc >= 1);
1605 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1606 strcmp(zone->db_argv[0], "rbt64") == 0;
1608 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1610 * The zone has no master file configured.
1612 result = ISC_R_SUCCESS;
1616 if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) {
1618 * This is a slave, stub, or dynamically updated
1619 * zone being reloaded. Do nothing - the database
1620 * we already have is guaranteed to be up-to-date.
1622 if (zone->type == dns_zone_master)
1623 result = DNS_R_DYNAMIC;
1625 result = ISC_R_SUCCESS;
1630 * Store the current time before the zone is loaded, so that if the
1631 * file changes between the time of the load and the time that
1632 * zone->loadtime is set, then the file will still be reloaded
1633 * the next time dns_zone_load is called.
1635 TIME_NOW(&loadtime);
1638 * Don't do the load if the file that stores the zone is older
1639 * than the last time the zone was loaded. If the zone has not
1640 * been loaded yet, zone->loadtime will be the epoch.
1642 if (zone->masterfile != NULL) {
1644 * The file is already loaded. If we are just doing a
1645 * "rndc reconfig", we are done.
1647 if (!isc_time_isepoch(&zone->loadtime) &&
1648 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1649 result = ISC_R_SUCCESS;
1653 result = isc_file_getmodtime(zone->masterfile, &filetime);
1654 if (result == ISC_R_SUCCESS) {
1655 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1656 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1657 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1658 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1659 "skipping load: master file "
1660 "older than last load");
1661 result = DNS_R_UPTODATE;
1664 loadtime = filetime;
1669 * Built in zones (with the exception of empty zones) don't need
1672 if (zone->type == dns_zone_master &&
1673 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1674 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1675 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1676 result = ISC_R_SUCCESS;
1680 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1681 (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
1683 if (zone->masterfile == NULL ||
1684 !isc_file_exists(zone->masterfile)) {
1685 if (zone->masterfile != NULL) {
1686 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1689 zone->refreshtime = now;
1690 if (zone->task != NULL)
1691 zone_settimer(zone, &now);
1692 result = ISC_R_SUCCESS;
1697 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1699 result = dns_db_create(zone->mctx, zone->db_argv[0],
1700 &zone->origin, (zone->type == dns_zone_stub) ?
1701 dns_dbtype_stub : dns_dbtype_zone,
1703 zone->db_argc - 1, zone->db_argv + 1,
1706 if (result != ISC_R_SUCCESS) {
1707 dns_zone_log(zone, ISC_LOG_ERROR,
1708 "loading zone: creating database: %s",
1709 isc_result_totext(result));
1712 dns_db_settask(db, zone->task);
1714 if (! dns_db_ispersistent(db)) {
1715 if (zone->masterfile != NULL) {
1716 result = zone_startload(db, zone, loadtime);
1718 result = DNS_R_NOMASTERFILE;
1719 if (zone->type == dns_zone_master ||
1720 (zone->type == dns_zone_redirect &&
1721 zone->masters == NULL)) {
1722 dns_zone_log(zone, ISC_LOG_ERROR,
1724 "no master file configured");
1727 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1728 "no master file configured: continuing");
1732 if (result == DNS_R_CONTINUE) {
1733 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1734 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1735 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1739 result = zone_postload(zone, db, loadtime, result);
1743 UNLOCK_ZONE(zone->raw);
1751 dns_zone_load(dns_zone_t *zone) {
1752 return (zone_load(zone, 0));
1756 dns_zone_loadnew(dns_zone_t *zone) {
1757 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1761 zone_asyncload(isc_task_t *task, isc_event_t *event) {
1762 dns_asyncload_t *asl = event->ev_arg;
1763 dns_zone_t *zone = asl->zone;
1764 isc_result_t result = ISC_R_SUCCESS;
1768 REQUIRE(DNS_ZONE_VALID(zone));
1770 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1771 result = ISC_R_CANCELED;
1772 isc_event_free(&event);
1773 if (result == ISC_R_CANCELED ||
1774 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
1780 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
1783 /* Inform the zone table we've finished loading */
1784 if (asl->loaded != NULL)
1785 (asl->loaded)(asl->loaded_arg, zone, task);
1788 isc_mem_put(zone->mctx, asl, sizeof (*asl));
1789 dns_zone_idetach(&zone);
1793 dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
1795 dns_asyncload_t *asl = NULL;
1796 isc_result_t result = ISC_R_SUCCESS;
1798 REQUIRE(DNS_ZONE_VALID(zone));
1800 if (zone->zmgr == NULL)
1801 return (ISC_R_FAILURE);
1803 asl = isc_mem_get(zone->mctx, sizeof (*asl));
1805 CHECK(ISC_R_NOMEMORY);
1809 asl->loaded_arg = arg;
1811 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
1813 zone_asyncload, asl,
1814 sizeof(isc_event_t));
1816 CHECK(ISC_R_NOMEMORY);
1819 zone_iattach(zone, &asl->zone);
1820 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
1821 isc_task_send(zone->loadtask, &e);
1824 return (ISC_R_SUCCESS);
1828 isc_mem_put(zone->mctx, asl, sizeof (*asl));
1833 dns__zone_loadpending(dns_zone_t *zone) {
1834 REQUIRE(DNS_ZONE_VALID(zone));
1836 return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)));
1840 dns_zone_loadandthaw(dns_zone_t *zone) {
1841 isc_result_t result;
1843 if (inline_raw(zone))
1844 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW);
1846 result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1849 case DNS_R_CONTINUE:
1850 /* Deferred thaw. */
1852 case DNS_R_UPTODATE:
1854 case DNS_R_SEENINCLUDE:
1855 zone->update_disabled = ISC_FALSE;
1857 case DNS_R_NOMASTERFILE:
1858 zone->update_disabled = ISC_FALSE;
1861 /* Error, remain in disabled state. */
1868 get_master_options(dns_zone_t *zone) {
1869 unsigned int options;
1871 options = DNS_MASTER_ZONE;
1872 if (zone->type == dns_zone_slave ||
1873 (zone->type == dns_zone_redirect && zone->masters == NULL))
1874 options |= DNS_MASTER_SLAVE;
1875 if (zone->type == dns_zone_key)
1876 options |= DNS_MASTER_KEY;
1877 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1878 options |= DNS_MASTER_CHECKNS;
1879 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1880 options |= DNS_MASTER_FATALNS;
1881 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1882 options |= DNS_MASTER_CHECKNAMES;
1883 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1884 options |= DNS_MASTER_CHECKNAMESFAIL;
1885 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1886 options |= DNS_MASTER_CHECKMX;
1887 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1888 options |= DNS_MASTER_CHECKMXFAIL;
1889 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1890 options |= DNS_MASTER_CHECKWILDCARD;
1891 if (inline_secure(zone) || (zone->type == dns_zone_master &&
1892 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1893 zone->ssutable != NULL)))
1894 options |= DNS_MASTER_RESIGN;
1899 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1900 dns_load_t *load = event->ev_arg;
1901 isc_result_t result = ISC_R_SUCCESS;
1902 unsigned int options;
1904 REQUIRE(DNS_LOAD_VALID(load));
1906 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1907 result = ISC_R_CANCELED;
1908 isc_event_free(&event);
1909 if (result == ISC_R_CANCELED)
1912 options = get_master_options(load->zone);
1914 result = dns_master_loadfileinc3(load->zone->masterfile,
1915 dns_db_origin(load->db),
1916 dns_db_origin(load->db),
1917 load->zone->rdclass, options, 0,
1918 &load->callbacks, task,
1919 zone_loaddone, load,
1920 &load->zone->lctx, load->zone->mctx,
1921 load->zone->masterformat);
1922 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1923 result != DNS_R_SEENINCLUDE)
1928 zone_loaddone(load, result);
1932 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
1933 isc_result_t result;
1934 unsigned int soacount;
1937 if (raw->db != NULL) {
1938 result = zone_get_from_db(raw, raw->db, NULL, &soacount,
1939 &rawdata->sourceserial,
1940 NULL, NULL, NULL, NULL,
1942 if (result == ISC_R_SUCCESS && soacount > 0U)
1943 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
1949 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1950 const char me[] = "zone_gotwritehandle";
1951 dns_zone_t *zone = event->ev_arg;
1952 isc_result_t result = ISC_R_SUCCESS;
1953 dns_dbversion_t *version = NULL;
1954 dns_masterrawheader_t rawdata;
1956 REQUIRE(DNS_ZONE_VALID(zone));
1957 INSIST(task == zone->task);
1960 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1961 result = ISC_R_CANCELED;
1962 isc_event_free(&event);
1963 if (result == ISC_R_CANCELED)
1967 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1968 if (zone->db != NULL) {
1969 const dns_master_style_t *output_style;
1971 dns_db_currentversion(zone->db, &version);
1972 dns_master_initrawheader(&rawdata);
1973 if (inline_secure(zone))
1974 get_raw_serial(zone->raw, &rawdata);
1975 if (zone->type == dns_zone_key)
1976 output_style = &dns_master_style_keyzone;
1978 output_style = &dns_master_style_default;
1979 result = dns_master_dumpinc3(zone->mctx, zone->db, version,
1980 output_style, zone->masterfile,
1981 zone->task, dump_done, zone, &zone->dctx, zone->masterformat,
1983 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1985 result = ISC_R_CANCELED;
1986 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1988 if (result != DNS_R_CONTINUE)
1993 dump_done(zone, result);
1997 * Save the raw serial number for inline-signing zones.
1998 * (XXX: Other information from the header will be used
1999 * for other purposes in the future, but for now this is
2000 * all we're interested in.)
2003 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2004 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
2007 zone->sourceserial = header->sourceserial;
2008 zone->sourceserialset = ISC_TRUE;
2012 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2017 zone_setrawdata(zone, header);
2022 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
2024 isc_result_t result;
2025 isc_result_t tresult;
2026 unsigned int options;
2028 result = dns_zone_rpz_enable_db(zone, db);
2029 if (result != ISC_R_SUCCESS)
2031 options = get_master_options(zone);
2032 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
2033 options |= DNS_MASTER_MANYERRORS;
2035 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
2036 load = isc_mem_get(zone->mctx, sizeof(*load));
2038 return (ISC_R_NOMEMORY);
2043 load->loadtime = loadtime;
2044 load->magic = LOAD_MAGIC;
2046 isc_mem_attach(zone->mctx, &load->mctx);
2047 zone_iattach(zone, &load->zone);
2048 dns_db_attach(db, &load->db);
2049 dns_rdatacallbacks_init(&load->callbacks);
2050 load->callbacks.rawdata = zone_setrawdata;
2051 zone_iattach(zone, &load->callbacks.zone);
2052 result = dns_db_beginload(db, &load->callbacks.add,
2053 &load->callbacks.add_private);
2054 if (result != ISC_R_SUCCESS)
2056 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask,
2057 zone_gotreadhandle, load,
2059 if (result != ISC_R_SUCCESS) {
2061 * We can't report multiple errors so ignore
2062 * the result of dns_db_endload().
2064 (void)dns_db_endload(load->db,
2065 &load->callbacks.add_private);
2068 result = DNS_R_CONTINUE;
2070 dns_rdatacallbacks_t callbacks;
2072 dns_rdatacallbacks_init(&callbacks);
2073 callbacks.rawdata = zone_setrawdata;
2074 zone_iattach(zone, &callbacks.zone);
2075 result = dns_db_beginload(db, &callbacks.add,
2076 &callbacks.add_private);
2077 if (result != ISC_R_SUCCESS) {
2078 zone_idetach(&callbacks.zone);
2081 result = dns_master_loadfile3(zone->masterfile,
2082 &zone->origin, &zone->origin,
2083 zone->rdclass, options, 0,
2084 &callbacks, zone->mctx,
2085 zone->masterformat);
2086 tresult = dns_db_endload(db, &callbacks.add_private);
2087 if (result == ISC_R_SUCCESS)
2089 zone_idetach(&callbacks.zone);
2096 dns_db_detach(&load->db);
2097 zone_idetach(&load->zone);
2098 zone_idetach(&load->callbacks.zone);
2099 isc_mem_detach(&load->mctx);
2100 isc_mem_put(zone->mctx, load, sizeof(*load));
2104 static isc_boolean_t
2105 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2108 isc_result_t result;
2109 char ownerbuf[DNS_NAME_FORMATSIZE];
2110 char namebuf[DNS_NAME_FORMATSIZE];
2111 char altbuf[DNS_NAME_FORMATSIZE];
2112 dns_fixedname_t fixed;
2113 dns_name_t *foundname;
2117 * "." means the services does not exist.
2119 if (dns_name_equal(name, dns_rootname))
2125 if (!dns_name_issubdomain(name, &zone->origin)) {
2126 if (zone->checkmx != NULL)
2127 return ((zone->checkmx)(zone, name, owner));
2131 if (zone->type == dns_zone_master)
2132 level = ISC_LOG_ERROR;
2134 level = ISC_LOG_WARNING;
2136 dns_fixedname_init(&fixed);
2137 foundname = dns_fixedname_name(&fixed);
2139 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2140 0, 0, NULL, foundname, NULL, NULL);
2141 if (result == ISC_R_SUCCESS)
2144 if (result == DNS_R_NXRRSET) {
2145 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2146 0, 0, NULL, foundname, NULL, NULL);
2147 if (result == ISC_R_SUCCESS)
2151 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2152 dns_name_format(name, namebuf, sizeof namebuf);
2153 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2154 result == DNS_R_EMPTYNAME) {
2155 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
2156 level = ISC_LOG_WARNING;
2157 dns_zone_log(zone, level,
2158 "%s/MX '%s' has no address records (A or AAAA)",
2160 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2163 if (result == DNS_R_CNAME) {
2164 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2165 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2166 level = ISC_LOG_WARNING;
2167 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2168 dns_zone_log(zone, level,
2169 "%s/MX '%s' is a CNAME (illegal)",
2171 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2174 if (result == DNS_R_DNAME) {
2175 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2176 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2177 level = ISC_LOG_WARNING;
2178 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
2179 dns_name_format(foundname, altbuf, sizeof altbuf);
2180 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
2181 " '%s' (illegal)", ownerbuf, namebuf,
2184 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2187 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
2188 return ((zone->checkmx)(zone, name, owner));
2193 static isc_boolean_t
2194 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2197 isc_result_t result;
2198 char ownerbuf[DNS_NAME_FORMATSIZE];
2199 char namebuf[DNS_NAME_FORMATSIZE];
2200 char altbuf[DNS_NAME_FORMATSIZE];
2201 dns_fixedname_t fixed;
2202 dns_name_t *foundname;
2206 * "." means the services does not exist.
2208 if (dns_name_equal(name, dns_rootname))
2214 if (!dns_name_issubdomain(name, &zone->origin)) {
2215 if (zone->checksrv != NULL)
2216 return ((zone->checksrv)(zone, name, owner));
2220 if (zone->type == dns_zone_master)
2221 level = ISC_LOG_ERROR;
2223 level = ISC_LOG_WARNING;
2225 dns_fixedname_init(&fixed);
2226 foundname = dns_fixedname_name(&fixed);
2228 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2229 0, 0, NULL, foundname, NULL, NULL);
2230 if (result == ISC_R_SUCCESS)
2233 if (result == DNS_R_NXRRSET) {
2234 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2235 0, 0, NULL, foundname, NULL, NULL);
2236 if (result == ISC_R_SUCCESS)
2240 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2241 dns_name_format(name, namebuf, sizeof namebuf);
2242 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2243 result == DNS_R_EMPTYNAME) {
2244 dns_zone_log(zone, level,
2245 "%s/SRV '%s' has no address records (A or AAAA)",
2247 /* XXX950 make fatal for 9.5.0. */
2251 if (result == DNS_R_CNAME) {
2252 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2253 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2254 level = ISC_LOG_WARNING;
2255 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2256 dns_zone_log(zone, level,
2257 "%s/SRV '%s' is a CNAME (illegal)",
2259 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2262 if (result == DNS_R_DNAME) {
2263 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2264 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2265 level = ISC_LOG_WARNING;
2266 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
2267 dns_name_format(foundname, altbuf, sizeof altbuf);
2268 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
2269 "DNAME '%s' (illegal)", ownerbuf, namebuf,
2272 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2275 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
2276 return ((zone->checksrv)(zone, name, owner));
2281 static isc_boolean_t
2282 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2285 isc_boolean_t answer = ISC_TRUE;
2286 isc_result_t result, tresult;
2287 char ownerbuf[DNS_NAME_FORMATSIZE];
2288 char namebuf[DNS_NAME_FORMATSIZE];
2289 char altbuf[DNS_NAME_FORMATSIZE];
2290 dns_fixedname_t fixed;
2291 dns_name_t *foundname;
2293 dns_rdataset_t aaaa;
2299 if (!dns_name_issubdomain(name, &zone->origin)) {
2300 if (zone->checkns != NULL)
2301 return ((zone->checkns)(zone, name, owner, NULL, NULL));
2305 if (zone->type == dns_zone_master)
2306 level = ISC_LOG_ERROR;
2308 level = ISC_LOG_WARNING;
2310 dns_fixedname_init(&fixed);
2311 foundname = dns_fixedname_name(&fixed);
2312 dns_rdataset_init(&a);
2313 dns_rdataset_init(&aaaa);
2315 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2316 DNS_DBFIND_GLUEOK, 0, NULL,
2317 foundname, &a, NULL);
2319 if (result == ISC_R_SUCCESS) {
2320 dns_rdataset_disassociate(&a);
2322 } else if (result == DNS_R_DELEGATION)
2323 dns_rdataset_disassociate(&a);
2325 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
2326 result == DNS_R_GLUE) {
2327 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2328 DNS_DBFIND_GLUEOK, 0, NULL,
2329 foundname, &aaaa, NULL);
2330 if (tresult == ISC_R_SUCCESS) {
2331 dns_rdataset_disassociate(&aaaa);
2334 if (tresult == DNS_R_DELEGATION)
2335 dns_rdataset_disassociate(&aaaa);
2336 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2338 * Check glue against child zone.
2340 if (zone->checkns != NULL)
2341 answer = (zone->checkns)(zone, name, owner,
2343 if (dns_rdataset_isassociated(&a))
2344 dns_rdataset_disassociate(&a);
2345 if (dns_rdataset_isassociated(&aaaa))
2346 dns_rdataset_disassociate(&aaaa);
2351 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2352 dns_name_format(name, namebuf, sizeof namebuf);
2353 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2354 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2356 isc_boolean_t required = ISC_FALSE;
2357 if (dns_name_issubdomain(name, owner)) {
2358 what = "REQUIRED GLUE ";
2359 required = ISC_TRUE;
2360 } else if (result == DNS_R_DELEGATION)
2361 what = "SIBLING GLUE ";
2365 if (result != DNS_R_DELEGATION || required ||
2366 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2367 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2368 "address records (A or AAAA)",
2369 ownerbuf, namebuf, what);
2371 * Log missing address record.
2373 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2374 (void)(zone->checkns)(zone, name, owner,
2376 /* XXX950 make fatal for 9.5.0. */
2377 /* answer = ISC_FALSE; */
2379 } else if (result == DNS_R_CNAME) {
2380 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2382 /* XXX950 make fatal for 9.5.0. */
2383 /* answer = ISC_FALSE; */
2384 } else if (result == DNS_R_DNAME) {
2385 dns_name_format(foundname, altbuf, sizeof altbuf);
2386 dns_zone_log(zone, level,
2387 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2388 ownerbuf, namebuf, altbuf);
2389 /* XXX950 make fatal for 9.5.0. */
2390 /* answer = ISC_FALSE; */
2393 if (dns_rdataset_isassociated(&a))
2394 dns_rdataset_disassociate(&a);
2395 if (dns_rdataset_isassociated(&aaaa))
2396 dns_rdataset_disassociate(&aaaa);
2400 static isc_boolean_t
2401 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2402 dns_rdataset_t *rdataset)
2404 dns_rdataset_t tmprdataset;
2405 isc_result_t result;
2406 isc_boolean_t answer = ISC_TRUE;
2407 isc_boolean_t format = ISC_TRUE;
2408 int level = ISC_LOG_WARNING;
2409 char ownerbuf[DNS_NAME_FORMATSIZE];
2410 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2411 unsigned int count1 = 0;
2413 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2414 level = ISC_LOG_ERROR;
2416 dns_rdataset_init(&tmprdataset);
2417 for (result = dns_rdataset_first(rdataset);
2418 result == ISC_R_SUCCESS;
2419 result = dns_rdataset_next(rdataset)) {
2420 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2421 unsigned int count2 = 0;
2424 dns_rdataset_current(rdataset, &rdata1);
2425 dns_rdataset_clone(rdataset, &tmprdataset);
2426 for (result = dns_rdataset_first(&tmprdataset);
2427 result == ISC_R_SUCCESS;
2428 result = dns_rdataset_next(&tmprdataset)) {
2429 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2431 if (count1 >= count2)
2433 dns_rdataset_current(&tmprdataset, &rdata2);
2434 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2436 dns_name_format(owner, ownerbuf,
2438 dns_rdatatype_format(rdata1.type,
2443 dns_zone_log(zone, level, "%s/%s has "
2444 "semantically identical records",
2446 if (level == ISC_LOG_ERROR)
2451 dns_rdataset_disassociate(&tmprdataset);
2458 static isc_boolean_t
2459 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2460 dns_dbiterator_t *dbiterator = NULL;
2461 dns_dbnode_t *node = NULL;
2462 dns_fixedname_t fixed;
2464 dns_rdataset_t rdataset;
2465 dns_rdatasetiter_t *rdsit = NULL;
2466 isc_boolean_t ok = ISC_TRUE;
2467 isc_result_t result;
2469 dns_fixedname_init(&fixed);
2470 name = dns_fixedname_name(&fixed);
2471 dns_rdataset_init(&rdataset);
2473 result = dns_db_createiterator(db, 0, &dbiterator);
2474 if (result != ISC_R_SUCCESS)
2477 for (result = dns_dbiterator_first(dbiterator);
2478 result == ISC_R_SUCCESS;
2479 result = dns_dbiterator_next(dbiterator)) {
2480 result = dns_dbiterator_current(dbiterator, &node, name);
2481 if (result != ISC_R_SUCCESS)
2484 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2485 if (result != ISC_R_SUCCESS)
2488 for (result = dns_rdatasetiter_first(rdsit);
2489 result == ISC_R_SUCCESS;
2490 result = dns_rdatasetiter_next(rdsit)) {
2491 dns_rdatasetiter_current(rdsit, &rdataset);
2492 if (!zone_rrset_check_dup(zone, name, &rdataset))
2494 dns_rdataset_disassociate(&rdataset);
2496 dns_rdatasetiter_destroy(&rdsit);
2497 dns_db_detachnode(db, &node);
2501 dns_db_detachnode(db, &node);
2502 dns_dbiterator_destroy(&dbiterator);
2507 static isc_boolean_t
2508 isspf(const dns_rdata_t *rdata) {
2510 const unsigned char *data = rdata->data;
2511 unsigned int rdl = rdata->length, i = 0, tl, len;
2518 if (len > sizeof(buf) - i - 1)
2519 len = sizeof(buf) - i - 1;
2520 memmove(buf + i, data, len);
2530 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
2535 static isc_boolean_t
2536 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2537 dns_dbiterator_t *dbiterator = NULL;
2538 dns_dbnode_t *node = NULL;
2539 dns_rdataset_t rdataset;
2540 dns_fixedname_t fixed;
2541 dns_fixedname_t fixedbottom;
2544 dns_rdata_in_srv_t srv;
2548 isc_result_t result;
2549 isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
2551 dns_fixedname_init(&fixed);
2552 name = dns_fixedname_name(&fixed);
2553 dns_fixedname_init(&fixedbottom);
2554 bottom = dns_fixedname_name(&fixedbottom);
2555 dns_rdataset_init(&rdataset);
2556 dns_rdata_init(&rdata);
2558 result = dns_db_createiterator(db, 0, &dbiterator);
2559 if (result != ISC_R_SUCCESS)
2562 result = dns_dbiterator_first(dbiterator);
2563 while (result == ISC_R_SUCCESS) {
2564 result = dns_dbiterator_current(dbiterator, &node, name);
2565 if (result != ISC_R_SUCCESS)
2569 * Is this name visible in the zone?
2571 if (!dns_name_issubdomain(name, &zone->origin) ||
2572 (dns_name_countlabels(bottom) > 0 &&
2573 dns_name_issubdomain(name, bottom)))
2577 * Don't check the NS records at the origin.
2579 if (dns_name_equal(name, &zone->origin))
2582 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2583 0, 0, &rdataset, NULL);
2584 if (result != ISC_R_SUCCESS)
2587 * Remember bottom of zone.
2589 dns_name_copy(name, bottom, NULL);
2591 result = dns_rdataset_first(&rdataset);
2592 while (result == ISC_R_SUCCESS) {
2593 dns_rdataset_current(&rdataset, &rdata);
2594 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2595 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2596 if (!zone_check_glue(zone, db, &ns.name, name))
2598 dns_rdata_reset(&rdata);
2599 result = dns_rdataset_next(&rdataset);
2601 dns_rdataset_disassociate(&rdataset);
2605 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2606 0, 0, &rdataset, NULL);
2607 if (result != ISC_R_SUCCESS)
2609 result = dns_rdataset_first(&rdataset);
2610 while (result == ISC_R_SUCCESS) {
2611 dns_rdataset_current(&rdataset, &rdata);
2612 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2613 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2614 if (!zone_check_mx(zone, db, &mx.mx, name))
2616 dns_rdata_reset(&rdata);
2617 result = dns_rdataset_next(&rdataset);
2619 dns_rdataset_disassociate(&rdataset);
2622 if (zone->rdclass != dns_rdataclass_in)
2624 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
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 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2632 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2633 if (!zone_check_srv(zone, db, &srv.target, name))
2635 dns_rdata_reset(&rdata);
2636 result = dns_rdataset_next(&rdataset);
2638 dns_rdataset_disassociate(&rdataset);
2642 * Check if there is a type TXT spf record without a type SPF
2643 * RRset being present.
2645 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
2647 if (zone->rdclass != dns_rdataclass_in)
2649 have_spf = have_txt = ISC_FALSE;
2650 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
2651 0, 0, &rdataset, NULL);
2652 if (result == ISC_R_SUCCESS) {
2653 dns_rdataset_disassociate(&rdataset);
2654 have_spf = ISC_TRUE;
2656 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
2657 0, 0, &rdataset, NULL);
2658 if (result != ISC_R_SUCCESS)
2660 result = dns_rdataset_first(&rdataset);
2661 while (result == ISC_R_SUCCESS) {
2662 dns_rdataset_current(&rdataset, &rdata);
2663 have_txt = isspf(&rdata);
2664 dns_rdata_reset(&rdata);
2667 result = dns_rdataset_next(&rdataset);
2669 dns_rdataset_disassociate(&rdataset);
2672 if (have_spf != have_txt) {
2673 char namebuf[DNS_NAME_FORMATSIZE];
2674 const char *found = have_txt ? "TXT" : "SPF";
2675 const char *need = have_txt ? "SPF" : "TXT";
2677 dns_name_format(name, namebuf, sizeof(namebuf));
2678 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s "
2679 "record but no SPF/%s record found, add "
2680 "matching type %s record", namebuf, found,
2685 dns_db_detachnode(db, &node);
2686 result = dns_dbiterator_next(dbiterator);
2691 dns_db_detachnode(db, &node);
2692 dns_dbiterator_destroy(&dbiterator);
2698 * OpenSSL verification of RSA keys with exponent 3 is known to be
2699 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2700 * if they are in use.
2703 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2704 dns_dbnode_t *node = NULL;
2705 dns_dbversion_t *version = NULL;
2706 dns_rdata_dnskey_t dnskey;
2707 dns_rdata_t rdata = DNS_RDATA_INIT;
2708 dns_rdataset_t rdataset;
2709 isc_result_t result;
2710 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2711 const char *algorithm;
2713 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2714 if (result != ISC_R_SUCCESS)
2717 dns_db_currentversion(db, &version);
2718 dns_rdataset_init(&rdataset);
2719 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2720 dns_rdatatype_none, 0, &rdataset, NULL);
2721 if (result != ISC_R_SUCCESS)
2724 for (result = dns_rdataset_first(&rdataset);
2725 result == ISC_R_SUCCESS;
2726 result = dns_rdataset_next(&rdataset))
2728 dns_rdataset_current(&rdataset, &rdata);
2729 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2730 INSIST(result == ISC_R_SUCCESS);
2732 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2733 dnskey.algorithm == DST_ALG_RSAMD5) &&
2734 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2735 dnskey.data[1] == 3)
2737 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2739 foundrsa = ISC_TRUE;
2740 algorithm = "RSASHA1";
2743 foundmd5 = ISC_TRUE;
2744 algorithm = "RSAMD5";
2747 dns_zone_log(zone, ISC_LOG_WARNING,
2748 "weak %s (%u) key found "
2749 "(exponent=3)", algorithm,
2751 if (foundrsa && foundmd5)
2754 dns_rdata_reset(&rdata);
2756 dns_rdataset_disassociate(&rdataset);
2760 dns_db_detachnode(db, &node);
2761 if (version != NULL)
2762 dns_db_closeversion(db, &version, ISC_FALSE);
2766 resume_signingwithkey(dns_zone_t *zone) {
2767 dns_dbnode_t *node = NULL;
2768 dns_dbversion_t *version = NULL;
2769 dns_rdata_t rdata = DNS_RDATA_INIT;
2770 dns_rdataset_t rdataset;
2771 isc_result_t result;
2772 dns_db_t *db = NULL;
2774 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2775 if (zone->db != NULL)
2776 dns_db_attach(zone->db, &db);
2777 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2781 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2782 if (result != ISC_R_SUCCESS)
2785 dns_db_currentversion(db, &version);
2786 dns_rdataset_init(&rdataset);
2787 result = dns_db_findrdataset(db, node, version,
2789 dns_rdatatype_none, 0,
2791 if (result != ISC_R_SUCCESS) {
2792 INSIST(!dns_rdataset_isassociated(&rdataset));
2796 for (result = dns_rdataset_first(&rdataset);
2797 result == ISC_R_SUCCESS;
2798 result = dns_rdataset_next(&rdataset))
2800 dns_rdataset_current(&rdataset, &rdata);
2801 if (rdata.length != 5 ||
2802 rdata.data[0] == 0 || rdata.data[4] != 0) {
2803 dns_rdata_reset(&rdata);
2807 result = zone_signwithkey(zone, rdata.data[0],
2808 (rdata.data[1] << 8) | rdata.data[2],
2809 ISC_TF(rdata.data[3]));
2810 if (result != ISC_R_SUCCESS) {
2811 dns_zone_log(zone, ISC_LOG_ERROR,
2812 "zone_signwithkey failed: %s",
2813 dns_result_totext(result));
2815 dns_rdata_reset(&rdata);
2817 dns_rdataset_disassociate(&rdataset);
2822 dns_db_detachnode(db, &node);
2823 if (version != NULL)
2824 dns_db_closeversion(db, &version, ISC_FALSE);
2830 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2831 dns_nsec3chain_t *nsec3chain, *current;
2832 dns_dbversion_t *version = NULL;
2833 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
2834 isc_result_t result;
2836 unsigned int options = 0;
2837 char saltbuf[255*2+1];
2838 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
2839 dns_db_t *db = NULL;
2842 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2843 if (zone->db != NULL)
2844 dns_db_attach(zone->db, &db);
2845 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2848 result = ISC_R_SUCCESS;
2852 dns_db_currentversion(db, &version);
2853 result = dns_nsec_nseconly(db, version, &nseconly);
2854 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
2855 dns_db_closeversion(db, &version, ISC_FALSE);
2856 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
2857 result = ISC_R_SUCCESS;
2861 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2862 if (nsec3chain == NULL) {
2863 result = ISC_R_NOMEMORY;
2867 nsec3chain->magic = 0;
2868 nsec3chain->done = ISC_FALSE;
2869 nsec3chain->db = NULL;
2870 nsec3chain->dbiterator = NULL;
2871 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2872 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2873 nsec3chain->nsec3param.hash = nsec3param->hash;
2874 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2875 nsec3chain->nsec3param.flags = nsec3param->flags;
2876 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2877 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2878 nsec3chain->nsec3param.salt = nsec3chain->salt;
2879 nsec3chain->seen_nsec = ISC_FALSE;
2880 nsec3chain->delete_nsec = ISC_FALSE;
2881 nsec3chain->save_delete_nsec = ISC_FALSE;
2883 if (nsec3param->flags == 0)
2884 strlcpy(flags, "NONE", sizeof(flags));
2887 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
2888 strlcat(flags, "REMOVE", sizeof(flags));
2889 if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) {
2890 if (flags[0] == '\0')
2891 strlcpy(flags, "INITIAL", sizeof(flags));
2893 strlcat(flags, "|INITIAL", sizeof(flags));
2895 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
2896 if (flags[0] == '\0')
2897 strlcpy(flags, "CREATE", sizeof(flags));
2899 strlcat(flags, "|CREATE", sizeof(flags));
2901 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
2902 if (flags[0] == '\0')
2903 strlcpy(flags, "NONSEC", sizeof(flags));
2905 strlcat(flags, "|NONSEC", sizeof(flags));
2907 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
2908 if (flags[0] == '\0')
2909 strlcpy(flags, "OPTOUT", sizeof(flags));
2911 strlcat(flags, "|OPTOUT", sizeof(flags));
2914 if (nsec3param->salt_length == 0)
2915 strlcpy(saltbuf, "-", sizeof(saltbuf));
2917 for (i = 0; i < nsec3param->salt_length; i++)
2918 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
2919 dns_zone_log(zone, ISC_LOG_INFO,
2920 "zone_addnsec3chain(%u,%s,%u,%s)",
2921 nsec3param->hash, flags, nsec3param->iterations,
2924 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2926 current = ISC_LIST_NEXT(current, link)) {
2927 if (current->db == db &&
2928 current->nsec3param.hash == nsec3param->hash &&
2929 current->nsec3param.iterations == nsec3param->iterations &&
2930 current->nsec3param.salt_length == nsec3param->salt_length
2931 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2932 nsec3param->salt_length))
2933 current->done = ISC_TRUE;
2936 dns_db_attach(db, &nsec3chain->db);
2937 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2938 options = DNS_DB_NONSEC3;
2939 result = dns_db_createiterator(nsec3chain->db, options,
2940 &nsec3chain->dbiterator);
2941 if (result == ISC_R_SUCCESS)
2942 dns_dbiterator_first(nsec3chain->dbiterator);
2943 if (result == ISC_R_SUCCESS) {
2944 dns_dbiterator_pause(nsec3chain->dbiterator);
2945 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2948 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2950 zone->nsec3chaintime = now;
2951 if (zone->task != NULL)
2952 zone_settimer(zone, &now);
2956 if (nsec3chain != NULL) {
2957 if (nsec3chain->db != NULL)
2958 dns_db_detach(&nsec3chain->db);
2959 if (nsec3chain->dbiterator != NULL)
2960 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2961 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2971 resume_addnsec3chain(dns_zone_t *zone) {
2972 dns_dbnode_t *node = NULL;
2973 dns_dbversion_t *version = NULL;
2974 dns_rdataset_t rdataset;
2975 isc_result_t result;
2976 dns_rdata_nsec3param_t nsec3param;
2977 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
2978 dns_db_t *db = NULL;
2980 if (zone->privatetype == 0)
2983 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2984 if (zone->db != NULL)
2985 dns_db_attach(zone->db, &db);
2986 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2990 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2991 if (result != ISC_R_SUCCESS)
2994 dns_db_currentversion(db, &version);
2996 result = dns_nsec_nseconly(db, version, &nseconly);
2997 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
2999 dns_rdataset_init(&rdataset);
3000 result = dns_db_findrdataset(db, node, version,
3001 zone->privatetype, dns_rdatatype_none,
3002 0, &rdataset, NULL);
3003 if (result != ISC_R_SUCCESS) {
3004 INSIST(!dns_rdataset_isassociated(&rdataset));
3008 for (result = dns_rdataset_first(&rdataset);
3009 result == ISC_R_SUCCESS;
3010 result = dns_rdataset_next(&rdataset))
3012 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
3013 dns_rdata_t rdata = DNS_RDATA_INIT;
3014 dns_rdata_t private = DNS_RDATA_INIT;
3016 dns_rdataset_current(&rdataset, &private);
3017 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
3020 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3021 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3022 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
3023 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
3025 result = zone_addnsec3chain(zone, &nsec3param);
3026 if (result != ISC_R_SUCCESS) {
3027 dns_zone_log(zone, ISC_LOG_ERROR,
3028 "zone_addnsec3chain failed: %s",
3029 dns_result_totext(result));
3033 dns_rdataset_disassociate(&rdataset);
3037 dns_db_detachnode(db, &node);
3038 if (version != NULL)
3039 dns_db_closeversion(db, &version, ISC_FALSE);
3045 set_resigntime(dns_zone_t *zone) {
3046 dns_rdataset_t rdataset;
3047 dns_fixedname_t fixed;
3048 unsigned int resign;
3049 isc_result_t result;
3050 isc_uint32_t nanosecs;
3051 dns_db_t *db = NULL;
3053 dns_rdataset_init(&rdataset);
3054 dns_fixedname_init(&fixed);
3056 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3057 if (zone->db != NULL)
3058 dns_db_attach(zone->db, &db);
3059 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3061 isc_time_settoepoch(&zone->resigntime);
3065 result = dns_db_getsigningtime(db, &rdataset,
3066 dns_fixedname_name(&fixed));
3067 if (result != ISC_R_SUCCESS) {
3068 isc_time_settoepoch(&zone->resigntime);
3072 resign = rdataset.resign - zone->sigresigninginterval;
3073 dns_rdataset_disassociate(&rdataset);
3074 isc_random_get(&nanosecs);
3075 nanosecs %= 1000000000;
3076 isc_time_set(&zone->resigntime, resign, nanosecs);
3083 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
3084 dns_dbnode_t *node = NULL;
3085 dns_rdataset_t rdataset;
3086 dns_dbversion_t *version = NULL;
3087 dns_rdata_nsec3param_t nsec3param;
3088 isc_boolean_t ok = ISC_FALSE;
3089 isc_result_t result;
3090 dns_rdata_t rdata = DNS_RDATA_INIT;
3091 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
3092 dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE;
3094 dns_rdataset_init(&rdataset);
3095 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3096 if (result != ISC_R_SUCCESS) {
3097 dns_zone_log(zone, ISC_LOG_ERROR,
3098 "nsec3param lookup failure: %s",
3099 dns_result_totext(result));
3102 dns_db_currentversion(db, &version);
3104 result = dns_db_findrdataset(db, node, version,
3105 dns_rdatatype_nsec3param,
3106 dns_rdatatype_none, 0, &rdataset, NULL);
3107 if (result == ISC_R_NOTFOUND) {
3108 INSIST(!dns_rdataset_isassociated(&rdataset));
3109 result = ISC_R_SUCCESS;
3112 if (result != ISC_R_SUCCESS) {
3113 INSIST(!dns_rdataset_isassociated(&rdataset));
3114 dns_zone_log(zone, ISC_LOG_ERROR,
3115 "nsec3param lookup failure: %s",
3116 dns_result_totext(result));
3121 * For dynamic zones we must support every algorithm so we can
3122 * regenerate all the NSEC3 chains.
3123 * For non-dynamic zones we only need to find a supported algorithm.
3125 for (result = dns_rdataset_first(&rdataset);
3126 result == ISC_R_SUCCESS;
3127 result = dns_rdataset_next(&rdataset))
3129 dns_rdataset_current(&rdataset, &rdata);
3130 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3131 dns_rdata_reset(&rdata);
3132 INSIST(result == ISC_R_SUCCESS);
3133 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
3134 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
3136 dns_zone_log(zone, ISC_LOG_WARNING,
3137 "nsec3 test \"unknown\" hash algorithm found: %u",
3140 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
3142 dns_zone_log(zone, ISC_LOG_ERROR,
3143 "unsupported nsec3 hash algorithm"
3144 " in dynamic zone: %u",
3146 result = DNS_R_BADZONE;
3147 /* Stop second error message. */
3151 dns_zone_log(zone, ISC_LOG_WARNING,
3152 "unsupported nsec3 hash algorithm: %u",
3157 if (result == ISC_R_NOMORE)
3158 result = ISC_R_SUCCESS;
3161 result = DNS_R_BADZONE;
3162 dns_zone_log(zone, ISC_LOG_ERROR,
3163 "no supported nsec3 hash algorithm");
3167 if (dns_rdataset_isassociated(&rdataset))
3168 dns_rdataset_disassociate(&rdataset);
3169 dns_db_closeversion(db, &version, ISC_FALSE);
3170 dns_db_detachnode(db, &node);
3175 * Set the timer for refreshing the key zone to the soonest future time
3176 * of the set (current timer, keydata->refresh, keydata->addhd,
3177 * keydata->removehd).
3180 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
3183 const char me[] = "set_refreshkeytimer";
3185 isc_time_t timenow, timethen;
3189 then = key->refresh;
3190 if (key->addhd > now && key->addhd < then)
3192 if (key->removehd > now && key->removehd < then)
3193 then = key->removehd;
3197 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
3200 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
3201 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
3202 zone->refreshkeytime = timethen;
3204 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
3205 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
3206 zone_settimer(zone, &timenow);
3210 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
3211 * If the key zone is changed, set '*changed' to ISC_TRUE.
3214 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3215 dns_diff_t *diff, dns_keytable_t *keytable,
3216 dns_keynode_t **keynodep, isc_boolean_t *changed)
3218 const char me[] = "create_keydata";
3219 isc_result_t result = ISC_R_SUCCESS;
3220 isc_buffer_t keyb, dstb;
3221 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
3222 dns_rdata_keydata_t keydata;
3223 dns_rdata_dnskey_t dnskey;
3224 dns_rdata_t rdata = DNS_RDATA_INIT;
3225 dns_keynode_t *keynode;
3230 REQUIRE(keynodep != NULL);
3231 keynode = *keynodep;
3234 isc_stdtime_get(&now);
3236 /* Loop in case there's more than one key. */
3237 while (result == ISC_R_SUCCESS) {
3238 dns_keynode_t *nextnode = NULL;
3240 key = dns_keynode_key(keynode);
3244 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
3245 CHECK(dst_key_todns(key, &dstb));
3247 /* Convert DST key to DNSKEY. */
3248 dns_rdata_reset(&rdata);
3249 isc_buffer_usedregion(&dstb, &r);
3250 dns_rdata_fromregion(&rdata, dst_key_class(key),
3251 dns_rdatatype_dnskey, &r);
3253 /* DSTKEY to KEYDATA. */
3254 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3255 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
3258 /* KEYDATA to rdata. */
3259 dns_rdata_reset(&rdata);
3260 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
3261 CHECK(dns_rdata_fromstruct(&rdata,
3262 zone->rdclass, dns_rdatatype_keydata,
3265 /* Add rdata to zone. */
3266 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
3267 dst_key_name(key), 0, &rdata));
3268 *changed = ISC_TRUE;
3269 /* Refresh new keys from the zone apex as soon as possible. */
3270 set_refreshkeytimer(zone, &keydata, now);
3273 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
3274 if (result != ISC_R_NOTFOUND) {
3275 dns_keytable_detachkeynode(keytable, &keynode);
3280 if (keynode != NULL)
3281 dns_keytable_detachkeynode(keytable, &keynode);
3284 return (ISC_R_SUCCESS);
3291 * Remove from the key zone all the KEYDATA records found in rdataset.
3294 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3295 dns_name_t *name, dns_rdataset_t *rdataset)
3297 dns_rdata_t rdata = DNS_RDATA_INIT;
3298 isc_result_t result, uresult;
3300 for (result = dns_rdataset_first(rdataset);
3301 result == ISC_R_SUCCESS;
3302 result = dns_rdataset_next(rdataset)) {
3303 dns_rdata_reset(&rdata);
3304 dns_rdataset_current(rdataset, &rdata);
3305 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3307 if (uresult != ISC_R_SUCCESS)
3310 if (result == ISC_R_NOMORE)
3311 result = ISC_R_SUCCESS;
3316 * Compute the DNSSEC key ID for a DNSKEY record.
3319 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
3322 isc_result_t result;
3323 dns_rdata_t rdata = DNS_RDATA_INIT;
3324 unsigned char data[4096];
3325 isc_buffer_t buffer;
3326 dst_key_t *dstkey = NULL;
3328 isc_buffer_init(&buffer, data, sizeof(data));
3329 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3330 dns_rdatatype_dnskey, dnskey, &buffer);
3332 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
3333 if (result == ISC_R_SUCCESS)
3334 *tag = dst_key_id(dstkey);
3335 dst_key_free(&dstkey);
3341 * Add key to the security roots.
3344 trust_key(dns_zone_t *zone, dns_name_t *keyname,
3345 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
3346 isc_result_t result;
3347 dns_rdata_t rdata = DNS_RDATA_INIT;
3348 unsigned char data[4096];
3349 isc_buffer_t buffer;
3350 dns_keytable_t *sr = NULL;
3351 dst_key_t *dstkey = NULL;
3353 /* Convert dnskey to DST key. */
3354 isc_buffer_init(&buffer, data, sizeof(data));
3355 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3356 dns_rdatatype_dnskey, dnskey, &buffer);
3358 result = dns_view_getsecroots(zone->view, &sr);
3359 if (result != ISC_R_SUCCESS)
3362 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
3363 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
3364 dns_keytable_detach(&sr);
3368 dst_key_free(&dstkey);
3370 dns_keytable_detach(&sr);
3375 * Add a null key to the security roots for so that all queries
3376 * to the zone will fail.
3379 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
3380 isc_result_t result;
3381 dns_keytable_t *sr = NULL;
3383 result = dns_view_getsecroots(zone->view, &sr);
3384 if (result == ISC_R_SUCCESS) {
3385 dns_keytable_marksecure(sr, keyname);
3386 dns_keytable_detach(&sr);
3391 * Scan a set of KEYDATA records from the key zone. The ones that are
3392 * valid (i.e., the add holddown timer has expired) become trusted keys.
3395 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
3396 isc_result_t result;
3397 dns_rdata_t rdata = DNS_RDATA_INIT;
3398 dns_rdata_keydata_t keydata;
3399 dns_rdata_dnskey_t dnskey;
3400 isc_mem_t *mctx = zone->mctx;
3401 int trusted = 0, revoked = 0, pending = 0;
3403 dns_keytable_t *sr = NULL;
3405 isc_stdtime_get(&now);
3407 result = dns_view_getsecroots(zone->view, &sr);
3408 if (result == ISC_R_SUCCESS) {
3409 dns_keytable_delete(sr, name);
3410 dns_keytable_detach(&sr);
3413 /* Now insert all the accepted trust anchors from this keydata set. */
3414 for (result = dns_rdataset_first(rdataset);
3415 result == ISC_R_SUCCESS;
3416 result = dns_rdataset_next(rdataset)) {
3417 dns_rdata_reset(&rdata);
3418 dns_rdataset_current(rdataset, &rdata);
3420 /* Convert rdata to keydata. */
3421 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
3422 if (result == ISC_R_UNEXPECTEDEND)
3424 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3426 /* Set the key refresh timer. */
3427 set_refreshkeytimer(zone, &keydata, now);
3429 /* If the removal timer is nonzero, this key was revoked. */
3430 if (keydata.removehd != 0) {
3436 * If the add timer is still pending, this key is not
3439 if (now < keydata.addhd) {
3444 /* Convert keydata to dnskey. */
3445 dns_keydata_todnskey(&keydata, &dnskey, NULL);
3447 /* Add to keytables. */
3449 trust_key(zone, name, &dnskey, mctx);
3452 if (trusted == 0 && pending != 0) {
3453 char namebuf[DNS_NAME_FORMATSIZE];
3454 dns_name_format(name, namebuf, sizeof namebuf);
3455 dns_zone_log(zone, ISC_LOG_ERROR,
3456 "No valid trust anchors for '%s'!", namebuf);
3457 dns_zone_log(zone, ISC_LOG_ERROR,
3458 "%d key(s) revoked, %d still pending",
3460 dns_zone_log(zone, ISC_LOG_ERROR,
3461 "All queries to '%s' will fail", namebuf);
3462 fail_secure(zone, name);
3467 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3470 dns_diff_t temp_diff;
3471 isc_result_t result;
3474 * Create a singleton diff.
3476 dns_diff_init(diff->mctx, &temp_diff);
3477 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3480 * Apply it to the database.
3482 result = dns_diff_apply(&temp_diff, db, ver);
3483 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3484 if (result != ISC_R_SUCCESS) {
3485 dns_difftuple_free(tuple);
3490 * Merge it into the current pending journal entry.
3492 dns_diff_appendminimal(diff, tuple);
3495 * Do not clear temp_diff.
3497 return (ISC_R_SUCCESS);
3501 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3502 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3505 dns_difftuple_t *tuple = NULL;
3506 isc_result_t result;
3507 result = dns_difftuple_create(diff->mctx, op,
3508 name, ttl, rdata, &tuple);
3509 if (result != ISC_R_SUCCESS)
3511 return (do_one_tuple(&tuple, db, ver, diff));
3515 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3516 isc_mem_t *mctx, dns_updatemethod_t method) {
3517 dns_difftuple_t *deltuple = NULL;
3518 dns_difftuple_t *addtuple = NULL;
3519 isc_uint32_t serial;
3520 isc_result_t result;
3522 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3523 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3524 addtuple->op = DNS_DIFFOP_ADD;
3526 serial = dns_soa_getserial(&addtuple->rdata);
3527 serial = dns_update_soaserial(serial, method);
3528 dns_soa_setserial(serial, &addtuple->rdata);
3529 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3530 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3531 result = ISC_R_SUCCESS;
3534 if (addtuple != NULL)
3535 dns_difftuple_free(&addtuple);
3536 if (deltuple != NULL)
3537 dns_difftuple_free(&deltuple);
3542 * Write all transactions in 'diff' to the zone journal file.
3545 zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
3548 const char me[] = "zone_journal";
3549 const char *journalfile;
3550 isc_result_t result = ISC_R_SUCCESS;
3551 dns_journal_t *journal = NULL;
3552 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
3555 journalfile = dns_zone_getjournal(zone);
3556 if (journalfile != NULL) {
3557 result = dns_journal_open(zone->mctx, journalfile, mode,
3559 if (result != ISC_R_SUCCESS) {
3560 dns_zone_log(zone, ISC_LOG_ERROR,
3561 "%s:dns_journal_open -> %s",
3562 caller, dns_result_totext(result));
3566 if (sourceserial != NULL)
3567 dns_journal_set_sourceserial(journal, *sourceserial);
3569 result = dns_journal_write_transaction(journal, diff);
3570 if (result != ISC_R_SUCCESS) {
3571 dns_zone_log(zone, ISC_LOG_ERROR,
3572 "%s:dns_journal_write_transaction -> %s",
3573 caller, dns_result_totext(result));
3575 dns_journal_destroy(&journal);
3582 * Create an SOA record for a newly-created zone
3585 add_soa(dns_zone_t *zone, dns_db_t *db) {
3586 isc_result_t result;
3587 dns_rdata_t rdata = DNS_RDATA_INIT;
3588 unsigned char buf[DNS_SOA_BUFFERSIZE];
3589 dns_dbversion_t *ver = NULL;
3592 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
3594 dns_diff_init(zone->mctx, &diff);
3595 result = dns_db_newversion(db, &ver);
3596 if (result != ISC_R_SUCCESS) {
3597 dns_zone_log(zone, ISC_LOG_ERROR,
3598 "add_soa:dns_db_newversion -> %s",
3599 dns_result_totext(result));
3603 /* Build SOA record */
3604 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
3605 0, 0, 0, 0, 0, buf, &rdata);
3606 if (result != ISC_R_SUCCESS) {
3607 dns_zone_log(zone, ISC_LOG_ERROR,
3608 "add_soa:dns_soa_buildrdata -> %s",
3609 dns_result_totext(result));
3613 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
3614 &zone->origin, 0, &rdata);
3617 dns_diff_clear(&diff);
3619 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
3625 * Synchronize the set of initializing keys found in managed-keys {}
3626 * statements with the set of trust anchors found in the managed-keys.bind
3627 * zone. If a domain is no longer named in managed-keys, delete all keys
3628 * from that domain from the key zone. If a domain is mentioned in in
3629 * managed-keys but there are no references to it in the key zone, load
3630 * the key zone with the initializing key(s) for that domain.
3633 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
3634 isc_result_t result = ISC_R_SUCCESS;
3635 isc_boolean_t changed = ISC_FALSE;
3636 isc_boolean_t commit = ISC_FALSE;
3637 dns_rbtnodechain_t chain;
3639 dns_name_t foundname, *origin;
3640 dns_keynode_t *keynode = NULL;
3641 dns_view_t *view = zone->view;
3642 dns_keytable_t *sr = NULL;
3643 dns_dbversion_t *ver = NULL;
3645 dns_rriterator_t rrit;
3647 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3649 dns_name_init(&foundname, NULL);
3650 dns_fixedname_init(&fn);
3651 origin = dns_fixedname_name(&fn);
3653 dns_diff_init(zone->mctx, &diff);
3655 CHECK(dns_view_getsecroots(view, &sr));
3657 result = dns_db_newversion(db, &ver);
3658 if (result != ISC_R_SUCCESS) {
3659 dns_zone_log(zone, ISC_LOG_ERROR,
3660 "sync_keyzone:dns_db_newversion -> %s",
3661 dns_result_totext(result));
3666 * Walk the zone DB. If we find any keys whose names are no longer
3667 * in managed-keys (or *are* in trusted-keys, meaning they are
3668 * permanent and not RFC5011-maintained), delete them from the
3669 * zone. Otherwise call load_secroots(), which loads keys into
3670 * secroots as appropriate.
3672 dns_rriterator_init(&rrit, db, ver, 0);
3673 for (result = dns_rriterator_first(&rrit);
3674 result == ISC_R_SUCCESS;
3675 result = dns_rriterator_nextrrset(&rrit)) {
3676 dns_rdataset_t *rdataset = NULL;
3677 dns_name_t *rrname = NULL;
3680 dns_rriterator_current(&rrit, &rrname, &ttl,
3682 if (!dns_rdataset_isassociated(rdataset)) {
3683 dns_rriterator_destroy(&rrit);
3687 if (rdataset->type != dns_rdatatype_keydata)
3690 result = dns_keytable_find(sr, rrname, &keynode);
3691 if ((result != ISC_R_SUCCESS &&
3692 result != DNS_R_PARTIALMATCH) ||
3693 dns_keynode_managed(keynode) == ISC_FALSE) {
3694 CHECK(delete_keydata(db, ver, &diff,
3698 load_secroots(zone, rrname, rdataset);
3701 if (keynode != NULL)
3702 dns_keytable_detachkeynode(sr, &keynode);
3704 dns_rriterator_destroy(&rrit);
3707 * Now walk secroots to find any managed keys that aren't
3708 * in the zone. If we find any, we add them to the zone.
3710 RWLOCK(&sr->rwlock, isc_rwlocktype_write);
3711 dns_rbtnodechain_init(&chain, zone->mctx);
3712 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
3713 if (result == ISC_R_NOTFOUND)
3714 result = ISC_R_NOMORE;
3715 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
3716 dns_rbtnode_t *rbtnode = NULL;
3718 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
3719 if (rbtnode->data == NULL)
3722 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
3723 if (dns_keynode_managed(keynode)) {
3724 dns_fixedname_t fname;
3725 dns_name_t *keyname;
3728 key = dns_keynode_key(keynode);
3729 dns_fixedname_init(&fname);
3731 if (key == NULL) /* fail_secure() was called. */
3734 keyname = dst_key_name(key);
3735 result = dns_db_find(db, keyname, ver,
3736 dns_rdatatype_keydata,
3737 DNS_DBFIND_NOWILD, 0, NULL,
3738 dns_fixedname_name(&fname),
3740 if (result != ISC_R_SUCCESS)
3741 result = create_keydata(zone, db, ver, &diff,
3742 sr, &keynode, &changed);
3743 if (result != ISC_R_SUCCESS)
3747 result = dns_rbtnodechain_next(&chain, &foundname, origin);
3748 if (keynode != NULL)
3749 dns_keytable_detachkeynode(sr, &keynode);
3751 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
3753 if (result == ISC_R_NOMORE)
3754 result = ISC_R_SUCCESS;
3757 /* Write changes to journal file. */
3758 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
3759 zone->updatemethod));
3760 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
3762 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
3763 zone_needdump(zone, 30);
3768 if (result != ISC_R_SUCCESS &&
3769 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3770 dns_zone_log(zone, ISC_LOG_ERROR,
3771 "unable to synchronize managed keys: %s",
3772 dns_result_totext(result));
3773 isc_time_settoepoch(&zone->refreshkeytime);
3775 if (keynode != NULL)
3776 dns_keytable_detachkeynode(sr, &keynode);
3778 dns_keytable_detach(&sr);
3780 dns_db_closeversion(db, &ver, commit);
3781 dns_diff_clear(&diff);
3787 dns_zone_synckeyzone(dns_zone_t *zone) {
3788 isc_result_t result;
3789 dns_db_t *db = NULL;
3791 if (zone->type != dns_zone_key)
3792 return (DNS_R_BADZONE);
3794 CHECK(dns_zone_getdb(zone, &db));
3797 result = sync_keyzone(zone, db);
3807 maybe_send_secure(dns_zone_t *zone) {
3808 isc_result_t result;
3811 * We've finished loading, or else failed to load, an inline-signing
3812 * 'secure' zone. We now need information about the status of the
3813 * 'raw' zone. If we failed to load, then we need it to send a
3814 * copy of its database; if we succeeded, we need it to send its
3815 * serial number so that we can sync with it. If it has not yet
3816 * loaded, we set a flag so that it will send the necessary
3817 * information when it has finished loading.
3819 if (zone->raw->db != NULL) {
3820 if (zone->db != NULL) {
3821 isc_uint32_t serial;
3822 unsigned int soacount;
3824 result = zone_get_from_db(zone->raw, zone->raw->db,
3825 NULL, &soacount, &serial, NULL,
3826 NULL, NULL, NULL, NULL);
3827 if (result == ISC_R_SUCCESS && soacount > 0U)
3828 zone_send_secureserial(zone->raw, serial);
3830 zone_send_securedb(zone->raw, zone->raw->db);
3833 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
3836 static isc_boolean_t
3837 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
3838 isc_result_t result;
3839 isc_boolean_t answer = ISC_FALSE;
3842 dns_diff_init(mctx, &diff);
3843 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
3844 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
3846 dns_diff_clear(&diff);
3851 * The zone is presumed to be locked.
3852 * If this is a inline_raw zone the secure version is also locked.
3855 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
3856 isc_result_t result)
3858 unsigned int soacount = 0;
3859 unsigned int nscount = 0;
3860 unsigned int errors = 0;
3861 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
3863 isc_boolean_t needdump = ISC_FALSE;
3864 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3865 isc_boolean_t nomaster = ISC_FALSE;
3866 unsigned int options;
3868 INSIST(LOCKED_ZONE(zone));
3869 if (inline_raw(zone))
3870 INSIST(LOCKED_ZONE(zone->secure));
3875 * Initiate zone transfer? We may need a error code that
3876 * indicates that the "permanent" form does not exist.
3877 * XXX better error feedback to log.
3879 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
3880 if (zone->type == dns_zone_slave ||
3881 zone->type == dns_zone_stub ||
3882 (zone->type == dns_zone_redirect &&
3883 zone->masters == NULL)) {
3884 if (result == ISC_R_FILENOTFOUND)
3885 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3887 else if (result != DNS_R_NOMASTERFILE)
3888 dns_zone_log(zone, ISC_LOG_ERROR,
3889 "loading from master file %s "
3892 dns_result_totext(result));
3893 } else if (zone->type == dns_zone_master &&
3894 inline_secure(zone) && result == ISC_R_FILENOTFOUND)
3896 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3897 "no master file, requesting db");
3898 maybe_send_secure(zone);
3900 int level = ISC_LOG_ERROR;
3901 if (zone->type == dns_zone_key &&
3902 result == ISC_R_FILENOTFOUND)
3903 level = ISC_LOG_DEBUG(1);
3904 dns_zone_log(zone, level,
3905 "loading from master file %s failed: %s",
3907 dns_result_totext(result));
3908 nomaster = ISC_TRUE;
3911 if (zone->type != dns_zone_key)
3915 dns_zone_log(zone, ISC_LOG_DEBUG(2),
3916 "number of nodes in database: %u",
3917 dns_db_nodecount(db));
3919 if (result == DNS_R_SEENINCLUDE)
3920 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3922 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3925 * If there's no master file for a key zone, then the zone is new:
3926 * create an SOA record. (We do this now, instead of later, so that
3927 * if there happens to be a journal file, we can roll forward from
3928 * a sane starting point.)
3930 if (nomaster && zone->type == dns_zone_key) {
3931 result = add_soa(zone, db);
3932 if (result != ISC_R_SUCCESS)
3937 * Apply update log, if any, on initial load.
3939 if (zone->journal != NULL &&
3940 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
3941 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
3943 if (zone->type == dns_zone_master &&
3944 (zone->update_acl != NULL || zone->ssutable != NULL))
3945 options = DNS_JOURNALOPT_RESIGN;
3948 result = dns_journal_rollforward2(zone->mctx, db, options,
3950 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
3951 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
3952 result != ISC_R_RANGE) {
3953 dns_zone_log(zone, ISC_LOG_ERROR,
3954 "journal rollforward failed: %s",
3955 dns_result_totext(result));
3960 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
3961 dns_zone_log(zone, ISC_LOG_ERROR,
3962 "journal rollforward failed: "
3963 "journal out of sync with zone");
3966 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3967 "journal rollforward completed "
3969 dns_result_totext(result));
3970 if (result == ISC_R_SUCCESS)
3971 needdump = ISC_TRUE;
3975 * Obtain ns, soa and cname counts for top of zone.
3978 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
3979 &refresh, &retry, &expire, &minimum,
3981 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
3982 dns_zone_log(zone, ISC_LOG_ERROR,
3983 "could not find NS and/or SOA records");
3987 * Check to make sure the journal is up to date, and remove the
3988 * journal file if it isn't, as we wouldn't be able to apply
3989 * updates otherwise.
3991 if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) &&
3992 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
3993 isc_uint32_t jserial;
3994 dns_journal_t *journal = NULL;
3996 result = dns_journal_open(zone->mctx, zone->journal,
3997 DNS_JOURNAL_READ, &journal);
3998 if (result == ISC_R_SUCCESS) {
3999 jserial = dns_journal_last_serial(journal);
4000 dns_journal_destroy(&journal);
4003 result = ISC_R_SUCCESS;
4006 if (jserial != serial) {
4007 dns_zone_log(zone, ISC_LOG_INFO,
4008 "journal file is out of date: "
4009 "removing journal file");
4010 if (remove(zone->journal) < 0 && errno != ENOENT) {
4011 char strbuf[ISC_STRERRORSIZE];
4012 isc__strerror(errno, strbuf, sizeof(strbuf));
4013 isc_log_write(dns_lctx,
4014 DNS_LOGCATEGORY_GENERAL,
4017 "unable to remove journal "
4019 zone->journal, strbuf);
4024 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
4027 * Master / Slave / Stub zones require both NS and SOA records at
4028 * the top of the zone.
4031 switch (zone->type) {
4033 case dns_zone_master:
4034 case dns_zone_slave:
4036 case dns_zone_redirect:
4037 if (soacount != 1) {
4038 dns_zone_log(zone, ISC_LOG_ERROR,
4039 "has %d SOA records", soacount);
4040 result = DNS_R_BADZONE;
4043 dns_zone_log(zone, ISC_LOG_ERROR,
4044 "has no NS records");
4045 result = DNS_R_BADZONE;
4047 if (result != ISC_R_SUCCESS)
4049 if (zone->type == dns_zone_master && errors != 0) {
4050 result = DNS_R_BADZONE;
4053 if (zone->type != dns_zone_stub &&
4054 zone->type != dns_zone_redirect) {
4055 result = check_nsec3param(zone, db);
4056 if (result != ISC_R_SUCCESS)
4059 if (zone->type == dns_zone_master &&
4060 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
4061 !integrity_checks(zone, db)) {
4062 result = DNS_R_BADZONE;
4065 if (zone->type == dns_zone_master &&
4066 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
4067 !zone_check_dup(zone, db)) {
4068 result = DNS_R_BADZONE;
4072 if (zone->db != NULL) {
4073 unsigned int oldsoacount;
4076 * This is checked in zone_replacedb() for slave zones
4077 * as they don't reload from disk.
4079 result = zone_get_from_db(zone, zone->db, NULL,
4080 &oldsoacount, &oldserial,
4081 NULL, NULL, NULL, NULL,
4083 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4084 RUNTIME_CHECK(soacount > 0U);
4085 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
4086 !isc_serial_gt(serial, oldserial)) {
4087 isc_uint32_t serialmin, serialmax;
4089 INSIST(zone->type == dns_zone_master);
4091 if (serial == oldserial &&
4092 zone_unchanged(zone->db, db, zone->mctx)) {
4093 dns_zone_log(zone, ISC_LOG_INFO,
4094 "ixfr-from-differences: "
4096 return(ISC_R_SUCCESS);
4099 serialmin = (oldserial + 1) & 0xffffffffU;
4100 serialmax = (oldserial + 0x7fffffffU) &
4102 dns_zone_log(zone, ISC_LOG_ERROR,
4103 "ixfr-from-differences: "
4104 "new serial (%u) out of range "
4105 "[%u - %u]", serial, serialmin,
4107 result = DNS_R_BADZONE;
4109 } else if (!isc_serial_ge(serial, oldserial))
4110 dns_zone_log(zone, ISC_LOG_ERROR,
4111 "zone serial (%u/%u) has gone "
4112 "backwards", serial, oldserial);
4113 else if (serial == oldserial && !hasinclude &&
4114 strcmp(zone->db_argv[0], "_builtin") != 0)
4115 dns_zone_log(zone, ISC_LOG_ERROR,
4116 "zone serial (%u) unchanged. "
4117 "zone may fail to transfer "
4118 "to slaves.", serial);
4121 if (zone->type == dns_zone_master &&
4122 (zone->update_acl != NULL || zone->ssutable != NULL) &&
4123 zone->sigresigninginterval < (3 * refresh) &&
4124 dns_db_issecure(db))
4126 dns_zone_log(zone, ISC_LOG_WARNING,
4127 "sig-re-signing-interval less than "
4131 zone->refresh = RANGE(refresh,
4132 zone->minrefresh, zone->maxrefresh);
4133 zone->retry = RANGE(retry,
4134 zone->minretry, zone->maxretry);
4135 zone->expire = RANGE(expire, zone->refresh + zone->retry,
4137 zone->minimum = minimum;
4138 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
4140 if (zone->type == dns_zone_slave ||
4141 zone->type == dns_zone_stub ||
4142 (zone->type == dns_zone_redirect &&
4143 zone->masters != NULL)) {
4147 result = isc_file_getmodtime(zone->journal, &t);
4148 if (result != ISC_R_SUCCESS)
4149 result = isc_file_getmodtime(zone->masterfile,
4151 if (result == ISC_R_SUCCESS)
4152 DNS_ZONE_TIME_ADD(&t, zone->expire,
4155 DNS_ZONE_TIME_ADD(&now, zone->retry,
4158 delay = isc_random_jitter(zone->retry,
4159 (zone->retry * 3) / 4);
4160 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
4161 if (isc_time_compare(&zone->refreshtime,
4162 &zone->expiretime) >= 0)
4163 zone->refreshtime = now;
4169 result = sync_keyzone(zone, db);
4170 if (result != ISC_R_SUCCESS)
4175 UNEXPECTED_ERROR(__FILE__, __LINE__,
4176 "unexpected zone type %d", zone->type);
4177 result = ISC_R_UNEXPECTED;
4182 * Check for weak DNSKEY's.
4184 if (zone->type == dns_zone_master)
4185 zone_check_dnskeys(zone, db);
4188 * Schedule DNSSEC key refresh.
4190 if (zone->type == dns_zone_master &&
4191 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
4192 zone->refreshkeytime = now;
4195 /* destroy notification example. */
4197 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
4198 DNS_EVENT_DBDESTROYED,
4199 dns_zonemgr_dbdestroyed,
4201 sizeof(isc_event_t));
4202 dns_db_ondestroy(db, zone->task, &e);
4206 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4207 if (zone->db != NULL) {
4208 result = zone_replacedb(zone, db, ISC_FALSE);
4209 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4210 if (result != ISC_R_SUCCESS)
4213 zone_attachdb(zone, db);
4214 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4215 DNS_ZONE_SETFLAG(zone,
4216 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
4217 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
4220 if (zone->secure->db == NULL)
4221 zone_send_securedb(zone, db);
4223 zone_send_secureserial(zone, serial);
4228 * Finished loading inline-signing zone; need to get status
4229 * from the raw side now.
4231 if (zone->type == dns_zone_master && inline_secure(zone))
4232 maybe_send_secure(zone);
4235 result = ISC_R_SUCCESS;
4238 if (zone->type == dns_zone_key)
4239 zone_needdump(zone, 30);
4241 zone_needdump(zone, DNS_DUMP_DELAY);
4244 if (zone->task != NULL) {
4245 if (zone->type == dns_zone_master) {
4246 set_resigntime(zone);
4247 resume_signingwithkey(zone);
4248 resume_addnsec3chain(zone);
4251 if (zone->type == dns_zone_master &&
4252 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
4253 dns_zone_isdynamic(zone, ISC_FALSE) &&
4254 dns_db_issecure(db)) {
4256 dns_fixedname_t fixed;
4257 dns_rdataset_t next;
4259 dns_rdataset_init(&next);
4260 dns_fixedname_init(&fixed);
4261 name = dns_fixedname_name(&fixed);
4263 result = dns_db_getsigningtime(db, &next, name);
4264 if (result == ISC_R_SUCCESS) {
4265 isc_stdtime_t timenow;
4266 char namebuf[DNS_NAME_FORMATSIZE];
4267 char typebuf[DNS_RDATATYPE_FORMATSIZE];
4269 isc_stdtime_get(&timenow);
4270 dns_name_format(name, namebuf, sizeof(namebuf));
4271 dns_rdatatype_format(next.covers,
4272 typebuf, sizeof(typebuf));
4273 dns_zone_log(zone, ISC_LOG_DEBUG(3),
4274 "next resign: %s/%s in %d seconds",
4276 next.resign - timenow -
4277 zone->sigresigninginterval);
4278 dns_rdataset_disassociate(&next);
4280 dns_zone_log(zone, ISC_LOG_WARNING,
4281 "signed dynamic zone has no "
4282 "resign event scheduled");
4285 zone_settimer(zone, &now);
4288 if (! dns_db_ispersistent(db))
4289 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
4290 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
4292 zone->loadtime = loadtime;
4293 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
4297 if (zone->type == dns_zone_slave ||
4298 zone->type == dns_zone_stub ||
4299 zone->type == dns_zone_key ||
4300 (zone->type == dns_zone_redirect && zone->masters != NULL)) {
4301 if (zone->journal != NULL)
4302 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
4303 if (zone->masterfile != NULL)
4304 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
4306 /* Mark the zone for immediate refresh. */
4307 zone->refreshtime = now;
4308 if (zone->task != NULL)
4309 zone_settimer(zone, &now);
4310 result = ISC_R_SUCCESS;
4311 } else if (zone->type == dns_zone_master ||
4312 zone->type == dns_zone_redirect) {
4313 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND))
4314 dns_zone_log(zone, ISC_LOG_ERROR,
4315 "not loaded due to errors.");
4316 else if (zone->type == dns_zone_master)
4317 result = ISC_R_SUCCESS;
4323 static isc_boolean_t
4324 exit_check(dns_zone_t *zone) {
4325 REQUIRE(LOCKED_ZONE(zone));
4327 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) {
4329 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
4331 INSIST(isc_refcount_current(&zone->erefs) == 0);
4337 static isc_boolean_t
4338 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
4339 dns_name_t *name, isc_boolean_t logit)
4341 isc_result_t result;
4342 char namebuf[DNS_NAME_FORMATSIZE];
4343 char altbuf[DNS_NAME_FORMATSIZE];
4344 dns_fixedname_t fixed;
4345 dns_name_t *foundname;
4348 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
4351 if (zone->type == dns_zone_master)
4352 level = ISC_LOG_ERROR;
4354 level = ISC_LOG_WARNING;
4356 dns_fixedname_init(&fixed);
4357 foundname = dns_fixedname_name(&fixed);
4359 result = dns_db_find(db, name, version, dns_rdatatype_a,
4360 0, 0, NULL, foundname, NULL, NULL);
4361 if (result == ISC_R_SUCCESS)
4364 if (result == DNS_R_NXRRSET) {
4365 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
4366 0, 0, NULL, foundname, NULL, NULL);
4367 if (result == ISC_R_SUCCESS)
4371 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
4372 result == DNS_R_EMPTYNAME) {
4374 dns_name_format(name, namebuf, sizeof namebuf);
4375 dns_zone_log(zone, level, "NS '%s' has no address "
4376 "records (A or AAAA)", namebuf);
4381 if (result == DNS_R_CNAME) {
4383 dns_name_format(name, namebuf, sizeof namebuf);
4384 dns_zone_log(zone, level, "NS '%s' is a CNAME "
4385 "(illegal)", namebuf);
4390 if (result == DNS_R_DNAME) {
4392 dns_name_format(name, namebuf, sizeof namebuf);
4393 dns_name_format(foundname, altbuf, sizeof altbuf);
4394 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
4395 "'%s' (illegal)", namebuf, altbuf);
4404 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
4405 dns_dbversion_t *version, unsigned int *nscount,
4406 unsigned int *errors, isc_boolean_t logit)
4408 isc_result_t result;
4409 unsigned int count = 0;
4410 unsigned int ecount = 0;
4411 dns_rdataset_t rdataset;
4415 dns_rdataset_init(&rdataset);
4416 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
4417 dns_rdatatype_none, 0, &rdataset, NULL);
4418 if (result == ISC_R_NOTFOUND) {
4419 INSIST(!dns_rdataset_isassociated(&rdataset));
4422 if (result != ISC_R_SUCCESS) {
4423 INSIST(!dns_rdataset_isassociated(&rdataset));
4424 goto invalidate_rdataset;
4427 result = dns_rdataset_first(&rdataset);
4428 while (result == ISC_R_SUCCESS) {
4429 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
4430 (zone->type == dns_zone_master ||
4431 zone->type == dns_zone_slave)) {
4432 dns_rdata_init(&rdata);
4433 dns_rdataset_current(&rdataset, &rdata);
4434 result = dns_rdata_tostruct(&rdata, &ns, NULL);
4435 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4436 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
4437 !zone_check_ns(zone, db, version, &ns.name, logit))
4441 result = dns_rdataset_next(&rdataset);
4443 dns_rdataset_disassociate(&rdataset);
4446 if (nscount != NULL)
4451 result = ISC_R_SUCCESS;
4453 invalidate_rdataset:
4454 dns_rdataset_invalidate(&rdataset);
4460 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4461 unsigned int *soacount,
4462 isc_uint32_t *serial, isc_uint32_t *refresh,
4463 isc_uint32_t *retry, isc_uint32_t *expire,
4464 isc_uint32_t *minimum)
4466 isc_result_t result;
4468 dns_rdataset_t rdataset;
4469 dns_rdata_t rdata = DNS_RDATA_INIT;
4470 dns_rdata_soa_t soa;
4472 dns_rdataset_init(&rdataset);
4473 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
4474 dns_rdatatype_none, 0, &rdataset, NULL);
4475 if (result == ISC_R_NOTFOUND) {
4476 INSIST(!dns_rdataset_isassociated(&rdataset));
4477 if (soacount != NULL)
4481 if (refresh != NULL)
4487 if (minimum != NULL)
4489 result = ISC_R_SUCCESS;
4490 goto invalidate_rdataset;
4492 if (result != ISC_R_SUCCESS) {
4493 INSIST(!dns_rdataset_isassociated(&rdataset));
4494 goto invalidate_rdataset;
4498 result = dns_rdataset_first(&rdataset);
4499 while (result == ISC_R_SUCCESS) {
4500 dns_rdata_init(&rdata);
4501 dns_rdataset_current(&rdataset, &rdata);
4504 result = dns_rdata_tostruct(&rdata, &soa, NULL);
4505 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4508 result = dns_rdataset_next(&rdataset);
4509 dns_rdata_reset(&rdata);
4511 dns_rdataset_disassociate(&rdataset);
4513 if (soacount != NULL)
4518 *serial = soa.serial;
4519 if (refresh != NULL)
4520 *refresh = soa.refresh;
4524 *expire = soa.expire;
4525 if (minimum != NULL)
4526 *minimum = soa.minimum;
4528 if (soacount != NULL)
4532 if (refresh != NULL)
4538 if (minimum != NULL)
4542 result = ISC_R_SUCCESS;
4544 invalidate_rdataset:
4545 dns_rdataset_invalidate(&rdataset);
4551 * zone must be locked.
4554 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
4555 unsigned int *soacount, isc_uint32_t *serial,
4556 isc_uint32_t *refresh, isc_uint32_t *retry,
4557 isc_uint32_t *expire, isc_uint32_t *minimum,
4558 unsigned int *errors)
4560 isc_result_t result;
4561 isc_result_t answer = ISC_R_SUCCESS;
4562 dns_dbversion_t *version = NULL;
4565 REQUIRE(db != NULL);
4566 REQUIRE(zone != NULL);
4568 dns_db_currentversion(db, &version);
4571 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
4572 if (result != ISC_R_SUCCESS) {
4577 if (nscount != NULL || errors != NULL) {
4578 result = zone_count_ns_rr(zone, db, node, version,
4579 nscount, errors, ISC_TRUE);
4580 if (result != ISC_R_SUCCESS)
4584 if (soacount != NULL || serial != NULL || refresh != NULL
4585 || retry != NULL || expire != NULL || minimum != NULL) {
4586 result = zone_load_soa_rr(db, node, version, soacount,
4587 serial, refresh, retry, expire,
4589 if (result != ISC_R_SUCCESS)
4593 dns_db_detachnode(db, &node);
4595 dns_db_closeversion(db, &version, ISC_FALSE);
4601 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
4602 REQUIRE(DNS_ZONE_VALID(source));
4603 REQUIRE(target != NULL && *target == NULL);
4604 isc_refcount_increment(&source->erefs, NULL);
4609 dns_zone_detach(dns_zone_t **zonep) {
4611 dns_zone_t *raw = NULL;
4612 dns_zone_t *secure = NULL;
4614 isc_boolean_t free_now = ISC_FALSE;
4616 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4620 isc_refcount_decrement(&zone->erefs, &refs);
4625 * We just detached the last external reference.
4627 if (zone->task != NULL) {
4629 * This zone is being managed. Post
4630 * its control event and let it clean
4631 * up synchronously in the context of
4634 isc_event_t *ev = &zone->ctlevent;
4635 isc_task_send(zone->task, &ev);
4638 * This zone is not being managed; it has
4639 * no task and can have no outstanding
4640 * events. Free it immediately.
4643 * Unmanaged zones should not have non-null views;
4644 * we have no way of detaching from the view here
4645 * without causing deadlock because this code is called
4646 * with the view already locked.
4648 INSIST(zone->view == NULL);
4649 free_now = ISC_TRUE;
4652 secure = zone->secure;
4653 zone->secure = NULL;
4660 dns_zone_detach(&raw);
4662 dns_zone_idetach(&secure);
4668 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4669 REQUIRE(DNS_ZONE_VALID(source));
4670 REQUIRE(target != NULL && *target == NULL);
4672 zone_iattach(source, target);
4673 UNLOCK_ZONE(source);
4677 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4680 * 'source' locked by caller.
4682 REQUIRE(LOCKED_ZONE(source));
4683 REQUIRE(DNS_ZONE_VALID(source));
4684 REQUIRE(target != NULL && *target == NULL);
4685 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
4687 INSIST(source->irefs != 0);
4692 zone_idetach(dns_zone_t **zonep) {
4696 * 'zone' locked by caller.
4698 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4700 REQUIRE(LOCKED_ZONE(*zonep));
4703 INSIST(zone->irefs > 0);
4705 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
4709 dns_zone_idetach(dns_zone_t **zonep) {
4711 isc_boolean_t free_needed;
4713 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4718 INSIST(zone->irefs > 0);
4720 free_needed = exit_check(zone);
4727 dns_zone_getmctx(dns_zone_t *zone) {
4728 REQUIRE(DNS_ZONE_VALID(zone));
4730 return (zone->mctx);
4734 dns_zone_getmgr(dns_zone_t *zone) {
4735 REQUIRE(DNS_ZONE_VALID(zone));
4737 return (zone->zmgr);
4741 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
4742 REQUIRE(DNS_ZONE_VALID(zone));
4746 DNS_ZONE_SETFLAG(zone, flags);
4748 DNS_ZONE_CLRFLAG(zone, flags);
4753 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
4755 REQUIRE(DNS_ZONE_VALID(zone));
4759 zone->options |= option;
4761 zone->options &= ~option;
4766 dns_zone_getoptions(dns_zone_t *zone) {
4768 REQUIRE(DNS_ZONE_VALID(zone));
4770 return (zone->options);
4774 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
4776 REQUIRE(DNS_ZONE_VALID(zone));
4780 zone->keyopts |= keyopt;
4782 zone->keyopts &= ~keyopt;
4787 dns_zone_getkeyopts(dns_zone_t *zone) {
4789 REQUIRE(DNS_ZONE_VALID(zone));
4791 return (zone->keyopts);
4795 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4796 REQUIRE(DNS_ZONE_VALID(zone));
4799 zone->xfrsource4 = *xfrsource;
4802 return (ISC_R_SUCCESS);
4806 dns_zone_getxfrsource4(dns_zone_t *zone) {
4807 REQUIRE(DNS_ZONE_VALID(zone));
4808 return (&zone->xfrsource4);
4812 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4813 REQUIRE(DNS_ZONE_VALID(zone));
4816 zone->xfrsource6 = *xfrsource;
4819 return (ISC_R_SUCCESS);
4823 dns_zone_getxfrsource6(dns_zone_t *zone) {
4824 REQUIRE(DNS_ZONE_VALID(zone));
4825 return (&zone->xfrsource6);
4829 dns_zone_setaltxfrsource4(dns_zone_t *zone,
4830 const isc_sockaddr_t *altxfrsource)
4832 REQUIRE(DNS_ZONE_VALID(zone));
4835 zone->altxfrsource4 = *altxfrsource;
4838 return (ISC_R_SUCCESS);
4842 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
4843 REQUIRE(DNS_ZONE_VALID(zone));
4844 return (&zone->altxfrsource4);
4848 dns_zone_setaltxfrsource6(dns_zone_t *zone,
4849 const isc_sockaddr_t *altxfrsource)
4851 REQUIRE(DNS_ZONE_VALID(zone));
4854 zone->altxfrsource6 = *altxfrsource;
4857 return (ISC_R_SUCCESS);
4861 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
4862 REQUIRE(DNS_ZONE_VALID(zone));
4863 return (&zone->altxfrsource6);
4867 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4868 REQUIRE(DNS_ZONE_VALID(zone));
4871 zone->notifysrc4 = *notifysrc;
4874 return (ISC_R_SUCCESS);
4878 dns_zone_getnotifysrc4(dns_zone_t *zone) {
4879 REQUIRE(DNS_ZONE_VALID(zone));
4880 return (&zone->notifysrc4);
4884 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4885 REQUIRE(DNS_ZONE_VALID(zone));
4888 zone->notifysrc6 = *notifysrc;
4891 return (ISC_R_SUCCESS);
4895 dns_zone_getnotifysrc6(dns_zone_t *zone) {
4896 REQUIRE(DNS_ZONE_VALID(zone));
4897 return (&zone->notifysrc6);
4900 static isc_boolean_t
4901 same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
4906 for (i = 0; i < count; i++)
4907 if (!isc_sockaddr_equal(&old[i], &new[i]))
4912 static isc_boolean_t
4913 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
4916 if (old == NULL && new == NULL)
4918 if (old == NULL || new == NULL)
4921 for (i = 0; i < count; i++) {
4922 if (old[i] == NULL && new[i] == NULL)
4924 if (old[i] == NULL || new[i] == NULL ||
4925 !dns_name_equal(old[i], new[i]))
4932 clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp,
4933 unsigned int *countp, isc_mem_t *mctx)
4936 isc_sockaddr_t *addrs;
4937 dns_name_t **keynames;
4939 REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL);
4945 keynames = *keynamesp;
4949 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
4951 if (keynames != NULL) {
4953 for (i = 0; i < count; i++) {
4954 if (keynames[i] != NULL) {
4955 dns_name_free(keynames[i], mctx);
4956 isc_mem_put(mctx, keynames[i],
4957 sizeof(dns_name_t));
4961 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
4966 set_addrkeylist(unsigned int count,
4967 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
4968 dns_name_t **names, dns_name_t ***newnamesp,
4971 isc_result_t result;
4972 isc_sockaddr_t *newaddrs = NULL;
4973 dns_name_t **newnames = NULL;
4976 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
4977 REQUIRE(newnamesp != NULL && *newnamesp == NULL);
4979 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
4980 if (newaddrs == NULL)
4981 return (ISC_R_NOMEMORY);
4982 memmove(newaddrs, addrs, count * sizeof(*newaddrs));
4985 if (names != NULL) {
4986 newnames = isc_mem_get(mctx, count * sizeof(*newnames));
4987 if (newnames == NULL) {
4988 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
4989 return (ISC_R_NOMEMORY);
4991 for (i = 0; i < count; i++)
4993 for (i = 0; i < count; i++) {
4994 if (names[i] != NULL) {
4995 newnames[i] = isc_mem_get(mctx,
4996 sizeof(dns_name_t));
4997 if (newnames[i] == NULL)
4999 dns_name_init(newnames[i], NULL);
5000 result = dns_name_dup(names[i], mctx,
5002 if (result != ISC_R_SUCCESS) {
5004 for (i = 0; i < count; i++)
5005 if (newnames[i] != NULL)
5009 isc_mem_put(mctx, newaddrs,
5010 count * sizeof(*newaddrs));
5011 isc_mem_put(mctx, newnames,
5012 count * sizeof(*newnames));
5013 return (ISC_R_NOMEMORY);
5019 *newaddrsp = newaddrs;
5020 *newnamesp = newnames;
5021 return (ISC_R_SUCCESS);
5025 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
5028 return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count));
5032 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
5033 dns_name_t **keynames, isc_uint32_t count)
5035 isc_result_t result;
5036 isc_sockaddr_t *newaddrs = NULL;
5037 dns_name_t **newnames = NULL;
5039 REQUIRE(DNS_ZONE_VALID(zone));
5040 REQUIRE(count == 0 || notify != NULL);
5041 if (keynames != NULL)
5042 REQUIRE(count != 0);
5046 if (count == zone->notifycnt &&
5047 same_addrs(zone->notify, notify, count) &&
5048 same_keynames(zone->notifykeynames, keynames, count))
5051 clear_addresskeylist(&zone->notify, &zone->notifykeynames,
5052 &zone->notifycnt, zone->mctx);
5058 * Set up the notify and notifykey lists
5060 result = set_addrkeylist(count, notify, &newaddrs,
5061 keynames, &newnames, zone->mctx);
5062 if (result != ISC_R_SUCCESS)
5066 * Everything is ok so attach to the zone.
5068 zone->notify = newaddrs;
5069 zone->notifykeynames = newnames;
5070 zone->notifycnt = count;
5073 return (ISC_R_SUCCESS);
5077 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
5080 isc_result_t result;
5082 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
5087 dns_zone_setmasterswithkeys(dns_zone_t *zone,
5088 const isc_sockaddr_t *masters,
5089 dns_name_t **keynames,
5092 isc_result_t result = ISC_R_SUCCESS;
5093 isc_sockaddr_t *newaddrs = NULL;
5094 dns_name_t **newnames = NULL;
5095 isc_boolean_t *newok;
5098 REQUIRE(DNS_ZONE_VALID(zone));
5099 REQUIRE(count == 0 || masters != NULL);
5100 if (keynames != NULL) {
5101 REQUIRE(count != 0);
5106 * The refresh code assumes that 'masters' wouldn't change under it.
5107 * If it will change then kill off any current refresh in progress
5108 * and update the masters info. If it won't change then we can just
5111 if (count != zone->masterscnt ||
5112 !same_addrs(zone->masters, masters, count) ||
5113 !same_keynames(zone->masterkeynames, keynames, count)) {
5114 if (zone->request != NULL)
5115 dns_request_cancel(zone->request);
5120 * This needs to happen before clear_addresskeylist() sets
5121 * zone->masterscnt to 0:
5123 if (zone->mastersok != NULL) {
5124 isc_mem_put(zone->mctx, zone->mastersok,
5125 zone->masterscnt * sizeof(isc_boolean_t));
5126 zone->mastersok = NULL;
5128 clear_addresskeylist(&zone->masters, &zone->masterkeynames,
5129 &zone->masterscnt, zone->mctx);
5131 * If count == 0, don't allocate any space for masters, mastersok or
5132 * keynames so internally, those pointers are NULL if count == 0
5138 * mastersok must contain count elements
5140 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
5141 if (newok == NULL) {
5142 result = ISC_R_NOMEMORY;
5143 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
5146 for (i = 0; i < count; i++)
5147 newok[i] = ISC_FALSE;
5150 * Now set up the masters and masterkey lists
5152 result = set_addrkeylist(count, masters, &newaddrs,
5153 keynames, &newnames, zone->mctx);
5154 if (result != ISC_R_SUCCESS) {
5155 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
5160 * Everything is ok so attach to the zone.
5162 zone->curmaster = 0;
5163 zone->mastersok = newok;
5164 zone->masters = newaddrs;
5165 zone->masterkeynames = newnames;
5166 zone->masterscnt = count;
5167 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
5175 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
5176 isc_result_t result = ISC_R_SUCCESS;
5178 REQUIRE(DNS_ZONE_VALID(zone));
5180 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5181 if (zone->db == NULL)
5182 result = DNS_R_NOTLOADED;
5184 dns_db_attach(zone->db, dpb);
5185 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5191 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
5192 REQUIRE(DNS_ZONE_VALID(zone));
5193 REQUIRE(zone->type == dns_zone_staticstub);
5195 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
5196 REQUIRE(zone->db == NULL);
5197 dns_db_attach(db, &zone->db);
5198 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
5202 * Co-ordinates the starting of routine jobs.
5206 dns_zone_maintenance(dns_zone_t *zone) {
5207 const char me[] = "dns_zone_maintenance";
5210 REQUIRE(DNS_ZONE_VALID(zone));
5215 zone_settimer(zone, &now);
5219 static inline isc_boolean_t
5220 was_dumping(dns_zone_t *zone) {
5221 isc_boolean_t dumping;
5223 REQUIRE(LOCKED_ZONE(zone));
5225 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
5226 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
5228 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
5229 isc_time_settoepoch(&zone->dumptime);
5235 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
5236 isc_mem_t *mctx, unsigned int maxkeys,
5237 dst_key_t **keys, unsigned int *nkeys)
5239 isc_result_t result;
5240 dns_dbnode_t *node = NULL;
5241 const char *directory = dns_zone_getkeydirectory(zone);
5243 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
5244 memset(keys, 0, sizeof(*keys) * maxkeys);
5245 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
5246 directory, mctx, maxkeys, keys,
5248 if (result == ISC_R_NOTFOUND)
5249 result = ISC_R_SUCCESS;
5252 dns_db_detachnode(db, &node);
5257 offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
5258 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
5260 isc_result_t result;
5262 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
5263 return (ISC_R_SUCCESS);
5264 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
5266 if (result != ISC_R_SUCCESS)
5268 rdata->flags |= DNS_RDATA_OFFLINE;
5269 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
5271 zonediff->offline = ISC_TRUE;
5276 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
5281 zone->key_expiry = when;
5283 dns_zone_log(zone, ISC_LOG_ERROR,
5284 "DNSKEY RRSIG(s) have expired");
5285 isc_time_settoepoch(&zone->keywarntime);
5286 } else if (when < now + 7 * 24 * 3600) {
5288 isc_time_set(&t, when, 0);
5289 isc_time_formattimestamp(&t, timebuf, 80);
5290 dns_zone_log(zone, ISC_LOG_WARNING,
5291 "DNSKEY RRSIG(s) will expire within 7 days: %s",
5294 delta--; /* loop prevention */
5295 delta /= 24 * 3600; /* to whole days */
5296 delta *= 24 * 3600; /* to seconds */
5297 isc_time_set(&zone->keywarntime, when - delta, 0);
5299 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
5300 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
5301 dns_zone_log(zone, ISC_LOG_NOTICE,
5302 "setting keywarntime to %s", timebuf);
5307 * Helper function to del_sigs(). We don't want to delete RRSIGs that
5310 static isc_boolean_t
5311 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
5312 isc_boolean_t *warn)
5315 isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE;
5316 isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE;
5318 for (i = 0; i < nkeys; i++) {
5319 if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
5321 if (dst_key_isprivate(keys[i])) {
5323 have_ksk = have_pksk = ISC_TRUE;
5325 have_zsk = have_pzsk = ISC_TRUE;
5328 have_ksk = ISC_TRUE;
5330 have_zsk = ISC_TRUE;
5334 if (have_zsk && have_ksk && !have_pzsk)
5338 * It's okay to delete a signature if there is an active key
5339 * with the same algorithm to replace it.
5341 if (have_pksk || have_pzsk)
5345 * Failing that, it is *not* okay to delete a signature
5346 * if the associated public key is still in the DNSKEY RRset
5348 for (i = 0; i < nkeys; i++) {
5349 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
5350 (rrsig_ptr->keyid == dst_key_id(keys[i])))
5355 * But if the key is gone, then go ahead.
5361 * Delete expired RRsigs and any RRsigs we are about to re-sign.
5362 * See also update.c:del_keysigs().
5365 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5366 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
5367 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
5369 isc_result_t result;
5370 dns_dbnode_t *node = NULL;
5371 dns_rdataset_t rdataset;
5373 dns_rdata_rrsig_t rrsig;
5374 isc_boolean_t found, changed;
5375 isc_int64_t warn = 0, maybe = 0;
5377 dns_rdataset_init(&rdataset);
5379 if (type == dns_rdatatype_nsec3)
5380 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5382 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5383 if (result == ISC_R_NOTFOUND)
5384 return (ISC_R_SUCCESS);
5385 if (result != ISC_R_SUCCESS)
5387 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
5388 (isc_stdtime_t) 0, &rdataset, NULL);
5389 dns_db_detachnode(db, &node);
5391 if (result == ISC_R_NOTFOUND) {
5392 INSIST(!dns_rdataset_isassociated(&rdataset));
5393 return (ISC_R_SUCCESS);
5395 if (result != ISC_R_SUCCESS) {
5396 INSIST(!dns_rdataset_isassociated(&rdataset));
5400 changed = ISC_FALSE;
5401 for (result = dns_rdataset_first(&rdataset);
5402 result == ISC_R_SUCCESS;
5403 result = dns_rdataset_next(&rdataset)) {
5404 dns_rdata_t rdata = DNS_RDATA_INIT;
5406 dns_rdataset_current(&rdataset, &rdata);
5407 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5408 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5410 if (type != dns_rdatatype_dnskey) {
5411 isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE;
5412 if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
5413 result = update_one_rr(db, ver, zonediff->diff,
5414 DNS_DIFFOP_DELRESIGN, name,
5415 rdataset.ttl, &rdata);
5418 if (result != ISC_R_SUCCESS)
5424 * At this point, we've got an RRSIG,
5425 * which is signed by an inactive key.
5426 * An administrator needs to provide a new
5427 * key/alg, but until that time, we want to
5428 * keep the old RRSIG. Marking the key as
5429 * offline will prevent us spinning waiting
5430 * for the private part.
5432 if (incremental && !deleted) {
5433 result = offline(db, ver, zonediff,
5437 if (result != ISC_R_SUCCESS)
5442 * Log the key id and algorithm of
5443 * the inactive key with no replacement
5445 if (zone->log_key_expired_timer <= now) {
5446 char origin[DNS_NAME_FORMATSIZE];
5447 char algbuf[DNS_NAME_FORMATSIZE];
5448 dns_name_format(&zone->origin, origin,
5450 dns_secalg_format(rrsig.algorithm,
5453 dns_zone_log(zone, ISC_LOG_WARNING,
5455 "missing or inactive "
5456 "and has no replacement: "
5457 "retaining signatures.",
5460 zone->log_key_expired_timer = now +
5468 * RRSIG(DNSKEY) requires special processing.
5471 for (i = 0; i < nkeys; i++) {
5472 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
5473 rrsig.keyid == dst_key_id(keys[i])) {
5476 * Mark offline RRSIG(DNSKEY).
5477 * We want the earliest offline expire time
5478 * iff there is a new offline signature.
5480 if (!dst_key_inactive(keys[i]) &&
5481 !dst_key_isprivate(keys[i]))
5483 isc_int64_t timeexpire =
5484 dns_time64_from32(rrsig.timeexpire);
5485 if (warn != 0 && warn > timeexpire)
5487 if (rdata.flags & DNS_RDATA_OFFLINE) {
5495 if (warn == 0 || warn > timeexpire)
5497 result = offline(db, ver, zonediff,
5503 result = update_one_rr(db, ver, zonediff->diff,
5504 DNS_DIFFOP_DELRESIGN,
5512 * If there is not a matching DNSKEY then
5516 result = update_one_rr(db, ver, zonediff->diff,
5517 DNS_DIFFOP_DELRESIGN, name,
5518 rdataset.ttl, &rdata);
5519 if (result != ISC_R_SUCCESS)
5523 if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0)
5524 dns_db_resigned(db, &rdataset, ver);
5526 dns_rdataset_disassociate(&rdataset);
5527 if (result == ISC_R_NOMORE)
5528 result = ISC_R_SUCCESS;
5530 #if defined(STDTIME_ON_32BITS)
5531 isc_stdtime_t stdwarn = (isc_stdtime_t)warn;
5532 if (warn == stdwarn)
5534 set_key_expiry_warning(zone, (isc_stdtime_t)warn, now);
5535 #if defined(STDTIME_ON_32BITS)
5537 dns_zone_log(zone, ISC_LOG_ERROR,
5538 "key expiry warning time out of range");
5543 dns_db_detachnode(db, &node);
5548 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5549 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
5550 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
5551 isc_stdtime_t expire, isc_boolean_t check_ksk,
5552 isc_boolean_t keyset_kskonly)
5554 isc_result_t result;
5555 dns_dbnode_t *node = NULL;
5556 dns_rdataset_t rdataset;
5557 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
5558 unsigned char data[1024]; /* XXX */
5559 isc_buffer_t buffer;
5562 dns_rdataset_init(&rdataset);
5563 isc_buffer_init(&buffer, data, sizeof(data));
5565 if (type == dns_rdatatype_nsec3)
5566 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5568 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5569 if (result == ISC_R_NOTFOUND)
5570 return (ISC_R_SUCCESS);
5571 if (result != ISC_R_SUCCESS)
5573 result = dns_db_findrdataset(db, node, ver, type, 0,
5574 (isc_stdtime_t) 0, &rdataset, NULL);
5575 dns_db_detachnode(db, &node);
5576 if (result == ISC_R_NOTFOUND) {
5577 INSIST(!dns_rdataset_isassociated(&rdataset));
5578 return (ISC_R_SUCCESS);
5580 if (result != ISC_R_SUCCESS) {
5581 INSIST(!dns_rdataset_isassociated(&rdataset));
5585 for (i = 0; i < nkeys; i++) {
5586 isc_boolean_t both = ISC_FALSE;
5588 if (!dst_key_isprivate(keys[i]))
5591 if (check_ksk && !REVOKE(keys[i])) {
5592 isc_boolean_t have_ksk, have_nonksk;
5594 have_ksk = ISC_TRUE;
5595 have_nonksk = ISC_FALSE;
5597 have_ksk = ISC_FALSE;
5598 have_nonksk = ISC_TRUE;
5600 for (j = 0; j < nkeys; j++) {
5601 if (j == i || ALG(keys[i]) != ALG(keys[j]))
5603 if (REVOKE(keys[j]))
5606 have_ksk = ISC_TRUE;
5608 have_nonksk = ISC_TRUE;
5609 both = have_ksk && have_nonksk;
5615 if (type == dns_rdatatype_dnskey) {
5616 if (!KSK(keys[i]) && keyset_kskonly)
5618 } else if (KSK(keys[i]))
5620 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
5623 /* Calculate the signature, creating a RRSIG RDATA. */
5624 isc_buffer_clear(&buffer);
5625 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
5626 &inception, &expire,
5627 mctx, &buffer, &sig_rdata));
5628 /* Update the database and journal with the RRSIG. */
5629 /* XXX inefficient - will cause dataset merging */
5630 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
5631 name, rdataset.ttl, &sig_rdata));
5632 dns_rdata_reset(&sig_rdata);
5633 isc_buffer_init(&buffer, data, sizeof(data));
5637 if (dns_rdataset_isassociated(&rdataset))
5638 dns_rdataset_disassociate(&rdataset);
5640 dns_db_detachnode(db, &node);
5645 zone_resigninc(dns_zone_t *zone) {
5646 const char *me = "zone_resigninc";
5647 dns_db_t *db = NULL;
5648 dns_dbversion_t *version = NULL;
5649 dns_diff_t _sig_diff;
5650 zonediff_t zonediff;
5651 dns_fixedname_t fixed;
5653 dns_rdataset_t rdataset;
5654 dns_rdatatype_t covers;
5655 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
5656 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
5657 isc_result_t result;
5658 isc_stdtime_t now, inception, soaexpire, expire, stop;
5659 isc_uint32_t jitter;
5661 unsigned int nkeys = 0;
5662 unsigned int resign;
5666 dns_rdataset_init(&rdataset);
5667 dns_fixedname_init(&fixed);
5668 dns_diff_init(zone->mctx, &_sig_diff);
5669 zonediff_init(&zonediff, &_sig_diff);
5672 * Zone is frozen or automatic resigning is disabled.
5673 * Pause for 5 minutes.
5675 if (zone->update_disabled ||
5676 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
5678 result = ISC_R_FAILURE;
5682 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5683 dns_db_attach(zone->db, &db);
5684 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5686 result = dns_db_newversion(db, &version);
5687 if (result != ISC_R_SUCCESS) {
5688 dns_zone_log(zone, ISC_LOG_ERROR,
5689 "zone_resigninc:dns_db_newversion -> %s",
5690 dns_result_totext(result));
5694 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
5696 if (result != ISC_R_SUCCESS) {
5697 dns_zone_log(zone, ISC_LOG_ERROR,
5698 "zone_resigninc:find_zone_keys -> %s",
5699 dns_result_totext(result));
5703 isc_stdtime_get(&now);
5704 inception = now - 3600; /* Allow for clock skew. */
5705 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5707 * Spread out signatures over time if they happen to be
5708 * clumped. We don't do this for each add_sigs() call as
5709 * we still want some clustering to occur.
5711 isc_random_get(&jitter);
5712 expire = soaexpire - jitter % 3600;
5715 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5716 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
5718 name = dns_fixedname_name(&fixed);
5719 result = dns_db_getsigningtime(db, &rdataset, name);
5720 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
5721 dns_zone_log(zone, ISC_LOG_ERROR,
5722 "zone_resigninc:dns_db_getsigningtime -> %s",
5723 dns_result_totext(result));
5727 while (result == ISC_R_SUCCESS) {
5728 resign = rdataset.resign - zone->sigresigninginterval;
5729 covers = rdataset.covers;
5730 dns_rdataset_disassociate(&rdataset);
5733 * Stop if we hit the SOA as that means we have walked the
5734 * entire zone. The SOA record should always be the most
5737 /* XXXMPA increase number of RRsets signed pre call */
5738 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
5742 result = del_sigs(zone, db, version, name, covers, &zonediff,
5743 zone_keys, nkeys, now, ISC_TRUE);
5744 if (result != ISC_R_SUCCESS) {
5745 dns_zone_log(zone, ISC_LOG_ERROR,
5746 "zone_resigninc:del_sigs -> %s",
5747 dns_result_totext(result));
5751 result = add_sigs(db, version, name, covers, zonediff.diff,
5752 zone_keys, nkeys, zone->mctx, inception,
5753 expire, check_ksk, keyset_kskonly);
5754 if (result != ISC_R_SUCCESS) {
5755 dns_zone_log(zone, ISC_LOG_ERROR,
5756 "zone_resigninc:add_sigs -> %s",
5757 dns_result_totext(result));
5760 result = dns_db_getsigningtime(db, &rdataset,
5761 dns_fixedname_name(&fixed));
5762 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
5763 result = ISC_R_SUCCESS;
5766 if (result != ISC_R_SUCCESS)
5767 dns_zone_log(zone, ISC_LOG_ERROR,
5768 "zone_resigninc:dns_db_getsigningtime -> %s",
5769 dns_result_totext(result));
5772 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
5775 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5776 &zonediff, zone_keys, nkeys, now, ISC_TRUE);
5777 if (result != ISC_R_SUCCESS) {
5778 dns_zone_log(zone, ISC_LOG_ERROR,
5779 "zone_resigninc:del_sigs -> %s",
5780 dns_result_totext(result));
5785 * Did we change anything in the zone?
5787 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
5789 * Commit the changes if any key has been marked as offline. */
5790 if (zonediff.offline)
5791 dns_db_closeversion(db, &version, ISC_TRUE);
5795 /* Increment SOA serial if we have made changes */
5796 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
5797 zone->updatemethod);
5798 if (result != ISC_R_SUCCESS) {
5799 dns_zone_log(zone, ISC_LOG_ERROR,
5800 "zone_resigninc:update_soa_serial -> %s",
5801 dns_result_totext(result));
5806 * Generate maximum life time signatures so that the above loop
5807 * termination is sensible.
5809 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5810 zonediff.diff, zone_keys, nkeys, zone->mctx,
5811 inception, soaexpire, check_ksk, keyset_kskonly);
5812 if (result != ISC_R_SUCCESS) {
5813 dns_zone_log(zone, ISC_LOG_ERROR,
5814 "zone_resigninc:add_sigs -> %s",
5815 dns_result_totext(result));
5819 /* Write changes to journal file. */
5820 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
5822 /* Everything has succeeded. Commit the changes. */
5823 dns_db_closeversion(db, &version, ISC_TRUE);
5826 dns_diff_clear(&_sig_diff);
5827 for (i = 0; i < nkeys; i++)
5828 dst_key_free(&zone_keys[i]);
5829 if (version != NULL) {
5830 dns_db_closeversion(zone->db, &version, ISC_FALSE);
5832 } else if (db != NULL)
5834 if (result == ISC_R_SUCCESS) {
5835 set_resigntime(zone);
5837 zone_needdump(zone, DNS_DUMP_DELAY);
5838 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5842 * Something failed. Retry in 5 minutes.
5844 isc_interval_t ival;
5845 isc_interval_set(&ival, 300, 0);
5846 isc_time_nowplusinterval(&zone->resigntime, &ival);
5851 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
5852 dns_name_t *newname, isc_boolean_t bottom)
5854 isc_result_t result;
5855 dns_dbiterator_t *dbit = NULL;
5856 dns_rdatasetiter_t *rdsit = NULL;
5857 dns_dbnode_t *node = NULL;
5859 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
5860 CHECK(dns_dbiterator_seek(dbit, oldname));
5862 result = dns_dbiterator_next(dbit);
5863 if (result == ISC_R_NOMORE)
5864 CHECK(dns_dbiterator_first(dbit));
5865 CHECK(dns_dbiterator_current(dbit, &node, newname));
5866 if (bottom && dns_name_issubdomain(newname, oldname) &&
5867 !dns_name_equal(newname, oldname)) {
5868 dns_db_detachnode(db, &node);
5872 * Is this node empty?
5874 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
5875 result = dns_rdatasetiter_first(rdsit);
5876 dns_db_detachnode(db, &node);
5877 dns_rdatasetiter_destroy(&rdsit);
5878 if (result != ISC_R_NOMORE)
5883 dns_db_detachnode(db, &node);
5885 dns_dbiterator_destroy(&dbit);
5889 static isc_boolean_t
5890 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5891 dns_rdatatype_t type, dst_key_t *key)
5893 isc_result_t result;
5894 dns_rdataset_t rdataset;
5895 dns_rdata_t rdata = DNS_RDATA_INIT;
5896 dns_rdata_rrsig_t rrsig;
5898 dns_rdataset_init(&rdataset);
5899 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
5900 type, 0, &rdataset, NULL);
5901 if (result != ISC_R_SUCCESS) {
5902 INSIST(!dns_rdataset_isassociated(&rdataset));
5905 for (result = dns_rdataset_first(&rdataset);
5906 result == ISC_R_SUCCESS;
5907 result = dns_rdataset_next(&rdataset)) {
5908 dns_rdataset_current(&rdataset, &rdata);
5909 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5910 INSIST(result == ISC_R_SUCCESS);
5911 if (rrsig.algorithm == dst_key_alg(key) &&
5912 rrsig.keyid == dst_key_id(key)) {
5913 dns_rdataset_disassociate(&rdataset);
5916 dns_rdata_reset(&rdata);
5918 dns_rdataset_disassociate(&rdataset);
5923 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5924 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
5927 dns_fixedname_t fixed;
5929 dns_rdata_t rdata = DNS_RDATA_INIT;
5930 isc_result_t result;
5931 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
5933 dns_fixedname_init(&fixed);
5934 next = dns_fixedname_name(&fixed);
5936 CHECK(next_active(db, version, name, next, bottom));
5937 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
5939 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
5946 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
5947 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5948 isc_boolean_t build_nsec, dst_key_t *key,
5949 isc_stdtime_t inception, isc_stdtime_t expire,
5950 unsigned int minimum, isc_boolean_t is_ksk,
5951 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
5952 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
5954 isc_result_t result;
5955 dns_rdatasetiter_t *iterator = NULL;
5956 dns_rdataset_t rdataset;
5957 dns_rdata_t rdata = DNS_RDATA_INIT;
5958 isc_buffer_t buffer;
5959 unsigned char data[1024];
5960 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
5961 seen_nsec3, seen_ds;
5962 isc_boolean_t bottom;
5964 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5965 if (result != ISC_R_SUCCESS) {
5966 if (result == ISC_R_NOTFOUND)
5967 result = ISC_R_SUCCESS;
5971 dns_rdataset_init(&rdataset);
5972 isc_buffer_init(&buffer, data, sizeof(data));
5973 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
5974 seen_nsec3 = seen_ds = ISC_FALSE;
5975 for (result = dns_rdatasetiter_first(iterator);
5976 result == ISC_R_SUCCESS;
5977 result = dns_rdatasetiter_next(iterator)) {
5978 dns_rdatasetiter_current(iterator, &rdataset);
5979 if (rdataset.type == dns_rdatatype_soa)
5980 seen_soa = ISC_TRUE;
5981 else if (rdataset.type == dns_rdatatype_ns)
5983 else if (rdataset.type == dns_rdatatype_ds)
5985 else if (rdataset.type == dns_rdatatype_dname)
5986 seen_dname = ISC_TRUE;
5987 else if (rdataset.type == dns_rdatatype_nsec)
5988 seen_nsec = ISC_TRUE;
5989 else if (rdataset.type == dns_rdatatype_nsec3)
5990 seen_nsec3 = ISC_TRUE;
5991 if (rdataset.type != dns_rdatatype_rrsig)
5993 dns_rdataset_disassociate(&rdataset);
5995 if (result != ISC_R_NOMORE)
5997 if (seen_ns && !seen_soa)
5998 *delegation = ISC_TRUE;
6000 * Going from insecure to NSEC3.
6001 * Don't generate NSEC3 records for NSEC3 records.
6003 if (build_nsec3 && !seen_nsec3 && seen_rr) {
6004 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
6005 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
6010 * Going from insecure to NSEC.
6011 * Don't generate NSEC records for NSEC3 records.
6013 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
6014 /* Build and add NSEC. */
6015 bottom = (seen_ns && !seen_soa) || seen_dname;
6017 * Build a NSEC record except at the origin.
6019 if (!dns_name_equal(name, dns_db_origin(db))) {
6020 CHECK(add_nsec(db, version, name, node, minimum,
6022 /* Count a NSEC generation as a signature generation. */
6026 result = dns_rdatasetiter_first(iterator);
6027 while (result == ISC_R_SUCCESS) {
6028 dns_rdatasetiter_current(iterator, &rdataset);
6029 if (rdataset.type == dns_rdatatype_soa ||
6030 rdataset.type == dns_rdatatype_rrsig)
6032 if (rdataset.type == dns_rdatatype_dnskey) {
6033 if (!is_ksk && keyset_kskonly)
6038 rdataset.type != dns_rdatatype_ds &&
6039 rdataset.type != dns_rdatatype_nsec)
6041 if (signed_with_key(db, node, version, rdataset.type, key))
6043 /* Calculate the signature, creating a RRSIG RDATA. */
6044 isc_buffer_clear(&buffer);
6045 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
6046 &expire, mctx, &buffer, &rdata));
6047 /* Update the database and journal with the RRSIG. */
6048 /* XXX inefficient - will cause dataset merging */
6049 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
6050 name, rdataset.ttl, &rdata));
6051 dns_rdata_reset(&rdata);
6054 dns_rdataset_disassociate(&rdataset);
6055 result = dns_rdatasetiter_next(iterator);
6057 if (result == ISC_R_NOMORE)
6058 result = ISC_R_SUCCESS;
6060 *delegation = ISC_TRUE;
6062 if (dns_rdataset_isassociated(&rdataset))
6063 dns_rdataset_disassociate(&rdataset);
6064 if (iterator != NULL)
6065 dns_rdatasetiter_destroy(&iterator);
6070 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
6073 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6074 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
6076 isc_result_t result;
6077 dns_rdataset_t rdataset;
6078 dns_dbnode_t *node = NULL;
6080 CHECK(dns_db_getoriginnode(db, &node));
6082 dns_rdataset_init(&rdataset);
6083 result = dns_db_findrdataset(db, node, version,
6086 0, &rdataset, NULL);
6087 if (dns_rdataset_isassociated(&rdataset))
6088 dns_rdataset_disassociate(&rdataset);
6089 if (result == ISC_R_NOTFOUND)
6091 if (result != ISC_R_SUCCESS)
6094 CHECK(delete_nsec(db, version, node, name, diff));
6095 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
6097 result = ISC_R_SUCCESS;
6100 dns_db_detachnode(db, &node);
6105 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
6106 dns_dbversion_t *version, isc_boolean_t build_nsec3,
6107 dns_ttl_t minimum, dns_diff_t *diff)
6109 isc_result_t result;
6110 dns_dbnode_t *node = NULL;
6111 dns_rdataset_t rdataset;
6112 dns_rdata_t rdata = DNS_RDATA_INIT;
6113 unsigned char data[5];
6114 isc_boolean_t seen_done = ISC_FALSE;
6115 isc_boolean_t have_rr = ISC_FALSE;
6117 dns_rdataset_init(&rdataset);
6118 result = dns_db_getoriginnode(signing->db, &node);
6119 if (result != ISC_R_SUCCESS)
6122 result = dns_db_findrdataset(signing->db, node, version,
6123 zone->privatetype, dns_rdatatype_none,
6124 0, &rdataset, NULL);
6125 if (result == ISC_R_NOTFOUND) {
6126 INSIST(!dns_rdataset_isassociated(&rdataset));
6127 result = ISC_R_SUCCESS;
6130 if (result != ISC_R_SUCCESS) {
6131 INSIST(!dns_rdataset_isassociated(&rdataset));
6134 for (result = dns_rdataset_first(&rdataset);
6135 result == ISC_R_SUCCESS;
6136 result = dns_rdataset_next(&rdataset)) {
6137 dns_rdataset_current(&rdataset, &rdata);
6139 * If we don't match the algorithm or keyid skip the record.
6141 if (rdata.length != 5 ||
6142 rdata.data[0] != signing->algorithm ||
6143 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
6144 rdata.data[2] != (signing->keyid & 0xff)) {
6146 dns_rdata_reset(&rdata);
6150 * We have a match. If we were signing (!signing->delete)
6151 * and we already have a record indicating that we have
6152 * finished signing (rdata.data[4] != 0) then keep it.
6153 * Otherwise it needs to be deleted as we have removed all
6154 * the signatures (signing->delete), so any record indicating
6155 * completion is now out of date, or we have finished signing
6156 * with the new record so we no longer need to remember that
6157 * we need to sign the zone with the matching key across a
6158 * nameserver re-start.
6160 if (!signing->delete && rdata.data[4] != 0) {
6161 seen_done = ISC_TRUE;
6164 CHECK(update_one_rr(signing->db, version, diff,
6165 DNS_DIFFOP_DEL, &zone->origin,
6166 rdataset.ttl, &rdata));
6167 dns_rdata_reset(&rdata);
6169 if (result == ISC_R_NOMORE)
6170 result = ISC_R_SUCCESS;
6171 if (!signing->delete && !seen_done) {
6173 * If we were signing then we need to indicate that we have
6174 * finished signing the zone with this key. If it is already
6175 * there we don't need to add it a second time.
6177 data[0] = signing->algorithm;
6178 data[1] = (signing->keyid >> 8) & 0xff;
6179 data[2] = signing->keyid & 0xff;
6182 rdata.length = sizeof(data);
6184 rdata.type = zone->privatetype;
6185 rdata.rdclass = dns_db_class(signing->db);
6186 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
6187 &zone->origin, rdataset.ttl, &rdata));
6188 } else if (!have_rr) {
6189 dns_name_t *origin = dns_db_origin(signing->db);
6191 * Rebuild the NSEC/NSEC3 record for the origin as we no
6192 * longer have any private records.
6195 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
6196 minimum, ISC_FALSE, diff));
6197 CHECK(updatesecure(signing->db, version, origin, minimum,
6202 if (dns_rdataset_isassociated(&rdataset))
6203 dns_rdataset_disassociate(&rdataset);
6205 dns_db_detachnode(signing->db, &node);
6210 * If 'active' is set then we are not done with the chain yet so only
6211 * delete the nsec3param record which indicates a full chain exists
6215 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
6216 isc_boolean_t active, dns_rdatatype_t privatetype,
6219 dns_dbnode_t *node = NULL;
6220 dns_name_t *name = dns_db_origin(db);
6221 dns_rdata_t rdata = DNS_RDATA_INIT;
6222 dns_rdataset_t rdataset;
6223 dns_rdata_nsec3param_t nsec3param;
6224 isc_result_t result;
6225 isc_buffer_t buffer;
6226 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
6228 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
6230 dns_rdataset_init(&rdataset);
6232 result = dns_db_getoriginnode(db, &node);
6233 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6234 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6235 0, 0, &rdataset, NULL);
6236 if (result == ISC_R_NOTFOUND)
6238 if (result != ISC_R_SUCCESS)
6242 * Preserve the existing ttl.
6247 * Delete all NSEC3PARAM records which match that in nsec3chain.
6249 for (result = dns_rdataset_first(&rdataset);
6250 result == ISC_R_SUCCESS;
6251 result = dns_rdataset_next(&rdataset)) {
6253 dns_rdataset_current(&rdataset, &rdata);
6254 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6256 if (nsec3param.hash != chain->nsec3param.hash ||
6257 (active && nsec3param.flags != 0) ||
6258 nsec3param.iterations != chain->nsec3param.iterations ||
6259 nsec3param.salt_length != chain->nsec3param.salt_length ||
6260 memcmp(nsec3param.salt, chain->nsec3param.salt,
6261 nsec3param.salt_length)) {
6262 dns_rdata_reset(&rdata);
6266 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6267 name, rdataset.ttl, &rdata));
6268 dns_rdata_reset(&rdata);
6270 if (result != ISC_R_NOMORE)
6273 dns_rdataset_disassociate(&rdataset);
6280 result = dns_nsec_nseconly(db, ver, &nseconly);
6281 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
6284 * Delete all private records which match that in nsec3chain.
6286 result = dns_db_findrdataset(db, node, ver, privatetype,
6287 0, 0, &rdataset, NULL);
6288 if (result == ISC_R_NOTFOUND)
6290 if (result != ISC_R_SUCCESS)
6293 for (result = dns_rdataset_first(&rdataset);
6294 result == ISC_R_SUCCESS;
6295 result = dns_rdataset_next(&rdataset)) {
6296 dns_rdata_t private = DNS_RDATA_INIT;
6297 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
6299 dns_rdataset_current(&rdataset, &private);
6300 if (!dns_nsec3param_fromprivate(&private, &rdata,
6303 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6306 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
6307 nsec3param.hash != chain->nsec3param.hash ||
6308 nsec3param.iterations != chain->nsec3param.iterations ||
6309 nsec3param.salt_length != chain->nsec3param.salt_length ||
6310 memcmp(nsec3param.salt, chain->nsec3param.salt,
6311 nsec3param.salt_length)) {
6312 dns_rdata_reset(&rdata);
6316 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6317 name, rdataset.ttl, &private));
6318 dns_rdata_reset(&rdata);
6320 if (result != ISC_R_NOMORE)
6324 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
6325 result = ISC_R_SUCCESS;
6330 * Add a NSEC3PARAM record which matches that in nsec3chain but
6331 * with all flags bits cleared.
6333 * Note: we do not clear chain->nsec3param.flags as this change
6336 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
6337 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
6338 dns_rdatatype_nsec3param,
6339 &chain->nsec3param, &buffer));
6340 rdata.data[1] = 0; /* Clear flag bits. */
6341 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
6344 dns_db_detachnode(db, &node);
6345 if (dns_rdataset_isassociated(&rdataset))
6346 dns_rdataset_disassociate(&rdataset);
6351 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6352 dns_name_t *name, dns_diff_t *diff)
6354 dns_rdataset_t rdataset;
6355 isc_result_t result;
6357 dns_rdataset_init(&rdataset);
6359 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6360 0, 0, &rdataset, NULL);
6361 if (result == ISC_R_NOTFOUND)
6362 return (ISC_R_SUCCESS);
6363 if (result != ISC_R_SUCCESS)
6365 for (result = dns_rdataset_first(&rdataset);
6366 result == ISC_R_SUCCESS;
6367 result = dns_rdataset_next(&rdataset)) {
6368 dns_rdata_t rdata = DNS_RDATA_INIT;
6370 dns_rdataset_current(&rdataset, &rdata);
6371 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6372 rdataset.ttl, &rdata));
6374 if (result == ISC_R_NOMORE)
6375 result = ISC_R_SUCCESS;
6377 dns_rdataset_disassociate(&rdataset);
6382 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6383 dns_name_t *name, const dns_rdata_nsec3param_t *param,
6386 dns_rdataset_t rdataset;
6387 dns_rdata_nsec3_t nsec3;
6388 isc_result_t result;
6390 dns_rdataset_init(&rdataset);
6391 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
6392 0, 0, &rdataset, NULL);
6393 if (result == ISC_R_NOTFOUND)
6394 return (ISC_R_SUCCESS);
6395 if (result != ISC_R_SUCCESS)
6398 for (result = dns_rdataset_first(&rdataset);
6399 result == ISC_R_SUCCESS;
6400 result = dns_rdataset_next(&rdataset)) {
6401 dns_rdata_t rdata = DNS_RDATA_INIT;
6403 dns_rdataset_current(&rdataset, &rdata);
6404 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
6405 if (nsec3.hash != param->hash ||
6406 nsec3.iterations != param->iterations ||
6407 nsec3.salt_length != param->salt_length ||
6408 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
6410 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6411 rdataset.ttl, &rdata));
6413 if (result == ISC_R_NOMORE)
6414 result = ISC_R_SUCCESS;
6416 dns_rdataset_disassociate(&rdataset);
6421 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
6422 const dns_rdata_nsec3param_t *param,
6423 isc_boolean_t *answer)
6425 dns_dbnode_t *node = NULL;
6426 dns_rdata_t rdata = DNS_RDATA_INIT;
6427 dns_rdata_nsec3param_t myparam;
6428 dns_rdataset_t rdataset;
6429 isc_result_t result;
6431 *answer = ISC_FALSE;
6433 result = dns_db_getoriginnode(db, &node);
6434 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6436 dns_rdataset_init(&rdataset);
6438 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6439 0, 0, &rdataset, NULL);
6440 if (result == ISC_R_SUCCESS) {
6441 dns_rdataset_disassociate(&rdataset);
6442 dns_db_detachnode(db, &node);
6445 if (result != ISC_R_NOTFOUND) {
6446 dns_db_detachnode(db, &node);
6450 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6451 0, 0, &rdataset, NULL);
6452 if (result == ISC_R_NOTFOUND) {
6454 dns_db_detachnode(db, &node);
6455 return (ISC_R_SUCCESS);
6457 if (result != ISC_R_SUCCESS) {
6458 dns_db_detachnode(db, &node);
6462 for (result = dns_rdataset_first(&rdataset);
6463 result == ISC_R_SUCCESS;
6464 result = dns_rdataset_next(&rdataset)) {
6465 dns_rdataset_current(&rdataset, &rdata);
6466 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
6467 dns_rdata_reset(&rdata);
6469 * Ignore any NSEC3PARAM removals.
6471 if (NSEC3REMOVE(myparam.flags))
6474 * Ignore the chain that we are in the process of deleting.
6476 if (myparam.hash == param->hash &&
6477 myparam.iterations == param->iterations &&
6478 myparam.salt_length == param->salt_length &&
6479 !memcmp(myparam.salt, param->salt, myparam.salt_length))
6482 * Found an active NSEC3 chain.
6486 if (result == ISC_R_NOMORE) {
6488 result = ISC_R_SUCCESS;
6492 if (dns_rdataset_isassociated(&rdataset))
6493 dns_rdataset_disassociate(&rdataset);
6494 dns_db_detachnode(db, &node);
6499 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
6500 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
6501 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
6502 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
6503 zonediff_t *zonediff)
6505 dns_difftuple_t *tuple;
6506 isc_result_t result;
6508 for (tuple = ISC_LIST_HEAD(diff->tuples);
6510 tuple = ISC_LIST_HEAD(diff->tuples)) {
6511 result = del_sigs(zone, db, version, &tuple->name,
6512 tuple->rdata.type, zonediff,
6513 zone_keys, nkeys, now, ISC_FALSE);
6514 if (result != ISC_R_SUCCESS) {
6515 dns_zone_log(zone, ISC_LOG_ERROR,
6516 "update_sigs:del_sigs -> %s",
6517 dns_result_totext(result));
6520 result = add_sigs(db, version, &tuple->name,
6521 tuple->rdata.type, zonediff->diff,
6522 zone_keys, nkeys, zone->mctx, inception,
6523 expire, check_ksk, keyset_kskonly);
6524 if (result != ISC_R_SUCCESS) {
6525 dns_zone_log(zone, ISC_LOG_ERROR,
6526 "update_sigs:add_sigs -> %s",
6527 dns_result_totext(result));
6532 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
6533 while (next != NULL &&
6534 (tuple->rdata.type != next->rdata.type ||
6535 !dns_name_equal(&tuple->name, &next->name)))
6536 next = ISC_LIST_NEXT(next, link);
6537 ISC_LIST_UNLINK(diff->tuples, tuple, link);
6538 dns_diff_appendminimal(zonediff->diff, &tuple);
6539 INSIST(tuple == NULL);
6541 } while (tuple != NULL);
6543 return (ISC_R_SUCCESS);
6547 * Incrementally build and sign a new NSEC3 chain using the parameters
6551 zone_nsec3chain(dns_zone_t *zone) {
6552 const char *me = "zone_nsec3chain";
6553 dns_db_t *db = NULL;
6554 dns_dbnode_t *node = NULL;
6555 dns_dbversion_t *version = NULL;
6556 dns_diff_t _sig_diff;
6557 dns_diff_t nsec_diff;
6558 dns_diff_t nsec3_diff;
6559 dns_diff_t param_diff;
6560 zonediff_t zonediff;
6561 dns_fixedname_t fixed;
6562 dns_fixedname_t nextfixed;
6563 dns_name_t *name, *nextname;
6564 dns_rdataset_t rdataset;
6565 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
6566 dns_nsec3chainlist_t cleanup;
6567 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6568 isc_int32_t signatures;
6569 isc_boolean_t check_ksk, keyset_kskonly;
6570 isc_boolean_t delegation;
6571 isc_boolean_t first;
6572 isc_result_t result;
6573 isc_stdtime_t now, inception, soaexpire, expire;
6574 isc_uint32_t jitter;
6576 unsigned int nkeys = 0;
6578 isc_boolean_t unsecure = ISC_FALSE;
6579 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
6580 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
6581 dns_rdatasetiter_t *iterator = NULL;
6582 isc_boolean_t buildnsecchain;
6583 isc_boolean_t updatensec = ISC_FALSE;
6584 dns_rdatatype_t privatetype = zone->privatetype;
6588 dns_rdataset_init(&rdataset);
6589 dns_fixedname_init(&fixed);
6590 name = dns_fixedname_name(&fixed);
6591 dns_fixedname_init(&nextfixed);
6592 nextname = dns_fixedname_name(&nextfixed);
6593 dns_diff_init(zone->mctx, ¶m_diff);
6594 dns_diff_init(zone->mctx, &nsec3_diff);
6595 dns_diff_init(zone->mctx, &nsec_diff);
6596 dns_diff_init(zone->mctx, &_sig_diff);
6597 zonediff_init(&zonediff, &_sig_diff);
6598 ISC_LIST_INIT(cleanup);
6601 * Updates are disabled. Pause for 5 minutes.
6603 if (zone->update_disabled) {
6604 result = ISC_R_FAILURE;
6608 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6609 dns_db_attach(zone->db, &db);
6610 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6612 result = dns_db_newversion(db, &version);
6613 if (result != ISC_R_SUCCESS) {
6614 dns_zone_log(zone, ISC_LOG_ERROR,
6615 "zone_nsec3chain:dns_db_newversion -> %s",
6616 dns_result_totext(result));
6620 result = find_zone_keys(zone, db, version, zone->mctx,
6621 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6622 if (result != ISC_R_SUCCESS) {
6623 dns_zone_log(zone, ISC_LOG_ERROR,
6624 "zone_nsec3chain:find_zone_keys -> %s",
6625 dns_result_totext(result));
6629 isc_stdtime_get(&now);
6630 inception = now - 3600; /* Allow for clock skew. */
6631 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6634 * Spread out signatures over time if they happen to be
6635 * clumped. We don't do this for each add_sigs() call as
6636 * we still want some clustering to occur.
6638 isc_random_get(&jitter);
6639 expire = soaexpire - jitter % 3600;
6641 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6642 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6645 * We keep pulling nodes off each iterator in turn until
6646 * we have no more nodes to pull off or we reach the limits
6649 nodes = zone->nodes;
6650 signatures = zone->signatures;
6652 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6656 if (nsec3chain != NULL)
6657 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6659 * Generate new NSEC3 chains first.
6661 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6663 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6665 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6666 if (nsec3chain->done || nsec3chain->db != zone->db) {
6667 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
6668 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6670 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6672 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
6676 * Possible future db.
6678 if (nsec3chain->db != db) {
6682 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
6685 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6687 if (nsec3chain->delete_nsec) {
6688 delegation = ISC_FALSE;
6689 dns_dbiterator_pause(nsec3chain->dbiterator);
6690 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
6694 * On the first pass we need to check if the current node
6695 * has not been obscured.
6697 delegation = ISC_FALSE;
6698 unsecure = ISC_FALSE;
6700 dns_fixedname_t ffound;
6702 dns_fixedname_init(&ffound);
6703 found = dns_fixedname_name(&ffound);
6704 result = dns_db_find(db, name, version,
6706 DNS_DBFIND_NOWILD, 0, NULL, found,
6708 if ((result == DNS_R_DELEGATION ||
6709 result == DNS_R_DNAME) &&
6710 !dns_name_equal(name, found)) {
6712 * Remember the obscuring name so that
6713 * we skip all obscured names.
6715 dns_name_copy(found, name, NULL);
6716 delegation = ISC_TRUE;
6722 * Check to see if this is a bottom of zone node.
6724 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6725 if (result == ISC_R_NOTFOUND) /* Empty node? */
6727 if (result != ISC_R_SUCCESS)
6730 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
6732 for (result = dns_rdatasetiter_first(iterator);
6733 result == ISC_R_SUCCESS;
6734 result = dns_rdatasetiter_next(iterator)) {
6735 dns_rdatasetiter_current(iterator, &rdataset);
6736 INSIST(rdataset.type != dns_rdatatype_nsec3);
6737 if (rdataset.type == dns_rdatatype_soa)
6738 seen_soa = ISC_TRUE;
6739 else if (rdataset.type == dns_rdatatype_ns)
6741 else if (rdataset.type == dns_rdatatype_dname)
6742 seen_dname = ISC_TRUE;
6743 else if (rdataset.type == dns_rdatatype_ds)
6745 else if (rdataset.type == dns_rdatatype_nsec)
6746 seen_nsec = ISC_TRUE;
6747 dns_rdataset_disassociate(&rdataset);
6749 dns_rdatasetiter_destroy(&iterator);
6751 * Is there a NSEC chain than needs to be cleaned up?
6754 nsec3chain->seen_nsec = ISC_TRUE;
6755 if (seen_ns && !seen_soa && !seen_ds)
6756 unsecure = ISC_TRUE;
6757 if ((seen_ns && !seen_soa) || seen_dname)
6758 delegation = ISC_TRUE;
6763 dns_dbiterator_pause(nsec3chain->dbiterator);
6764 result = dns_nsec3_addnsec3(db, version, name,
6765 &nsec3chain->nsec3param,
6766 zone->minimum, unsecure,
6768 if (result != ISC_R_SUCCESS) {
6769 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6770 "dns_nsec3_addnsec3 -> %s",
6771 dns_result_totext(result));
6776 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
6777 * two signatures. Additionally there will, in general, be
6778 * two signature generated below.
6780 * If we are only changing the optout flag the cost is half
6781 * that of the cost of generating a completely new chain.
6786 * Go onto next node.
6790 dns_db_detachnode(db, &node);
6792 result = dns_dbiterator_next(nsec3chain->dbiterator);
6794 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
6795 dns_dbiterator_pause(nsec3chain->dbiterator);
6796 CHECK(fixup_nsec3param(db, version, nsec3chain,
6797 ISC_FALSE, privatetype,
6800 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6803 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6806 if (result == ISC_R_NOMORE) {
6807 dns_dbiterator_pause(nsec3chain->dbiterator);
6808 if (nsec3chain->seen_nsec) {
6809 CHECK(fixup_nsec3param(db, version,
6814 nsec3chain->delete_nsec = ISC_TRUE;
6817 CHECK(fixup_nsec3param(db, version, nsec3chain,
6818 ISC_FALSE, privatetype,
6821 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6824 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6826 } else if (result != ISC_R_SUCCESS) {
6827 dns_zone_log(zone, ISC_LOG_ERROR,
6829 "dns_dbiterator_next -> %s",
6830 dns_result_totext(result));
6832 } else if (delegation) {
6833 dns_dbiterator_current(nsec3chain->dbiterator,
6835 dns_db_detachnode(db, &node);
6836 if (!dns_name_issubdomain(nextname, name))
6844 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6849 dns_dbiterator_pause(nsec3chain->dbiterator);
6850 nsec3chain = nextnsec3chain;
6852 if (nsec3chain != NULL)
6853 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6860 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6863 buildnsecchain = ISC_FALSE;
6864 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6866 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6869 if (nsec3chain->db != db)
6870 goto next_removechain;
6872 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
6873 goto next_removechain;
6876 * Work out if we need to build a NSEC chain as a consequence
6877 * of removing this NSEC3 chain.
6879 if (first && !updatensec &&
6880 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
6882 result = need_nsec_chain(db, version,
6883 &nsec3chain->nsec3param,
6885 if (result != ISC_R_SUCCESS) {
6886 dns_zone_log(zone, ISC_LOG_ERROR,
6888 "need_nsec_chain -> %s",
6889 dns_result_totext(result));
6895 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
6896 "buildnsecchain = %u\n", buildnsecchain);
6898 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6899 delegation = ISC_FALSE;
6901 if (!buildnsecchain) {
6903 * Delete the NSECPARAM record that matches this chain.
6906 result = fixup_nsec3param(db, version,
6908 ISC_TRUE, privatetype,
6910 if (result != ISC_R_SUCCESS) {
6911 dns_zone_log(zone, ISC_LOG_ERROR,
6913 "fixup_nsec3param -> %s",
6914 dns_result_totext(result));
6920 * Delete the NSEC3 records.
6922 result = deletematchingnsec3(db, version, node, name,
6923 &nsec3chain->nsec3param,
6925 if (result != ISC_R_SUCCESS) {
6926 dns_zone_log(zone, ISC_LOG_ERROR,
6928 "deletematchingnsec3 -> %s",
6929 dns_result_totext(result));
6932 goto next_removenode;
6936 dns_fixedname_t ffound;
6938 dns_fixedname_init(&ffound);
6939 found = dns_fixedname_name(&ffound);
6940 result = dns_db_find(db, name, version,
6942 DNS_DBFIND_NOWILD, 0, NULL, found,
6944 if ((result == DNS_R_DELEGATION ||
6945 result == DNS_R_DNAME) &&
6946 !dns_name_equal(name, found)) {
6948 * Remember the obscuring name so that
6949 * we skip all obscured names.
6951 dns_name_copy(found, name, NULL);
6952 delegation = ISC_TRUE;
6953 goto next_removenode;
6958 * Check to see if this is a bottom of zone node.
6960 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6961 if (result == ISC_R_NOTFOUND) /* Empty node? */
6962 goto next_removenode;
6963 if (result != ISC_R_SUCCESS)
6966 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
6967 seen_rr = ISC_FALSE;
6968 for (result = dns_rdatasetiter_first(iterator);
6969 result == ISC_R_SUCCESS;
6970 result = dns_rdatasetiter_next(iterator)) {
6971 dns_rdatasetiter_current(iterator, &rdataset);
6972 if (rdataset.type == dns_rdatatype_soa)
6973 seen_soa = ISC_TRUE;
6974 else if (rdataset.type == dns_rdatatype_ns)
6976 else if (rdataset.type == dns_rdatatype_dname)
6977 seen_dname = ISC_TRUE;
6978 else if (rdataset.type == dns_rdatatype_nsec)
6979 seen_nsec = ISC_TRUE;
6980 else if (rdataset.type == dns_rdatatype_nsec3)
6981 seen_nsec3 = ISC_TRUE;
6982 if (rdataset.type != dns_rdatatype_rrsig)
6984 dns_rdataset_disassociate(&rdataset);
6986 dns_rdatasetiter_destroy(&iterator);
6988 if (!seen_rr || seen_nsec3 || seen_nsec)
6989 goto next_removenode;
6990 if ((seen_ns && !seen_soa) || seen_dname)
6991 delegation = ISC_TRUE;
6994 * Add a NSEC record except at the origin.
6996 if (!dns_name_equal(name, dns_db_origin(db))) {
6997 dns_dbiterator_pause(nsec3chain->dbiterator);
6998 CHECK(add_nsec(db, version, name, node, zone->minimum,
6999 delegation, &nsec_diff));
7004 dns_db_detachnode(db, &node);
7006 result = dns_dbiterator_next(nsec3chain->dbiterator);
7007 if (result == ISC_R_NOMORE && buildnsecchain) {
7009 * The NSEC chain should now be built.
7010 * We can now remove the NSEC3 chain.
7012 updatensec = ISC_TRUE;
7013 goto same_removechain;
7015 if (result == ISC_R_NOMORE) {
7017 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
7020 ISC_LIST_APPEND(cleanup, nsec3chain, link);
7021 dns_dbiterator_pause(nsec3chain->dbiterator);
7022 result = fixup_nsec3param(db, version,
7023 nsec3chain, ISC_FALSE,
7026 if (result != ISC_R_SUCCESS) {
7027 dns_zone_log(zone, ISC_LOG_ERROR,
7029 "fixup_nsec3param -> %s",
7030 dns_result_totext(result));
7033 goto next_removechain;
7034 } else if (result != ISC_R_SUCCESS) {
7035 dns_zone_log(zone, ISC_LOG_ERROR,
7037 "dns_dbiterator_next -> %s",
7038 dns_result_totext(result));
7040 } else if (delegation) {
7041 dns_dbiterator_current(nsec3chain->dbiterator,
7043 dns_db_detachnode(db, &node);
7044 if (!dns_name_issubdomain(nextname, name))
7052 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
7053 buildnsecchain = ISC_FALSE;
7058 dns_dbiterator_pause(nsec3chain->dbiterator);
7059 nsec3chain = nextnsec3chain;
7064 * We may need to update the NSEC/NSEC3 records for the zone apex.
7066 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
7067 isc_boolean_t rebuild_nsec = ISC_FALSE,
7068 rebuild_nsec3 = ISC_FALSE;
7069 result = dns_db_getoriginnode(db, &node);
7070 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7071 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7072 if (result != ISC_R_SUCCESS) {
7073 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7074 "dns_db_allrdatasets -> %s",
7075 dns_result_totext(result));
7078 for (result = dns_rdatasetiter_first(iterator);
7079 result == ISC_R_SUCCESS;
7080 result = dns_rdatasetiter_next(iterator)) {
7081 dns_rdatasetiter_current(iterator, &rdataset);
7082 if (rdataset.type == dns_rdatatype_nsec)
7083 rebuild_nsec = ISC_TRUE;
7084 if (rdataset.type == dns_rdatatype_nsec3param)
7085 rebuild_nsec3 = ISC_TRUE;
7086 dns_rdataset_disassociate(&rdataset);
7088 dns_rdatasetiter_destroy(&iterator);
7089 dns_db_detachnode(db, &node);
7092 if (nsec3chain != NULL)
7093 dns_dbiterator_pause(nsec3chain->dbiterator);
7095 result = updatesecure(db, version, &zone->origin,
7096 zone->minimum, ISC_TRUE,
7098 if (result != ISC_R_SUCCESS) {
7099 dns_zone_log(zone, ISC_LOG_ERROR,
7101 "updatesecure -> %s",
7102 dns_result_totext(result));
7107 if (rebuild_nsec3) {
7108 if (nsec3chain != NULL)
7109 dns_dbiterator_pause(nsec3chain->dbiterator);
7111 result = dns_nsec3_addnsec3s(db, version,
7113 zone->minimum, ISC_FALSE,
7115 if (result != ISC_R_SUCCESS) {
7116 dns_zone_log(zone, ISC_LOG_ERROR,
7118 "dns_nsec3_addnsec3s -> %s",
7119 dns_result_totext(result));
7125 if (nsec3chain != NULL)
7126 dns_dbiterator_pause(nsec3chain->dbiterator);
7129 * Add / update signatures for the NSEC3 records.
7131 if (nsec3chain != NULL)
7132 dns_dbiterator_pause(nsec3chain->dbiterator);
7133 result = update_sigs(&nsec3_diff, db, version, zone_keys,
7134 nkeys, zone, inception, expire, now,
7135 check_ksk, keyset_kskonly, &zonediff);
7136 if (result != ISC_R_SUCCESS) {
7137 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7138 "update_sigs -> %s", dns_result_totext(result));
7143 * We have changed the NSEC3PARAM or private RRsets
7144 * above so we need to update the signatures.
7146 result = update_sigs(¶m_diff, db, version, zone_keys,
7147 nkeys, zone, inception, expire, now,
7148 check_ksk, keyset_kskonly, &zonediff);
7149 if (result != ISC_R_SUCCESS) {
7150 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7151 "update_sigs -> %s", dns_result_totext(result));
7156 result = updatesecure(db, version, &zone->origin,
7157 zone->minimum, ISC_FALSE, &nsec_diff);
7158 if (result != ISC_R_SUCCESS) {
7159 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7160 "updatesecure -> %s",
7161 dns_result_totext(result));
7166 result = update_sigs(&nsec_diff, db, version, zone_keys,
7167 nkeys, zone, inception, expire, now,
7168 check_ksk, keyset_kskonly, &zonediff);
7169 if (result != ISC_R_SUCCESS) {
7170 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7171 "update_sigs -> %s", dns_result_totext(result));
7176 * If we made no effective changes to the zone then we can just
7177 * cleanup otherwise we need to increment the serial.
7179 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7181 * No need to call dns_db_closeversion() here as it is
7182 * called with commit = ISC_TRUE below.
7187 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7188 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7189 if (result != ISC_R_SUCCESS) {
7190 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7191 "del_sigs -> %s", dns_result_totext(result));
7195 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7196 zone->updatemethod);
7197 if (result != ISC_R_SUCCESS) {
7198 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7199 "update_soa_serial -> %s",
7200 dns_result_totext(result));
7204 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7205 zonediff.diff, zone_keys, nkeys, zone->mctx,
7206 inception, soaexpire, check_ksk, keyset_kskonly);
7207 if (result != ISC_R_SUCCESS) {
7208 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7209 "add_sigs -> %s", dns_result_totext(result));
7213 /* Write changes to journal file. */
7214 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
7217 zone_needdump(zone, DNS_DUMP_DELAY);
7218 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7223 * Pause all iterators so that dns_db_closeversion() can succeed.
7226 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7228 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7229 dns_dbiterator_pause(nsec3chain->dbiterator);
7233 * Everything has succeeded. Commit the changes.
7234 * Unconditionally commit as zonediff.offline not checked above.
7236 dns_db_closeversion(db, &version, ISC_TRUE);
7239 * Everything succeeded so we can clean these up now.
7241 nsec3chain = ISC_LIST_HEAD(cleanup);
7242 while (nsec3chain != NULL) {
7243 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7244 dns_db_detach(&nsec3chain->db);
7245 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7246 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7247 nsec3chain = ISC_LIST_HEAD(cleanup);
7250 set_resigntime(zone);
7253 if (result != ISC_R_SUCCESS)
7254 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
7255 dns_result_totext(result));
7257 * On error roll back the current nsec3chain.
7259 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
7260 if (nsec3chain->done) {
7261 dns_db_detach(&nsec3chain->db);
7262 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7263 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7265 result = dns_dbiterator_first(nsec3chain->dbiterator);
7266 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7267 dns_dbiterator_pause(nsec3chain->dbiterator);
7268 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7273 * Rollback the cleanup list.
7275 nsec3chain = ISC_LIST_TAIL(cleanup);
7276 while (nsec3chain != NULL) {
7277 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7278 if (nsec3chain->done) {
7279 dns_db_detach(&nsec3chain->db);
7280 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7281 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7284 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
7286 result = dns_dbiterator_first(nsec3chain->dbiterator);
7287 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7288 dns_dbiterator_pause(nsec3chain->dbiterator);
7289 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7291 nsec3chain = ISC_LIST_TAIL(cleanup);
7295 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7297 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7298 dns_dbiterator_pause(nsec3chain->dbiterator);
7301 dns_diff_clear(¶m_diff);
7302 dns_diff_clear(&nsec3_diff);
7303 dns_diff_clear(&nsec_diff);
7304 dns_diff_clear(&_sig_diff);
7306 if (iterator != NULL)
7307 dns_rdatasetiter_destroy(&iterator);
7309 for (i = 0; i < nkeys; i++)
7310 dst_key_free(&zone_keys[i]);
7313 dns_db_detachnode(db, &node);
7314 if (version != NULL) {
7315 dns_db_closeversion(db, &version, ISC_FALSE);
7317 } else if (db != NULL)
7321 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
7323 if (zone->update_disabled || result != ISC_R_SUCCESS)
7324 isc_interval_set(&i, 60, 0); /* 1 minute */
7326 isc_interval_set(&i, 0, 10000000); /* 10 ms */
7327 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
7329 isc_time_settoepoch(&zone->nsec3chaintime);
7334 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
7335 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
7336 isc_uint16_t keyid, dns_diff_t *diff)
7338 dns_rdata_rrsig_t rrsig;
7339 dns_rdataset_t rdataset;
7340 dns_rdatasetiter_t *iterator = NULL;
7341 isc_result_t result;
7343 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7344 if (result != ISC_R_SUCCESS) {
7345 if (result == ISC_R_NOTFOUND)
7346 result = ISC_R_SUCCESS;
7350 dns_rdataset_init(&rdataset);
7351 for (result = dns_rdatasetiter_first(iterator);
7352 result == ISC_R_SUCCESS;
7353 result = dns_rdatasetiter_next(iterator)) {
7354 dns_rdatasetiter_current(iterator, &rdataset);
7355 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
7356 for (result = dns_rdataset_first(&rdataset);
7357 result == ISC_R_SUCCESS;
7358 result = dns_rdataset_next(&rdataset)) {
7359 dns_rdata_t rdata = DNS_RDATA_INIT;
7360 dns_rdataset_current(&rdataset, &rdata);
7361 CHECK(update_one_rr(db, version, diff,
7362 DNS_DIFFOP_DEL, name,
7363 rdataset.ttl, &rdata));
7365 if (result != ISC_R_NOMORE)
7367 dns_rdataset_disassociate(&rdataset);
7370 if (rdataset.type != dns_rdatatype_rrsig) {
7371 dns_rdataset_disassociate(&rdataset);
7374 for (result = dns_rdataset_first(&rdataset);
7375 result == ISC_R_SUCCESS;
7376 result = dns_rdataset_next(&rdataset)) {
7377 dns_rdata_t rdata = DNS_RDATA_INIT;
7378 dns_rdataset_current(&rdataset, &rdata);
7379 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
7380 if (rrsig.algorithm != algorithm ||
7381 rrsig.keyid != keyid)
7383 CHECK(update_one_rr(db, version, diff,
7384 DNS_DIFFOP_DELRESIGN, name,
7385 rdataset.ttl, &rdata));
7387 dns_rdataset_disassociate(&rdataset);
7388 if (result != ISC_R_NOMORE)
7391 if (result == ISC_R_NOMORE)
7392 result = ISC_R_SUCCESS;
7394 if (dns_rdataset_isassociated(&rdataset))
7395 dns_rdataset_disassociate(&rdataset);
7396 dns_rdatasetiter_destroy(&iterator);
7401 * Incrementally sign the zone using the keys requested.
7402 * Builds the NSEC chain if required.
7405 zone_sign(dns_zone_t *zone) {
7406 const char *me = "zone_sign";
7407 dns_db_t *db = NULL;
7408 dns_dbnode_t *node = NULL;
7409 dns_dbversion_t *version = NULL;
7410 dns_diff_t _sig_diff;
7411 dns_diff_t post_diff;
7412 zonediff_t zonediff;
7413 dns_fixedname_t fixed;
7414 dns_fixedname_t nextfixed;
7415 dns_name_t *name, *nextname;
7416 dns_rdataset_t rdataset;
7417 dns_signing_t *signing, *nextsigning;
7418 dns_signinglist_t cleanup;
7419 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
7420 isc_int32_t signatures;
7421 isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
7422 isc_boolean_t commit = ISC_FALSE;
7423 isc_boolean_t delegation;
7424 isc_boolean_t build_nsec = ISC_FALSE;
7425 isc_boolean_t build_nsec3 = ISC_FALSE;
7426 isc_boolean_t first;
7427 isc_result_t result;
7428 isc_stdtime_t now, inception, soaexpire, expire;
7429 isc_uint32_t jitter;
7431 unsigned int nkeys = 0;
7436 dns_rdataset_init(&rdataset);
7437 dns_fixedname_init(&fixed);
7438 name = dns_fixedname_name(&fixed);
7439 dns_fixedname_init(&nextfixed);
7440 nextname = dns_fixedname_name(&nextfixed);
7441 dns_diff_init(zone->mctx, &_sig_diff);
7442 dns_diff_init(zone->mctx, &post_diff);
7443 zonediff_init(&zonediff, &_sig_diff);
7444 ISC_LIST_INIT(cleanup);
7447 * Updates are disabled. Pause for 5 minutes.
7449 if (zone->update_disabled) {
7450 result = ISC_R_FAILURE;
7454 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7455 if (zone->db != NULL)
7456 dns_db_attach(zone->db, &db);
7457 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7459 result = ISC_R_FAILURE;
7463 result = dns_db_newversion(db, &version);
7464 if (result != ISC_R_SUCCESS) {
7465 dns_zone_log(zone, ISC_LOG_ERROR,
7466 "zone_sign:dns_db_newversion -> %s",
7467 dns_result_totext(result));
7471 result = find_zone_keys(zone, db, version, zone->mctx,
7472 DNS_MAXZONEKEYS, zone_keys, &nkeys);
7473 if (result != ISC_R_SUCCESS) {
7474 dns_zone_log(zone, ISC_LOG_ERROR,
7475 "zone_sign:find_zone_keys -> %s",
7476 dns_result_totext(result));
7480 isc_stdtime_get(&now);
7481 inception = now - 3600; /* Allow for clock skew. */
7482 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
7485 * Spread out signatures over time if they happen to be
7486 * clumped. We don't do this for each add_sigs() call as
7487 * we still want some clustering to occur.
7489 isc_random_get(&jitter);
7490 expire = soaexpire - jitter % 3600;
7493 * We keep pulling nodes off each iterator in turn until
7494 * we have no more nodes to pull off or we reach the limits
7497 nodes = zone->nodes;
7498 signatures = zone->signatures;
7499 signing = ISC_LIST_HEAD(zone->signing);
7502 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
7503 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
7505 /* Determine which type of chain to build */
7506 CHECK(dns_private_chains(db, version, zone->privatetype,
7507 &build_nsec, &build_nsec3));
7509 /* If neither chain is found, default to NSEC */
7510 if (!build_nsec && !build_nsec3)
7511 build_nsec = ISC_TRUE;
7513 while (signing != NULL && nodes-- > 0 && signatures > 0) {
7514 nextsigning = ISC_LIST_NEXT(signing, link);
7516 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7517 if (signing->done || signing->db != zone->db) {
7519 * The zone has been reloaded. We will have
7520 * created new signings as part of the reload
7521 * process so we can destroy this one.
7523 ISC_LIST_UNLINK(zone->signing, signing, link);
7524 ISC_LIST_APPEND(cleanup, signing, link);
7525 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7528 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7530 if (signing->db != db)
7533 delegation = ISC_FALSE;
7535 if (first && signing->delete) {
7537 * Remove the key we are deleting from consideration.
7539 for (i = 0, j = 0; i < nkeys; i++) {
7541 * Find the key we want to remove.
7543 if (ALG(zone_keys[i]) == signing->algorithm &&
7544 dst_key_id(zone_keys[i]) == signing->keyid)
7546 if (KSK(zone_keys[i]))
7547 dst_key_free(&zone_keys[i]);
7550 zone_keys[j] = zone_keys[i];
7556 dns_dbiterator_current(signing->dbiterator, &node, name);
7558 if (signing->delete) {
7559 dns_dbiterator_pause(signing->dbiterator);
7560 CHECK(del_sig(db, version, name, node, nkeys,
7561 signing->algorithm, signing->keyid,
7566 * On the first pass we need to check if the current node
7567 * has not been obscured.
7570 dns_fixedname_t ffound;
7572 dns_fixedname_init(&ffound);
7573 found = dns_fixedname_name(&ffound);
7574 result = dns_db_find(db, name, version,
7576 DNS_DBFIND_NOWILD, 0, NULL, found,
7578 if ((result == DNS_R_DELEGATION ||
7579 result == DNS_R_DNAME) &&
7580 !dns_name_equal(name, found)) {
7582 * Remember the obscuring name so that
7583 * we skip all obscured names.
7585 dns_name_copy(found, name, NULL);
7586 delegation = ISC_TRUE;
7594 dns_dbiterator_pause(signing->dbiterator);
7595 for (i = 0; i < nkeys; i++) {
7596 isc_boolean_t both = ISC_FALSE;
7599 * Find the keys we want to sign with.
7601 if (!dst_key_isprivate(zone_keys[i]))
7605 * When adding look for the specific key.
7607 if (!signing->delete &&
7608 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
7609 dst_key_id(zone_keys[i]) != signing->keyid))
7613 * When deleting make sure we are properly signed
7614 * with the algorithm that was being removed.
7616 if (signing->delete &&
7617 ALG(zone_keys[i]) != signing->algorithm)
7621 * Do we do KSK processing?
7623 if (check_ksk && !REVOKE(zone_keys[i])) {
7624 isc_boolean_t have_ksk, have_nonksk;
7625 if (KSK(zone_keys[i])) {
7626 have_ksk = ISC_TRUE;
7627 have_nonksk = ISC_FALSE;
7629 have_ksk = ISC_FALSE;
7630 have_nonksk = ISC_TRUE;
7632 for (j = 0; j < nkeys; j++) {
7634 ALG(zone_keys[i]) !=
7637 if (REVOKE(zone_keys[j]))
7639 if (KSK(zone_keys[j]))
7640 have_ksk = ISC_TRUE;
7642 have_nonksk = ISC_TRUE;
7643 both = have_ksk && have_nonksk;
7648 if (both || REVOKE(zone_keys[i]))
7649 is_ksk = KSK(zone_keys[i]);
7653 CHECK(sign_a_node(db, name, node, version, build_nsec3,
7654 build_nsec, zone_keys[i], inception,
7655 expire, zone->minimum, is_ksk,
7656 ISC_TF(both && keyset_kskonly),
7657 &delegation, zonediff.diff,
7658 &signatures, zone->mctx));
7660 * If we are adding we are done. Look for other keys
7661 * of the same algorithm if deleting.
7663 if (!signing->delete)
7668 * Go onto next node.
7672 dns_db_detachnode(db, &node);
7674 result = dns_dbiterator_next(signing->dbiterator);
7675 if (result == ISC_R_NOMORE) {
7676 ISC_LIST_UNLINK(zone->signing, signing, link);
7677 ISC_LIST_APPEND(cleanup, signing, link);
7678 dns_dbiterator_pause(signing->dbiterator);
7679 if (nkeys != 0 && build_nsec) {
7681 * We have finished regenerating the
7682 * zone with a zone signing key.
7683 * The NSEC chain is now complete and
7684 * there is a full set of signatures
7685 * for the zone. We can now clear the
7686 * OPT bit from the NSEC record.
7688 result = updatesecure(db, version,
7693 if (result != ISC_R_SUCCESS) {
7696 "updatesecure -> %s",
7697 dns_result_totext(result));
7701 result = updatesignwithkey(zone, signing,
7706 if (result != ISC_R_SUCCESS) {
7707 dns_zone_log(zone, ISC_LOG_ERROR,
7708 "updatesignwithkey -> %s",
7709 dns_result_totext(result));
7712 build_nsec = ISC_FALSE;
7714 } else if (result != ISC_R_SUCCESS) {
7715 dns_zone_log(zone, ISC_LOG_ERROR,
7716 "zone_sign:dns_dbiterator_next -> %s",
7717 dns_result_totext(result));
7719 } else if (delegation) {
7720 dns_dbiterator_current(signing->dbiterator,
7722 dns_db_detachnode(db, &node);
7723 if (!dns_name_issubdomain(nextname, name))
7731 dns_dbiterator_pause(signing->dbiterator);
7732 signing = nextsigning;
7736 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
7737 result = update_sigs(&post_diff, db, version, zone_keys,
7738 nkeys, zone, inception, expire, now,
7739 check_ksk, keyset_kskonly, &zonediff);
7740 if (result != ISC_R_SUCCESS) {
7741 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
7742 "update_sigs -> %s",
7743 dns_result_totext(result));
7749 * Have we changed anything?
7751 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7752 if (zonediff.offline)
7754 result = ISC_R_SUCCESS;
7760 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7761 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7762 if (result != ISC_R_SUCCESS) {
7763 dns_zone_log(zone, ISC_LOG_ERROR,
7764 "zone_sign:del_sigs -> %s",
7765 dns_result_totext(result));
7769 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7770 zone->updatemethod);
7771 if (result != ISC_R_SUCCESS) {
7772 dns_zone_log(zone, ISC_LOG_ERROR,
7773 "zone_sign:update_soa_serial -> %s",
7774 dns_result_totext(result));
7779 * Generate maximum life time signatures so that the above loop
7780 * termination is sensible.
7782 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7783 zonediff.diff, zone_keys, nkeys, zone->mctx,
7784 inception, soaexpire, check_ksk, keyset_kskonly);
7785 if (result != ISC_R_SUCCESS) {
7786 dns_zone_log(zone, ISC_LOG_ERROR,
7787 "zone_sign:add_sigs -> %s",
7788 dns_result_totext(result));
7793 * Write changes to journal file.
7795 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
7799 * Pause all iterators so that dns_db_closeversion() can succeed.
7801 for (signing = ISC_LIST_HEAD(zone->signing);
7803 signing = ISC_LIST_NEXT(signing, link))
7804 dns_dbiterator_pause(signing->dbiterator);
7806 for (signing = ISC_LIST_HEAD(cleanup);
7808 signing = ISC_LIST_NEXT(signing, link))
7809 dns_dbiterator_pause(signing->dbiterator);
7812 * Everything has succeeded. Commit the changes.
7814 dns_db_closeversion(db, &version, commit);
7817 * Everything succeeded so we can clean these up now.
7819 signing = ISC_LIST_HEAD(cleanup);
7820 while (signing != NULL) {
7821 ISC_LIST_UNLINK(cleanup, signing, link);
7822 dns_db_detach(&signing->db);
7823 dns_dbiterator_destroy(&signing->dbiterator);
7824 isc_mem_put(zone->mctx, signing, sizeof *signing);
7825 signing = ISC_LIST_HEAD(cleanup);
7828 set_resigntime(zone);
7832 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7833 zone_needdump(zone, DNS_DUMP_DELAY);
7839 * Rollback the cleanup list.
7841 signing = ISC_LIST_HEAD(cleanup);
7842 while (signing != NULL) {
7843 ISC_LIST_UNLINK(cleanup, signing, link);
7844 ISC_LIST_PREPEND(zone->signing, signing, link);
7845 dns_dbiterator_first(signing->dbiterator);
7846 dns_dbiterator_pause(signing->dbiterator);
7847 signing = ISC_LIST_HEAD(cleanup);
7850 for (signing = ISC_LIST_HEAD(zone->signing);
7852 signing = ISC_LIST_NEXT(signing, link))
7853 dns_dbiterator_pause(signing->dbiterator);
7855 dns_diff_clear(&_sig_diff);
7857 for (i = 0; i < nkeys; i++)
7858 dst_key_free(&zone_keys[i]);
7861 dns_db_detachnode(db, &node);
7863 if (version != NULL) {
7864 dns_db_closeversion(db, &version, ISC_FALSE);
7866 } else if (db != NULL)
7869 if (ISC_LIST_HEAD(zone->signing) != NULL) {
7871 if (zone->update_disabled || result != ISC_R_SUCCESS)
7872 isc_interval_set(&i, 60, 0); /* 1 minute */
7874 isc_interval_set(&i, 0, 10000000); /* 10 ms */
7875 isc_time_nowplusinterval(&zone->signingtime, &i);
7877 isc_time_settoepoch(&zone->signingtime);
7881 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
7882 unsigned char *data, int size) {
7883 dns_rdata_dnskey_t dnskey;
7884 dns_rdata_keydata_t keydata;
7886 isc_result_t result;
7888 dns_rdata_reset(target);
7889 isc_buffer_init(&buf, data, size);
7892 case dns_rdatatype_dnskey:
7893 result = dns_rdata_tostruct(rr, &dnskey, NULL);
7894 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7895 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
7896 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7899 case dns_rdatatype_keydata:
7900 result = dns_rdata_tostruct(rr, &keydata, NULL);
7901 if (result == ISC_R_UNEXPECTEDEND)
7903 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7904 dns_keydata_todnskey(&keydata, &dnskey, NULL);
7905 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7911 return (ISC_R_SUCCESS);
7915 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
7916 * a KEYDATA rdataset from the key zone.
7918 * 'rr' contains either a DNSKEY record, or a KEYDATA record
7920 * After normalizing keys to the same format (DNSKEY, with revoke bit
7921 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
7922 * 'rdset', or ISC_FALSE if not.
7925 static isc_boolean_t
7926 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
7927 unsigned char data1[4096], data2[4096];
7928 dns_rdata_t rdata, rdata1, rdata2;
7929 isc_result_t result;
7931 dns_rdata_init(&rdata);
7932 dns_rdata_init(&rdata1);
7933 dns_rdata_init(&rdata2);
7935 result = normalize_key(rr, &rdata1, data1, sizeof(data1));
7936 if (result != ISC_R_SUCCESS)
7939 for (result = dns_rdataset_first(rdset);
7940 result == ISC_R_SUCCESS;
7941 result = dns_rdataset_next(rdset)) {
7942 dns_rdata_reset(&rdata);
7943 dns_rdataset_current(rdset, &rdata);
7944 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
7945 if (result != ISC_R_SUCCESS)
7947 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
7955 * Calculate the refresh interval for a keydata zone, per
7956 * RFC5011: MAX(1 hr,
7959 * 1/2 * RRSigExpirationInterval))
7960 * or for retries: MAX(1 hr,
7963 * 1/10 * RRSigExpirationInterval))
7965 static inline isc_stdtime_t
7966 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
7967 isc_result_t result;
7969 dns_rdataset_t *rdset;
7970 dns_rdata_t sigrr = DNS_RDATA_INIT;
7971 dns_rdata_sig_t sig;
7974 isc_stdtime_get(&now);
7976 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7977 rdset = &kfetch->dnskeysigset;
7979 return (now + HOUR);
7981 result = dns_rdataset_first(rdset);
7982 if (result != ISC_R_SUCCESS)
7983 return (now + HOUR);
7985 dns_rdataset_current(rdset, &sigrr);
7986 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7987 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7990 t = sig.originalttl / 2;
7992 if (isc_serial_gt(sig.timeexpire, now)) {
7993 isc_uint32_t exp = (sig.timeexpire - now) / 2;
8004 t = sig.originalttl / 10;
8006 if (isc_serial_gt(sig.timeexpire, now)) {
8007 isc_uint32_t exp = (sig.timeexpire - now) / 10;
8023 * This routine is called when no changes are needed in a KEYDATA
8024 * record except to simply update the refresh timer. Caller should
8028 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
8030 isc_result_t result;
8032 unsigned char key_buf[4096];
8033 dns_rdata_t rdata = DNS_RDATA_INIT;
8034 dns_rdata_keydata_t keydata;
8036 dns_zone_t *zone = kfetch->zone;
8039 name = dns_fixedname_name(&kfetch->name);
8040 isc_stdtime_get(&now);
8042 for (result = dns_rdataset_first(&kfetch->keydataset);
8043 result == ISC_R_SUCCESS;
8044 result = dns_rdataset_next(&kfetch->keydataset)) {
8045 dns_rdata_reset(&rdata);
8046 dns_rdataset_current(&kfetch->keydataset, &rdata);
8048 /* Delete old version */
8049 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
8052 /* Update refresh timer */
8053 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
8054 if (result == ISC_R_UNEXPECTEDEND)
8056 if (result != ISC_R_SUCCESS)
8058 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
8059 set_refreshkeytimer(zone, &keydata, now);
8061 dns_rdata_reset(&rdata);
8062 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8063 CHECK(dns_rdata_fromstruct(&rdata,
8064 zone->rdclass, dns_rdatatype_keydata,
8067 /* Insert updated version */
8068 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
8071 result = ISC_R_SUCCESS;
8077 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
8079 static isc_boolean_t
8080 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
8081 isc_result_t result;
8082 dns_name_t *keyname;
8084 dns_rdata_t sigrr = DNS_RDATA_INIT;
8085 dns_rdata_t rr = DNS_RDATA_INIT;
8086 dns_rdata_rrsig_t sig;
8087 dns_rdata_dnskey_t dnskey;
8088 dst_key_t *dstkey = NULL;
8089 unsigned char key_buf[4096];
8091 isc_boolean_t answer = ISC_FALSE;
8093 REQUIRE(kfetch != NULL && keydata != NULL);
8094 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
8096 keyname = dns_fixedname_name(&kfetch->name);
8097 mctx = kfetch->zone->view->mctx;
8099 /* Generate a key from keydata */
8100 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8101 dns_keydata_todnskey(keydata, &dnskey, NULL);
8102 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
8104 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
8105 if (result != ISC_R_SUCCESS)
8108 /* See if that key generated any of the signatures */
8109 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8110 result == ISC_R_SUCCESS;
8111 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
8112 dns_fixedname_t fixed;
8113 dns_fixedname_init(&fixed);
8115 dns_rdata_reset(&sigrr);
8116 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8117 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8118 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8120 if (dst_key_alg(dstkey) == sig.algorithm &&
8121 (dst_key_id(dstkey) == sig.keyid ||
8122 dst_key_rid(dstkey) == sig.keyid)) {
8123 result = dns_dnssec_verify2(keyname,
8125 dstkey, ISC_FALSE, mctx, &sigrr,
8126 dns_fixedname_name(&fixed));
8128 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
8129 "Confirm revoked DNSKEY is self-signed: "
8130 "%s", dns_result_totext(result));
8132 if (result == ISC_R_SUCCESS) {
8139 dst_key_free(&dstkey);
8144 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
8145 * anchors are being managed; scan the keyset, and update the key zone and the
8146 * local trust anchors according to RFC5011.
8149 keyfetch_done(isc_task_t *task, isc_event_t *event) {
8150 isc_result_t result, eresult;
8151 dns_fetchevent_t *devent;
8152 dns_keyfetch_t *kfetch;
8154 isc_mem_t *mctx = NULL;
8155 dns_keytable_t *secroots = NULL;
8156 dns_dbversion_t *ver = NULL;
8158 isc_boolean_t alldone = ISC_FALSE;
8159 isc_boolean_t commit = ISC_FALSE;
8160 dns_name_t *keyname;
8161 dns_rdata_t sigrr = DNS_RDATA_INIT;
8162 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
8163 dns_rdata_t keydatarr = DNS_RDATA_INIT;
8164 dns_rdata_rrsig_t sig;
8165 dns_rdata_dnskey_t dnskey;
8166 dns_rdata_keydata_t keydata;
8167 isc_boolean_t initializing;
8168 char namebuf[DNS_NAME_FORMATSIZE];
8169 unsigned char key_buf[4096];
8174 isc_boolean_t secure;
8175 isc_boolean_t free_needed;
8178 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
8179 INSIST(event->ev_arg != NULL);
8181 kfetch = event->ev_arg;
8182 zone = kfetch->zone;
8183 isc_mem_attach(zone->mctx, &mctx);
8184 keyname = dns_fixedname_name(&kfetch->name);
8186 devent = (dns_fetchevent_t *) event;
8187 eresult = devent->result;
8189 /* Free resources which are not of interest */
8190 if (devent->node != NULL)
8191 dns_db_detachnode(devent->db, &devent->node);
8192 if (devent->db != NULL)
8193 dns_db_detach(&devent->db);
8194 isc_event_free(&event);
8195 dns_resolver_destroyfetch(&kfetch->fetch);
8198 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
8201 isc_stdtime_get(&now);
8202 dns_name_format(keyname, namebuf, sizeof(namebuf));
8204 result = dns_view_getsecroots(zone->view, &secroots);
8205 INSIST(result == ISC_R_SUCCESS);
8207 dns_diff_init(mctx, &diff);
8209 CHECK(dns_db_newversion(kfetch->db, &ver));
8211 zone->refreshkeycount--;
8212 alldone = ISC_TF(zone->refreshkeycount == 0);
8215 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8218 if (eresult != ISC_R_SUCCESS ||
8219 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
8220 dns_zone_log(zone, ISC_LOG_WARNING,
8221 "Unable to fetch DNSKEY set "
8222 "'%s': %s", namebuf, dns_result_totext(eresult));
8223 CHECK(minimal_update(kfetch, ver, &diff));
8227 /* No RRSIGs found */
8228 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
8229 dns_zone_log(zone, ISC_LOG_WARNING,
8230 "No DNSKEY RRSIGs found for "
8231 "'%s': %s", namebuf, dns_result_totext(eresult));
8232 CHECK(minimal_update(kfetch, ver, &diff));
8237 * Validate the dnskeyset against the current trusted keys.
8239 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8240 result == ISC_R_SUCCESS;
8241 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
8242 dns_keynode_t *keynode = NULL;
8244 dns_rdata_reset(&sigrr);
8245 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8246 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8247 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8249 result = dns_keytable_find(secroots, keyname, &keynode);
8250 while (result == ISC_R_SUCCESS) {
8251 dns_keynode_t *nextnode = NULL;
8252 dns_fixedname_t fixed;
8253 dns_fixedname_init(&fixed);
8255 dstkey = dns_keynode_key(keynode);
8256 if (dstkey == NULL) /* fail_secure() was called */
8259 if (dst_key_alg(dstkey) == sig.algorithm &&
8260 dst_key_id(dstkey) == sig.keyid) {
8261 result = dns_dnssec_verify2(keyname,
8264 zone->view->mctx, &sigrr,
8265 dns_fixedname_name(&fixed));
8267 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8268 "Verifying DNSKEY set for zone "
8269 "'%s': %s", namebuf,
8270 dns_result_totext(result));
8272 if (result == ISC_R_SUCCESS) {
8273 kfetch->dnskeyset.trust =
8275 kfetch->dnskeysigset.trust =
8277 dns_keytable_detachkeynode(secroots,
8283 result = dns_keytable_nextkeynode(secroots,
8284 keynode, &nextnode);
8285 dns_keytable_detachkeynode(secroots, &keynode);
8289 if (kfetch->dnskeyset.trust == dns_trust_secure)
8294 * If we were not able to verify the answer using the current
8295 * trusted keys then all we can do is look at any revoked keys.
8297 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
8300 * First scan keydataset to find keys that are not in dnskeyset
8301 * - Missing keys which are not scheduled for removal,
8303 * - Missing keys which are scheduled for removal and
8304 * the remove hold-down timer has completed should
8305 * be removed from the key zone
8306 * - Missing keys whose acceptance timers have not yet
8307 * completed, log a warning and reset the acceptance
8308 * timer to 30 days in the future
8309 * - All keys not being removed have their refresh timers
8312 initializing = ISC_TRUE;
8313 for (result = dns_rdataset_first(&kfetch->keydataset);
8314 result == ISC_R_SUCCESS;
8315 result = dns_rdataset_next(&kfetch->keydataset)) {
8316 dns_rdata_reset(&keydatarr);
8317 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8318 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8319 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8322 * If any keydata record has a nonzero add holddown, then
8323 * there was a pre-existing trust anchor for this domain;
8324 * that means we are *not* initializing it and shouldn't
8325 * automatically trust all the keys we find at the zone apex.
8327 initializing = initializing && ISC_TF(keydata.addhd == 0);
8329 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
8330 isc_boolean_t deletekey = ISC_FALSE;
8333 if (now > keydata.removehd)
8334 deletekey = ISC_TRUE;
8335 } else if (now < keydata.addhd) {
8336 dns_zone_log(zone, ISC_LOG_WARNING,
8337 "Pending key unexpectedly missing "
8338 "from %s; restarting acceptance "
8340 keydata.addhd = now + MONTH;
8341 keydata.refresh = refresh_time(kfetch,
8343 } else if (keydata.addhd == 0) {
8344 keydata.addhd = now;
8345 } else if (keydata.removehd == 0) {
8346 dns_zone_log(zone, ISC_LOG_WARNING,
8347 "Active key unexpectedly missing "
8348 "from %s", namebuf);
8349 keydata.refresh = now + HOUR;
8350 } else if (now > keydata.removehd) {
8351 deletekey = ISC_TRUE;
8353 keydata.refresh = refresh_time(kfetch,
8357 if (secure || deletekey) {
8358 /* Delete old version */
8359 CHECK(update_one_rr(kfetch->db, ver, &diff,
8360 DNS_DIFFOP_DEL, keyname, 0,
8364 if (!secure || deletekey)
8367 dns_rdata_reset(&keydatarr);
8368 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8369 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8370 dns_rdatatype_keydata,
8373 /* Insert updated version */
8374 CHECK(update_one_rr(kfetch->db, ver, &diff,
8375 DNS_DIFFOP_ADD, keyname, 0,
8378 set_refreshkeytimer(zone, &keydata, now);
8383 * Next scan dnskeyset:
8384 * - If new keys are found (i.e., lacking a match in keydataset)
8385 * add them to the key zone and set the acceptance timer
8386 * to 30 days in the future (or to immediately if we've
8387 * determined that we're initializing the zone for the
8389 * - Previously-known keys that have been revoked
8390 * must be scheduled for removal from the key zone (or,
8391 * if they hadn't been accepted as trust anchors yet
8392 * anyway, removed at once)
8393 * - Previously-known unrevoked keys whose acceptance timers
8394 * have completed are promoted to trust anchors
8395 * - All keys not being removed have their refresh
8398 for (result = dns_rdataset_first(&kfetch->dnskeyset);
8399 result == ISC_R_SUCCESS;
8400 result = dns_rdataset_next(&kfetch->dnskeyset)) {
8401 isc_boolean_t revoked = ISC_FALSE;
8402 isc_boolean_t newkey = ISC_FALSE;
8403 isc_boolean_t updatekey = ISC_FALSE;
8404 isc_boolean_t deletekey = ISC_FALSE;
8405 isc_boolean_t trustkey = ISC_FALSE;
8407 dns_rdata_reset(&dnskeyrr);
8408 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
8409 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8410 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8413 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
8416 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
8418 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
8419 dns_rdata_reset(&keydatarr);
8420 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8421 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8422 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8424 if (revoked && revocable(kfetch, &keydata)) {
8425 if (keydata.addhd > now) {
8427 * Key wasn't trusted yet, and now
8428 * it's been revoked? Just remove it
8430 deletekey = ISC_TRUE;
8431 } else if (keydata.removehd == 0) {
8432 /* Remove from secroots */
8433 dns_view_untrust(zone->view, keyname,
8436 /* If initializing, delete now */
8437 if (keydata.addhd == 0)
8438 deletekey = ISC_TRUE;
8440 keydata.removehd = now + MONTH;
8441 } else if (keydata.removehd < now) {
8442 /* Scheduled for removal */
8443 deletekey = ISC_TRUE;
8445 } else if (revoked) {
8446 if (secure && keydata.removehd == 0) {
8447 dns_zone_log(zone, ISC_LOG_WARNING,
8448 "Active key for zone "
8449 "'%s' is revoked but "
8450 "did not self-sign; "
8451 "ignoring.", namebuf);
8454 } else if (secure) {
8455 if (keydata.removehd != 0) {
8457 * Key isn't revoked--but it
8458 * seems it used to be.
8459 * Remove it now and add it
8460 * back as if it were a fresh key.
8462 deletekey = ISC_TRUE;
8464 } else if (keydata.addhd > now)
8466 else if (keydata.addhd == 0)
8467 keydata.addhd = now;
8469 if (keydata.addhd <= now)
8470 trustkey = ISC_TRUE;
8473 if (!deletekey && !newkey)
8474 updatekey = ISC_TRUE;
8475 } else if (secure) {
8477 * Key wasn't in the key zone but it's
8478 * revoked now anyway, so just skip it
8483 /* Key wasn't in the key zone: add it */
8487 dns_keytag_t tag = 0;
8488 CHECK(compute_tag(keyname, &dnskey,
8490 dns_zone_log(zone, ISC_LOG_WARNING,
8491 "Initializing automatic trust "
8492 "anchor management for zone '%s'; "
8493 "DNSKEY ID %d is now trusted, "
8494 "waiving the normal 30-day "
8497 trustkey = ISC_TRUE;
8501 * No previously known key, and the key is not
8502 * secure, so skip it.
8507 /* Delete old version */
8508 if (deletekey || !newkey)
8509 CHECK(update_one_rr(kfetch->db, ver, &diff,
8510 DNS_DIFFOP_DEL, keyname, 0,
8514 /* Set refresh timer */
8515 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
8516 dns_rdata_reset(&keydatarr);
8517 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8518 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8519 dns_rdatatype_keydata,
8522 /* Insert updated version */
8523 CHECK(update_one_rr(kfetch->db, ver, &diff,
8524 DNS_DIFFOP_ADD, keyname, 0,
8526 } else if (newkey) {
8527 /* Convert DNSKEY to KEYDATA */
8528 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8529 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8530 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
8532 keydata.addhd = initializing ? now : now + MONTH;
8533 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
8534 dns_rdata_reset(&keydatarr);
8535 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8536 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8537 dns_rdatatype_keydata,
8540 /* Insert into key zone */
8541 CHECK(update_one_rr(kfetch->db, ver, &diff,
8542 DNS_DIFFOP_ADD, keyname, 0,
8547 /* Trust this key. */
8548 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8549 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8550 trust_key(zone, keyname, &dnskey, mctx);
8553 if (secure && !deletekey)
8554 set_refreshkeytimer(zone, &keydata, now);
8558 * RFC5011 says, "A trust point that has all of its trust anchors
8559 * revoked is considered deleted and is treated as if the trust
8560 * point was never configured." But if someone revoked their
8561 * active key before the standby was trusted, that would mean the
8562 * zone would suddenly be nonsecured. We avoid this by checking to
8563 * see if there's pending keydata. If so, we put a null key in
8564 * the security roots; then all queries to the zone will fail.
8567 fail_secure(zone, keyname);
8571 if (!ISC_LIST_EMPTY(diff.tuples)) {
8572 /* Write changes to journal file. */
8573 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
8574 zone->updatemethod));
8575 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
8578 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8579 zone_needdump(zone, 30);
8584 dns_diff_clear(&diff);
8586 dns_db_closeversion(kfetch->db, &ver, commit);
8589 dns_db_detach(&kfetch->db);
8591 INSIST(zone->irefs > 0);
8593 kfetch->zone = NULL;
8595 if (dns_rdataset_isassociated(&kfetch->keydataset))
8596 dns_rdataset_disassociate(&kfetch->keydataset);
8597 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
8598 dns_rdataset_disassociate(&kfetch->dnskeyset);
8599 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8600 dns_rdataset_disassociate(&kfetch->dnskeysigset);
8602 dns_name_free(keyname, mctx);
8603 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
8604 isc_mem_detach(&mctx);
8606 if (secroots != NULL)
8607 dns_keytable_detach(&secroots);
8609 free_needed = exit_check(zone);
8616 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
8617 * records from the zone apex.
8620 zone_refreshkeys(dns_zone_t *zone) {
8621 const char me[] = "zone_refreshkeys";
8622 isc_result_t result;
8623 dns_rriterator_t rrit;
8624 dns_db_t *db = NULL;
8625 dns_dbversion_t *ver = NULL;
8627 dns_rdata_t rdata = DNS_RDATA_INIT;
8628 dns_rdata_keydata_t kd;
8630 isc_boolean_t commit = ISC_FALSE;
8631 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
8634 REQUIRE(zone->db != NULL);
8636 isc_stdtime_get(&now);
8639 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
8640 isc_time_settoepoch(&zone->refreshkeytime);
8645 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8646 dns_db_attach(zone->db, &db);
8647 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8649 dns_diff_init(zone->mctx, &diff);
8651 CHECK(dns_db_newversion(db, &ver));
8653 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
8655 dns_rriterator_init(&rrit, db, ver, 0);
8656 for (result = dns_rriterator_first(&rrit);
8657 result == ISC_R_SUCCESS;
8658 result = dns_rriterator_nextrrset(&rrit)) {
8659 isc_stdtime_t timer = 0xffffffff;
8660 dns_name_t *name = NULL, *kname = NULL;
8661 dns_rdataset_t *kdset = NULL;
8662 dns_keyfetch_t *kfetch;
8665 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
8666 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
8667 !dns_rdataset_isassociated(kdset))
8671 * Scan the stored keys looking for ones that need
8672 * removal or refreshing
8674 for (result = dns_rdataset_first(kdset);
8675 result == ISC_R_SUCCESS;
8676 result = dns_rdataset_next(kdset)) {
8677 dns_rdata_reset(&rdata);
8678 dns_rdataset_current(kdset, &rdata);
8679 result = dns_rdata_tostruct(&rdata, &kd, NULL);
8680 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8682 /* Removal timer expired? */
8683 if (kd.removehd != 0 && kd.removehd < now) {
8684 CHECK(update_one_rr(db, ver, &diff,
8685 DNS_DIFFOP_DEL, name, ttl,
8690 /* Acceptance timer expired? */
8691 if (kd.addhd != 0 && kd.addhd < now)
8694 /* Or do we just need to refresh the keyset? */
8695 if (timer > kd.refresh)
8702 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
8703 if (kfetch == NULL) {
8704 fetch_err = ISC_TRUE;
8708 zone->refreshkeycount++;
8709 kfetch->zone = zone;
8711 INSIST(zone->irefs != 0);
8712 dns_fixedname_init(&kfetch->name);
8713 kname = dns_fixedname_name(&kfetch->name);
8714 dns_name_dup(name, zone->mctx, kname);
8715 dns_rdataset_init(&kfetch->dnskeyset);
8716 dns_rdataset_init(&kfetch->dnskeysigset);
8717 dns_rdataset_init(&kfetch->keydataset);
8718 dns_rdataset_clone(kdset, &kfetch->keydataset);
8720 dns_db_attach(db, &kfetch->db);
8721 kfetch->fetch = NULL;
8723 result = dns_resolver_createfetch(zone->view->resolver,
8724 kname, dns_rdatatype_dnskey,
8726 DNS_FETCHOPT_NOVALIDATE,
8728 keyfetch_done, kfetch,
8730 &kfetch->dnskeysigset,
8732 if (result == ISC_R_SUCCESS)
8733 fetching = ISC_TRUE;
8735 zone->refreshkeycount--;
8737 dns_db_detach(&kfetch->db);
8738 dns_rdataset_disassociate(&kfetch->keydataset);
8739 dns_name_free(kname, zone->mctx);
8740 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
8741 dns_zone_log(zone, ISC_LOG_WARNING,
8742 "Failed to create fetch for "
8744 fetch_err = ISC_TRUE;
8747 if (!ISC_LIST_EMPTY(diff.tuples)) {
8748 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
8749 zone->updatemethod));
8750 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
8752 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8753 zone_needdump(zone, 30);
8759 * Error during a key fetch; retry in an hour.
8761 isc_time_t timenow, timethen;
8765 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
8766 zone->refreshkeytime = timethen;
8767 zone_settimer(zone, &timenow);
8769 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
8770 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
8774 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8779 dns_diff_clear(&diff);
8781 dns_rriterator_destroy(&rrit);
8782 dns_db_closeversion(db, &ver, commit);
8788 zone_maintenance(dns_zone_t *zone) {
8789 const char me[] = "zone_maintenance";
8791 isc_result_t result;
8792 isc_boolean_t dumping;
8794 REQUIRE(DNS_ZONE_VALID(zone));
8798 * Are we pending load/reload?
8800 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
8804 * Configuring the view of this zone may have
8805 * failed, for example because the config file
8806 * had a syntax error. In that case, the view
8807 * adb or resolver will be NULL, and we had better not try
8808 * to do further maintenance on it.
8810 if (zone->view == NULL || zone->view->adb == NULL)
8818 switch (zone->type) {
8819 case dns_zone_redirect:
8820 if (zone->masters == NULL)
8822 case dns_zone_slave:
8825 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
8826 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8828 zone->refreshtime = now;
8839 switch (zone->type) {
8840 case dns_zone_redirect:
8841 if (zone->masters == NULL)
8843 case dns_zone_slave:
8845 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
8846 isc_time_compare(&now, &zone->refreshtime) >= 0)
8847 dns_zone_refresh(zone);
8854 * Slaves send notifies before backing up to disk, masters after.
8856 if (zone->type == dns_zone_slave &&
8857 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8858 isc_time_compare(&now, &zone->notifytime) >= 0)
8859 zone_notify(zone, &now);
8862 * Do we need to consolidate the backing store?
8864 switch (zone->type) {
8865 case dns_zone_master:
8866 case dns_zone_slave:
8868 case dns_zone_redirect:
8871 if (zone->masterfile != NULL &&
8872 isc_time_compare(&now, &zone->dumptime) >= 0 &&
8873 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8874 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
8875 dumping = was_dumping(zone);
8880 result = zone_dump(zone, ISC_TRUE); /* task locked */
8881 if (result != ISC_R_SUCCESS)
8882 dns_zone_log(zone, ISC_LOG_WARNING,
8884 dns_result_totext(result));
8892 * Master/redirect zones send notifies now, if needed
8894 switch (zone->type) {
8895 case dns_zone_master:
8896 case dns_zone_redirect:
8897 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8898 isc_time_compare(&now, &zone->notifytime) >= 0)
8899 zone_notify(zone, &now);
8905 * Do we need to refresh keys?
8907 switch (zone->type) {
8909 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
8910 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8911 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
8912 zone_refreshkeys(zone);
8916 case dns_zone_master:
8917 if (!isc_time_isepoch(&zone->refreshkeytime) &&
8918 isc_time_compare(&now, &zone->refreshkeytime) >= 0)
8924 switch (zone->type) {
8925 case dns_zone_master:
8926 case dns_zone_redirect:
8927 case dns_zone_slave:
8929 * Do we need to sign/resign some RRsets?
8931 if (!isc_time_isepoch(&zone->signingtime) &&
8932 isc_time_compare(&now, &zone->signingtime) >= 0)
8934 else if (!isc_time_isepoch(&zone->resigntime) &&
8935 isc_time_compare(&now, &zone->resigntime) >= 0)
8936 zone_resigninc(zone);
8937 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
8938 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
8939 zone_nsec3chain(zone);
8941 * Do we need to issue a key expiry warning?
8943 if (!isc_time_isepoch(&zone->keywarntime) &&
8944 isc_time_compare(&now, &zone->keywarntime) >= 0)
8945 set_key_expiry_warning(zone, zone->key_expiry,
8946 isc_time_seconds(&now));
8952 zone_settimer(zone, &now);
8956 dns_zone_markdirty(dns_zone_t *zone) {
8957 isc_uint32_t serial;
8958 isc_result_t result = ISC_R_SUCCESS;
8959 dns_zone_t *secure = NULL;
8962 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
8963 * could result in a deadlock due to a LOR so we will spin if we
8964 * can't obtain the both locks.
8968 if (zone->type == dns_zone_master) {
8969 if (inline_raw(zone)) {
8970 unsigned int soacount;
8971 secure = zone->secure;
8972 INSIST(secure != zone);
8973 TRYLOCK_ZONE(result, secure);
8974 if (result != ISC_R_SUCCESS) {
8977 #ifdef ISC_PLATFORM_USETHREADS
8983 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8984 if (zone->db != NULL) {
8985 result = zone_get_from_db(zone, zone->db, NULL,
8990 result = DNS_R_NOTLOADED;
8991 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8992 if (result == ISC_R_SUCCESS && soacount > 0U)
8993 zone_send_secureserial(zone, serial);
8996 /* XXXMPA make separate call back */
8997 if (result == ISC_R_SUCCESS)
8998 set_resigntime(zone);
9001 UNLOCK_ZONE(secure);
9002 zone_needdump(zone, DNS_DUMP_DELAY);
9007 dns_zone_expire(dns_zone_t *zone) {
9008 REQUIRE(DNS_ZONE_VALID(zone));
9016 zone_expire(dns_zone_t *zone) {
9018 * 'zone' locked by caller.
9021 REQUIRE(LOCKED_ZONE(zone));
9023 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
9025 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
9026 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9027 zone->retry = DNS_ZONE_DEFAULTRETRY;
9028 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9033 dns_zone_refresh(dns_zone_t *zone) {
9035 isc_uint32_t oldflags;
9037 isc_result_t result;
9039 REQUIRE(DNS_ZONE_VALID(zone));
9041 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9045 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
9046 * in progress at a time.
9050 oldflags = zone->flags;
9051 if (zone->masterscnt == 0) {
9052 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
9053 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
9054 dns_zone_log(zone, ISC_LOG_ERROR,
9055 "cannot refresh: no masters");
9058 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9059 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9060 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9061 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
9065 * Set the next refresh time as if refresh check has failed.
9066 * Setting this to the retry time will do that. XXXMLG
9067 * If we are successful it will be reset using zone->refresh.
9069 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
9071 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
9072 if (result != ISC_R_SUCCESS)
9073 dns_zone_log(zone, ISC_LOG_WARNING,
9074 "isc_time_nowplusinterval() failed: %s",
9075 dns_result_totext(result));
9078 * When lacking user-specified timer values from the SOA,
9079 * do exponential backoff of the retry time up to a
9080 * maximum of six hours.
9082 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
9083 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
9085 zone->curmaster = 0;
9086 for (j = 0; j < zone->masterscnt; j++)
9087 zone->mastersok[j] = ISC_FALSE;
9088 /* initiate soa query */
9089 queue_soa_query(zone);
9095 dns_zone_flush(dns_zone_t *zone) {
9096 isc_result_t result = ISC_R_SUCCESS;
9097 isc_boolean_t dumping;
9099 REQUIRE(DNS_ZONE_VALID(zone));
9102 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
9103 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9104 zone->masterfile != NULL) {
9105 result = ISC_R_ALREADYRUNNING;
9106 dumping = was_dumping(zone);
9111 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
9116 dns_zone_dump(dns_zone_t *zone) {
9117 isc_result_t result = ISC_R_ALREADYRUNNING;
9118 isc_boolean_t dumping;
9120 REQUIRE(DNS_ZONE_VALID(zone));
9123 dumping = was_dumping(zone);
9126 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
9131 zone_needdump(dns_zone_t *zone, unsigned int delay) {
9132 const char me[] = "zone_needdump";
9133 isc_time_t dumptime;
9137 * 'zone' locked by caller
9140 REQUIRE(DNS_ZONE_VALID(zone));
9141 REQUIRE(LOCKED_ZONE(zone));
9145 * Do we have a place to dump to and are we loaded?
9147 if (zone->masterfile == NULL ||
9148 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
9152 /* add some noise */
9153 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
9155 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9156 if (isc_time_isepoch(&zone->dumptime) ||
9157 isc_time_compare(&zone->dumptime, &dumptime) > 0)
9158 zone->dumptime = dumptime;
9159 if (zone->task != NULL)
9160 zone_settimer(zone, &now);
9164 dump_done(void *arg, isc_result_t result) {
9165 const char me[] = "dump_done";
9166 dns_zone_t *zone = arg;
9168 dns_dbversion_t *version;
9169 isc_boolean_t again = ISC_FALSE;
9170 isc_boolean_t compact = ISC_FALSE;
9171 isc_uint32_t serial;
9172 isc_result_t tresult;
9174 REQUIRE(DNS_ZONE_VALID(zone));
9178 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
9179 zone->journalsize != -1) {
9182 * We don't own these, zone->dctx must stay valid.
9184 db = dns_dumpctx_db(zone->dctx);
9185 version = dns_dumpctx_version(zone->dctx);
9187 tresult = dns_db_getsoaserial(db, version, &serial);
9189 * If there is a secure version of this zone
9190 * use its serial if it is less than ours.
9192 if (tresult == ISC_R_SUCCESS && inline_raw(zone) &&
9193 zone->secure->db != NULL)
9195 isc_uint32_t sserial;
9196 isc_result_t mresult;
9198 mresult = dns_db_getsoaserial(zone->secure->db,
9200 if (mresult == ISC_R_SUCCESS &&
9201 isc_serial_lt(sserial, serial))
9205 * Note: we are task locked here so we can test
9208 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
9209 tresult = dns_journal_compact(zone->mctx,
9216 case ISC_R_NOTFOUND:
9217 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9218 "dns_journal_compact: %s",
9219 dns_result_totext(tresult));
9222 dns_zone_log(zone, ISC_LOG_ERROR,
9223 "dns_journal_compact failed: %s",
9224 dns_result_totext(tresult));
9227 } else if (tresult == ISC_R_SUCCESS) {
9229 zone->compact_serial = serial;
9234 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9236 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9237 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
9239 * Try again in a short while.
9241 zone_needdump(zone, DNS_DUMP_DELAY);
9242 } else if (result == ISC_R_SUCCESS &&
9243 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9244 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9245 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9246 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9247 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9248 isc_time_settoepoch(&zone->dumptime);
9250 } else if (result == ISC_R_SUCCESS)
9251 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9253 if (zone->dctx != NULL)
9254 dns_dumpctx_detach(&zone->dctx);
9255 zonemgr_putio(&zone->writeio);
9258 (void)zone_dump(zone, ISC_FALSE);
9259 dns_zone_idetach(&zone);
9263 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
9264 const char me[] = "zone_dump";
9265 isc_result_t result;
9266 dns_dbversion_t *version = NULL;
9267 isc_boolean_t again;
9268 dns_db_t *db = NULL;
9269 char *masterfile = NULL;
9270 dns_masterformat_t masterformat = dns_masterformat_none;
9273 * 'compact' MUST only be set if we are task locked.
9276 REQUIRE(DNS_ZONE_VALID(zone));
9280 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9281 if (zone->db != NULL)
9282 dns_db_attach(zone->db, &db);
9283 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9285 if (zone->masterfile != NULL) {
9286 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
9287 masterformat = zone->masterformat;
9291 result = DNS_R_NOTLOADED;
9294 if (masterfile == NULL) {
9295 result = DNS_R_NOMASTERFILE;
9299 if (compact && zone->type != dns_zone_stub) {
9300 dns_zone_t *dummy = NULL;
9302 zone_iattach(zone, &dummy);
9303 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
9304 zone_gotwritehandle, zone,
9306 if (result != ISC_R_SUCCESS)
9307 zone_idetach(&dummy);
9309 result = DNS_R_CONTINUE;
9312 const dns_master_style_t *output_style;
9314 dns_masterrawheader_t rawdata;
9315 dns_db_currentversion(db, &version);
9316 dns_master_initrawheader(&rawdata);
9317 if (inline_secure(zone))
9318 get_raw_serial(zone->raw, &rawdata);
9319 if (zone->type == dns_zone_key)
9320 output_style = &dns_master_style_keyzone;
9322 output_style = &dns_master_style_default;
9323 result = dns_master_dump3(zone->mctx, db, version,
9324 output_style, masterfile,
9325 masterformat, &rawdata);
9326 dns_db_closeversion(db, &version, ISC_FALSE);
9331 if (masterfile != NULL)
9332 isc_mem_free(zone->mctx, masterfile);
9335 if (result == DNS_R_CONTINUE)
9336 return (ISC_R_SUCCESS); /* XXXMPA */
9340 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9341 if (result != ISC_R_SUCCESS) {
9343 * Try again in a short while.
9345 zone_needdump(zone, DNS_DUMP_DELAY);
9346 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9347 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9348 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9349 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9350 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9351 isc_time_settoepoch(&zone->dumptime);
9354 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9363 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
9364 dns_masterformat_t format, const isc_uint32_t rawversion)
9366 isc_result_t result;
9367 dns_dbversion_t *version = NULL;
9368 dns_db_t *db = NULL;
9369 dns_masterrawheader_t rawdata;
9371 REQUIRE(DNS_ZONE_VALID(zone));
9373 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9374 if (zone->db != NULL)
9375 dns_db_attach(zone->db, &db);
9376 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9378 return (DNS_R_NOTLOADED);
9380 dns_db_currentversion(db, &version);
9381 dns_master_initrawheader(&rawdata);
9382 if (rawversion == 0)
9383 rawdata.flags |= DNS_MASTERRAW_COMPAT;
9384 else if (inline_secure(zone))
9385 get_raw_serial(zone->raw, &rawdata);
9386 else if (zone->sourceserialset) {
9387 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
9388 rawdata.sourceserial = zone->sourceserial;
9390 result = dns_master_dumptostream3(zone->mctx, db, version, style,
9391 format, &rawdata, fd);
9392 dns_db_closeversion(db, &version, ISC_FALSE);
9398 dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9399 const dns_master_style_t *style,
9400 const isc_uint32_t rawversion)
9402 return (dumptostream(zone, fd, style, format, rawversion));
9406 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9407 const dns_master_style_t *style) {
9408 return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
9412 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
9413 return (dumptostream(zone, fd, &dns_master_style_default,
9414 dns_masterformat_text, 0));
9418 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
9419 return (dumptostream(zone, fd, &dns_master_style_full,
9420 dns_masterformat_text, 0));
9424 dns_zone_unload(dns_zone_t *zone) {
9425 REQUIRE(DNS_ZONE_VALID(zone));
9433 notify_cancel(dns_zone_t *zone) {
9434 dns_notify_t *notify;
9437 * 'zone' locked by caller.
9440 REQUIRE(LOCKED_ZONE(zone));
9442 for (notify = ISC_LIST_HEAD(zone->notifies);
9444 notify = ISC_LIST_NEXT(notify, link)) {
9445 if (notify->find != NULL)
9446 dns_adb_cancelfind(notify->find);
9447 if (notify->request != NULL)
9448 dns_request_cancel(notify->request);
9453 forward_cancel(dns_zone_t *zone) {
9454 dns_forward_t *forward;
9457 * 'zone' locked by caller.
9460 REQUIRE(LOCKED_ZONE(zone));
9462 for (forward = ISC_LIST_HEAD(zone->forwards);
9464 forward = ISC_LIST_NEXT(forward, link)) {
9465 if (forward->request != NULL)
9466 dns_request_cancel(forward->request);
9471 zone_unload(dns_zone_t *zone) {
9473 * 'zone' locked by caller.
9476 REQUIRE(LOCKED_ZONE(zone));
9478 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
9479 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
9480 if (zone->writeio != NULL)
9481 zonemgr_cancelio(zone->writeio);
9483 if (zone->dctx != NULL)
9484 dns_dumpctx_cancel(zone->dctx);
9486 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9487 zone_detachdb(zone);
9488 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9489 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
9490 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9494 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
9495 REQUIRE(DNS_ZONE_VALID(zone));
9498 zone->minrefresh = val;
9502 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
9503 REQUIRE(DNS_ZONE_VALID(zone));
9506 zone->maxrefresh = val;
9510 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
9511 REQUIRE(DNS_ZONE_VALID(zone));
9514 zone->minretry = val;
9518 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
9519 REQUIRE(DNS_ZONE_VALID(zone));
9522 zone->maxretry = val;
9525 static isc_boolean_t
9526 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
9527 dns_notify_t *notify;
9529 for (notify = ISC_LIST_HEAD(zone->notifies);
9531 notify = ISC_LIST_NEXT(notify, link)) {
9532 if (notify->request != NULL)
9534 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
9535 dns_name_equal(name, ¬ify->ns))
9537 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
9543 static isc_boolean_t
9544 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
9545 dns_tsigkey_t *key = NULL;
9548 isc_boolean_t isself;
9549 isc_netaddr_t dstaddr;
9550 isc_result_t result;
9552 if (zone->view == NULL || zone->isself == NULL)
9555 switch (isc_sockaddr_pf(dst)) {
9557 src = zone->notifysrc4;
9558 isc_sockaddr_any(&any);
9561 src = zone->notifysrc6;
9562 isc_sockaddr_any6(&any);
9569 * When sending from any the kernel will assign a source address
9570 * that matches the destination address.
9572 if (isc_sockaddr_eqaddr(&any, &src))
9575 isc_netaddr_fromsockaddr(&dstaddr, dst);
9576 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
9577 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
9579 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
9582 dns_tsigkey_detach(&key);
9587 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
9591 * Caller holds zone lock.
9593 REQUIRE(DNS_NOTIFY_VALID(notify));
9595 if (notify->zone != NULL) {
9597 LOCK_ZONE(notify->zone);
9598 REQUIRE(LOCKED_ZONE(notify->zone));
9599 if (ISC_LINK_LINKED(notify, link))
9600 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
9602 UNLOCK_ZONE(notify->zone);
9604 zone_idetach(¬ify->zone);
9606 dns_zone_idetach(¬ify->zone);
9608 if (notify->find != NULL)
9609 dns_adb_destroyfind(¬ify->find);
9610 if (notify->request != NULL)
9611 dns_request_destroy(¬ify->request);
9612 if (dns_name_dynamic(¬ify->ns))
9613 dns_name_free(¬ify->ns, notify->mctx);
9614 if (notify->key != NULL)
9615 dns_tsigkey_detach(¬ify->key);
9616 mctx = notify->mctx;
9617 isc_mem_put(notify->mctx, notify, sizeof(*notify));
9618 isc_mem_detach(&mctx);
9622 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
9623 dns_notify_t *notify;
9625 REQUIRE(notifyp != NULL && *notifyp == NULL);
9627 notify = isc_mem_get(mctx, sizeof(*notify));
9629 return (ISC_R_NOMEMORY);
9631 notify->mctx = NULL;
9632 isc_mem_attach(mctx, ¬ify->mctx);
9633 notify->flags = flags;
9634 notify->zone = NULL;
9635 notify->find = NULL;
9636 notify->request = NULL;
9638 isc_sockaddr_any(¬ify->dst);
9639 dns_name_init(¬ify->ns, NULL);
9640 ISC_LINK_INIT(notify, link);
9641 notify->magic = NOTIFY_MAGIC;
9643 return (ISC_R_SUCCESS);
9647 * XXXAG should check for DNS_ZONEFLG_EXITING
9650 process_adb_event(isc_task_t *task, isc_event_t *ev) {
9651 dns_notify_t *notify;
9652 isc_eventtype_t result;
9656 notify = ev->ev_arg;
9657 REQUIRE(DNS_NOTIFY_VALID(notify));
9658 INSIST(task == notify->zone->task);
9659 result = ev->ev_type;
9660 isc_event_free(&ev);
9661 if (result == DNS_EVENT_ADBMOREADDRESSES) {
9662 dns_adb_destroyfind(¬ify->find);
9663 notify_find_address(notify);
9666 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
9667 LOCK_ZONE(notify->zone);
9668 notify_send(notify);
9669 UNLOCK_ZONE(notify->zone);
9671 notify_destroy(notify, ISC_FALSE);
9675 notify_find_address(dns_notify_t *notify) {
9676 isc_result_t result;
9677 unsigned int options;
9679 REQUIRE(DNS_NOTIFY_VALID(notify));
9680 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
9681 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
9683 if (notify->zone->view->adb == NULL)
9686 result = dns_adb_createfind(notify->zone->view->adb,
9688 process_adb_event, notify,
9689 ¬ify->ns, dns_rootname, 0,
9691 notify->zone->view->dstport,
9694 /* Something failed? */
9695 if (result != ISC_R_SUCCESS)
9698 /* More addresses pending? */
9699 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
9702 /* We have as many addresses as we can get. */
9703 LOCK_ZONE(notify->zone);
9704 notify_send(notify);
9705 UNLOCK_ZONE(notify->zone);
9708 notify_destroy(notify, ISC_FALSE);
9713 notify_send_queue(dns_notify_t *notify) {
9715 isc_result_t result;
9717 e = isc_event_allocate(notify->mctx, NULL,
9718 DNS_EVENT_NOTIFYSENDTOADDR,
9720 notify, sizeof(isc_event_t));
9722 return (ISC_R_NOMEMORY);
9724 e->ev_sender = NULL;
9725 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
9726 notify->zone->task, &e);
9727 if (result != ISC_R_SUCCESS)
9733 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
9734 dns_notify_t *notify;
9735 isc_result_t result;
9736 dns_message_t *message = NULL;
9737 isc_netaddr_t dstip;
9738 dns_tsigkey_t *key = NULL;
9739 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9742 isc_boolean_t have_notifysource = ISC_FALSE;
9744 notify = event->ev_arg;
9745 REQUIRE(DNS_NOTIFY_VALID(notify));
9749 LOCK_ZONE(notify->zone);
9751 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
9752 result = ISC_R_CANCELED;
9756 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
9757 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
9758 notify->zone->view->requestmgr == NULL ||
9759 notify->zone->db == NULL) {
9760 result = ISC_R_CANCELED;
9765 * The raw IPv4 address should also exist. Don't send to the
9768 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
9769 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
9770 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9771 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9772 "notify: ignoring IPv6 mapped IPV4 address: %s",
9774 result = ISC_R_CANCELED;
9778 result = notify_createmessage(notify->zone, notify->flags, &message);
9779 if (result != ISC_R_SUCCESS)
9782 if (notify->key != NULL) {
9783 /* Transfer ownership of key */
9787 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
9788 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9789 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
9790 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
9791 notify_log(notify->zone, ISC_LOG_ERROR,
9792 "NOTIFY to %s not sent. "
9793 "Peer TSIG key lookup failure.", addrbuf);
9794 goto cleanup_message;
9798 /* XXX: should we log the tsig key too? */
9799 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
9801 if (notify->zone->view->peers != NULL) {
9802 dns_peer_t *peer = NULL;
9803 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
9805 if (result == ISC_R_SUCCESS) {
9806 result = dns_peer_getnotifysource(peer, &src);
9807 if (result == ISC_R_SUCCESS)
9808 have_notifysource = ISC_TRUE;
9811 switch (isc_sockaddr_pf(¬ify->dst)) {
9813 if (!have_notifysource)
9814 src = notify->zone->notifysrc4;
9817 if (!have_notifysource)
9818 src = notify->zone->notifysrc6;
9821 result = ISC_R_NOTIMPLEMENTED;
9825 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
9827 result = dns_request_createvia2(notify->zone->view->requestmgr,
9828 message, &src, ¬ify->dst, 0, key,
9829 timeout * 3, timeout,
9830 notify->zone->task, notify_done,
9831 notify, ¬ify->request);
9832 if (result == ISC_R_SUCCESS) {
9833 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
9834 inc_stats(notify->zone,
9835 dns_zonestatscounter_notifyoutv4);
9837 inc_stats(notify->zone,
9838 dns_zonestatscounter_notifyoutv6);
9844 dns_tsigkey_detach(&key);
9846 dns_message_destroy(&message);
9848 UNLOCK_ZONE(notify->zone);
9849 isc_event_free(&event);
9850 if (result != ISC_R_SUCCESS)
9851 notify_destroy(notify, ISC_FALSE);
9855 notify_send(dns_notify_t *notify) {
9856 dns_adbaddrinfo_t *ai;
9858 isc_result_t result;
9859 dns_notify_t *new = NULL;
9862 * Zone lock held by caller.
9864 REQUIRE(DNS_NOTIFY_VALID(notify));
9865 REQUIRE(LOCKED_ZONE(notify->zone));
9867 for (ai = ISC_LIST_HEAD(notify->find->list);
9869 ai = ISC_LIST_NEXT(ai, publink)) {
9871 if (notify_isqueued(notify->zone, NULL, &dst))
9873 if (notify_isself(notify->zone, &dst))
9876 result = notify_create(notify->mctx,
9877 (notify->flags & DNS_NOTIFY_NOSOA),
9879 if (result != ISC_R_SUCCESS)
9881 zone_iattach(notify->zone, &new->zone);
9882 ISC_LIST_APPEND(new->zone->notifies, new, link);
9884 result = notify_send_queue(new);
9885 if (result != ISC_R_SUCCESS)
9892 notify_destroy(new, ISC_TRUE);
9896 dns_zone_notify(dns_zone_t *zone) {
9899 REQUIRE(DNS_ZONE_VALID(zone));
9902 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9905 zone_settimer(zone, &now);
9910 zone_notify(dns_zone_t *zone, isc_time_t *now) {
9911 dns_dbnode_t *node = NULL;
9912 dns_db_t *zonedb = NULL;
9913 dns_dbversion_t *version = NULL;
9914 dns_name_t *origin = NULL;
9917 dns_rdata_soa_t soa;
9918 isc_uint32_t serial;
9919 dns_rdata_t rdata = DNS_RDATA_INIT;
9920 dns_rdataset_t nsrdset;
9921 dns_rdataset_t soardset;
9922 isc_result_t result;
9923 dns_notify_t *notify = NULL;
9926 isc_boolean_t isqueued;
9927 dns_notifytype_t notifytype;
9928 unsigned int flags = 0;
9929 isc_boolean_t loggednotify = ISC_FALSE;
9931 REQUIRE(DNS_ZONE_VALID(zone));
9934 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9935 notifytype = zone->notifytype;
9936 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
9939 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
9942 if (notifytype == dns_notifytype_no)
9945 if (notifytype == dns_notifytype_masteronly &&
9946 zone->type != dns_zone_master)
9949 origin = &zone->origin;
9952 * If the zone is dialup we are done as we don't want to send
9953 * the current soa so as to force a refresh query.
9955 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
9956 flags |= DNS_NOTIFY_NOSOA;
9961 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9962 if (zone->db != NULL)
9963 dns_db_attach(zone->db, &zonedb);
9964 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9967 dns_db_currentversion(zonedb, &version);
9968 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
9969 if (result != ISC_R_SUCCESS)
9972 dns_rdataset_init(&soardset);
9973 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
9974 dns_rdatatype_none, 0, &soardset, NULL);
9975 if (result != ISC_R_SUCCESS)
9979 * Find serial and master server's name.
9981 dns_name_init(&master, NULL);
9982 result = dns_rdataset_first(&soardset);
9983 if (result != ISC_R_SUCCESS)
9985 dns_rdataset_current(&soardset, &rdata);
9986 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9987 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9988 dns_rdata_reset(&rdata);
9989 result = dns_name_dup(&soa.origin, zone->mctx, &master);
9990 serial = soa.serial;
9991 dns_rdataset_disassociate(&soardset);
9992 if (result != ISC_R_SUCCESS)
9996 * Enqueue notify requests for 'also-notify' servers.
9999 for (i = 0; i < zone->notifycnt; i++) {
10000 dns_tsigkey_t *key = NULL;
10002 dst = zone->notify[i];
10003 if (notify_isqueued(zone, NULL, &dst))
10006 result = notify_create(zone->mctx, flags, ¬ify);
10007 if (result != ISC_R_SUCCESS)
10010 zone_iattach(zone, ¬ify->zone);
10013 if ((zone->notifykeynames != NULL) &&
10014 (zone->notifykeynames[i] != NULL)) {
10015 dns_view_t *view = dns_zone_getview(zone);
10016 dns_name_t *keyname = zone->notifykeynames[i];
10017 result = dns_view_gettsig(view, keyname, &key);
10018 if (result == ISC_R_SUCCESS) {
10024 ISC_LIST_APPEND(zone->notifies, notify, link);
10025 result = notify_send_queue(notify);
10026 if (result != ISC_R_SUCCESS)
10027 notify_destroy(notify, ISC_TRUE);
10028 if (!loggednotify) {
10029 notify_log(zone, ISC_LOG_INFO,
10030 "sending notifies (serial %u)",
10032 loggednotify = ISC_TRUE;
10038 if (notifytype == dns_notifytype_explicit)
10042 * Process NS RRset to generate notifies.
10045 dns_rdataset_init(&nsrdset);
10046 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
10047 dns_rdatatype_none, 0, &nsrdset, NULL);
10048 if (result != ISC_R_SUCCESS)
10051 result = dns_rdataset_first(&nsrdset);
10052 while (result == ISC_R_SUCCESS) {
10053 dns_rdataset_current(&nsrdset, &rdata);
10054 result = dns_rdata_tostruct(&rdata, &ns, NULL);
10055 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10056 dns_rdata_reset(&rdata);
10058 * Don't notify the master server unless explicitly
10059 * configured to do so.
10061 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
10062 dns_name_compare(&master, &ns.name) == 0) {
10063 result = dns_rdataset_next(&nsrdset);
10067 if (!loggednotify) {
10068 notify_log(zone, ISC_LOG_INFO,
10069 "sending notifies (serial %u)",
10071 loggednotify = ISC_TRUE;
10075 isqueued = notify_isqueued(zone, &ns.name, NULL);
10078 result = dns_rdataset_next(&nsrdset);
10081 result = notify_create(zone->mctx, flags, ¬ify);
10082 if (result != ISC_R_SUCCESS)
10084 dns_zone_iattach(zone, ¬ify->zone);
10085 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
10086 if (result != ISC_R_SUCCESS) {
10088 notify_destroy(notify, ISC_TRUE);
10093 ISC_LIST_APPEND(zone->notifies, notify, link);
10095 notify_find_address(notify);
10097 result = dns_rdataset_next(&nsrdset);
10099 dns_rdataset_disassociate(&nsrdset);
10102 if (dns_name_dynamic(&master))
10103 dns_name_free(&master, zone->mctx);
10105 dns_db_detachnode(zonedb, &node);
10107 dns_db_closeversion(zonedb, &version, ISC_FALSE);
10108 dns_db_detach(&zonedb);
10115 static inline isc_result_t
10116 save_nsrrset(dns_message_t *message, dns_name_t *name,
10117 dns_db_t *db, dns_dbversion_t *version)
10119 dns_rdataset_t *nsrdataset = NULL;
10120 dns_rdataset_t *rdataset = NULL;
10121 dns_dbnode_t *node = NULL;
10123 isc_result_t result;
10124 dns_rdata_t rdata = DNS_RDATA_INIT;
10127 * Extract NS RRset from message.
10129 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
10130 dns_rdatatype_ns, dns_rdatatype_none,
10131 NULL, &nsrdataset);
10132 if (result != ISC_R_SUCCESS)
10138 result = dns_db_findnode(db, name, ISC_TRUE, &node);
10139 if (result != ISC_R_SUCCESS)
10141 result = dns_db_addrdataset(db, node, version, 0,
10142 nsrdataset, 0, NULL);
10143 dns_db_detachnode(db, &node);
10144 if (result != ISC_R_SUCCESS)
10147 * Add glue rdatasets.
10149 for (result = dns_rdataset_first(nsrdataset);
10150 result == ISC_R_SUCCESS;
10151 result = dns_rdataset_next(nsrdataset)) {
10152 dns_rdataset_current(nsrdataset, &rdata);
10153 result = dns_rdata_tostruct(&rdata, &ns, NULL);
10154 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10155 dns_rdata_reset(&rdata);
10156 if (!dns_name_issubdomain(&ns.name, name))
10159 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10160 &ns.name, dns_rdatatype_aaaa,
10161 dns_rdatatype_none, NULL,
10163 if (result == ISC_R_SUCCESS) {
10164 result = dns_db_findnode(db, &ns.name,
10166 if (result != ISC_R_SUCCESS)
10168 result = dns_db_addrdataset(db, node, version, 0,
10169 rdataset, 0, NULL);
10170 dns_db_detachnode(db, &node);
10171 if (result != ISC_R_SUCCESS)
10175 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10176 &ns.name, dns_rdatatype_a,
10177 dns_rdatatype_none, NULL,
10179 if (result == ISC_R_SUCCESS) {
10180 result = dns_db_findnode(db, &ns.name,
10182 if (result != ISC_R_SUCCESS)
10184 result = dns_db_addrdataset(db, node, version, 0,
10185 rdataset, 0, NULL);
10186 dns_db_detachnode(db, &node);
10187 if (result != ISC_R_SUCCESS)
10191 if (result != ISC_R_NOMORE)
10194 return (ISC_R_SUCCESS);
10201 stub_callback(isc_task_t *task, isc_event_t *event) {
10202 const char me[] = "stub_callback";
10203 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10204 dns_stub_t *stub = NULL;
10205 dns_message_t *msg = NULL;
10206 dns_zone_t *zone = NULL;
10207 char master[ISC_SOCKADDR_FORMATSIZE];
10208 char source[ISC_SOCKADDR_FORMATSIZE];
10209 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
10210 isc_result_t result;
10212 isc_boolean_t exiting = ISC_FALSE;
10214 unsigned int j, soacount;
10216 stub = revent->ev_arg;
10217 INSIST(DNS_STUB_VALID(stub));
10229 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10230 zone_debuglog(zone, me, 1, "exiting");
10231 exiting = ISC_TRUE;
10235 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10236 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10238 if (revent->result != ISC_R_SUCCESS) {
10239 if (revent->result == ISC_R_TIMEDOUT &&
10240 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10241 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10242 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10243 "refreshing stub: timeout retrying "
10244 " without EDNS master %s (source %s)",
10248 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
10249 &zone->sourceaddr, &now);
10250 dns_zone_log(zone, ISC_LOG_INFO,
10251 "could not refresh stub from master %s"
10252 " (source %s): %s", master, source,
10253 dns_result_totext(revent->result));
10257 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10258 if (result != ISC_R_SUCCESS)
10261 result = dns_request_getresponse(revent->request, msg, 0);
10262 if (result != ISC_R_SUCCESS)
10266 * Unexpected rcode.
10268 if (msg->rcode != dns_rcode_noerror) {
10272 isc_buffer_init(&rb, rcode, sizeof(rcode));
10273 (void)dns_rcode_totext(msg->rcode, &rb);
10275 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10276 (msg->rcode == dns_rcode_servfail ||
10277 msg->rcode == dns_rcode_notimp ||
10278 msg->rcode == dns_rcode_formerr)) {
10279 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10280 "refreshing stub: rcode (%.*s) retrying "
10281 "without EDNS master %s (source %s)",
10282 (int)rb.used, rcode, master, source);
10283 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10287 dns_zone_log(zone, ISC_LOG_INFO,
10288 "refreshing stub: "
10289 "unexpected rcode (%.*s) from %s (source %s)",
10290 (int)rb.used, rcode, master, source);
10295 * We need complete messages.
10297 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10298 if (dns_request_usedtcp(revent->request)) {
10299 dns_zone_log(zone, ISC_LOG_INFO,
10300 "refreshing stub: truncated TCP "
10301 "response from master %s (source %s)",
10305 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10310 * If non-auth log and next master.
10312 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10313 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10314 "non-authoritative answer from "
10315 "master %s (source %s)", master, source);
10322 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10323 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
10325 if (cnamecnt != 0) {
10326 dns_zone_log(zone, ISC_LOG_INFO,
10327 "refreshing stub: unexpected CNAME response "
10328 "from master %s (source %s)", master, source);
10333 dns_zone_log(zone, ISC_LOG_INFO,
10334 "refreshing stub: no NS records in response "
10335 "from master %s (source %s)", master, source);
10342 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
10343 if (result != ISC_R_SUCCESS) {
10344 dns_zone_log(zone, ISC_LOG_INFO,
10345 "refreshing stub: unable to save NS records "
10346 "from master %s (source %s)", master, source);
10353 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
10354 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
10355 if (zone->db == NULL)
10356 zone_attachdb(zone, stub->db);
10357 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
10358 &refresh, &retry, &expire, NULL, NULL);
10359 if (result == ISC_R_SUCCESS && soacount > 0U) {
10360 zone->refresh = RANGE(refresh, zone->minrefresh,
10362 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
10363 zone->expire = RANGE(expire, zone->refresh + zone->retry,
10365 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
10367 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
10368 dns_db_detach(&stub->db);
10370 dns_message_destroy(&msg);
10371 isc_event_free(&event);
10372 dns_request_destroy(&zone->request);
10374 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10375 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
10376 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10377 isc_interval_set(&i, zone->expire, 0);
10378 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10380 if (zone->masterfile != NULL)
10381 zone_needdump(zone, 0);
10383 zone_settimer(zone, &now);
10387 if (stub->version != NULL)
10388 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
10389 if (stub->db != NULL)
10390 dns_db_detach(&stub->db);
10392 dns_message_destroy(&msg);
10393 isc_event_free(&event);
10394 dns_request_destroy(&zone->request);
10396 * Skip to next failed / untried master.
10400 } while (zone->curmaster < zone->masterscnt &&
10401 zone->mastersok[zone->curmaster]);
10402 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10403 if (exiting || zone->curmaster >= zone->masterscnt) {
10404 isc_boolean_t done = ISC_TRUE;
10406 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10407 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10409 * Did we get a good answer from all the masters?
10411 for (j = 0; j < zone->masterscnt; j++)
10412 if (zone->mastersok[j] == ISC_FALSE) {
10419 zone->curmaster = 0;
10421 * Find the next failed master.
10423 while (zone->curmaster < zone->masterscnt &&
10424 zone->mastersok[zone->curmaster])
10426 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10428 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10430 zone_settimer(zone, &now);
10434 queue_soa_query(zone);
10439 dns_message_destroy(&msg);
10440 isc_event_free(&event);
10441 dns_request_destroy(&zone->request);
10442 ns_query(zone, NULL, stub);
10449 dns_zone_idetach(&stub->zone);
10450 INSIST(stub->db == NULL);
10451 INSIST(stub->version == NULL);
10452 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10455 INSIST(event == NULL);
10460 * An SOA query has finished (successfully or not).
10463 refresh_callback(isc_task_t *task, isc_event_t *event) {
10464 const char me[] = "refresh_callback";
10465 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10467 dns_message_t *msg = NULL;
10468 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
10470 char master[ISC_SOCKADDR_FORMATSIZE];
10471 char source[ISC_SOCKADDR_FORMATSIZE];
10472 dns_rdataset_t *rdataset = NULL;
10473 dns_rdata_t rdata = DNS_RDATA_INIT;
10474 dns_rdata_soa_t soa;
10475 isc_result_t result;
10476 isc_uint32_t serial, oldserial = 0;
10478 isc_boolean_t do_queue_xfrin = ISC_FALSE;
10480 zone = revent->ev_arg;
10481 INSIST(DNS_ZONE_VALID(zone));
10491 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10492 isc_event_free(&event);
10493 dns_request_destroy(&zone->request);
10498 * if timeout log and next master;
10501 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10502 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10504 if (revent->result != ISC_R_SUCCESS) {
10505 if (revent->result == ISC_R_TIMEDOUT &&
10506 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10507 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10508 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10509 "refresh: timeout retrying without EDNS "
10510 "master %s (source %s)", master, source);
10513 if (revent->result == ISC_R_TIMEDOUT &&
10514 !dns_request_usedtcp(revent->request)) {
10515 dns_zone_log(zone, ISC_LOG_INFO,
10516 "refresh: retry limit for "
10517 "master %s exceeded (source %s)",
10519 /* Try with slave with TCP. */
10520 if ((zone->type == dns_zone_slave ||
10521 zone->type == dns_zone_redirect) &&
10522 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
10523 if (!dns_zonemgr_unreachable(zone->zmgr,
10528 DNS_ZONE_SETFLAG(zone,
10529 DNS_ZONEFLG_SOABEFOREAXFR);
10532 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10533 "refresh: skipped tcp fallback "
10534 "as master %s (source %s) is "
10535 "unreachable (cached)",
10539 dns_zone_log(zone, ISC_LOG_INFO,
10540 "refresh: failure trying master "
10541 "%s (source %s): %s", master, source,
10542 dns_result_totext(revent->result));
10546 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10547 if (result != ISC_R_SUCCESS)
10549 result = dns_request_getresponse(revent->request, msg, 0);
10550 if (result != ISC_R_SUCCESS) {
10551 dns_zone_log(zone, ISC_LOG_INFO,
10552 "refresh: failure trying master "
10553 "%s (source %s): %s", master, source,
10554 dns_result_totext(result));
10559 * Unexpected rcode.
10561 if (msg->rcode != dns_rcode_noerror) {
10565 isc_buffer_init(&rb, rcode, sizeof(rcode));
10566 (void)dns_rcode_totext(msg->rcode, &rb);
10568 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10569 (msg->rcode == dns_rcode_servfail ||
10570 msg->rcode == dns_rcode_notimp ||
10571 msg->rcode == dns_rcode_formerr)) {
10572 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10573 "refresh: rcode (%.*s) retrying without "
10574 "EDNS master %s (source %s)",
10575 (int)rb.used, rcode, master, source);
10576 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10579 dns_zone_log(zone, ISC_LOG_INFO,
10580 "refresh: unexpected rcode (%.*s) from "
10581 "master %s (source %s)", (int)rb.used, rcode,
10584 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
10586 if (msg->rcode == dns_rcode_refused &&
10587 (zone->type == dns_zone_slave ||
10588 zone->type == dns_zone_redirect))
10594 * If truncated punt to zone transfer which will query again.
10596 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10597 if (zone->type == dns_zone_slave ||
10598 zone->type == dns_zone_redirect) {
10599 dns_zone_log(zone, ISC_LOG_INFO,
10600 "refresh: truncated UDP answer, "
10601 "initiating TCP zone xfer "
10602 "for master %s (source %s)",
10604 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
10607 INSIST(zone->type == dns_zone_stub);
10608 if (dns_request_usedtcp(revent->request)) {
10609 dns_zone_log(zone, ISC_LOG_INFO,
10610 "refresh: truncated TCP response "
10611 "from master %s (source %s)",
10615 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10621 * if non-auth log and next master;
10623 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10624 dns_zone_log(zone, ISC_LOG_INFO,
10625 "refresh: non-authoritative answer from "
10626 "master %s (source %s)", master, source);
10630 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10631 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
10632 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
10633 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
10634 dns_rdatatype_soa);
10637 * There should not be a CNAME record at top of zone.
10639 if (cnamecnt != 0) {
10640 dns_zone_log(zone, ISC_LOG_INFO,
10641 "refresh: CNAME at top of zone "
10642 "in master %s (source %s)", master, source);
10647 * if referral log and next master;
10649 if (soacnt == 0 && soacount == 0 && nscount != 0) {
10650 dns_zone_log(zone, ISC_LOG_INFO,
10651 "refresh: referral response "
10652 "from master %s (source %s)", master, source);
10657 * if nodata log and next master;
10659 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
10660 dns_zone_log(zone, ISC_LOG_INFO,
10661 "refresh: NODATA response "
10662 "from master %s (source %s)", master, source);
10667 * Only one soa at top of zone.
10670 dns_zone_log(zone, ISC_LOG_INFO,
10671 "refresh: answer SOA count (%d) != 1 "
10672 "from master %s (source %s)",
10673 soacnt, master, source);
10681 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
10682 dns_rdatatype_soa, dns_rdatatype_none,
10684 if (result != ISC_R_SUCCESS) {
10685 dns_zone_log(zone, ISC_LOG_INFO,
10686 "refresh: unable to get SOA record "
10687 "from master %s (source %s)", master, source);
10691 result = dns_rdataset_first(rdataset);
10692 if (result != ISC_R_SUCCESS) {
10693 dns_zone_log(zone, ISC_LOG_INFO,
10694 "refresh: dns_rdataset_first() failed");
10698 dns_rdataset_current(rdataset, &rdata);
10699 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10700 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10702 serial = soa.serial;
10703 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10704 unsigned int soacount;
10705 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
10706 &oldserial, NULL, NULL, NULL, NULL,
10708 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10709 RUNTIME_CHECK(soacount > 0U);
10710 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
10711 serial, oldserial);
10713 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
10716 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
10717 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
10718 isc_serial_gt(serial, oldserial)) {
10719 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10720 &zone->sourceaddr, &now))
10722 dns_zone_log(zone, ISC_LOG_INFO,
10723 "refresh: skipping %s as master %s "
10724 "(source %s) is unreachable (cached)",
10725 (zone->type == dns_zone_slave ||
10726 zone->type == dns_zone_redirect) ?
10727 "zone transfer" : "NS query",
10732 isc_event_free(&event);
10733 dns_request_destroy(&zone->request);
10734 if (zone->type == dns_zone_slave ||
10735 zone->type == dns_zone_redirect) {
10736 do_queue_xfrin = ISC_TRUE;
10738 INSIST(zone->type == dns_zone_stub);
10739 ns_query(zone, rdataset, NULL);
10742 dns_message_destroy(&msg);
10743 } else if (isc_serial_eq(soa.serial, oldserial)) {
10744 if (zone->masterfile != NULL) {
10745 result = ISC_R_FAILURE;
10746 if (zone->journal != NULL)
10747 result = isc_file_settime(zone->journal, &now);
10748 if (result == ISC_R_SUCCESS &&
10749 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10750 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10751 result = isc_file_settime(zone->masterfile,
10753 } else if (result != ISC_R_SUCCESS)
10754 result = isc_file_settime(zone->masterfile,
10756 /* Someone removed the file from underneath us! */
10757 if (result == ISC_R_FILENOTFOUND) {
10758 zone_needdump(zone, DNS_DUMP_DELAY);
10759 } else if (result != ISC_R_SUCCESS)
10760 dns_zone_log(zone, ISC_LOG_ERROR,
10761 "refresh: could not set file "
10762 "modification time of '%s': %s",
10764 dns_result_totext(result));
10766 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10767 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10768 zone->mastersok[zone->curmaster] = ISC_TRUE;
10771 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
10772 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
10773 "received from master %s < ours (%u)",
10774 soa.serial, master, oldserial);
10776 zone_debuglog(zone, me, 1, "ahead");
10777 zone->mastersok[zone->curmaster] = ISC_TRUE;
10781 dns_message_destroy(&msg);
10786 dns_message_destroy(&msg);
10787 isc_event_free(&event);
10788 dns_request_destroy(&zone->request);
10790 * Skip to next failed / untried master.
10794 } while (zone->curmaster < zone->masterscnt &&
10795 zone->mastersok[zone->curmaster]);
10796 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10797 if (zone->curmaster >= zone->masterscnt) {
10798 isc_boolean_t done = ISC_TRUE;
10799 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10800 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10802 * Did we get a good answer from all the masters?
10804 for (j = 0; j < zone->masterscnt; j++)
10805 if (zone->mastersok[j] == ISC_FALSE) {
10812 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10813 zone->curmaster = 0;
10815 * Find the next failed master.
10817 while (zone->curmaster < zone->masterscnt &&
10818 zone->mastersok[zone->curmaster])
10822 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10823 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
10824 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
10825 zone->refreshtime = now;
10827 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10828 zone_settimer(zone, &now);
10833 queue_soa_query(zone);
10838 dns_message_destroy(&msg);
10839 isc_event_free(&event);
10840 dns_request_destroy(&zone->request);
10841 queue_soa_query(zone);
10845 if (do_queue_xfrin)
10847 dns_zone_idetach(&zone);
10852 queue_soa_query(dns_zone_t *zone) {
10853 const char me[] = "queue_soa_query";
10855 dns_zone_t *dummy = NULL;
10856 isc_result_t result;
10862 REQUIRE(LOCKED_ZONE(zone));
10864 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10865 cancel_refresh(zone);
10869 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
10870 soa_query, zone, sizeof(isc_event_t));
10872 cancel_refresh(zone);
10877 * Attach so that we won't clean up
10878 * until the event is delivered.
10880 zone_iattach(zone, &dummy);
10883 e->ev_sender = NULL;
10884 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
10885 if (result != ISC_R_SUCCESS) {
10886 zone_idetach(&dummy);
10887 isc_event_free(&e);
10888 cancel_refresh(zone);
10892 static inline isc_result_t
10893 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
10894 dns_message_t **messagep)
10896 dns_message_t *message = NULL;
10897 dns_name_t *qname = NULL;
10898 dns_rdataset_t *qrdataset = NULL;
10899 isc_result_t result;
10901 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10903 if (result != ISC_R_SUCCESS)
10906 message->opcode = dns_opcode_query;
10907 message->rdclass = zone->rdclass;
10909 result = dns_message_gettempname(message, &qname);
10910 if (result != ISC_R_SUCCESS)
10913 result = dns_message_gettemprdataset(message, &qrdataset);
10914 if (result != ISC_R_SUCCESS)
10920 dns_name_init(qname, NULL);
10921 dns_name_clone(&zone->origin, qname);
10922 dns_rdataset_init(qrdataset);
10923 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
10924 ISC_LIST_APPEND(qname->list, qrdataset, link);
10925 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
10927 *messagep = message;
10928 return (ISC_R_SUCCESS);
10932 dns_message_puttempname(message, &qname);
10933 if (qrdataset != NULL)
10934 dns_message_puttemprdataset(message, &qrdataset);
10935 if (message != NULL)
10936 dns_message_destroy(&message);
10940 static isc_result_t
10941 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
10942 dns_rdataset_t *rdataset = NULL;
10943 dns_rdatalist_t *rdatalist = NULL;
10944 dns_rdata_t *rdata = NULL;
10945 isc_result_t result;
10947 result = dns_message_gettemprdatalist(message, &rdatalist);
10948 if (result != ISC_R_SUCCESS)
10950 result = dns_message_gettemprdata(message, &rdata);
10951 if (result != ISC_R_SUCCESS)
10953 result = dns_message_gettemprdataset(message, &rdataset);
10954 if (result != ISC_R_SUCCESS)
10956 dns_rdataset_init(rdataset);
10958 rdatalist->type = dns_rdatatype_opt;
10959 rdatalist->covers = 0;
10962 * Set Maximum UDP buffer size.
10964 rdatalist->rdclass = udpsize;
10967 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
10969 rdatalist->ttl = 0;
10971 /* Set EDNS options if applicable */
10973 unsigned char data[4];
10976 isc_buffer_init(&buf, data, sizeof(data));
10977 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
10978 isc_buffer_putuint16(&buf, 0);
10979 rdata->data = data;
10980 rdata->length = sizeof(data);
10982 rdata->data = NULL;
10986 rdata->rdclass = rdatalist->rdclass;
10987 rdata->type = rdatalist->type;
10990 ISC_LIST_INIT(rdatalist->rdata);
10991 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
10992 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
10995 return (dns_message_setopt(message, rdataset));
10998 if (rdatalist != NULL)
10999 dns_message_puttemprdatalist(message, &rdatalist);
11000 if (rdataset != NULL)
11001 dns_message_puttemprdataset(message, &rdataset);
11003 dns_message_puttemprdata(message, &rdata);
11009 soa_query(isc_task_t *task, isc_event_t *event) {
11010 const char me[] = "soa_query";
11011 isc_result_t result = ISC_R_FAILURE;
11012 dns_message_t *message = NULL;
11013 dns_zone_t *zone = event->ev_arg;
11014 dns_zone_t *dummy = NULL;
11015 isc_netaddr_t masterip;
11016 dns_tsigkey_t *key = NULL;
11017 isc_uint32_t options;
11018 isc_boolean_t cancel = ISC_TRUE;
11020 isc_boolean_t have_xfrsource, reqnsid;
11021 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11023 REQUIRE(DNS_ZONE_VALID(zone));
11030 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
11031 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
11032 zone->view->requestmgr == NULL) {
11033 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11034 cancel = ISC_FALSE;
11039 * XXX Optimisation: Create message when zone is setup and reuse.
11041 result = create_query(zone, dns_rdatatype_soa, &message);
11042 if (result != ISC_R_SUCCESS)
11046 INSIST(zone->masterscnt > 0);
11047 INSIST(zone->curmaster < zone->masterscnt);
11049 zone->masteraddr = zone->masters[zone->curmaster];
11051 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11053 * First, look for a tsig key in the master statement, then
11054 * try for a server key.
11056 if ((zone->masterkeynames != NULL) &&
11057 (zone->masterkeynames[zone->curmaster] != NULL)) {
11058 dns_view_t *view = dns_zone_getview(zone);
11059 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11060 result = dns_view_gettsig(view, keyname, &key);
11061 if (result != ISC_R_SUCCESS) {
11062 char namebuf[DNS_NAME_FORMATSIZE];
11063 dns_name_format(keyname, namebuf, sizeof(namebuf));
11064 dns_zone_log(zone, ISC_LOG_ERROR,
11065 "unable to find key: %s", namebuf);
11070 result = dns_view_getpeertsig(zone->view, &masterip, &key);
11071 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
11072 char addrbuf[ISC_NETADDR_FORMATSIZE];
11073 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
11074 dns_zone_log(zone, ISC_LOG_ERROR,
11075 "unable to find TSIG key for %s", addrbuf);
11080 have_xfrsource = ISC_FALSE;
11081 reqnsid = zone->view->requestnsid;
11082 if (zone->view->peers != NULL) {
11083 dns_peer_t *peer = NULL;
11084 isc_boolean_t edns;
11085 result = dns_peerlist_peerbyaddr(zone->view->peers,
11087 if (result == ISC_R_SUCCESS) {
11088 result = dns_peer_getsupportedns(peer, &edns);
11089 if (result == ISC_R_SUCCESS && !edns)
11090 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11091 result = dns_peer_gettransfersource(peer,
11092 &zone->sourceaddr);
11093 if (result == ISC_R_SUCCESS)
11094 have_xfrsource = ISC_TRUE;
11095 if (zone->view->resolver != NULL)
11097 dns_resolver_getudpsize(zone->view->resolver);
11098 (void)dns_peer_getudpsize(peer, &udpsize);
11099 (void)dns_peer_getrequestnsid(peer, &reqnsid);
11103 switch (isc_sockaddr_pf(&zone->masteraddr)) {
11105 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11106 if (isc_sockaddr_equal(&zone->altxfrsource4,
11107 &zone->xfrsource4))
11109 zone->sourceaddr = zone->altxfrsource4;
11110 } else if (!have_xfrsource)
11111 zone->sourceaddr = zone->xfrsource4;
11114 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11115 if (isc_sockaddr_equal(&zone->altxfrsource6,
11116 &zone->xfrsource6))
11118 zone->sourceaddr = zone->altxfrsource6;
11119 } else if (!have_xfrsource)
11120 zone->sourceaddr = zone->xfrsource6;
11123 result = ISC_R_NOTIMPLEMENTED;
11127 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
11128 DNS_REQUESTOPT_TCP : 0;
11130 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11131 result = add_opt(message, udpsize, reqnsid);
11132 if (result != ISC_R_SUCCESS)
11133 zone_debuglog(zone, me, 1,
11134 "unable to add opt record: %s",
11135 dns_result_totext(result));
11138 zone_iattach(zone, &dummy);
11140 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11142 result = dns_request_createvia2(zone->view->requestmgr, message,
11143 &zone->sourceaddr, &zone->masteraddr,
11144 options, key, timeout * 3, timeout,
11145 zone->task, refresh_callback, zone,
11147 if (result != ISC_R_SUCCESS) {
11148 zone_idetach(&dummy);
11149 zone_debuglog(zone, me, 1,
11150 "dns_request_createvia2() failed: %s",
11151 dns_result_totext(result));
11154 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
11155 inc_stats(zone, dns_zonestatscounter_soaoutv4);
11157 inc_stats(zone, dns_zonestatscounter_soaoutv6);
11159 cancel = ISC_FALSE;
11163 dns_tsigkey_detach(&key);
11164 if (result != ISC_R_SUCCESS)
11165 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11166 if (message != NULL)
11167 dns_message_destroy(&message);
11169 cancel_refresh(zone);
11170 isc_event_free(&event);
11172 dns_zone_idetach(&zone);
11177 dns_tsigkey_detach(&key);
11179 * Skip to next failed / untried master.
11183 } while (zone->curmaster < zone->masterscnt &&
11184 zone->mastersok[zone->curmaster]);
11185 if (zone->curmaster < zone->masterscnt)
11187 zone->curmaster = 0;
11192 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
11193 const char me[] = "ns_query";
11194 isc_result_t result;
11195 dns_message_t *message = NULL;
11196 isc_netaddr_t masterip;
11197 dns_tsigkey_t *key = NULL;
11198 dns_dbnode_t *node = NULL;
11200 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
11201 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11203 REQUIRE(DNS_ZONE_VALID(zone));
11204 REQUIRE(LOCKED_ZONE(zone));
11205 REQUIRE((soardataset != NULL && stub == NULL) ||
11206 (soardataset == NULL && stub != NULL));
11207 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
11211 if (stub == NULL) {
11212 stub = isc_mem_get(zone->mctx, sizeof(*stub));
11215 stub->magic = STUB_MAGIC;
11216 stub->mctx = zone->mctx;
11219 stub->version = NULL;
11222 * Attach so that the zone won't disappear from under us.
11224 zone_iattach(zone, &stub->zone);
11227 * If a db exists we will update it, otherwise we create a
11228 * new one and attach it to the zone once we have the NS
11231 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11232 if (zone->db != NULL) {
11233 dns_db_attach(zone->db, &stub->db);
11234 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11236 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11238 INSIST(zone->db_argc >= 1);
11239 result = dns_db_create(zone->mctx, zone->db_argv[0],
11240 &zone->origin, dns_dbtype_stub,
11245 if (result != ISC_R_SUCCESS) {
11246 dns_zone_log(zone, ISC_LOG_ERROR,
11247 "refreshing stub: "
11248 "could not create "
11250 dns_result_totext(result));
11253 dns_db_settask(stub->db, zone->task);
11256 result = dns_db_newversion(stub->db, &stub->version);
11257 if (result != ISC_R_SUCCESS) {
11258 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11259 "dns_db_newversion() failed: %s",
11260 dns_result_totext(result));
11265 * Update SOA record.
11267 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
11269 if (result != ISC_R_SUCCESS) {
11270 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11271 "dns_db_findnode() failed: %s",
11272 dns_result_totext(result));
11276 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
11277 soardataset, 0, NULL);
11278 dns_db_detachnode(stub->db, &node);
11279 if (result != ISC_R_SUCCESS) {
11280 dns_zone_log(zone, ISC_LOG_INFO,
11281 "refreshing stub: "
11282 "dns_db_addrdataset() failed: %s",
11283 dns_result_totext(result));
11289 * XXX Optimisation: Create message when zone is setup and reuse.
11291 result = create_query(zone, dns_rdatatype_ns, &message);
11292 INSIST(result == ISC_R_SUCCESS);
11294 INSIST(zone->masterscnt > 0);
11295 INSIST(zone->curmaster < zone->masterscnt);
11296 zone->masteraddr = zone->masters[zone->curmaster];
11298 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11300 * First, look for a tsig key in the master statement, then
11301 * try for a server key.
11303 if ((zone->masterkeynames != NULL) &&
11304 (zone->masterkeynames[zone->curmaster] != NULL)) {
11305 dns_view_t *view = dns_zone_getview(zone);
11306 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11307 result = dns_view_gettsig(view, keyname, &key);
11308 if (result != ISC_R_SUCCESS) {
11309 char namebuf[DNS_NAME_FORMATSIZE];
11310 dns_name_format(keyname, namebuf, sizeof(namebuf));
11311 dns_zone_log(zone, ISC_LOG_ERROR,
11312 "unable to find key: %s", namebuf);
11316 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
11318 reqnsid = zone->view->requestnsid;
11319 if (zone->view->peers != NULL) {
11320 dns_peer_t *peer = NULL;
11321 isc_boolean_t edns;
11322 result = dns_peerlist_peerbyaddr(zone->view->peers,
11324 if (result == ISC_R_SUCCESS) {
11325 result = dns_peer_getsupportedns(peer, &edns);
11326 if (result == ISC_R_SUCCESS && !edns)
11327 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11328 result = dns_peer_gettransfersource(peer,
11329 &zone->sourceaddr);
11330 if (result == ISC_R_SUCCESS)
11331 have_xfrsource = ISC_TRUE;
11332 if (zone->view->resolver != NULL)
11334 dns_resolver_getudpsize(zone->view->resolver);
11335 (void)dns_peer_getudpsize(peer, &udpsize);
11336 (void)dns_peer_getrequestnsid(peer, &reqnsid);
11340 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11341 result = add_opt(message, udpsize, reqnsid);
11342 if (result != ISC_R_SUCCESS)
11343 zone_debuglog(zone, me, 1,
11344 "unable to add opt record: %s",
11345 dns_result_totext(result));
11349 * Always use TCP so that we shouldn't truncate in additional section.
11351 switch (isc_sockaddr_pf(&zone->masteraddr)) {
11353 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
11354 zone->sourceaddr = zone->altxfrsource4;
11355 else if (!have_xfrsource)
11356 zone->sourceaddr = zone->xfrsource4;
11359 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
11360 zone->sourceaddr = zone->altxfrsource6;
11361 else if (!have_xfrsource)
11362 zone->sourceaddr = zone->xfrsource6;
11365 result = ISC_R_NOTIMPLEMENTED;
11370 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11372 result = dns_request_createvia2(zone->view->requestmgr, message,
11373 &zone->sourceaddr, &zone->masteraddr,
11374 DNS_REQUESTOPT_TCP, key, timeout * 3,
11375 timeout, zone->task, stub_callback,
11376 stub, &zone->request);
11377 if (result != ISC_R_SUCCESS) {
11378 zone_debuglog(zone, me, 1,
11379 "dns_request_createvia() failed: %s",
11380 dns_result_totext(result));
11383 dns_message_destroy(&message);
11387 cancel_refresh(zone);
11388 if (stub != NULL) {
11390 if (stub->version != NULL)
11391 dns_db_closeversion(stub->db, &stub->version,
11393 if (stub->db != NULL)
11394 dns_db_detach(&stub->db);
11395 if (stub->zone != NULL)
11396 zone_idetach(&stub->zone);
11397 isc_mem_put(stub->mctx, stub, sizeof(*stub));
11399 if (message != NULL)
11400 dns_message_destroy(&message);
11403 dns_tsigkey_detach(&key);
11408 * Handle the control event. Note that although this event causes the zone
11409 * to shut down, it is not a shutdown event in the sense of the task library.
11412 zone_shutdown(isc_task_t *task, isc_event_t *event) {
11413 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
11414 isc_boolean_t free_needed, linked = ISC_FALSE;
11415 dns_zone_t *raw = NULL, *secure = NULL;
11418 REQUIRE(DNS_ZONE_VALID(zone));
11419 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
11420 INSIST(isc_refcount_current(&zone->erefs) == 0);
11422 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
11425 * Stop things being restarted after we cancel them below.
11428 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
11432 * If we were waiting for xfrin quota, step out of
11434 * If there's no zone manager, we can't be waiting for the
11437 if (zone->zmgr != NULL) {
11438 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11439 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
11440 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
11443 zone->statelist = NULL;
11445 if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
11446 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
11448 zone->statelist = NULL;
11449 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
11451 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11455 * In task context, no locking required. See zone_xfrdone().
11457 if (zone->xfr != NULL)
11458 dns_xfrin_shutdown(zone->xfr);
11460 /* Safe to release the zone now */
11461 if (zone->zmgr != NULL)
11462 dns_zonemgr_releasezone(zone->zmgr, zone);
11466 INSIST(zone->irefs > 0);
11469 if (zone->request != NULL) {
11470 dns_request_cancel(zone->request);
11473 if (zone->readio != NULL)
11474 zonemgr_cancelio(zone->readio);
11476 if (zone->lctx != NULL)
11477 dns_loadctx_cancel(zone->lctx);
11479 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
11480 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11481 if (zone->writeio != NULL)
11482 zonemgr_cancelio(zone->writeio);
11484 if (zone->dctx != NULL)
11485 dns_dumpctx_cancel(zone->dctx);
11488 notify_cancel(zone);
11490 forward_cancel(zone);
11492 if (zone->timer != NULL) {
11493 isc_timer_detach(&zone->timer);
11494 INSIST(zone->irefs > 0);
11498 if (zone->view != NULL)
11499 dns_view_weakdetach(&zone->view);
11502 * We have now canceled everything set the flag to allow exit_check()
11503 * to succeed. We must not unlock between setting this flag and
11504 * calling exit_check().
11506 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
11507 free_needed = exit_check(zone);
11508 if (inline_secure(zone)) {
11512 if (inline_raw(zone)) {
11513 secure = zone->secure;
11514 zone->secure = NULL;
11518 dns_zone_detach(&raw);
11519 if (secure != NULL)
11520 dns_zone_idetach(&secure);
11526 zone_timer(isc_task_t *task, isc_event_t *event) {
11527 const char me[] = "zone_timer";
11528 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
11531 REQUIRE(DNS_ZONE_VALID(zone));
11535 zone_maintenance(zone);
11537 isc_event_free(&event);
11541 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
11542 const char me[] = "zone_settimer";
11544 isc_result_t result;
11547 REQUIRE(DNS_ZONE_VALID(zone));
11548 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11551 isc_time_settoepoch(&next);
11553 switch (zone->type) {
11554 case dns_zone_redirect:
11555 if (zone->masters != NULL)
11556 goto treat_as_slave;
11559 case dns_zone_master:
11560 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
11561 next = zone->notifytime;
11562 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11563 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11564 INSIST(!isc_time_isepoch(&zone->dumptime));
11565 if (isc_time_isepoch(&next) ||
11566 isc_time_compare(&zone->dumptime, &next) < 0)
11567 next = zone->dumptime;
11569 if (zone->type == dns_zone_redirect)
11571 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
11572 !isc_time_isepoch(&zone->refreshkeytime)) {
11573 if (isc_time_isepoch(&next) ||
11574 isc_time_compare(&zone->refreshkeytime, &next) < 0)
11575 next = zone->refreshkeytime;
11577 if (!isc_time_isepoch(&zone->resigntime)) {
11578 if (isc_time_isepoch(&next) ||
11579 isc_time_compare(&zone->resigntime, &next) < 0)
11580 next = zone->resigntime;
11582 if (!isc_time_isepoch(&zone->keywarntime)) {
11583 if (isc_time_isepoch(&next) ||
11584 isc_time_compare(&zone->keywarntime, &next) < 0)
11585 next = zone->keywarntime;
11587 if (!isc_time_isepoch(&zone->signingtime)) {
11588 if (isc_time_isepoch(&next) ||
11589 isc_time_compare(&zone->signingtime, &next) < 0)
11590 next = zone->signingtime;
11592 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
11593 if (isc_time_isepoch(&next) ||
11594 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
11595 next = zone->nsec3chaintime;
11599 case dns_zone_slave:
11601 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
11602 next = zone->notifytime;
11605 case dns_zone_stub:
11606 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
11607 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
11608 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
11609 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
11610 INSIST(!isc_time_isepoch(&zone->refreshtime));
11611 if (isc_time_isepoch(&next) ||
11612 isc_time_compare(&zone->refreshtime, &next) < 0)
11613 next = zone->refreshtime;
11615 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
11616 !isc_time_isepoch(&zone->expiretime)) {
11617 if (isc_time_isepoch(&next) ||
11618 isc_time_compare(&zone->expiretime, &next) < 0)
11619 next = zone->expiretime;
11621 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11622 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11623 INSIST(!isc_time_isepoch(&zone->dumptime));
11624 if (isc_time_isepoch(&next) ||
11625 isc_time_compare(&zone->dumptime, &next) < 0)
11626 next = zone->dumptime;
11631 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11632 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11633 INSIST(!isc_time_isepoch(&zone->dumptime));
11634 if (isc_time_isepoch(&next) ||
11635 isc_time_compare(&zone->dumptime, &next) < 0)
11636 next = zone->dumptime;
11638 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
11639 if (isc_time_isepoch(&next) ||
11640 (!isc_time_isepoch(&zone->refreshkeytime) &&
11641 isc_time_compare(&zone->refreshkeytime, &next) < 0))
11642 next = zone->refreshkeytime;
11650 if (isc_time_isepoch(&next)) {
11651 zone_debuglog(zone, me, 10, "settimer inactive");
11652 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
11653 NULL, NULL, ISC_TRUE);
11654 if (result != ISC_R_SUCCESS)
11655 dns_zone_log(zone, ISC_LOG_ERROR,
11656 "could not deactivate zone timer: %s",
11657 isc_result_totext(result));
11659 if (isc_time_compare(&next, now) <= 0)
11661 result = isc_timer_reset(zone->timer, isc_timertype_once,
11662 &next, NULL, ISC_TRUE);
11663 if (result != ISC_R_SUCCESS)
11664 dns_zone_log(zone, ISC_LOG_ERROR,
11665 "could not reset zone timer: %s",
11666 isc_result_totext(result));
11671 cancel_refresh(dns_zone_t *zone) {
11672 const char me[] = "cancel_refresh";
11676 * 'zone' locked by caller.
11679 REQUIRE(DNS_ZONE_VALID(zone));
11680 REQUIRE(LOCKED_ZONE(zone));
11684 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11686 zone_settimer(zone, &now);
11689 static isc_result_t
11690 notify_createmessage(dns_zone_t *zone, unsigned int flags,
11691 dns_message_t **messagep)
11693 dns_db_t *zonedb = NULL;
11694 dns_dbnode_t *node = NULL;
11695 dns_dbversion_t *version = NULL;
11696 dns_message_t *message = NULL;
11697 dns_rdataset_t rdataset;
11698 dns_rdata_t rdata = DNS_RDATA_INIT;
11700 dns_name_t *tempname = NULL;
11701 dns_rdata_t *temprdata = NULL;
11702 dns_rdatalist_t *temprdatalist = NULL;
11703 dns_rdataset_t *temprdataset = NULL;
11705 isc_result_t result;
11707 isc_buffer_t *b = NULL;
11709 REQUIRE(DNS_ZONE_VALID(zone));
11710 REQUIRE(messagep != NULL && *messagep == NULL);
11712 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
11714 if (result != ISC_R_SUCCESS)
11717 message->opcode = dns_opcode_notify;
11718 message->flags |= DNS_MESSAGEFLAG_AA;
11719 message->rdclass = zone->rdclass;
11721 result = dns_message_gettempname(message, &tempname);
11722 if (result != ISC_R_SUCCESS)
11725 result = dns_message_gettemprdataset(message, &temprdataset);
11726 if (result != ISC_R_SUCCESS)
11732 dns_name_init(tempname, NULL);
11733 dns_name_clone(&zone->origin, tempname);
11734 dns_rdataset_init(temprdataset);
11735 dns_rdataset_makequestion(temprdataset, zone->rdclass,
11736 dns_rdatatype_soa);
11737 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11738 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
11740 temprdataset = NULL;
11742 if ((flags & DNS_NOTIFY_NOSOA) != 0)
11745 result = dns_message_gettempname(message, &tempname);
11746 if (result != ISC_R_SUCCESS)
11748 result = dns_message_gettemprdata(message, &temprdata);
11749 if (result != ISC_R_SUCCESS)
11751 result = dns_message_gettemprdataset(message, &temprdataset);
11752 if (result != ISC_R_SUCCESS)
11754 result = dns_message_gettemprdatalist(message, &temprdatalist);
11755 if (result != ISC_R_SUCCESS)
11758 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11759 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
11760 dns_db_attach(zone->db, &zonedb);
11761 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11763 dns_name_init(tempname, NULL);
11764 dns_name_clone(&zone->origin, tempname);
11765 dns_db_currentversion(zonedb, &version);
11766 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
11767 if (result != ISC_R_SUCCESS)
11770 dns_rdataset_init(&rdataset);
11771 result = dns_db_findrdataset(zonedb, node, version,
11773 dns_rdatatype_none, 0, &rdataset,
11775 if (result != ISC_R_SUCCESS)
11777 result = dns_rdataset_first(&rdataset);
11778 if (result != ISC_R_SUCCESS)
11780 dns_rdataset_current(&rdataset, &rdata);
11781 dns_rdata_toregion(&rdata, &r);
11782 result = isc_buffer_allocate(zone->mctx, &b, r.length);
11783 if (result != ISC_R_SUCCESS)
11785 isc_buffer_putmem(b, r.base, r.length);
11786 isc_buffer_usedregion(b, &r);
11787 dns_rdata_init(temprdata);
11788 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
11789 dns_message_takebuffer(message, &b);
11790 result = dns_rdataset_next(&rdataset);
11791 dns_rdataset_disassociate(&rdataset);
11792 if (result != ISC_R_NOMORE)
11794 temprdatalist->rdclass = rdata.rdclass;
11795 temprdatalist->type = rdata.type;
11796 temprdatalist->covers = 0;
11797 temprdatalist->ttl = rdataset.ttl;
11798 ISC_LIST_INIT(temprdatalist->rdata);
11799 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
11801 dns_rdataset_init(temprdataset);
11802 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
11803 if (result != ISC_R_SUCCESS)
11806 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11807 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
11808 temprdatalist = NULL;
11809 temprdataset = NULL;
11815 dns_db_detachnode(zonedb, &node);
11816 if (version != NULL)
11817 dns_db_closeversion(zonedb, &version, ISC_FALSE);
11818 if (zonedb != NULL)
11819 dns_db_detach(&zonedb);
11820 if (tempname != NULL)
11821 dns_message_puttempname(message, &tempname);
11822 if (temprdata != NULL)
11823 dns_message_puttemprdata(message, &temprdata);
11824 if (temprdataset != NULL)
11825 dns_message_puttemprdataset(message, &temprdataset);
11826 if (temprdatalist != NULL)
11827 dns_message_puttemprdatalist(message, &temprdatalist);
11830 *messagep = message;
11831 return (ISC_R_SUCCESS);
11834 if (tempname != NULL)
11835 dns_message_puttempname(message, &tempname);
11836 if (temprdataset != NULL)
11837 dns_message_puttemprdataset(message, &temprdataset);
11838 dns_message_destroy(&message);
11843 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
11844 dns_message_t *msg)
11847 dns_rdata_soa_t soa;
11848 dns_rdataset_t *rdataset = NULL;
11849 dns_rdata_t rdata = DNS_RDATA_INIT;
11850 isc_result_t result;
11851 char fromtext[ISC_SOCKADDR_FORMATSIZE];
11853 isc_netaddr_t netaddr;
11854 isc_sockaddr_t local, remote;
11856 REQUIRE(DNS_ZONE_VALID(zone));
11859 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
11863 * Check that 'from' is a valid notify source, (zone->masters).
11864 * Return DNS_R_REFUSED if not.
11866 * If the notify message contains a serial number check it
11867 * against the zones serial and return if <= current serial
11869 * If a refresh check is progress, if so just record the
11870 * fact we received a NOTIFY and from where and return.
11871 * We will perform a new refresh check when the current one
11872 * completes. Return ISC_R_SUCCESS.
11874 * Otherwise initiate a refresh check using 'from' as the
11875 * first address to check. Return ISC_R_SUCCESS.
11878 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
11881 * Notify messages are processed by the raw zone.
11884 if (inline_secure(zone)) {
11885 result = dns_zone_notifyreceive(zone->raw, from, msg);
11890 * We only handle NOTIFY (SOA) at the present.
11892 if (isc_sockaddr_pf(from) == PF_INET)
11893 inc_stats(zone, dns_zonestatscounter_notifyinv4);
11895 inc_stats(zone, dns_zonestatscounter_notifyinv6);
11896 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
11897 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
11898 dns_rdatatype_soa, dns_rdatatype_none,
11899 NULL, NULL) != ISC_R_SUCCESS) {
11901 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
11902 dns_zone_log(zone, ISC_LOG_NOTICE,
11904 "question section from: %s", fromtext);
11905 return (DNS_R_FORMERR);
11907 dns_zone_log(zone, ISC_LOG_NOTICE,
11908 "NOTIFY zone does not match");
11909 return (DNS_R_NOTIMP);
11913 * If we are a master zone just succeed.
11915 if (zone->type == dns_zone_master) {
11917 return (ISC_R_SUCCESS);
11920 isc_netaddr_fromsockaddr(&netaddr, from);
11921 for (i = 0; i < zone->masterscnt; i++) {
11922 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
11924 if (zone->view->aclenv.match_mapped &&
11925 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
11926 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
11927 isc_netaddr_t na1, na2;
11928 isc_netaddr_fromv4mapped(&na1, &netaddr);
11929 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
11930 if (isc_netaddr_equal(&na1, &na2))
11936 * Accept notify requests from non masters if they are on
11937 * 'zone->notify_acl'.
11939 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
11940 dns_acl_match(&netaddr, NULL, zone->notify_acl,
11941 &zone->view->aclenv,
11942 &match, NULL) == ISC_R_SUCCESS &&
11945 /* Accept notify. */
11946 } else if (i >= zone->masterscnt) {
11948 dns_zone_log(zone, ISC_LOG_INFO,
11949 "refused notify from non-master: %s", fromtext);
11950 inc_stats(zone, dns_zonestatscounter_notifyrej);
11951 return (DNS_R_REFUSED);
11955 * If the zone is loaded and there are answers check the serial
11956 * to see if we need to do a refresh. Do not worry about this
11957 * check if we are a dialup zone as we use the notify request
11958 * to trigger a refresh check.
11960 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
11961 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
11962 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
11963 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
11966 dns_rdatatype_none, NULL,
11968 if (result == ISC_R_SUCCESS)
11969 result = dns_rdataset_first(rdataset);
11970 if (result == ISC_R_SUCCESS) {
11971 isc_uint32_t serial = 0, oldserial;
11972 unsigned int soacount;
11974 dns_rdataset_current(rdataset, &rdata);
11975 result = dns_rdata_tostruct(&rdata, &soa, NULL);
11976 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11977 serial = soa.serial;
11979 * The following should safely be performed without DB
11980 * lock and succeed in this context.
11982 result = zone_get_from_db(zone, zone->db, NULL,
11983 &soacount, &oldserial, NULL,
11984 NULL, NULL, NULL, NULL);
11985 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11986 RUNTIME_CHECK(soacount > 0U);
11987 if (isc_serial_le(serial, oldserial)) {
11991 "zone is up to date",
11994 return (ISC_R_SUCCESS);
12000 * If we got this far and there was a refresh in progress just
12001 * let it complete. Record where we got the notify from so we
12002 * can perform a refresh check when the current one completes
12004 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
12005 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12006 zone->notifyfrom = *from;
12008 dns_zone_log(zone, ISC_LOG_INFO,
12009 "notify from %s: refresh in progress, "
12010 "refresh check queued",
12012 return (ISC_R_SUCCESS);
12014 zone->notifyfrom = *from;
12015 local = zone->masteraddr;
12016 remote = zone->sourceaddr;
12018 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
12019 dns_zone_refresh(zone);
12020 return (ISC_R_SUCCESS);
12024 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
12026 REQUIRE(DNS_ZONE_VALID(zone));
12029 if (zone->notify_acl != NULL)
12030 dns_acl_detach(&zone->notify_acl);
12031 dns_acl_attach(acl, &zone->notify_acl);
12036 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
12038 REQUIRE(DNS_ZONE_VALID(zone));
12041 if (zone->query_acl != NULL)
12042 dns_acl_detach(&zone->query_acl);
12043 dns_acl_attach(acl, &zone->query_acl);
12048 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
12050 REQUIRE(DNS_ZONE_VALID(zone));
12053 if (zone->queryon_acl != NULL)
12054 dns_acl_detach(&zone->queryon_acl);
12055 dns_acl_attach(acl, &zone->queryon_acl);
12060 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
12062 REQUIRE(DNS_ZONE_VALID(zone));
12065 if (zone->update_acl != NULL)
12066 dns_acl_detach(&zone->update_acl);
12067 dns_acl_attach(acl, &zone->update_acl);
12072 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
12074 REQUIRE(DNS_ZONE_VALID(zone));
12077 if (zone->forward_acl != NULL)
12078 dns_acl_detach(&zone->forward_acl);
12079 dns_acl_attach(acl, &zone->forward_acl);
12084 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
12086 REQUIRE(DNS_ZONE_VALID(zone));
12089 if (zone->xfr_acl != NULL)
12090 dns_acl_detach(&zone->xfr_acl);
12091 dns_acl_attach(acl, &zone->xfr_acl);
12096 dns_zone_getnotifyacl(dns_zone_t *zone) {
12098 REQUIRE(DNS_ZONE_VALID(zone));
12100 return (zone->notify_acl);
12104 dns_zone_getqueryacl(dns_zone_t *zone) {
12106 REQUIRE(DNS_ZONE_VALID(zone));
12108 return (zone->query_acl);
12112 dns_zone_getqueryonacl(dns_zone_t *zone) {
12114 REQUIRE(DNS_ZONE_VALID(zone));
12116 return (zone->queryon_acl);
12120 dns_zone_getupdateacl(dns_zone_t *zone) {
12122 REQUIRE(DNS_ZONE_VALID(zone));
12124 return (zone->update_acl);
12128 dns_zone_getforwardacl(dns_zone_t *zone) {
12130 REQUIRE(DNS_ZONE_VALID(zone));
12132 return (zone->forward_acl);
12136 dns_zone_getxfracl(dns_zone_t *zone) {
12138 REQUIRE(DNS_ZONE_VALID(zone));
12140 return (zone->xfr_acl);
12144 dns_zone_clearupdateacl(dns_zone_t *zone) {
12146 REQUIRE(DNS_ZONE_VALID(zone));
12149 if (zone->update_acl != NULL)
12150 dns_acl_detach(&zone->update_acl);
12155 dns_zone_clearforwardacl(dns_zone_t *zone) {
12157 REQUIRE(DNS_ZONE_VALID(zone));
12160 if (zone->forward_acl != NULL)
12161 dns_acl_detach(&zone->forward_acl);
12166 dns_zone_clearnotifyacl(dns_zone_t *zone) {
12168 REQUIRE(DNS_ZONE_VALID(zone));
12171 if (zone->notify_acl != NULL)
12172 dns_acl_detach(&zone->notify_acl);
12177 dns_zone_clearqueryacl(dns_zone_t *zone) {
12179 REQUIRE(DNS_ZONE_VALID(zone));
12182 if (zone->query_acl != NULL)
12183 dns_acl_detach(&zone->query_acl);
12188 dns_zone_clearqueryonacl(dns_zone_t *zone) {
12190 REQUIRE(DNS_ZONE_VALID(zone));
12193 if (zone->queryon_acl != NULL)
12194 dns_acl_detach(&zone->queryon_acl);
12199 dns_zone_clearxfracl(dns_zone_t *zone) {
12201 REQUIRE(DNS_ZONE_VALID(zone));
12204 if (zone->xfr_acl != NULL)
12205 dns_acl_detach(&zone->xfr_acl);
12210 dns_zone_getupdatedisabled(dns_zone_t *zone) {
12211 REQUIRE(DNS_ZONE_VALID(zone));
12212 return (zone->update_disabled);
12217 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
12218 REQUIRE(DNS_ZONE_VALID(zone));
12219 zone->update_disabled = state;
12223 dns_zone_getzeronosoattl(dns_zone_t *zone) {
12224 REQUIRE(DNS_ZONE_VALID(zone));
12225 return (zone->zero_no_soa_ttl);
12230 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
12231 REQUIRE(DNS_ZONE_VALID(zone));
12232 zone->zero_no_soa_ttl = state;
12236 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
12238 REQUIRE(DNS_ZONE_VALID(zone));
12240 zone->check_names = severity;
12244 dns_zone_getchecknames(dns_zone_t *zone) {
12246 REQUIRE(DNS_ZONE_VALID(zone));
12248 return (zone->check_names);
12252 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
12254 REQUIRE(DNS_ZONE_VALID(zone));
12256 zone->journalsize = size;
12260 dns_zone_getjournalsize(dns_zone_t *zone) {
12262 REQUIRE(DNS_ZONE_VALID(zone));
12264 return (zone->journalsize);
12268 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
12269 isc_result_t result = ISC_R_FAILURE;
12270 isc_buffer_t buffer;
12272 REQUIRE(buf != NULL);
12273 REQUIRE(length > 1U);
12276 * Leave space for terminating '\0'.
12278 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12279 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
12280 if (dns_name_dynamic(&zone->origin))
12281 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12282 if (result != ISC_R_SUCCESS &&
12283 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12284 isc_buffer_putstr(&buffer, "<UNKNOWN>");
12286 if (isc_buffer_availablelength(&buffer) > 0)
12287 isc_buffer_putstr(&buffer, "/");
12288 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
12291 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
12292 strcmp(zone->view->name, "_default") != 0 &&
12293 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
12294 isc_buffer_putstr(&buffer, "/");
12295 isc_buffer_putstr(&buffer, zone->view->name);
12297 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
12298 isc_buffer_putstr(&buffer, " (signed)");
12299 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
12300 isc_buffer_putstr(&buffer, " (unsigned)");
12302 buf[isc_buffer_usedlength(&buffer)] = '\0';
12306 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
12307 isc_result_t result = ISC_R_FAILURE;
12308 isc_buffer_t buffer;
12310 REQUIRE(buf != NULL);
12311 REQUIRE(length > 1U);
12314 * Leave space for terminating '\0'.
12316 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12317 if (dns_name_dynamic(&zone->origin))
12318 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12319 if (result != ISC_R_SUCCESS &&
12320 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12321 isc_buffer_putstr(&buffer, "<UNKNOWN>");
12323 buf[isc_buffer_usedlength(&buffer)] = '\0';
12327 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
12328 isc_buffer_t buffer;
12330 REQUIRE(buf != NULL);
12331 REQUIRE(length > 1U);
12334 * Leave space for terminating '\0'.
12336 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12337 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
12339 buf[isc_buffer_usedlength(&buffer)] = '\0';
12343 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
12344 isc_buffer_t buffer;
12346 REQUIRE(buf != NULL);
12347 REQUIRE(length > 1U);
12351 * Leave space for terminating '\0'.
12353 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12355 if (zone->view == NULL) {
12356 isc_buffer_putstr(&buffer, "_none");
12357 } else if (strlen(zone->view->name)
12358 < isc_buffer_availablelength(&buffer)) {
12359 isc_buffer_putstr(&buffer, zone->view->name);
12361 isc_buffer_putstr(&buffer, "_toolong");
12364 buf[isc_buffer_usedlength(&buffer)] = '\0';
12368 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
12369 REQUIRE(DNS_ZONE_VALID(zone));
12370 REQUIRE(buf != NULL);
12371 zone_namerd_tostr(zone, buf, length);
12375 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12377 char message[4096];
12379 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12383 vsnprintf(message, sizeof(message), fmt, ap);
12385 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
12386 level, "zone %s: %s", zone->strnamerd, message);
12390 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
12391 int level, const char *fmt, ...) {
12393 char message[4096];
12395 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12399 vsnprintf(message, sizeof(message), fmt, ap);
12401 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
12402 level, "%s%s: %s", (zone->type == dns_zone_key) ?
12403 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
12404 "redirect-zone" : "zone ", zone->strnamerd, message);
12408 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12410 char message[4096];
12412 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12416 vsnprintf(message, sizeof(message), fmt, ap);
12418 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
12419 level, "%s%s: %s", (zone->type == dns_zone_key) ?
12420 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
12421 "redirect-zone" : "zone ", zone->strnamerd, message);
12425 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
12426 const char *fmt, ...)
12429 char message[4096];
12430 int level = ISC_LOG_DEBUG(debuglevel);
12433 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12437 vsnprintf(message, sizeof(message), fmt, ap);
12440 switch (zone->type) {
12442 zstr = "managed-keys-zone";
12444 case dns_zone_redirect:
12445 zstr = "redirect-zone";
12451 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
12452 level, "%s: %s %s: %s", me, zstr, zone->strnamerd,
12457 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
12459 isc_result_t result;
12461 dns_rdataset_t *curr;
12464 result = dns_message_firstname(msg, section);
12465 while (result == ISC_R_SUCCESS) {
12467 dns_message_currentname(msg, section, &name);
12469 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
12470 curr = ISC_LIST_PREV(curr, link)) {
12471 if (curr->type == type)
12474 result = dns_message_nextname(msg, section);
12481 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
12482 REQUIRE(DNS_ZONE_VALID(zone));
12484 zone->maxxfrin = maxxfrin;
12488 dns_zone_getmaxxfrin(dns_zone_t *zone) {
12489 REQUIRE(DNS_ZONE_VALID(zone));
12491 return (zone->maxxfrin);
12495 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
12496 REQUIRE(DNS_ZONE_VALID(zone));
12497 zone->maxxfrout = maxxfrout;
12501 dns_zone_getmaxxfrout(dns_zone_t *zone) {
12502 REQUIRE(DNS_ZONE_VALID(zone));
12504 return (zone->maxxfrout);
12508 dns_zone_gettype(dns_zone_t *zone) {
12509 REQUIRE(DNS_ZONE_VALID(zone));
12511 return (zone->type);
12515 dns_zone_getorigin(dns_zone_t *zone) {
12516 REQUIRE(DNS_ZONE_VALID(zone));
12518 return (&zone->origin);
12522 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
12523 REQUIRE(DNS_ZONE_VALID(zone));
12526 if (zone->task != NULL)
12527 isc_task_detach(&zone->task);
12528 isc_task_attach(task, &zone->task);
12529 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12530 if (zone->db != NULL)
12531 dns_db_settask(zone->db, zone->task);
12532 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12537 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
12538 REQUIRE(DNS_ZONE_VALID(zone));
12539 isc_task_attach(zone->task, target);
12543 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
12544 REQUIRE(DNS_ZONE_VALID(zone));
12547 idlein = DNS_DEFAULT_IDLEIN;
12548 zone->idlein = idlein;
12552 dns_zone_getidlein(dns_zone_t *zone) {
12553 REQUIRE(DNS_ZONE_VALID(zone));
12555 return (zone->idlein);
12559 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
12560 REQUIRE(DNS_ZONE_VALID(zone));
12562 zone->idleout = idleout;
12566 dns_zone_getidleout(dns_zone_t *zone) {
12567 REQUIRE(DNS_ZONE_VALID(zone));
12569 return (zone->idleout);
12573 notify_done(isc_task_t *task, isc_event_t *event) {
12574 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12575 dns_notify_t *notify;
12576 isc_result_t result;
12577 dns_message_t *message = NULL;
12580 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
12584 notify = event->ev_arg;
12585 REQUIRE(DNS_NOTIFY_VALID(notify));
12586 INSIST(task == notify->zone->task);
12588 isc_buffer_init(&buf, rcode, sizeof(rcode));
12589 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
12591 result = revent->result;
12592 if (result == ISC_R_SUCCESS)
12593 result = dns_message_create(notify->zone->mctx,
12594 DNS_MESSAGE_INTENTPARSE, &message);
12595 if (result == ISC_R_SUCCESS)
12596 result = dns_request_getresponse(revent->request, message,
12597 DNS_MESSAGEPARSE_PRESERVEORDER);
12598 if (result == ISC_R_SUCCESS)
12599 result = dns_rcode_totext(message->rcode, &buf);
12600 if (result == ISC_R_SUCCESS)
12601 notify_log(notify->zone, ISC_LOG_DEBUG(3),
12602 "notify response from %s: %.*s",
12603 addrbuf, (int)buf.used, rcode);
12605 notify_log(notify->zone, ISC_LOG_DEBUG(2),
12606 "notify to %s failed: %s", addrbuf,
12607 dns_result_totext(result));
12610 * Old bind's return formerr if they see a soa record. Retry w/o
12611 * the soa if we see a formerr and had sent a SOA.
12613 isc_event_free(&event);
12614 if (message != NULL && message->rcode == dns_rcode_formerr &&
12615 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
12616 notify->flags |= DNS_NOTIFY_NOSOA;
12617 dns_request_destroy(¬ify->request);
12618 result = notify_send_queue(notify);
12619 if (result != ISC_R_SUCCESS)
12620 notify_destroy(notify, ISC_FALSE);
12622 if (result == ISC_R_TIMEDOUT)
12623 notify_log(notify->zone, ISC_LOG_DEBUG(1),
12624 "notify to %s: retries exceeded", addrbuf);
12625 notify_destroy(notify, ISC_FALSE);
12627 if (message != NULL)
12628 dns_message_destroy(&message);
12631 struct secure_event {
12634 isc_uint32_t serial;
12638 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
12640 dns_zone_log(zone, level, "%s", message);
12643 static isc_result_t
12644 sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal,
12645 isc_uint32_t start, isc_uint32_t end,
12646 dns_difftuple_t **soatuplep, dns_diff_t *diff)
12648 isc_result_t result;
12649 dns_difftuple_t *tuple = NULL;
12650 dns_diffop_t op = DNS_DIFFOP_ADD;
12653 REQUIRE(soatuplep != NULL);
12656 return (DNS_R_UNCHANGED);
12658 CHECK(dns_journal_iter_init(journal, start, end));
12659 for (result = dns_journal_first_rr(journal);
12660 result == ISC_R_SUCCESS;
12661 result = dns_journal_next_rr(journal))
12663 dns_name_t *name = NULL;
12665 dns_rdata_t *rdata = NULL;
12666 dns_journal_current_rr(journal, &name, &ttl, &rdata);
12668 if (rdata->type == dns_rdatatype_soa) {
12672 * Save the latest raw SOA record.
12674 if (*soatuplep != NULL)
12675 dns_difftuple_free(soatuplep);
12676 CHECK(dns_difftuple_create(diff->mctx,
12688 dns_zone_log(zone->raw, ISC_LOG_ERROR,
12689 "corrupt journal file: '%s'\n",
12690 zone->raw->journal);
12691 return (ISC_R_FAILURE);
12694 if (zone->privatetype != 0 &&
12695 rdata->type == zone->privatetype)
12698 if (rdata->type == dns_rdatatype_nsec ||
12699 rdata->type == dns_rdatatype_rrsig ||
12700 rdata->type == dns_rdatatype_nsec3 ||
12701 rdata->type == dns_rdatatype_dnskey ||
12702 rdata->type == dns_rdatatype_nsec3param)
12705 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
12707 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
12709 dns_diff_appendminimal(diff, &tuple);
12711 if (result == ISC_R_NOMORE)
12712 result = ISC_R_SUCCESS;
12718 static isc_result_t
12719 sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb,
12720 dns_dbversion_t *secver, dns_difftuple_t **soatuple,
12723 isc_result_t result;
12724 dns_db_t *rawdb = NULL;
12725 dns_dbversion_t *rawver = NULL;
12726 dns_difftuple_t *tuple = NULL, *next;
12727 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
12728 dns_rdata_soa_t oldsoa, newsoa;
12730 REQUIRE(DNS_ZONE_VALID(seczone));
12731 REQUIRE(inline_secure(seczone));
12732 REQUIRE(soatuple != NULL && *soatuple == NULL);
12734 if (!seczone->sourceserialset)
12735 return (DNS_R_UNCHANGED);
12737 dns_db_attach(seczone->raw->db, &rawdb);
12738 dns_db_currentversion(rawdb, &rawver);
12739 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
12740 dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
12741 dns_db_detach(&rawdb);
12743 if (result != ISC_R_SUCCESS)
12746 for (tuple = ISC_LIST_HEAD(diff->tuples);
12750 next = ISC_LIST_NEXT(tuple, link);
12751 if (tuple->rdata.type == dns_rdatatype_nsec ||
12752 tuple->rdata.type == dns_rdatatype_rrsig ||
12753 tuple->rdata.type == dns_rdatatype_dnskey ||
12754 tuple->rdata.type == dns_rdatatype_nsec3 ||
12755 tuple->rdata.type == dns_rdatatype_nsec3param)
12757 ISC_LIST_UNLINK(diff->tuples, tuple, link);
12758 dns_difftuple_free(&tuple);
12761 if (tuple->rdata.type == dns_rdatatype_soa) {
12762 if (tuple->op == DNS_DIFFOP_DEL) {
12763 INSIST(oldtuple == NULL);
12766 if (tuple->op == DNS_DIFFOP_ADD) {
12767 INSIST(newtuple == NULL);
12773 if (oldtuple != NULL && newtuple != NULL) {
12775 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
12776 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12778 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
12779 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12782 * If the SOA records are the same except for the serial
12783 * remove them from the diff.
12785 if (oldsoa.refresh == newsoa.refresh &&
12786 oldsoa.retry == newsoa.retry &&
12787 oldsoa.minimum == newsoa.minimum &&
12788 oldsoa.expire == newsoa.expire &&
12789 dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
12790 dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
12791 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
12792 dns_difftuple_free(&oldtuple);
12793 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
12794 dns_difftuple_free(&newtuple);
12798 if (ISC_LIST_EMPTY(diff->tuples))
12799 return (DNS_R_UNCHANGED);
12802 * If there are still SOA records in the diff they can now be removed
12803 * saving the new SOA record.
12805 if (oldtuple != NULL) {
12806 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
12807 dns_difftuple_free(&oldtuple);
12810 if (newtuple != NULL) {
12811 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
12812 *soatuple = newtuple;
12815 return (ISC_R_SUCCESS);
12819 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
12820 static char me[] = "receive_secure_serial";
12821 isc_result_t result;
12822 dns_journal_t *rjournal = NULL;
12823 isc_uint32_t start, end;
12825 dns_db_t *db = NULL;
12826 dns_dbversion_t *newver = NULL, *oldver = NULL;
12828 dns_difftuple_t *tuple = NULL, *soatuple = NULL;
12829 dns_update_log_t log = { update_log_cb, NULL };
12830 isc_time_t timenow;
12832 zone = event->ev_arg;
12833 end = ((struct secure_event *)event)->serial;
12834 isc_event_free(&event);
12840 dns_diff_init(zone->mctx, &diff);
12844 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12845 if (zone->db != NULL)
12846 dns_db_attach(zone->db, &db);
12847 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12850 * zone->db may be NULL if the load from disk failed.
12852 if (db == NULL || !inline_secure(zone)) {
12853 result = ISC_R_FAILURE;
12858 * We first attempt to sync the raw zone to the secure zone
12859 * by using the raw zone's journal, applying all the deltas
12860 * from the latest source-serial of the secure zone up to
12861 * the current serial number of the raw zone.
12863 * If that fails, then we'll fall back to a direct comparison
12864 * between raw and secure zones.
12866 result = dns_journal_open(zone->raw->mctx, zone->raw->journal,
12867 DNS_JOURNAL_WRITE, &rjournal);
12868 if (result != ISC_R_SUCCESS)
12871 dns_journal_t *sjournal = NULL;
12873 result = dns_journal_open(zone->mctx, zone->journal,
12874 DNS_JOURNAL_READ, &sjournal);
12875 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
12878 if (!dns_journal_get_sourceserial(rjournal, &start)) {
12879 start = dns_journal_first_serial(rjournal);
12880 dns_journal_set_sourceserial(rjournal, start);
12882 if (sjournal != NULL) {
12883 isc_uint32_t serial;
12885 * We read the secure journal first, if that exists
12886 * use its value provided it is greater that from the
12889 if (dns_journal_get_sourceserial(sjournal, &serial)) {
12890 if (isc_serial_gt(serial, start))
12893 dns_journal_destroy(&sjournal);
12897 dns_db_currentversion(db, &oldver);
12898 CHECK(dns_db_newversion(db, &newver));
12901 * Try to apply diffs from the raw zone's journal to the secure
12902 * zone. If that fails, we recover by syncing up the databases
12905 result = sync_secure_journal(zone, rjournal, start, end,
12907 if (result == DNS_R_UNCHANGED)
12909 else if (result != ISC_R_SUCCESS)
12910 CHECK(sync_secure_db(zone, db, oldver, &soatuple, &diff));
12912 CHECK(dns_diff_apply(&diff, db, newver));
12914 if (soatuple != NULL) {
12915 isc_uint32_t oldserial, newserial, desired;
12917 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
12918 DNS_DIFFOP_DEL, &tuple));
12919 oldserial = dns_soa_getserial(&tuple->rdata);
12920 newserial = desired = dns_soa_getserial(&soatuple->rdata);
12921 if (!isc_serial_gt(newserial, oldserial)) {
12922 newserial = oldserial + 1;
12923 if (newserial == 0)
12925 dns_soa_setserial(newserial, &soatuple->rdata);
12927 CHECK(do_one_tuple(&tuple, db, newver, &diff));
12928 CHECK(do_one_tuple(&soatuple, db, newver, &diff));
12929 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
12930 newserial, desired);
12932 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
12933 zone->updatemethod));
12935 CHECK(dns_update_signatures(&log, zone, db, oldver, newver,
12936 &diff, zone->sigvalidityinterval));
12938 CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial"));
12940 dns_journal_set_sourceserial(rjournal, end);
12941 dns_journal_commit(rjournal);
12943 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
12945 zone->sourceserial = end;
12946 zone->sourceserialset = ISC_TRUE;
12947 zone_needdump(zone, DNS_DUMP_DELAY);
12949 TIME_NOW(&timenow);
12950 zone_settimer(zone, &timenow);
12952 dns_db_closeversion(db, &oldver, ISC_FALSE);
12953 dns_db_closeversion(db, &newver, ISC_TRUE);
12957 if (result != ISC_R_SUCCESS)
12958 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
12959 dns_result_totext(result));
12961 dns_difftuple_free(&tuple);
12962 if (soatuple != NULL)
12963 dns_difftuple_free(&soatuple);
12965 if (oldver != NULL)
12966 dns_db_closeversion(db, &oldver, ISC_FALSE);
12967 if (newver != NULL)
12968 dns_db_closeversion(db, &newver, ISC_FALSE);
12969 dns_db_detach(&db);
12971 if (rjournal != NULL)
12972 dns_journal_destroy(&rjournal);
12973 dns_diff_clear(&diff);
12974 dns_zone_idetach(&zone);
12977 static isc_result_t
12978 zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) {
12980 dns_zone_t *dummy = NULL;
12982 e = isc_event_allocate(zone->secure->mctx, zone,
12983 DNS_EVENT_ZONESECURESERIAL,
12984 receive_secure_serial, zone->secure,
12985 sizeof(struct secure_event));
12987 return (ISC_R_NOMEMORY);
12988 ((struct secure_event *)e)->serial = serial;
12989 INSIST(LOCKED_ZONE(zone->secure));
12990 zone_iattach(zone->secure, &dummy);
12991 isc_task_send(zone->secure->task, &e);
12993 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
12994 return (ISC_R_SUCCESS);
12997 static isc_result_t
12998 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
12999 dns_rdataset_t *rdataset, isc_uint32_t oldserial)
13001 dns_rdata_soa_t soa;
13002 dns_rdata_t rdata = DNS_RDATA_INIT;
13003 dns_rdatalist_t temprdatalist;
13004 dns_rdataset_t temprdataset;
13006 isc_result_t result;
13007 unsigned char buf[DNS_SOA_BUFFERSIZE];
13009 result = dns_rdataset_first(rdataset);
13010 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13011 dns_rdataset_current(rdataset, &rdata);
13012 result = dns_rdata_tostruct(&rdata, &soa, NULL);
13013 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13015 if (isc_serial_gt(soa.serial, oldserial))
13016 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
13019 * Always bump the serial.
13022 if (oldserial == 0)
13024 soa.serial = oldserial;
13027 * Construct a replacement rdataset.
13029 dns_rdata_reset(&rdata);
13030 isc_buffer_init(&b, buf, sizeof(buf));
13031 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
13032 dns_rdatatype_soa, &soa, &b);
13033 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13034 temprdatalist.rdclass = rdata.rdclass;
13035 temprdatalist.type = rdata.type;
13036 temprdatalist.covers = 0;
13037 temprdatalist.ttl = rdataset->ttl;
13038 ISC_LIST_INIT(temprdatalist.rdata);
13039 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
13041 dns_rdataset_init(&temprdataset);
13042 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
13043 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13044 return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
13049 * This function should populate an nsec3paramlist_t with the
13050 * nsecparam_t data from a zone.
13052 static isc_result_t
13053 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
13054 isc_result_t result;
13055 dns_dbnode_t *node = NULL;
13056 dns_rdataset_t rdataset, prdataset;
13057 dns_rdata_t rdata_in, prdata_in, prdata_out;
13058 dns_dbversion_t *version = NULL;
13059 nsec3param_t *nsec3param = NULL;
13060 nsec3param_t *nsec3p = NULL;
13061 nsec3param_t *next;
13062 dns_db_t *db = NULL;
13063 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
13065 REQUIRE(DNS_ZONE_VALID(zone));
13066 REQUIRE(nsec3list != NULL);
13067 REQUIRE(ISC_LIST_EMPTY(*nsec3list));
13069 dns_db_attach(zone->db, &db);
13070 CHECK(dns_db_getoriginnode(db, &node));
13072 dns_rdataset_init(&rdataset);
13073 dns_db_currentversion(db, &version);
13074 result = dns_db_findrdataset(db, node, version,
13075 dns_rdatatype_nsec3param,
13076 dns_rdatatype_none, 0, &rdataset, NULL);
13078 if (result != ISC_R_SUCCESS)
13082 * walk nsec3param rdataset making a list of parameters (note that
13083 * multiple simultaneous nsec3 chains are annoyingly legal -- this
13084 * is why we use an nsec3list, even tho we will usually only have
13087 for (result = dns_rdataset_first(&rdataset);
13088 result == ISC_R_SUCCESS;
13089 result = dns_rdataset_next(&rdataset))
13091 dns_rdata_init(&rdata_in);
13092 dns_rdataset_current(&rdataset, &rdata_in);
13093 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13094 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13095 "looping through nsec3param data");
13096 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13097 if (nsec3param == NULL)
13098 CHECK(ISC_R_NOMEMORY);
13099 ISC_LINK_INIT(nsec3param, link);
13102 * now transfer the data from the rdata to
13105 dns_rdata_init(&prdata_out);
13106 dns_nsec3param_toprivate(&rdata_in, &prdata_out,
13107 zone->privatetype, nsec3param->data,
13108 sizeof(nsec3param->data));
13109 nsec3param->length = prdata_out.length;
13110 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13114 dns_rdataset_init(&prdataset);
13115 result = dns_db_findrdataset(db, node, version, zone->privatetype,
13116 dns_rdatatype_none, 0, &prdataset, NULL);
13117 if (result != ISC_R_SUCCESS)
13121 * walk private type records, converting them to nsec3 parameters
13122 * using dns_nsec3param_fromprivate(), do the right thing based on
13123 * CREATE and REMOVE flags
13125 for (result = dns_rdataset_first(&prdataset);
13126 result == ISC_R_SUCCESS;
13127 result = dns_rdataset_next(&prdataset))
13129 dns_rdata_init(&prdata_in);
13130 dns_rdataset_current(&prdataset, &prdata_in);
13131 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13132 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13133 "looping through nsec3param private data");
13135 if (!dns_nsec3param_fromprivate(&prdata_in, &prdata_out,
13139 if ((prdata_out.data[1] & DNS_NSEC3FLAG_REMOVE) !=0) {
13140 prdata_out.data[1] = 0;
13142 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13146 next = ISC_LIST_NEXT(nsec3p, link);
13147 if (memcmp(prdata_out.data, nsec3p->data,
13148 sizeof(nsec3p->data)) == 0) {
13149 ISC_LIST_UNLINK(*nsec3list,
13151 isc_mem_put(zone->mctx, nsec3p,
13152 sizeof(nsec3param_t));
13158 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13159 if (nsec3param == NULL)
13160 CHECK(ISC_R_NOMEMORY);
13161 ISC_LINK_INIT(nsec3param, link);
13163 dns_rdata_init(&prdata_out);
13164 dns_nsec3param_toprivate(&prdata_in, &prdata_out,
13165 zone->privatetype, nsec3param->data,
13166 sizeof(nsec3param->data));
13167 nsec3param->length = prdata_out.length;
13168 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13172 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
13173 result = ISC_R_SUCCESS;
13177 dns_db_detachnode(db, &node);
13178 if (version != NULL)
13179 dns_db_closeversion(db, &version, ISC_FALSE);
13181 dns_db_detach(&db);
13182 if (dns_rdataset_isassociated(&rdataset))
13183 dns_rdataset_disassociate(&rdataset);
13184 if (dns_rdataset_isassociated(&prdataset))
13185 dns_rdataset_disassociate(&prdataset);
13190 * Walk the list of the nsec3 chains desired for the zone, converting
13191 * parameters to private type records using dns_nsec3param_toprivate(),
13192 * and insert them into the new zone db.
13194 static isc_result_t
13195 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
13196 nsec3paramlist_t *nsec3list)
13198 isc_result_t result;
13201 nsec3param_t *nsec3p = NULL;
13202 nsec3param_t *next;
13204 REQUIRE(DNS_ZONE_VALID(zone));
13205 REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
13207 dns_diff_init(zone->mctx, &diff);
13210 * Loop through the list of private-type records, set the INITIAL
13211 * and CREATE flags, and the add the record to the apex of the tree
13214 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13218 next = ISC_LIST_NEXT(nsec3p, link);
13219 dns_rdata_init(&rdata);
13220 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
13221 rdata.length = nsec3p->length;
13222 rdata.data = nsec3p->data;
13223 rdata.type = zone->privatetype;
13224 rdata.rdclass = zone->rdclass;
13225 CHECK(update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
13226 &zone->origin, 0, &rdata));
13229 result = ISC_R_SUCCESS;
13232 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13236 next = ISC_LIST_NEXT(nsec3p, link);
13237 ISC_LIST_UNLINK(*nsec3list, nsec3p, link);
13238 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
13241 dns_diff_clear(&diff);
13246 receive_secure_db(isc_task_t *task, isc_event_t *event) {
13247 isc_result_t result;
13249 dns_db_t *rawdb, *db = NULL;
13250 dns_dbnode_t *rawnode = NULL, *node = NULL;
13251 dns_fixedname_t fname;
13253 dns_dbiterator_t *dbiterator = NULL;
13254 dns_rdatasetiter_t *rdsit = NULL;
13255 dns_rdataset_t rdataset;
13256 dns_dbversion_t *version = NULL;
13257 isc_time_t loadtime;
13258 unsigned int oldserial = 0;
13259 isc_boolean_t have_oldserial = ISC_FALSE;
13260 nsec3paramlist_t nsec3list;
13264 ISC_LIST_INIT(nsec3list);
13266 zone = event->ev_arg;
13267 rawdb = ((struct secure_event *)event)->db;
13268 isc_event_free(&event);
13270 dns_fixedname_init(&fname);
13271 name = dns_fixedname_name(&fname);
13272 dns_rdataset_init(&rdataset);
13275 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
13276 result = ISC_R_SHUTTINGDOWN;
13280 TIME_NOW(&loadtime);
13281 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13282 if (zone->db != NULL) {
13283 result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
13284 if (result == ISC_R_SUCCESS)
13285 have_oldserial = ISC_TRUE;
13288 * assemble nsec3parameters from the old zone, and set a flag
13291 result = save_nsec3param(zone, &nsec3list);
13292 if (result != ISC_R_SUCCESS) {
13293 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13297 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13299 result = dns_db_create(zone->mctx, zone->db_argv[0],
13300 &zone->origin, dns_dbtype_zone, zone->rdclass,
13301 zone->db_argc - 1, zone->db_argv + 1, &db);
13302 if (result != ISC_R_SUCCESS)
13305 result = dns_db_newversion(db, &version);
13306 if (result != ISC_R_SUCCESS)
13309 result = dns_db_createiterator(rawdb, 0, &dbiterator);
13310 if (result != ISC_R_SUCCESS)
13313 for (result = dns_dbiterator_first(dbiterator);
13314 result == ISC_R_SUCCESS;
13315 result = dns_dbiterator_next(dbiterator)) {
13316 result = dns_dbiterator_current(dbiterator, &rawnode, name);
13317 if (result != ISC_R_SUCCESS)
13320 result = dns_db_findnode(db, name, ISC_TRUE, &node);
13321 if (result != ISC_R_SUCCESS)
13324 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
13325 if (result != ISC_R_SUCCESS)
13328 for (result = dns_rdatasetiter_first(rdsit);
13329 result == ISC_R_SUCCESS;
13330 result = dns_rdatasetiter_next(rdsit)) {
13331 dns_rdatasetiter_current(rdsit, &rdataset);
13332 if (rdataset.type == dns_rdatatype_nsec ||
13333 rdataset.type == dns_rdatatype_rrsig ||
13334 rdataset.type == dns_rdatatype_nsec3 ||
13335 rdataset.type == dns_rdatatype_dnskey ||
13336 rdataset.type == dns_rdatatype_nsec3param) {
13337 dns_rdataset_disassociate(&rdataset);
13340 if (rdataset.type == dns_rdatatype_soa &&
13342 result = checkandaddsoa(db, node, version,
13343 &rdataset, oldserial);
13345 result = dns_db_addrdataset(db, node, version,
13348 if (result != ISC_R_SUCCESS)
13351 dns_rdataset_disassociate(&rdataset);
13353 dns_rdatasetiter_destroy(&rdsit);
13354 dns_db_detachnode(rawdb, &rawnode);
13355 dns_db_detachnode(db, &node);
13359 * Call restore_nsec3param() to create private-type records from
13360 * the old nsec3 parameters and insert them into db
13362 if (!ISC_LIST_EMPTY(nsec3list))
13363 restore_nsec3param(zone, db, version, &nsec3list);
13365 dns_db_closeversion(db, &version, ISC_TRUE);
13368 * Lock hierarchy: zmgr, zone, raw.
13370 INSIST(zone != zone->raw);
13371 LOCK_ZONE(zone->raw);
13372 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13373 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
13374 zone_needdump(zone, 0); /* XXXMPA */
13375 UNLOCK_ZONE(zone->raw);
13379 if (result != ISC_R_SUCCESS)
13380 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
13381 dns_result_totext(result));
13383 if (dns_rdataset_isassociated(&rdataset))
13384 dns_rdataset_disassociate(&rdataset);
13387 dns_db_detachnode(db, &node);
13388 dns_db_detach(&db);
13390 if (rawnode != NULL)
13391 dns_db_detachnode(rawdb, &rawnode);
13392 dns_db_detach(&rawdb);
13393 if (dbiterator != NULL)
13394 dns_dbiterator_destroy(&dbiterator);
13395 dns_zone_idetach(&zone);
13398 static isc_result_t
13399 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
13401 dns_db_t *dummy = NULL;
13402 dns_zone_t *secure = NULL;
13404 e = isc_event_allocate(zone->secure->mctx, zone,
13405 DNS_EVENT_ZONESECUREDB,
13406 receive_secure_db, zone->secure,
13407 sizeof(struct secure_event));
13409 return (ISC_R_NOMEMORY);
13410 dns_db_attach(db, &dummy);
13411 ((struct secure_event *)e)->db = dummy;
13412 INSIST(LOCKED_ZONE(zone->secure));
13413 zone_iattach(zone->secure, &secure);
13414 isc_task_send(zone->secure->task, &e);
13415 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
13416 return (ISC_R_SUCCESS);
13420 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
13421 isc_result_t result;
13422 dns_zone_t *secure = NULL;
13424 REQUIRE(DNS_ZONE_VALID(zone));
13427 if (inline_raw(zone)) {
13428 secure = zone->secure;
13429 INSIST(secure != zone);
13430 TRYLOCK_ZONE(result, secure);
13431 if (result != ISC_R_SUCCESS) {
13434 #if ISC_PLATFORM_USETHREADS
13435 isc_thread_yield();
13440 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
13441 result = zone_replacedb(zone, db, dump);
13442 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
13443 if (secure != NULL)
13444 UNLOCK_ZONE(secure);
13449 static isc_result_t
13450 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
13451 dns_dbversion_t *ver;
13452 isc_result_t result;
13453 unsigned int soacount = 0;
13454 unsigned int nscount = 0;
13457 * 'zone' and 'zonedb' locked by caller.
13459 REQUIRE(DNS_ZONE_VALID(zone));
13460 REQUIRE(LOCKED_ZONE(zone));
13461 if (inline_raw(zone))
13462 REQUIRE(LOCKED_ZONE(zone->secure));
13464 result = zone_get_from_db(zone, db, &nscount, &soacount,
13465 NULL, NULL, NULL, NULL, NULL, NULL);
13466 if (result == ISC_R_SUCCESS) {
13467 if (soacount != 1) {
13468 dns_zone_log(zone, ISC_LOG_ERROR,
13469 "has %d SOA records", soacount);
13470 result = DNS_R_BADZONE;
13472 if (nscount == 0 && zone->type != dns_zone_key) {
13473 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
13474 result = DNS_R_BADZONE;
13476 if (result != ISC_R_SUCCESS)
13479 dns_zone_log(zone, ISC_LOG_ERROR,
13480 "retrieving SOA and NS records failed: %s",
13481 dns_result_totext(result));
13485 result = check_nsec3param(zone, db);
13486 if (result != ISC_R_SUCCESS)
13490 dns_db_currentversion(db, &ver);
13493 * The initial version of a slave zone is always dumped;
13494 * subsequent versions may be journaled instead if this
13495 * is enabled in the configuration.
13497 if (zone->db != NULL && zone->journal != NULL &&
13498 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
13499 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
13501 isc_uint32_t serial, oldserial;
13502 unsigned int soacount;
13504 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
13506 result = dns_db_getsoaserial(db, ver, &serial);
13507 if (result != ISC_R_SUCCESS) {
13508 dns_zone_log(zone, ISC_LOG_ERROR,
13509 "ixfr-from-differences: unable to get "
13515 * This is checked in zone_postload() for master zones.
13517 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
13518 &oldserial, NULL, NULL, NULL, NULL,
13520 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13521 RUNTIME_CHECK(soacount > 0U);
13522 if ((zone->type == dns_zone_slave ||
13523 (zone->type == dns_zone_redirect &&
13524 zone->masters != NULL))
13525 && !isc_serial_gt(serial, oldserial)) {
13526 isc_uint32_t serialmin, serialmax;
13527 serialmin = (oldserial + 1) & 0xffffffffU;
13528 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
13529 dns_zone_log(zone, ISC_LOG_ERROR,
13530 "ixfr-from-differences: failed: "
13531 "new serial (%u) out of range [%u - %u]",
13532 serial, serialmin, serialmax);
13533 result = ISC_R_RANGE;
13537 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
13539 if (result != ISC_R_SUCCESS)
13542 zone_needdump(zone, DNS_DUMP_DELAY);
13543 else if (zone->journalsize != -1) {
13544 result = dns_journal_compact(zone->mctx, zone->journal,
13545 serial, zone->journalsize);
13547 case ISC_R_SUCCESS:
13548 case ISC_R_NOSPACE:
13549 case ISC_R_NOTFOUND:
13550 dns_zone_log(zone, ISC_LOG_DEBUG(3),
13551 "dns_journal_compact: %s",
13552 dns_result_totext(result));
13555 dns_zone_log(zone, ISC_LOG_ERROR,
13556 "dns_journal_compact failed: %s",
13557 dns_result_totext(result));
13561 if (zone->type == dns_zone_master && inline_raw(zone))
13562 zone_send_secureserial(zone, serial);
13564 if (dump && zone->masterfile != NULL) {
13566 * If DNS_ZONEFLG_FORCEXFER was set we don't want
13567 * to keep the old masterfile.
13569 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
13570 remove(zone->masterfile) < 0 && errno != ENOENT) {
13571 char strbuf[ISC_STRERRORSIZE];
13572 isc__strerror(errno, strbuf, sizeof(strbuf));
13573 isc_log_write(dns_lctx,
13574 DNS_LOGCATEGORY_GENERAL,
13575 DNS_LOGMODULE_ZONE,
13577 "unable to remove masterfile "
13579 zone->masterfile, strbuf);
13581 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
13582 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
13584 zone_needdump(zone, 0);
13586 if (dump && zone->journal != NULL) {
13588 * The in-memory database just changed, and
13589 * because 'dump' is set, it didn't change by
13590 * being loaded from disk. Also, we have not
13591 * journaled diffs for this change.
13592 * Therefore, the on-disk journal is missing
13593 * the deltas for this change. Since it can
13594 * no longer be used to bring the zone
13595 * up-to-date, it is useless and should be
13598 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13599 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13600 "removing journal file");
13601 if (remove(zone->journal) < 0 && errno != ENOENT) {
13602 char strbuf[ISC_STRERRORSIZE];
13603 isc__strerror(errno, strbuf, sizeof(strbuf));
13604 isc_log_write(dns_lctx,
13605 DNS_LOGCATEGORY_GENERAL,
13606 DNS_LOGMODULE_ZONE,
13608 "unable to remove journal "
13610 zone->journal, strbuf);
13614 if (inline_raw(zone))
13615 zone_send_securedb(zone, db);
13618 dns_db_closeversion(db, &ver, ISC_FALSE);
13620 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
13622 if (zone->db != NULL)
13623 zone_detachdb(zone);
13624 zone_attachdb(zone, db);
13625 dns_db_settask(zone->db, zone->task);
13626 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
13627 return (ISC_R_SUCCESS);
13630 dns_db_closeversion(db, &ver, ISC_FALSE);
13634 /* The caller must hold the dblock as a writer. */
13636 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
13637 REQUIRE(zone->db == NULL && db != NULL);
13639 dns_db_attach(db, &zone->db);
13640 if (zone->acache != NULL) {
13641 isc_result_t result;
13642 result = dns_acache_setdb(zone->acache, db);
13643 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
13644 UNEXPECTED_ERROR(__FILE__, __LINE__,
13645 "dns_acache_setdb() failed: %s",
13646 isc_result_totext(result));
13651 /* The caller must hold the dblock as a writer. */
13653 zone_detachdb(dns_zone_t *zone) {
13654 REQUIRE(zone->db != NULL);
13656 if (zone->acache != NULL)
13657 (void)dns_acache_putdb(zone->acache, zone->db);
13658 dns_db_detach(&zone->db);
13662 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
13664 isc_boolean_t again = ISC_FALSE;
13665 unsigned int soacount;
13666 unsigned int nscount;
13667 isc_uint32_t serial, refresh, retry, expire, minimum;
13668 isc_result_t xfrresult = result;
13669 isc_boolean_t free_needed;
13670 dns_zone_t *secure = NULL;
13672 REQUIRE(DNS_ZONE_VALID(zone));
13674 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13675 "zone transfer finished: %s", dns_result_totext(result));
13678 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
13679 * could result in a deadlock due to a LOR so we will spin if we
13680 * can't obtain the both locks.
13684 if (inline_raw(zone)) {
13685 secure = zone->secure;
13686 INSIST(secure != zone);
13687 TRYLOCK_ZONE(result, secure);
13688 if (result != ISC_R_SUCCESS) {
13691 #if ISC_PLATFORM_USETHREADS
13692 isc_thread_yield();
13698 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
13699 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
13700 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
13704 case ISC_R_SUCCESS:
13705 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13707 case DNS_R_UPTODATE:
13708 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13710 * Has the zone expired underneath us?
13712 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13713 if (zone->db == NULL) {
13714 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13719 * Update the zone structure's data from the actual
13724 INSIST(zone->db != NULL);
13725 result = zone_get_from_db(zone, zone->db, &nscount,
13726 &soacount, &serial, &refresh,
13727 &retry, &expire, &minimum, NULL);
13728 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13729 if (result == ISC_R_SUCCESS) {
13731 dns_zone_log(zone, ISC_LOG_ERROR,
13732 "transferred zone "
13733 "has %d SOA record%s", soacount,
13734 (soacount != 0) ? "s" : "");
13735 if (nscount == 0) {
13736 dns_zone_log(zone, ISC_LOG_ERROR,
13737 "transferred zone "
13738 "has no NS records");
13739 if (DNS_ZONE_FLAG(zone,
13740 DNS_ZONEFLG_HAVETIMERS)) {
13741 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
13742 zone->retry = DNS_ZONE_DEFAULTRETRY;
13744 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
13748 zone->refresh = RANGE(refresh, zone->minrefresh,
13750 zone->retry = RANGE(retry, zone->minretry,
13752 zone->expire = RANGE(expire,
13753 zone->refresh + zone->retry,
13755 zone->minimum = minimum;
13756 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
13760 * Set our next update/expire times.
13762 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
13763 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
13764 zone->refreshtime = now;
13765 DNS_ZONE_TIME_ADD(&now, zone->expire,
13766 &zone->expiretime);
13768 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
13769 &zone->refreshtime);
13770 DNS_ZONE_TIME_ADD(&now, zone->expire,
13771 &zone->expiretime);
13773 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
13774 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
13775 if (zone->tsigkey != NULL) {
13776 char namebuf[DNS_NAME_FORMATSIZE];
13777 dns_name_format(&zone->tsigkey->name, namebuf,
13779 snprintf(buf, sizeof(buf), ": TSIG '%s'",
13783 dns_zone_log(zone, ISC_LOG_INFO,
13784 "transferred serial %u%s",
13786 if (inline_raw(zone))
13787 zone_send_secureserial(zone, serial);
13791 * This is not necessary if we just performed a AXFR
13792 * however it is necessary for an IXFR / UPTODATE and
13793 * won't hurt with an AXFR.
13795 if (zone->masterfile != NULL || zone->journal != NULL) {
13796 unsigned int delay = DNS_DUMP_DELAY;
13798 result = ISC_R_FAILURE;
13799 if (zone->journal != NULL)
13800 result = isc_file_settime(zone->journal, &now);
13801 if (result != ISC_R_SUCCESS &&
13802 zone->masterfile != NULL)
13803 result = isc_file_settime(zone->masterfile,
13806 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
13807 result == ISC_R_FILENOTFOUND)
13810 if ((result == ISC_R_SUCCESS ||
13811 result == ISC_R_FILENOTFOUND) &&
13812 zone->masterfile != NULL)
13813 zone_needdump(zone, delay);
13814 else if (result != ISC_R_SUCCESS)
13815 dns_zone_log(zone, ISC_LOG_ERROR,
13816 "transfer: could not set file "
13817 "modification time of '%s': %s",
13819 dns_result_totext(result));
13821 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
13822 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
13825 case DNS_R_BADIXFR:
13826 /* Force retry with AXFR. */
13827 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
13833 * Skip to next failed / untried master.
13837 } while (zone->curmaster < zone->masterscnt &&
13838 zone->mastersok[zone->curmaster]);
13841 if (zone->curmaster >= zone->masterscnt) {
13842 zone->curmaster = 0;
13843 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
13844 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
13845 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
13846 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
13847 while (zone->curmaster < zone->masterscnt &&
13848 zone->mastersok[zone->curmaster])
13852 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
13854 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
13857 inc_stats(zone, dns_zonestatscounter_xfrfail);
13860 zone_settimer(zone, &now);
13863 * If creating the transfer object failed, zone->xfr is NULL.
13864 * Otherwise, we are called as the done callback of a zone
13865 * transfer object that just entered its shutting-down
13866 * state. Since we are no longer responsible for shutting
13867 * it down, we can detach our reference.
13869 if (zone->xfr != NULL)
13870 dns_xfrin_detach(&zone->xfr);
13872 if (zone->tsigkey != NULL)
13873 dns_tsigkey_detach(&zone->tsigkey);
13876 * Handle any deferred journal compaction.
13878 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
13879 result = dns_journal_compact(zone->mctx, zone->journal,
13880 zone->compact_serial,
13881 zone->journalsize);
13883 case ISC_R_SUCCESS:
13884 case ISC_R_NOSPACE:
13885 case ISC_R_NOTFOUND:
13886 dns_zone_log(zone, ISC_LOG_DEBUG(3),
13887 "dns_journal_compact: %s",
13888 dns_result_totext(result));
13891 dns_zone_log(zone, ISC_LOG_ERROR,
13892 "dns_journal_compact failed: %s",
13893 dns_result_totext(result));
13896 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
13899 if (secure != NULL)
13900 UNLOCK_ZONE(secure);
13902 * This transfer finishing freed up a transfer quota slot.
13903 * Let any other zones waiting for quota have it.
13905 if (zone->zmgr != NULL &&
13906 zone->statelist == &zone->zmgr->xfrin_in_progress) {
13908 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
13909 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
13910 zone->statelist = NULL;
13911 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
13912 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
13917 * Retry with a different server if necessary.
13919 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
13920 queue_soa_query(zone);
13922 INSIST(zone->irefs > 0);
13924 free_needed = exit_check(zone);
13931 zone_loaddone(void *arg, isc_result_t result) {
13932 static char me[] = "zone_loaddone";
13933 dns_load_t *load = arg;
13935 isc_result_t tresult;
13936 dns_zone_t *secure = NULL;
13938 REQUIRE(DNS_LOAD_VALID(load));
13943 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
13944 if (tresult != ISC_R_SUCCESS &&
13945 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
13949 * Lock hierarchy: zmgr, zone, raw.
13953 if (inline_secure(zone))
13954 LOCK_ZONE(zone->raw);
13955 else if (inline_raw(zone)) {
13956 secure = zone->secure;
13957 TRYLOCK_ZONE(result, secure);
13958 if (result != ISC_R_SUCCESS) {
13961 #if ISC_PLATFORM_USETHREADS
13962 isc_thread_yield();
13967 (void)zone_postload(zone, load->db, load->loadtime, result);
13968 zonemgr_putio(&zone->readio);
13969 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
13970 zone_idetach(&load->callbacks.zone);
13972 * Leave the zone frozen if the reload fails.
13974 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
13975 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
13976 zone->update_disabled = ISC_FALSE;
13977 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
13978 if (inline_secure(zone))
13979 UNLOCK_ZONE(zone->raw);
13980 else if (secure != NULL)
13981 UNLOCK_ZONE(secure);
13985 dns_db_detach(&load->db);
13986 if (load->zone->lctx != NULL)
13987 dns_loadctx_detach(&load->zone->lctx);
13988 dns_zone_idetach(&load->zone);
13989 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
13993 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
13994 REQUIRE(DNS_ZONE_VALID(zone));
13995 REQUIRE(table != NULL);
13996 REQUIRE(*table == NULL);
13999 if (zone->ssutable != NULL)
14000 dns_ssutable_attach(zone->ssutable, table);
14005 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
14006 REQUIRE(DNS_ZONE_VALID(zone));
14009 if (zone->ssutable != NULL)
14010 dns_ssutable_detach(&zone->ssutable);
14012 dns_ssutable_attach(table, &zone->ssutable);
14017 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
14018 REQUIRE(DNS_ZONE_VALID(zone));
14020 zone->sigvalidityinterval = interval;
14024 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
14025 REQUIRE(DNS_ZONE_VALID(zone));
14027 return (zone->sigvalidityinterval);
14031 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
14034 REQUIRE(DNS_ZONE_VALID(zone));
14037 zone->sigresigninginterval = interval;
14038 set_resigntime(zone);
14039 if (zone->task != NULL) {
14041 zone_settimer(zone, &now);
14047 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
14048 REQUIRE(DNS_ZONE_VALID(zone));
14050 return (zone->sigresigninginterval);
14054 queue_xfrin(dns_zone_t *zone) {
14055 const char me[] = "queue_xfrin";
14056 isc_result_t result;
14057 dns_zonemgr_t *zmgr = zone->zmgr;
14061 INSIST(zone->statelist == NULL);
14063 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14064 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
14068 zone->statelist = &zmgr->waiting_for_xfrin;
14069 result = zmgr_start_xfrin_ifquota(zmgr, zone);
14070 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14072 if (result == ISC_R_QUOTA) {
14073 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
14074 "zone transfer deferred due to quota");
14075 } else if (result != ISC_R_SUCCESS) {
14076 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
14077 "starting zone transfer: %s",
14078 isc_result_totext(result));
14083 * This event callback is called when a zone has received
14084 * any necessary zone transfer quota. This is the time
14085 * to go ahead and start the transfer.
14088 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
14089 isc_result_t result = ISC_R_SUCCESS;
14090 dns_peer_t *peer = NULL;
14091 char master[ISC_SOCKADDR_FORMATSIZE];
14092 char source[ISC_SOCKADDR_FORMATSIZE];
14093 dns_rdatatype_t xfrtype;
14094 dns_zone_t *zone = event->ev_arg;
14095 isc_netaddr_t masterip;
14096 isc_sockaddr_t sourceaddr;
14097 isc_sockaddr_t masteraddr;
14099 const char *soa_before = "";
14100 isc_boolean_t loaded;
14104 INSIST(task == zone->task);
14106 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
14107 result = ISC_R_CANCELED;
14113 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
14114 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
14115 &zone->sourceaddr, &now))
14117 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
14118 dns_zone_log(zone, ISC_LOG_INFO,
14119 "got_transfer_quota: skipping zone transfer as "
14120 "master %s (source %s) is unreachable (cached)",
14122 result = ISC_R_CANCELED;
14126 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
14127 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
14129 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14130 soa_before = "SOA before ";
14132 * Decide whether we should request IXFR or AXFR.
14134 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14135 loaded = ISC_TF(zone->db != NULL);
14136 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14139 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14140 "no database exists yet, requesting AXFR of "
14141 "initial version from %s", master);
14142 xfrtype = dns_rdatatype_axfr;
14143 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
14144 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14145 "forced reload, requesting AXFR of "
14146 "initial version from %s", master);
14147 xfrtype = dns_rdatatype_axfr;
14148 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
14149 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14150 "retrying with AXFR from %s due to "
14151 "previous IXFR failure", master);
14152 xfrtype = dns_rdatatype_axfr;
14154 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
14157 isc_boolean_t use_ixfr = ISC_TRUE;
14159 result = dns_peer_getrequestixfr(peer, &use_ixfr);
14160 if (peer == NULL || result != ISC_R_SUCCESS)
14161 use_ixfr = zone->requestixfr;
14162 if (use_ixfr == ISC_FALSE) {
14163 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14164 "IXFR disabled, requesting %sAXFR from %s",
14165 soa_before, master);
14166 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14167 xfrtype = dns_rdatatype_soa;
14169 xfrtype = dns_rdatatype_axfr;
14171 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14172 "requesting IXFR from %s", master);
14173 xfrtype = dns_rdatatype_ixfr;
14178 * Determine if we should attempt to sign the request with TSIG.
14180 result = ISC_R_NOTFOUND;
14182 * First, look for a tsig key in the master statement, then
14183 * try for a server key.
14185 if ((zone->masterkeynames != NULL) &&
14186 (zone->masterkeynames[zone->curmaster] != NULL)) {
14187 dns_view_t *view = dns_zone_getview(zone);
14188 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
14189 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
14191 if (zone->tsigkey == NULL)
14192 result = dns_view_getpeertsig(zone->view, &masterip,
14195 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
14196 dns_zone_log(zone, ISC_LOG_ERROR,
14197 "could not get TSIG key for zone transfer: %s",
14198 isc_result_totext(result));
14202 masteraddr = zone->masteraddr;
14203 sourceaddr = zone->sourceaddr;
14205 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
14206 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
14207 zone->tsigkey, zone->mctx,
14208 zone->zmgr->timermgr, zone->zmgr->socketmgr,
14209 zone->task, zone_xfrdone, &zone->xfr);
14210 if (result == ISC_R_SUCCESS) {
14212 if (xfrtype == dns_rdatatype_axfr) {
14213 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
14214 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
14216 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
14217 } else if (xfrtype == dns_rdatatype_ixfr) {
14218 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
14219 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
14221 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
14227 * Any failure in this function is handled like a failed
14228 * zone transfer. This ensures that we get removed from
14229 * zmgr->xfrin_in_progress.
14231 if (result != ISC_R_SUCCESS)
14232 zone_xfrdone(zone, result);
14234 isc_event_free(&event);
14238 * Update forwarding support.
14242 forward_destroy(dns_forward_t *forward) {
14244 forward->magic = 0;
14245 if (forward->request != NULL)
14246 dns_request_destroy(&forward->request);
14247 if (forward->msgbuf != NULL)
14248 isc_buffer_free(&forward->msgbuf);
14249 if (forward->zone != NULL) {
14250 LOCK(&forward->zone->lock);
14251 if (ISC_LINK_LINKED(forward, link))
14252 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
14253 UNLOCK(&forward->zone->lock);
14254 dns_zone_idetach(&forward->zone);
14256 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
14259 static isc_result_t
14260 sendtomaster(dns_forward_t *forward) {
14261 isc_result_t result;
14262 isc_sockaddr_t src;
14264 LOCK_ZONE(forward->zone);
14266 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
14267 UNLOCK_ZONE(forward->zone);
14268 return (ISC_R_CANCELED);
14271 if (forward->which >= forward->zone->masterscnt) {
14272 UNLOCK_ZONE(forward->zone);
14273 return (ISC_R_NOMORE);
14276 forward->addr = forward->zone->masters[forward->which];
14278 * Always use TCP regardless of whether the original update
14280 * XXX The timeout may but a bit small if we are far down a
14281 * transfer graph and the master has to try several masters.
14283 switch (isc_sockaddr_pf(&forward->addr)) {
14285 src = forward->zone->xfrsource4;
14288 src = forward->zone->xfrsource6;
14291 result = ISC_R_NOTIMPLEMENTED;
14294 result = dns_request_createraw(forward->zone->view->requestmgr,
14296 &src, &forward->addr,
14297 DNS_REQUESTOPT_TCP, 15 /* XXX */,
14298 forward->zone->task,
14299 forward_callback, forward,
14300 &forward->request);
14301 if (result == ISC_R_SUCCESS) {
14302 if (!ISC_LINK_LINKED(forward, link))
14303 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
14307 UNLOCK_ZONE(forward->zone);
14312 forward_callback(isc_task_t *task, isc_event_t *event) {
14313 const char me[] = "forward_callback";
14314 dns_requestevent_t *revent = (dns_requestevent_t *)event;
14315 dns_message_t *msg = NULL;
14316 char master[ISC_SOCKADDR_FORMATSIZE];
14317 isc_result_t result;
14318 dns_forward_t *forward;
14323 forward = revent->ev_arg;
14324 INSIST(DNS_FORWARD_VALID(forward));
14325 zone = forward->zone;
14326 INSIST(DNS_ZONE_VALID(zone));
14330 isc_sockaddr_format(&forward->addr, master, sizeof(master));
14332 if (revent->result != ISC_R_SUCCESS) {
14333 dns_zone_log(zone, ISC_LOG_INFO,
14334 "could not forward dynamic update to %s: %s",
14335 master, dns_result_totext(revent->result));
14339 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
14340 if (result != ISC_R_SUCCESS)
14343 result = dns_request_getresponse(revent->request, msg,
14344 DNS_MESSAGEPARSE_PRESERVEORDER |
14345 DNS_MESSAGEPARSE_CLONEBUFFER);
14346 if (result != ISC_R_SUCCESS)
14349 switch (msg->rcode) {
14351 * Pass these rcodes back to client.
14353 case dns_rcode_noerror:
14354 case dns_rcode_yxdomain:
14355 case dns_rcode_yxrrset:
14356 case dns_rcode_nxrrset:
14357 case dns_rcode_refused:
14358 case dns_rcode_nxdomain: {
14362 isc_buffer_init(&rb, rcode, sizeof(rcode));
14363 (void)dns_rcode_totext(msg->rcode, &rb);
14364 dns_zone_log(zone, ISC_LOG_INFO,
14365 "forwarded dynamic update: "
14366 "master %s returned: %.*s",
14367 master, (int)rb.used, rcode);
14371 /* These should not occur if the masters/zone are valid. */
14372 case dns_rcode_notzone:
14373 case dns_rcode_notauth: {
14377 isc_buffer_init(&rb, rcode, sizeof(rcode));
14378 (void)dns_rcode_totext(msg->rcode, &rb);
14379 dns_zone_log(zone, ISC_LOG_WARNING,
14380 "forwarding dynamic update: "
14381 "unexpected response: master %s returned: %.*s",
14382 master, (int)rb.used, rcode);
14386 /* Try another server for these rcodes. */
14387 case dns_rcode_formerr:
14388 case dns_rcode_servfail:
14389 case dns_rcode_notimp:
14390 case dns_rcode_badvers:
14395 /* call callback */
14396 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
14398 dns_request_destroy(&forward->request);
14399 forward_destroy(forward);
14400 isc_event_free(&event);
14405 dns_message_destroy(&msg);
14406 isc_event_free(&event);
14408 dns_request_destroy(&forward->request);
14409 result = sendtomaster(forward);
14410 if (result != ISC_R_SUCCESS) {
14411 /* call callback */
14412 dns_zone_log(zone, ISC_LOG_DEBUG(3),
14413 "exhausted dynamic update forwarder list");
14414 (forward->callback)(forward->callback_arg, result, NULL);
14415 forward_destroy(forward);
14420 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
14421 dns_updatecallback_t callback, void *callback_arg)
14423 dns_forward_t *forward;
14424 isc_result_t result;
14427 REQUIRE(DNS_ZONE_VALID(zone));
14428 REQUIRE(msg != NULL);
14429 REQUIRE(callback != NULL);
14431 forward = isc_mem_get(zone->mctx, sizeof(*forward));
14432 if (forward == NULL)
14433 return (ISC_R_NOMEMORY);
14435 forward->request = NULL;
14436 forward->zone = NULL;
14437 forward->msgbuf = NULL;
14438 forward->which = 0;
14440 forward->callback = callback;
14441 forward->callback_arg = callback_arg;
14442 ISC_LINK_INIT(forward, link);
14443 forward->magic = FORWARD_MAGIC;
14445 mr = dns_message_getrawmessage(msg);
14447 result = ISC_R_UNEXPECTEDEND;
14451 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
14452 if (result != ISC_R_SUCCESS)
14454 result = isc_buffer_copyregion(forward->msgbuf, mr);
14455 if (result != ISC_R_SUCCESS)
14458 isc_mem_attach(zone->mctx, &forward->mctx);
14459 dns_zone_iattach(zone, &forward->zone);
14460 result = sendtomaster(forward);
14463 if (result != ISC_R_SUCCESS) {
14464 forward_destroy(forward);
14470 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
14471 REQUIRE(DNS_ZONE_VALID(zone));
14472 REQUIRE(next != NULL && *next == NULL);
14474 *next = ISC_LIST_NEXT(zone, link);
14476 return (ISC_R_NOMORE);
14478 return (ISC_R_SUCCESS);
14482 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
14483 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14484 REQUIRE(first != NULL && *first == NULL);
14486 *first = ISC_LIST_HEAD(zmgr->zones);
14487 if (*first == NULL)
14488 return (ISC_R_NOMORE);
14490 return (ISC_R_SUCCESS);
14498 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
14499 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
14500 dns_zonemgr_t **zmgrp)
14502 dns_zonemgr_t *zmgr;
14503 isc_result_t result;
14504 isc_interval_t interval;
14506 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
14508 return (ISC_R_NOMEMORY);
14511 isc_mem_attach(mctx, &zmgr->mctx);
14512 zmgr->taskmgr = taskmgr;
14513 zmgr->timermgr = timermgr;
14514 zmgr->socketmgr = socketmgr;
14515 zmgr->zonetasks = NULL;
14516 zmgr->loadtasks = NULL;
14517 zmgr->mctxpool = NULL;
14519 zmgr->notifyrl = NULL;
14520 zmgr->refreshrl = NULL;
14521 ISC_LIST_INIT(zmgr->zones);
14522 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
14523 ISC_LIST_INIT(zmgr->xfrin_in_progress);
14524 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
14525 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
14526 if (result != ISC_R_SUCCESS)
14529 zmgr->transfersin = 10;
14530 zmgr->transfersperns = 2;
14532 /* Unreachable lock. */
14533 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
14534 if (result != ISC_R_SUCCESS)
14537 /* Create a single task for queueing of SOA queries. */
14538 result = isc_task_create(taskmgr, 1, &zmgr->task);
14539 if (result != ISC_R_SUCCESS)
14542 isc_task_setname(zmgr->task, "zmgr", zmgr);
14543 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14545 if (result != ISC_R_SUCCESS)
14548 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14550 if (result != ISC_R_SUCCESS)
14551 goto free_notifyrl;
14553 /* default to 20 refresh queries / notifies per second. */
14554 isc_interval_set(&interval, 0, 1000000000/2);
14555 result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
14556 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14557 isc_ratelimiter_setpertic(zmgr->notifyrl, 10);
14559 result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
14560 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14561 isc_ratelimiter_setpertic(zmgr->refreshrl, 10);
14564 zmgr->ioactive = 0;
14565 ISC_LIST_INIT(zmgr->high);
14566 ISC_LIST_INIT(zmgr->low);
14568 result = isc_mutex_init(&zmgr->iolock);
14569 if (result != ISC_R_SUCCESS)
14570 goto free_refreshrl;
14572 zmgr->magic = ZONEMGR_MAGIC;
14575 return (ISC_R_SUCCESS);
14579 DESTROYLOCK(&zmgr->iolock);
14582 isc_ratelimiter_detach(&zmgr->refreshrl);
14584 isc_ratelimiter_detach(&zmgr->notifyrl);
14586 isc_task_detach(&zmgr->task);
14588 isc_rwlock_destroy(&zmgr->urlock);
14590 isc_rwlock_destroy(&zmgr->rwlock);
14592 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
14593 isc_mem_detach(&mctx);
14598 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
14599 isc_result_t result;
14600 isc_mem_t *mctx = NULL;
14601 dns_zone_t *zone = NULL;
14604 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14605 REQUIRE(zonep != NULL && *zonep == NULL);
14607 if (zmgr->mctxpool == NULL)
14608 return (ISC_R_FAILURE);
14610 item = isc_pool_get(zmgr->mctxpool);
14612 return (ISC_R_FAILURE);
14614 isc_mem_attach((isc_mem_t *) item, &mctx);
14615 result = dns_zone_create(&zone, mctx);
14616 isc_mem_detach(&mctx);
14618 if (result == ISC_R_SUCCESS)
14625 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14626 isc_result_t result;
14628 REQUIRE(DNS_ZONE_VALID(zone));
14629 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14631 if (zmgr->zonetasks == NULL)
14632 return (ISC_R_FAILURE);
14634 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14636 REQUIRE(zone->task == NULL);
14637 REQUIRE(zone->timer == NULL);
14638 REQUIRE(zone->zmgr == NULL);
14640 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
14641 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
14644 * Set the task name. The tag will arbitrarily point to one
14645 * of the zones sharing the task (in practice, the one
14646 * to be managed last).
14648 isc_task_setname(zone->task, "zone", zone);
14649 isc_task_setname(zone->loadtask, "loadzone", zone);
14651 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
14653 zone->task, zone_timer, zone,
14656 if (result != ISC_R_SUCCESS)
14657 goto cleanup_tasks;
14660 * The timer "holds" a iref.
14663 INSIST(zone->irefs != 0);
14665 ISC_LIST_APPEND(zmgr->zones, zone, link);
14672 isc_task_detach(&zone->loadtask);
14673 isc_task_detach(&zone->task);
14677 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14682 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14683 isc_boolean_t free_now = ISC_FALSE;
14685 REQUIRE(DNS_ZONE_VALID(zone));
14686 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14687 REQUIRE(zone->zmgr == zmgr);
14689 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14692 ISC_LIST_UNLINK(zmgr->zones, zone, link);
14695 if (zmgr->refs == 0)
14696 free_now = ISC_TRUE;
14699 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14702 zonemgr_free(zmgr);
14703 ENSURE(zone->zmgr == NULL);
14707 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
14708 REQUIRE(DNS_ZONEMGR_VALID(source));
14709 REQUIRE(target != NULL && *target == NULL);
14711 RWLOCK(&source->rwlock, isc_rwlocktype_write);
14712 REQUIRE(source->refs > 0);
14714 INSIST(source->refs > 0);
14715 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
14720 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
14721 dns_zonemgr_t *zmgr;
14722 isc_boolean_t free_now = ISC_FALSE;
14724 REQUIRE(zmgrp != NULL);
14726 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14728 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14730 if (zmgr->refs == 0)
14731 free_now = ISC_TRUE;
14732 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14735 zonemgr_free(zmgr);
14740 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
14743 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14745 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
14746 for (p = ISC_LIST_HEAD(zmgr->zones);
14748 p = ISC_LIST_NEXT(p, link))
14750 dns_zone_maintenance(p);
14752 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
14755 * Recent configuration changes may have increased the
14756 * amount of available transfers quota. Make sure any
14757 * transfers currently blocked on quota get started if
14760 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14761 zmgr_resume_xfrs(zmgr, ISC_TRUE);
14762 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14763 return (ISC_R_SUCCESS);
14767 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
14769 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14771 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14772 zmgr_resume_xfrs(zmgr, ISC_TRUE);
14773 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14777 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
14780 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14782 isc_ratelimiter_shutdown(zmgr->notifyrl);
14783 isc_ratelimiter_shutdown(zmgr->refreshrl);
14785 if (zmgr->task != NULL)
14786 isc_task_destroy(&zmgr->task);
14787 if (zmgr->zonetasks != NULL)
14788 isc_taskpool_destroy(&zmgr->zonetasks);
14789 if (zmgr->loadtasks != NULL)
14790 isc_taskpool_destroy(&zmgr->loadtasks);
14791 if (zmgr->mctxpool != NULL)
14792 isc_pool_destroy(&zmgr->mctxpool);
14794 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
14795 for (zone = ISC_LIST_HEAD(zmgr->zones);
14797 zone = ISC_LIST_NEXT(zone, link))
14800 forward_cancel(zone);
14803 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
14806 static isc_result_t
14807 mctxinit(void **target, void *arg) {
14808 isc_result_t result;
14809 isc_mem_t *mctx = NULL;
14813 REQUIRE(target != NULL && *target == NULL);
14815 result = isc_mem_create(0, 0, &mctx);
14816 if (result != ISC_R_SUCCESS)
14818 isc_mem_setname(mctx, "zonemgr-pool", NULL);
14821 return (ISC_R_SUCCESS);
14825 mctxfree(void **target) {
14826 isc_mem_t *mctx = *(isc_mem_t **) target;
14827 isc_mem_detach(&mctx);
14831 #define ZONES_PER_TASK 100
14832 #define ZONES_PER_MCTX 1000
14835 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
14836 isc_result_t result;
14837 int ntasks = num_zones / ZONES_PER_TASK;
14838 int nmctx = num_zones / ZONES_PER_MCTX;
14839 isc_taskpool_t *pool = NULL;
14840 isc_pool_t *mctxpool = NULL;
14842 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14845 * For anything fewer than 1000 zones we use 10 tasks in
14846 * the task pools. More than that, and we'll scale at one
14847 * task per 100 zones. Similarly, for anything smaller than
14848 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
14855 /* Create or resize the zone task pools. */
14856 if (zmgr->zonetasks == NULL)
14857 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
14860 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
14862 if (result == ISC_R_SUCCESS)
14863 zmgr->zonetasks = pool;
14866 if (zmgr->loadtasks == NULL)
14867 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
14870 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
14872 if (result == ISC_R_SUCCESS)
14873 zmgr->loadtasks = pool;
14877 * We always set all tasks in the zone-load task pool to
14878 * privileged. This prevents other tasks in the system from
14879 * running while the server task manager is in privileged
14882 * NOTE: If we start using task privileges for any other
14883 * part of the system than zone tasks, then this will need to be
14884 * revisted. In that case we'd want to turn on privileges for
14885 * zone tasks only when we were loading, and turn them off the
14886 * rest of the time. For now, however, it's okay to just
14887 * set it and forget it.
14889 isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE);
14892 /* Create or resize the zone memory context pool. */
14893 if (zmgr->mctxpool == NULL)
14894 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
14895 mctxinit, NULL, &mctxpool);
14897 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
14899 if (result == ISC_R_SUCCESS)
14900 zmgr->mctxpool = mctxpool;
14906 zonemgr_free(dns_zonemgr_t *zmgr) {
14909 INSIST(zmgr->refs == 0);
14910 INSIST(ISC_LIST_EMPTY(zmgr->zones));
14914 DESTROYLOCK(&zmgr->iolock);
14915 isc_ratelimiter_detach(&zmgr->notifyrl);
14916 isc_ratelimiter_detach(&zmgr->refreshrl);
14918 isc_rwlock_destroy(&zmgr->urlock);
14919 isc_rwlock_destroy(&zmgr->rwlock);
14921 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
14922 isc_mem_detach(&mctx);
14926 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
14927 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14929 zmgr->transfersin = value;
14933 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
14934 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14936 return (zmgr->transfersin);
14940 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
14941 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14943 zmgr->transfersperns = value;
14947 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
14948 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14950 return (zmgr->transfersperns);
14954 * Try to start a new incoming zone transfer to fill a quota
14955 * slot that was just vacated.
14958 * The zone manager is locked by the caller.
14961 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
14965 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
14969 isc_result_t result;
14970 next = ISC_LIST_NEXT(zone, statelink);
14971 result = zmgr_start_xfrin_ifquota(zmgr, zone);
14972 if (result == ISC_R_SUCCESS) {
14976 * We successfully filled the slot. We're done.
14979 } else if (result == ISC_R_QUOTA) {
14981 * Not enough quota. This is probably the per-server
14982 * quota, because we usually get called when a unit of
14983 * global quota has just been freed. Try the next
14984 * zone, it may succeed if it uses another master.
14988 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14989 "starting zone transfer: %s",
14990 isc_result_totext(result));
14997 * Try to start an incoming zone transfer for 'zone', quota permitting.
15000 * The zone manager is locked by the caller.
15003 * ISC_R_SUCCESS There was enough quota and we attempted to
15004 * start a transfer. zone_xfrdone() has been or will
15006 * ISC_R_QUOTA Not enough quota.
15009 static isc_result_t
15010 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15011 dns_peer_t *peer = NULL;
15012 isc_netaddr_t masterip;
15013 isc_uint32_t nxfrsin, nxfrsperns;
15015 isc_uint32_t maxtransfersin, maxtransfersperns;
15019 * If we are exiting just pretend we got quota so the zone will
15020 * be cleaned up in the zone's task context.
15023 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
15029 * Find any configured information about the server we'd
15030 * like to transfer this zone from.
15032 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
15033 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
15037 * Determine the total maximum number of simultaneous
15038 * transfers allowed, and the maximum for this specific
15041 maxtransfersin = zmgr->transfersin;
15042 maxtransfersperns = zmgr->transfersperns;
15044 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
15047 * Count the total number of transfers that are in progress,
15048 * and the number of transfers in progress from this master.
15049 * We linearly scan a list of all transfers; if this turns
15050 * out to be too slow, we could hash on the master address.
15052 nxfrsin = nxfrsperns = 0;
15053 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15055 x = ISC_LIST_NEXT(x, statelink))
15060 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
15064 if (isc_netaddr_equal(&xip, &masterip))
15068 /* Enforce quota. */
15069 if (nxfrsin >= maxtransfersin)
15070 return (ISC_R_QUOTA);
15072 if (nxfrsperns >= maxtransfersperns)
15073 return (ISC_R_QUOTA);
15077 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
15078 * list and send it an event to let it start the actual transfer in the
15079 * context of its own task.
15081 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
15082 got_transfer_quota, zone, sizeof(isc_event_t));
15084 return (ISC_R_NOMEMORY);
15087 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
15088 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
15089 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
15090 zone->statelist = &zmgr->xfrin_in_progress;
15091 isc_task_send(zone->task, &e);
15092 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
15095 return (ISC_R_SUCCESS);
15099 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
15101 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15102 REQUIRE(iolimit > 0);
15104 zmgr->iolimit = iolimit;
15108 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
15110 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15112 return (zmgr->iolimit);
15116 * Get permission to request a file handle from the OS.
15117 * An event will be sent to action when one is available.
15118 * There are two queues available (high and low), the high
15119 * queue will be serviced before the low one.
15121 * zonemgr_putio() must be called after the event is delivered to
15125 static isc_result_t
15126 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
15127 isc_task_t *task, isc_taskaction_t action, void *arg,
15131 isc_boolean_t queue;
15133 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15134 REQUIRE(iop != NULL && *iop == NULL);
15136 io = isc_mem_get(zmgr->mctx, sizeof(*io));
15138 return (ISC_R_NOMEMORY);
15140 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
15141 action, arg, sizeof(*io->event));
15142 if (io->event == NULL) {
15143 isc_mem_put(zmgr->mctx, io, sizeof(*io));
15144 return (ISC_R_NOMEMORY);
15150 isc_task_attach(task, &io->task);
15151 ISC_LINK_INIT(io, link);
15152 io->magic = IO_MAGIC;
15154 LOCK(&zmgr->iolock);
15156 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
15159 ISC_LIST_APPEND(zmgr->high, io, link);
15161 ISC_LIST_APPEND(zmgr->low, io, link);
15163 UNLOCK(&zmgr->iolock);
15167 isc_task_send(io->task, &io->event);
15168 return (ISC_R_SUCCESS);
15172 zonemgr_putio(dns_io_t **iop) {
15175 dns_zonemgr_t *zmgr;
15177 REQUIRE(iop != NULL);
15179 REQUIRE(DNS_IO_VALID(io));
15183 INSIST(!ISC_LINK_LINKED(io, link));
15184 INSIST(io->event == NULL);
15187 isc_task_detach(&io->task);
15189 isc_mem_put(zmgr->mctx, io, sizeof(*io));
15191 LOCK(&zmgr->iolock);
15192 INSIST(zmgr->ioactive > 0);
15194 next = HEAD(zmgr->high);
15196 next = HEAD(zmgr->low);
15197 if (next != NULL) {
15199 ISC_LIST_UNLINK(zmgr->high, next, link);
15201 ISC_LIST_UNLINK(zmgr->low, next, link);
15202 INSIST(next->event != NULL);
15204 UNLOCK(&zmgr->iolock);
15206 isc_task_send(next->task, &next->event);
15210 zonemgr_cancelio(dns_io_t *io) {
15211 isc_boolean_t send_event = ISC_FALSE;
15213 REQUIRE(DNS_IO_VALID(io));
15216 * If we are queued to be run then dequeue.
15218 LOCK(&io->zmgr->iolock);
15219 if (ISC_LINK_LINKED(io, link)) {
15221 ISC_LIST_UNLINK(io->zmgr->high, io, link);
15223 ISC_LIST_UNLINK(io->zmgr->low, io, link);
15225 send_event = ISC_TRUE;
15226 INSIST(io->event != NULL);
15228 UNLOCK(&io->zmgr->iolock);
15230 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
15231 isc_task_send(io->task, &io->event);
15236 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
15239 isc_result_t result;
15241 buflen = strlen(path) + strlen(templat) + 2;
15243 buf = isc_mem_get(zone->mctx, buflen);
15247 result = isc_file_template(path, templat, buf, buflen);
15248 if (result != ISC_R_SUCCESS)
15251 result = isc_file_renameunique(path, buf);
15252 if (result != ISC_R_SUCCESS)
15255 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
15256 "renaming file to '%s' for failure analysis and "
15257 "retransferring.", path, buf);
15260 isc_mem_put(zone->mctx, buf, buflen);
15264 /* Hook for ondestroy notification from a database. */
15267 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
15268 dns_db_t *db = event->sender;
15271 isc_event_free(&event);
15273 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15274 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
15275 "database (%p) destroyed", (void*) db);
15280 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
15281 isc_interval_t interval;
15282 isc_uint32_t s, ns;
15283 isc_uint32_t pertic;
15284 isc_result_t result;
15286 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15295 } else if (value <= 10) {
15297 ns = 1000000000 / value;
15301 ns = (1000000000 / value) * 10;
15305 isc_interval_set(&interval, s, ns);
15307 result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
15308 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15309 isc_ratelimiter_setpertic(zmgr->notifyrl, pertic);
15311 result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
15312 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15313 isc_ratelimiter_setpertic(zmgr->refreshrl, pertic);
15315 zmgr->serialqueryrate = value;
15319 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
15320 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15322 return (zmgr->serialqueryrate);
15326 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15327 isc_sockaddr_t *local, isc_time_t *now)
15330 isc_rwlocktype_t locktype;
15331 isc_result_t result;
15332 isc_uint32_t seconds = isc_time_seconds(now);
15333 isc_uint32_t count = 0;
15335 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15337 locktype = isc_rwlocktype_read;
15338 RWLOCK(&zmgr->urlock, locktype);
15339 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15340 if (zmgr->unreachable[i].expire >= seconds &&
15341 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15342 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
15343 result = isc_rwlock_tryupgrade(&zmgr->urlock);
15344 if (result == ISC_R_SUCCESS) {
15345 locktype = isc_rwlocktype_write;
15346 zmgr->unreachable[i].last = seconds;
15347 count = zmgr->unreachable[i].count;
15352 RWUNLOCK(&zmgr->urlock, locktype);
15353 return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U));
15357 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15358 isc_sockaddr_t *local)
15361 isc_rwlocktype_t locktype;
15362 isc_result_t result;
15364 char master[ISC_SOCKADDR_FORMATSIZE];
15365 char source[ISC_SOCKADDR_FORMATSIZE];
15367 isc_sockaddr_format(remote, master, sizeof(master));
15368 isc_sockaddr_format(local, source, sizeof(source));
15370 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15372 locktype = isc_rwlocktype_read;
15373 RWLOCK(&zmgr->urlock, locktype);
15374 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15375 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15376 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
15377 if (zmgr->unreachable[i].expire == 0)
15379 result = isc_rwlock_tryupgrade(&zmgr->urlock);
15380 if (result == ISC_R_SUCCESS) {
15381 locktype = isc_rwlocktype_write;
15382 zmgr->unreachable[i].expire = 0;
15383 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15384 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
15385 "master %s (source %s) deleted "
15386 "from unreachable cache",
15392 RWUNLOCK(&zmgr->urlock, locktype);
15396 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15397 isc_sockaddr_t *local, isc_time_t *now)
15399 isc_uint32_t seconds = isc_time_seconds(now);
15400 isc_uint32_t last = seconds;
15401 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
15403 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15405 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
15406 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15407 /* Existing entry? */
15408 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15409 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
15412 if (zmgr->unreachable[i].expire < seconds)
15414 /* Least recently used slot? */
15415 if (zmgr->unreachable[i].last < last) {
15416 last = zmgr->unreachable[i].last;
15420 if (i < UNREACH_CHACHE_SIZE) {
15422 * Found a existing entry. Update the expire timer and
15423 * last usage timestamps.
15425 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
15426 zmgr->unreachable[i].last = seconds;
15427 if (zmgr->unreachable[i].expire < seconds)
15428 zmgr->unreachable[i].count = 1;
15430 zmgr->unreachable[i].count++;
15431 } else if (slot != UNREACH_CHACHE_SIZE) {
15433 * Found a empty slot. Add a new entry to the cache.
15435 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
15436 zmgr->unreachable[slot].last = seconds;
15437 zmgr->unreachable[slot].remote = *remote;
15438 zmgr->unreachable[slot].local = *local;
15439 zmgr->unreachable[slot].count = 1;
15442 * Replace the least recently used entry in the cache.
15444 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
15445 zmgr->unreachable[oldest].last = seconds;
15446 zmgr->unreachable[oldest].remote = *remote;
15447 zmgr->unreachable[oldest].local = *local;
15448 zmgr->unreachable[oldest].count = 1;
15450 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
15454 dns_zone_forcereload(dns_zone_t *zone) {
15455 REQUIRE(DNS_ZONE_VALID(zone));
15457 if (zone->type == dns_zone_master ||
15458 (zone->type == dns_zone_redirect && zone->masters == NULL))
15462 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
15464 dns_zone_refresh(zone);
15468 dns_zone_isforced(dns_zone_t *zone) {
15469 REQUIRE(DNS_ZONE_VALID(zone));
15471 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
15475 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
15477 * This function is obsoleted.
15481 return (ISC_R_NOTIMPLEMENTED);
15485 dns_zone_getstatscounters(dns_zone_t *zone) {
15487 * This function is obsoleted.
15494 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
15495 REQUIRE(DNS_ZONE_VALID(zone));
15496 REQUIRE(zone->stats == NULL);
15499 zone->stats = NULL;
15500 isc_stats_attach(stats, &zone->stats);
15505 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
15507 REQUIRE(DNS_ZONE_VALID(zone));
15510 if (zone->requeststats_on && stats == NULL)
15511 zone->requeststats_on = ISC_FALSE;
15512 else if (!zone->requeststats_on && stats != NULL) {
15513 if (zone->requeststats == NULL) {
15514 isc_stats_attach(stats, &zone->requeststats);
15515 zone->requeststats_on = ISC_TRUE;
15523 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
15525 REQUIRE(DNS_ZONE_VALID(zone));
15528 if (zone->requeststats_on && stats != NULL) {
15529 if (zone->rcvquerystats == NULL) {
15530 dns_stats_attach(stats, &zone->rcvquerystats);
15531 zone->requeststats_on = ISC_TRUE;
15539 dns_zone_getrequeststats(dns_zone_t *zone) {
15541 * We don't lock zone for efficiency reason. This is not catastrophic
15542 * because requeststats must always be valid when requeststats_on is
15544 * Some counters may be incremented while requeststats_on is becoming
15545 * false, or some cannot be incremented just after the statistics are
15546 * installed, but it shouldn't matter much in practice.
15548 if (zone->requeststats_on)
15549 return (zone->requeststats);
15556 * Return the received query stats bucket
15557 * see note from dns_zone_getrequeststats()
15560 dns_zone_getrcvquerystats(dns_zone_t *zone) {
15561 if (zone->requeststats_on)
15562 return (zone->rcvquerystats);
15569 dns_zone_dialup(dns_zone_t *zone) {
15571 REQUIRE(DNS_ZONE_VALID(zone));
15573 zone_debuglog(zone, "dns_zone_dialup", 3,
15574 "notify = %d, refresh = %d",
15575 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
15576 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
15578 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
15579 dns_zone_notify(zone);
15580 if (zone->type != dns_zone_master && zone->masters != NULL &&
15581 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
15582 dns_zone_refresh(zone);
15586 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
15587 REQUIRE(DNS_ZONE_VALID(zone));
15590 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
15591 DNS_ZONEFLG_DIALREFRESH |
15592 DNS_ZONEFLG_NOREFRESH);
15594 case dns_dialuptype_no:
15596 case dns_dialuptype_yes:
15597 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
15598 DNS_ZONEFLG_DIALREFRESH |
15599 DNS_ZONEFLG_NOREFRESH));
15601 case dns_dialuptype_notify:
15602 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
15604 case dns_dialuptype_notifypassive:
15605 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
15606 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15608 case dns_dialuptype_refresh:
15609 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
15610 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15612 case dns_dialuptype_passive:
15613 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15622 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
15623 isc_result_t result = ISC_R_SUCCESS;
15625 REQUIRE(DNS_ZONE_VALID(zone));
15628 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
15635 dns_zone_getkeydirectory(dns_zone_t *zone) {
15636 REQUIRE(DNS_ZONE_VALID(zone));
15638 return (zone->keydirectory);
15642 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
15644 unsigned int count = 0;
15646 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15648 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15650 case DNS_ZONESTATE_XFERRUNNING:
15651 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15653 zone = ISC_LIST_NEXT(zone, statelink))
15656 case DNS_ZONESTATE_XFERDEFERRED:
15657 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
15659 zone = ISC_LIST_NEXT(zone, statelink))
15662 case DNS_ZONESTATE_SOAQUERY:
15663 for (zone = ISC_LIST_HEAD(zmgr->zones);
15665 zone = ISC_LIST_NEXT(zone, link))
15666 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
15669 case DNS_ZONESTATE_ANY:
15670 for (zone = ISC_LIST_HEAD(zmgr->zones);
15672 zone = ISC_LIST_NEXT(zone, link)) {
15673 dns_view_t *view = zone->view;
15674 if (view != NULL && strcmp(view->name, "_bind") == 0)
15683 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15689 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
15690 isc_boolean_t ok = ISC_TRUE;
15691 isc_boolean_t fail = ISC_FALSE;
15692 char namebuf[DNS_NAME_FORMATSIZE];
15693 char namebuf2[DNS_NAME_FORMATSIZE];
15694 char typebuf[DNS_RDATATYPE_FORMATSIZE];
15695 int level = ISC_LOG_WARNING;
15698 REQUIRE(DNS_ZONE_VALID(zone));
15700 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
15701 return (ISC_R_SUCCESS);
15703 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
15704 level = ISC_LOG_ERROR;
15708 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
15710 dns_name_format(name, namebuf, sizeof(namebuf));
15711 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
15712 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
15713 dns_result_totext(DNS_R_BADOWNERNAME));
15715 return (DNS_R_BADOWNERNAME);
15718 dns_name_init(&bad, NULL);
15719 ok = dns_rdata_checknames(rdata, name, &bad);
15721 dns_name_format(name, namebuf, sizeof(namebuf));
15722 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
15723 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
15724 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
15725 namebuf2, dns_result_totext(DNS_R_BADNAME));
15727 return (DNS_R_BADNAME);
15730 return (ISC_R_SUCCESS);
15734 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
15735 REQUIRE(DNS_ZONE_VALID(zone));
15736 zone->checkmx = checkmx;
15740 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
15741 REQUIRE(DNS_ZONE_VALID(zone));
15742 zone->checksrv = checksrv;
15746 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
15747 REQUIRE(DNS_ZONE_VALID(zone));
15748 zone->checkns = checkns;
15752 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
15753 REQUIRE(DNS_ZONE_VALID(zone));
15756 zone->isself = isself;
15757 zone->isselfarg = arg;
15762 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
15763 REQUIRE(DNS_ZONE_VALID(zone));
15766 zone->notifydelay = delay;
15771 dns_zone_getnotifydelay(dns_zone_t *zone) {
15772 REQUIRE(DNS_ZONE_VALID(zone));
15774 return (zone->notifydelay);
15778 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
15779 isc_uint16_t keyid, isc_boolean_t delete)
15781 isc_result_t result;
15782 REQUIRE(DNS_ZONE_VALID(zone));
15784 dns_zone_log(zone, ISC_LOG_NOTICE,
15785 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
15788 result = zone_signwithkey(zone, algorithm, keyid, delete);
15794 static const char *hex = "0123456789ABCDEF";
15797 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
15798 isc_result_t result;
15799 char salt[255*2+1];
15802 REQUIRE(DNS_ZONE_VALID(zone));
15804 if (nsec3param->salt_length != 0) {
15805 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
15806 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
15807 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
15808 salt[j++] = hex[nsec3param->salt[i] & 0xf];
15813 dns_zone_log(zone, ISC_LOG_NOTICE,
15814 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
15815 nsec3param->hash, nsec3param->iterations,
15818 result = zone_addnsec3chain(zone, nsec3param);
15825 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
15826 REQUIRE(DNS_ZONE_VALID(zone));
15830 zone->nodes = nodes;
15834 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
15835 REQUIRE(DNS_ZONE_VALID(zone));
15838 * We treat signatures as a signed value so explicitly
15839 * limit its range here.
15841 if (signatures > ISC_INT32_MAX)
15842 signatures = ISC_INT32_MAX;
15843 else if (signatures == 0)
15845 zone->signatures = signatures;
15849 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
15850 REQUIRE(DNS_ZONE_VALID(zone));
15851 zone->privatetype = type;
15855 dns_zone_getprivatetype(dns_zone_t *zone) {
15856 REQUIRE(DNS_ZONE_VALID(zone));
15857 return (zone->privatetype);
15860 static isc_result_t
15861 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
15862 isc_boolean_t delete)
15864 dns_signing_t *signing;
15865 dns_signing_t *current;
15866 isc_result_t result = ISC_R_SUCCESS;
15868 dns_db_t *db = NULL;
15870 signing = isc_mem_get(zone->mctx, sizeof *signing);
15871 if (signing == NULL)
15872 return (ISC_R_NOMEMORY);
15874 signing->magic = 0;
15875 signing->db = NULL;
15876 signing->dbiterator = NULL;
15877 signing->algorithm = algorithm;
15878 signing->keyid = keyid;
15879 signing->delete = delete;
15880 signing->done = ISC_FALSE;
15884 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
15885 if (zone->db != NULL)
15886 dns_db_attach(zone->db, &db);
15887 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15890 result = ISC_R_NOTFOUND;
15894 dns_db_attach(db, &signing->db);
15896 for (current = ISC_LIST_HEAD(zone->signing);
15898 current = ISC_LIST_NEXT(current, link)) {
15899 if (current->db == signing->db &&
15900 current->algorithm == signing->algorithm &&
15901 current->keyid == signing->keyid) {
15902 if (current->delete != signing->delete)
15903 current->done = ISC_TRUE;
15909 result = dns_db_createiterator(signing->db, 0,
15910 &signing->dbiterator);
15912 if (result == ISC_R_SUCCESS)
15913 result = dns_dbiterator_first(signing->dbiterator);
15914 if (result == ISC_R_SUCCESS) {
15915 dns_dbiterator_pause(signing->dbiterator);
15916 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
15918 if (isc_time_isepoch(&zone->signingtime)) {
15919 zone->signingtime = now;
15920 if (zone->task != NULL)
15921 zone_settimer(zone, &now);
15926 if (signing != NULL) {
15927 if (signing->db != NULL)
15928 dns_db_detach(&signing->db);
15929 if (signing->dbiterator != NULL)
15930 dns_dbiterator_destroy(&signing->dbiterator);
15931 isc_mem_put(zone->mctx, signing, sizeof *signing);
15934 dns_db_detach(&db);
15939 logmsg(const char *format, ...) {
15941 va_start(args, format);
15942 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
15943 ISC_LOG_DEBUG(1), format, args);
15948 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
15949 dns_dnsseckey_t *key;
15950 while (!ISC_LIST_EMPTY(*list)) {
15951 key = ISC_LIST_HEAD(*list);
15952 ISC_LIST_UNLINK(*list, key, link);
15953 dns_dnsseckey_destroy(mctx, &key);
15957 /* Called once; *timep should be set to the current time. */
15958 static isc_result_t
15959 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
15960 isc_result_t result;
15961 isc_stdtime_t now, then = 0, event;
15966 for (i = 0; i <= DST_MAX_TIMES; i++) {
15967 result = dst_key_gettime(key, i, &event);
15968 if (result == ISC_R_SUCCESS && event > now &&
15969 (then == 0 || event < then))
15975 return (ISC_R_SUCCESS);
15978 return (ISC_R_NOTFOUND);
15981 static isc_result_t
15982 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
15983 const dns_rdata_t *rdata, isc_boolean_t *flag)
15985 dns_rdataset_t rdataset;
15986 dns_dbnode_t *node = NULL;
15987 isc_result_t result;
15989 dns_rdataset_init(&rdataset);
15990 if (rdata->type == dns_rdatatype_nsec3)
15991 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
15993 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
15994 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
15995 (isc_stdtime_t) 0, &rdataset, NULL);
15996 if (result == ISC_R_NOTFOUND) {
15998 result = ISC_R_SUCCESS;
16002 for (result = dns_rdataset_first(&rdataset);
16003 result == ISC_R_SUCCESS;
16004 result = dns_rdataset_next(&rdataset)) {
16005 dns_rdata_t myrdata = DNS_RDATA_INIT;
16006 dns_rdataset_current(&rdataset, &myrdata);
16007 if (!dns_rdata_compare(&myrdata, rdata))
16010 dns_rdataset_disassociate(&rdataset);
16011 if (result == ISC_R_SUCCESS) {
16013 } else if (result == ISC_R_NOMORE) {
16015 result = ISC_R_SUCCESS;
16020 dns_db_detachnode(db, &node);
16025 * Add records to signal the state of signing or of key removal.
16027 static isc_result_t
16028 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
16029 dns_dbversion_t *ver, dns_diff_t *diff,
16030 isc_boolean_t sign_all)
16032 dns_difftuple_t *tuple, *newtuple = NULL;
16033 dns_rdata_dnskey_t dnskey;
16034 dns_rdata_t rdata = DNS_RDATA_INIT;
16035 isc_boolean_t flag;
16037 isc_result_t result = ISC_R_SUCCESS;
16038 isc_uint16_t keyid;
16039 unsigned char buf[5];
16040 dns_name_t *name = dns_db_origin(db);
16042 for (tuple = ISC_LIST_HEAD(diff->tuples);
16044 tuple = ISC_LIST_NEXT(tuple, link)) {
16045 if (tuple->rdata.type != dns_rdatatype_dnskey)
16048 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
16049 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16050 if ((dnskey.flags &
16051 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
16052 != DNS_KEYOWNER_ZONE)
16055 dns_rdata_toregion(&tuple->rdata, &r);
16057 keyid = dst_region_computeid(&r, dnskey.algorithm);
16059 buf[0] = dnskey.algorithm;
16060 buf[1] = (keyid & 0xff00) >> 8;
16061 buf[2] = (keyid & 0xff);
16062 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
16065 rdata.length = sizeof(buf);
16066 rdata.type = privatetype;
16067 rdata.rdclass = tuple->rdata.rdclass;
16069 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
16070 CHECK(rr_exists(db, ver, name, &rdata, &flag));
16073 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
16074 name, 0, &rdata, &newtuple));
16075 CHECK(do_one_tuple(&newtuple, db, ver, diff));
16076 INSIST(newtuple == NULL);
16080 * Remove any record which says this operation has already
16084 CHECK(rr_exists(db, ver, name, &rdata, &flag));
16086 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
16087 name, 0, &rdata, &newtuple));
16088 CHECK(do_one_tuple(&newtuple, db, ver, diff));
16089 INSIST(newtuple == NULL);
16096 static isc_result_t
16097 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16098 dns_diff_t *diff, zonediff_t *zonediff)
16100 isc_result_t result;
16101 isc_stdtime_t now, inception, soaexpire;
16102 isc_boolean_t check_ksk, keyset_kskonly;
16103 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
16104 unsigned int nkeys = 0, i;
16105 dns_difftuple_t *tuple;
16107 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
16108 zone_keys, &nkeys);
16109 if (result != ISC_R_SUCCESS) {
16110 dns_zone_log(zone, ISC_LOG_ERROR,
16111 "sign_apex:find_zone_keys -> %s",
16112 dns_result_totext(result));
16116 isc_stdtime_get(&now);
16117 inception = now - 3600; /* Allow for clock skew. */
16118 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
16120 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
16121 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
16124 * See if update_sigs will update DNSKEY signature and if not
16125 * cause them to sign so that so that newly activated keys
16128 for (tuple = ISC_LIST_HEAD(diff->tuples);
16130 tuple = ISC_LIST_NEXT(tuple, link)) {
16131 if (tuple->rdata.type == dns_rdatatype_dnskey &&
16132 dns_name_equal(&tuple->name, &zone->origin))
16136 if (tuple == NULL) {
16137 result = del_sigs(zone, db, ver, &zone->origin,
16138 dns_rdatatype_dnskey, zonediff,
16139 zone_keys, nkeys, now, ISC_FALSE);
16140 if (result != ISC_R_SUCCESS) {
16141 dns_zone_log(zone, ISC_LOG_ERROR,
16142 "sign_apex:del_sigs -> %s",
16143 dns_result_totext(result));
16146 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
16147 zonediff->diff, zone_keys, nkeys, zone->mctx,
16148 inception, soaexpire, check_ksk,
16150 if (result != ISC_R_SUCCESS) {
16151 dns_zone_log(zone, ISC_LOG_ERROR,
16152 "sign_apex:add_sigs -> %s",
16153 dns_result_totext(result));
16158 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
16159 inception, soaexpire, now, check_ksk,
16160 keyset_kskonly, zonediff);
16162 if (result != ISC_R_SUCCESS) {
16163 dns_zone_log(zone, ISC_LOG_ERROR,
16164 "sign_apex:update_sigs -> %s",
16165 dns_result_totext(result));
16170 for (i = 0; i < nkeys; i++)
16171 dst_key_free(&zone_keys[i]);
16176 * Prevent the zone entering a inconsistent state where
16177 * NSEC only DNSKEYs are present with NSEC3 chains.
16178 * See update.c:check_dnssec()
16180 static isc_boolean_t
16181 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16184 isc_result_t result;
16185 dns_difftuple_t *tuple;
16186 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
16187 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
16189 /* Scan the tuples for an NSEC-only DNSKEY */
16190 for (tuple = ISC_LIST_HEAD(diff->tuples);
16192 tuple = ISC_LIST_NEXT(tuple, link)) {
16194 if (tuple->rdata.type != dns_rdatatype_dnskey ||
16195 tuple->op != DNS_DIFFOP_ADD)
16198 alg = tuple->rdata.data[3];
16199 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
16200 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
16201 nseconly = ISC_TRUE;
16206 /* Check existing DB for NSEC-only DNSKEY */
16208 result = dns_nsec_nseconly(db, ver, &nseconly);
16209 if (result == ISC_R_NOTFOUND)
16210 result = ISC_R_SUCCESS;
16214 /* Check existing DB for NSEC3 */
16216 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
16217 privatetype, &nsec3));
16219 /* Refuse to allow NSEC3 with NSEC-only keys */
16220 if (nseconly && nsec3) {
16221 dns_zone_log(zone, ISC_LOG_ERROR,
16222 "NSEC only DNSKEYs and NSEC3 chains not allowed");
16229 return (ISC_FALSE);
16232 static isc_result_t
16233 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16236 isc_result_t result;
16237 dns_dbnode_t *node = NULL;
16238 dns_rdataset_t rdataset;
16240 dns_rdataset_init(&rdataset);
16241 CHECK(dns_db_getoriginnode(db, &node));
16243 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
16244 dns_rdatatype_none, 0, &rdataset, NULL);
16245 if (dns_rdataset_isassociated(&rdataset))
16246 dns_rdataset_disassociate(&rdataset);
16247 if (result != ISC_R_NOTFOUND)
16250 result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff);
16254 dns_db_detachnode(db, &node);
16259 * Given an RRSIG rdataset and an algorithm, determine whether there
16260 * are any signatures using that algorithm.
16262 static isc_boolean_t
16263 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
16264 dns_rdata_t rdata = DNS_RDATA_INIT;
16265 dns_rdata_rrsig_t rrsig;
16266 isc_result_t result;
16268 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
16269 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
16270 return (ISC_FALSE);
16273 for (result = dns_rdataset_first(rdataset);
16274 result == ISC_R_SUCCESS;
16275 result = dns_rdataset_next(rdataset))
16277 dns_rdataset_current(rdataset, &rdata);
16278 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
16279 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16280 dns_rdata_reset(&rdata);
16281 if (rrsig.algorithm == alg)
16285 return (ISC_FALSE);
16288 static isc_result_t
16289 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16292 dns_name_t *origin;
16293 isc_boolean_t build_nsec3;
16294 isc_result_t result;
16296 origin = dns_db_origin(db);
16297 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
16300 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
16301 ISC_FALSE, zone->privatetype, diff));
16302 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
16309 zone_rekey(dns_zone_t *zone) {
16310 isc_result_t result;
16311 dns_db_t *db = NULL;
16312 dns_dbnode_t *node = NULL;
16313 dns_dbversion_t *ver = NULL;
16314 dns_rdataset_t soaset, soasigs, keyset, keysigs;
16315 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
16316 dns_dnsseckey_t *key;
16317 dns_diff_t diff, _sig_diff;
16318 zonediff_t zonediff;
16319 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
16320 isc_boolean_t newalg = ISC_FALSE;
16321 isc_boolean_t fullsign;
16322 dns_ttl_t ttl = 3600;
16326 isc_time_t timenow;
16327 isc_interval_t ival;
16330 REQUIRE(DNS_ZONE_VALID(zone));
16332 ISC_LIST_INIT(dnskeys);
16333 ISC_LIST_INIT(keys);
16334 ISC_LIST_INIT(rmkeys);
16335 dns_rdataset_init(&soaset);
16336 dns_rdataset_init(&soasigs);
16337 dns_rdataset_init(&keyset);
16338 dns_rdataset_init(&keysigs);
16339 dir = dns_zone_getkeydirectory(zone);
16341 dns_diff_init(mctx, &diff);
16342 dns_diff_init(mctx, &_sig_diff);
16343 zonediff_init(&zonediff, &_sig_diff);
16345 CHECK(dns_zone_getdb(zone, &db));
16346 CHECK(dns_db_newversion(db, &ver));
16347 CHECK(dns_db_getoriginnode(db, &node));
16349 TIME_NOW(&timenow);
16350 now = isc_time_seconds(&timenow);
16352 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
16354 /* Get the SOA record's TTL */
16355 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
16356 dns_rdatatype_none, 0, &soaset, &soasigs));
16358 dns_rdataset_disassociate(&soaset);
16360 /* Get the DNSKEY rdataset */
16361 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
16362 dns_rdatatype_none, 0, &keyset, &keysigs);
16363 if (result == ISC_R_SUCCESS) {
16365 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
16367 &keysigs, &soasigs,
16368 ISC_FALSE, ISC_FALSE,
16370 } else if (result != ISC_R_NOTFOUND)
16374 * True when called from "rndc sign". Indicates the zone should be
16375 * fully signed now.
16377 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
16379 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
16380 if (result == ISC_R_SUCCESS) {
16381 isc_boolean_t check_ksk;
16382 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
16384 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
16385 &zone->origin, ttl, &diff,
16386 ISC_TF(!check_ksk),
16389 /* Keys couldn't be updated for some reason;
16390 * try again later. */
16391 if (result != ISC_R_SUCCESS) {
16392 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
16393 "couldn't update zone keys: %s",
16394 isc_result_totext(result));
16399 * See if any pre-existing keys have newly become active;
16400 * also, see if any new key is for a new algorithm, as in that
16401 * event, we need to sign the zone fully. (If there's a new
16402 * key, but it's for an already-existing algorithm, then
16403 * the zone signing can be handled incrementally.)
16405 for (key = ISC_LIST_HEAD(dnskeys);
16407 key = ISC_LIST_NEXT(key, link)) {
16408 if (!key->first_sign)
16411 newactive = ISC_TRUE;
16413 if (!dns_rdataset_isassociated(&keysigs)) {
16418 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
16420 * This isn't a new algorithm; clear
16421 * first_sign so we won't sign the
16422 * whole zone with this key later
16424 key->first_sign = ISC_FALSE;
16431 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
16432 dnskey_sane(zone, db, ver, &diff)) {
16433 CHECK(dns_diff_apply(&diff, db, ver));
16434 CHECK(clean_nsec3param(zone, db, ver, &diff));
16435 CHECK(add_signing_records(db, zone->privatetype,
16437 ISC_TF(newalg || fullsign)));
16438 CHECK(update_soa_serial(db, ver, &diff, mctx,
16439 zone->updatemethod));
16440 CHECK(add_chains(zone, db, ver, &diff));
16441 CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
16442 CHECK(zone_journal(zone, zonediff.diff, NULL,
16448 dns_db_closeversion(db, &ver, ISC_TRUE);
16451 dns_difftuple_t *tuple;
16454 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
16456 zone_needdump(zone, DNS_DUMP_DELAY);
16458 zone_settimer(zone, &timenow);
16460 /* Remove any signatures from removed keys. */
16461 if (!ISC_LIST_EMPTY(rmkeys)) {
16462 for (key = ISC_LIST_HEAD(rmkeys);
16464 key = ISC_LIST_NEXT(key, link)) {
16465 result = zone_signwithkey(zone,
16466 dst_key_alg(key->key),
16467 dst_key_id(key->key),
16469 if (result != ISC_R_SUCCESS) {
16470 dns_zone_log(zone, ISC_LOG_ERROR,
16471 "zone_signwithkey failed: %s",
16472 dns_result_totext(result));
16479 * "rndc sign" was called, so we now sign the zone
16480 * with all active keys, whether they're new or not.
16482 for (key = ISC_LIST_HEAD(dnskeys);
16484 key = ISC_LIST_NEXT(key, link)) {
16485 if (!key->force_sign && !key->hint_sign)
16488 result = zone_signwithkey(zone,
16489 dst_key_alg(key->key),
16490 dst_key_id(key->key),
16492 if (result != ISC_R_SUCCESS) {
16493 dns_zone_log(zone, ISC_LOG_ERROR,
16494 "zone_signwithkey failed: %s",
16495 dns_result_totext(result));
16498 } else if (newalg) {
16500 * We haven't been told to sign fully, but a new
16501 * algorithm was added to the DNSKEY. We sign
16502 * the full zone, but only with newly active
16505 for (key = ISC_LIST_HEAD(dnskeys);
16507 key = ISC_LIST_NEXT(key, link)) {
16508 if (!key->first_sign)
16511 result = zone_signwithkey(zone,
16512 dst_key_alg(key->key),
16513 dst_key_id(key->key),
16515 if (result != ISC_R_SUCCESS) {
16516 dns_zone_log(zone, ISC_LOG_ERROR,
16517 "zone_signwithkey failed: %s",
16518 dns_result_totext(result));
16524 * Clear fullsign flag, if it was set, so we don't do
16525 * another full signing next time
16527 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
16530 * Cause the zone to add/delete NSEC3 chains for the
16531 * deferred NSEC3PARAM changes.
16533 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
16535 tuple = ISC_LIST_NEXT(tuple, link)) {
16536 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
16537 dns_rdata_t rdata = DNS_RDATA_INIT;
16538 dns_rdata_nsec3param_t nsec3param;
16540 if (tuple->rdata.type != zone->privatetype ||
16541 tuple->op != DNS_DIFFOP_ADD)
16544 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
16547 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
16548 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16549 if (nsec3param.flags == 0)
16552 result = zone_addnsec3chain(zone, &nsec3param);
16553 if (result != ISC_R_SUCCESS) {
16554 dns_zone_log(zone, ISC_LOG_ERROR,
16555 "zone_addnsec3chain failed: %s",
16556 dns_result_totext(result));
16561 * Activate any NSEC3 chain updates that may have
16562 * been scheduled before this rekey.
16564 if (fullsign || newalg)
16565 resume_addnsec3chain(zone);
16568 * Schedule the next resigning event
16570 set_resigntime(zone);
16574 isc_time_settoepoch(&zone->refreshkeytime);
16577 * If we're doing key maintenance, set the key refresh timer to
16578 * the next scheduled key event or to 'dnssec-loadkeys-interval'
16579 * seconds in the future, whichever is sooner.
16581 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
16582 isc_time_t timethen;
16583 isc_stdtime_t then;
16586 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
16588 zone->refreshkeytime = timethen;
16591 for (key = ISC_LIST_HEAD(dnskeys);
16593 key = ISC_LIST_NEXT(key, link)) {
16595 result = next_keyevent(key->key, &then);
16596 if (result != ISC_R_SUCCESS)
16599 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
16601 if (isc_time_compare(&timethen,
16602 &zone->refreshkeytime) < 0) {
16603 zone->refreshkeytime = timethen;
16608 zone_settimer(zone, &timenow);
16610 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
16611 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
16615 dns_diff_clear(&diff);
16616 dns_diff_clear(&_sig_diff);
16618 clear_keylist(&dnskeys, mctx);
16619 clear_keylist(&keys, mctx);
16620 clear_keylist(&rmkeys, mctx);
16623 dns_db_closeversion(db, &ver, ISC_FALSE);
16624 if (dns_rdataset_isassociated(&keyset))
16625 dns_rdataset_disassociate(&keyset);
16626 if (dns_rdataset_isassociated(&keysigs))
16627 dns_rdataset_disassociate(&keysigs);
16628 if (dns_rdataset_isassociated(&soasigs))
16629 dns_rdataset_disassociate(&soasigs);
16631 dns_db_detachnode(db, &node);
16633 dns_db_detach(&db);
16638 * Something went wrong; try again in ten minutes or
16639 * after a key refresh interval, whichever is shorter.
16641 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
16642 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
16647 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
16650 if (zone->type == dns_zone_master && zone->task != NULL) {
16654 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
16657 zone->refreshkeytime = now;
16658 zone_settimer(zone, &now);
16665 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
16666 unsigned int *errors)
16668 isc_result_t result;
16669 dns_dbnode_t *node = NULL;
16671 REQUIRE(DNS_ZONE_VALID(zone));
16672 REQUIRE(errors != NULL);
16674 result = dns_db_getoriginnode(db, &node);
16675 if (result != ISC_R_SUCCESS)
16677 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
16679 dns_db_detachnode(db, &node);
16684 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
16685 REQUIRE(DNS_ZONE_VALID(zone));
16687 zone->added = added;
16692 dns_zone_getadded(dns_zone_t *zone) {
16693 REQUIRE(DNS_ZONE_VALID(zone));
16694 return (zone->added);
16698 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
16700 isc_time_t loadtime;
16701 isc_result_t result;
16702 dns_zone_t *secure = NULL;
16704 TIME_NOW(&loadtime);
16707 * Lock hierarchy: zmgr, zone, raw.
16711 if (inline_secure(zone))
16712 LOCK_ZONE(zone->raw);
16713 else if (inline_raw(zone)) {
16714 secure = zone->secure;
16715 TRYLOCK_ZONE(result, secure);
16716 if (result != ISC_R_SUCCESS) {
16719 #if ISC_PLATFORM_USETHREADS
16720 isc_thread_yield();
16725 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
16726 if (inline_secure(zone))
16727 UNLOCK_ZONE(zone->raw);
16728 else if (secure != NULL)
16729 UNLOCK_ZONE(secure);
16735 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) {
16736 REQUIRE(DNS_ZONE_VALID(zone));
16738 return (ISC_R_RANGE);
16739 /* Maximum value: 24 hours (3600 minutes) */
16740 if (interval > (24 * 60))
16741 interval = (24 * 60);
16742 /* Multiply by 60 for seconds */
16743 zone->refreshkeyinterval = interval * 60;
16744 return (ISC_R_SUCCESS);
16748 dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) {
16749 REQUIRE(DNS_ZONE_VALID(zone));
16750 zone->requestixfr = flag;
16754 dns_zone_getrequestixfr(dns_zone_t *zone) {
16755 REQUIRE(DNS_ZONE_VALID(zone));
16756 return (zone->requestixfr);
16760 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
16761 REQUIRE(DNS_ZONE_VALID(zone));
16762 zone->updatemethod = method;
16766 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
16767 REQUIRE(DNS_ZONE_VALID(zone));
16768 return(zone->updatemethod);
16772 * Lock hierarchy: zmgr, zone, raw.
16775 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
16776 isc_result_t result;
16777 dns_zonemgr_t *zmgr;
16779 REQUIRE(DNS_ZONE_VALID(zone));
16780 REQUIRE(zone->zmgr != NULL);
16781 REQUIRE(zone->task != NULL);
16782 REQUIRE(zone->loadtask != NULL);
16783 REQUIRE(zone->raw == NULL);
16785 REQUIRE(DNS_ZONE_VALID(raw));
16786 REQUIRE(raw->zmgr == NULL);
16787 REQUIRE(raw->task == NULL);
16788 REQUIRE(raw->loadtask == NULL);
16789 REQUIRE(raw->secure == NULL);
16792 * Lock hierarchy: zmgr, zone, raw.
16795 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16799 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
16800 NULL, NULL, zone->task, zone_timer, raw,
16802 if (result != ISC_R_SUCCESS)
16806 * The timer "holds" a iref.
16809 INSIST(raw->irefs != 0);
16812 /* dns_zone_attach(raw, &zone->raw); */
16813 isc_refcount_increment(&raw->erefs, NULL);
16816 /* dns_zone_iattach(zone, &raw->secure); */
16817 zone_iattach(zone, &raw->secure);
16819 isc_task_attach(zone->task, &raw->task);
16820 isc_task_attach(zone->loadtask, &raw->loadtask);
16822 ISC_LIST_APPEND(zmgr->zones, raw, link);
16829 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16834 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
16835 REQUIRE(DNS_ZONE_VALID(zone));
16836 REQUIRE(raw != NULL && *raw == NULL);
16839 if (zone->raw != NULL)
16840 dns_zone_attach(zone->raw, raw);
16841 UNLOCK(&zone->lock);
16847 unsigned char data[5];
16850 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
16853 keydone(isc_task_t *task, isc_event_t *event) {
16854 const char *me = "keydone";
16855 isc_boolean_t commit = ISC_FALSE;
16856 isc_result_t result;
16857 dns_rdata_t rdata = DNS_RDATA_INIT;
16858 dns_dbversion_t *oldver = NULL, *newver = NULL;
16860 dns_db_t *db = NULL;
16861 dns_dbnode_t *node = NULL;
16862 dns_rdataset_t rdataset;
16864 struct keydone *keydone = (struct keydone *)event;
16865 dns_update_log_t log = { update_log_cb, NULL };
16866 isc_boolean_t clear_pending = ISC_FALSE;
16870 zone = event->ev_arg;
16871 INSIST(DNS_ZONE_VALID(zone));
16875 dns_rdataset_init(&rdataset);
16876 dns_diff_init(zone->mctx, &diff);
16878 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
16879 if (zone->db != NULL) {
16880 dns_db_attach(zone->db, &db);
16881 dns_db_currentversion(db, &oldver);
16882 result = dns_db_newversion(db, &newver);
16883 if (result != ISC_R_SUCCESS) {
16884 dns_zone_log(zone, ISC_LOG_ERROR,
16885 "keydone:dns_db_newversion -> %s",
16886 dns_result_totext(result));
16890 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
16894 result = dns_db_getoriginnode(db, &node);
16895 if (result != ISC_R_SUCCESS)
16898 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
16899 dns_rdatatype_none, 0, &rdataset, NULL);
16900 if (result == ISC_R_NOTFOUND) {
16901 INSIST(!dns_rdataset_isassociated(&rdataset));
16904 if (result != ISC_R_SUCCESS) {
16905 INSIST(!dns_rdataset_isassociated(&rdataset));
16909 for (result = dns_rdataset_first(&rdataset);
16910 result == ISC_R_SUCCESS;
16911 result = dns_rdataset_next(&rdataset)) {
16912 isc_boolean_t found = ISC_FALSE;
16914 dns_rdataset_current(&rdataset, &rdata);
16916 if (keydone->all) {
16917 if (rdata.length == 5 && rdata.data[0] != 0 &&
16918 rdata.data[3] == 0 && rdata.data[4] == 1)
16920 else if (rdata.data[0] == 0 &&
16921 (rdata.data[2] & PENDINGFLAGS) != 0) {
16923 clear_pending = ISC_TRUE;
16925 } else if (rdata.length == 5 &&
16926 memcmp(rdata.data, keydone->data, 5) == 0)
16930 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
16931 &zone->origin, rdataset.ttl,
16933 dns_rdata_reset(&rdata);
16936 if (!ISC_LIST_EMPTY(diff.tuples)) {
16937 /* Write changes to journal file. */
16938 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
16939 zone->updatemethod));
16941 result = dns_update_signatures(&log, zone, db,
16942 oldver, newver, &diff,
16943 zone->sigvalidityinterval);
16944 if (!clear_pending)
16947 CHECK(zone_journal(zone, &diff, NULL, "keydone"));
16951 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
16952 zone_needdump(zone, 30);
16957 if (dns_rdataset_isassociated(&rdataset))
16958 dns_rdataset_disassociate(&rdataset);
16961 dns_db_detachnode(db, &node);
16962 if (oldver != NULL)
16963 dns_db_closeversion(db, &oldver, ISC_FALSE);
16964 if (newver != NULL)
16965 dns_db_closeversion(db, &newver, commit);
16966 dns_db_detach(&db);
16968 dns_diff_clear(&diff);
16969 isc_event_free(&event);
16970 dns_zone_idetach(&zone);
16974 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
16975 isc_result_t result = ISC_R_SUCCESS;
16978 dns_zone_t *dummy = NULL;
16979 struct keydone *kd;
16981 REQUIRE(DNS_ZONE_VALID(zone));
16985 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
16986 zone, sizeof(struct keydone));
16988 result = ISC_R_NOMEMORY;
16992 kd = (struct keydone *) e;
16993 if (strcasecmp(keystr, "all") == 0)
16994 kd->all = ISC_TRUE;
16996 isc_textregion_t r;
16998 dns_keytag_t keyid;
17002 kd->all = ISC_FALSE;
17004 n = sscanf(keystr, "%hd/", &keyid);
17006 CHECK(ISC_R_FAILURE);
17008 algstr = strchr(keystr, '/');
17009 if (algstr != NULL)
17012 CHECK(ISC_R_FAILURE);
17014 n = sscanf(algstr, "%hhd", &alg);
17016 DE_CONST(algstr, r.base);
17017 r.length = strlen(algstr);
17018 CHECK(dns_secalg_fromtext(&alg, &r));
17021 /* construct a private-type rdata */
17022 isc_buffer_init(&b, kd->data, sizeof(kd->data));
17023 isc_buffer_putuint8(&b, alg);
17024 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
17025 isc_buffer_putuint8(&b, (keyid & 0xff));
17026 isc_buffer_putuint8(&b, 0);
17027 isc_buffer_putuint8(&b, 1);
17030 zone_iattach(zone, &dummy);
17031 isc_task_send(zone->task, &e);
17035 isc_event_free(&e);
17041 setnsec3param(isc_task_t *task, isc_event_t *event) {
17042 const char *me = "setnsec3param";
17043 isc_boolean_t commit = ISC_FALSE;
17044 isc_result_t result;
17045 dns_dbversion_t *oldver = NULL, *newver = NULL;
17047 dns_db_t *db = NULL;
17048 dns_dbnode_t *node = NULL;
17049 dns_rdataset_t prdataset, nrdataset;
17051 struct np3event *npe = (struct np3event *)event;
17053 dns_update_log_t log = { update_log_cb, NULL };
17055 isc_boolean_t nseconly;
17056 isc_boolean_t exists = ISC_FALSE;
17060 zone = event->ev_arg;
17061 INSIST(DNS_ZONE_VALID(zone));
17067 dns_rdataset_init(&prdataset);
17068 dns_rdataset_init(&nrdataset);
17069 dns_diff_init(zone->mctx, &diff);
17071 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17072 if (zone->db != NULL) {
17073 dns_db_attach(zone->db, &db);
17074 dns_db_currentversion(db, &oldver);
17075 result = dns_db_newversion(db, &newver);
17076 if (result != ISC_R_SUCCESS) {
17077 dns_zone_log(zone, ISC_LOG_ERROR,
17078 "setnsec3param:dns_db_newversion -> %s",
17079 dns_result_totext(result));
17083 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17087 CHECK(dns_db_getoriginnode(db, &node));
17090 * Does a private-type record already exist for this chain?
17092 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
17093 dns_rdatatype_none, 0, &prdataset, NULL);
17094 if (result == ISC_R_SUCCESS) {
17095 for (result = dns_rdataset_first(&prdataset);
17096 result == ISC_R_SUCCESS;
17097 result = dns_rdataset_next(&prdataset)) {
17098 dns_rdata_init(&rdata);
17099 dns_rdataset_current(&prdataset, &rdata);
17101 if (np->length == rdata.length &&
17102 memcmp(rdata.data, np->data, np->length) == 0) {
17107 } else if (result != ISC_R_NOTFOUND) {
17108 INSIST(!dns_rdataset_isassociated(&prdataset));
17113 * Does the chain already exist?
17115 result = dns_db_findrdataset(db, node, newver,
17116 dns_rdatatype_nsec3param,
17117 dns_rdatatype_none, 0, &nrdataset, NULL);
17118 if (result == ISC_R_SUCCESS) {
17119 for (result = dns_rdataset_first(&nrdataset);
17120 result == ISC_R_SUCCESS;
17121 result = dns_rdataset_next(&nrdataset)) {
17122 dns_rdata_init(&rdata);
17123 dns_rdataset_current(&nrdataset, &rdata);
17125 if (np->length == (rdata.length + 1) &&
17126 memcmp(rdata.data, np->data + 1,
17127 np->length - 1) == 0)
17133 } else if (result != ISC_R_NOTFOUND) {
17134 INSIST(!dns_rdataset_isassociated(&nrdataset));
17140 * We need to remove any existing NSEC3 chains.
17142 if (!exists && np->replace && (np->length != 0 || np->nsec))
17143 CHECK(dns_nsec3param_deletechains(db, newver, zone,
17144 !np->nsec, &diff));
17146 if (!exists && np->length != 0) {
17148 * We're creating an NSEC3 chain.
17150 * If the zone is not currently capable of supporting
17151 * an NSEC3 chain, add the INITIAL flag, so these
17152 * parameters can be used later when NSEC3 becomes
17155 dns_rdata_init(&rdata);
17157 np->data[2] |= DNS_NSEC3FLAG_CREATE;
17158 result = dns_nsec_nseconly(db, newver, &nseconly);
17159 if (result == ISC_R_NOTFOUND || nseconly)
17160 np->data[2] |= DNS_NSEC3FLAG_INITIAL;
17162 rdata.length = np->length;
17163 rdata.data = np->data;
17164 rdata.type = zone->privatetype;
17165 rdata.rdclass = zone->rdclass;
17166 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
17167 &zone->origin, 0, &rdata));
17170 if (!ISC_LIST_EMPTY(diff.tuples)) {
17171 /* Write changes to journal file. */
17172 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
17173 zone->updatemethod));
17174 result = dns_update_signatures(&log, zone, db,
17175 oldver, newver, &diff,
17176 zone->sigvalidityinterval);
17177 if (result != ISC_R_NOTFOUND)
17179 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
17183 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
17184 zone_needdump(zone, 30);
17189 if (dns_rdataset_isassociated(&prdataset))
17190 dns_rdataset_disassociate(&prdataset);
17191 if (dns_rdataset_isassociated(&nrdataset))
17192 dns_rdataset_disassociate(&nrdataset);
17194 dns_db_detachnode(db, &node);
17195 if (oldver != NULL)
17196 dns_db_closeversion(db, &oldver, ISC_FALSE);
17197 if (newver != NULL)
17198 dns_db_closeversion(db, &newver, commit);
17200 dns_db_detach(&db);
17202 resume_addnsec3chain(zone);
17203 dns_diff_clear(&diff);
17204 isc_event_free(&event);
17205 dns_zone_idetach(&zone);
17209 dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
17210 isc_uint16_t iter, isc_uint8_t saltlen,
17211 unsigned char *salt, isc_boolean_t replace)
17213 isc_result_t result = ISC_R_SUCCESS;
17214 dns_rdata_nsec3param_t param;
17215 dns_rdata_t nrdata = DNS_RDATA_INIT;
17216 dns_rdata_t prdata = DNS_RDATA_INIT;
17217 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
17218 struct np3event *npe;
17220 dns_zone_t *dummy = NULL;
17224 REQUIRE(DNS_ZONE_VALID(zone));
17225 REQUIRE(salt != NULL);
17229 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
17230 setnsec3param, zone, sizeof(struct np3event));
17232 result = ISC_R_NOMEMORY;
17236 npe = (struct np3event *) e;
17239 np->replace = replace;
17242 np->nsec = ISC_TRUE;
17244 param.common.rdclass = zone->rdclass;
17245 param.common.rdtype = dns_rdatatype_nsec3param;
17246 ISC_LINK_INIT(¶m.common, link);
17249 param.flags = flags;
17250 param.iterations = iter;
17251 param.salt_length = saltlen;
17253 isc_buffer_init(&b, nbuf, sizeof(nbuf));
17254 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
17255 dns_rdatatype_nsec3param,
17257 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
17258 np->data, sizeof(np->data));
17259 np->length = prdata.length;
17262 zone_iattach(zone, &dummy);
17263 isc_task_send(zone->task, &e);
17267 isc_event_free(&e);
17273 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
17274 REQUIRE(DNS_ZONE_VALID(zone));
17276 zone->statlevel = level;
17279 dns_zonestat_level_t
17280 dns_zone_getstatlevel(dns_zone_t *zone) {
17281 REQUIRE(DNS_ZONE_VALID(zone));
17283 return (zone->statlevel);