2 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: zone.c,v 1.483.36.17 2009/12/21 04:32:42 marka Exp $ */
26 #include <isc/mutex.h>
27 #include <isc/print.h>
28 #include <isc/random.h>
29 #include <isc/ratelimiter.h>
30 #include <isc/refcount.h>
31 #include <isc/rwlock.h>
32 #include <isc/serial.h>
33 #include <isc/strerror.h>
34 #include <isc/stats.h>
35 #include <isc/stdtime.h>
36 #include <isc/string.h>
37 #include <isc/taskpool.h>
38 #include <isc/timer.h>
41 #include <dns/acache.h>
44 #include <dns/callbacks.h>
46 #include <dns/dbiterator.h>
47 #include <dns/dnssec.h>
48 #include <dns/events.h>
49 #include <dns/journal.h>
50 #include <dns/keyvalues.h>
52 #include <dns/master.h>
53 #include <dns/masterdump.h>
54 #include <dns/message.h>
57 #include <dns/nsec3.h>
59 #include <dns/rcode.h>
60 #include <dns/rdataclass.h>
61 #include <dns/rdatalist.h>
62 #include <dns/rdataset.h>
63 #include <dns/rdatasetiter.h>
64 #include <dns/rdatastruct.h>
65 #include <dns/rdatatype.h>
66 #include <dns/request.h>
67 #include <dns/resolver.h>
68 #include <dns/result.h>
71 #include <dns/stats.h>
73 #include <dns/xfrin.h>
78 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
79 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
81 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
82 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
84 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
85 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
87 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
88 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
90 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
91 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
93 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
94 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
96 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
97 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
100 * Ensure 'a' is at least 'min' but not more than 'max'.
102 #define RANGE(a, min, max) \
103 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
105 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
110 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
111 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
112 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
114 #ifndef DNS_MAX_EXPIRE
115 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
118 #ifndef DNS_DUMP_DELAY
119 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
122 typedef struct dns_notify dns_notify_t;
123 typedef struct dns_stub dns_stub_t;
124 typedef struct dns_load dns_load_t;
125 typedef struct dns_forward dns_forward_t;
126 typedef struct dns_io dns_io_t;
127 typedef ISC_LIST(dns_io_t) dns_iolist_t;
128 typedef struct dns_signing dns_signing_t;
129 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
130 typedef struct dns_nsec3chain dns_nsec3chain_t;
131 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
133 #define DNS_ZONE_CHECKLOCK
134 #ifdef DNS_ZONE_CHECKLOCK
135 #define LOCK_ZONE(z) \
136 do { LOCK(&(z)->lock); \
137 INSIST((z)->locked == ISC_FALSE); \
138 (z)->locked = ISC_TRUE; \
140 #define UNLOCK_ZONE(z) \
141 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
142 #define LOCKED_ZONE(z) ((z)->locked)
144 #define LOCK_ZONE(z) LOCK(&(z)->lock)
145 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
146 #define LOCKED_ZONE(z) ISC_TRUE
149 #ifdef ISC_RWLOCK_USEATOMIC
150 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
151 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
152 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
153 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
155 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
156 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
157 #define ZONEDB_LOCK(l, t) LOCK(l)
158 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
165 #ifdef DNS_ZONE_CHECKLOCK
166 isc_boolean_t locked;
169 isc_refcount_t erefs;
171 #ifdef ISC_RWLOCK_USEATOMIC
176 dns_db_t *db; /* Locked by dblock */
180 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
185 dns_masterformat_t masterformat;
187 isc_int32_t journalsize;
188 dns_rdataclass_t rdclass;
191 unsigned int options;
192 unsigned int db_argc;
194 isc_time_t expiretime;
195 isc_time_t refreshtime;
198 isc_time_t notifytime;
199 isc_time_t resigntime;
200 isc_time_t keywarntime;
201 isc_time_t signingtime;
202 isc_time_t nsec3chaintime;
203 isc_uint32_t refresh;
206 isc_uint32_t minimum;
207 isc_stdtime_t key_expiry;
210 isc_uint32_t maxrefresh;
211 isc_uint32_t minrefresh;
212 isc_uint32_t maxretry;
213 isc_uint32_t minretry;
215 isc_sockaddr_t *masters;
216 dns_name_t **masterkeynames;
217 isc_boolean_t *mastersok;
218 unsigned int masterscnt;
219 unsigned int curmaster;
220 isc_sockaddr_t masteraddr;
221 dns_notifytype_t notifytype;
222 isc_sockaddr_t *notify;
223 unsigned int notifycnt;
224 isc_sockaddr_t notifyfrom;
226 isc_sockaddr_t notifysrc4;
227 isc_sockaddr_t notifysrc6;
228 isc_sockaddr_t xfrsource4;
229 isc_sockaddr_t xfrsource6;
230 isc_sockaddr_t altxfrsource4;
231 isc_sockaddr_t altxfrsource6;
232 isc_sockaddr_t sourceaddr;
233 dns_xfrin_ctx_t *xfr; /* task locked */
234 dns_tsigkey_t *tsigkey; /* key used for xfr */
235 /* Access Control Lists */
236 dns_acl_t *update_acl;
237 dns_acl_t *forward_acl;
238 dns_acl_t *notify_acl;
239 dns_acl_t *query_acl;
240 dns_acl_t *queryon_acl;
242 isc_boolean_t update_disabled;
243 isc_boolean_t zero_no_soa_ttl;
244 dns_severity_t check_names;
245 ISC_LIST(dns_notify_t) notifies;
246 dns_request_t *request;
251 isc_uint32_t maxxfrin;
252 isc_uint32_t maxxfrout;
254 isc_uint32_t idleout;
255 isc_event_t ctlevent;
256 dns_ssutable_t *ssutable;
257 isc_uint32_t sigvalidityinterval;
258 isc_uint32_t sigresigninginterval;
260 dns_acache_t *acache;
261 dns_checkmxfunc_t checkmx;
262 dns_checksrvfunc_t checksrv;
263 dns_checknsfunc_t checkns;
265 * Zones in certain states such as "waiting for zone transfer"
266 * or "zone transfer in progress" are kept on per-state linked lists
267 * in the zone manager using the 'statelink' field. The 'statelist'
268 * field points at the list the zone is currently on. It the zone
269 * is not on any such list, statelist is NULL.
271 ISC_LINK(dns_zone_t) statelink;
272 dns_zonelist_t *statelist;
274 * Statistics counters about zone management.
278 * Optional per-zone statistics counters. Counted outside of this
281 isc_boolean_t requeststats_on;
282 isc_stats_t *requeststats;
283 isc_uint32_t notifydelay;
284 dns_isselffunc_t isself;
293 * Serial number for deferred journal compaction.
295 isc_uint32_t compact_serial;
297 * Keys that are signing the zone for the first time.
299 dns_signinglist_t signing;
300 dns_nsec3chainlist_t nsec3chain;
302 * Signing / re-signing quantum stopping parameters.
304 isc_uint32_t signatures;
306 dns_rdatatype_t privatetype;
309 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
310 #define DNS_ZONE_SETFLAG(z,f) do { \
311 INSIST(LOCKED_ZONE(z)); \
314 #define DNS_ZONE_CLRFLAG(z,f) do { \
315 INSIST(LOCKED_ZONE(z)); \
316 (z)->flags &= ~(f); \
318 /* XXX MPA these may need to go back into zone.h */
319 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
320 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
321 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
322 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
323 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
324 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
325 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
326 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
327 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
328 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
330 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
332 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
334 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
335 * zone with no masters
337 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
338 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
339 * from SOA (if not set, we
341 * default timer values) */
342 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
343 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
344 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
345 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
346 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
347 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
348 #define DNS_ZONEFLG_FLUSH 0x00200000U
349 #define DNS_ZONEFLG_NOEDNS 0x00400000U
350 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
351 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
352 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
353 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
354 #define DNS_ZONEFLG_THAW 0x08000000U
356 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
358 /* Flags for zone_load() */
359 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
360 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
363 #define UNREACH_CHACHE_SIZE 10U
364 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
367 do { result = (op); \
368 if (result != ISC_R_SUCCESS) goto failure; \
371 struct dns_unreachable {
372 isc_sockaddr_t remote;
373 isc_sockaddr_t local;
381 int refs; /* Locked by rwlock */
382 isc_taskmgr_t * taskmgr;
383 isc_timermgr_t * timermgr;
384 isc_socketmgr_t * socketmgr;
385 isc_taskpool_t * zonetasks;
387 isc_ratelimiter_t * rl;
391 /* Locked by rwlock. */
392 dns_zonelist_t zones;
393 dns_zonelist_t waiting_for_xfrin;
394 dns_zonelist_t xfrin_in_progress;
396 /* Configuration data. */
397 isc_uint32_t transfersin;
398 isc_uint32_t transfersperns;
399 unsigned int serialqueryrate;
401 /* Locked by iolock */
402 isc_uint32_t iolimit;
403 isc_uint32_t ioactive;
407 /* Locked by rwlock. */
409 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
421 dns_request_t *request;
424 ISC_LINK(dns_notify_t) link;
427 #define DNS_NOTIFY_NOSOA 0x0001U
430 * dns_stub holds state while performing a 'stub' transfer.
431 * 'db' is the zone's 'db' or a new one if this is the initial
440 dns_dbversion_t *version;
452 dns_rdatacallbacks_t callbacks;
456 * Hold forward state.
462 isc_buffer_t *msgbuf;
463 dns_request_t *request;
466 dns_updatecallback_t callback;
471 * Hold IO request state.
478 ISC_LINK(dns_io_t) link;
483 * Hold state for when we are signing a zone with a new
484 * DNSKEY as result of an update.
489 dns_dbiterator_t *dbiterator;
490 dns_secalg_t algorithm;
492 isc_boolean_t delete;
494 ISC_LINK(dns_signing_t) link;
497 struct dns_nsec3chain {
500 dns_dbiterator_t *dbiterator;
501 dns_rdata_nsec3param_t nsec3param;
502 unsigned char salt[255];
504 isc_boolean_t seen_nsec;
505 isc_boolean_t delete_nsec;
506 isc_boolean_t save_delete_nsec;
507 ISC_LINK(dns_nsec3chain_t) link;
510 * 'dbiterator' contains a iterator for the database. If we are creating
511 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
512 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
515 * 'nsec3param' contains the parameters of the NSEC3 chain being created
518 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
520 * 'seen_nsec' will be set to true if, while iterating the zone to create a
521 * NSEC3 chain, a NSEC record is seen.
523 * 'delete_nsec' will be set to true if, at the completion of the creation
524 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
525 * are in the process of deleting the NSEC chain.
527 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
528 * so it can be recovered in the event of a error.
532 #define SEND_BUFFER_SIZE 2048
534 static void zone_settimer(dns_zone_t *, isc_time_t *);
535 static void cancel_refresh(dns_zone_t *);
536 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
537 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
538 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
539 ISC_FORMAT_PRINTF(3, 4);
540 static void queue_xfrin(dns_zone_t *zone);
541 static void zone_unload(dns_zone_t *zone);
542 static void zone_expire(dns_zone_t *zone);
543 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
544 static void zone_idetach(dns_zone_t **zonep);
545 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
547 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
548 static inline void zone_detachdb(dns_zone_t *zone);
549 static isc_result_t default_journal(dns_zone_t *zone);
550 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
551 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
552 isc_time_t loadtime, isc_result_t result);
553 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
554 static void zone_shutdown(isc_task_t *, isc_event_t *);
555 static void zone_loaddone(void *arg, isc_result_t result);
556 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
557 isc_time_t loadtime);
558 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
559 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
560 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
561 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
564 /* ondestroy example */
565 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
568 static void refresh_callback(isc_task_t *, isc_event_t *);
569 static void stub_callback(isc_task_t *, isc_event_t *);
570 static void queue_soa_query(dns_zone_t *zone);
571 static void soa_query(isc_task_t *, isc_event_t *);
572 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
574 static int message_count(dns_message_t *msg, dns_section_t section,
575 dns_rdatatype_t type);
576 static void notify_cancel(dns_zone_t *zone);
577 static void notify_find_address(dns_notify_t *notify);
578 static void notify_send(dns_notify_t *notify);
579 static isc_result_t notify_createmessage(dns_zone_t *zone,
581 dns_message_t **messagep);
582 static void notify_done(isc_task_t *task, isc_event_t *event);
583 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
584 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
585 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
586 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
588 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
589 static void zonemgr_free(dns_zonemgr_t *zmgr);
590 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
591 isc_task_t *task, isc_taskaction_t action,
592 void *arg, dns_io_t **iop);
593 static void zonemgr_putio(dns_io_t **iop);
594 static void zonemgr_cancelio(dns_io_t *io);
597 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
598 unsigned int *soacount, isc_uint32_t *serial,
599 isc_uint32_t *refresh, isc_uint32_t *retry,
600 isc_uint32_t *expire, isc_uint32_t *minimum,
601 unsigned int *errors);
603 static void zone_freedbargs(dns_zone_t *zone);
604 static void forward_callback(isc_task_t *task, isc_event_t *event);
605 static void zone_saveunique(dns_zone_t *zone, const char *path,
606 const char *templat);
607 static void zone_maintenance(dns_zone_t *zone);
608 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
609 static void dump_done(void *arg, isc_result_t result);
610 static isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr,
611 isc_sockaddr_t *remote,
612 isc_sockaddr_t *local,
614 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
615 isc_uint16_t keyid, isc_boolean_t delete);
617 #define ENTER zone_debuglog(zone, me, 1, "enter")
619 static const unsigned int dbargc_default = 1;
620 static const char *dbargv_default[] = { "rbt" };
622 #define DNS_ZONE_JITTER_ADD(a, b, c) \
626 _j = isc_random_jitter((b), (b)/4); \
627 isc_interval_set(&_i, _j, 0); \
628 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
629 dns_zone_log(zone, ISC_LOG_WARNING, \
630 "epoch approaching: upgrade required: " \
631 "now + %s failed", #b); \
632 isc_interval_set(&_i, _j/2, 0); \
633 (void)isc_time_add((a), &_i, (c)); \
637 #define DNS_ZONE_TIME_ADD(a, b, c) \
640 isc_interval_set(&_i, (b), 0); \
641 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
642 dns_zone_log(zone, ISC_LOG_WARNING, \
643 "epoch approaching: upgrade required: " \
644 "now + %s failed", #b); \
645 isc_interval_set(&_i, (b)/2, 0); \
646 (void)isc_time_add((a), &_i, (c)); \
651 * Increment resolver-related statistics counters. Zone must be locked.
654 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
655 if (zone->stats != NULL)
656 isc_stats_increment(zone->stats, counter);
660 *** Public functions.
664 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
669 REQUIRE(zonep != NULL && *zonep == NULL);
670 REQUIRE(mctx != NULL);
673 zone = isc_mem_get(mctx, sizeof(*zone));
675 return (ISC_R_NOMEMORY);
678 isc_mem_attach(mctx, &zone->mctx);
680 result = isc_mutex_init(&zone->lock);
681 if (result != ISC_R_SUCCESS)
684 result = ZONEDB_INITLOCK(&zone->dblock);
685 if (result != ISC_R_SUCCESS)
688 /* XXX MPA check that all elements are initialised */
689 #ifdef DNS_ZONE_CHECKLOCK
690 zone->locked = ISC_FALSE;
694 ISC_LINK_INIT(zone, link);
695 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
696 if (result != ISC_R_SUCCESS)
699 dns_name_init(&zone->origin, NULL);
700 zone->strnamerd = NULL;
701 zone->strname = NULL;
702 zone->strrdclass = NULL;
703 zone->strviewname = NULL;
704 zone->masterfile = NULL;
705 zone->masterformat = dns_masterformat_none;
706 zone->keydirectory = NULL;
707 zone->journalsize = -1;
708 zone->journal = NULL;
709 zone->rdclass = dns_rdataclass_none;
710 zone->type = dns_zone_none;
714 zone->db_argv = NULL;
715 isc_time_settoepoch(&zone->expiretime);
716 isc_time_settoepoch(&zone->refreshtime);
717 isc_time_settoepoch(&zone->dumptime);
718 isc_time_settoepoch(&zone->loadtime);
719 zone->notifytime = now;
720 isc_time_settoepoch(&zone->resigntime);
721 isc_time_settoepoch(&zone->keywarntime);
722 isc_time_settoepoch(&zone->signingtime);
723 isc_time_settoepoch(&zone->nsec3chaintime);
724 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
725 zone->retry = DNS_ZONE_DEFAULTRETRY;
728 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
729 zone->minrefresh = DNS_ZONE_MINREFRESH;
730 zone->maxretry = DNS_ZONE_MAXRETRY;
731 zone->minretry = DNS_ZONE_MINRETRY;
732 zone->masters = NULL;
733 zone->masterkeynames = NULL;
734 zone->mastersok = NULL;
735 zone->masterscnt = 0;
738 zone->notifytype = dns_notifytype_yes;
741 zone->update_acl = NULL;
742 zone->forward_acl = NULL;
743 zone->notify_acl = NULL;
744 zone->query_acl = NULL;
745 zone->queryon_acl = NULL;
746 zone->xfr_acl = NULL;
747 zone->update_disabled = ISC_FALSE;
748 zone->zero_no_soa_ttl = ISC_TRUE;
749 zone->check_names = dns_severity_ignore;
750 zone->request = NULL;
754 zone->writeio = NULL;
756 zone->idlein = DNS_DEFAULT_IDLEIN;
757 zone->idleout = DNS_DEFAULT_IDLEOUT;
758 ISC_LIST_INIT(zone->notifies);
759 isc_sockaddr_any(&zone->notifysrc4);
760 isc_sockaddr_any6(&zone->notifysrc6);
761 isc_sockaddr_any(&zone->xfrsource4);
762 isc_sockaddr_any6(&zone->xfrsource6);
763 isc_sockaddr_any(&zone->altxfrsource4);
764 isc_sockaddr_any6(&zone->altxfrsource6);
766 zone->tsigkey = NULL;
767 zone->maxxfrin = MAX_XFER_TIME;
768 zone->maxxfrout = MAX_XFER_TIME;
769 zone->ssutable = NULL;
770 zone->sigvalidityinterval = 30 * 24 * 3600;
771 zone->sigresigninginterval = 7 * 24 * 3600;
774 zone->checkmx = NULL;
775 zone->checksrv = NULL;
776 zone->checkns = NULL;
777 ISC_LINK_INIT(zone, statelink);
778 zone->statelist = NULL;
780 zone->requeststats_on = ISC_FALSE;
781 zone->requeststats = NULL;
782 zone->notifydelay = 5;
784 zone->isselfarg = NULL;
785 ISC_LIST_INIT(zone->signing);
786 ISC_LIST_INIT(zone->nsec3chain);
787 zone->signatures = 10;
789 zone->privatetype = (dns_rdatatype_t)0xffffU;
791 zone->magic = ZONE_MAGIC;
793 /* Must be after magic is set. */
794 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
795 if (result != ISC_R_SUCCESS)
798 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
799 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
802 return (ISC_R_SUCCESS);
805 isc_refcount_decrement(&zone->erefs, NULL);
806 isc_refcount_destroy(&zone->erefs);
809 ZONEDB_DESTROYLOCK(&zone->dblock);
812 DESTROYLOCK(&zone->lock);
815 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
820 * Free a zone. Because we require that there be no more
821 * outstanding events or references, no locking is necessary.
824 zone_free(dns_zone_t *zone) {
825 isc_mem_t *mctx = NULL;
826 dns_signing_t *signing;
827 dns_nsec3chain_t *nsec3chain;
829 REQUIRE(DNS_ZONE_VALID(zone));
830 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
831 REQUIRE(zone->irefs == 0);
832 REQUIRE(!LOCKED_ZONE(zone));
833 REQUIRE(zone->timer == NULL);
836 * Managed objects. Order is important.
838 if (zone->request != NULL)
839 dns_request_destroy(&zone->request); /* XXXMPA */
840 INSIST(zone->readio == NULL);
841 INSIST(zone->statelist == NULL);
842 INSIST(zone->writeio == NULL);
844 if (zone->task != NULL)
845 isc_task_detach(&zone->task);
846 if (zone->zmgr != NULL)
847 dns_zonemgr_releasezone(zone->zmgr, zone);
849 /* Unmanaged objects */
850 for (signing = ISC_LIST_HEAD(zone->signing);
852 signing = ISC_LIST_HEAD(zone->signing)) {
853 ISC_LIST_UNLINK(zone->signing, signing, link);
854 dns_db_detach(&signing->db);
855 dns_dbiterator_destroy(&signing->dbiterator);
856 isc_mem_put(zone->mctx, signing, sizeof *signing);
858 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
860 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
861 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
862 dns_db_detach(&nsec3chain->db);
863 dns_dbiterator_destroy(&nsec3chain->dbiterator);
864 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
866 if (zone->masterfile != NULL)
867 isc_mem_free(zone->mctx, zone->masterfile);
868 zone->masterfile = NULL;
869 if (zone->keydirectory != NULL)
870 isc_mem_free(zone->mctx, zone->keydirectory);
871 zone->keydirectory = NULL;
872 zone->journalsize = -1;
873 if (zone->journal != NULL)
874 isc_mem_free(zone->mctx, zone->journal);
875 zone->journal = NULL;
876 if (zone->stats != NULL)
877 isc_stats_detach(&zone->stats);
878 if (zone->requeststats != NULL)
879 isc_stats_detach(&zone->requeststats);
880 if (zone->db != NULL)
882 if (zone->acache != NULL)
883 dns_acache_detach(&zone->acache);
884 zone_freedbargs(zone);
885 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
887 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
889 zone->check_names = dns_severity_ignore;
890 if (zone->update_acl != NULL)
891 dns_acl_detach(&zone->update_acl);
892 if (zone->forward_acl != NULL)
893 dns_acl_detach(&zone->forward_acl);
894 if (zone->notify_acl != NULL)
895 dns_acl_detach(&zone->notify_acl);
896 if (zone->query_acl != NULL)
897 dns_acl_detach(&zone->query_acl);
898 if (zone->queryon_acl != NULL)
899 dns_acl_detach(&zone->queryon_acl);
900 if (zone->xfr_acl != NULL)
901 dns_acl_detach(&zone->xfr_acl);
902 if (dns_name_dynamic(&zone->origin))
903 dns_name_free(&zone->origin, zone->mctx);
904 if (zone->strnamerd != NULL)
905 isc_mem_free(zone->mctx, zone->strnamerd);
906 if (zone->strname != NULL)
907 isc_mem_free(zone->mctx, zone->strname);
908 if (zone->strrdclass != NULL)
909 isc_mem_free(zone->mctx, zone->strrdclass);
910 if (zone->strviewname != NULL)
911 isc_mem_free(zone->mctx, zone->strviewname);
912 if (zone->ssutable != NULL)
913 dns_ssutable_detach(&zone->ssutable);
916 ZONEDB_DESTROYLOCK(&zone->dblock);
917 DESTROYLOCK(&zone->lock);
918 isc_refcount_destroy(&zone->erefs);
921 isc_mem_put(mctx, zone, sizeof(*zone));
922 isc_mem_detach(&mctx);
929 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
932 REQUIRE(DNS_ZONE_VALID(zone));
933 REQUIRE(rdclass != dns_rdataclass_none);
939 REQUIRE(zone->rdclass == dns_rdataclass_none ||
940 zone->rdclass == rdclass);
941 zone->rdclass = rdclass;
943 if (zone->strnamerd != NULL)
944 isc_mem_free(zone->mctx, zone->strnamerd);
945 if (zone->strrdclass != NULL)
946 isc_mem_free(zone->mctx, zone->strrdclass);
948 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
949 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
950 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
951 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
957 dns_zone_getclass(dns_zone_t *zone) {
958 REQUIRE(DNS_ZONE_VALID(zone));
960 return (zone->rdclass);
964 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
965 REQUIRE(DNS_ZONE_VALID(zone));
968 zone->notifytype = notifytype;
973 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
976 REQUIRE(DNS_ZONE_VALID(zone));
977 REQUIRE(serialp != NULL);
980 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
981 if (zone->db != NULL) {
982 result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
983 NULL, NULL, NULL, NULL, NULL);
985 result = DNS_R_NOTLOADED;
986 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
993 dns_zone_getserial(dns_zone_t *zone) {
997 result = dns_zone_getserial2(zone, &serial);
998 if (result != ISC_R_SUCCESS)
999 serial = 0; /* XXX: not really correct, but no other choice */
1008 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1010 REQUIRE(DNS_ZONE_VALID(zone));
1011 REQUIRE(type != dns_zone_none);
1017 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1023 zone_freedbargs(dns_zone_t *zone) {
1026 /* Free the old database argument list. */
1027 if (zone->db_argv != NULL) {
1028 for (i = 0; i < zone->db_argc; i++)
1029 isc_mem_free(zone->mctx, zone->db_argv[i]);
1030 isc_mem_put(zone->mctx, zone->db_argv,
1031 zone->db_argc * sizeof(*zone->db_argv));
1034 zone->db_argv = NULL;
1038 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1041 isc_result_t result = ISC_R_SUCCESS;
1045 REQUIRE(DNS_ZONE_VALID(zone));
1046 REQUIRE(argv != NULL && *argv == NULL);
1049 size = (zone->db_argc + 1) * sizeof(char *);
1050 for (i = 0; i < zone->db_argc; i++)
1051 size += strlen(zone->db_argv[i]) + 1;
1052 mem = isc_mem_allocate(mctx, size);
1056 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1057 for (i = 0; i < zone->db_argc; i++) {
1059 strcpy(tmp2, zone->db_argv[i]);
1060 tmp2 += strlen(tmp2) + 1;
1064 result = ISC_R_NOMEMORY;
1071 dns_zone_setdbtype(dns_zone_t *zone,
1072 unsigned int dbargc, const char * const *dbargv) {
1073 isc_result_t result = ISC_R_SUCCESS;
1077 REQUIRE(DNS_ZONE_VALID(zone));
1078 REQUIRE(dbargc >= 1);
1079 REQUIRE(dbargv != NULL);
1083 /* Set up a new database argument list. */
1084 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1087 for (i = 0; i < dbargc; i++)
1089 for (i = 0; i < dbargc; i++) {
1090 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1095 /* Free the old list. */
1096 zone_freedbargs(zone);
1098 zone->db_argc = dbargc;
1099 zone->db_argv = new;
1100 result = ISC_R_SUCCESS;
1105 for (i = 0; i < dbargc; i++)
1107 isc_mem_free(zone->mctx, new[i]);
1108 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1110 result = ISC_R_NOMEMORY;
1118 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1120 REQUIRE(DNS_ZONE_VALID(zone));
1123 if (zone->view != NULL)
1124 dns_view_weakdetach(&zone->view);
1125 dns_view_weakattach(view, &zone->view);
1127 if (zone->strviewname != NULL)
1128 isc_mem_free(zone->mctx, zone->strviewname);
1129 if (zone->strnamerd != NULL)
1130 isc_mem_free(zone->mctx, zone->strnamerd);
1132 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1133 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1134 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1135 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1142 dns_zone_getview(dns_zone_t *zone) {
1143 REQUIRE(DNS_ZONE_VALID(zone));
1145 return (zone->view);
1150 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1151 isc_result_t result;
1154 REQUIRE(DNS_ZONE_VALID(zone));
1155 REQUIRE(origin != NULL);
1158 if (dns_name_dynamic(&zone->origin)) {
1159 dns_name_free(&zone->origin, zone->mctx);
1160 dns_name_init(&zone->origin, NULL);
1162 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1164 if (zone->strnamerd != NULL)
1165 isc_mem_free(zone->mctx, zone->strnamerd);
1166 if (zone->strname != NULL)
1167 isc_mem_free(zone->mctx, zone->strname);
1169 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1170 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1171 zone_name_tostr(zone, namebuf, sizeof namebuf);
1172 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1179 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1180 REQUIRE(DNS_ZONE_VALID(zone));
1181 REQUIRE(acache != NULL);
1184 if (zone->acache != NULL)
1185 dns_acache_detach(&zone->acache);
1186 dns_acache_attach(acache, &zone->acache);
1187 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1188 if (zone->db != NULL) {
1189 isc_result_t result;
1192 * If the zone reuses an existing DB, the DB needs to be
1193 * set in the acache explicitly. We can safely ignore the
1194 * case where the DB is already set. If other error happens,
1195 * the acache will not work effectively.
1197 result = dns_acache_setdb(acache, zone->db);
1198 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1199 UNEXPECTED_ERROR(__FILE__, __LINE__,
1200 "dns_acache_setdb() failed: %s",
1201 isc_result_totext(result));
1204 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1209 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1212 if (value != NULL) {
1213 copy = isc_mem_strdup(zone->mctx, value);
1215 return (ISC_R_NOMEMORY);
1221 isc_mem_free(zone->mctx, *field);
1224 return (ISC_R_SUCCESS);
1228 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1229 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1233 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1234 dns_masterformat_t format) {
1235 isc_result_t result = ISC_R_SUCCESS;
1237 REQUIRE(DNS_ZONE_VALID(zone));
1240 result = dns_zone_setstring(zone, &zone->masterfile, file);
1241 if (result == ISC_R_SUCCESS) {
1242 zone->masterformat = format;
1243 result = default_journal(zone);
1251 dns_zone_getfile(dns_zone_t *zone) {
1252 REQUIRE(DNS_ZONE_VALID(zone));
1254 return (zone->masterfile);
1258 default_journal(dns_zone_t *zone) {
1259 isc_result_t result;
1262 REQUIRE(DNS_ZONE_VALID(zone));
1263 REQUIRE(LOCKED_ZONE(zone));
1265 if (zone->masterfile != NULL) {
1266 /* Calculate string length including '\0'. */
1267 int len = strlen(zone->masterfile) + sizeof(".jnl");
1268 journal = isc_mem_allocate(zone->mctx, len);
1269 if (journal == NULL)
1270 return (ISC_R_NOMEMORY);
1271 strcpy(journal, zone->masterfile);
1272 strcat(journal, ".jnl");
1276 result = dns_zone_setstring(zone, &zone->journal, journal);
1277 if (journal != NULL)
1278 isc_mem_free(zone->mctx, journal);
1283 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1284 isc_result_t result = ISC_R_SUCCESS;
1286 REQUIRE(DNS_ZONE_VALID(zone));
1289 result = dns_zone_setstring(zone, &zone->journal, journal);
1296 dns_zone_getjournal(dns_zone_t *zone) {
1297 REQUIRE(DNS_ZONE_VALID(zone));
1299 return (zone->journal);
1303 * Return true iff the zone is "dynamic", in the sense that the zone's
1304 * master file (if any) is written by the server, rather than being
1305 * updated manually and read by the server.
1307 * This is true for slave zones, stub zones, and zones that allow
1308 * dynamic updates either by having an update policy ("ssutable")
1309 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1311 static isc_boolean_t
1312 zone_isdynamic(dns_zone_t *zone) {
1313 REQUIRE(DNS_ZONE_VALID(zone));
1315 return (ISC_TF(zone->type == dns_zone_slave ||
1316 zone->type == dns_zone_stub ||
1317 (!zone->update_disabled && zone->ssutable != NULL) ||
1318 (!zone->update_disabled && zone->update_acl != NULL &&
1319 !dns_acl_isnone(zone->update_acl))));
1324 zone_load(dns_zone_t *zone, unsigned int flags) {
1325 isc_result_t result;
1327 isc_time_t loadtime, filetime;
1328 dns_db_t *db = NULL;
1330 REQUIRE(DNS_ZONE_VALID(zone));
1335 INSIST(zone->type != dns_zone_none);
1337 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1338 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1339 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1340 result = DNS_R_CONTINUE;
1344 if (zone->db != NULL && zone->masterfile == NULL) {
1346 * The zone has no master file configured, but it already
1347 * has a database. It could be the built-in
1348 * version.bind. CH zone, a zone with a persistent
1349 * database being reloaded, or maybe a zone that
1350 * used to have a master file but whose configuration
1351 * was changed so that it no longer has one. Do nothing.
1353 result = ISC_R_SUCCESS;
1357 if (zone->db != NULL && zone_isdynamic(zone)) {
1359 * This is a slave, stub, or dynamically updated
1360 * zone being reloaded. Do nothing - the database
1361 * we already have is guaranteed to be up-to-date.
1363 if (zone->type == dns_zone_master)
1364 result = DNS_R_DYNAMIC;
1366 result = ISC_R_SUCCESS;
1372 * Store the current time before the zone is loaded, so that if the
1373 * file changes between the time of the load and the time that
1374 * zone->loadtime is set, then the file will still be reloaded
1375 * the next time dns_zone_load is called.
1377 TIME_NOW(&loadtime);
1380 * Don't do the load if the file that stores the zone is older
1381 * than the last time the zone was loaded. If the zone has not
1382 * been loaded yet, zone->loadtime will be the epoch.
1384 if (zone->masterfile != NULL) {
1386 * The file is already loaded. If we are just doing a
1387 * "rndc reconfig", we are done.
1389 if (!isc_time_isepoch(&zone->loadtime) &&
1390 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1391 result = ISC_R_SUCCESS;
1395 result = isc_file_getmodtime(zone->masterfile, &filetime);
1396 if (result == ISC_R_SUCCESS) {
1397 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1398 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1399 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1400 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1401 "skipping load: master file "
1402 "older than last load");
1403 result = DNS_R_UPTODATE;
1406 loadtime = filetime;
1410 INSIST(zone->db_argc >= 1);
1413 * Built in zones don't need to be reloaded.
1415 if (zone->type == dns_zone_master &&
1416 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1417 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1418 result = ISC_R_SUCCESS;
1422 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1423 (strcmp(zone->db_argv[0], "rbt") == 0 ||
1424 strcmp(zone->db_argv[0], "rbt64") == 0)) {
1425 if (zone->masterfile == NULL ||
1426 !isc_file_exists(zone->masterfile)) {
1427 if (zone->masterfile != NULL) {
1428 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1431 zone->refreshtime = now;
1432 if (zone->task != NULL)
1433 zone_settimer(zone, &now);
1434 result = ISC_R_SUCCESS;
1439 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1441 result = dns_db_create(zone->mctx, zone->db_argv[0],
1442 &zone->origin, (zone->type == dns_zone_stub) ?
1443 dns_dbtype_stub : dns_dbtype_zone,
1445 zone->db_argc - 1, zone->db_argv + 1,
1448 if (result != ISC_R_SUCCESS) {
1449 dns_zone_log(zone, ISC_LOG_ERROR,
1450 "loading zone: creating database: %s",
1451 isc_result_totext(result));
1454 dns_db_settask(db, zone->task);
1456 if (! dns_db_ispersistent(db)) {
1457 if (zone->masterfile != NULL) {
1458 result = zone_startload(db, zone, loadtime);
1460 result = DNS_R_NOMASTERFILE;
1461 if (zone->type == dns_zone_master) {
1462 dns_zone_log(zone, ISC_LOG_ERROR,
1464 "no master file configured");
1467 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1468 "no master file configured: continuing");
1472 if (result == DNS_R_CONTINUE) {
1473 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1474 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1475 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1479 result = zone_postload(zone, db, loadtime, result);
1489 dns_zone_load(dns_zone_t *zone) {
1490 return (zone_load(zone, 0));
1494 dns_zone_loadnew(dns_zone_t *zone) {
1495 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1499 dns_zone_loadandthaw(dns_zone_t *zone) {
1500 isc_result_t result;
1502 result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1504 case DNS_R_CONTINUE:
1505 /* Deferred thaw. */
1508 case DNS_R_UPTODATE:
1509 case DNS_R_SEENINCLUDE:
1510 zone->update_disabled = ISC_FALSE;
1512 case DNS_R_NOMASTERFILE:
1513 zone->update_disabled = ISC_FALSE;
1516 /* Error, remain in disabled state. */
1523 get_master_options(dns_zone_t *zone) {
1524 unsigned int options;
1526 options = DNS_MASTER_ZONE;
1527 if (zone->type == dns_zone_slave)
1528 options |= DNS_MASTER_SLAVE;
1529 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1530 options |= DNS_MASTER_CHECKNS;
1531 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1532 options |= DNS_MASTER_FATALNS;
1533 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1534 options |= DNS_MASTER_CHECKNAMES;
1535 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1536 options |= DNS_MASTER_CHECKNAMESFAIL;
1537 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1538 options |= DNS_MASTER_CHECKMX;
1539 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1540 options |= DNS_MASTER_CHECKMXFAIL;
1541 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1542 options |= DNS_MASTER_CHECKWILDCARD;
1543 if (zone->type == dns_zone_master &&
1544 (zone->update_acl != NULL || zone->ssutable != NULL))
1545 options |= DNS_MASTER_RESIGN;
1550 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1551 dns_load_t *load = event->ev_arg;
1552 isc_result_t result = ISC_R_SUCCESS;
1553 unsigned int options;
1555 REQUIRE(DNS_LOAD_VALID(load));
1557 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1558 result = ISC_R_CANCELED;
1559 isc_event_free(&event);
1560 if (result == ISC_R_CANCELED)
1563 options = get_master_options(load->zone);
1565 result = dns_master_loadfileinc3(load->zone->masterfile,
1566 dns_db_origin(load->db),
1567 dns_db_origin(load->db),
1568 load->zone->rdclass,
1570 load->zone->sigresigninginterval,
1571 &load->callbacks, task,
1572 zone_loaddone, load,
1573 &load->zone->lctx, load->zone->mctx,
1574 load->zone->masterformat);
1575 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1576 result != DNS_R_SEENINCLUDE)
1581 zone_loaddone(load, result);
1585 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1586 const char me[] = "zone_gotwritehandle";
1587 dns_zone_t *zone = event->ev_arg;
1588 isc_result_t result = ISC_R_SUCCESS;
1589 dns_dbversion_t *version = NULL;
1591 REQUIRE(DNS_ZONE_VALID(zone));
1592 INSIST(task == zone->task);
1595 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1596 result = ISC_R_CANCELED;
1597 isc_event_free(&event);
1598 if (result == ISC_R_CANCELED)
1602 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1603 dns_db_currentversion(zone->db, &version);
1604 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1605 &dns_master_style_default,
1606 zone->masterfile, zone->task, dump_done,
1607 zone, &zone->dctx, zone->masterformat);
1608 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1609 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1611 if (result != DNS_R_CONTINUE)
1616 dump_done(zone, result);
1620 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1622 isc_result_t result;
1623 isc_result_t tresult;
1624 unsigned int options;
1626 options = get_master_options(zone);
1628 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1629 options |= DNS_MASTER_MANYERRORS;
1631 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1632 load = isc_mem_get(zone->mctx, sizeof(*load));
1634 return (ISC_R_NOMEMORY);
1639 load->loadtime = loadtime;
1640 load->magic = LOAD_MAGIC;
1642 isc_mem_attach(zone->mctx, &load->mctx);
1643 zone_iattach(zone, &load->zone);
1644 dns_db_attach(db, &load->db);
1645 dns_rdatacallbacks_init(&load->callbacks);
1646 result = dns_db_beginload(db, &load->callbacks.add,
1647 &load->callbacks.add_private);
1648 if (result != ISC_R_SUCCESS)
1650 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1651 zone_gotreadhandle, load,
1653 if (result != ISC_R_SUCCESS) {
1655 * We can't report multiple errors so ignore
1656 * the result of dns_db_endload().
1658 (void)dns_db_endload(load->db,
1659 &load->callbacks.add_private);
1662 result = DNS_R_CONTINUE;
1664 dns_rdatacallbacks_t callbacks;
1666 dns_rdatacallbacks_init(&callbacks);
1667 result = dns_db_beginload(db, &callbacks.add,
1668 &callbacks.add_private);
1669 if (result != ISC_R_SUCCESS)
1671 result = dns_master_loadfile3(zone->masterfile, &zone->origin,
1672 &zone->origin, zone->rdclass,
1673 options, zone->sigresigninginterval,
1674 &callbacks, zone->mctx,
1675 zone->masterformat);
1676 tresult = dns_db_endload(db, &callbacks.add_private);
1677 if (result == ISC_R_SUCCESS)
1685 dns_db_detach(&load->db);
1686 zone_idetach(&load->zone);
1687 isc_mem_detach(&load->mctx);
1688 isc_mem_put(zone->mctx, load, sizeof(*load));
1692 static isc_boolean_t
1693 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1696 isc_result_t result;
1697 char ownerbuf[DNS_NAME_FORMATSIZE];
1698 char namebuf[DNS_NAME_FORMATSIZE];
1699 char altbuf[DNS_NAME_FORMATSIZE];
1700 dns_fixedname_t fixed;
1701 dns_name_t *foundname;
1707 if (!dns_name_issubdomain(name, &zone->origin)) {
1708 if (zone->checkmx != NULL)
1709 return ((zone->checkmx)(zone, name, owner));
1713 if (zone->type == dns_zone_master)
1714 level = ISC_LOG_ERROR;
1716 level = ISC_LOG_WARNING;
1718 dns_fixedname_init(&fixed);
1719 foundname = dns_fixedname_name(&fixed);
1721 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1722 0, 0, NULL, foundname, NULL, NULL);
1723 if (result == ISC_R_SUCCESS)
1726 if (result == DNS_R_NXRRSET) {
1727 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1728 0, 0, NULL, foundname, NULL, NULL);
1729 if (result == ISC_R_SUCCESS)
1733 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1734 dns_name_format(name, namebuf, sizeof namebuf);
1735 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1736 result == DNS_R_EMPTYNAME) {
1737 dns_zone_log(zone, level,
1738 "%s/MX '%s' has no address records (A or AAAA)",
1740 /* XXX950 make fatal for 9.5.0. */
1744 if (result == DNS_R_CNAME) {
1745 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1746 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1747 level = ISC_LOG_WARNING;
1748 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1749 dns_zone_log(zone, level,
1750 "%s/MX '%s' is a CNAME (illegal)",
1752 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1755 if (result == DNS_R_DNAME) {
1756 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1757 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1758 level = ISC_LOG_WARNING;
1759 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1760 dns_name_format(foundname, altbuf, sizeof altbuf);
1761 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1762 " '%s' (illegal)", ownerbuf, namebuf,
1765 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1768 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1769 return ((zone->checkmx)(zone, name, owner));
1774 static isc_boolean_t
1775 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1778 isc_result_t result;
1779 char ownerbuf[DNS_NAME_FORMATSIZE];
1780 char namebuf[DNS_NAME_FORMATSIZE];
1781 char altbuf[DNS_NAME_FORMATSIZE];
1782 dns_fixedname_t fixed;
1783 dns_name_t *foundname;
1787 * "." means the services does not exist.
1789 if (dns_name_equal(name, dns_rootname))
1795 if (!dns_name_issubdomain(name, &zone->origin)) {
1796 if (zone->checksrv != NULL)
1797 return ((zone->checksrv)(zone, name, owner));
1801 if (zone->type == dns_zone_master)
1802 level = ISC_LOG_ERROR;
1804 level = ISC_LOG_WARNING;
1806 dns_fixedname_init(&fixed);
1807 foundname = dns_fixedname_name(&fixed);
1809 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1810 0, 0, NULL, foundname, NULL, NULL);
1811 if (result == ISC_R_SUCCESS)
1814 if (result == DNS_R_NXRRSET) {
1815 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1816 0, 0, NULL, foundname, NULL, NULL);
1817 if (result == ISC_R_SUCCESS)
1821 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1822 dns_name_format(name, namebuf, sizeof namebuf);
1823 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1824 result == DNS_R_EMPTYNAME) {
1825 dns_zone_log(zone, level,
1826 "%s/SRV '%s' has no address records (A or AAAA)",
1828 /* XXX950 make fatal for 9.5.0. */
1832 if (result == DNS_R_CNAME) {
1833 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1834 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1835 level = ISC_LOG_WARNING;
1836 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1837 dns_zone_log(zone, level,
1838 "%s/SRV '%s' is a CNAME (illegal)",
1840 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1843 if (result == DNS_R_DNAME) {
1844 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1845 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1846 level = ISC_LOG_WARNING;
1847 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1848 dns_name_format(foundname, altbuf, sizeof altbuf);
1849 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1850 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1853 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1856 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1857 return ((zone->checksrv)(zone, name, owner));
1862 static isc_boolean_t
1863 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1866 isc_boolean_t answer = ISC_TRUE;
1867 isc_result_t result, tresult;
1868 char ownerbuf[DNS_NAME_FORMATSIZE];
1869 char namebuf[DNS_NAME_FORMATSIZE];
1870 char altbuf[DNS_NAME_FORMATSIZE];
1871 dns_fixedname_t fixed;
1872 dns_name_t *foundname;
1874 dns_rdataset_t aaaa;
1880 if (!dns_name_issubdomain(name, &zone->origin)) {
1881 if (zone->checkns != NULL)
1882 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1886 if (zone->type == dns_zone_master)
1887 level = ISC_LOG_ERROR;
1889 level = ISC_LOG_WARNING;
1891 dns_fixedname_init(&fixed);
1892 foundname = dns_fixedname_name(&fixed);
1893 dns_rdataset_init(&a);
1894 dns_rdataset_init(&aaaa);
1896 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1897 DNS_DBFIND_GLUEOK, 0, NULL,
1898 foundname, &a, NULL);
1900 if (result == ISC_R_SUCCESS) {
1901 dns_rdataset_disassociate(&a);
1903 } else if (result == DNS_R_DELEGATION)
1904 dns_rdataset_disassociate(&a);
1906 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1907 result == DNS_R_GLUE) {
1908 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1909 DNS_DBFIND_GLUEOK, 0, NULL,
1910 foundname, &aaaa, NULL);
1911 if (tresult == ISC_R_SUCCESS) {
1912 dns_rdataset_disassociate(&aaaa);
1915 if (tresult == DNS_R_DELEGATION)
1916 dns_rdataset_disassociate(&aaaa);
1917 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1919 * Check glue against child zone.
1921 if (zone->checkns != NULL)
1922 answer = (zone->checkns)(zone, name, owner,
1924 if (dns_rdataset_isassociated(&a))
1925 dns_rdataset_disassociate(&a);
1926 if (dns_rdataset_isassociated(&aaaa))
1927 dns_rdataset_disassociate(&aaaa);
1933 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1934 dns_name_format(name, namebuf, sizeof namebuf);
1935 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1936 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
1938 isc_boolean_t required = ISC_FALSE;
1939 if (dns_name_issubdomain(name, owner)) {
1940 what = "REQUIRED GLUE ";
1941 required = ISC_TRUE;
1942 } else if (result == DNS_R_DELEGATION)
1943 what = "SIBLING GLUE ";
1947 if (result != DNS_R_DELEGATION || required ||
1948 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
1949 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
1950 "address records (A or AAAA)",
1951 ownerbuf, namebuf, what);
1953 * Log missing address record.
1955 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
1956 (void)(zone->checkns)(zone, name, owner,
1958 /* XXX950 make fatal for 9.5.0. */
1959 /* answer = ISC_FALSE; */
1961 } else if (result == DNS_R_CNAME) {
1962 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
1964 /* XXX950 make fatal for 9.5.0. */
1965 /* answer = ISC_FALSE; */
1966 } else if (result == DNS_R_DNAME) {
1967 dns_name_format(foundname, altbuf, sizeof altbuf);
1968 dns_zone_log(zone, level,
1969 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1970 ownerbuf, namebuf, altbuf);
1971 /* XXX950 make fatal for 9.5.0. */
1972 /* answer = ISC_FALSE; */
1975 if (dns_rdataset_isassociated(&a))
1976 dns_rdataset_disassociate(&a);
1977 if (dns_rdataset_isassociated(&aaaa))
1978 dns_rdataset_disassociate(&aaaa);
1982 static isc_boolean_t
1983 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
1984 dns_dbiterator_t *dbiterator = NULL;
1985 dns_dbnode_t *node = NULL;
1986 dns_rdataset_t rdataset;
1987 dns_fixedname_t fixed;
1988 dns_fixedname_t fixedbottom;
1991 dns_rdata_in_srv_t srv;
1995 isc_result_t result;
1996 isc_boolean_t ok = ISC_TRUE;
1998 dns_fixedname_init(&fixed);
1999 name = dns_fixedname_name(&fixed);
2000 dns_fixedname_init(&fixedbottom);
2001 bottom = dns_fixedname_name(&fixedbottom);
2002 dns_rdataset_init(&rdataset);
2003 dns_rdata_init(&rdata);
2005 result = dns_db_createiterator(db, 0, &dbiterator);
2006 if (result != ISC_R_SUCCESS)
2009 result = dns_dbiterator_first(dbiterator);
2010 while (result == ISC_R_SUCCESS) {
2011 result = dns_dbiterator_current(dbiterator, &node, name);
2012 if (result != ISC_R_SUCCESS)
2016 * Is this name visible in the zone?
2018 if (!dns_name_issubdomain(name, &zone->origin) ||
2019 (dns_name_countlabels(bottom) > 0 &&
2020 dns_name_issubdomain(name, bottom)))
2024 * Don't check the NS records at the origin.
2026 if (dns_name_equal(name, &zone->origin))
2029 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2030 0, 0, &rdataset, NULL);
2031 if (result != ISC_R_SUCCESS)
2034 * Remember bottom of zone.
2036 dns_name_copy(name, bottom, NULL);
2038 result = dns_rdataset_first(&rdataset);
2039 while (result == ISC_R_SUCCESS) {
2040 dns_rdataset_current(&rdataset, &rdata);
2041 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2042 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2043 if (!zone_check_glue(zone, db, &ns.name, name))
2045 dns_rdata_reset(&rdata);
2046 result = dns_rdataset_next(&rdataset);
2048 dns_rdataset_disassociate(&rdataset);
2051 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2052 0, 0, &rdataset, NULL);
2053 if (result != ISC_R_SUCCESS)
2055 result = dns_rdataset_first(&rdataset);
2056 while (result == ISC_R_SUCCESS) {
2057 dns_rdataset_current(&rdataset, &rdata);
2058 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2059 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2060 if (!zone_check_mx(zone, db, &mx.mx, name))
2062 dns_rdata_reset(&rdata);
2063 result = dns_rdataset_next(&rdataset);
2065 dns_rdataset_disassociate(&rdataset);
2068 if (zone->rdclass != dns_rdataclass_in)
2070 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2071 0, 0, &rdataset, NULL);
2072 if (result != ISC_R_SUCCESS)
2074 result = dns_rdataset_first(&rdataset);
2075 while (result == ISC_R_SUCCESS) {
2076 dns_rdataset_current(&rdataset, &rdata);
2077 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2078 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2079 if (!zone_check_srv(zone, db, &srv.target, name))
2081 dns_rdata_reset(&rdata);
2082 result = dns_rdataset_next(&rdataset);
2084 dns_rdataset_disassociate(&rdataset);
2087 dns_db_detachnode(db, &node);
2088 result = dns_dbiterator_next(dbiterator);
2093 dns_db_detachnode(db, &node);
2094 dns_dbiterator_destroy(&dbiterator);
2100 * OpenSSL verification of RSA keys with exponent 3 is known to be
2101 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2102 * if they are in use.
2105 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2106 dns_dbnode_t *node = NULL;
2107 dns_dbversion_t *version = NULL;
2108 dns_rdata_dnskey_t dnskey;
2109 dns_rdata_t rdata = DNS_RDATA_INIT;
2110 dns_rdataset_t rdataset;
2111 isc_result_t result;
2112 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2113 const char *algorithm;
2115 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2116 if (result != ISC_R_SUCCESS)
2119 dns_db_currentversion(db, &version);
2120 dns_rdataset_init(&rdataset);
2121 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2122 dns_rdatatype_none, 0, &rdataset, NULL);
2123 if (result != ISC_R_SUCCESS)
2126 for (result = dns_rdataset_first(&rdataset);
2127 result == ISC_R_SUCCESS;
2128 result = dns_rdataset_next(&rdataset))
2130 dns_rdataset_current(&rdataset, &rdata);
2131 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2132 INSIST(result == ISC_R_SUCCESS);
2134 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2135 dnskey.algorithm == DST_ALG_RSAMD5) &&
2136 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2137 dnskey.data[1] == 3)
2139 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2141 foundrsa = ISC_TRUE;
2142 algorithm = "RSASHA1";
2145 foundmd5 = ISC_TRUE;
2146 algorithm = "RSAMD5";
2149 dns_zone_log(zone, ISC_LOG_WARNING,
2150 "weak %s (%u) key found "
2151 "(exponent=3)", algorithm,
2153 if (foundrsa && foundmd5)
2156 dns_rdata_reset(&rdata);
2158 dns_rdataset_disassociate(&rdataset);
2162 dns_db_detachnode(db, &node);
2163 if (version != NULL)
2164 dns_db_closeversion(db, &version, ISC_FALSE);
2169 resume_signingwithkey(dns_zone_t *zone) {
2170 dns_dbnode_t *node = NULL;
2171 dns_dbversion_t *version = NULL;
2172 dns_rdata_t rdata = DNS_RDATA_INIT;
2173 dns_rdataset_t rdataset;
2174 isc_result_t result;
2176 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2177 if (result != ISC_R_SUCCESS)
2180 dns_db_currentversion(zone->db, &version);
2181 dns_rdataset_init(&rdataset);
2182 result = dns_db_findrdataset(zone->db, node, version,
2184 dns_rdatatype_none, 0,
2186 if (result != ISC_R_SUCCESS)
2189 for (result = dns_rdataset_first(&rdataset);
2190 result == ISC_R_SUCCESS;
2191 result = dns_rdataset_next(&rdataset))
2193 dns_rdataset_current(&rdataset, &rdata);
2194 if (rdata.length != 5 || rdata.data[4] != 0) {
2195 dns_rdata_reset(&rdata);
2199 result = zone_signwithkey(zone, rdata.data[0],
2200 (rdata.data[1] << 8) | rdata.data[2],
2201 ISC_TF(rdata.data[3]));
2202 if (result != ISC_R_SUCCESS) {
2203 dns_zone_log(zone, ISC_LOG_ERROR,
2204 "zone_signwithkey failed: %s",
2205 dns_result_totext(result));
2207 dns_rdata_reset(&rdata);
2209 dns_rdataset_disassociate(&rdataset);
2213 dns_db_detachnode(zone->db, &node);
2214 if (version != NULL)
2215 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2220 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2221 dns_nsec3chain_t *nsec3chain, *current;
2222 isc_result_t result;
2224 unsigned int options = 0;
2226 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2227 if (nsec3chain == NULL)
2228 return (ISC_R_NOMEMORY);
2230 nsec3chain->magic = 0;
2231 nsec3chain->done = ISC_FALSE;
2232 nsec3chain->db = NULL;
2233 nsec3chain->dbiterator = NULL;
2234 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2235 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2236 nsec3chain->nsec3param.hash = nsec3param->hash;
2237 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2238 nsec3chain->nsec3param.flags = nsec3param->flags;
2239 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2240 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2241 nsec3chain->nsec3param.salt = nsec3chain->salt;
2242 nsec3chain->seen_nsec = ISC_FALSE;
2243 nsec3chain->delete_nsec = ISC_FALSE;
2244 nsec3chain->save_delete_nsec = ISC_FALSE;
2246 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2248 current = ISC_LIST_NEXT(current, link)) {
2249 if (current->db == zone->db &&
2250 current->nsec3param.hash == nsec3param->hash &&
2251 current->nsec3param.iterations == nsec3param->iterations &&
2252 current->nsec3param.salt_length == nsec3param->salt_length
2253 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2254 nsec3param->salt_length))
2255 current->done = ISC_TRUE;
2258 if (zone->db != NULL) {
2259 dns_db_attach(zone->db, &nsec3chain->db);
2260 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2261 options = DNS_DB_NONSEC3;
2262 result = dns_db_createiterator(nsec3chain->db, options,
2263 &nsec3chain->dbiterator);
2264 if (result == ISC_R_SUCCESS)
2265 dns_dbiterator_first(nsec3chain->dbiterator);
2266 if (result == ISC_R_SUCCESS) {
2267 dns_dbiterator_pause(nsec3chain->dbiterator);
2268 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2271 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2273 zone->nsec3chaintime = now;
2274 if (zone->task != NULL)
2275 zone_settimer(zone, &now);
2279 result = ISC_R_NOTFOUND;
2281 if (nsec3chain != NULL) {
2282 if (nsec3chain->db != NULL)
2283 dns_db_detach(&nsec3chain->db);
2284 if (nsec3chain->dbiterator != NULL)
2285 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2286 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2292 resume_addnsec3chain(dns_zone_t *zone) {
2293 dns_dbnode_t *node = NULL;
2294 dns_dbversion_t *version = NULL;
2295 dns_rdata_t rdata = DNS_RDATA_INIT;
2296 dns_rdataset_t rdataset;
2297 isc_result_t result;
2298 dns_rdata_nsec3param_t nsec3param;
2300 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2301 if (result != ISC_R_SUCCESS)
2304 dns_db_currentversion(zone->db, &version);
2305 dns_rdataset_init(&rdataset);
2306 result = dns_db_findrdataset(zone->db, node, version,
2307 dns_rdatatype_nsec3param,
2308 dns_rdatatype_none, 0,
2310 if (result != ISC_R_SUCCESS)
2313 for (result = dns_rdataset_first(&rdataset);
2314 result == ISC_R_SUCCESS;
2315 result = dns_rdataset_next(&rdataset))
2317 dns_rdataset_current(&rdataset, &rdata);
2318 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2319 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2320 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
2321 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
2322 result = zone_addnsec3chain(zone, &nsec3param);
2323 if (result != ISC_R_SUCCESS) {
2324 dns_zone_log(zone, ISC_LOG_ERROR,
2325 "zone_addnsec3chain failed: %s",
2326 dns_result_totext(result));
2329 dns_rdata_reset(&rdata);
2331 dns_rdataset_disassociate(&rdataset);
2335 dns_db_detachnode(zone->db, &node);
2336 if (version != NULL)
2337 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2341 set_resigntime(dns_zone_t *zone) {
2342 dns_rdataset_t rdataset;
2343 dns_fixedname_t fixed;
2344 unsigned int resign;
2345 isc_result_t result;
2346 isc_uint32_t nanosecs;
2348 dns_rdataset_init(&rdataset);
2349 dns_fixedname_init(&fixed);
2350 result = dns_db_getsigningtime(zone->db, &rdataset,
2351 dns_fixedname_name(&fixed));
2352 if (result != ISC_R_SUCCESS) {
2353 isc_time_settoepoch(&zone->resigntime);
2356 resign = rdataset.resign;
2357 dns_rdataset_disassociate(&rdataset);
2358 isc_random_get(&nanosecs);
2359 nanosecs %= 1000000000;
2360 isc_time_set(&zone->resigntime, resign, nanosecs);
2364 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2365 dns_dbnode_t *node = NULL;
2366 dns_rdataset_t rdataset;
2367 dns_dbversion_t *version = NULL;
2368 dns_rdata_nsec3param_t nsec3param;
2369 isc_boolean_t ok = ISC_FALSE;
2370 isc_result_t result;
2371 dns_rdata_t rdata = DNS_RDATA_INIT;
2372 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
2373 zone_isdynamic(zone) : ISC_FALSE;
2375 dns_rdataset_init(&rdataset);
2376 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2377 if (result != ISC_R_SUCCESS) {
2378 dns_zone_log(zone, ISC_LOG_ERROR,
2379 "nsec3param lookup failure: %s",
2380 dns_result_totext(result));
2383 dns_db_currentversion(db, &version);
2385 result = dns_db_findrdataset(db, node, version,
2386 dns_rdatatype_nsec3param,
2387 dns_rdatatype_none, 0, &rdataset, NULL);
2388 if (result == ISC_R_NOTFOUND) {
2389 result = ISC_R_SUCCESS;
2392 if (result != ISC_R_SUCCESS) {
2393 dns_zone_log(zone, ISC_LOG_ERROR,
2394 "nsec3param lookup failure: %s",
2395 dns_result_totext(result));
2400 * For dynamic zones we must support every algorithm so we can
2401 * regenerate all the NSEC3 chains.
2402 * For non-dynamic zones we only need to find a supported algorithm.
2404 for (result = dns_rdataset_first(&rdataset);
2405 result == ISC_R_SUCCESS;
2406 result = dns_rdataset_next(&rdataset))
2408 dns_rdataset_current(&rdataset, &rdata);
2409 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2410 dns_rdata_reset(&rdata);
2411 INSIST(result == ISC_R_SUCCESS);
2412 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
2413 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
2415 dns_zone_log(zone, ISC_LOG_WARNING,
2416 "nsec3 test \"unknown\" hash algorithm found: %u",
2419 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
2421 dns_zone_log(zone, ISC_LOG_ERROR,
2422 "unsupported nsec3 hash algorithm"
2423 " in dynamic zone: %u",
2425 result = DNS_R_BADZONE;
2426 /* Stop second error message. */
2430 dns_zone_log(zone, ISC_LOG_WARNING,
2431 "unsupported nsec3 hash algorithm: %u",
2436 if (result == ISC_R_NOMORE)
2437 result = ISC_R_SUCCESS;
2440 result = DNS_R_BADZONE;
2441 dns_zone_log(zone, ISC_LOG_ERROR,
2442 "no supported nsec3 hash algorithm");
2446 if (dns_rdataset_isassociated(&rdataset))
2447 dns_rdataset_disassociate(&rdataset);
2448 dns_db_closeversion(db, &version, ISC_FALSE);
2449 dns_db_detachnode(db, &node);
2454 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
2455 isc_result_t result)
2457 unsigned int soacount = 0;
2458 unsigned int nscount = 0;
2459 unsigned int errors = 0;
2460 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
2462 isc_boolean_t needdump = ISC_FALSE;
2463 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2464 unsigned int options;
2469 * Initiate zone transfer? We may need a error code that
2470 * indicates that the "permanent" form does not exist.
2471 * XXX better error feedback to log.
2473 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
2474 if (zone->type == dns_zone_slave ||
2475 zone->type == dns_zone_stub) {
2476 if (result == ISC_R_FILENOTFOUND)
2477 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2479 else if (result != DNS_R_NOMASTERFILE)
2480 dns_zone_log(zone, ISC_LOG_ERROR,
2481 "loading from master file %s "
2484 dns_result_totext(result));
2486 dns_zone_log(zone, ISC_LOG_ERROR,
2487 "loading from master file %s failed: %s",
2489 dns_result_totext(result));
2493 dns_zone_log(zone, ISC_LOG_DEBUG(2),
2494 "number of nodes in database: %u",
2495 dns_db_nodecount(db));
2497 if (result == DNS_R_SEENINCLUDE)
2498 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2500 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2503 * Apply update log, if any, on initial load.
2505 if (zone->journal != NULL &&
2506 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
2507 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
2509 if (zone->type == dns_zone_master &&
2510 (zone->update_acl != NULL || zone->ssutable != NULL))
2511 options = DNS_JOURNALOPT_RESIGN;
2514 result = dns_journal_rollforward2(zone->mctx, db, options,
2515 zone->sigresigninginterval,
2517 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
2518 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
2519 result != ISC_R_RANGE) {
2520 dns_zone_log(zone, ISC_LOG_ERROR,
2521 "journal rollforward failed: %s",
2522 dns_result_totext(result));
2525 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
2526 dns_zone_log(zone, ISC_LOG_ERROR,
2527 "journal rollforward failed: "
2528 "journal out of sync with zone");
2531 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2532 "journal rollforward completed "
2534 dns_result_totext(result));
2535 if (result == ISC_R_SUCCESS)
2536 needdump = ISC_TRUE;
2539 zone->loadtime = loadtime;
2541 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded");
2543 * Obtain ns, soa and cname counts for top of zone.
2546 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
2547 &refresh, &retry, &expire, &minimum,
2549 if (result != ISC_R_SUCCESS) {
2550 dns_zone_log(zone, ISC_LOG_ERROR,
2551 "could not find NS and/or SOA records");
2555 * Master / Slave / Stub zones require both NS and SOA records at
2556 * the top of the zone.
2559 switch (zone->type) {
2560 case dns_zone_master:
2561 case dns_zone_slave:
2563 if (soacount != 1) {
2564 dns_zone_log(zone, ISC_LOG_ERROR,
2565 "has %d SOA records", soacount);
2566 result = DNS_R_BADZONE;
2569 dns_zone_log(zone, ISC_LOG_ERROR,
2570 "has no NS records");
2571 result = DNS_R_BADZONE;
2573 if (result != ISC_R_SUCCESS)
2575 if (zone->type == dns_zone_master && errors != 0) {
2576 result = DNS_R_BADZONE;
2579 if (zone->type != dns_zone_stub) {
2580 result = check_nsec3param(zone, db);
2581 if (result != ISC_R_SUCCESS)
2584 if (zone->type == dns_zone_master &&
2585 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
2586 !integrity_checks(zone, db)) {
2587 result = DNS_R_BADZONE;
2591 if (zone->db != NULL) {
2593 * This is checked in zone_replacedb() for slave zones
2594 * as they don't reload from disk.
2596 result = zone_get_from_db(zone, zone->db, NULL, NULL,
2597 &oldserial, NULL, NULL, NULL,
2599 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2600 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
2601 !isc_serial_gt(serial, oldserial)) {
2602 isc_uint32_t serialmin, serialmax;
2604 INSIST(zone->type == dns_zone_master);
2606 serialmin = (oldserial + 1) & 0xffffffffU;
2607 serialmax = (oldserial + 0x7fffffffU) &
2609 dns_zone_log(zone, ISC_LOG_ERROR,
2610 "ixfr-from-differences: "
2611 "new serial (%u) out of range "
2612 "[%u - %u]", serial, serialmin,
2614 result = DNS_R_BADZONE;
2616 } else if (!isc_serial_ge(serial, oldserial))
2617 dns_zone_log(zone, ISC_LOG_ERROR,
2618 "zone serial has gone backwards");
2619 else if (serial == oldserial && !hasinclude)
2620 dns_zone_log(zone, ISC_LOG_ERROR,
2621 "zone serial unchanged. "
2622 "zone may fail to transfer "
2626 if (zone->type == dns_zone_master &&
2627 (zone->update_acl != NULL || zone->ssutable != NULL) &&
2628 zone->sigresigninginterval < (3 * refresh) &&
2629 dns_db_issecure(db))
2631 dns_zone_log(zone, ISC_LOG_WARNING,
2632 "sig-re-signing-interval less than "
2636 zone->refresh = RANGE(refresh,
2637 zone->minrefresh, zone->maxrefresh);
2638 zone->retry = RANGE(retry,
2639 zone->minretry, zone->maxretry);
2640 zone->expire = RANGE(expire, zone->refresh + zone->retry,
2642 zone->minimum = minimum;
2643 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
2645 if (zone->type == dns_zone_slave ||
2646 zone->type == dns_zone_stub) {
2650 result = isc_file_getmodtime(zone->journal, &t);
2651 if (result != ISC_R_SUCCESS)
2652 result = isc_file_getmodtime(zone->masterfile,
2654 if (result == ISC_R_SUCCESS)
2655 DNS_ZONE_TIME_ADD(&t, zone->expire,
2658 DNS_ZONE_TIME_ADD(&now, zone->retry,
2661 delay = isc_random_jitter(zone->retry,
2662 (zone->retry * 3) / 4);
2663 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
2664 if (isc_time_compare(&zone->refreshtime,
2665 &zone->expiretime) >= 0)
2666 zone->refreshtime = now;
2670 UNEXPECTED_ERROR(__FILE__, __LINE__,
2671 "unexpected zone type %d", zone->type);
2672 result = ISC_R_UNEXPECTED;
2677 * Check for weak DNSKEY's.
2679 if (zone->type == dns_zone_master)
2680 zone_check_dnskeys(zone, db);
2683 /* destroy notification example. */
2685 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
2686 DNS_EVENT_DBDESTROYED,
2687 dns_zonemgr_dbdestroyed,
2689 sizeof(isc_event_t));
2690 dns_db_ondestroy(db, zone->task, &e);
2694 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2695 if (zone->db != NULL) {
2696 result = zone_replacedb(zone, db, ISC_FALSE);
2697 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2698 if (result != ISC_R_SUCCESS)
2701 zone_attachdb(zone, db);
2702 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2703 DNS_ZONE_SETFLAG(zone,
2704 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
2706 result = ISC_R_SUCCESS;
2708 zone_needdump(zone, DNS_DUMP_DELAY);
2709 if (zone->task != NULL) {
2710 if (zone->type == dns_zone_master) {
2711 set_resigntime(zone);
2712 resume_signingwithkey(zone);
2713 resume_addnsec3chain(zone);
2715 zone_settimer(zone, &now);
2718 if (! dns_db_ispersistent(db))
2719 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
2720 dns_db_issecure(db) ? " (signed)" : "");
2725 if (zone->type == dns_zone_slave ||
2726 zone->type == dns_zone_stub) {
2727 if (zone->journal != NULL)
2728 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
2729 if (zone->masterfile != NULL)
2730 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
2732 /* Mark the zone for immediate refresh. */
2733 zone->refreshtime = now;
2734 if (zone->task != NULL)
2735 zone_settimer(zone, &now);
2736 result = ISC_R_SUCCESS;
2737 } else if (zone->type == dns_zone_master)
2738 dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
2742 static isc_boolean_t
2743 exit_check(dns_zone_t *zone) {
2745 REQUIRE(LOCKED_ZONE(zone));
2747 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
2751 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2753 INSIST(isc_refcount_current(&zone->erefs) == 0);
2759 static isc_boolean_t
2760 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
2761 isc_result_t result;
2762 char namebuf[DNS_NAME_FORMATSIZE];
2763 char altbuf[DNS_NAME_FORMATSIZE];
2764 dns_fixedname_t fixed;
2765 dns_name_t *foundname;
2768 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
2771 if (zone->type == dns_zone_master)
2772 level = ISC_LOG_ERROR;
2774 level = ISC_LOG_WARNING;
2776 dns_fixedname_init(&fixed);
2777 foundname = dns_fixedname_name(&fixed);
2779 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2780 0, 0, NULL, foundname, NULL, NULL);
2781 if (result == ISC_R_SUCCESS)
2784 if (result == DNS_R_NXRRSET) {
2785 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2786 0, 0, NULL, foundname, NULL, NULL);
2787 if (result == ISC_R_SUCCESS)
2791 dns_name_format(name, namebuf, sizeof namebuf);
2792 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2793 result == DNS_R_EMPTYNAME) {
2794 dns_zone_log(zone, level,
2795 "NS '%s' has no address records (A or AAAA)",
2797 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2801 if (result == DNS_R_CNAME) {
2802 dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
2804 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2808 if (result == DNS_R_DNAME) {
2809 dns_name_format(foundname, altbuf, sizeof altbuf);
2810 dns_zone_log(zone, level,
2811 "NS '%s' is below a DNAME '%s' (illegal)",
2813 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2821 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
2822 dns_dbversion_t *version, unsigned int *nscount,
2823 unsigned int *errors)
2825 isc_result_t result;
2826 unsigned int count = 0;
2827 unsigned int ecount = 0;
2828 dns_rdataset_t rdataset;
2832 dns_rdataset_init(&rdataset);
2833 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
2834 dns_rdatatype_none, 0, &rdataset, NULL);
2835 if (result == ISC_R_NOTFOUND)
2837 if (result != ISC_R_SUCCESS)
2838 goto invalidate_rdataset;
2840 result = dns_rdataset_first(&rdataset);
2841 while (result == ISC_R_SUCCESS) {
2842 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
2843 (zone->type == dns_zone_master ||
2844 zone->type == dns_zone_slave)) {
2845 dns_rdata_init(&rdata);
2846 dns_rdataset_current(&rdataset, &rdata);
2847 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2848 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2849 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
2850 !zone_check_ns(zone, db, &ns.name))
2854 result = dns_rdataset_next(&rdataset);
2856 dns_rdataset_disassociate(&rdataset);
2859 if (nscount != NULL)
2864 result = ISC_R_SUCCESS;
2866 invalidate_rdataset:
2867 dns_rdataset_invalidate(&rdataset);
2873 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
2874 unsigned int *soacount,
2875 isc_uint32_t *serial, isc_uint32_t *refresh,
2876 isc_uint32_t *retry, isc_uint32_t *expire,
2877 isc_uint32_t *minimum)
2879 isc_result_t result;
2881 dns_rdataset_t rdataset;
2882 dns_rdata_t rdata = DNS_RDATA_INIT;
2883 dns_rdata_soa_t soa;
2885 dns_rdataset_init(&rdataset);
2886 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
2887 dns_rdatatype_none, 0, &rdataset, NULL);
2888 if (result == ISC_R_NOTFOUND) {
2889 if (soacount != NULL)
2893 if (refresh != NULL)
2899 if (minimum != NULL)
2901 result = ISC_R_SUCCESS;
2902 goto invalidate_rdataset;
2904 if (result != ISC_R_SUCCESS)
2905 goto invalidate_rdataset;
2908 result = dns_rdataset_first(&rdataset);
2909 while (result == ISC_R_SUCCESS) {
2910 dns_rdata_init(&rdata);
2911 dns_rdataset_current(&rdataset, &rdata);
2914 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2915 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2918 result = dns_rdataset_next(&rdataset);
2919 dns_rdata_reset(&rdata);
2921 dns_rdataset_disassociate(&rdataset);
2923 if (soacount != NULL)
2928 *serial = soa.serial;
2929 if (refresh != NULL)
2930 *refresh = soa.refresh;
2934 *expire = soa.expire;
2935 if (minimum != NULL)
2936 *minimum = soa.minimum;
2939 result = ISC_R_SUCCESS;
2941 invalidate_rdataset:
2942 dns_rdataset_invalidate(&rdataset);
2948 * zone must be locked.
2951 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
2952 unsigned int *soacount, isc_uint32_t *serial,
2953 isc_uint32_t *refresh, isc_uint32_t *retry,
2954 isc_uint32_t *expire, isc_uint32_t *minimum,
2955 unsigned int *errors)
2957 dns_dbversion_t *version;
2958 isc_result_t result;
2959 isc_result_t answer = ISC_R_SUCCESS;
2962 REQUIRE(db != NULL);
2963 REQUIRE(zone != NULL);
2966 dns_db_currentversion(db, &version);
2969 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2970 if (result != ISC_R_SUCCESS) {
2975 if (nscount != NULL || errors != NULL) {
2976 result = zone_count_ns_rr(zone, db, node, version,
2978 if (result != ISC_R_SUCCESS)
2982 if (soacount != NULL || serial != NULL || refresh != NULL
2983 || retry != NULL || expire != NULL || minimum != NULL) {
2984 result = zone_load_soa_rr(db, node, version, soacount,
2985 serial, refresh, retry, expire,
2987 if (result != ISC_R_SUCCESS)
2991 dns_db_detachnode(db, &node);
2993 dns_db_closeversion(db, &version, ISC_FALSE);
2999 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
3000 REQUIRE(DNS_ZONE_VALID(source));
3001 REQUIRE(target != NULL && *target == NULL);
3002 isc_refcount_increment(&source->erefs, NULL);
3007 dns_zone_detach(dns_zone_t **zonep) {
3010 isc_boolean_t free_now = ISC_FALSE;
3012 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3016 isc_refcount_decrement(&zone->erefs, &refs);
3021 * We just detached the last external reference.
3023 if (zone->task != NULL) {
3025 * This zone is being managed. Post
3026 * its control event and let it clean
3027 * up synchronously in the context of
3030 isc_event_t *ev = &zone->ctlevent;
3031 isc_task_send(zone->task, &ev);
3034 * This zone is not being managed; it has
3035 * no task and can have no outstanding
3036 * events. Free it immediately.
3039 * Unmanaged zones should not have non-null views;
3040 * we have no way of detaching from the view here
3041 * without causing deadlock because this code is called
3042 * with the view already locked.
3044 INSIST(zone->view == NULL);
3045 free_now = ISC_TRUE;
3055 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3056 REQUIRE(DNS_ZONE_VALID(source));
3057 REQUIRE(target != NULL && *target == NULL);
3059 zone_iattach(source, target);
3060 UNLOCK_ZONE(source);
3064 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3067 * 'source' locked by caller.
3069 REQUIRE(LOCKED_ZONE(source));
3070 REQUIRE(DNS_ZONE_VALID(source));
3071 REQUIRE(target != NULL && *target == NULL);
3072 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
3074 INSIST(source->irefs != 0);
3079 zone_idetach(dns_zone_t **zonep) {
3083 * 'zone' locked by caller.
3085 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3087 REQUIRE(LOCKED_ZONE(*zonep));
3090 INSIST(zone->irefs > 0);
3092 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
3096 dns_zone_idetach(dns_zone_t **zonep) {
3098 isc_boolean_t free_needed;
3100 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3105 INSIST(zone->irefs > 0);
3107 free_needed = exit_check(zone);
3114 dns_zone_getmctx(dns_zone_t *zone) {
3115 REQUIRE(DNS_ZONE_VALID(zone));
3117 return (zone->mctx);
3121 dns_zone_getmgr(dns_zone_t *zone) {
3122 REQUIRE(DNS_ZONE_VALID(zone));
3124 return (zone->zmgr);
3128 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
3129 REQUIRE(DNS_ZONE_VALID(zone));
3133 DNS_ZONE_SETFLAG(zone, flags);
3135 DNS_ZONE_CLRFLAG(zone, flags);
3140 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
3142 REQUIRE(DNS_ZONE_VALID(zone));
3146 zone->options |= option;
3148 zone->options &= ~option;
3153 dns_zone_getoptions(dns_zone_t *zone) {
3155 REQUIRE(DNS_ZONE_VALID(zone));
3157 return (zone->options);
3161 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3162 REQUIRE(DNS_ZONE_VALID(zone));
3165 zone->xfrsource4 = *xfrsource;
3168 return (ISC_R_SUCCESS);
3172 dns_zone_getxfrsource4(dns_zone_t *zone) {
3173 REQUIRE(DNS_ZONE_VALID(zone));
3174 return (&zone->xfrsource4);
3178 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3179 REQUIRE(DNS_ZONE_VALID(zone));
3182 zone->xfrsource6 = *xfrsource;
3185 return (ISC_R_SUCCESS);
3189 dns_zone_getxfrsource6(dns_zone_t *zone) {
3190 REQUIRE(DNS_ZONE_VALID(zone));
3191 return (&zone->xfrsource6);
3195 dns_zone_setaltxfrsource4(dns_zone_t *zone,
3196 const isc_sockaddr_t *altxfrsource)
3198 REQUIRE(DNS_ZONE_VALID(zone));
3201 zone->altxfrsource4 = *altxfrsource;
3204 return (ISC_R_SUCCESS);
3208 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
3209 REQUIRE(DNS_ZONE_VALID(zone));
3210 return (&zone->altxfrsource4);
3214 dns_zone_setaltxfrsource6(dns_zone_t *zone,
3215 const isc_sockaddr_t *altxfrsource)
3217 REQUIRE(DNS_ZONE_VALID(zone));
3220 zone->altxfrsource6 = *altxfrsource;
3223 return (ISC_R_SUCCESS);
3227 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
3228 REQUIRE(DNS_ZONE_VALID(zone));
3229 return (&zone->altxfrsource6);
3233 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3234 REQUIRE(DNS_ZONE_VALID(zone));
3237 zone->notifysrc4 = *notifysrc;
3240 return (ISC_R_SUCCESS);
3244 dns_zone_getnotifysrc4(dns_zone_t *zone) {
3245 REQUIRE(DNS_ZONE_VALID(zone));
3246 return (&zone->notifysrc4);
3250 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3251 REQUIRE(DNS_ZONE_VALID(zone));
3254 zone->notifysrc6 = *notifysrc;
3257 return (ISC_R_SUCCESS);
3261 dns_zone_getnotifysrc6(dns_zone_t *zone) {
3262 REQUIRE(DNS_ZONE_VALID(zone));
3263 return (&zone->notifysrc6);
3267 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
3270 isc_sockaddr_t *new;
3272 REQUIRE(DNS_ZONE_VALID(zone));
3273 REQUIRE(count == 0 || notify != NULL);
3276 if (zone->notify != NULL) {
3277 isc_mem_put(zone->mctx, zone->notify,
3278 zone->notifycnt * sizeof(*new));
3279 zone->notify = NULL;
3280 zone->notifycnt = 0;
3283 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3286 return (ISC_R_NOMEMORY);
3288 memcpy(new, notify, count * sizeof(*new));
3290 zone->notifycnt = count;
3293 return (ISC_R_SUCCESS);
3297 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
3300 isc_result_t result;
3302 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
3306 static isc_boolean_t
3307 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
3312 for (i = 0; i < count; i++)
3313 if (!isc_sockaddr_equal(&old[i], &new[i]))
3318 static isc_boolean_t
3319 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
3322 if (old == NULL && new == NULL)
3324 if (old == NULL || new == NULL)
3327 for (i = 0; i < count; i++) {
3328 if (old[i] == NULL && new[i] == NULL)
3330 if (old[i] == NULL || new[i] == NULL ||
3331 !dns_name_equal(old[i], new[i]))
3338 dns_zone_setmasterswithkeys(dns_zone_t *zone,
3339 const isc_sockaddr_t *masters,
3340 dns_name_t **keynames,
3343 isc_sockaddr_t *new;
3344 isc_result_t result = ISC_R_SUCCESS;
3345 dns_name_t **newname;
3346 isc_boolean_t *newok;
3349 REQUIRE(DNS_ZONE_VALID(zone));
3350 REQUIRE(count == 0 || masters != NULL);
3351 if (keynames != NULL) {
3352 REQUIRE(count != 0);
3357 * The refresh code assumes that 'masters' wouldn't change under it.
3358 * If it will change then kill off any current refresh in progress
3359 * and update the masters info. If it won't change then we can just
3362 if (count != zone->masterscnt ||
3363 !same_masters(zone->masters, masters, count) ||
3364 !same_keynames(zone->masterkeynames, keynames, count)) {
3365 if (zone->request != NULL)
3366 dns_request_cancel(zone->request);
3369 if (zone->masters != NULL) {
3370 isc_mem_put(zone->mctx, zone->masters,
3371 zone->masterscnt * sizeof(*new));
3372 zone->masters = NULL;
3374 if (zone->masterkeynames != NULL) {
3375 for (i = 0; i < zone->masterscnt; i++) {
3376 if (zone->masterkeynames[i] != NULL) {
3377 dns_name_free(zone->masterkeynames[i],
3379 isc_mem_put(zone->mctx,
3380 zone->masterkeynames[i],
3381 sizeof(dns_name_t));
3382 zone->masterkeynames[i] = NULL;
3385 isc_mem_put(zone->mctx, zone->masterkeynames,
3386 zone->masterscnt * sizeof(dns_name_t *));
3387 zone->masterkeynames = NULL;
3389 if (zone->mastersok != NULL) {
3390 isc_mem_put(zone->mctx, zone->mastersok,
3391 zone->masterscnt * sizeof(isc_boolean_t));
3392 zone->mastersok = NULL;
3394 zone->masterscnt = 0;
3396 * If count == 0, don't allocate any space for masters, mastersok or
3397 * keynames so internally, those pointers are NULL if count == 0
3403 * masters must contain count elements!
3405 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3407 result = ISC_R_NOMEMORY;
3410 memcpy(new, masters, count * sizeof(*new));
3413 * Similarly for mastersok.
3415 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
3416 if (newok == NULL) {
3417 result = ISC_R_NOMEMORY;
3418 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3421 for (i = 0; i < count; i++)
3422 newok[i] = ISC_FALSE;
3425 * if keynames is non-NULL, it must contain count elements!
3428 if (keynames != NULL) {
3429 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
3430 if (newname == NULL) {
3431 result = ISC_R_NOMEMORY;
3432 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3433 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
3436 for (i = 0; i < count; i++)
3438 for (i = 0; i < count; i++) {
3439 if (keynames[i] != NULL) {
3440 newname[i] = isc_mem_get(zone->mctx,
3441 sizeof(dns_name_t));
3442 if (newname[i] == NULL)
3444 dns_name_init(newname[i], NULL);
3445 result = dns_name_dup(keynames[i], zone->mctx,
3447 if (result != ISC_R_SUCCESS) {
3449 for (i = 0; i < count; i++)
3450 if (newname[i] != NULL)
3454 isc_mem_put(zone->mctx, new,
3455 count * sizeof(*new));
3456 isc_mem_put(zone->mctx, newok,
3457 count * sizeof(*newok));
3458 isc_mem_put(zone->mctx, newname,
3459 count * sizeof(*newname));
3467 * Everything is ok so attach to the zone.
3469 zone->masters = new;
3470 zone->mastersok = newok;
3471 zone->masterkeynames = newname;
3472 zone->masterscnt = count;
3473 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
3481 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
3482 isc_result_t result = ISC_R_SUCCESS;
3484 REQUIRE(DNS_ZONE_VALID(zone));
3486 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3487 if (zone->db == NULL)
3488 result = DNS_R_NOTLOADED;
3490 dns_db_attach(zone->db, dpb);
3491 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3497 * Co-ordinates the starting of routine jobs.
3501 dns_zone_maintenance(dns_zone_t *zone) {
3502 const char me[] = "dns_zone_maintenance";
3505 REQUIRE(DNS_ZONE_VALID(zone));
3510 zone_settimer(zone, &now);
3514 static inline isc_boolean_t
3515 was_dumping(dns_zone_t *zone) {
3516 isc_boolean_t dumping;
3518 REQUIRE(LOCKED_ZONE(zone));
3520 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
3521 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3523 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3524 isc_time_settoepoch(&zone->dumptime);
3529 #define MAXZONEKEYS 10
3532 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3535 dns_diff_t temp_diff;
3536 isc_result_t result;
3539 * Create a singleton diff.
3541 dns_diff_init(diff->mctx, &temp_diff);
3542 temp_diff.resign = diff->resign;
3543 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3546 * Apply it to the database.
3548 result = dns_diff_apply(&temp_diff, db, ver);
3549 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3550 if (result != ISC_R_SUCCESS) {
3551 dns_difftuple_free(tuple);
3556 * Merge it into the current pending journal entry.
3558 dns_diff_appendminimal(diff, tuple);
3561 * Do not clear temp_diff.
3563 return (ISC_R_SUCCESS);
3567 increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
3568 dns_diff_t *diff, isc_mem_t *mctx)
3570 dns_difftuple_t *deltuple = NULL;
3571 dns_difftuple_t *addtuple = NULL;
3572 isc_uint32_t serial;
3573 isc_result_t result;
3575 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3576 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3577 addtuple->op = DNS_DIFFOP_ADD;
3579 serial = dns_soa_getserial(&addtuple->rdata);
3582 serial = (serial + 1) & 0xFFFFFFFF;
3586 dns_soa_setserial(serial, &addtuple->rdata);
3587 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3588 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3589 result = ISC_R_SUCCESS;
3592 if (addtuple != NULL)
3593 dns_difftuple_free(&addtuple);
3594 if (deltuple != NULL)
3595 dns_difftuple_free(&deltuple);
3600 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3601 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3604 dns_difftuple_t *tuple = NULL;
3605 isc_result_t result;
3606 result = dns_difftuple_create(diff->mctx, op,
3607 name, ttl, rdata, &tuple);
3608 if (result != ISC_R_SUCCESS)
3610 return (do_one_tuple(&tuple, db, ver, diff));
3613 static isc_boolean_t
3614 ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) {
3615 isc_boolean_t ret = ISC_FALSE;
3616 isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE;
3617 isc_result_t result;
3618 dns_dbnode_t *node = NULL;
3619 dns_rdataset_t rdataset;
3620 dns_rdata_t rdata = DNS_RDATA_INIT;
3621 dns_rdata_dnskey_t dnskey;
3623 dns_rdataset_init(&rdataset);
3624 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3625 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
3627 CHECK(dns_rdataset_first(&rdataset));
3628 while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) {
3629 dns_rdataset_current(&rdataset, &rdata);
3630 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3631 if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
3632 == DNS_KEYOWNER_ZONE) {
3633 if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0)
3634 have_ksk = ISC_TRUE;
3636 have_nonksk = ISC_TRUE;
3638 dns_rdata_reset(&rdata);
3639 result = dns_rdataset_next(&rdataset);
3641 if (have_ksk && have_nonksk)
3644 if (dns_rdataset_isassociated(&rdataset))
3645 dns_rdataset_disassociate(&rdataset);
3647 dns_db_detachnode(db, &node);
3652 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3653 isc_mem_t *mctx, unsigned int maxkeys,
3654 dst_key_t **keys, unsigned int *nkeys)
3656 isc_result_t result;
3657 dns_dbnode_t *node = NULL;
3658 const char *directory = dns_zone_getkeydirectory(zone);
3659 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3660 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
3661 directory, mctx, maxkeys, keys,
3663 if (result == ISC_R_NOTFOUND)
3664 result = ISC_R_SUCCESS;
3667 dns_db_detachnode(db, &node);
3672 offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
3673 dns_ttl_t ttl, dns_rdata_t *rdata)
3675 isc_result_t result;
3677 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
3678 return (ISC_R_SUCCESS);
3679 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
3681 if (result != ISC_R_SUCCESS)
3683 rdata->flags |= DNS_RDATA_OFFLINE;
3684 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3690 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
3694 zone->key_expiry = when;
3696 dns_zone_log(zone, ISC_LOG_ERROR,
3697 "DNSKEY RRSIG(s) have expired");
3698 isc_time_settoepoch(&zone->keywarntime);
3699 } else if (when < now + 7 * 24 * 3600) {
3700 dns_zone_log(zone, ISC_LOG_WARNING,
3701 "DNSKEY RRSIG(s) will expire at %u",
3702 when); /* XXXMPA convert to date. */
3704 delta--; /* loop prevention */
3705 delta /= 24 * 3600; /* to whole days */
3706 delta *= 24 * 3600; /* to seconds */
3707 isc_time_set(&zone->keywarntime, when - delta, 0);
3709 dns_zone_log(zone, ISC_LOG_NOTICE, /* XXMPA ISC_LOG_DEBUG(1) */
3710 "setting keywarntime to %u - 7 days",
3711 when); /* XXXMPA convert to date. */
3712 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
3717 * Delete expired RRsigs and any RRsigs we are about to re-sign.
3718 * See also update.c:del_keysigs().
3721 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3722 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3723 unsigned int nkeys, isc_stdtime_t now)
3725 isc_result_t result;
3726 dns_dbnode_t *node = NULL;
3727 dns_rdataset_t rdataset;
3728 dns_rdata_t rdata = DNS_RDATA_INIT;
3730 dns_rdata_rrsig_t rrsig;
3731 isc_boolean_t found;
3732 isc_stdtime_t warn = 0, maybe = 0;
3734 dns_rdataset_init(&rdataset);
3736 if (type == dns_rdatatype_nsec3)
3737 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3739 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3740 if (result == ISC_R_NOTFOUND)
3741 return (ISC_R_SUCCESS);
3742 if (result != ISC_R_SUCCESS)
3744 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
3745 (isc_stdtime_t) 0, &rdataset, NULL);
3746 dns_db_detachnode(db, &node);
3748 if (result == ISC_R_NOTFOUND)
3749 return (ISC_R_SUCCESS);
3750 if (result != ISC_R_SUCCESS)
3753 for (result = dns_rdataset_first(&rdataset);
3754 result == ISC_R_SUCCESS;
3755 result = dns_rdataset_next(&rdataset)) {
3756 dns_rdataset_current(&rdataset, &rdata);
3757 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
3758 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3760 if (type != dns_rdatatype_dnskey) {
3761 result = update_one_rr(db, ver, diff,
3762 DNS_DIFFOP_DEL, name,
3763 rdataset.ttl, &rdata);
3764 dns_rdata_reset(&rdata);
3765 if (result != ISC_R_SUCCESS)
3771 * RRSIG(DNSKEY) requires special processing.
3774 for (i = 0; i < nkeys; i++) {
3775 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
3776 rrsig.keyid == dst_key_id(keys[i])) {
3779 * Mark offline RRSIG(DNSKEY).
3780 * We want the earliest offline expire time
3781 * iff there is a new offline signature.
3783 if (!dst_key_isprivate(keys[i])) {
3785 warn > rrsig.timeexpire)
3786 warn = rrsig.timeexpire;
3787 if (rdata.flags & DNS_RDATA_OFFLINE) {
3789 maybe > rrsig.timeexpire)
3797 warn > rrsig.timeexpire)
3798 warn = rrsig.timeexpire;
3799 result = offline(db, ver, diff, name,
3800 rdataset.ttl, &rdata);
3803 result = update_one_rr(db, ver, diff,
3811 * If there is not a matching DNSKEY then
3815 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3816 name, rdataset.ttl, &rdata);
3817 dns_rdata_reset(&rdata);
3818 if (result != ISC_R_SUCCESS)
3821 dns_rdataset_disassociate(&rdataset);
3822 if (result == ISC_R_NOMORE)
3823 result = ISC_R_SUCCESS;
3825 set_key_expiry_warning(zone, warn, now);
3828 dns_db_detachnode(db, &node);
3833 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3834 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3835 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
3836 isc_stdtime_t expire, isc_boolean_t check_ksk)
3838 isc_result_t result;
3839 dns_dbnode_t *node = NULL;
3840 dns_rdataset_t rdataset;
3841 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
3842 unsigned char data[1024]; /* XXX */
3843 isc_buffer_t buffer;
3846 dns_rdataset_init(&rdataset);
3847 isc_buffer_init(&buffer, data, sizeof(data));
3849 if (type == dns_rdatatype_nsec3)
3850 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3852 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3853 if (result == ISC_R_NOTFOUND)
3854 return (ISC_R_SUCCESS);
3855 if (result != ISC_R_SUCCESS)
3857 result = dns_db_findrdataset(db, node, ver, type, 0,
3858 (isc_stdtime_t) 0, &rdataset, NULL);
3859 dns_db_detachnode(db, &node);
3860 if (result == ISC_R_NOTFOUND)
3861 return (ISC_R_SUCCESS);
3862 if (result != ISC_R_SUCCESS)
3865 for (i = 0; i < nkeys; i++) {
3866 if (check_ksk && type != dns_rdatatype_dnskey &&
3867 (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0)
3869 if (!dst_key_isprivate(keys[i]))
3871 /* Calculate the signature, creating a RRSIG RDATA. */
3872 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
3873 &inception, &expire,
3874 mctx, &buffer, &sig_rdata));
3875 /* Update the database and journal with the RRSIG. */
3876 /* XXX inefficient - will cause dataset merging */
3877 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3878 name, rdataset.ttl, &sig_rdata));
3879 dns_rdata_reset(&sig_rdata);
3883 if (dns_rdataset_isassociated(&rdataset))
3884 dns_rdataset_disassociate(&rdataset);
3886 dns_db_detachnode(db, &node);
3891 zone_resigninc(dns_zone_t *zone) {
3892 const char *journalfile;
3893 dns_db_t *db = NULL;
3894 dns_dbversion_t *version = NULL;
3895 dns_diff_t sig_diff;
3896 dns_fixedname_t fixed;
3898 dns_rdataset_t rdataset;
3899 dns_rdatatype_t covers;
3900 dst_key_t *zone_keys[MAXZONEKEYS];
3901 isc_boolean_t check_ksk;
3902 isc_result_t result;
3903 isc_stdtime_t now, inception, soaexpire, expire, stop;
3904 isc_uint32_t jitter;
3906 unsigned int nkeys = 0;
3907 unsigned int resign;
3909 dns_rdataset_init(&rdataset);
3910 dns_fixedname_init(&fixed);
3911 dns_diff_init(zone->mctx, &sig_diff);
3912 sig_diff.resign = zone->sigresigninginterval;
3915 * Updates are disabled. Pause for 5 minutes.
3917 if (zone->update_disabled) {
3918 result = ISC_R_FAILURE;
3922 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3923 dns_db_attach(zone->db, &db);
3924 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3926 result = dns_db_newversion(db, &version);
3927 if (result != ISC_R_SUCCESS) {
3928 dns_zone_log(zone, ISC_LOG_ERROR,
3929 "zone_resigninc:dns_db_newversion -> %s\n",
3930 dns_result_totext(result));
3934 result = find_zone_keys(zone, db, version, zone->mctx, MAXZONEKEYS,
3936 if (result != ISC_R_SUCCESS) {
3937 dns_zone_log(zone, ISC_LOG_ERROR,
3938 "zone_resigninc:find_zone_keys -> %s\n",
3939 dns_result_totext(result));
3943 isc_stdtime_get(&now);
3944 inception = now - 3600; /* Allow for clock skew. */
3945 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
3947 * Spread out signatures over time if they happen to be
3948 * clumped. We don't do this for each add_sigs() call as
3949 * we still want some clustering to occur.
3951 isc_random_get(&jitter);
3952 expire = soaexpire - jitter % 3600;
3955 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
3957 check_ksk = ksk_sanity(db, version);
3959 name = dns_fixedname_name(&fixed);
3960 result = dns_db_getsigningtime(db, &rdataset, name);
3961 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
3962 dns_zone_log(zone, ISC_LOG_ERROR,
3963 "zone_resigninc:dns_db_getsigningtime -> %s\n",
3964 dns_result_totext(result));
3968 while (result == ISC_R_SUCCESS) {
3969 resign = rdataset.resign;
3970 covers = rdataset.covers;
3972 * Stop if we hit the SOA as that means we have walked the
3973 * entire zone. The SOA record should always be the most
3976 /* XXXMPA increase number of RRsets signed pre call */
3977 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
3980 * Ensure that we don't loop resigning the SOA.
3982 if (covers == dns_rdatatype_soa)
3983 dns_db_resigned(db, &rdataset, version);
3984 dns_rdataset_disassociate(&rdataset);
3988 dns_db_resigned(db, &rdataset, version);
3989 dns_rdataset_disassociate(&rdataset);
3991 result = del_sigs(zone, db, version, name, covers, &sig_diff,
3992 zone_keys, nkeys, now);
3993 if (result != ISC_R_SUCCESS) {
3994 dns_zone_log(zone, ISC_LOG_ERROR,
3995 "zone_resigninc:del_sigs -> %s\n",
3996 dns_result_totext(result));
3999 result = add_sigs(db, version, name, covers, &sig_diff,
4000 zone_keys, nkeys, zone->mctx, inception,
4002 if (result != ISC_R_SUCCESS) {
4003 dns_zone_log(zone, ISC_LOG_ERROR,
4004 "zone_resigninc:add_sigs -> %s\n",
4005 dns_result_totext(result));
4008 result = dns_db_getsigningtime(db, &rdataset,
4009 dns_fixedname_name(&fixed));
4010 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
4011 result = ISC_R_SUCCESS;
4014 if (result != ISC_R_SUCCESS)
4015 dns_zone_log(zone, ISC_LOG_ERROR,
4016 "zone_resigninc:dns_db_getsigningtime -> %s\n",
4017 dns_result_totext(result));
4020 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
4023 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
4024 &sig_diff, zone_keys, nkeys, now);
4025 if (result != ISC_R_SUCCESS) {
4026 dns_zone_log(zone, ISC_LOG_ERROR,
4027 "zone_resigninc:del_sigs -> %s\n",
4028 dns_result_totext(result));
4032 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
4033 if (result != ISC_R_SUCCESS) {
4034 dns_zone_log(zone, ISC_LOG_ERROR,
4035 "zone_resigninc:increment_soa_serial -> %s\n",
4036 dns_result_totext(result));
4041 * Generate maximum life time signatures so that the above loop
4042 * termination is sensible.
4044 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
4045 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
4046 soaexpire, check_ksk);
4047 if (result != ISC_R_SUCCESS) {
4048 dns_zone_log(zone, ISC_LOG_ERROR,
4049 "zone_resigninc:add_sigs -> %s\n",
4050 dns_result_totext(result));
4054 journalfile = dns_zone_getjournal(zone);
4055 if (journalfile != NULL) {
4056 dns_journal_t *journal = NULL;
4057 result = dns_journal_open(zone->mctx, journalfile,
4058 ISC_TRUE, &journal);
4059 if (result != ISC_R_SUCCESS) {
4060 dns_zone_log(zone, ISC_LOG_ERROR,
4061 "zone_resigninc:dns_journal_open -> %s\n",
4062 dns_result_totext(result));
4066 result = dns_journal_write_transaction(journal, &sig_diff);
4067 dns_journal_destroy(&journal);
4068 if (result != ISC_R_SUCCESS) {
4069 dns_zone_log(zone, ISC_LOG_ERROR,
4070 "zone_resigninc:dns_journal_write_transaction -> %s\n",
4071 dns_result_totext(result));
4077 * Everything has succeeded. Commit the changes.
4079 dns_db_closeversion(db, &version, ISC_TRUE);
4082 dns_diff_clear(&sig_diff);
4083 for (i = 0; i < nkeys; i++)
4084 dst_key_free(&zone_keys[i]);
4085 if (version != NULL) {
4086 dns_db_closeversion(zone->db, &version, ISC_FALSE);
4088 } else if (db != NULL)
4090 if (result == ISC_R_SUCCESS) {
4091 set_resigntime(zone);
4093 zone_needdump(zone, DNS_DUMP_DELAY);
4094 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
4098 * Something failed. Retry in 5 minutes.
4100 isc_interval_t ival;
4101 isc_interval_set(&ival, 300, 0);
4102 isc_time_nowplusinterval(&zone->resigntime, &ival);
4107 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
4108 dns_name_t *newname, isc_boolean_t bottom)
4110 isc_result_t result;
4111 dns_dbiterator_t *dbit = NULL;
4112 dns_rdatasetiter_t *rdsit = NULL;
4113 dns_dbnode_t *node = NULL;
4115 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
4116 CHECK(dns_dbiterator_seek(dbit, oldname));
4118 result = dns_dbiterator_next(dbit);
4119 if (result == ISC_R_NOMORE)
4120 CHECK(dns_dbiterator_first(dbit));
4121 CHECK(dns_dbiterator_current(dbit, &node, newname));
4122 if (bottom && dns_name_issubdomain(newname, oldname) &&
4123 !dns_name_equal(newname, oldname)) {
4124 dns_db_detachnode(db, &node);
4128 * Is this node empty?
4130 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
4131 result = dns_rdatasetiter_first(rdsit);
4132 dns_db_detachnode(db, &node);
4133 dns_rdatasetiter_destroy(&rdsit);
4134 if (result != ISC_R_NOMORE)
4139 dns_db_detachnode(db, &node);
4141 dns_dbiterator_destroy(&dbit);
4146 set_bit(unsigned char *array, unsigned int index) {
4147 unsigned int shift, mask;
4149 shift = 7 - (index % 8);
4152 array[index / 8] |= mask;
4155 static isc_boolean_t
4156 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4157 dns_rdatatype_t type, dst_key_t *key)
4159 isc_result_t result;
4160 dns_rdataset_t rdataset;
4161 dns_rdata_t rdata = DNS_RDATA_INIT;
4162 dns_rdata_rrsig_t rrsig;
4164 dns_rdataset_init(&rdataset);
4165 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
4166 type, 0, &rdataset, NULL);
4167 if (result != ISC_R_SUCCESS)
4169 for (result = dns_rdataset_first(&rdataset);
4170 result == ISC_R_SUCCESS;
4171 result = dns_rdataset_next(&rdataset)) {
4172 dns_rdataset_current(&rdataset, &rdata);
4173 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
4174 INSIST(result == ISC_R_SUCCESS);
4175 if (rrsig.algorithm == dst_key_alg(key) &&
4176 rrsig.keyid == dst_key_id(key)) {
4177 dns_rdataset_disassociate(&rdataset);
4180 dns_rdata_reset(&rdata);
4182 dns_rdataset_disassociate(&rdataset);
4187 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4188 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
4191 dns_fixedname_t fixed;
4193 dns_rdata_t rdata = DNS_RDATA_INIT;
4194 isc_result_t result;
4195 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4197 dns_fixedname_init(&fixed);
4198 next = dns_fixedname_name(&fixed);
4200 CHECK(next_active(db, version, name, next, bottom));
4201 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
4203 if (dns_name_equal(dns_db_origin(db), name)) {
4205 * Set the OPT bit to indicate that this is a
4206 * partially secure zone.
4208 isc_region_t region;
4210 dns_rdata_toregion(&rdata, ®ion);
4211 dns_name_fromregion(next, ®ion);
4212 isc_region_consume(®ion, next->length);
4213 INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
4214 region.base[0] == 0 &&
4215 region.base[1] > dns_rdatatype_opt / 8);
4216 set_bit(region.base + 2, dns_rdatatype_opt);
4218 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
4225 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
4226 dns_dbversion_t *version, isc_boolean_t build_nsec3,
4227 isc_boolean_t build_nsec, dst_key_t *key,
4228 isc_stdtime_t inception, isc_stdtime_t expire,
4229 unsigned int minimum, isc_boolean_t is_ksk,
4230 isc_boolean_t *delegation, dns_diff_t *diff,
4231 isc_int32_t *signatures, isc_mem_t *mctx)
4233 isc_result_t result;
4234 dns_rdatasetiter_t *iterator = NULL;
4235 dns_rdataset_t rdataset;
4236 dns_rdata_t rdata = DNS_RDATA_INIT;
4237 isc_buffer_t buffer;
4238 unsigned char data[1024];
4239 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
4240 seen_nsec3, seen_ds;
4241 isc_boolean_t bottom;
4243 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4244 if (result != ISC_R_SUCCESS) {
4245 if (result == ISC_R_NOTFOUND)
4246 result = ISC_R_SUCCESS;
4249 dns_rdataset_init(&rdataset);
4250 isc_buffer_init(&buffer, data, sizeof(data));
4251 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
4252 seen_nsec3 = seen_ds = ISC_FALSE;
4253 for (result = dns_rdatasetiter_first(iterator);
4254 result == ISC_R_SUCCESS;
4255 result = dns_rdatasetiter_next(iterator)) {
4256 dns_rdatasetiter_current(iterator, &rdataset);
4257 if (rdataset.type == dns_rdatatype_soa)
4258 seen_soa = ISC_TRUE;
4259 else if (rdataset.type == dns_rdatatype_ns)
4261 else if (rdataset.type == dns_rdatatype_ds)
4263 else if (rdataset.type == dns_rdatatype_dname)
4264 seen_dname = ISC_TRUE;
4265 else if (rdataset.type == dns_rdatatype_nsec)
4266 seen_nsec = ISC_TRUE;
4267 else if (rdataset.type == dns_rdatatype_nsec3)
4268 seen_nsec3 = ISC_TRUE;
4270 dns_rdataset_disassociate(&rdataset);
4272 if (result != ISC_R_NOMORE)
4274 if (seen_ns && !seen_soa)
4275 *delegation = ISC_TRUE;
4277 * Going from insecure to NSEC3.
4278 * Don't generate NSEC3 records for NSEC3 records.
4280 if (build_nsec3 && !seen_nsec3 && seen_rr) {
4281 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
4282 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
4287 * Going from insecure to NSEC.
4288 * Don't generate NSEC records for NSEC3 records.
4290 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
4291 /* Build and add NSEC. */
4292 bottom = (seen_ns && !seen_soa) || seen_dname;
4293 CHECK(add_nsec(db, version, name, node, minimum, bottom, diff));
4294 /* Count a NSEC generation as a signature generation. */
4297 result = dns_rdatasetiter_first(iterator);
4298 while (result == ISC_R_SUCCESS) {
4299 dns_rdatasetiter_current(iterator, &rdataset);
4300 if (rdataset.type == dns_rdatatype_soa ||
4301 rdataset.type == dns_rdatatype_rrsig)
4303 if (is_ksk && rdataset.type != dns_rdatatype_dnskey)
4306 rdataset.type != dns_rdatatype_ds &&
4307 rdataset.type != dns_rdatatype_nsec)
4309 if (signed_with_key(db, node, version, rdataset.type, key))
4311 /* Calculate the signature, creating a RRSIG RDATA. */
4312 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
4313 &expire, mctx, &buffer, &rdata));
4314 /* Update the database and journal with the RRSIG. */
4315 /* XXX inefficient - will cause dataset merging */
4316 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
4317 name, rdataset.ttl, &rdata));
4318 dns_rdata_reset(&rdata);
4321 dns_rdataset_disassociate(&rdataset);
4322 result = dns_rdatasetiter_next(iterator);
4324 if (result == ISC_R_NOMORE)
4325 result = ISC_R_SUCCESS;
4327 *delegation = ISC_TRUE;
4329 if (dns_rdataset_isassociated(&rdataset))
4330 dns_rdataset_disassociate(&rdataset);
4331 if (iterator != NULL)
4332 dns_rdatasetiter_destroy(&iterator);
4337 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4338 dns_ttl_t minimum, isc_boolean_t *secureupdated, dns_diff_t *diff)
4340 isc_result_t result;
4341 dns_rdata_t rdata = DNS_RDATA_INIT;
4342 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4343 dns_rdataset_t rdataset;
4344 dns_rdata_nsec_t nsec;
4345 dns_dbnode_t *node = NULL;
4348 * Check to see if the OPT bit has already been cleared.
4350 CHECK(dns_db_getoriginnode(db, &node));
4351 dns_rdataset_init(&rdataset);
4352 CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
4353 dns_rdatatype_none, 0, &rdataset, NULL));
4354 CHECK(dns_rdataset_first(&rdataset));
4355 dns_rdataset_current(&rdataset, &rdata);
4358 * Find the NEXT name for building the new record.
4360 CHECK(dns_rdata_tostruct(&rdata, &nsec, NULL));
4363 * Delete the old NSEC record.
4365 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_DEL, name, minimum,
4367 dns_rdata_reset(&rdata);
4370 * Add the new NSEC record.
4372 CHECK(dns_nsec_buildrdata(db, version, node, &nsec.next, nsecbuffer,
4374 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, minimum,
4376 dns_rdata_reset(&rdata);
4378 if (secureupdated != NULL)
4379 *secureupdated = ISC_TRUE;
4383 dns_db_detachnode(db, &node);
4384 if (dns_rdataset_isassociated(&rdataset))
4385 dns_rdataset_disassociate(&rdataset);
4390 updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
4391 dns_name_t *name, dns_rdatatype_t privatetype,
4394 isc_result_t result;
4395 dns_dbnode_t *node = NULL;
4396 dns_rdataset_t rdataset;
4397 dns_rdata_t rdata = DNS_RDATA_INIT;
4398 unsigned char data[5];
4399 isc_boolean_t seen_done = ISC_FALSE;
4401 dns_rdataset_init(&rdataset);
4402 result = dns_db_getoriginnode(signing->db, &node);
4403 if (result != ISC_R_SUCCESS)
4406 result = dns_db_findrdataset(signing->db, node, version, privatetype,
4407 dns_rdatatype_none, 0, &rdataset, NULL);
4408 if (result == ISC_R_NOTFOUND) {
4409 result = ISC_R_SUCCESS;
4412 if (result != ISC_R_SUCCESS)
4414 for (result = dns_rdataset_first(&rdataset);
4415 result == ISC_R_SUCCESS;
4416 result = dns_rdataset_next(&rdataset)) {
4417 dns_rdataset_current(&rdataset, &rdata);
4418 if (rdata.length != 5 ||
4419 rdata.data[0] != signing->algorithm ||
4420 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
4421 rdata.data[2] != (signing->keyid & 0xff)) {
4422 dns_rdata_reset(&rdata);
4425 if (!signing->delete && rdata.data[4] != 0)
4426 seen_done = ISC_TRUE;
4428 CHECK(update_one_rr(signing->db, version, diff,
4429 DNS_DIFFOP_DEL, name,
4430 rdataset.ttl, &rdata));
4431 dns_rdata_reset(&rdata);
4433 if (result == ISC_R_NOMORE)
4434 result = ISC_R_SUCCESS;
4435 if (!signing->delete && !seen_done) {
4437 data[0] = signing->algorithm;
4438 data[1] = (signing->keyid >> 8) & 0xff;
4439 data[2] = signing->keyid & 0xff;
4442 rdata.length = sizeof(data);
4444 rdata.type = privatetype;
4445 rdata.rdclass = dns_db_class(signing->db);
4446 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
4447 name, rdataset.ttl, &rdata));
4450 if (dns_rdataset_isassociated(&rdataset))
4451 dns_rdataset_disassociate(&rdataset);
4453 dns_db_detachnode(signing->db, &node);
4458 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
4459 isc_boolean_t active, dns_diff_t *diff)
4461 dns_dbnode_t *node = NULL;
4462 dns_name_t *name = dns_db_origin(db);
4463 dns_rdata_t rdata = DNS_RDATA_INIT;
4464 dns_rdataset_t rdataset;
4465 dns_rdata_nsec3param_t nsec3param;
4466 isc_result_t result;
4467 isc_buffer_t buffer;
4468 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
4471 dns_rdataset_init(&rdataset);
4473 result = dns_db_getoriginnode(db, &node);
4474 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4475 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4476 0, 0, &rdataset, NULL);
4477 if (result == ISC_R_NOTFOUND)
4479 if (result != ISC_R_SUCCESS)
4483 * Preserve the existing ttl.
4488 * Delete all NSEC3PARAM records which match that in nsec3chain.
4490 for (result = dns_rdataset_first(&rdataset);
4491 result == ISC_R_SUCCESS;
4492 result = dns_rdataset_next(&rdataset)) {
4494 dns_rdataset_current(&rdataset, &rdata);
4495 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
4497 if (nsec3param.hash != chain->nsec3param.hash ||
4498 (active && nsec3param.flags != 0) ||
4499 nsec3param.iterations != chain->nsec3param.iterations ||
4500 nsec3param.salt_length != chain->nsec3param.salt_length ||
4501 memcmp(nsec3param.salt, chain->nsec3param.salt,
4502 nsec3param.salt_length)) {
4503 dns_rdata_reset(&rdata);
4507 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
4508 name, rdataset.ttl, &rdata));
4509 dns_rdata_reset(&rdata);
4511 if (result != ISC_R_NOMORE)
4515 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
4516 result = ISC_R_SUCCESS;
4521 * Add a NSEC3PARAM record which matches that in nsec3chain but
4522 * with all flags bits cleared.
4524 * Note: we do not clear chain->nsec3param.flags as this change
4527 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
4528 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
4529 dns_rdatatype_nsec3param,
4530 &chain->nsec3param, &buffer));
4531 rdata.data[1] = 0; /* Clear flag bits. */
4532 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
4535 dns_db_detachnode(db, &node);
4536 if (dns_rdataset_isassociated(&rdataset))
4537 dns_rdataset_disassociate(&rdataset);
4542 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4543 dns_name_t *name, dns_diff_t *diff)
4545 dns_rdataset_t rdataset;
4546 isc_result_t result;
4548 dns_rdataset_init(&rdataset);
4550 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4551 0, 0, &rdataset, NULL);
4552 if (result == ISC_R_NOTFOUND)
4553 return (ISC_R_SUCCESS);
4554 if (result != ISC_R_SUCCESS)
4556 for (result = dns_rdataset_first(&rdataset);
4557 result == ISC_R_SUCCESS;
4558 result = dns_rdataset_next(&rdataset)) {
4559 dns_rdata_t rdata = DNS_RDATA_INIT;
4561 dns_rdataset_current(&rdataset, &rdata);
4562 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4563 rdataset.ttl, &rdata));
4565 if (result == ISC_R_NOMORE)
4566 result = ISC_R_SUCCESS;
4568 dns_rdataset_disassociate(&rdataset);
4573 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4574 dns_name_t *name, const dns_rdata_nsec3param_t *param,
4577 dns_rdataset_t rdataset;
4578 dns_rdata_nsec3_t nsec3;
4579 isc_result_t result;
4581 dns_rdataset_init(&rdataset);
4582 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
4583 0, 0, &rdataset, NULL);
4584 if (result == ISC_R_NOTFOUND)
4585 return (ISC_R_SUCCESS);
4586 if (result != ISC_R_SUCCESS)
4589 for (result = dns_rdataset_first(&rdataset);
4590 result == ISC_R_SUCCESS;
4591 result = dns_rdataset_next(&rdataset)) {
4592 dns_rdata_t rdata = DNS_RDATA_INIT;
4594 dns_rdataset_current(&rdataset, &rdata);
4595 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
4596 if (nsec3.hash != param->hash ||
4597 nsec3.iterations != param->iterations ||
4598 nsec3.salt_length != param->salt_length ||
4599 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
4601 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4602 rdataset.ttl, &rdata));
4604 if (result == ISC_R_NOMORE)
4605 result = ISC_R_SUCCESS;
4607 dns_rdataset_disassociate(&rdataset);
4612 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
4613 const dns_rdata_nsec3param_t *param,
4614 isc_boolean_t *answer, isc_boolean_t *updatensec)
4616 dns_dbnode_t *node = NULL;
4617 dns_rdata_t rdata = DNS_RDATA_INIT;
4618 dns_rdata_nsec3param_t myparam;
4619 dns_rdataset_t rdataset;
4620 isc_result_t result;
4622 *answer = ISC_FALSE;
4624 result = dns_db_getoriginnode(db, &node);
4625 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4627 dns_rdataset_init(&rdataset);
4628 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4629 0, 0, &rdataset, NULL);
4630 if (result == ISC_R_NOTFOUND)
4631 goto check_nsec3param;
4633 if (result != ISC_R_SUCCESS)
4636 CHECK(dns_rdataset_first(&rdataset));
4637 dns_rdataset_current(&rdataset, &rdata);
4639 if (!dns_nsec_typepresent(&rdata, dns_rdatatype_opt)) {
4641 * We have a complete NSEC chain. Signal to update
4642 * the apex NSEC record.
4644 *updatensec = ISC_TRUE;
4647 dns_rdataset_disassociate(&rdataset);
4648 dns_rdata_reset(&rdata);
4651 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4652 0, 0, &rdataset, NULL);
4653 if (result == ISC_R_NOTFOUND) {
4655 dns_db_detachnode(db, &node);
4656 return (ISC_R_SUCCESS);
4658 if (result != ISC_R_SUCCESS) {
4659 dns_db_detachnode(db, &node);
4663 for (result = dns_rdataset_first(&rdataset);
4664 result == ISC_R_SUCCESS;
4665 result = dns_rdataset_next(&rdataset)) {
4666 dns_rdataset_current(&rdataset, &rdata);
4667 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
4668 dns_rdata_reset(&rdata);
4670 * Ignore any NSEC3PARAM removals.
4672 if (NSEC3REMOVE(myparam.flags))
4675 * Ignore the chain that we are in the process of deleting.
4677 if (myparam.hash == param->hash &&
4678 myparam.iterations == param->iterations &&
4679 myparam.salt_length == param->salt_length &&
4680 !memcmp(myparam.salt, param->salt, myparam.salt_length))
4683 * Found an active NSEC3 chain.
4687 if (result == ISC_R_NOMORE) {
4689 result = ISC_R_SUCCESS;
4693 if (dns_rdataset_isassociated(&rdataset))
4694 dns_rdataset_disassociate(&rdataset);
4695 dns_db_detachnode(db, &node);
4700 * Incrementally build and sign a new NSEC3 chain using the parameters
4704 zone_nsec3chain(dns_zone_t *zone) {
4705 const char *journalfile;
4706 dns_db_t *db = NULL;
4707 dns_dbnode_t *node = NULL;
4708 dns_dbversion_t *version = NULL;
4709 dns_diff_t sig_diff;
4710 dns_diff_t nsec_diff;
4711 dns_diff_t nsec3_diff;
4712 dns_diff_t param_diff;
4713 dns_fixedname_t fixed;
4714 dns_fixedname_t nextfixed;
4715 dns_name_t *name, *nextname;
4716 dns_rdataset_t rdataset;
4717 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
4718 dns_nsec3chainlist_t cleanup;
4719 dst_key_t *zone_keys[MAXZONEKEYS];
4720 isc_int32_t signatures;
4721 isc_boolean_t check_ksk, is_ksk;
4722 isc_boolean_t delegation;
4723 isc_boolean_t first;
4724 isc_result_t result;
4725 isc_stdtime_t now, inception, soaexpire, expire, stop;
4726 isc_uint32_t jitter;
4728 unsigned int nkeys = 0;
4730 isc_boolean_t unsecure = ISC_FALSE;
4731 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
4732 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
4733 dns_rdatasetiter_t *iterator = NULL;
4734 dns_difftuple_t *tuple;
4735 isc_boolean_t buildnsecchain;
4736 isc_boolean_t updatensec = ISC_FALSE;
4738 dns_rdataset_init(&rdataset);
4739 dns_fixedname_init(&fixed);
4740 name = dns_fixedname_name(&fixed);
4741 dns_fixedname_init(&nextfixed);
4742 nextname = dns_fixedname_name(&nextfixed);
4743 dns_diff_init(zone->mctx, ¶m_diff);
4744 dns_diff_init(zone->mctx, &nsec3_diff);
4745 dns_diff_init(zone->mctx, &nsec_diff);
4746 dns_diff_init(zone->mctx, &sig_diff);
4747 sig_diff.resign = zone->sigresigninginterval;
4748 ISC_LIST_INIT(cleanup);
4751 * Updates are disabled. Pause for 5 minutes.
4753 if (zone->update_disabled) {
4754 result = ISC_R_FAILURE;
4758 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4759 dns_db_attach(zone->db, &db);
4760 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4762 result = dns_db_newversion(db, &version);
4763 if (result != ISC_R_SUCCESS) {
4764 dns_zone_log(zone, ISC_LOG_ERROR,
4765 "zone_nsec3chain:dns_db_newversion -> %s\n",
4766 dns_result_totext(result));
4770 result = find_zone_keys(zone, db, version, zone->mctx,
4771 MAXZONEKEYS, zone_keys, &nkeys);
4772 if (result != ISC_R_SUCCESS) {
4773 dns_zone_log(zone, ISC_LOG_ERROR,
4774 "zone_nsec3chain:find_zone_keys -> %s\n",
4775 dns_result_totext(result));
4779 isc_stdtime_get(&now);
4780 inception = now - 3600; /* Allow for clock skew. */
4781 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
4784 * Spread out signatures over time if they happen to be
4785 * clumped. We don't do this for each add_sigs() call as
4786 * we still want some clustering to occur.
4788 isc_random_get(&jitter);
4789 expire = soaexpire - jitter % 3600;
4792 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
4794 check_ksk = ksk_sanity(db, version);
4797 * We keep pulling nodes off each iterator in turn until
4798 * we have no more nodes to pull off or we reach the limits
4801 nodes = zone->nodes;
4802 signatures = zone->signatures;
4804 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
4808 if (nsec3chain != NULL)
4809 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
4811 * Generate new NSEC3 chains first.
4813 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
4815 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
4817 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4818 if (nsec3chain->done || nsec3chain->db != zone->db) {
4819 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
4820 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4822 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4824 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
4828 * Possible future db.
4830 if (nsec3chain->db != db) {
4834 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
4838 delegation = ISC_FALSE;
4839 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
4841 if (nsec3chain->delete_nsec) {
4842 delegation = ISC_FALSE;
4843 dns_dbiterator_pause(nsec3chain->dbiterator);
4844 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
4848 * On the first pass we need to check if the current node
4849 * has not been obscured.
4851 delegation = ISC_FALSE;
4852 unsecure = ISC_FALSE;
4854 dns_fixedname_t ffound;
4856 dns_fixedname_init(&ffound);
4857 found = dns_fixedname_name(&ffound);
4858 result = dns_db_find(db, name, version,
4860 DNS_DBFIND_NOWILD, 0, NULL, found,
4862 if ((result == DNS_R_DELEGATION ||
4863 result == DNS_R_DNAME) &&
4864 !dns_name_equal(name, found)) {
4866 * Remember the obscuring name so that
4867 * we skip all obscured names.
4869 dns_name_copy(found, name, NULL);
4870 delegation = ISC_TRUE;
4876 * Check to see if this is a bottom of zone node.
4878 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4879 if (result == ISC_R_NOTFOUND) /* Empty node? */
4881 if (result != ISC_R_SUCCESS)
4884 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
4886 for (result = dns_rdatasetiter_first(iterator);
4887 result == ISC_R_SUCCESS;
4888 result = dns_rdatasetiter_next(iterator)) {
4889 dns_rdatasetiter_current(iterator, &rdataset);
4890 INSIST(rdataset.type != dns_rdatatype_nsec3);
4891 if (rdataset.type == dns_rdatatype_soa)
4892 seen_soa = ISC_TRUE;
4893 else if (rdataset.type == dns_rdatatype_ns)
4895 else if (rdataset.type == dns_rdatatype_dname)
4896 seen_dname = ISC_TRUE;
4897 else if (rdataset.type == dns_rdatatype_ds)
4899 else if (rdataset.type == dns_rdatatype_nsec)
4900 seen_nsec = ISC_TRUE;
4901 dns_rdataset_disassociate(&rdataset);
4903 dns_rdatasetiter_destroy(&iterator);
4905 * Is there a NSEC chain than needs to be cleaned up?
4908 nsec3chain->seen_nsec = ISC_TRUE;
4909 if (seen_ns && !seen_soa && !seen_ds)
4910 unsecure = ISC_TRUE;
4911 if ((seen_ns && !seen_soa) || seen_dname)
4912 delegation = ISC_TRUE;
4917 dns_dbiterator_pause(nsec3chain->dbiterator);
4918 CHECK(dns_nsec3_addnsec3(db, version, name,
4919 &nsec3chain->nsec3param,
4920 zone->minimum, unsecure, &nsec3_diff));
4922 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
4923 * two signatures. Additionally there will, in general, be
4924 * two signature generated below.
4926 * If we are only changing the optout flag the cost is half
4927 * that of the cost of generating a completely new chain.
4932 * Go onto next node.
4936 dns_db_detachnode(db, &node);
4938 result = dns_dbiterator_next(nsec3chain->dbiterator);
4940 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
4941 CHECK(fixup_nsec3param(db, version, nsec3chain,
4942 ISC_FALSE, ¶m_diff));
4944 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4947 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4950 if (result == ISC_R_NOMORE) {
4951 dns_dbiterator_pause(nsec3chain->dbiterator);
4952 if (nsec3chain->seen_nsec) {
4953 CHECK(fixup_nsec3param(db, version,
4957 nsec3chain->delete_nsec = ISC_TRUE;
4960 CHECK(fixup_nsec3param(db, version, nsec3chain,
4961 ISC_FALSE, ¶m_diff));
4963 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4966 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4968 } else if (result != ISC_R_SUCCESS) {
4969 dns_zone_log(zone, ISC_LOG_ERROR,
4971 "dns_dbiterator_next -> %s\n",
4972 dns_result_totext(result));
4974 } else if (delegation) {
4975 dns_dbiterator_current(nsec3chain->dbiterator,
4977 dns_db_detachnode(db, &node);
4978 if (!dns_name_issubdomain(nextname, name))
4986 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
4991 dns_dbiterator_pause(nsec3chain->dbiterator);
4992 nsec3chain = nextnsec3chain;
4994 if (nsec3chain != NULL)
4995 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
5002 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5005 buildnsecchain = ISC_FALSE;
5006 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
5008 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
5011 if (nsec3chain->db != db)
5012 goto next_removechain;
5014 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
5015 goto next_removechain;
5018 * Work out if we need to build a NSEC chain as a consequence
5019 * of removing this NSEC3 chain.
5021 if (first && !updatensec &&
5022 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
5023 CHECK(need_nsec_chain(db, version,
5024 &nsec3chain->nsec3param,
5025 &buildnsecchain, &updatensec));
5027 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
5028 delegation = ISC_FALSE;
5030 if (!buildnsecchain) {
5032 * Delete the NSECPARAM record that matches this chain.
5035 CHECK(fixup_nsec3param(db, version, nsec3chain,
5036 ISC_TRUE, ¶m_diff));
5039 * Delete the NSEC3 records.
5041 CHECK(deletematchingnsec3(db, version, node, name,
5042 &nsec3chain->nsec3param,
5044 goto next_removenode;
5048 dns_fixedname_t ffound;
5050 dns_fixedname_init(&ffound);
5051 found = dns_fixedname_name(&ffound);
5052 result = dns_db_find(db, name, version,
5054 DNS_DBFIND_NOWILD, 0, NULL, found,
5056 if ((result == DNS_R_DELEGATION ||
5057 result == DNS_R_DNAME) &&
5058 !dns_name_equal(name, found)) {
5060 * Remember the obscuring name so that
5061 * we skip all obscured names.
5063 dns_name_copy(found, name, NULL);
5064 delegation = ISC_TRUE;
5065 goto next_removenode;
5070 * Check to see if this is a bottom of zone node.
5072 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5073 if (result == ISC_R_NOTFOUND) /* Empty node? */
5074 goto next_removenode;
5075 if (result != ISC_R_SUCCESS)
5078 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
5079 seen_rr = ISC_FALSE;
5080 for (result = dns_rdatasetiter_first(iterator);
5081 result == ISC_R_SUCCESS;
5082 result = dns_rdatasetiter_next(iterator)) {
5083 dns_rdatasetiter_current(iterator, &rdataset);
5084 if (rdataset.type == dns_rdatatype_soa)
5085 seen_soa = ISC_TRUE;
5086 else if (rdataset.type == dns_rdatatype_ns)
5088 else if (rdataset.type == dns_rdatatype_dname)
5089 seen_dname = ISC_TRUE;
5090 else if (rdataset.type == dns_rdatatype_nsec)
5091 seen_nsec = ISC_TRUE;
5092 else if (rdataset.type == dns_rdatatype_nsec3)
5093 seen_nsec3 = ISC_TRUE;
5095 dns_rdataset_disassociate(&rdataset);
5097 dns_rdatasetiter_destroy(&iterator);
5099 if (!seen_rr || seen_nsec3 || seen_nsec)
5100 goto next_removenode;
5101 if ((seen_ns && !seen_soa) || seen_dname)
5102 delegation = ISC_TRUE;
5104 CHECK(add_nsec(db, version, name, node, zone->minimum,
5105 delegation, &nsec_diff));
5109 dns_db_detachnode(db, &node);
5111 result = dns_dbiterator_next(nsec3chain->dbiterator);
5112 if (result == ISC_R_NOMORE && buildnsecchain) {
5114 * The NSEC chain should now be built.
5115 * We can now remove the NSEC3 chain.
5117 updatensec = ISC_TRUE;
5118 goto same_removechain;
5120 if (result == ISC_R_NOMORE) {
5122 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
5125 ISC_LIST_APPEND(cleanup, nsec3chain, link);
5126 dns_dbiterator_pause(nsec3chain->dbiterator);
5127 CHECK(fixup_nsec3param(db, version, nsec3chain,
5128 ISC_FALSE, ¶m_diff));
5129 goto next_removechain;
5130 } else if (result != ISC_R_SUCCESS) {
5131 dns_zone_log(zone, ISC_LOG_ERROR,
5133 "dns_dbiterator_next -> %s\n",
5134 dns_result_totext(result));
5136 } else if (delegation) {
5137 dns_dbiterator_current(nsec3chain->dbiterator,
5139 dns_db_detachnode(db, &node);
5140 if (!dns_name_issubdomain(nextname, name))
5148 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
5149 buildnsecchain = ISC_FALSE;
5154 dns_dbiterator_pause(nsec3chain->dbiterator);
5155 nsec3chain = nextnsec3chain;
5160 * Add / update signatures for the NSEC3 records.
5162 for (tuple = ISC_LIST_HEAD(nsec3_diff.tuples);
5164 tuple = ISC_LIST_HEAD(nsec3_diff.tuples)) {
5166 * We have changed the NSEC3 RRset above so we need to update
5169 result = del_sigs(zone, db, version, &tuple->name,
5170 dns_rdatatype_nsec3, &sig_diff,
5171 zone_keys, nkeys, now);
5172 if (result != ISC_R_SUCCESS) {
5173 dns_zone_log(zone, ISC_LOG_ERROR,
5174 "zone_nsec3chain:del_sigs -> %s\n",
5175 dns_result_totext(result));
5178 result = add_sigs(db, version, &tuple->name,
5179 dns_rdatatype_nsec3, &sig_diff, zone_keys,
5180 nkeys, zone->mctx, inception, expire,
5182 if (result != ISC_R_SUCCESS) {
5183 dns_zone_log(zone, ISC_LOG_ERROR,
5184 "zone_nsec3chain:add_sigs -> %s\n",
5185 dns_result_totext(result));
5190 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
5191 while (next != NULL &&
5192 !dns_name_equal(&tuple->name, &next->name))
5193 next = ISC_LIST_NEXT(next, link);
5194 ISC_LIST_UNLINK(nsec3_diff.tuples, tuple, link);
5195 dns_diff_appendminimal(&sig_diff, &tuple);
5196 INSIST(tuple == NULL);
5198 } while (tuple != NULL);
5201 for (tuple = ISC_LIST_HEAD(param_diff.tuples);
5203 tuple = ISC_LIST_HEAD(param_diff.tuples)) {
5205 * We have changed the NSEC3PARAM RRset above so we need to
5206 * update the signatures.
5208 result = del_sigs(zone, db, version, &tuple->name,
5209 dns_rdatatype_nsec3param, &sig_diff,
5210 zone_keys, nkeys, now);
5211 if (result != ISC_R_SUCCESS) {
5212 dns_zone_log(zone, ISC_LOG_ERROR,
5213 "zone_nsec3chain:del_sigs -> %s\n",
5214 dns_result_totext(result));
5217 result = add_sigs(db, version, &tuple->name,
5218 dns_rdatatype_nsec3param, &sig_diff,
5219 zone_keys, nkeys, zone->mctx, inception,
5221 if (result != ISC_R_SUCCESS) {
5222 dns_zone_log(zone, ISC_LOG_ERROR,
5223 "zone_nsec3chain:add_sigs -> %s\n",
5224 dns_result_totext(result));
5227 ISC_LIST_UNLINK(param_diff.tuples, tuple, link);
5228 dns_diff_appendminimal(&sig_diff, &tuple);
5229 INSIST(tuple == NULL);
5233 CHECK(updatesecure(db, version, &zone->origin, zone->minimum,
5236 for (tuple = ISC_LIST_HEAD(nsec_diff.tuples);
5238 tuple = ISC_LIST_HEAD(nsec_diff.tuples)) {
5239 result = del_sigs(zone, db, version, &tuple->name,
5240 dns_rdatatype_nsec, &sig_diff,
5241 zone_keys, nkeys, now);
5242 if (result != ISC_R_SUCCESS) {
5243 dns_zone_log(zone, ISC_LOG_ERROR,
5244 "zone_nsec3chain:del_sigs -> %s\n",
5245 dns_result_totext(result));
5248 result = add_sigs(db, version, &tuple->name,
5249 dns_rdatatype_nsec, &sig_diff,
5250 zone_keys, nkeys, zone->mctx, inception,
5252 if (result != ISC_R_SUCCESS) {
5253 dns_zone_log(zone, ISC_LOG_ERROR,
5254 "zone_nsec3chain:add_sigs -> %s\n",
5255 dns_result_totext(result));
5258 ISC_LIST_UNLINK(nsec_diff.tuples, tuple, link);
5259 dns_diff_appendminimal(&sig_diff, &tuple);
5260 INSIST(tuple == NULL);
5264 * If we made no effective changes to the zone then we can just
5265 * cleanup otherwise we need to increment the serial.
5267 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5270 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5271 &sig_diff, zone_keys, nkeys, now);
5272 if (result != ISC_R_SUCCESS) {
5273 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5274 "del_sigs -> %s\n", dns_result_totext(result));
5278 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5279 if (result != ISC_R_SUCCESS) {
5280 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5281 "increment_soa_serial -> %s\n",
5282 dns_result_totext(result));
5286 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5287 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5288 soaexpire, check_ksk);
5289 if (result != ISC_R_SUCCESS) {
5290 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5291 "add_sigs -> %s\n", dns_result_totext(result));
5295 journalfile = dns_zone_getjournal(zone);
5296 if (journalfile != NULL) {
5297 dns_journal_t *journal = NULL;
5298 result = dns_journal_open(zone->mctx, journalfile,
5299 ISC_TRUE, &journal);
5300 if (result != ISC_R_SUCCESS) {
5301 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5302 "dns_journal_open -> %s\n",
5303 dns_result_totext(result));
5307 result = dns_journal_write_transaction(journal, &sig_diff);
5308 dns_journal_destroy(&journal);
5309 if (result != ISC_R_SUCCESS) {
5310 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5311 "dns_journal_write_transaction -> %s\n",
5312 dns_result_totext(result));
5318 zone_needdump(zone, DNS_DUMP_DELAY);
5323 * Pause all iterators so that dns_db_closeversion() can succeed.
5326 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5328 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5329 dns_dbiterator_pause(nsec3chain->dbiterator);
5333 * Everything has succeeded. Commit the changes.
5335 dns_db_closeversion(db, &version, ISC_TRUE);
5338 * Everything succeeded so we can clean these up now.
5340 nsec3chain = ISC_LIST_HEAD(cleanup);
5341 while (nsec3chain != NULL) {
5342 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5343 dns_db_detach(&nsec3chain->db);
5344 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5345 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5346 nsec3chain = ISC_LIST_HEAD(cleanup);
5349 set_resigntime(zone);
5353 * On error roll back the current nsec3chain.
5355 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
5356 if (nsec3chain->done) {
5357 dns_db_detach(&nsec3chain->db);
5358 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5359 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5361 result = dns_dbiterator_first(nsec3chain->dbiterator);
5362 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5363 dns_dbiterator_pause(nsec3chain->dbiterator);
5364 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5369 * Rollback the cleanup list.
5371 nsec3chain = ISC_LIST_TAIL(cleanup);
5372 while (nsec3chain != NULL) {
5373 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5374 if (nsec3chain->done) {
5375 dns_db_detach(&nsec3chain->db);
5376 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5377 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5380 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
5382 result = dns_dbiterator_first(nsec3chain->dbiterator);
5383 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5384 dns_dbiterator_pause(nsec3chain->dbiterator);
5385 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5387 nsec3chain = ISC_LIST_TAIL(cleanup);
5391 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5393 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5394 dns_dbiterator_pause(nsec3chain->dbiterator);
5397 dns_diff_clear(¶m_diff);
5398 dns_diff_clear(&nsec3_diff);
5399 dns_diff_clear(&nsec_diff);
5400 dns_diff_clear(&sig_diff);
5402 if (iterator != NULL)
5403 dns_rdatasetiter_destroy(&iterator);
5405 for (i = 0; i < nkeys; i++)
5406 dst_key_free(&zone_keys[i]);
5408 if (version != NULL) {
5409 dns_db_closeversion(db, &version, ISC_FALSE);
5411 } else if (db != NULL)
5415 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
5417 if (zone->update_disabled || result != ISC_R_SUCCESS)
5418 isc_interval_set(&i, 60, 0); /* 1 minute */
5420 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5421 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
5423 isc_time_settoepoch(&zone->nsec3chaintime);
5428 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5429 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
5430 isc_uint16_t keyid, dns_diff_t *diff)
5432 dns_rdata_rrsig_t rrsig;
5433 dns_rdataset_t rdataset;
5434 dns_rdatasetiter_t *iterator = NULL;
5435 isc_result_t result;
5437 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5438 if (result != ISC_R_SUCCESS) {
5439 if (result == ISC_R_NOTFOUND)
5440 result = ISC_R_SUCCESS;
5444 dns_rdataset_init(&rdataset);
5445 for (result = dns_rdatasetiter_first(iterator);
5446 result == ISC_R_SUCCESS;
5447 result = dns_rdatasetiter_next(iterator)) {
5448 dns_rdatasetiter_current(iterator, &rdataset);
5449 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
5450 for (result = dns_rdataset_first(&rdataset);
5451 result == ISC_R_SUCCESS;
5452 result = dns_rdataset_next(&rdataset)) {
5453 dns_rdata_t rdata = DNS_RDATA_INIT;
5454 dns_rdataset_current(&rdataset, &rdata);
5455 CHECK(update_one_rr(db, version, diff,
5456 DNS_DIFFOP_DEL, name,
5457 rdataset.ttl, &rdata));
5459 if (result != ISC_R_NOMORE)
5461 dns_rdataset_disassociate(&rdataset);
5464 if (rdataset.type != dns_rdatatype_rrsig) {
5465 dns_rdataset_disassociate(&rdataset);
5468 for (result = dns_rdataset_first(&rdataset);
5469 result == ISC_R_SUCCESS;
5470 result = dns_rdataset_next(&rdataset)) {
5471 dns_rdata_t rdata = DNS_RDATA_INIT;
5472 dns_rdataset_current(&rdataset, &rdata);
5473 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
5474 if (rrsig.algorithm != algorithm ||
5475 rrsig.keyid != keyid)
5477 CHECK(update_one_rr(db, version, diff,
5478 DNS_DIFFOP_DEL, name,
5479 rdataset.ttl, &rdata));
5481 dns_rdataset_disassociate(&rdataset);
5482 if (result != ISC_R_NOMORE)
5485 if (result == ISC_R_NOMORE)
5486 result = ISC_R_SUCCESS;
5488 if (dns_rdataset_isassociated(&rdataset))
5489 dns_rdataset_disassociate(&rdataset);
5490 dns_rdatasetiter_destroy(&iterator);
5495 * Incrementally sign the zone using the keys requested.
5496 * Builds the NSEC chain if required.
5499 zone_sign(dns_zone_t *zone) {
5500 const char *journalfile;
5501 dns_db_t *db = NULL;
5502 dns_dbnode_t *node = NULL;
5503 dns_dbversion_t *version = NULL;
5504 dns_diff_t sig_diff;
5505 dns_fixedname_t fixed;
5506 dns_fixedname_t nextfixed;
5507 dns_name_t *name, *nextname;
5508 dns_rdataset_t rdataset;
5509 dns_signing_t *signing, *nextsigning;
5510 dns_signinglist_t cleanup;
5511 dst_key_t *zone_keys[MAXZONEKEYS];
5512 isc_int32_t signatures;
5513 isc_boolean_t check_ksk, is_ksk;
5514 isc_boolean_t commit = ISC_FALSE;
5515 isc_boolean_t delegation;
5516 isc_boolean_t finishedakey = ISC_FALSE;
5517 isc_boolean_t secureupdated = ISC_FALSE;
5518 isc_boolean_t build_nsec3 = ISC_FALSE, build_nsec = ISC_FALSE;
5519 isc_boolean_t first;
5520 isc_result_t result;
5521 isc_stdtime_t now, inception, soaexpire, expire, stop;
5522 isc_uint32_t jitter;
5524 unsigned int nkeys = 0;
5527 dns_rdataset_init(&rdataset);
5528 dns_fixedname_init(&fixed);
5529 name = dns_fixedname_name(&fixed);
5530 dns_fixedname_init(&nextfixed);
5531 nextname = dns_fixedname_name(&nextfixed);
5532 dns_diff_init(zone->mctx, &sig_diff);
5533 sig_diff.resign = zone->sigresigninginterval;
5534 ISC_LIST_INIT(cleanup);
5537 * Updates are disabled. Pause for 5 minutes.
5539 if (zone->update_disabled) {
5540 result = ISC_R_FAILURE;
5544 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5545 dns_db_attach(zone->db, &db);
5546 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5548 result = dns_db_newversion(db, &version);
5549 if (result != ISC_R_SUCCESS) {
5550 dns_zone_log(zone, ISC_LOG_ERROR,
5551 "zone_sign:dns_db_newversion -> %s\n",
5552 dns_result_totext(result));
5556 result = find_zone_keys(zone, db, version, zone->mctx,
5557 MAXZONEKEYS, zone_keys, &nkeys);
5558 if (result != ISC_R_SUCCESS) {
5559 dns_zone_log(zone, ISC_LOG_ERROR,
5560 "zone_sign:find_zone_keys -> %s\n",
5561 dns_result_totext(result));
5565 isc_stdtime_get(&now);
5566 inception = now - 3600; /* Allow for clock skew. */
5567 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5570 * Spread out signatures over time if they happen to be
5571 * clumped. We don't do this for each add_sigs() call as
5572 * we still want some clustering to occur.
5574 isc_random_get(&jitter);
5575 expire = soaexpire - jitter % 3600;
5578 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5580 check_ksk = ksk_sanity(db, version);
5583 * We keep pulling nodes off each iterator in turn until
5584 * we have no more nodes to pull off or we reach the limits
5587 nodes = zone->nodes;
5588 signatures = zone->signatures;
5589 signing = ISC_LIST_HEAD(zone->signing);
5592 * See if we have a NSEC chain.
5594 result = dns_db_getoriginnode(db, &node);
5595 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5596 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
5597 dns_rdatatype_none, 0, &rdataset, NULL);
5598 dns_db_detachnode(db, &node);
5599 if (result == ISC_R_SUCCESS) {
5600 build_nsec = ISC_TRUE;
5601 dns_rdataset_disassociate(&rdataset);
5602 } else if (result != ISC_R_NOTFOUND) {
5606 * No NSEC chain present.
5607 * See if we need to build a NSEC3 chain?
5609 result = dns_nsec3_active(db, version, ISC_TRUE, &build_nsec3);
5610 if (result == ISC_R_SUCCESS) {
5612 build_nsec3 = ISC_FALSE;
5614 result = dns_nsec3_active(db, version,
5618 secureupdated = ISC_TRUE;
5620 build_nsec = ISC_TRUE;
5625 while (signing != NULL && nodes-- > 0 && signatures > 0) {
5626 nextsigning = ISC_LIST_NEXT(signing, link);
5628 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5629 if (signing->done || signing->db != zone->db) {
5631 * The zone has been reloaded. We will have
5632 * created new signings as part of the reload
5633 * process so we can destroy this one.
5635 ISC_LIST_UNLINK(zone->signing, signing, link);
5636 ISC_LIST_APPEND(cleanup, signing, link);
5637 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5640 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5642 if (signing->db != db)
5646 delegation = ISC_FALSE;
5648 dns_dbiterator_current(signing->dbiterator, &node, name);
5650 if (signing->delete) {
5651 dns_dbiterator_pause(signing->dbiterator);
5652 CHECK(del_sig(db, version, name, node, nkeys,
5653 signing->algorithm, signing->keyid,
5658 * On the first pass we need to check if the current node
5659 * has not been obscured.
5662 dns_fixedname_t ffound;
5664 dns_fixedname_init(&ffound);
5665 found = dns_fixedname_name(&ffound);
5666 result = dns_db_find(db, name, version,
5668 DNS_DBFIND_NOWILD, 0, NULL, found,
5670 if ((result == DNS_R_DELEGATION ||
5671 result == DNS_R_DNAME) &&
5672 !dns_name_equal(name, found)) {
5674 * Remember the obscuring name so that
5675 * we skip all obscured names.
5677 dns_name_copy(found, name, NULL);
5678 delegation = ISC_TRUE;
5686 dns_dbiterator_pause(signing->dbiterator);
5687 for (i = 0; i < nkeys; i++) {
5689 * Find the key we want to sign with.
5691 if (dst_key_alg(zone_keys[i]) != signing->algorithm ||
5692 dst_key_id(zone_keys[i]) != signing->keyid ||
5693 !dst_key_isprivate(zone_keys[i]))
5696 * Do we do KSK processing?
5699 (dst_key_flags(zone_keys[i]) & DNS_KEYFLAG_KSK) != 0)
5701 CHECK(sign_a_node(db, name, node, version, build_nsec3,
5702 build_nsec, zone_keys[i], inception,
5703 expire, zone->minimum, is_ksk,
5704 &delegation, &sig_diff, &signatures,
5709 * Go onto next node.
5713 dns_db_detachnode(db, &node);
5715 result = dns_dbiterator_next(signing->dbiterator);
5716 if (result == ISC_R_NOMORE) {
5717 ISC_LIST_UNLINK(zone->signing, signing, link);
5718 ISC_LIST_APPEND(cleanup, signing, link);
5719 dns_dbiterator_pause(signing->dbiterator);
5720 finishedakey = ISC_TRUE;
5721 if (!is_ksk && !secureupdated && nkeys != 0 &&
5724 * We have finished regenerating the
5725 * zone with a zone signing key.
5726 * The NSEC chain is now complete and
5727 * there is a full set of signatures
5728 * for the zone. We can now clear the
5729 * OPT bit from the NSEC record.
5731 result = updatesecure(db, version,
5736 if (result != ISC_R_SUCCESS) {
5739 "updatesecure -> %s\n",
5740 dns_result_totext(result));
5744 result = updatesignwithkey(signing, version,
5748 if (result != ISC_R_SUCCESS) {
5749 dns_zone_log(zone, ISC_LOG_ERROR,
5750 "updatesignwithkey -> %s\n",
5751 dns_result_totext(result));
5755 } else if (result != ISC_R_SUCCESS) {
5756 dns_zone_log(zone, ISC_LOG_ERROR,
5757 "zone_sign:dns_dbiterator_next -> %s\n",
5758 dns_result_totext(result));
5760 } else if (delegation) {
5761 dns_dbiterator_current(signing->dbiterator,
5763 dns_db_detachnode(db, &node);
5764 if (!dns_name_issubdomain(nextname, name))
5772 dns_dbiterator_pause(signing->dbiterator);
5773 signing = nextsigning;
5777 if (secureupdated) {
5779 * We have changed the NSEC RRset above so we need to update
5782 result = del_sigs(zone, db, version, &zone->origin,
5783 dns_rdatatype_nsec, &sig_diff, zone_keys,
5785 if (result != ISC_R_SUCCESS) {
5786 dns_zone_log(zone, ISC_LOG_ERROR,
5787 "zone_sign:del_sigs -> %s\n",
5788 dns_result_totext(result));
5791 result = add_sigs(db, version, &zone->origin,
5792 dns_rdatatype_nsec, &sig_diff, zone_keys,
5793 nkeys, zone->mctx, inception, soaexpire,
5795 if (result != ISC_R_SUCCESS) {
5796 dns_zone_log(zone, ISC_LOG_ERROR,
5797 "zone_sign:add_sigs -> %s\n",
5798 dns_result_totext(result));
5805 * We have changed the RRset above so we need to update
5808 result = del_sigs(zone, db, version, &zone->origin,
5809 zone->privatetype, &sig_diff,
5810 zone_keys, nkeys, now);
5811 if (result != ISC_R_SUCCESS) {
5812 dns_zone_log(zone, ISC_LOG_ERROR,
5813 "zone_sign:del_sigs -> %s\n",
5814 dns_result_totext(result));
5817 result = add_sigs(db, version, &zone->origin,
5818 zone->privatetype, &sig_diff,
5819 zone_keys, nkeys, zone->mctx, inception,
5820 soaexpire, check_ksk);
5821 if (result != ISC_R_SUCCESS) {
5822 dns_zone_log(zone, ISC_LOG_ERROR,
5823 "zone_sign:add_sigs -> %s\n",
5824 dns_result_totext(result));
5830 * Have we changed anything?
5832 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5837 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5838 &sig_diff, zone_keys, nkeys, now);
5839 if (result != ISC_R_SUCCESS) {
5840 dns_zone_log(zone, ISC_LOG_ERROR,
5841 "zone_sign:del_sigs -> %s\n",
5842 dns_result_totext(result));
5846 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5847 if (result != ISC_R_SUCCESS) {
5848 dns_zone_log(zone, ISC_LOG_ERROR,
5849 "zone_sign:increment_soa_serial -> %s\n",
5850 dns_result_totext(result));
5855 * Generate maximum life time signatures so that the above loop
5856 * termination is sensible.
5858 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5859 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5860 soaexpire, check_ksk);
5861 if (result != ISC_R_SUCCESS) {
5862 dns_zone_log(zone, ISC_LOG_ERROR,
5863 "zone_sign:add_sigs -> %s\n",
5864 dns_result_totext(result));
5869 * Write changes to journal file.
5871 journalfile = dns_zone_getjournal(zone);
5872 if (journalfile != NULL) {
5873 dns_journal_t *journal = NULL;
5874 result = dns_journal_open(zone->mctx, journalfile,
5875 ISC_TRUE, &journal);
5876 if (result != ISC_R_SUCCESS) {
5877 dns_zone_log(zone, ISC_LOG_ERROR,
5878 "zone_sign:dns_journal_open -> %s\n",
5879 dns_result_totext(result));
5883 result = dns_journal_write_transaction(journal, &sig_diff);
5884 dns_journal_destroy(&journal);
5885 if (result != ISC_R_SUCCESS) {
5886 dns_zone_log(zone, ISC_LOG_ERROR,
5887 "zone_sign:dns_journal_write_transaction -> %s\n",
5888 dns_result_totext(result));
5895 * Pause all iterators so that dns_db_closeversion() can succeed.
5897 for (signing = ISC_LIST_HEAD(zone->signing);
5899 signing = ISC_LIST_NEXT(signing, link))
5900 dns_dbiterator_pause(signing->dbiterator);
5902 for (signing = ISC_LIST_HEAD(cleanup);
5904 signing = ISC_LIST_NEXT(signing, link))
5905 dns_dbiterator_pause(signing->dbiterator);
5908 * Everything has succeeded. Commit the changes.
5910 dns_db_closeversion(db, &version, commit);
5913 * Everything succeeded so we can clean these up now.
5915 signing = ISC_LIST_HEAD(cleanup);
5916 while (signing != NULL) {
5917 ISC_LIST_UNLINK(cleanup, signing, link);
5918 dns_db_detach(&signing->db);
5919 dns_dbiterator_destroy(&signing->dbiterator);
5920 isc_mem_put(zone->mctx, signing, sizeof *signing);
5921 signing = ISC_LIST_HEAD(cleanup);
5924 set_resigntime(zone);
5928 zone_needdump(zone, DNS_DUMP_DELAY);
5934 * Rollback the cleanup list.
5936 signing = ISC_LIST_HEAD(cleanup);
5937 while (signing != NULL) {
5938 ISC_LIST_UNLINK(cleanup, signing, link);
5939 ISC_LIST_APPEND(zone->signing, signing, link);
5940 dns_dbiterator_first(signing->dbiterator);
5941 dns_dbiterator_pause(signing->dbiterator);
5942 signing = ISC_LIST_HEAD(cleanup);
5945 for (signing = ISC_LIST_HEAD(zone->signing);
5947 signing = ISC_LIST_NEXT(signing, link))
5948 dns_dbiterator_pause(signing->dbiterator);
5950 dns_diff_clear(&sig_diff);
5952 for (i = 0; i < nkeys; i++)
5953 dst_key_free(&zone_keys[i]);
5955 if (version != NULL) {
5956 dns_db_closeversion(db, &version, ISC_FALSE);
5958 } else if (db != NULL)
5961 if (ISC_LIST_HEAD(zone->signing) != NULL) {
5963 if (zone->update_disabled || result != ISC_R_SUCCESS)
5964 isc_interval_set(&i, 60, 0); /* 1 minute */
5966 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5967 isc_time_nowplusinterval(&zone->signingtime, &i);
5969 isc_time_settoepoch(&zone->signingtime);
5973 zone_maintenance(dns_zone_t *zone) {
5974 const char me[] = "zone_maintenance";
5976 isc_result_t result;
5977 isc_boolean_t dumping;
5979 REQUIRE(DNS_ZONE_VALID(zone));
5983 * Configuring the view of this zone may have
5984 * failed, for example because the config file
5985 * had a syntax error. In that case, the view
5986 * adb or resolver, and we had better not try
5987 * to do maintenance on it.
5989 if (zone->view == NULL || zone->view->adb == NULL)
5997 switch (zone->type) {
5998 case dns_zone_slave:
6001 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
6002 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6004 zone->refreshtime = now;
6015 switch (zone->type) {
6016 case dns_zone_slave:
6018 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
6019 isc_time_compare(&now, &zone->refreshtime) >= 0)
6020 dns_zone_refresh(zone);
6027 * Do we need to consolidate the backing store?
6029 switch (zone->type) {
6030 case dns_zone_master:
6031 case dns_zone_slave:
6033 if (zone->masterfile != NULL &&
6034 isc_time_compare(&now, &zone->dumptime) >= 0 &&
6035 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
6036 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
6037 dumping = was_dumping(zone);
6042 result = zone_dump(zone, ISC_TRUE); /* task locked */
6043 if (result != ISC_R_SUCCESS)
6044 dns_zone_log(zone, ISC_LOG_WARNING,
6046 dns_result_totext(result));
6053 switch (zone->type) {
6054 case dns_zone_master:
6055 case dns_zone_slave:
6057 * Do we need to send out notify messages?
6059 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
6060 isc_time_compare(&now, &zone->notifytime) >= 0)
6061 zone_notify(zone, &now);
6063 * Do we need to sign/resign some RRsets?
6065 if (!isc_time_isepoch(&zone->signingtime) &&
6066 isc_time_compare(&now, &zone->signingtime) >= 0)
6068 else if (!isc_time_isepoch(&zone->resigntime) &&
6069 isc_time_compare(&now, &zone->resigntime) >= 0)
6070 zone_resigninc(zone);
6071 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
6072 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
6073 zone_nsec3chain(zone);
6075 * Do we need to issue a key expiry warning.
6077 if (!isc_time_isepoch(&zone->keywarntime) &&
6078 isc_time_compare(&now, &zone->keywarntime) >= 0)
6079 set_key_expiry_warning(zone, zone->key_expiry,
6080 isc_time_seconds(&now));
6085 zone_settimer(zone, &now);
6089 dns_zone_markdirty(dns_zone_t *zone) {
6092 set_resigntime(zone); /* XXXMPA make separate call back */
6093 zone_needdump(zone, DNS_DUMP_DELAY);
6098 dns_zone_expire(dns_zone_t *zone) {
6099 REQUIRE(DNS_ZONE_VALID(zone));
6107 zone_expire(dns_zone_t *zone) {
6109 * 'zone' locked by caller.
6112 REQUIRE(LOCKED_ZONE(zone));
6114 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
6116 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
6117 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
6118 zone->retry = DNS_ZONE_DEFAULTRETRY;
6119 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6124 dns_zone_refresh(dns_zone_t *zone) {
6126 isc_uint32_t oldflags;
6128 isc_result_t result;
6130 REQUIRE(DNS_ZONE_VALID(zone));
6132 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
6136 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
6137 * in progress at a time.
6141 oldflags = zone->flags;
6142 if (zone->masterscnt == 0) {
6143 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
6144 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
6145 dns_zone_log(zone, ISC_LOG_ERROR,
6146 "cannot refresh: no masters");
6149 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6150 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
6151 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6152 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
6156 * Set the next refresh time as if refresh check has failed.
6157 * Setting this to the retry time will do that. XXXMLG
6158 * If we are successful it will be reset using zone->refresh.
6160 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
6162 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
6163 if (result |= ISC_R_SUCCESS)
6164 dns_zone_log(zone, ISC_LOG_WARNING,
6165 "isc_time_nowplusinterval() failed: %s",
6166 dns_result_totext(result));
6169 * When lacking user-specified timer values from the SOA,
6170 * do exponential backoff of the retry time up to a
6171 * maximum of six hours.
6173 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
6174 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
6176 zone->curmaster = 0;
6177 for (j = 0; j < zone->masterscnt; j++)
6178 zone->mastersok[j] = ISC_FALSE;
6179 /* initiate soa query */
6180 queue_soa_query(zone);
6186 dns_zone_flush(dns_zone_t *zone) {
6187 isc_result_t result = ISC_R_SUCCESS;
6188 isc_boolean_t dumping;
6190 REQUIRE(DNS_ZONE_VALID(zone));
6193 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
6194 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6195 zone->masterfile != NULL) {
6196 result = ISC_R_ALREADYRUNNING;
6197 dumping = was_dumping(zone);
6202 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6207 dns_zone_dump(dns_zone_t *zone) {
6208 isc_result_t result = ISC_R_ALREADYRUNNING;
6209 isc_boolean_t dumping;
6211 REQUIRE(DNS_ZONE_VALID(zone));
6214 dumping = was_dumping(zone);
6217 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6222 zone_needdump(dns_zone_t *zone, unsigned int delay) {
6223 isc_time_t dumptime;
6227 * 'zone' locked by caller
6230 REQUIRE(DNS_ZONE_VALID(zone));
6231 REQUIRE(LOCKED_ZONE(zone));
6234 * Do we have a place to dump to and are we loaded?
6236 if (zone->masterfile == NULL ||
6237 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
6241 /* add some noise */
6242 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
6244 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6245 if (isc_time_isepoch(&zone->dumptime) ||
6246 isc_time_compare(&zone->dumptime, &dumptime) > 0)
6247 zone->dumptime = dumptime;
6248 if (zone->task != NULL)
6249 zone_settimer(zone, &now);
6253 dump_done(void *arg, isc_result_t result) {
6254 const char me[] = "dump_done";
6255 dns_zone_t *zone = arg;
6257 dns_dbversion_t *version;
6258 isc_boolean_t again = ISC_FALSE;
6259 isc_boolean_t compact = ISC_FALSE;
6260 isc_uint32_t serial;
6261 isc_result_t tresult;
6263 REQUIRE(DNS_ZONE_VALID(zone));
6267 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
6268 zone->journalsize != -1) {
6271 * We don't own these, zone->dctx must stay valid.
6273 db = dns_dumpctx_db(zone->dctx);
6274 version = dns_dumpctx_version(zone->dctx);
6276 tresult = dns_db_getsoaserial(db, version, &serial);
6278 * Note: we are task locked here so we can test
6281 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
6282 tresult = dns_journal_compact(zone->mctx,
6289 case ISC_R_NOTFOUND:
6290 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6291 "dns_journal_compact: %s",
6292 dns_result_totext(tresult));
6295 dns_zone_log(zone, ISC_LOG_ERROR,
6296 "dns_journal_compact failed: %s",
6297 dns_result_totext(tresult));
6300 } else if (tresult == ISC_R_SUCCESS) {
6302 zone->compact_serial = serial;
6307 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6309 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
6310 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
6312 * Try again in a short while.
6314 zone_needdump(zone, DNS_DUMP_DELAY);
6315 } else if (result == ISC_R_SUCCESS &&
6316 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6317 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6318 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6319 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6320 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6321 isc_time_settoepoch(&zone->dumptime);
6323 } else if (result == ISC_R_SUCCESS)
6324 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6326 if (zone->dctx != NULL)
6327 dns_dumpctx_detach(&zone->dctx);
6328 zonemgr_putio(&zone->writeio);
6331 (void)zone_dump(zone, ISC_FALSE);
6332 dns_zone_idetach(&zone);
6336 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
6337 const char me[] = "zone_dump";
6338 isc_result_t result;
6339 dns_dbversion_t *version = NULL;
6340 isc_boolean_t again;
6341 dns_db_t *db = NULL;
6342 char *masterfile = NULL;
6343 dns_masterformat_t masterformat = dns_masterformat_none;
6346 * 'compact' MUST only be set if we are task locked.
6349 REQUIRE(DNS_ZONE_VALID(zone));
6353 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6354 if (zone->db != NULL)
6355 dns_db_attach(zone->db, &db);
6356 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6358 if (zone->masterfile != NULL) {
6359 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
6360 masterformat = zone->masterformat;
6364 result = DNS_R_NOTLOADED;
6367 if (masterfile == NULL) {
6368 result = DNS_R_NOMASTERFILE;
6373 dns_zone_t *dummy = NULL;
6375 zone_iattach(zone, &dummy);
6376 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
6377 zone_gotwritehandle, zone,
6379 if (result != ISC_R_SUCCESS)
6380 zone_idetach(&dummy);
6382 result = DNS_R_CONTINUE;
6385 dns_db_currentversion(db, &version);
6386 result = dns_master_dump2(zone->mctx, db, version,
6387 &dns_master_style_default,
6388 masterfile, masterformat);
6389 dns_db_closeversion(db, &version, ISC_FALSE);
6394 if (masterfile != NULL)
6395 isc_mem_free(zone->mctx, masterfile);
6398 if (result == DNS_R_CONTINUE)
6399 return (ISC_R_SUCCESS); /* XXXMPA */
6403 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6404 if (result != ISC_R_SUCCESS) {
6406 * Try again in a short while.
6408 zone_needdump(zone, DNS_DUMP_DELAY);
6409 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6410 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6411 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6412 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6413 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6414 isc_time_settoepoch(&zone->dumptime);
6417 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6426 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
6427 dns_masterformat_t format)
6429 isc_result_t result;
6430 dns_dbversion_t *version = NULL;
6431 dns_db_t *db = NULL;
6433 REQUIRE(DNS_ZONE_VALID(zone));
6435 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6436 if (zone->db != NULL)
6437 dns_db_attach(zone->db, &db);
6438 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6440 return (DNS_R_NOTLOADED);
6442 dns_db_currentversion(db, &version);
6443 result = dns_master_dumptostream2(zone->mctx, db, version, style,
6445 dns_db_closeversion(db, &version, ISC_FALSE);
6451 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
6452 const dns_master_style_t *style) {
6453 return dumptostream(zone, fd, style, format);
6457 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
6458 return dumptostream(zone, fd, &dns_master_style_default,
6459 dns_masterformat_text);
6463 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
6464 return dumptostream(zone, fd, &dns_master_style_full,
6465 dns_masterformat_text);
6469 dns_zone_unload(dns_zone_t *zone) {
6470 REQUIRE(DNS_ZONE_VALID(zone));
6478 notify_cancel(dns_zone_t *zone) {
6479 dns_notify_t *notify;
6482 * 'zone' locked by caller.
6485 REQUIRE(LOCKED_ZONE(zone));
6487 for (notify = ISC_LIST_HEAD(zone->notifies);
6489 notify = ISC_LIST_NEXT(notify, link)) {
6490 if (notify->find != NULL)
6491 dns_adb_cancelfind(notify->find);
6492 if (notify->request != NULL)
6493 dns_request_cancel(notify->request);
6498 zone_unload(dns_zone_t *zone) {
6501 * 'zone' locked by caller.
6504 REQUIRE(LOCKED_ZONE(zone));
6506 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6507 zone_detachdb(zone);
6508 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6509 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
6510 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6514 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6515 REQUIRE(DNS_ZONE_VALID(zone));
6518 zone->minrefresh = val;
6522 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6523 REQUIRE(DNS_ZONE_VALID(zone));
6526 zone->maxrefresh = val;
6530 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
6531 REQUIRE(DNS_ZONE_VALID(zone));
6534 zone->minretry = val;
6538 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
6539 REQUIRE(DNS_ZONE_VALID(zone));
6542 zone->maxretry = val;
6545 static isc_boolean_t
6546 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
6547 dns_notify_t *notify;
6549 for (notify = ISC_LIST_HEAD(zone->notifies);
6551 notify = ISC_LIST_NEXT(notify, link)) {
6552 if (notify->request != NULL)
6554 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
6555 dns_name_equal(name, ¬ify->ns))
6557 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
6563 static isc_boolean_t
6564 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
6565 dns_tsigkey_t *key = NULL;
6568 isc_boolean_t isself;
6569 isc_netaddr_t dstaddr;
6570 isc_result_t result;
6572 if (zone->view == NULL || zone->isself == NULL)
6575 switch (isc_sockaddr_pf(dst)) {
6577 src = zone->notifysrc4;
6578 isc_sockaddr_any(&any);
6581 src = zone->notifysrc6;
6582 isc_sockaddr_any6(&any);
6589 * When sending from any the kernel will assign a source address
6590 * that matches the destination address.
6592 if (isc_sockaddr_eqaddr(&any, &src))
6595 isc_netaddr_fromsockaddr(&dstaddr, dst);
6596 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
6597 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
6599 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
6602 dns_tsigkey_detach(&key);
6607 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
6611 * Caller holds zone lock.
6613 REQUIRE(DNS_NOTIFY_VALID(notify));
6615 if (notify->zone != NULL) {
6617 LOCK_ZONE(notify->zone);
6618 REQUIRE(LOCKED_ZONE(notify->zone));
6619 if (ISC_LINK_LINKED(notify, link))
6620 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
6622 UNLOCK_ZONE(notify->zone);
6624 zone_idetach(¬ify->zone);
6626 dns_zone_idetach(¬ify->zone);
6628 if (notify->find != NULL)
6629 dns_adb_destroyfind(¬ify->find);
6630 if (notify->request != NULL)
6631 dns_request_destroy(¬ify->request);
6632 if (dns_name_dynamic(¬ify->ns))
6633 dns_name_free(¬ify->ns, notify->mctx);
6634 mctx = notify->mctx;
6635 isc_mem_put(notify->mctx, notify, sizeof(*notify));
6636 isc_mem_detach(&mctx);
6640 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
6641 dns_notify_t *notify;
6643 REQUIRE(notifyp != NULL && *notifyp == NULL);
6645 notify = isc_mem_get(mctx, sizeof(*notify));
6647 return (ISC_R_NOMEMORY);
6649 notify->mctx = NULL;
6650 isc_mem_attach(mctx, ¬ify->mctx);
6651 notify->flags = flags;
6652 notify->zone = NULL;
6653 notify->find = NULL;
6654 notify->request = NULL;
6655 isc_sockaddr_any(¬ify->dst);
6656 dns_name_init(¬ify->ns, NULL);
6657 ISC_LINK_INIT(notify, link);
6658 notify->magic = NOTIFY_MAGIC;
6660 return (ISC_R_SUCCESS);
6664 * XXXAG should check for DNS_ZONEFLG_EXITING
6667 process_adb_event(isc_task_t *task, isc_event_t *ev) {
6668 dns_notify_t *notify;
6669 isc_eventtype_t result;
6673 notify = ev->ev_arg;
6674 REQUIRE(DNS_NOTIFY_VALID(notify));
6675 INSIST(task == notify->zone->task);
6676 result = ev->ev_type;
6677 isc_event_free(&ev);
6678 if (result == DNS_EVENT_ADBMOREADDRESSES) {
6679 dns_adb_destroyfind(¬ify->find);
6680 notify_find_address(notify);
6683 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
6684 LOCK_ZONE(notify->zone);
6685 notify_send(notify);
6686 UNLOCK_ZONE(notify->zone);
6688 notify_destroy(notify, ISC_FALSE);
6692 notify_find_address(dns_notify_t *notify) {
6693 isc_result_t result;
6694 unsigned int options;
6696 REQUIRE(DNS_NOTIFY_VALID(notify));
6697 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
6698 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
6700 if (notify->zone->view->adb == NULL)
6703 result = dns_adb_createfind(notify->zone->view->adb,
6705 process_adb_event, notify,
6706 ¬ify->ns, dns_rootname, 0,
6708 notify->zone->view->dstport,
6711 /* Something failed? */
6712 if (result != ISC_R_SUCCESS)
6715 /* More addresses pending? */
6716 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
6719 /* We have as many addresses as we can get. */
6720 LOCK_ZONE(notify->zone);
6721 notify_send(notify);
6722 UNLOCK_ZONE(notify->zone);
6725 notify_destroy(notify, ISC_FALSE);
6730 notify_send_queue(dns_notify_t *notify) {
6732 isc_result_t result;
6734 e = isc_event_allocate(notify->mctx, NULL,
6735 DNS_EVENT_NOTIFYSENDTOADDR,
6737 notify, sizeof(isc_event_t));
6739 return (ISC_R_NOMEMORY);
6741 e->ev_sender = NULL;
6742 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
6743 notify->zone->task, &e);
6744 if (result != ISC_R_SUCCESS)
6750 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
6751 dns_notify_t *notify;
6752 isc_result_t result;
6753 dns_message_t *message = NULL;
6754 isc_netaddr_t dstip;
6755 dns_tsigkey_t *key = NULL;
6756 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6759 isc_boolean_t have_notifysource = ISC_FALSE;
6761 notify = event->ev_arg;
6762 REQUIRE(DNS_NOTIFY_VALID(notify));
6766 LOCK_ZONE(notify->zone);
6768 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
6769 result = ISC_R_CANCELED;
6773 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
6774 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
6775 notify->zone->view->requestmgr == NULL ||
6776 notify->zone->db == NULL) {
6777 result = ISC_R_CANCELED;
6782 * The raw IPv4 address should also exist. Don't send to the
6785 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
6786 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
6787 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6788 notify_log(notify->zone, ISC_LOG_DEBUG(3),
6789 "notify: ignoring IPv6 mapped IPV4 address: %s",
6791 result = ISC_R_CANCELED;
6795 result = notify_createmessage(notify->zone, notify->flags, &message);
6796 if (result != ISC_R_SUCCESS)
6799 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
6800 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6801 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
6802 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6803 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
6804 "sent. Peer TSIG key lookup failure.", addrbuf);
6805 goto cleanup_message;
6808 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
6810 if (notify->zone->view->peers != NULL) {
6811 dns_peer_t *peer = NULL;
6812 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
6814 if (result == ISC_R_SUCCESS) {
6815 result = dns_peer_getnotifysource(peer, &src);
6816 if (result == ISC_R_SUCCESS)
6817 have_notifysource = ISC_TRUE;
6820 switch (isc_sockaddr_pf(¬ify->dst)) {
6822 if (!have_notifysource)
6823 src = notify->zone->notifysrc4;
6826 if (!have_notifysource)
6827 src = notify->zone->notifysrc6;
6830 result = ISC_R_NOTIMPLEMENTED;
6834 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
6836 result = dns_request_createvia2(notify->zone->view->requestmgr,
6837 message, &src, ¬ify->dst, 0, key,
6838 timeout * 3, timeout,
6839 notify->zone->task, notify_done,
6840 notify, ¬ify->request);
6841 if (result == ISC_R_SUCCESS) {
6842 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
6843 inc_stats(notify->zone,
6844 dns_zonestatscounter_notifyoutv4);
6846 inc_stats(notify->zone,
6847 dns_zonestatscounter_notifyoutv6);
6853 dns_tsigkey_detach(&key);
6855 dns_message_destroy(&message);
6857 UNLOCK_ZONE(notify->zone);
6858 if (result != ISC_R_SUCCESS)
6859 notify_destroy(notify, ISC_FALSE);
6860 isc_event_free(&event);
6864 notify_send(dns_notify_t *notify) {
6865 dns_adbaddrinfo_t *ai;
6867 isc_result_t result;
6868 dns_notify_t *new = NULL;
6871 * Zone lock held by caller.
6873 REQUIRE(DNS_NOTIFY_VALID(notify));
6874 REQUIRE(LOCKED_ZONE(notify->zone));
6876 for (ai = ISC_LIST_HEAD(notify->find->list);
6878 ai = ISC_LIST_NEXT(ai, publink)) {
6880 if (notify_isqueued(notify->zone, NULL, &dst))
6882 if (notify_isself(notify->zone, &dst))
6885 result = notify_create(notify->mctx,
6886 (notify->flags & DNS_NOTIFY_NOSOA),
6888 if (result != ISC_R_SUCCESS)
6890 zone_iattach(notify->zone, &new->zone);
6891 ISC_LIST_APPEND(new->zone->notifies, new, link);
6893 result = notify_send_queue(new);
6894 if (result != ISC_R_SUCCESS)
6901 notify_destroy(new, ISC_TRUE);
6905 dns_zone_notify(dns_zone_t *zone) {
6908 REQUIRE(DNS_ZONE_VALID(zone));
6911 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6914 zone_settimer(zone, &now);
6919 zone_notify(dns_zone_t *zone, isc_time_t *now) {
6920 dns_dbnode_t *node = NULL;
6921 dns_db_t *zonedb = NULL;
6922 dns_dbversion_t *version = NULL;
6923 dns_name_t *origin = NULL;
6926 dns_rdata_soa_t soa;
6927 isc_uint32_t serial;
6928 dns_rdata_t rdata = DNS_RDATA_INIT;
6929 dns_rdataset_t nsrdset;
6930 dns_rdataset_t soardset;
6931 isc_result_t result;
6932 dns_notify_t *notify = NULL;
6935 isc_boolean_t isqueued;
6936 dns_notifytype_t notifytype;
6937 unsigned int flags = 0;
6938 isc_boolean_t loggednotify = ISC_FALSE;
6940 REQUIRE(DNS_ZONE_VALID(zone));
6943 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6944 notifytype = zone->notifytype;
6945 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
6948 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
6951 if (notifytype == dns_notifytype_no)
6954 if (notifytype == dns_notifytype_masteronly &&
6955 zone->type != dns_zone_master)
6958 origin = &zone->origin;
6961 * If the zone is dialup we are done as we don't want to send
6962 * the current soa so as to force a refresh query.
6964 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
6965 flags |= DNS_NOTIFY_NOSOA;
6970 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6971 if (zone->db != NULL)
6972 dns_db_attach(zone->db, &zonedb);
6973 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6976 dns_db_currentversion(zonedb, &version);
6977 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
6978 if (result != ISC_R_SUCCESS)
6981 dns_rdataset_init(&soardset);
6982 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
6983 dns_rdatatype_none, 0, &soardset, NULL);
6984 if (result != ISC_R_SUCCESS)
6988 * Find serial and master server's name.
6990 dns_name_init(&master, NULL);
6991 result = dns_rdataset_first(&soardset);
6992 if (result != ISC_R_SUCCESS)
6994 dns_rdataset_current(&soardset, &rdata);
6995 result = dns_rdata_tostruct(&rdata, &soa, NULL);
6996 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6997 dns_rdata_reset(&rdata);
6998 result = dns_name_dup(&soa.origin, zone->mctx, &master);
6999 serial = soa.serial;
7000 dns_rdataset_disassociate(&soardset);
7001 if (result != ISC_R_SUCCESS)
7005 * Enqueue notify requests for 'also-notify' servers.
7008 for (i = 0; i < zone->notifycnt; i++) {
7009 dst = zone->notify[i];
7010 if (notify_isqueued(zone, NULL, &dst))
7012 result = notify_create(zone->mctx, flags, ¬ify);
7013 if (result != ISC_R_SUCCESS)
7015 zone_iattach(zone, ¬ify->zone);
7017 ISC_LIST_APPEND(zone->notifies, notify, link);
7018 result = notify_send_queue(notify);
7019 if (result != ISC_R_SUCCESS)
7020 notify_destroy(notify, ISC_TRUE);
7021 if (!loggednotify) {
7022 notify_log(zone, ISC_LOG_INFO,
7023 "sending notifies (serial %u)",
7025 loggednotify = ISC_TRUE;
7031 if (notifytype == dns_notifytype_explicit)
7035 * Process NS RRset to generate notifies.
7038 dns_rdataset_init(&nsrdset);
7039 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
7040 dns_rdatatype_none, 0, &nsrdset, NULL);
7041 if (result != ISC_R_SUCCESS)
7044 result = dns_rdataset_first(&nsrdset);
7045 while (result == ISC_R_SUCCESS) {
7046 dns_rdataset_current(&nsrdset, &rdata);
7047 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7048 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7049 dns_rdata_reset(&rdata);
7051 * Don't notify the master server unless explicitly
7052 * configured to do so.
7054 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
7055 dns_name_compare(&master, &ns.name) == 0) {
7056 result = dns_rdataset_next(&nsrdset);
7060 if (!loggednotify) {
7061 notify_log(zone, ISC_LOG_INFO,
7062 "sending notifies (serial %u)",
7064 loggednotify = ISC_TRUE;
7068 isqueued = notify_isqueued(zone, &ns.name, NULL);
7071 result = dns_rdataset_next(&nsrdset);
7074 result = notify_create(zone->mctx, flags, ¬ify);
7075 if (result != ISC_R_SUCCESS)
7077 dns_zone_iattach(zone, ¬ify->zone);
7078 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
7079 if (result != ISC_R_SUCCESS) {
7081 notify_destroy(notify, ISC_TRUE);
7086 ISC_LIST_APPEND(zone->notifies, notify, link);
7088 notify_find_address(notify);
7090 result = dns_rdataset_next(&nsrdset);
7092 dns_rdataset_disassociate(&nsrdset);
7095 if (dns_name_dynamic(&master))
7096 dns_name_free(&master, zone->mctx);
7098 dns_db_detachnode(zonedb, &node);
7100 dns_db_closeversion(zonedb, &version, ISC_FALSE);
7101 dns_db_detach(&zonedb);
7108 static inline isc_result_t
7109 save_nsrrset(dns_message_t *message, dns_name_t *name,
7110 dns_db_t *db, dns_dbversion_t *version)
7112 dns_rdataset_t *nsrdataset = NULL;
7113 dns_rdataset_t *rdataset = NULL;
7114 dns_dbnode_t *node = NULL;
7116 isc_result_t result;
7117 dns_rdata_t rdata = DNS_RDATA_INIT;
7120 * Extract NS RRset from message.
7122 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
7123 dns_rdatatype_ns, dns_rdatatype_none,
7125 if (result != ISC_R_SUCCESS)
7131 result = dns_db_findnode(db, name, ISC_TRUE, &node);
7132 if (result != ISC_R_SUCCESS)
7134 result = dns_db_addrdataset(db, node, version, 0,
7135 nsrdataset, 0, NULL);
7136 dns_db_detachnode(db, &node);
7137 if (result != ISC_R_SUCCESS)
7140 * Add glue rdatasets.
7142 for (result = dns_rdataset_first(nsrdataset);
7143 result == ISC_R_SUCCESS;
7144 result = dns_rdataset_next(nsrdataset)) {
7145 dns_rdataset_current(nsrdataset, &rdata);
7146 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7147 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7148 dns_rdata_reset(&rdata);
7149 if (!dns_name_issubdomain(&ns.name, name))
7152 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7153 &ns.name, dns_rdatatype_aaaa,
7154 dns_rdatatype_none, NULL,
7156 if (result == ISC_R_SUCCESS) {
7157 result = dns_db_findnode(db, &ns.name,
7159 if (result != ISC_R_SUCCESS)
7161 result = dns_db_addrdataset(db, node, version, 0,
7163 dns_db_detachnode(db, &node);
7164 if (result != ISC_R_SUCCESS)
7168 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7169 &ns.name, dns_rdatatype_a,
7170 dns_rdatatype_none, NULL,
7172 if (result == ISC_R_SUCCESS) {
7173 result = dns_db_findnode(db, &ns.name,
7175 if (result != ISC_R_SUCCESS)
7177 result = dns_db_addrdataset(db, node, version, 0,
7179 dns_db_detachnode(db, &node);
7180 if (result != ISC_R_SUCCESS)
7184 if (result != ISC_R_NOMORE)
7187 return (ISC_R_SUCCESS);
7194 stub_callback(isc_task_t *task, isc_event_t *event) {
7195 const char me[] = "stub_callback";
7196 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7197 dns_stub_t *stub = NULL;
7198 dns_message_t *msg = NULL;
7199 dns_zone_t *zone = NULL;
7200 char master[ISC_SOCKADDR_FORMATSIZE];
7201 char source[ISC_SOCKADDR_FORMATSIZE];
7202 isc_uint32_t nscnt, cnamecnt;
7203 isc_result_t result;
7205 isc_boolean_t exiting = ISC_FALSE;
7209 stub = revent->ev_arg;
7210 INSIST(DNS_STUB_VALID(stub));
7220 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7221 zone_debuglog(zone, me, 1, "exiting");
7226 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7227 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7229 if (revent->result != ISC_R_SUCCESS) {
7230 if (revent->result == ISC_R_TIMEDOUT &&
7231 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7233 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7235 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7236 "refreshing stub: timeout retrying "
7237 " without EDNS master %s (source %s)",
7241 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
7242 &zone->sourceaddr, &now);
7243 dns_zone_log(zone, ISC_LOG_INFO,
7244 "could not refresh stub from master %s"
7245 " (source %s): %s", master, source,
7246 dns_result_totext(revent->result));
7250 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7251 if (result != ISC_R_SUCCESS)
7254 result = dns_request_getresponse(revent->request, msg, 0);
7255 if (result != ISC_R_SUCCESS)
7261 if (msg->rcode != dns_rcode_noerror) {
7265 isc_buffer_init(&rb, rcode, sizeof(rcode));
7266 (void)dns_rcode_totext(msg->rcode, &rb);
7268 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7269 (msg->rcode == dns_rcode_servfail ||
7270 msg->rcode == dns_rcode_notimp ||
7271 msg->rcode == dns_rcode_formerr)) {
7272 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7273 "refreshing stub: rcode (%.*s) retrying "
7274 "without EDNS master %s (source %s)",
7275 (int)rb.used, rcode, master, source);
7277 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7282 dns_zone_log(zone, ISC_LOG_INFO,
7284 "unexpected rcode (%.*s) from %s (source %s)",
7285 (int)rb.used, rcode, master, source);
7290 * We need complete messages.
7292 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7293 if (dns_request_usedtcp(revent->request)) {
7294 dns_zone_log(zone, ISC_LOG_INFO,
7295 "refreshing stub: truncated TCP "
7296 "response from master %s (source %s)",
7301 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7307 * If non-auth log and next master.
7309 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7310 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
7311 "non-authoritative answer from "
7312 "master %s (source %s)", master, source);
7319 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7320 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
7322 if (cnamecnt != 0) {
7323 dns_zone_log(zone, ISC_LOG_INFO,
7324 "refreshing stub: unexpected CNAME response "
7325 "from master %s (source %s)", master, source);
7330 dns_zone_log(zone, ISC_LOG_INFO,
7331 "refreshing stub: no NS records in response "
7332 "from master %s (source %s)", master, source);
7339 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
7340 if (result != ISC_R_SUCCESS) {
7341 dns_zone_log(zone, ISC_LOG_INFO,
7342 "refreshing stub: unable to save NS records "
7343 "from master %s (source %s)", master, source);
7350 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
7351 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
7352 if (zone->db == NULL)
7353 zone_attachdb(zone, stub->db);
7354 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
7355 dns_db_detach(&stub->db);
7357 if (zone->masterfile != NULL) {
7358 dns_zone_dump(zone);
7359 TIME_NOW(&zone->loadtime);
7362 dns_message_destroy(&msg);
7363 isc_event_free(&event);
7365 dns_request_destroy(&zone->request);
7366 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7367 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7368 isc_interval_set(&i, zone->expire, 0);
7369 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7370 zone_settimer(zone, &now);
7375 if (stub->version != NULL)
7376 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
7377 if (stub->db != NULL)
7378 dns_db_detach(&stub->db);
7380 dns_message_destroy(&msg);
7381 isc_event_free(&event);
7383 dns_request_destroy(&zone->request);
7385 * Skip to next failed / untried master.
7389 } while (zone->curmaster < zone->masterscnt &&
7390 zone->mastersok[zone->curmaster]);
7391 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7392 if (exiting || zone->curmaster >= zone->masterscnt) {
7393 isc_boolean_t done = ISC_TRUE;
7395 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7396 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7398 * Did we get a good answer from all the masters?
7400 for (j = 0; j < zone->masterscnt; j++)
7401 if (zone->mastersok[j] == ISC_FALSE) {
7408 zone->curmaster = 0;
7410 * Find the next failed master.
7412 while (zone->curmaster < zone->masterscnt &&
7413 zone->mastersok[zone->curmaster])
7415 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7417 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7419 zone_settimer(zone, &now);
7424 queue_soa_query(zone);
7430 dns_message_destroy(&msg);
7431 isc_event_free(&event);
7433 dns_request_destroy(&zone->request);
7435 ns_query(zone, NULL, stub);
7440 dns_zone_idetach(&stub->zone);
7441 INSIST(stub->db == NULL);
7442 INSIST(stub->version == NULL);
7443 isc_mem_put(stub->mctx, stub, sizeof(*stub));
7446 INSIST(event == NULL);
7451 * An SOA query has finished (successfully or not).
7454 refresh_callback(isc_task_t *task, isc_event_t *event) {
7455 const char me[] = "refresh_callback";
7456 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7458 dns_message_t *msg = NULL;
7459 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
7461 char master[ISC_SOCKADDR_FORMATSIZE];
7462 char source[ISC_SOCKADDR_FORMATSIZE];
7463 dns_rdataset_t *rdataset = NULL;
7464 dns_rdata_t rdata = DNS_RDATA_INIT;
7465 dns_rdata_soa_t soa;
7466 isc_result_t result;
7467 isc_uint32_t serial, oldserial;
7470 zone = revent->ev_arg;
7471 INSIST(DNS_ZONE_VALID(zone));
7478 * if timeout log and next master;
7481 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7482 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7486 if (revent->result != ISC_R_SUCCESS) {
7487 if (revent->result == ISC_R_TIMEDOUT &&
7488 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7490 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7492 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7493 "refresh: timeout retrying without EDNS "
7494 "master %s (source %s)", master, source);
7497 if (revent->result == ISC_R_TIMEDOUT &&
7498 !dns_request_usedtcp(revent->request)) {
7499 dns_zone_log(zone, ISC_LOG_INFO,
7500 "refresh: retry limit for "
7501 "master %s exceeded (source %s)",
7503 /* Try with slave with TCP. */
7504 if (zone->type == dns_zone_slave &&
7505 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
7506 if (!dns_zonemgr_unreachable(zone->zmgr,
7511 DNS_ZONE_SETFLAG(zone,
7512 DNS_ZONEFLG_SOABEFOREAXFR);
7516 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7517 "refresh: skipped tcp fallback"
7518 "as master %s (source %s) is "
7519 "unreachable (cached)",
7523 dns_zone_log(zone, ISC_LOG_INFO,
7524 "refresh: failure trying master "
7525 "%s (source %s): %s", master, source,
7526 dns_result_totext(revent->result));
7530 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7531 if (result != ISC_R_SUCCESS)
7533 result = dns_request_getresponse(revent->request, msg, 0);
7534 if (result != ISC_R_SUCCESS) {
7535 dns_zone_log(zone, ISC_LOG_INFO,
7536 "refresh: failure trying master "
7537 "%s (source %s): %s", master, source,
7538 dns_result_totext(result));
7545 if (msg->rcode != dns_rcode_noerror) {
7549 isc_buffer_init(&rb, rcode, sizeof(rcode));
7550 (void)dns_rcode_totext(msg->rcode, &rb);
7552 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7553 (msg->rcode == dns_rcode_servfail ||
7554 msg->rcode == dns_rcode_notimp ||
7555 msg->rcode == dns_rcode_formerr)) {
7556 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7557 "refresh: rcode (%.*s) retrying without "
7558 "EDNS master %s (source %s)",
7559 (int)rb.used, rcode, master, source);
7561 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7565 dns_zone_log(zone, ISC_LOG_INFO,
7566 "refresh: unexpected rcode (%.*s) from "
7567 "master %s (source %s)", (int)rb.used, rcode,
7570 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
7572 if (msg->rcode == dns_rcode_refused &&
7573 zone->type == dns_zone_slave)
7579 * If truncated punt to zone transfer which will query again.
7581 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7582 if (zone->type == dns_zone_slave) {
7583 dns_zone_log(zone, ISC_LOG_INFO,
7584 "refresh: truncated UDP answer, "
7585 "initiating TCP zone xfer "
7586 "for master %s (source %s)",
7589 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
7593 INSIST(zone->type == dns_zone_stub);
7594 if (dns_request_usedtcp(revent->request)) {
7595 dns_zone_log(zone, ISC_LOG_INFO,
7596 "refresh: truncated TCP response "
7597 "from master %s (source %s)",
7602 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7609 * if non-auth log and next master;
7611 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7612 dns_zone_log(zone, ISC_LOG_INFO,
7613 "refresh: non-authoritative answer from "
7614 "master %s (source %s)", master, source);
7618 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7619 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
7620 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
7621 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
7625 * There should not be a CNAME record at top of zone.
7627 if (cnamecnt != 0) {
7628 dns_zone_log(zone, ISC_LOG_INFO,
7629 "refresh: CNAME at top of zone "
7630 "in master %s (source %s)", master, source);
7635 * if referral log and next master;
7637 if (soacnt == 0 && soacount == 0 && nscount != 0) {
7638 dns_zone_log(zone, ISC_LOG_INFO,
7639 "refresh: referral response "
7640 "from master %s (source %s)", master, source);
7645 * if nodata log and next master;
7647 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
7648 dns_zone_log(zone, ISC_LOG_INFO,
7649 "refresh: NODATA response "
7650 "from master %s (source %s)", master, source);
7655 * Only one soa at top of zone.
7658 dns_zone_log(zone, ISC_LOG_INFO,
7659 "refresh: answer SOA count (%d) != 1 "
7660 "from master %s (source %s)",
7661 soacnt, master, source);
7668 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
7669 dns_rdatatype_soa, dns_rdatatype_none,
7671 if (result != ISC_R_SUCCESS) {
7672 dns_zone_log(zone, ISC_LOG_INFO,
7673 "refresh: unable to get SOA record "
7674 "from master %s (source %s)", master, source);
7678 result = dns_rdataset_first(rdataset);
7679 if (result != ISC_R_SUCCESS) {
7680 dns_zone_log(zone, ISC_LOG_INFO,
7681 "refresh: dns_rdataset_first() failed");
7685 dns_rdataset_current(rdataset, &rdata);
7686 result = dns_rdata_tostruct(&rdata, &soa, NULL);
7687 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7689 serial = soa.serial;
7690 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
7691 result = dns_zone_getserial2(zone, &oldserial);
7692 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7693 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
7696 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
7698 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
7699 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
7700 isc_serial_gt(serial, oldserial)) {
7701 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
7702 &zone->sourceaddr, &now)) {
7703 dns_zone_log(zone, ISC_LOG_INFO,
7704 "refresh: skipping %s as master %s "
7705 "(source %s) is unreachable (cached)",
7706 zone->type == dns_zone_slave ?
7707 "zone transfer" : "NS query",
7712 isc_event_free(&event);
7714 dns_request_destroy(&zone->request);
7716 if (zone->type == dns_zone_slave) {
7719 INSIST(zone->type == dns_zone_stub);
7720 ns_query(zone, rdataset, NULL);
7723 dns_message_destroy(&msg);
7724 } else if (isc_serial_eq(soa.serial, oldserial)) {
7725 if (zone->masterfile != NULL) {
7726 result = ISC_R_FAILURE;
7727 if (zone->journal != NULL)
7728 result = isc_file_settime(zone->journal, &now);
7729 if (result == ISC_R_SUCCESS &&
7730 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
7731 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
7732 result = isc_file_settime(zone->masterfile,
7734 } else if (result != ISC_R_SUCCESS)
7735 result = isc_file_settime(zone->masterfile,
7737 /* Someone removed the file from underneath us! */
7738 if (result == ISC_R_FILENOTFOUND) {
7740 zone_needdump(zone, DNS_DUMP_DELAY);
7742 } else if (result != ISC_R_SUCCESS)
7743 dns_zone_log(zone, ISC_LOG_ERROR,
7744 "refresh: could not set file "
7745 "modification time of '%s': %s",
7747 dns_result_totext(result));
7749 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7750 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7751 zone->mastersok[zone->curmaster] = ISC_TRUE;
7754 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
7755 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
7756 "received from master %s < ours (%u)",
7757 soa.serial, master, oldserial);
7759 zone_debuglog(zone, me, 1, "ahead");
7760 zone->mastersok[zone->curmaster] = ISC_TRUE;
7764 dns_message_destroy(&msg);
7769 dns_message_destroy(&msg);
7770 isc_event_free(&event);
7772 dns_request_destroy(&zone->request);
7774 * Skip to next failed / untried master.
7778 } while (zone->curmaster < zone->masterscnt &&
7779 zone->mastersok[zone->curmaster]);
7780 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7781 if (zone->curmaster >= zone->masterscnt) {
7782 isc_boolean_t done = ISC_TRUE;
7783 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7784 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7786 * Did we get a good answer from all the masters?
7788 for (j = 0; j < zone->masterscnt; j++)
7789 if (zone->mastersok[j] == ISC_FALSE) {
7796 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7797 zone->curmaster = 0;
7799 * Find the next failed master.
7801 while (zone->curmaster < zone->masterscnt &&
7802 zone->mastersok[zone->curmaster])
7806 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7807 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
7808 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
7809 zone->refreshtime = now;
7811 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7812 zone_settimer(zone, &now);
7818 queue_soa_query(zone);
7824 dns_message_destroy(&msg);
7825 isc_event_free(&event);
7827 dns_request_destroy(&zone->request);
7828 queue_soa_query(zone);
7832 dns_zone_idetach(&zone);
7837 queue_soa_query(dns_zone_t *zone) {
7838 const char me[] = "queue_soa_query";
7840 dns_zone_t *dummy = NULL;
7841 isc_result_t result;
7847 REQUIRE(LOCKED_ZONE(zone));
7849 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7850 cancel_refresh(zone);
7854 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
7855 soa_query, zone, sizeof(isc_event_t));
7857 cancel_refresh(zone);
7862 * Attach so that we won't clean up
7863 * until the event is delivered.
7865 zone_iattach(zone, &dummy);
7868 e->ev_sender = NULL;
7869 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
7870 if (result != ISC_R_SUCCESS) {
7871 zone_idetach(&dummy);
7873 cancel_refresh(zone);
7877 static inline isc_result_t
7878 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
7879 dns_message_t **messagep)
7881 dns_message_t *message = NULL;
7882 dns_name_t *qname = NULL;
7883 dns_rdataset_t *qrdataset = NULL;
7884 isc_result_t result;
7886 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
7888 if (result != ISC_R_SUCCESS)
7891 message->opcode = dns_opcode_query;
7892 message->rdclass = zone->rdclass;
7894 result = dns_message_gettempname(message, &qname);
7895 if (result != ISC_R_SUCCESS)
7898 result = dns_message_gettemprdataset(message, &qrdataset);
7899 if (result != ISC_R_SUCCESS)
7905 dns_name_init(qname, NULL);
7906 dns_name_clone(&zone->origin, qname);
7907 dns_rdataset_init(qrdataset);
7908 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
7909 ISC_LIST_APPEND(qname->list, qrdataset, link);
7910 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
7912 *messagep = message;
7913 return (ISC_R_SUCCESS);
7917 dns_message_puttempname(message, &qname);
7918 if (qrdataset != NULL)
7919 dns_message_puttemprdataset(message, &qrdataset);
7920 if (message != NULL)
7921 dns_message_destroy(&message);
7926 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
7927 dns_rdataset_t *rdataset = NULL;
7928 dns_rdatalist_t *rdatalist = NULL;
7929 dns_rdata_t *rdata = NULL;
7930 isc_result_t result;
7932 result = dns_message_gettemprdatalist(message, &rdatalist);
7933 if (result != ISC_R_SUCCESS)
7935 result = dns_message_gettemprdata(message, &rdata);
7936 if (result != ISC_R_SUCCESS)
7938 result = dns_message_gettemprdataset(message, &rdataset);
7939 if (result != ISC_R_SUCCESS)
7941 dns_rdataset_init(rdataset);
7943 rdatalist->type = dns_rdatatype_opt;
7944 rdatalist->covers = 0;
7947 * Set Maximum UDP buffer size.
7949 rdatalist->rdclass = udpsize;
7952 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
7956 /* Set EDNS options if applicable */
7958 unsigned char data[4];
7961 isc_buffer_init(&buf, data, sizeof(data));
7962 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
7963 isc_buffer_putuint16(&buf, 0);
7965 rdata->length = sizeof(data);
7971 rdata->rdclass = rdatalist->rdclass;
7972 rdata->type = rdatalist->type;
7975 ISC_LIST_INIT(rdatalist->rdata);
7976 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
7977 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
7980 return (dns_message_setopt(message, rdataset));
7983 if (rdatalist != NULL)
7984 dns_message_puttemprdatalist(message, &rdatalist);
7985 if (rdataset != NULL)
7986 dns_message_puttemprdataset(message, &rdataset);
7988 dns_message_puttemprdata(message, &rdata);
7994 soa_query(isc_task_t *task, isc_event_t *event) {
7995 const char me[] = "soa_query";
7996 isc_result_t result = ISC_R_FAILURE;
7997 dns_message_t *message = NULL;
7998 dns_zone_t *zone = event->ev_arg;
7999 dns_zone_t *dummy = NULL;
8000 isc_netaddr_t masterip;
8001 dns_tsigkey_t *key = NULL;
8002 isc_uint32_t options;
8003 isc_boolean_t cancel = ISC_TRUE;
8005 isc_boolean_t have_xfrsource, reqnsid;
8006 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8008 REQUIRE(DNS_ZONE_VALID(zone));
8015 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
8016 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
8017 zone->view->requestmgr == NULL) {
8018 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8024 * XXX Optimisation: Create message when zone is setup and reuse.
8026 result = create_query(zone, dns_rdatatype_soa, &message);
8027 if (result != ISC_R_SUCCESS)
8031 INSIST(zone->masterscnt > 0);
8032 INSIST(zone->curmaster < zone->masterscnt);
8034 zone->masteraddr = zone->masters[zone->curmaster];
8036 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8038 * First, look for a tsig key in the master statement, then
8039 * try for a server key.
8041 if ((zone->masterkeynames != NULL) &&
8042 (zone->masterkeynames[zone->curmaster] != NULL)) {
8043 dns_view_t *view = dns_zone_getview(zone);
8044 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8045 result = dns_view_gettsig(view, keyname, &key);
8046 if (result != ISC_R_SUCCESS) {
8047 char namebuf[DNS_NAME_FORMATSIZE];
8048 dns_name_format(keyname, namebuf, sizeof(namebuf));
8049 dns_zone_log(zone, ISC_LOG_ERROR,
8050 "unable to find key: %s", namebuf);
8055 result = dns_view_getpeertsig(zone->view, &masterip, &key);
8056 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
8057 char addrbuf[ISC_NETADDR_FORMATSIZE];
8058 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
8059 dns_zone_log(zone, ISC_LOG_ERROR,
8060 "unable to find TSIG key for %s", addrbuf);
8065 have_xfrsource = ISC_FALSE;
8066 reqnsid = zone->view->requestnsid;
8067 if (zone->view->peers != NULL) {
8068 dns_peer_t *peer = NULL;
8070 result = dns_peerlist_peerbyaddr(zone->view->peers,
8072 if (result == ISC_R_SUCCESS) {
8073 result = dns_peer_getsupportedns(peer, &edns);
8074 if (result == ISC_R_SUCCESS && !edns)
8075 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8076 result = dns_peer_gettransfersource(peer,
8078 if (result == ISC_R_SUCCESS)
8079 have_xfrsource = ISC_TRUE;
8080 if (zone->view->resolver != NULL)
8082 dns_resolver_getudpsize(zone->view->resolver);
8083 (void)dns_peer_getudpsize(peer, &udpsize);
8084 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8088 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8090 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8091 if (isc_sockaddr_equal(&zone->altxfrsource4,
8094 zone->sourceaddr = zone->altxfrsource4;
8095 } else if (!have_xfrsource)
8096 zone->sourceaddr = zone->xfrsource4;
8099 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8100 if (isc_sockaddr_equal(&zone->altxfrsource6,
8103 zone->sourceaddr = zone->altxfrsource6;
8104 } else if (!have_xfrsource)
8105 zone->sourceaddr = zone->xfrsource6;
8108 result = ISC_R_NOTIMPLEMENTED;
8112 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
8113 DNS_REQUESTOPT_TCP : 0;
8115 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8116 result = add_opt(message, udpsize, reqnsid);
8117 if (result != ISC_R_SUCCESS)
8118 zone_debuglog(zone, me, 1,
8119 "unable to add opt record: %s",
8120 dns_result_totext(result));
8123 zone_iattach(zone, &dummy);
8125 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8127 result = dns_request_createvia2(zone->view->requestmgr, message,
8128 &zone->sourceaddr, &zone->masteraddr,
8129 options, key, timeout * 3, timeout,
8130 zone->task, refresh_callback, zone,
8132 if (result != ISC_R_SUCCESS) {
8133 zone_idetach(&dummy);
8134 zone_debuglog(zone, me, 1,
8135 "dns_request_createvia2() failed: %s",
8136 dns_result_totext(result));
8139 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
8140 inc_stats(zone, dns_zonestatscounter_soaoutv4);
8142 inc_stats(zone, dns_zonestatscounter_soaoutv6);
8148 dns_tsigkey_detach(&key);
8149 if (result != ISC_R_SUCCESS)
8150 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8151 if (message != NULL)
8152 dns_message_destroy(&message);
8154 cancel_refresh(zone);
8155 isc_event_free(&event);
8157 dns_zone_idetach(&zone);
8162 dns_tsigkey_detach(&key);
8164 * Skip to next failed / untried master.
8168 } while (zone->curmaster < zone->masterscnt &&
8169 zone->mastersok[zone->curmaster]);
8170 if (zone->curmaster < zone->masterscnt)
8172 zone->curmaster = 0;
8177 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
8178 const char me[] = "ns_query";
8179 isc_result_t result;
8180 dns_message_t *message = NULL;
8181 isc_netaddr_t masterip;
8182 dns_tsigkey_t *key = NULL;
8183 dns_dbnode_t *node = NULL;
8185 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
8186 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8188 REQUIRE(DNS_ZONE_VALID(zone));
8189 REQUIRE((soardataset != NULL && stub == NULL) ||
8190 (soardataset == NULL && stub != NULL));
8191 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
8197 stub = isc_mem_get(zone->mctx, sizeof(*stub));
8200 stub->magic = STUB_MAGIC;
8201 stub->mctx = zone->mctx;
8204 stub->version = NULL;
8207 * Attach so that the zone won't disappear from under us.
8209 zone_iattach(zone, &stub->zone);
8212 * If a db exists we will update it, otherwise we create a
8213 * new one and attach it to the zone once we have the NS
8216 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8217 if (zone->db != NULL) {
8218 dns_db_attach(zone->db, &stub->db);
8219 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8221 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8223 INSIST(zone->db_argc >= 1);
8224 result = dns_db_create(zone->mctx, zone->db_argv[0],
8225 &zone->origin, dns_dbtype_stub,
8230 if (result != ISC_R_SUCCESS) {
8231 dns_zone_log(zone, ISC_LOG_ERROR,
8235 dns_result_totext(result));
8238 dns_db_settask(stub->db, zone->task);
8241 dns_db_newversion(stub->db, &stub->version);
8244 * Update SOA record.
8246 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
8248 if (result != ISC_R_SUCCESS) {
8249 dns_zone_log(zone, ISC_LOG_INFO,
8251 "dns_db_findnode() failed: %s",
8252 dns_result_totext(result));
8256 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
8257 soardataset, 0, NULL);
8258 dns_db_detachnode(stub->db, &node);
8259 if (result != ISC_R_SUCCESS) {
8260 dns_zone_log(zone, ISC_LOG_INFO,
8262 "dns_db_addrdataset() failed: %s",
8263 dns_result_totext(result));
8269 * XXX Optimisation: Create message when zone is setup and reuse.
8271 result = create_query(zone, dns_rdatatype_ns, &message);
8273 INSIST(zone->masterscnt > 0);
8274 INSIST(zone->curmaster < zone->masterscnt);
8275 zone->masteraddr = zone->masters[zone->curmaster];
8277 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8279 * First, look for a tsig key in the master statement, then
8280 * try for a server key.
8282 if ((zone->masterkeynames != NULL) &&
8283 (zone->masterkeynames[zone->curmaster] != NULL)) {
8284 dns_view_t *view = dns_zone_getview(zone);
8285 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8286 result = dns_view_gettsig(view, keyname, &key);
8287 if (result != ISC_R_SUCCESS) {
8288 char namebuf[DNS_NAME_FORMATSIZE];
8289 dns_name_format(keyname, namebuf, sizeof(namebuf));
8290 dns_zone_log(zone, ISC_LOG_ERROR,
8291 "unable to find key: %s", namebuf);
8295 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
8297 reqnsid = zone->view->requestnsid;
8298 if (zone->view->peers != NULL) {
8299 dns_peer_t *peer = NULL;
8301 result = dns_peerlist_peerbyaddr(zone->view->peers,
8303 if (result == ISC_R_SUCCESS) {
8304 result = dns_peer_getsupportedns(peer, &edns);
8305 if (result == ISC_R_SUCCESS && !edns)
8306 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8307 result = dns_peer_gettransfersource(peer,
8309 if (result == ISC_R_SUCCESS)
8310 have_xfrsource = ISC_TRUE;
8311 if (zone->view->resolver != NULL)
8313 dns_resolver_getudpsize(zone->view->resolver);
8314 (void)dns_peer_getudpsize(peer, &udpsize);
8315 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8319 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8320 result = add_opt(message, udpsize, reqnsid);
8321 if (result != ISC_R_SUCCESS)
8322 zone_debuglog(zone, me, 1,
8323 "unable to add opt record: %s",
8324 dns_result_totext(result));
8328 * Always use TCP so that we shouldn't truncate in additional section.
8330 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8332 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8333 zone->sourceaddr = zone->altxfrsource4;
8334 else if (!have_xfrsource)
8335 zone->sourceaddr = zone->xfrsource4;
8338 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8339 zone->sourceaddr = zone->altxfrsource6;
8340 else if (!have_xfrsource)
8341 zone->sourceaddr = zone->xfrsource6;
8344 result = ISC_R_NOTIMPLEMENTED;
8348 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8350 result = dns_request_createvia2(zone->view->requestmgr, message,
8351 &zone->sourceaddr, &zone->masteraddr,
8352 DNS_REQUESTOPT_TCP, key, timeout * 3,
8353 timeout, zone->task, stub_callback,
8354 stub, &zone->request);
8355 if (result != ISC_R_SUCCESS) {
8356 zone_debuglog(zone, me, 1,
8357 "dns_request_createvia() failed: %s",
8358 dns_result_totext(result));
8361 dns_message_destroy(&message);
8365 cancel_refresh(zone);
8368 if (stub->version != NULL)
8369 dns_db_closeversion(stub->db, &stub->version,
8371 if (stub->db != NULL)
8372 dns_db_detach(&stub->db);
8373 if (stub->zone != NULL)
8374 zone_idetach(&stub->zone);
8375 isc_mem_put(stub->mctx, stub, sizeof(*stub));
8377 if (message != NULL)
8378 dns_message_destroy(&message);
8381 dns_tsigkey_detach(&key);
8387 * Handle the control event. Note that although this event causes the zone
8388 * to shut down, it is not a shutdown event in the sense of the task library.
8391 zone_shutdown(isc_task_t *task, isc_event_t *event) {
8392 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
8393 isc_boolean_t free_needed, linked = ISC_FALSE;
8396 REQUIRE(DNS_ZONE_VALID(zone));
8397 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
8398 INSIST(isc_refcount_current(&zone->erefs) == 0);
8399 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
8402 * Stop things being restarted after we cancel them below.
8405 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
8409 * If we were waiting for xfrin quota, step out of
8411 * If there's no zone manager, we can't be waiting for the
8414 if (zone->zmgr != NULL) {
8415 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8416 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
8417 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
8420 zone->statelist = NULL;
8422 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8426 * In task context, no locking required. See zone_xfrdone().
8428 if (zone->xfr != NULL)
8429 dns_xfrin_shutdown(zone->xfr);
8433 INSIST(zone->irefs > 0);
8436 if (zone->request != NULL) {
8437 dns_request_cancel(zone->request);
8440 if (zone->readio != NULL)
8441 zonemgr_cancelio(zone->readio);
8443 if (zone->lctx != NULL)
8444 dns_loadctx_cancel(zone->lctx);
8446 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8447 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8448 if (zone->writeio != NULL)
8449 zonemgr_cancelio(zone->writeio);
8451 if (zone->dctx != NULL)
8452 dns_dumpctx_cancel(zone->dctx);
8455 notify_cancel(zone);
8457 if (zone->timer != NULL) {
8458 isc_timer_detach(&zone->timer);
8459 INSIST(zone->irefs > 0);
8463 if (zone->view != NULL)
8464 dns_view_weakdetach(&zone->view);
8467 * We have now canceled everything set the flag to allow exit_check()
8468 * to succeed. We must not unlock between setting this flag and
8469 * calling exit_check().
8471 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
8472 free_needed = exit_check(zone);
8479 zone_timer(isc_task_t *task, isc_event_t *event) {
8480 const char me[] = "zone_timer";
8481 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
8484 REQUIRE(DNS_ZONE_VALID(zone));
8488 zone_maintenance(zone);
8490 isc_event_free(&event);
8494 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
8495 const char me[] = "zone_settimer";
8497 isc_result_t result;
8499 REQUIRE(DNS_ZONE_VALID(zone));
8500 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8503 isc_time_settoepoch(&next);
8505 switch (zone->type) {
8506 case dns_zone_master:
8507 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8508 next = zone->notifytime;
8509 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8510 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8511 INSIST(!isc_time_isepoch(&zone->dumptime));
8512 if (isc_time_isepoch(&next) ||
8513 isc_time_compare(&zone->dumptime, &next) < 0)
8514 next = zone->dumptime;
8516 if (!isc_time_isepoch(&zone->resigntime)) {
8517 if (isc_time_isepoch(&next) ||
8518 isc_time_compare(&zone->resigntime, &next) < 0)
8519 next = zone->resigntime;
8521 if (!isc_time_isepoch(&zone->keywarntime)) {
8522 if (isc_time_isepoch(&next) ||
8523 isc_time_compare(&zone->keywarntime, &next) < 0)
8524 next = zone->keywarntime;
8526 if (!isc_time_isepoch(&zone->signingtime)) {
8527 if (isc_time_isepoch(&next) ||
8528 isc_time_compare(&zone->signingtime, &next) < 0)
8529 next = zone->signingtime;
8531 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
8532 if (isc_time_isepoch(&next) ||
8533 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
8534 next = zone->nsec3chaintime;
8538 case dns_zone_slave:
8539 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8540 next = zone->notifytime;
8544 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
8545 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
8546 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
8547 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
8548 INSIST(!isc_time_isepoch(&zone->refreshtime));
8549 if (isc_time_isepoch(&next) ||
8550 isc_time_compare(&zone->refreshtime, &next) < 0)
8551 next = zone->refreshtime;
8553 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8554 INSIST(!isc_time_isepoch(&zone->expiretime));
8555 if (isc_time_isepoch(&next) ||
8556 isc_time_compare(&zone->expiretime, &next) < 0)
8557 next = zone->expiretime;
8559 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8560 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8561 INSIST(!isc_time_isepoch(&zone->dumptime));
8562 if (isc_time_isepoch(&next) ||
8563 isc_time_compare(&zone->dumptime, &next) < 0)
8564 next = zone->dumptime;
8572 if (isc_time_isepoch(&next)) {
8573 zone_debuglog(zone, me, 10, "settimer inactive");
8574 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
8575 NULL, NULL, ISC_TRUE);
8576 if (result != ISC_R_SUCCESS)
8577 dns_zone_log(zone, ISC_LOG_ERROR,
8578 "could not deactivate zone timer: %s",
8579 isc_result_totext(result));
8581 if (isc_time_compare(&next, now) <= 0)
8583 result = isc_timer_reset(zone->timer, isc_timertype_once,
8584 &next, NULL, ISC_TRUE);
8585 if (result != ISC_R_SUCCESS)
8586 dns_zone_log(zone, ISC_LOG_ERROR,
8587 "could not reset zone timer: %s",
8588 isc_result_totext(result));
8593 cancel_refresh(dns_zone_t *zone) {
8594 const char me[] = "cancel_refresh";
8598 * 'zone' locked by caller.
8601 REQUIRE(DNS_ZONE_VALID(zone));
8602 REQUIRE(LOCKED_ZONE(zone));
8606 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8608 zone_settimer(zone, &now);
8612 notify_createmessage(dns_zone_t *zone, unsigned int flags,
8613 dns_message_t **messagep)
8615 dns_db_t *zonedb = NULL;
8616 dns_dbnode_t *node = NULL;
8617 dns_dbversion_t *version = NULL;
8618 dns_message_t *message = NULL;
8619 dns_rdataset_t rdataset;
8620 dns_rdata_t rdata = DNS_RDATA_INIT;
8622 dns_name_t *tempname = NULL;
8623 dns_rdata_t *temprdata = NULL;
8624 dns_rdatalist_t *temprdatalist = NULL;
8625 dns_rdataset_t *temprdataset = NULL;
8627 isc_result_t result;
8629 isc_buffer_t *b = NULL;
8631 REQUIRE(DNS_ZONE_VALID(zone));
8632 REQUIRE(messagep != NULL && *messagep == NULL);
8634 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
8636 if (result != ISC_R_SUCCESS)
8639 message->opcode = dns_opcode_notify;
8640 message->flags |= DNS_MESSAGEFLAG_AA;
8641 message->rdclass = zone->rdclass;
8643 result = dns_message_gettempname(message, &tempname);
8644 if (result != ISC_R_SUCCESS)
8647 result = dns_message_gettemprdataset(message, &temprdataset);
8648 if (result != ISC_R_SUCCESS)
8654 dns_name_init(tempname, NULL);
8655 dns_name_clone(&zone->origin, tempname);
8656 dns_rdataset_init(temprdataset);
8657 dns_rdataset_makequestion(temprdataset, zone->rdclass,
8659 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8660 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
8662 temprdataset = NULL;
8664 if ((flags & DNS_NOTIFY_NOSOA) != 0)
8667 result = dns_message_gettempname(message, &tempname);
8668 if (result != ISC_R_SUCCESS)
8670 result = dns_message_gettemprdata(message, &temprdata);
8671 if (result != ISC_R_SUCCESS)
8673 result = dns_message_gettemprdataset(message, &temprdataset);
8674 if (result != ISC_R_SUCCESS)
8676 result = dns_message_gettemprdatalist(message, &temprdatalist);
8677 if (result != ISC_R_SUCCESS)
8680 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8681 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
8682 dns_db_attach(zone->db, &zonedb);
8683 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8685 dns_name_init(tempname, NULL);
8686 dns_name_clone(&zone->origin, tempname);
8687 dns_db_currentversion(zonedb, &version);
8688 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
8689 if (result != ISC_R_SUCCESS)
8692 dns_rdataset_init(&rdataset);
8693 result = dns_db_findrdataset(zonedb, node, version,
8695 dns_rdatatype_none, 0, &rdataset,
8697 if (result != ISC_R_SUCCESS)
8699 result = dns_rdataset_first(&rdataset);
8700 if (result != ISC_R_SUCCESS)
8702 dns_rdataset_current(&rdataset, &rdata);
8703 dns_rdata_toregion(&rdata, &r);
8704 result = isc_buffer_allocate(zone->mctx, &b, r.length);
8705 if (result != ISC_R_SUCCESS)
8707 isc_buffer_putmem(b, r.base, r.length);
8708 isc_buffer_usedregion(b, &r);
8709 dns_rdata_init(temprdata);
8710 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
8711 dns_message_takebuffer(message, &b);
8712 result = dns_rdataset_next(&rdataset);
8713 dns_rdataset_disassociate(&rdataset);
8714 if (result != ISC_R_NOMORE)
8716 temprdatalist->rdclass = rdata.rdclass;
8717 temprdatalist->type = rdata.type;
8718 temprdatalist->covers = 0;
8719 temprdatalist->ttl = rdataset.ttl;
8720 ISC_LIST_INIT(temprdatalist->rdata);
8721 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
8723 dns_rdataset_init(temprdataset);
8724 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
8725 if (result != ISC_R_SUCCESS)
8728 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8729 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
8730 temprdatalist = NULL;
8731 temprdataset = NULL;
8737 dns_db_detachnode(zonedb, &node);
8738 if (version != NULL)
8739 dns_db_closeversion(zonedb, &version, ISC_FALSE);
8741 dns_db_detach(&zonedb);
8742 if (tempname != NULL)
8743 dns_message_puttempname(message, &tempname);
8744 if (temprdata != NULL)
8745 dns_message_puttemprdata(message, &temprdata);
8746 if (temprdataset != NULL)
8747 dns_message_puttemprdataset(message, &temprdataset);
8748 if (temprdatalist != NULL)
8749 dns_message_puttemprdatalist(message, &temprdatalist);
8752 *messagep = message;
8753 return (ISC_R_SUCCESS);
8756 if (tempname != NULL)
8757 dns_message_puttempname(message, &tempname);
8758 if (temprdataset != NULL)
8759 dns_message_puttemprdataset(message, &temprdataset);
8760 dns_message_destroy(&message);
8765 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
8769 dns_rdata_soa_t soa;
8770 dns_rdataset_t *rdataset = NULL;
8771 dns_rdata_t rdata = DNS_RDATA_INIT;
8772 isc_result_t result;
8773 char fromtext[ISC_SOCKADDR_FORMATSIZE];
8775 isc_netaddr_t netaddr;
8777 REQUIRE(DNS_ZONE_VALID(zone));
8780 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
8784 * Check that 'from' is a valid notify source, (zone->masters).
8785 * Return DNS_R_REFUSED if not.
8787 * If the notify message contains a serial number check it
8788 * against the zones serial and return if <= current serial
8790 * If a refresh check is progress, if so just record the
8791 * fact we received a NOTIFY and from where and return.
8792 * We will perform a new refresh check when the current one
8793 * completes. Return ISC_R_SUCCESS.
8795 * Otherwise initiate a refresh check using 'from' as the
8796 * first address to check. Return ISC_R_SUCCESS.
8799 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
8802 * We only handle NOTIFY (SOA) at the present.
8805 if (isc_sockaddr_pf(from) == PF_INET)
8806 inc_stats(zone, dns_zonestatscounter_notifyinv4);
8808 inc_stats(zone, dns_zonestatscounter_notifyinv6);
8809 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
8810 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
8811 dns_rdatatype_soa, dns_rdatatype_none,
8812 NULL, NULL) != ISC_R_SUCCESS) {
8814 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
8815 dns_zone_log(zone, ISC_LOG_NOTICE,
8817 "question section from: %s", fromtext);
8818 return (DNS_R_FORMERR);
8820 dns_zone_log(zone, ISC_LOG_NOTICE,
8821 "NOTIFY zone does not match");
8822 return (DNS_R_NOTIMP);
8826 * If we are a master zone just succeed.
8828 if (zone->type == dns_zone_master) {
8830 return (ISC_R_SUCCESS);
8833 isc_netaddr_fromsockaddr(&netaddr, from);
8834 for (i = 0; i < zone->masterscnt; i++) {
8835 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
8837 if (zone->view->aclenv.match_mapped &&
8838 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
8839 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
8840 isc_netaddr_t na1, na2;
8841 isc_netaddr_fromv4mapped(&na1, &netaddr);
8842 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
8843 if (isc_netaddr_equal(&na1, &na2))
8849 * Accept notify requests from non masters if they are on
8850 * 'zone->notify_acl'.
8852 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
8853 dns_acl_match(&netaddr, NULL, zone->notify_acl,
8854 &zone->view->aclenv,
8855 &match, NULL) == ISC_R_SUCCESS &&
8858 /* Accept notify. */
8859 } else if (i >= zone->masterscnt) {
8861 dns_zone_log(zone, ISC_LOG_INFO,
8862 "refused notify from non-master: %s", fromtext);
8863 inc_stats(zone, dns_zonestatscounter_notifyrej);
8864 return (DNS_R_REFUSED);
8868 * If the zone is loaded and there are answers check the serial
8869 * to see if we need to do a refresh. Do not worry about this
8870 * check if we are a dialup zone as we use the notify request
8871 * to trigger a refresh check.
8873 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
8874 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8875 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
8876 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
8879 dns_rdatatype_none, NULL,
8881 if (result == ISC_R_SUCCESS)
8882 result = dns_rdataset_first(rdataset);
8883 if (result == ISC_R_SUCCESS) {
8884 isc_uint32_t serial = 0, oldserial;
8886 dns_rdataset_current(rdataset, &rdata);
8887 result = dns_rdata_tostruct(&rdata, &soa, NULL);
8888 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8889 serial = soa.serial;
8891 * The following should safely be performed without DB
8892 * lock and succeed in this context.
8894 result = zone_get_from_db(zone, zone->db, NULL, NULL,
8895 &oldserial, NULL, NULL, NULL,
8897 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8898 if (isc_serial_le(serial, oldserial)) {
8899 dns_zone_log(zone, ISC_LOG_INFO,
8901 "zone is up to date",
8904 return (ISC_R_SUCCESS);
8910 * If we got this far and there was a refresh in progress just
8911 * let it complete. Record where we got the notify from so we
8912 * can perform a refresh check when the current one completes
8914 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
8915 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
8916 zone->notifyfrom = *from;
8918 dns_zone_log(zone, ISC_LOG_INFO,
8919 "notify from %s: refresh in progress, "
8920 "refresh check queued",
8922 return (ISC_R_SUCCESS);
8924 zone->notifyfrom = *from;
8926 dns_zone_refresh(zone);
8927 return (ISC_R_SUCCESS);
8931 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
8933 REQUIRE(DNS_ZONE_VALID(zone));
8936 if (zone->notify_acl != NULL)
8937 dns_acl_detach(&zone->notify_acl);
8938 dns_acl_attach(acl, &zone->notify_acl);
8943 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
8945 REQUIRE(DNS_ZONE_VALID(zone));
8948 if (zone->query_acl != NULL)
8949 dns_acl_detach(&zone->query_acl);
8950 dns_acl_attach(acl, &zone->query_acl);
8955 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
8957 REQUIRE(DNS_ZONE_VALID(zone));
8960 if (zone->queryon_acl != NULL)
8961 dns_acl_detach(&zone->queryon_acl);
8962 dns_acl_attach(acl, &zone->queryon_acl);
8967 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
8969 REQUIRE(DNS_ZONE_VALID(zone));
8972 if (zone->update_acl != NULL)
8973 dns_acl_detach(&zone->update_acl);
8974 dns_acl_attach(acl, &zone->update_acl);
8979 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
8981 REQUIRE(DNS_ZONE_VALID(zone));
8984 if (zone->forward_acl != NULL)
8985 dns_acl_detach(&zone->forward_acl);
8986 dns_acl_attach(acl, &zone->forward_acl);
8991 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
8993 REQUIRE(DNS_ZONE_VALID(zone));
8996 if (zone->xfr_acl != NULL)
8997 dns_acl_detach(&zone->xfr_acl);
8998 dns_acl_attach(acl, &zone->xfr_acl);
9003 dns_zone_getnotifyacl(dns_zone_t *zone) {
9005 REQUIRE(DNS_ZONE_VALID(zone));
9007 return (zone->notify_acl);
9011 dns_zone_getqueryacl(dns_zone_t *zone) {
9013 REQUIRE(DNS_ZONE_VALID(zone));
9015 return (zone->query_acl);
9019 dns_zone_getqueryonacl(dns_zone_t *zone) {
9021 REQUIRE(DNS_ZONE_VALID(zone));
9023 return (zone->queryon_acl);
9027 dns_zone_getupdateacl(dns_zone_t *zone) {
9029 REQUIRE(DNS_ZONE_VALID(zone));
9031 return (zone->update_acl);
9035 dns_zone_getforwardacl(dns_zone_t *zone) {
9037 REQUIRE(DNS_ZONE_VALID(zone));
9039 return (zone->forward_acl);
9043 dns_zone_getxfracl(dns_zone_t *zone) {
9045 REQUIRE(DNS_ZONE_VALID(zone));
9047 return (zone->xfr_acl);
9051 dns_zone_clearupdateacl(dns_zone_t *zone) {
9053 REQUIRE(DNS_ZONE_VALID(zone));
9056 if (zone->update_acl != NULL)
9057 dns_acl_detach(&zone->update_acl);
9062 dns_zone_clearforwardacl(dns_zone_t *zone) {
9064 REQUIRE(DNS_ZONE_VALID(zone));
9067 if (zone->forward_acl != NULL)
9068 dns_acl_detach(&zone->forward_acl);
9073 dns_zone_clearnotifyacl(dns_zone_t *zone) {
9075 REQUIRE(DNS_ZONE_VALID(zone));
9078 if (zone->notify_acl != NULL)
9079 dns_acl_detach(&zone->notify_acl);
9084 dns_zone_clearqueryacl(dns_zone_t *zone) {
9086 REQUIRE(DNS_ZONE_VALID(zone));
9089 if (zone->query_acl != NULL)
9090 dns_acl_detach(&zone->query_acl);
9095 dns_zone_clearqueryonacl(dns_zone_t *zone) {
9097 REQUIRE(DNS_ZONE_VALID(zone));
9100 if (zone->queryon_acl != NULL)
9101 dns_acl_detach(&zone->queryon_acl);
9106 dns_zone_clearxfracl(dns_zone_t *zone) {
9108 REQUIRE(DNS_ZONE_VALID(zone));
9111 if (zone->xfr_acl != NULL)
9112 dns_acl_detach(&zone->xfr_acl);
9117 dns_zone_getupdatedisabled(dns_zone_t *zone) {
9118 REQUIRE(DNS_ZONE_VALID(zone));
9119 return (zone->update_disabled);
9124 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
9125 REQUIRE(DNS_ZONE_VALID(zone));
9126 zone->update_disabled = state;
9130 dns_zone_getzeronosoattl(dns_zone_t *zone) {
9131 REQUIRE(DNS_ZONE_VALID(zone));
9132 return (zone->zero_no_soa_ttl);
9137 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
9138 REQUIRE(DNS_ZONE_VALID(zone));
9139 zone->zero_no_soa_ttl = state;
9143 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
9145 REQUIRE(DNS_ZONE_VALID(zone));
9147 zone->check_names = severity;
9151 dns_zone_getchecknames(dns_zone_t *zone) {
9153 REQUIRE(DNS_ZONE_VALID(zone));
9155 return (zone->check_names);
9159 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
9161 REQUIRE(DNS_ZONE_VALID(zone));
9163 zone->journalsize = size;
9167 dns_zone_getjournalsize(dns_zone_t *zone) {
9169 REQUIRE(DNS_ZONE_VALID(zone));
9171 return (zone->journalsize);
9175 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
9176 isc_result_t result = ISC_R_FAILURE;
9177 isc_buffer_t buffer;
9179 REQUIRE(buf != NULL);
9180 REQUIRE(length > 1U);
9183 * Leave space for terminating '\0'.
9185 isc_buffer_init(&buffer, buf, length - 1);
9186 if (dns_name_dynamic(&zone->origin))
9187 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9188 if (result != ISC_R_SUCCESS &&
9189 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9190 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9192 if (isc_buffer_availablelength(&buffer) > 0)
9193 isc_buffer_putstr(&buffer, "/");
9194 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9196 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
9197 strcmp(zone->view->name, "_default") != 0 &&
9198 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
9199 isc_buffer_putstr(&buffer, "/");
9200 isc_buffer_putstr(&buffer, zone->view->name);
9203 buf[isc_buffer_usedlength(&buffer)] = '\0';
9207 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
9208 isc_result_t result = ISC_R_FAILURE;
9209 isc_buffer_t buffer;
9211 REQUIRE(buf != NULL);
9212 REQUIRE(length > 1U);
9215 * Leave space for terminating '\0'.
9217 isc_buffer_init(&buffer, buf, length - 1);
9218 if (dns_name_dynamic(&zone->origin))
9219 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9220 if (result != ISC_R_SUCCESS &&
9221 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9222 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9224 buf[isc_buffer_usedlength(&buffer)] = '\0';
9228 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
9229 isc_buffer_t buffer;
9231 REQUIRE(buf != NULL);
9232 REQUIRE(length > 1U);
9235 * Leave space for terminating '\0'.
9237 isc_buffer_init(&buffer, buf, length - 1);
9238 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9240 buf[isc_buffer_usedlength(&buffer)] = '\0';
9244 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
9245 isc_buffer_t buffer;
9247 REQUIRE(buf != NULL);
9248 REQUIRE(length > 1U);
9252 * Leave space for terminating '\0'.
9254 isc_buffer_init(&buffer, buf, length - 1);
9256 if (zone->view == NULL) {
9257 isc_buffer_putstr(&buffer, "_none");
9258 } else if (strlen(zone->view->name)
9259 < isc_buffer_availablelength(&buffer)) {
9260 isc_buffer_putstr(&buffer, zone->view->name);
9262 isc_buffer_putstr(&buffer, "_toolong");
9265 buf[isc_buffer_usedlength(&buffer)] = '\0';
9269 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
9270 REQUIRE(DNS_ZONE_VALID(zone));
9271 REQUIRE(buf != NULL);
9272 zone_namerd_tostr(zone, buf, length);
9276 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9280 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9284 vsnprintf(message, sizeof(message), fmt, ap);
9286 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
9287 level, "zone %s: %s", zone->strnamerd, message);
9291 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
9292 int level, const char *fmt, ...) {
9296 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9300 vsnprintf(message, sizeof(message), fmt, ap);
9302 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
9303 level, "zone %s: %s", zone->strnamerd, message);
9307 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9311 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9315 vsnprintf(message, sizeof(message), fmt, ap);
9317 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9318 level, "zone %s: %s", zone->strnamerd, message);
9322 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
9323 const char *fmt, ...)
9327 int level = ISC_LOG_DEBUG(debuglevel);
9329 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9333 vsnprintf(message, sizeof(message), fmt, ap);
9335 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9336 level, "%s: zone %s: %s", me, zone->strnamerd, message);
9340 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
9342 isc_result_t result;
9344 dns_rdataset_t *curr;
9347 result = dns_message_firstname(msg, section);
9348 while (result == ISC_R_SUCCESS) {
9350 dns_message_currentname(msg, section, &name);
9352 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
9353 curr = ISC_LIST_PREV(curr, link)) {
9354 if (curr->type == type)
9357 result = dns_message_nextname(msg, section);
9364 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
9365 REQUIRE(DNS_ZONE_VALID(zone));
9367 zone->maxxfrin = maxxfrin;
9371 dns_zone_getmaxxfrin(dns_zone_t *zone) {
9372 REQUIRE(DNS_ZONE_VALID(zone));
9374 return (zone->maxxfrin);
9378 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
9379 REQUIRE(DNS_ZONE_VALID(zone));
9380 zone->maxxfrout = maxxfrout;
9384 dns_zone_getmaxxfrout(dns_zone_t *zone) {
9385 REQUIRE(DNS_ZONE_VALID(zone));
9387 return (zone->maxxfrout);
9391 dns_zone_gettype(dns_zone_t *zone) {
9392 REQUIRE(DNS_ZONE_VALID(zone));
9394 return (zone->type);
9398 dns_zone_getorigin(dns_zone_t *zone) {
9399 REQUIRE(DNS_ZONE_VALID(zone));
9401 return (&zone->origin);
9405 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
9406 REQUIRE(DNS_ZONE_VALID(zone));
9409 if (zone->task != NULL)
9410 isc_task_detach(&zone->task);
9411 isc_task_attach(task, &zone->task);
9412 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9413 if (zone->db != NULL)
9414 dns_db_settask(zone->db, zone->task);
9415 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9420 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
9421 REQUIRE(DNS_ZONE_VALID(zone));
9422 isc_task_attach(zone->task, target);
9426 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
9427 REQUIRE(DNS_ZONE_VALID(zone));
9430 idlein = DNS_DEFAULT_IDLEIN;
9431 zone->idlein = idlein;
9435 dns_zone_getidlein(dns_zone_t *zone) {
9436 REQUIRE(DNS_ZONE_VALID(zone));
9438 return (zone->idlein);
9442 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
9443 REQUIRE(DNS_ZONE_VALID(zone));
9445 zone->idleout = idleout;
9449 dns_zone_getidleout(dns_zone_t *zone) {
9450 REQUIRE(DNS_ZONE_VALID(zone));
9452 return (zone->idleout);
9456 notify_done(isc_task_t *task, isc_event_t *event) {
9457 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9458 dns_notify_t *notify;
9459 isc_result_t result;
9460 dns_message_t *message = NULL;
9463 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9467 notify = event->ev_arg;
9468 REQUIRE(DNS_NOTIFY_VALID(notify));
9469 INSIST(task == notify->zone->task);
9471 isc_buffer_init(&buf, rcode, sizeof(rcode));
9472 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9474 result = revent->result;
9475 if (result == ISC_R_SUCCESS)
9476 result = dns_message_create(notify->zone->mctx,
9477 DNS_MESSAGE_INTENTPARSE, &message);
9478 if (result == ISC_R_SUCCESS)
9479 result = dns_request_getresponse(revent->request, message,
9480 DNS_MESSAGEPARSE_PRESERVEORDER);
9481 if (result == ISC_R_SUCCESS)
9482 result = dns_rcode_totext(message->rcode, &buf);
9483 if (result == ISC_R_SUCCESS)
9484 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9485 "notify response from %s: %.*s",
9486 addrbuf, (int)buf.used, rcode);
9488 notify_log(notify->zone, ISC_LOG_DEBUG(2),
9489 "notify to %s failed: %s", addrbuf,
9490 dns_result_totext(result));
9493 * Old bind's return formerr if they see a soa record. Retry w/o
9494 * the soa if we see a formerr and had sent a SOA.
9496 isc_event_free(&event);
9497 if (message != NULL && message->rcode == dns_rcode_formerr &&
9498 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
9499 notify->flags |= DNS_NOTIFY_NOSOA;
9500 dns_request_destroy(¬ify->request);
9501 result = notify_send_queue(notify);
9502 if (result != ISC_R_SUCCESS)
9503 notify_destroy(notify, ISC_FALSE);
9505 if (result == ISC_R_TIMEDOUT)
9506 notify_log(notify->zone, ISC_LOG_DEBUG(1),
9507 "notify to %s: retries exceeded", addrbuf);
9508 notify_destroy(notify, ISC_FALSE);
9510 if (message != NULL)
9511 dns_message_destroy(&message);
9515 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9516 isc_result_t result;
9518 REQUIRE(DNS_ZONE_VALID(zone));
9520 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9521 result = zone_replacedb(zone, db, dump);
9522 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9528 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9529 dns_dbversion_t *ver;
9530 isc_result_t result;
9531 unsigned int soacount = 0;
9532 unsigned int nscount = 0;
9535 * 'zone' and 'zonedb' locked by caller.
9537 REQUIRE(DNS_ZONE_VALID(zone));
9538 REQUIRE(LOCKED_ZONE(zone));
9540 result = zone_get_from_db(zone, db, &nscount, &soacount,
9541 NULL, NULL, NULL, NULL, NULL, NULL);
9542 if (result == ISC_R_SUCCESS) {
9543 if (soacount != 1) {
9544 dns_zone_log(zone, ISC_LOG_ERROR,
9545 "has %d SOA records", soacount);
9546 result = DNS_R_BADZONE;
9549 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
9550 result = DNS_R_BADZONE;
9552 if (result != ISC_R_SUCCESS)
9555 dns_zone_log(zone, ISC_LOG_ERROR,
9556 "retrieving SOA and NS records failed: %s",
9557 dns_result_totext(result));
9561 result = check_nsec3param(zone, db);
9562 if (result != ISC_R_SUCCESS)
9566 dns_db_currentversion(db, &ver);
9569 * The initial version of a slave zone is always dumped;
9570 * subsequent versions may be journaled instead if this
9571 * is enabled in the configuration.
9573 if (zone->db != NULL && zone->journal != NULL &&
9574 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
9575 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
9576 isc_uint32_t serial, oldserial;
9578 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
9580 result = dns_db_getsoaserial(db, ver, &serial);
9581 if (result != ISC_R_SUCCESS) {
9582 dns_zone_log(zone, ISC_LOG_ERROR,
9583 "ixfr-from-differences: unable to get "
9589 * This is checked in zone_postload() for master zones.
9591 result = zone_get_from_db(zone, zone->db, NULL, NULL,
9592 &oldserial, NULL, NULL, NULL, NULL,
9594 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9595 if (zone->type == dns_zone_slave &&
9596 !isc_serial_gt(serial, oldserial)) {
9597 isc_uint32_t serialmin, serialmax;
9598 serialmin = (oldserial + 1) & 0xffffffffU;
9599 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
9600 dns_zone_log(zone, ISC_LOG_ERROR,
9601 "ixfr-from-differences: failed: "
9602 "new serial (%u) out of range [%u - %u]",
9603 serial, serialmin, serialmax);
9604 result = ISC_R_RANGE;
9608 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
9610 if (result != ISC_R_SUCCESS)
9613 zone_needdump(zone, DNS_DUMP_DELAY);
9614 else if (zone->journalsize != -1) {
9615 result = dns_journal_compact(zone->mctx, zone->journal,
9616 serial, zone->journalsize);
9620 case ISC_R_NOTFOUND:
9621 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9622 "dns_journal_compact: %s",
9623 dns_result_totext(result));
9626 dns_zone_log(zone, ISC_LOG_ERROR,
9627 "dns_journal_compact failed: %s",
9628 dns_result_totext(result));
9633 if (dump && zone->masterfile != NULL) {
9634 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9635 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9636 "dumping new zone version");
9637 result = dns_db_dump2(db, ver, zone->masterfile,
9638 zone->masterformat);
9639 if (result != ISC_R_SUCCESS)
9643 * Update the time the zone was updated, so
9644 * dns_zone_load can avoid loading it when
9645 * the server is reloaded. If isc_time_now
9646 * fails for some reason, all that happens is
9647 * the timestamp is not updated.
9649 TIME_NOW(&zone->loadtime);
9652 if (dump && zone->journal != NULL) {
9654 * The in-memory database just changed, and
9655 * because 'dump' is set, it didn't change by
9656 * being loaded from disk. Also, we have not
9657 * journaled diffs for this change.
9658 * Therefore, the on-disk journal is missing
9659 * the deltas for this change. Since it can
9660 * no longer be used to bring the zone
9661 * up-to-date, it is useless and should be
9664 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9665 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9666 "removing journal file");
9667 if (remove(zone->journal) < 0 && errno != ENOENT) {
9668 char strbuf[ISC_STRERRORSIZE];
9669 isc__strerror(errno, strbuf, sizeof(strbuf));
9670 isc_log_write(dns_lctx,
9671 DNS_LOGCATEGORY_GENERAL,
9674 "unable to remove journal "
9676 zone->journal, strbuf);
9681 dns_db_closeversion(db, &ver, ISC_FALSE);
9683 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9684 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9685 "replacing zone database");
9687 if (zone->db != NULL)
9688 zone_detachdb(zone);
9689 zone_attachdb(zone, db);
9690 dns_db_settask(zone->db, zone->task);
9691 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
9692 return (ISC_R_SUCCESS);
9695 dns_db_closeversion(db, &ver, ISC_FALSE);
9699 /* The caller must hold the dblock as a writer. */
9701 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
9702 REQUIRE(zone->db == NULL && db != NULL);
9704 dns_db_attach(db, &zone->db);
9705 if (zone->acache != NULL) {
9706 isc_result_t result;
9707 result = dns_acache_setdb(zone->acache, db);
9708 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
9709 UNEXPECTED_ERROR(__FILE__, __LINE__,
9710 "dns_acache_setdb() failed: %s",
9711 isc_result_totext(result));
9716 /* The caller must hold the dblock as a writer. */
9718 zone_detachdb(dns_zone_t *zone) {
9719 REQUIRE(zone->db != NULL);
9721 if (zone->acache != NULL)
9722 (void)dns_acache_putdb(zone->acache, zone->db);
9723 dns_db_detach(&zone->db);
9727 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
9729 isc_boolean_t again = ISC_FALSE;
9730 unsigned int soacount;
9731 unsigned int nscount;
9732 isc_uint32_t serial, refresh, retry, expire, minimum;
9733 isc_result_t xfrresult = result;
9734 isc_boolean_t free_needed;
9736 REQUIRE(DNS_ZONE_VALID(zone));
9738 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9739 "zone transfer finished: %s", dns_result_totext(result));
9742 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
9743 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9744 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9749 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9751 case DNS_R_UPTODATE:
9752 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
9754 * Has the zone expired underneath us?
9756 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9757 if (zone->db == NULL) {
9758 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9763 * Update the zone structure's data from the actual
9768 INSIST(zone->db != NULL);
9769 result = zone_get_from_db(zone, zone->db, &nscount,
9770 &soacount, &serial, &refresh,
9771 &retry, &expire, &minimum, NULL);
9772 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9773 if (result == ISC_R_SUCCESS) {
9775 dns_zone_log(zone, ISC_LOG_ERROR,
9777 "has %d SOA record%s", soacount,
9778 (soacount != 0) ? "s" : "");
9780 dns_zone_log(zone, ISC_LOG_ERROR,
9782 "has no NS records");
9783 if (DNS_ZONE_FLAG(zone,
9784 DNS_ZONEFLG_HAVETIMERS)) {
9785 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9786 zone->retry = DNS_ZONE_DEFAULTRETRY;
9788 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9792 zone->refresh = RANGE(refresh, zone->minrefresh,
9794 zone->retry = RANGE(retry, zone->minretry,
9796 zone->expire = RANGE(expire,
9797 zone->refresh + zone->retry,
9799 zone->minimum = minimum;
9800 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9804 * Set our next update/expire times.
9806 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
9807 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
9808 zone->refreshtime = now;
9809 DNS_ZONE_TIME_ADD(&now, zone->expire,
9812 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
9813 &zone->refreshtime);
9814 DNS_ZONE_TIME_ADD(&now, zone->expire,
9817 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
9818 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
9819 if (zone->tsigkey != NULL) {
9820 char namebuf[DNS_NAME_FORMATSIZE];
9821 dns_name_format(&zone->tsigkey->name, namebuf,
9823 snprintf(buf, sizeof(buf), ": TSIG '%s'",
9827 dns_zone_log(zone, ISC_LOG_INFO,
9828 "transferred serial %u%s",
9833 * This is not necessary if we just performed a AXFR
9834 * however it is necessary for an IXFR / UPTODATE and
9835 * won't hurt with an AXFR.
9837 if (zone->masterfile != NULL || zone->journal != NULL) {
9838 result = ISC_R_FAILURE;
9839 if (zone->journal != NULL)
9840 result = isc_file_settime(zone->journal, &now);
9841 if (result != ISC_R_SUCCESS &&
9842 zone->masterfile != NULL)
9843 result = isc_file_settime(zone->masterfile,
9845 /* Someone removed the file from underneath us! */
9846 if (result == ISC_R_FILENOTFOUND &&
9847 zone->masterfile != NULL)
9848 zone_needdump(zone, DNS_DUMP_DELAY);
9849 else if (result != ISC_R_SUCCESS)
9850 dns_zone_log(zone, ISC_LOG_ERROR,
9851 "transfer: could not set file "
9852 "modification time of '%s': %s",
9854 dns_result_totext(result));
9857 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
9861 /* Force retry with AXFR. */
9862 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
9868 * Skip to next failed / untried master.
9872 } while (zone->curmaster < zone->masterscnt &&
9873 zone->mastersok[zone->curmaster]);
9876 if (zone->curmaster >= zone->masterscnt) {
9877 zone->curmaster = 0;
9878 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9879 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9880 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9881 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9882 while (zone->curmaster < zone->masterscnt &&
9883 zone->mastersok[zone->curmaster])
9887 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9889 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9892 inc_stats(zone, dns_zonestatscounter_xfrfail);
9895 zone_settimer(zone, &now);
9898 * If creating the transfer object failed, zone->xfr is NULL.
9899 * Otherwise, we are called as the done callback of a zone
9900 * transfer object that just entered its shutting-down
9901 * state. Since we are no longer responsible for shutting
9902 * it down, we can detach our reference.
9904 if (zone->xfr != NULL)
9905 dns_xfrin_detach(&zone->xfr);
9907 if (zone->tsigkey != NULL)
9908 dns_tsigkey_detach(&zone->tsigkey);
9911 * Handle any deferred journal compaction.
9913 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
9914 result = dns_journal_compact(zone->mctx, zone->journal,
9915 zone->compact_serial,
9920 case ISC_R_NOTFOUND:
9921 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9922 "dns_journal_compact: %s",
9923 dns_result_totext(result));
9926 dns_zone_log(zone, ISC_LOG_ERROR,
9927 "dns_journal_compact failed: %s",
9928 dns_result_totext(result));
9931 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9935 * This transfer finishing freed up a transfer quota slot.
9936 * Let any other zones waiting for quota have it.
9938 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9939 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
9940 zone->statelist = NULL;
9941 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
9942 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9945 * Retry with a different server if necessary.
9947 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9948 queue_soa_query(zone);
9950 INSIST(zone->irefs > 0);
9952 free_needed = exit_check(zone);
9959 zone_loaddone(void *arg, isc_result_t result) {
9960 static char me[] = "zone_loaddone";
9961 dns_load_t *load = arg;
9963 isc_result_t tresult;
9965 REQUIRE(DNS_LOAD_VALID(load));
9970 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
9971 if (tresult != ISC_R_SUCCESS &&
9972 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
9975 LOCK_ZONE(load->zone);
9976 (void)zone_postload(load->zone, load->db, load->loadtime, result);
9977 zonemgr_putio(&load->zone->readio);
9978 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
9980 * Leave the zone frozen if the reload fails.
9982 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
9983 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
9984 zone->update_disabled = ISC_FALSE;
9985 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
9986 UNLOCK_ZONE(load->zone);
9989 dns_db_detach(&load->db);
9990 if (load->zone->lctx != NULL)
9991 dns_loadctx_detach(&load->zone->lctx);
9992 dns_zone_idetach(&load->zone);
9993 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
9997 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
9998 REQUIRE(DNS_ZONE_VALID(zone));
9999 REQUIRE(table != NULL);
10000 REQUIRE(*table == NULL);
10003 if (zone->ssutable != NULL)
10004 dns_ssutable_attach(zone->ssutable, table);
10009 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
10010 REQUIRE(DNS_ZONE_VALID(zone));
10013 if (zone->ssutable != NULL)
10014 dns_ssutable_detach(&zone->ssutable);
10016 dns_ssutable_attach(table, &zone->ssutable);
10021 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
10022 REQUIRE(DNS_ZONE_VALID(zone));
10024 zone->sigvalidityinterval = interval;
10028 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
10029 REQUIRE(DNS_ZONE_VALID(zone));
10031 return (zone->sigvalidityinterval);
10035 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
10036 REQUIRE(DNS_ZONE_VALID(zone));
10038 zone->sigresigninginterval = interval;
10042 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
10043 REQUIRE(DNS_ZONE_VALID(zone));
10045 return (zone->sigresigninginterval);
10049 queue_xfrin(dns_zone_t *zone) {
10050 const char me[] = "queue_xfrin";
10051 isc_result_t result;
10052 dns_zonemgr_t *zmgr = zone->zmgr;
10056 INSIST(zone->statelist == NULL);
10058 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10059 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
10063 zone->statelist = &zmgr->waiting_for_xfrin;
10064 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10065 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10067 if (result == ISC_R_QUOTA) {
10068 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
10069 "zone transfer deferred due to quota");
10070 } else if (result != ISC_R_SUCCESS) {
10071 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
10072 "starting zone transfer: %s",
10073 isc_result_totext(result));
10078 * This event callback is called when a zone has received
10079 * any necessary zone transfer quota. This is the time
10080 * to go ahead and start the transfer.
10083 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
10084 isc_result_t result;
10085 dns_peer_t *peer = NULL;
10086 char master[ISC_SOCKADDR_FORMATSIZE];
10087 char source[ISC_SOCKADDR_FORMATSIZE];
10088 dns_rdatatype_t xfrtype;
10089 dns_zone_t *zone = event->ev_arg;
10090 isc_netaddr_t masterip;
10091 isc_sockaddr_t sourceaddr;
10092 isc_sockaddr_t masteraddr;
10097 INSIST(task == zone->task);
10099 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10100 result = ISC_R_CANCELED;
10106 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10107 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10108 &zone->sourceaddr, &now)) {
10109 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10110 dns_zone_log(zone, ISC_LOG_INFO,
10111 "got_transfer_quota: skipping zone transfer as "
10112 "master %s (source %s) is unreachable (cached)",
10114 result = ISC_R_CANCELED;
10118 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10119 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
10122 * Decide whether we should request IXFR or AXFR.
10124 if (zone->db == NULL) {
10125 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10126 "no database exists yet, requesting AXFR of "
10127 "initial version from %s", master);
10128 xfrtype = dns_rdatatype_axfr;
10129 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
10130 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
10131 "set, requesting AXFR from %s", master);
10132 xfrtype = dns_rdatatype_axfr;
10133 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
10134 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10135 "forced reload, requesting AXFR of "
10136 "initial version from %s", master);
10137 xfrtype = dns_rdatatype_axfr;
10138 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
10139 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10140 "retrying with AXFR from %s due to "
10141 "previous IXFR failure", master);
10142 xfrtype = dns_rdatatype_axfr;
10144 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
10147 isc_boolean_t use_ixfr = ISC_TRUE;
10148 if (peer != NULL &&
10149 dns_peer_getrequestixfr(peer, &use_ixfr) ==
10151 ; /* Using peer setting */
10153 use_ixfr = zone->view->requestixfr;
10155 if (use_ixfr == ISC_FALSE) {
10156 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10157 "IXFR disabled, requesting AXFR from %s",
10159 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10160 xfrtype = dns_rdatatype_soa;
10162 xfrtype = dns_rdatatype_axfr;
10164 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10165 "requesting IXFR from %s", master);
10166 xfrtype = dns_rdatatype_ixfr;
10171 * Determine if we should attempt to sign the request with TSIG.
10173 result = ISC_R_NOTFOUND;
10175 * First, look for a tsig key in the master statement, then
10176 * try for a server key.
10178 if ((zone->masterkeynames != NULL) &&
10179 (zone->masterkeynames[zone->curmaster] != NULL)) {
10180 dns_view_t *view = dns_zone_getview(zone);
10181 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10182 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
10184 if (zone->tsigkey == NULL)
10185 result = dns_view_getpeertsig(zone->view, &masterip,
10188 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10189 dns_zone_log(zone, ISC_LOG_ERROR,
10190 "could not get TSIG key for zone transfer: %s",
10191 isc_result_totext(result));
10195 masteraddr = zone->masteraddr;
10196 sourceaddr = zone->sourceaddr;
10198 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
10199 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
10200 zone->tsigkey, zone->mctx,
10201 zone->zmgr->timermgr, zone->zmgr->socketmgr,
10202 zone->task, zone_xfrdone, &zone->xfr);
10203 if (result == ISC_R_SUCCESS) {
10205 if (xfrtype == dns_rdatatype_axfr) {
10206 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10207 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
10209 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
10210 } else if (xfrtype == dns_rdatatype_ixfr) {
10211 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10212 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
10214 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
10220 * Any failure in this function is handled like a failed
10221 * zone transfer. This ensures that we get removed from
10222 * zmgr->xfrin_in_progress.
10224 if (result != ISC_R_SUCCESS)
10225 zone_xfrdone(zone, result);
10227 isc_event_free(&event);
10231 * Update forwarding support.
10235 forward_destroy(dns_forward_t *forward) {
10237 forward->magic = 0;
10238 if (forward->request != NULL)
10239 dns_request_destroy(&forward->request);
10240 if (forward->msgbuf != NULL)
10241 isc_buffer_free(&forward->msgbuf);
10242 if (forward->zone != NULL)
10243 dns_zone_idetach(&forward->zone);
10244 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
10247 static isc_result_t
10248 sendtomaster(dns_forward_t *forward) {
10249 isc_result_t result;
10250 isc_sockaddr_t src;
10252 LOCK_ZONE(forward->zone);
10253 if (forward->which >= forward->zone->masterscnt) {
10254 UNLOCK_ZONE(forward->zone);
10255 return (ISC_R_NOMORE);
10258 forward->addr = forward->zone->masters[forward->which];
10260 * Always use TCP regardless of whether the original update
10262 * XXX The timeout may but a bit small if we are far down a
10263 * transfer graph and the master has to try several masters.
10265 switch (isc_sockaddr_pf(&forward->addr)) {
10267 src = forward->zone->xfrsource4;
10270 src = forward->zone->xfrsource6;
10273 result = ISC_R_NOTIMPLEMENTED;
10276 result = dns_request_createraw(forward->zone->view->requestmgr,
10278 &src, &forward->addr,
10279 DNS_REQUESTOPT_TCP, 15 /* XXX */,
10280 forward->zone->task,
10281 forward_callback, forward,
10282 &forward->request);
10284 UNLOCK_ZONE(forward->zone);
10289 forward_callback(isc_task_t *task, isc_event_t *event) {
10290 const char me[] = "forward_callback";
10291 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10292 dns_message_t *msg = NULL;
10293 char master[ISC_SOCKADDR_FORMATSIZE];
10294 isc_result_t result;
10295 dns_forward_t *forward;
10300 forward = revent->ev_arg;
10301 INSIST(DNS_FORWARD_VALID(forward));
10302 zone = forward->zone;
10303 INSIST(DNS_ZONE_VALID(zone));
10307 isc_sockaddr_format(&forward->addr, master, sizeof(master));
10309 if (revent->result != ISC_R_SUCCESS) {
10310 dns_zone_log(zone, ISC_LOG_INFO,
10311 "could not forward dynamic update to %s: %s",
10312 master, dns_result_totext(revent->result));
10316 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10317 if (result != ISC_R_SUCCESS)
10320 result = dns_request_getresponse(revent->request, msg,
10321 DNS_MESSAGEPARSE_PRESERVEORDER |
10322 DNS_MESSAGEPARSE_CLONEBUFFER);
10323 if (result != ISC_R_SUCCESS)
10326 switch (msg->rcode) {
10328 * Pass these rcodes back to client.
10330 case dns_rcode_noerror:
10331 case dns_rcode_yxdomain:
10332 case dns_rcode_yxrrset:
10333 case dns_rcode_nxrrset:
10334 case dns_rcode_refused:
10335 case dns_rcode_nxdomain:
10338 /* These should not occur if the masters/zone are valid. */
10339 case dns_rcode_notzone:
10340 case dns_rcode_notauth: {
10344 isc_buffer_init(&rb, rcode, sizeof(rcode));
10345 (void)dns_rcode_totext(msg->rcode, &rb);
10346 dns_zone_log(zone, ISC_LOG_WARNING,
10347 "forwarding dynamic update: "
10348 "unexpected response: master %s returned: %.*s",
10349 master, (int)rb.used, rcode);
10353 /* Try another server for these rcodes. */
10354 case dns_rcode_formerr:
10355 case dns_rcode_servfail:
10356 case dns_rcode_notimp:
10357 case dns_rcode_badvers:
10362 /* call callback */
10363 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
10365 dns_request_destroy(&forward->request);
10366 forward_destroy(forward);
10367 isc_event_free(&event);
10372 dns_message_destroy(&msg);
10373 isc_event_free(&event);
10375 dns_request_destroy(&forward->request);
10376 result = sendtomaster(forward);
10377 if (result != ISC_R_SUCCESS) {
10378 /* call callback */
10379 dns_zone_log(zone, ISC_LOG_DEBUG(3),
10380 "exhausted dynamic update forwarder list");
10381 (forward->callback)(forward->callback_arg, result, NULL);
10382 forward_destroy(forward);
10387 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
10388 dns_updatecallback_t callback, void *callback_arg)
10390 dns_forward_t *forward;
10391 isc_result_t result;
10394 REQUIRE(DNS_ZONE_VALID(zone));
10395 REQUIRE(msg != NULL);
10396 REQUIRE(callback != NULL);
10398 forward = isc_mem_get(zone->mctx, sizeof(*forward));
10399 if (forward == NULL)
10400 return (ISC_R_NOMEMORY);
10402 forward->request = NULL;
10403 forward->zone = NULL;
10404 forward->msgbuf = NULL;
10405 forward->which = 0;
10407 forward->callback = callback;
10408 forward->callback_arg = callback_arg;
10409 forward->magic = FORWARD_MAGIC;
10411 mr = dns_message_getrawmessage(msg);
10413 result = ISC_R_UNEXPECTEDEND;
10417 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
10418 if (result != ISC_R_SUCCESS)
10420 result = isc_buffer_copyregion(forward->msgbuf, mr);
10421 if (result != ISC_R_SUCCESS)
10424 isc_mem_attach(zone->mctx, &forward->mctx);
10425 dns_zone_iattach(zone, &forward->zone);
10426 result = sendtomaster(forward);
10429 if (result != ISC_R_SUCCESS) {
10430 forward_destroy(forward);
10436 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
10437 REQUIRE(DNS_ZONE_VALID(zone));
10438 REQUIRE(next != NULL && *next == NULL);
10440 *next = ISC_LIST_NEXT(zone, link);
10442 return (ISC_R_NOMORE);
10444 return (ISC_R_SUCCESS);
10448 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
10449 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10450 REQUIRE(first != NULL && *first == NULL);
10452 *first = ISC_LIST_HEAD(zmgr->zones);
10453 if (*first == NULL)
10454 return (ISC_R_NOMORE);
10456 return (ISC_R_SUCCESS);
10464 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
10465 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
10466 dns_zonemgr_t **zmgrp)
10468 dns_zonemgr_t *zmgr;
10469 isc_result_t result;
10470 isc_interval_t interval;
10472 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
10474 return (ISC_R_NOMEMORY);
10477 isc_mem_attach(mctx, &zmgr->mctx);
10478 zmgr->taskmgr = taskmgr;
10479 zmgr->timermgr = timermgr;
10480 zmgr->socketmgr = socketmgr;
10481 zmgr->zonetasks = NULL;
10484 ISC_LIST_INIT(zmgr->zones);
10485 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
10486 ISC_LIST_INIT(zmgr->xfrin_in_progress);
10487 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
10488 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
10489 if (result != ISC_R_SUCCESS)
10492 zmgr->transfersin = 10;
10493 zmgr->transfersperns = 2;
10495 /* Create the zone task pool. */
10496 result = isc_taskpool_create(taskmgr, mctx,
10497 8 /* XXX */, 2, &zmgr->zonetasks);
10498 if (result != ISC_R_SUCCESS)
10501 /* Create a single task for queueing of SOA queries. */
10502 result = isc_task_create(taskmgr, 1, &zmgr->task);
10503 if (result != ISC_R_SUCCESS)
10504 goto free_taskpool;
10505 isc_task_setname(zmgr->task, "zmgr", zmgr);
10506 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
10508 if (result != ISC_R_SUCCESS)
10510 /* default to 20 refresh queries / notifies per second. */
10511 isc_interval_set(&interval, 0, 1000000000/2);
10512 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
10513 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10514 isc_ratelimiter_setpertic(zmgr->rl, 10);
10517 zmgr->ioactive = 0;
10518 ISC_LIST_INIT(zmgr->high);
10519 ISC_LIST_INIT(zmgr->low);
10521 result = isc_mutex_init(&zmgr->iolock);
10522 if (result != ISC_R_SUCCESS)
10525 zmgr->magic = ZONEMGR_MAGIC;
10528 return (ISC_R_SUCCESS);
10532 DESTROYLOCK(&zmgr->iolock);
10535 isc_ratelimiter_detach(&zmgr->rl);
10537 isc_task_detach(&zmgr->task);
10539 isc_taskpool_destroy(&zmgr->zonetasks);
10541 isc_rwlock_destroy(&zmgr->rwlock);
10543 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10544 isc_mem_detach(&mctx);
10549 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10550 isc_result_t result;
10552 REQUIRE(DNS_ZONE_VALID(zone));
10553 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10555 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10557 REQUIRE(zone->task == NULL);
10558 REQUIRE(zone->timer == NULL);
10559 REQUIRE(zone->zmgr == NULL);
10561 isc_taskpool_gettask(zmgr->zonetasks,
10562 dns_name_hash(dns_zone_getorigin(zone),
10567 * Set the task name. The tag will arbitrarily point to one
10568 * of the zones sharing the task (in practice, the one
10569 * to be managed last).
10571 isc_task_setname(zone->task, "zone", zone);
10573 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
10575 zone->task, zone_timer, zone,
10578 if (result != ISC_R_SUCCESS)
10582 * The timer "holds" a iref.
10585 INSIST(zone->irefs != 0);
10587 ISC_LIST_APPEND(zmgr->zones, zone, link);
10594 isc_task_detach(&zone->task);
10598 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10603 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10604 isc_boolean_t free_now = ISC_FALSE;
10606 REQUIRE(DNS_ZONE_VALID(zone));
10607 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10608 REQUIRE(zone->zmgr == zmgr);
10610 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10613 ISC_LIST_UNLINK(zmgr->zones, zone, link);
10616 if (zmgr->refs == 0)
10617 free_now = ISC_TRUE;
10620 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10623 zonemgr_free(zmgr);
10624 ENSURE(zone->zmgr == NULL);
10628 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
10629 REQUIRE(DNS_ZONEMGR_VALID(source));
10630 REQUIRE(target != NULL && *target == NULL);
10632 RWLOCK(&source->rwlock, isc_rwlocktype_write);
10633 REQUIRE(source->refs > 0);
10635 INSIST(source->refs > 0);
10636 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
10641 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
10642 dns_zonemgr_t *zmgr;
10643 isc_boolean_t free_now = ISC_FALSE;
10645 REQUIRE(zmgrp != NULL);
10647 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10649 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10651 if (zmgr->refs == 0)
10652 free_now = ISC_TRUE;
10653 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10656 zonemgr_free(zmgr);
10660 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
10663 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10665 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10666 for (p = ISC_LIST_HEAD(zmgr->zones);
10668 p = ISC_LIST_NEXT(p, link))
10670 dns_zone_maintenance(p);
10672 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10675 * Recent configuration changes may have increased the
10676 * amount of available transfers quota. Make sure any
10677 * transfers currently blocked on quota get started if
10680 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10681 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10682 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10683 return (ISC_R_SUCCESS);
10687 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
10689 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10691 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10692 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10693 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10697 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
10698 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10700 isc_ratelimiter_shutdown(zmgr->rl);
10702 if (zmgr->task != NULL)
10703 isc_task_destroy(&zmgr->task);
10704 if (zmgr->zonetasks != NULL)
10705 isc_taskpool_destroy(&zmgr->zonetasks);
10709 zonemgr_free(dns_zonemgr_t *zmgr) {
10712 INSIST(zmgr->refs == 0);
10713 INSIST(ISC_LIST_EMPTY(zmgr->zones));
10717 DESTROYLOCK(&zmgr->iolock);
10718 isc_ratelimiter_detach(&zmgr->rl);
10720 isc_rwlock_destroy(&zmgr->rwlock);
10722 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10723 isc_mem_detach(&mctx);
10727 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10728 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10730 zmgr->transfersin = value;
10734 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
10735 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10737 return (zmgr->transfersin);
10741 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10742 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10744 zmgr->transfersperns = value;
10748 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
10749 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10751 return (zmgr->transfersperns);
10755 * Try to start a new incoming zone transfer to fill a quota
10756 * slot that was just vacated.
10759 * The zone manager is locked by the caller.
10762 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
10766 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
10770 isc_result_t result;
10771 next = ISC_LIST_NEXT(zone, statelink);
10772 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10773 if (result == ISC_R_SUCCESS) {
10777 * We successfully filled the slot. We're done.
10780 } else if (result == ISC_R_QUOTA) {
10782 * Not enough quota. This is probably the per-server
10783 * quota, because we usually get called when a unit of
10784 * global quota has just been freed. Try the next
10785 * zone, it may succeed if it uses another master.
10789 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10790 "starting zone transfer: %s",
10791 isc_result_totext(result));
10798 * Try to start an incoming zone transfer for 'zone', quota permitting.
10801 * The zone manager is locked by the caller.
10804 * ISC_R_SUCCESS There was enough quota and we attempted to
10805 * start a transfer. zone_xfrdone() has been or will
10807 * ISC_R_QUOTA Not enough quota.
10810 static isc_result_t
10811 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10812 dns_peer_t *peer = NULL;
10813 isc_netaddr_t masterip;
10814 isc_uint32_t nxfrsin, nxfrsperns;
10816 isc_uint32_t maxtransfersin, maxtransfersperns;
10820 * Find any configured information about the server we'd
10821 * like to transfer this zone from.
10823 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10824 (void)dns_peerlist_peerbyaddr(zone->view->peers,
10828 * Determine the total maximum number of simultaneous
10829 * transfers allowed, and the maximum for this specific
10832 maxtransfersin = zmgr->transfersin;
10833 maxtransfersperns = zmgr->transfersperns;
10835 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
10838 * Count the total number of transfers that are in progress,
10839 * and the number of transfers in progress from this master.
10840 * We linearly scan a list of all transfers; if this turns
10841 * out to be too slow, we could hash on the master address.
10843 nxfrsin = nxfrsperns = 0;
10844 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
10846 x = ISC_LIST_NEXT(x, statelink))
10849 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
10851 if (isc_netaddr_equal(&xip, &masterip))
10855 /* Enforce quota. */
10856 if (nxfrsin >= maxtransfersin)
10857 return (ISC_R_QUOTA);
10859 if (nxfrsperns >= maxtransfersperns)
10860 return (ISC_R_QUOTA);
10863 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
10864 * list and send it an event to let it start the actual transfer in the
10865 * context of its own task.
10867 e = isc_event_allocate(zmgr->mctx, zmgr,
10868 DNS_EVENT_ZONESTARTXFRIN,
10869 got_transfer_quota, zone,
10870 sizeof(isc_event_t));
10872 return (ISC_R_NOMEMORY);
10875 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
10876 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
10877 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
10878 zone->statelist = &zmgr->xfrin_in_progress;
10879 isc_task_send(zone->task, &e);
10880 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
10883 return (ISC_R_SUCCESS);
10887 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
10889 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10890 REQUIRE(iolimit > 0);
10892 zmgr->iolimit = iolimit;
10896 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
10898 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10900 return (zmgr->iolimit);
10904 * Get permission to request a file handle from the OS.
10905 * An event will be sent to action when one is available.
10906 * There are two queues available (high and low), the high
10907 * queue will be serviced before the low one.
10909 * zonemgr_putio() must be called after the event is delivered to
10913 static isc_result_t
10914 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
10915 isc_task_t *task, isc_taskaction_t action, void *arg,
10919 isc_boolean_t queue;
10921 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10922 REQUIRE(iop != NULL && *iop == NULL);
10924 io = isc_mem_get(zmgr->mctx, sizeof(*io));
10926 return (ISC_R_NOMEMORY);
10927 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
10928 action, arg, sizeof(*io->event));
10929 if (io->event == NULL) {
10930 isc_mem_put(zmgr->mctx, io, sizeof(*io));
10931 return (ISC_R_NOMEMORY);
10936 isc_task_attach(task, &io->task);
10937 ISC_LINK_INIT(io, link);
10938 io->magic = IO_MAGIC;
10940 LOCK(&zmgr->iolock);
10942 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
10945 ISC_LIST_APPEND(zmgr->high, io, link);
10947 ISC_LIST_APPEND(zmgr->low, io, link);
10949 UNLOCK(&zmgr->iolock);
10953 isc_task_send(io->task, &io->event);
10955 return (ISC_R_SUCCESS);
10959 zonemgr_putio(dns_io_t **iop) {
10962 dns_zonemgr_t *zmgr;
10964 REQUIRE(iop != NULL);
10966 REQUIRE(DNS_IO_VALID(io));
10970 INSIST(!ISC_LINK_LINKED(io, link));
10971 INSIST(io->event == NULL);
10974 isc_task_detach(&io->task);
10976 isc_mem_put(zmgr->mctx, io, sizeof(*io));
10978 LOCK(&zmgr->iolock);
10979 INSIST(zmgr->ioactive > 0);
10981 next = HEAD(zmgr->high);
10983 next = HEAD(zmgr->low);
10984 if (next != NULL) {
10986 ISC_LIST_UNLINK(zmgr->high, next, link);
10988 ISC_LIST_UNLINK(zmgr->low, next, link);
10989 INSIST(next->event != NULL);
10991 UNLOCK(&zmgr->iolock);
10993 isc_task_send(next->task, &next->event);
10997 zonemgr_cancelio(dns_io_t *io) {
10998 isc_boolean_t send_event = ISC_FALSE;
11000 REQUIRE(DNS_IO_VALID(io));
11003 * If we are queued to be run then dequeue.
11005 LOCK(&io->zmgr->iolock);
11006 if (ISC_LINK_LINKED(io, link)) {
11008 ISC_LIST_UNLINK(io->zmgr->high, io, link);
11010 ISC_LIST_UNLINK(io->zmgr->low, io, link);
11012 send_event = ISC_TRUE;
11013 INSIST(io->event != NULL);
11015 UNLOCK(&io->zmgr->iolock);
11017 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
11018 isc_task_send(io->task, &io->event);
11023 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
11026 isc_result_t result;
11028 buflen = strlen(path) + strlen(templat) + 2;
11030 buf = isc_mem_get(zone->mctx, buflen);
11034 result = isc_file_template(path, templat, buf, buflen);
11035 if (result != ISC_R_SUCCESS)
11038 result = isc_file_renameunique(path, buf);
11039 if (result != ISC_R_SUCCESS)
11042 dns_zone_log(zone, ISC_LOG_WARNING, "saved '%s' as '%s'",
11046 isc_mem_put(zone->mctx, buf, buflen);
11050 /* Hook for ondestroy notification from a database. */
11053 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
11054 dns_db_t *db = event->sender;
11057 isc_event_free(&event);
11059 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11060 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11061 "database (%p) destroyed", (void*) db);
11066 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
11067 isc_interval_t interval;
11068 isc_uint32_t s, ns;
11069 isc_uint32_t pertic;
11070 isc_result_t result;
11072 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11081 } else if (value <= 10) {
11083 ns = 1000000000 / value;
11087 ns = (1000000000 / value) * 10;
11091 isc_interval_set(&interval, s, ns);
11092 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
11093 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11094 isc_ratelimiter_setpertic(zmgr->rl, pertic);
11096 zmgr->serialqueryrate = value;
11100 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
11101 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11103 return (zmgr->serialqueryrate);
11106 static isc_boolean_t
11107 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11108 isc_sockaddr_t *local, isc_time_t *now)
11111 isc_rwlocktype_t locktype;
11112 isc_result_t result;
11113 isc_uint32_t seconds = isc_time_seconds(now);
11115 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11117 locktype = isc_rwlocktype_read;
11118 RWLOCK(&zmgr->rwlock, locktype);
11119 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11120 if (zmgr->unreachable[i].expire >= seconds &&
11121 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11122 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
11123 result = isc_rwlock_tryupgrade(&zmgr->rwlock);
11124 if (result == ISC_R_SUCCESS) {
11125 locktype = isc_rwlocktype_write;
11126 zmgr->unreachable[i].last = seconds;
11131 RWUNLOCK(&zmgr->rwlock, locktype);
11132 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
11136 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11137 isc_sockaddr_t *local, isc_time_t *now)
11139 isc_uint32_t seconds = isc_time_seconds(now);
11140 isc_uint32_t last = seconds;
11141 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
11143 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11145 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
11146 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11147 /* Existing entry? */
11148 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11149 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
11152 if (zmgr->unreachable[i].expire < seconds)
11154 /* Least recently used slot? */
11155 if (zmgr->unreachable[i].last < last) {
11156 last = zmgr->unreachable[i].last;
11160 if (i < UNREACH_CHACHE_SIZE) {
11162 * Found a existing entry. Update the expire timer and
11163 * last usage timestamps.
11165 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
11166 zmgr->unreachable[i].last = seconds;
11167 } else if (slot != UNREACH_CHACHE_SIZE) {
11169 * Found a empty slot. Add a new entry to the cache.
11171 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
11172 zmgr->unreachable[slot].last = seconds;
11173 zmgr->unreachable[slot].remote = *remote;
11174 zmgr->unreachable[slot].local = *local;
11177 * Replace the least recently used entry in the cache.
11179 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
11180 zmgr->unreachable[oldest].last = seconds;
11181 zmgr->unreachable[oldest].remote = *remote;
11182 zmgr->unreachable[oldest].local = *local;
11184 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
11188 dns_zone_forcereload(dns_zone_t *zone) {
11189 REQUIRE(DNS_ZONE_VALID(zone));
11191 if (zone->type == dns_zone_master)
11195 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
11197 dns_zone_refresh(zone);
11201 dns_zone_isforced(dns_zone_t *zone) {
11202 REQUIRE(DNS_ZONE_VALID(zone));
11204 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
11208 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
11210 * This function is obsoleted.
11214 return (ISC_R_NOTIMPLEMENTED);
11218 dns_zone_getstatscounters(dns_zone_t *zone) {
11220 * This function is obsoleted.
11227 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
11228 REQUIRE(DNS_ZONE_VALID(zone));
11229 REQUIRE(zone->stats == NULL);
11232 zone->stats = NULL;
11233 isc_stats_attach(stats, &zone->stats);
11238 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
11239 REQUIRE(DNS_ZONE_VALID(zone));
11242 if (zone->requeststats_on && stats == NULL)
11243 zone->requeststats_on = ISC_FALSE;
11244 else if (!zone->requeststats_on && stats != NULL) {
11245 if (zone->requeststats == NULL) {
11246 isc_stats_attach(stats, &zone->requeststats);
11247 zone->requeststats_on = ISC_TRUE;
11256 dns_zone_getrequeststats(dns_zone_t *zone) {
11258 * We don't lock zone for efficiency reason. This is not catastrophic
11259 * because requeststats must always be valid when requeststats_on is
11261 * Some counters may be incremented while requeststats_on is becoming
11262 * false, or some cannot be incremented just after the statistics are
11263 * installed, but it shouldn't matter much in practice.
11265 if (zone->requeststats_on)
11266 return (zone->requeststats);
11272 dns_zone_dialup(dns_zone_t *zone) {
11274 REQUIRE(DNS_ZONE_VALID(zone));
11276 zone_debuglog(zone, "dns_zone_dialup", 3,
11277 "notify = %d, refresh = %d",
11278 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
11279 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
11281 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
11282 dns_zone_notify(zone);
11283 if (zone->type != dns_zone_master &&
11284 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11285 dns_zone_refresh(zone);
11289 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
11290 REQUIRE(DNS_ZONE_VALID(zone));
11293 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
11294 DNS_ZONEFLG_DIALREFRESH |
11295 DNS_ZONEFLG_NOREFRESH);
11297 case dns_dialuptype_no:
11299 case dns_dialuptype_yes:
11300 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
11301 DNS_ZONEFLG_DIALREFRESH |
11302 DNS_ZONEFLG_NOREFRESH));
11304 case dns_dialuptype_notify:
11305 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11307 case dns_dialuptype_notifypassive:
11308 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11309 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11311 case dns_dialuptype_refresh:
11312 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
11313 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11315 case dns_dialuptype_passive:
11316 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11325 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
11326 isc_result_t result = ISC_R_SUCCESS;
11328 REQUIRE(DNS_ZONE_VALID(zone));
11331 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
11338 dns_zone_getkeydirectory(dns_zone_t *zone) {
11339 REQUIRE(DNS_ZONE_VALID(zone));
11341 return (zone->keydirectory);
11345 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
11347 unsigned int count = 0;
11349 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11351 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11353 case DNS_ZONESTATE_XFERRUNNING:
11354 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
11356 zone = ISC_LIST_NEXT(zone, statelink))
11359 case DNS_ZONESTATE_XFERDEFERRED:
11360 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
11362 zone = ISC_LIST_NEXT(zone, statelink))
11365 case DNS_ZONESTATE_SOAQUERY:
11366 for (zone = ISC_LIST_HEAD(zmgr->zones);
11368 zone = ISC_LIST_NEXT(zone, link))
11369 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
11372 case DNS_ZONESTATE_ANY:
11373 for (zone = ISC_LIST_HEAD(zmgr->zones);
11375 zone = ISC_LIST_NEXT(zone, link)) {
11376 dns_view_t *view = zone->view;
11377 if (view != NULL && strcmp(view->name, "_bind") == 0)
11386 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11392 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
11393 isc_boolean_t ok = ISC_TRUE;
11394 isc_boolean_t fail = ISC_FALSE;
11395 char namebuf[DNS_NAME_FORMATSIZE];
11396 char namebuf2[DNS_NAME_FORMATSIZE];
11397 char typebuf[DNS_RDATATYPE_FORMATSIZE];
11398 int level = ISC_LOG_WARNING;
11401 REQUIRE(DNS_ZONE_VALID(zone));
11403 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
11404 return (ISC_R_SUCCESS);
11406 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
11407 level = ISC_LOG_ERROR;
11411 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
11413 dns_name_format(name, namebuf, sizeof(namebuf));
11414 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11415 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
11416 dns_result_totext(DNS_R_BADOWNERNAME));
11418 return (DNS_R_BADOWNERNAME);
11421 dns_name_init(&bad, NULL);
11422 ok = dns_rdata_checknames(rdata, name, &bad);
11424 dns_name_format(name, namebuf, sizeof(namebuf));
11425 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
11426 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11427 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
11428 namebuf2, dns_result_totext(DNS_R_BADNAME));
11430 return (DNS_R_BADNAME);
11433 return (ISC_R_SUCCESS);
11437 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
11438 REQUIRE(DNS_ZONE_VALID(zone));
11439 zone->checkmx = checkmx;
11443 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
11444 REQUIRE(DNS_ZONE_VALID(zone));
11445 zone->checksrv = checksrv;
11449 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
11450 REQUIRE(DNS_ZONE_VALID(zone));
11451 zone->checkns = checkns;
11455 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
11456 REQUIRE(DNS_ZONE_VALID(zone));
11459 zone->isself = isself;
11460 zone->isselfarg = arg;
11465 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
11466 REQUIRE(DNS_ZONE_VALID(zone));
11469 zone->notifydelay = delay;
11474 dns_zone_getnotifydelay(dns_zone_t *zone) {
11475 REQUIRE(DNS_ZONE_VALID(zone));
11477 return (zone->notifydelay);
11481 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
11482 isc_uint16_t keyid, isc_boolean_t delete)
11484 isc_result_t result;
11485 REQUIRE(DNS_ZONE_VALID(zone));
11487 dns_zone_log(zone, ISC_LOG_NOTICE,
11488 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
11491 result = zone_signwithkey(zone, algorithm, keyid, delete);
11497 static const char *hex = "0123456789ABCDEF";
11500 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
11501 isc_result_t result;
11502 char salt[255*2+1];
11505 REQUIRE(DNS_ZONE_VALID(zone));
11507 if (nsec3param->salt_length != 0) {
11508 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
11509 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
11510 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
11511 salt[j++] = hex[nsec3param->salt[i] & 0xf];
11516 dns_zone_log(zone, ISC_LOG_NOTICE,
11517 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
11518 nsec3param->hash, nsec3param->iterations,
11521 result = zone_addnsec3chain(zone, nsec3param);
11528 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
11529 REQUIRE(DNS_ZONE_VALID(zone));
11533 zone->nodes = nodes;
11537 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
11538 REQUIRE(DNS_ZONE_VALID(zone));
11541 * We treat signatures as a signed value so explicitly
11542 * limit its range here.
11544 if (signatures > ISC_INT32_MAX)
11545 signatures = ISC_INT32_MAX;
11546 else if (signatures == 0)
11548 zone->signatures = signatures;
11552 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
11553 REQUIRE(DNS_ZONE_VALID(zone));
11554 zone->privatetype = type;
11558 dns_zone_getprivatetype(dns_zone_t *zone) {
11559 REQUIRE(DNS_ZONE_VALID(zone));
11560 return (zone->privatetype);
11563 static isc_result_t
11564 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
11565 isc_boolean_t delete)
11567 dns_signing_t *signing;
11568 dns_signing_t *current;
11569 isc_result_t result = ISC_R_SUCCESS;
11572 signing = isc_mem_get(zone->mctx, sizeof *signing);
11573 if (signing == NULL)
11574 return (ISC_R_NOMEMORY);
11576 signing->magic = 0;
11577 signing->db = NULL;
11578 signing->dbiterator = NULL;
11579 signing->algorithm = algorithm;
11580 signing->keyid = keyid;
11581 signing->delete = delete;
11582 signing->done = ISC_FALSE;
11586 for (current = ISC_LIST_HEAD(zone->signing);
11588 current = ISC_LIST_NEXT(current, link)) {
11589 if (current->db == zone->db &&
11590 current->algorithm == signing->algorithm &&
11591 current->keyid == signing->keyid) {
11592 if (current->delete != signing->delete)
11593 current->done = ISC_TRUE;
11599 if (zone->db != NULL) {
11600 dns_db_attach(zone->db, &signing->db);
11601 result = dns_db_createiterator(signing->db, 0,
11602 &signing->dbiterator);
11604 if (result == ISC_R_SUCCESS)
11605 result = dns_dbiterator_first(signing->dbiterator);
11606 if (result == ISC_R_SUCCESS) {
11607 dns_dbiterator_pause(signing->dbiterator);
11608 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
11610 if (isc_time_isepoch(&zone->signingtime)) {
11611 zone->signingtime = now;
11612 if (zone->task != NULL)
11613 zone_settimer(zone, &now);
11617 result = ISC_R_NOTFOUND;
11620 if (signing != NULL) {
11621 if (signing->db != NULL)
11622 dns_db_detach(&signing->db);
11623 if (signing->dbiterator != NULL)
11624 dns_dbiterator_destroy(&signing->dbiterator);
11625 isc_mem_put(zone->mctx, signing, sizeof *signing);