2 * Copyright (C) 2004-2010 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.23 2010-12-14 00:48:22 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;
1705 * "." means the services does not exist.
1707 if (dns_name_equal(name, dns_rootname))
1713 if (!dns_name_issubdomain(name, &zone->origin)) {
1714 if (zone->checkmx != NULL)
1715 return ((zone->checkmx)(zone, name, owner));
1719 if (zone->type == dns_zone_master)
1720 level = ISC_LOG_ERROR;
1722 level = ISC_LOG_WARNING;
1724 dns_fixedname_init(&fixed);
1725 foundname = dns_fixedname_name(&fixed);
1727 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1728 0, 0, NULL, foundname, NULL, NULL);
1729 if (result == ISC_R_SUCCESS)
1732 if (result == DNS_R_NXRRSET) {
1733 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1734 0, 0, NULL, foundname, NULL, NULL);
1735 if (result == ISC_R_SUCCESS)
1739 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1740 dns_name_format(name, namebuf, sizeof namebuf);
1741 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1742 result == DNS_R_EMPTYNAME) {
1743 dns_zone_log(zone, level,
1744 "%s/MX '%s' has no address records (A or AAAA)",
1746 /* XXX950 make fatal for 9.5.0. */
1750 if (result == DNS_R_CNAME) {
1751 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1752 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1753 level = ISC_LOG_WARNING;
1754 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1755 dns_zone_log(zone, level,
1756 "%s/MX '%s' is a CNAME (illegal)",
1758 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1761 if (result == DNS_R_DNAME) {
1762 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1763 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1764 level = ISC_LOG_WARNING;
1765 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1766 dns_name_format(foundname, altbuf, sizeof altbuf);
1767 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1768 " '%s' (illegal)", ownerbuf, namebuf,
1771 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1774 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1775 return ((zone->checkmx)(zone, name, owner));
1780 static isc_boolean_t
1781 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1784 isc_result_t result;
1785 char ownerbuf[DNS_NAME_FORMATSIZE];
1786 char namebuf[DNS_NAME_FORMATSIZE];
1787 char altbuf[DNS_NAME_FORMATSIZE];
1788 dns_fixedname_t fixed;
1789 dns_name_t *foundname;
1793 * "." means the services does not exist.
1795 if (dns_name_equal(name, dns_rootname))
1801 if (!dns_name_issubdomain(name, &zone->origin)) {
1802 if (zone->checksrv != NULL)
1803 return ((zone->checksrv)(zone, name, owner));
1807 if (zone->type == dns_zone_master)
1808 level = ISC_LOG_ERROR;
1810 level = ISC_LOG_WARNING;
1812 dns_fixedname_init(&fixed);
1813 foundname = dns_fixedname_name(&fixed);
1815 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1816 0, 0, NULL, foundname, NULL, NULL);
1817 if (result == ISC_R_SUCCESS)
1820 if (result == DNS_R_NXRRSET) {
1821 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1822 0, 0, NULL, foundname, NULL, NULL);
1823 if (result == ISC_R_SUCCESS)
1827 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1828 dns_name_format(name, namebuf, sizeof namebuf);
1829 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1830 result == DNS_R_EMPTYNAME) {
1831 dns_zone_log(zone, level,
1832 "%s/SRV '%s' has no address records (A or AAAA)",
1834 /* XXX950 make fatal for 9.5.0. */
1838 if (result == DNS_R_CNAME) {
1839 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1840 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1841 level = ISC_LOG_WARNING;
1842 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1843 dns_zone_log(zone, level,
1844 "%s/SRV '%s' is a CNAME (illegal)",
1846 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1849 if (result == DNS_R_DNAME) {
1850 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1851 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1852 level = ISC_LOG_WARNING;
1853 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1854 dns_name_format(foundname, altbuf, sizeof altbuf);
1855 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1856 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1859 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1862 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1863 return ((zone->checksrv)(zone, name, owner));
1868 static isc_boolean_t
1869 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1872 isc_boolean_t answer = ISC_TRUE;
1873 isc_result_t result, tresult;
1874 char ownerbuf[DNS_NAME_FORMATSIZE];
1875 char namebuf[DNS_NAME_FORMATSIZE];
1876 char altbuf[DNS_NAME_FORMATSIZE];
1877 dns_fixedname_t fixed;
1878 dns_name_t *foundname;
1880 dns_rdataset_t aaaa;
1886 if (!dns_name_issubdomain(name, &zone->origin)) {
1887 if (zone->checkns != NULL)
1888 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1892 if (zone->type == dns_zone_master)
1893 level = ISC_LOG_ERROR;
1895 level = ISC_LOG_WARNING;
1897 dns_fixedname_init(&fixed);
1898 foundname = dns_fixedname_name(&fixed);
1899 dns_rdataset_init(&a);
1900 dns_rdataset_init(&aaaa);
1902 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1903 DNS_DBFIND_GLUEOK, 0, NULL,
1904 foundname, &a, NULL);
1906 if (result == ISC_R_SUCCESS) {
1907 dns_rdataset_disassociate(&a);
1909 } else if (result == DNS_R_DELEGATION)
1910 dns_rdataset_disassociate(&a);
1912 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1913 result == DNS_R_GLUE) {
1914 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1915 DNS_DBFIND_GLUEOK, 0, NULL,
1916 foundname, &aaaa, NULL);
1917 if (tresult == ISC_R_SUCCESS) {
1918 dns_rdataset_disassociate(&aaaa);
1921 if (tresult == DNS_R_DELEGATION)
1922 dns_rdataset_disassociate(&aaaa);
1923 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1925 * Check glue against child zone.
1927 if (zone->checkns != NULL)
1928 answer = (zone->checkns)(zone, name, owner,
1930 if (dns_rdataset_isassociated(&a))
1931 dns_rdataset_disassociate(&a);
1932 if (dns_rdataset_isassociated(&aaaa))
1933 dns_rdataset_disassociate(&aaaa);
1939 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1940 dns_name_format(name, namebuf, sizeof namebuf);
1941 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1942 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
1944 isc_boolean_t required = ISC_FALSE;
1945 if (dns_name_issubdomain(name, owner)) {
1946 what = "REQUIRED GLUE ";
1947 required = ISC_TRUE;
1948 } else if (result == DNS_R_DELEGATION)
1949 what = "SIBLING GLUE ";
1953 if (result != DNS_R_DELEGATION || required ||
1954 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
1955 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
1956 "address records (A or AAAA)",
1957 ownerbuf, namebuf, what);
1959 * Log missing address record.
1961 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
1962 (void)(zone->checkns)(zone, name, owner,
1964 /* XXX950 make fatal for 9.5.0. */
1965 /* answer = ISC_FALSE; */
1967 } else if (result == DNS_R_CNAME) {
1968 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
1970 /* XXX950 make fatal for 9.5.0. */
1971 /* answer = ISC_FALSE; */
1972 } else if (result == DNS_R_DNAME) {
1973 dns_name_format(foundname, altbuf, sizeof altbuf);
1974 dns_zone_log(zone, level,
1975 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1976 ownerbuf, namebuf, altbuf);
1977 /* XXX950 make fatal for 9.5.0. */
1978 /* answer = ISC_FALSE; */
1981 if (dns_rdataset_isassociated(&a))
1982 dns_rdataset_disassociate(&a);
1983 if (dns_rdataset_isassociated(&aaaa))
1984 dns_rdataset_disassociate(&aaaa);
1988 static isc_boolean_t
1989 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
1990 dns_dbiterator_t *dbiterator = NULL;
1991 dns_dbnode_t *node = NULL;
1992 dns_rdataset_t rdataset;
1993 dns_fixedname_t fixed;
1994 dns_fixedname_t fixedbottom;
1997 dns_rdata_in_srv_t srv;
2001 isc_result_t result;
2002 isc_boolean_t ok = ISC_TRUE;
2004 dns_fixedname_init(&fixed);
2005 name = dns_fixedname_name(&fixed);
2006 dns_fixedname_init(&fixedbottom);
2007 bottom = dns_fixedname_name(&fixedbottom);
2008 dns_rdataset_init(&rdataset);
2009 dns_rdata_init(&rdata);
2011 result = dns_db_createiterator(db, 0, &dbiterator);
2012 if (result != ISC_R_SUCCESS)
2015 result = dns_dbiterator_first(dbiterator);
2016 while (result == ISC_R_SUCCESS) {
2017 result = dns_dbiterator_current(dbiterator, &node, name);
2018 if (result != ISC_R_SUCCESS)
2022 * Is this name visible in the zone?
2024 if (!dns_name_issubdomain(name, &zone->origin) ||
2025 (dns_name_countlabels(bottom) > 0 &&
2026 dns_name_issubdomain(name, bottom)))
2030 * Don't check the NS records at the origin.
2032 if (dns_name_equal(name, &zone->origin))
2035 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2036 0, 0, &rdataset, NULL);
2037 if (result != ISC_R_SUCCESS)
2040 * Remember bottom of zone.
2042 dns_name_copy(name, bottom, NULL);
2044 result = dns_rdataset_first(&rdataset);
2045 while (result == ISC_R_SUCCESS) {
2046 dns_rdataset_current(&rdataset, &rdata);
2047 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2048 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2049 if (!zone_check_glue(zone, db, &ns.name, name))
2051 dns_rdata_reset(&rdata);
2052 result = dns_rdataset_next(&rdataset);
2054 dns_rdataset_disassociate(&rdataset);
2057 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2058 0, 0, &rdataset, NULL);
2059 if (result != ISC_R_SUCCESS)
2061 result = dns_rdataset_first(&rdataset);
2062 while (result == ISC_R_SUCCESS) {
2063 dns_rdataset_current(&rdataset, &rdata);
2064 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2065 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2066 if (!zone_check_mx(zone, db, &mx.mx, name))
2068 dns_rdata_reset(&rdata);
2069 result = dns_rdataset_next(&rdataset);
2071 dns_rdataset_disassociate(&rdataset);
2074 if (zone->rdclass != dns_rdataclass_in)
2076 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2077 0, 0, &rdataset, NULL);
2078 if (result != ISC_R_SUCCESS)
2080 result = dns_rdataset_first(&rdataset);
2081 while (result == ISC_R_SUCCESS) {
2082 dns_rdataset_current(&rdataset, &rdata);
2083 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2084 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2085 if (!zone_check_srv(zone, db, &srv.target, name))
2087 dns_rdata_reset(&rdata);
2088 result = dns_rdataset_next(&rdataset);
2090 dns_rdataset_disassociate(&rdataset);
2093 dns_db_detachnode(db, &node);
2094 result = dns_dbiterator_next(dbiterator);
2099 dns_db_detachnode(db, &node);
2100 dns_dbiterator_destroy(&dbiterator);
2106 * OpenSSL verification of RSA keys with exponent 3 is known to be
2107 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2108 * if they are in use.
2111 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2112 dns_dbnode_t *node = NULL;
2113 dns_dbversion_t *version = NULL;
2114 dns_rdata_dnskey_t dnskey;
2115 dns_rdata_t rdata = DNS_RDATA_INIT;
2116 dns_rdataset_t rdataset;
2117 isc_result_t result;
2118 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2119 const char *algorithm;
2121 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2122 if (result != ISC_R_SUCCESS)
2125 dns_db_currentversion(db, &version);
2126 dns_rdataset_init(&rdataset);
2127 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2128 dns_rdatatype_none, 0, &rdataset, NULL);
2129 if (result != ISC_R_SUCCESS)
2132 for (result = dns_rdataset_first(&rdataset);
2133 result == ISC_R_SUCCESS;
2134 result = dns_rdataset_next(&rdataset))
2136 dns_rdataset_current(&rdataset, &rdata);
2137 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2138 INSIST(result == ISC_R_SUCCESS);
2140 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2141 dnskey.algorithm == DST_ALG_RSAMD5) &&
2142 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2143 dnskey.data[1] == 3)
2145 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2147 foundrsa = ISC_TRUE;
2148 algorithm = "RSASHA1";
2151 foundmd5 = ISC_TRUE;
2152 algorithm = "RSAMD5";
2155 dns_zone_log(zone, ISC_LOG_WARNING,
2156 "weak %s (%u) key found "
2157 "(exponent=3)", algorithm,
2159 if (foundrsa && foundmd5)
2162 dns_rdata_reset(&rdata);
2164 dns_rdataset_disassociate(&rdataset);
2168 dns_db_detachnode(db, &node);
2169 if (version != NULL)
2170 dns_db_closeversion(db, &version, ISC_FALSE);
2175 resume_signingwithkey(dns_zone_t *zone) {
2176 dns_dbnode_t *node = NULL;
2177 dns_dbversion_t *version = NULL;
2178 dns_rdata_t rdata = DNS_RDATA_INIT;
2179 dns_rdataset_t rdataset;
2180 isc_result_t result;
2182 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2183 if (result != ISC_R_SUCCESS)
2186 dns_db_currentversion(zone->db, &version);
2187 dns_rdataset_init(&rdataset);
2188 result = dns_db_findrdataset(zone->db, node, version,
2190 dns_rdatatype_none, 0,
2192 if (result != ISC_R_SUCCESS)
2195 for (result = dns_rdataset_first(&rdataset);
2196 result == ISC_R_SUCCESS;
2197 result = dns_rdataset_next(&rdataset))
2199 dns_rdataset_current(&rdataset, &rdata);
2200 if (rdata.length != 5 || rdata.data[4] != 0) {
2201 dns_rdata_reset(&rdata);
2205 result = zone_signwithkey(zone, rdata.data[0],
2206 (rdata.data[1] << 8) | rdata.data[2],
2207 ISC_TF(rdata.data[3]));
2208 if (result != ISC_R_SUCCESS) {
2209 dns_zone_log(zone, ISC_LOG_ERROR,
2210 "zone_signwithkey failed: %s",
2211 dns_result_totext(result));
2213 dns_rdata_reset(&rdata);
2215 dns_rdataset_disassociate(&rdataset);
2219 dns_db_detachnode(zone->db, &node);
2220 if (version != NULL)
2221 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2226 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2227 dns_nsec3chain_t *nsec3chain, *current;
2228 isc_result_t result;
2230 unsigned int options = 0;
2232 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2233 if (nsec3chain == NULL)
2234 return (ISC_R_NOMEMORY);
2236 nsec3chain->magic = 0;
2237 nsec3chain->done = ISC_FALSE;
2238 nsec3chain->db = NULL;
2239 nsec3chain->dbiterator = NULL;
2240 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2241 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2242 nsec3chain->nsec3param.hash = nsec3param->hash;
2243 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2244 nsec3chain->nsec3param.flags = nsec3param->flags;
2245 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2246 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2247 nsec3chain->nsec3param.salt = nsec3chain->salt;
2248 nsec3chain->seen_nsec = ISC_FALSE;
2249 nsec3chain->delete_nsec = ISC_FALSE;
2250 nsec3chain->save_delete_nsec = ISC_FALSE;
2252 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2254 current = ISC_LIST_NEXT(current, link)) {
2255 if (current->db == zone->db &&
2256 current->nsec3param.hash == nsec3param->hash &&
2257 current->nsec3param.iterations == nsec3param->iterations &&
2258 current->nsec3param.salt_length == nsec3param->salt_length
2259 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2260 nsec3param->salt_length))
2261 current->done = ISC_TRUE;
2264 if (zone->db != NULL) {
2265 dns_db_attach(zone->db, &nsec3chain->db);
2266 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2267 options = DNS_DB_NONSEC3;
2268 result = dns_db_createiterator(nsec3chain->db, options,
2269 &nsec3chain->dbiterator);
2270 if (result == ISC_R_SUCCESS)
2271 dns_dbiterator_first(nsec3chain->dbiterator);
2272 if (result == ISC_R_SUCCESS) {
2273 dns_dbiterator_pause(nsec3chain->dbiterator);
2274 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2277 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2279 zone->nsec3chaintime = now;
2280 if (zone->task != NULL)
2281 zone_settimer(zone, &now);
2285 result = ISC_R_NOTFOUND;
2287 if (nsec3chain != NULL) {
2288 if (nsec3chain->db != NULL)
2289 dns_db_detach(&nsec3chain->db);
2290 if (nsec3chain->dbiterator != NULL)
2291 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2292 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2298 resume_addnsec3chain(dns_zone_t *zone) {
2299 dns_dbnode_t *node = NULL;
2300 dns_dbversion_t *version = NULL;
2301 dns_rdata_t rdata = DNS_RDATA_INIT;
2302 dns_rdataset_t rdataset;
2303 isc_result_t result;
2304 dns_rdata_nsec3param_t nsec3param;
2306 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2307 if (result != ISC_R_SUCCESS)
2310 dns_db_currentversion(zone->db, &version);
2311 dns_rdataset_init(&rdataset);
2312 result = dns_db_findrdataset(zone->db, node, version,
2313 dns_rdatatype_nsec3param,
2314 dns_rdatatype_none, 0,
2316 if (result != ISC_R_SUCCESS)
2319 for (result = dns_rdataset_first(&rdataset);
2320 result == ISC_R_SUCCESS;
2321 result = dns_rdataset_next(&rdataset))
2323 dns_rdataset_current(&rdataset, &rdata);
2324 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2325 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2326 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
2327 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
2328 result = zone_addnsec3chain(zone, &nsec3param);
2329 if (result != ISC_R_SUCCESS) {
2330 dns_zone_log(zone, ISC_LOG_ERROR,
2331 "zone_addnsec3chain failed: %s",
2332 dns_result_totext(result));
2335 dns_rdata_reset(&rdata);
2337 dns_rdataset_disassociate(&rdataset);
2341 dns_db_detachnode(zone->db, &node);
2342 if (version != NULL)
2343 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2347 set_resigntime(dns_zone_t *zone) {
2348 dns_rdataset_t rdataset;
2349 dns_fixedname_t fixed;
2350 unsigned int resign;
2351 isc_result_t result;
2352 isc_uint32_t nanosecs;
2354 dns_rdataset_init(&rdataset);
2355 dns_fixedname_init(&fixed);
2356 result = dns_db_getsigningtime(zone->db, &rdataset,
2357 dns_fixedname_name(&fixed));
2358 if (result != ISC_R_SUCCESS) {
2359 isc_time_settoepoch(&zone->resigntime);
2362 resign = rdataset.resign;
2363 dns_rdataset_disassociate(&rdataset);
2364 isc_random_get(&nanosecs);
2365 nanosecs %= 1000000000;
2366 isc_time_set(&zone->resigntime, resign, nanosecs);
2370 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2371 dns_dbnode_t *node = NULL;
2372 dns_rdataset_t rdataset;
2373 dns_dbversion_t *version = NULL;
2374 dns_rdata_nsec3param_t nsec3param;
2375 isc_boolean_t ok = ISC_FALSE;
2376 isc_result_t result;
2377 dns_rdata_t rdata = DNS_RDATA_INIT;
2378 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
2379 zone_isdynamic(zone) : ISC_FALSE;
2381 dns_rdataset_init(&rdataset);
2382 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2383 if (result != ISC_R_SUCCESS) {
2384 dns_zone_log(zone, ISC_LOG_ERROR,
2385 "nsec3param lookup failure: %s",
2386 dns_result_totext(result));
2389 dns_db_currentversion(db, &version);
2391 result = dns_db_findrdataset(db, node, version,
2392 dns_rdatatype_nsec3param,
2393 dns_rdatatype_none, 0, &rdataset, NULL);
2394 if (result == ISC_R_NOTFOUND) {
2395 result = ISC_R_SUCCESS;
2398 if (result != ISC_R_SUCCESS) {
2399 dns_zone_log(zone, ISC_LOG_ERROR,
2400 "nsec3param lookup failure: %s",
2401 dns_result_totext(result));
2406 * For dynamic zones we must support every algorithm so we can
2407 * regenerate all the NSEC3 chains.
2408 * For non-dynamic zones we only need to find a supported algorithm.
2410 for (result = dns_rdataset_first(&rdataset);
2411 result == ISC_R_SUCCESS;
2412 result = dns_rdataset_next(&rdataset))
2414 dns_rdataset_current(&rdataset, &rdata);
2415 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2416 dns_rdata_reset(&rdata);
2417 INSIST(result == ISC_R_SUCCESS);
2418 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
2419 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
2421 dns_zone_log(zone, ISC_LOG_WARNING,
2422 "nsec3 test \"unknown\" hash algorithm found: %u",
2425 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
2427 dns_zone_log(zone, ISC_LOG_ERROR,
2428 "unsupported nsec3 hash algorithm"
2429 " in dynamic zone: %u",
2431 result = DNS_R_BADZONE;
2432 /* Stop second error message. */
2436 dns_zone_log(zone, ISC_LOG_WARNING,
2437 "unsupported nsec3 hash algorithm: %u",
2442 if (result == ISC_R_NOMORE)
2443 result = ISC_R_SUCCESS;
2446 result = DNS_R_BADZONE;
2447 dns_zone_log(zone, ISC_LOG_ERROR,
2448 "no supported nsec3 hash algorithm");
2452 if (dns_rdataset_isassociated(&rdataset))
2453 dns_rdataset_disassociate(&rdataset);
2454 dns_db_closeversion(db, &version, ISC_FALSE);
2455 dns_db_detachnode(db, &node);
2460 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
2461 isc_result_t result)
2463 unsigned int soacount = 0;
2464 unsigned int nscount = 0;
2465 unsigned int errors = 0;
2466 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
2468 isc_boolean_t needdump = ISC_FALSE;
2469 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2470 unsigned int options;
2475 * Initiate zone transfer? We may need a error code that
2476 * indicates that the "permanent" form does not exist.
2477 * XXX better error feedback to log.
2479 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
2480 if (zone->type == dns_zone_slave ||
2481 zone->type == dns_zone_stub) {
2482 if (result == ISC_R_FILENOTFOUND)
2483 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2485 else if (result != DNS_R_NOMASTERFILE)
2486 dns_zone_log(zone, ISC_LOG_ERROR,
2487 "loading from master file %s "
2490 dns_result_totext(result));
2492 dns_zone_log(zone, ISC_LOG_ERROR,
2493 "loading from master file %s failed: %s",
2495 dns_result_totext(result));
2499 dns_zone_log(zone, ISC_LOG_DEBUG(2),
2500 "number of nodes in database: %u",
2501 dns_db_nodecount(db));
2503 if (result == DNS_R_SEENINCLUDE)
2504 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2506 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2509 * Apply update log, if any, on initial load.
2511 if (zone->journal != NULL &&
2512 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
2513 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
2515 if (zone->type == dns_zone_master &&
2516 (zone->update_acl != NULL || zone->ssutable != NULL))
2517 options = DNS_JOURNALOPT_RESIGN;
2520 result = dns_journal_rollforward2(zone->mctx, db, options,
2521 zone->sigresigninginterval,
2523 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
2524 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
2525 result != ISC_R_RANGE) {
2526 dns_zone_log(zone, ISC_LOG_ERROR,
2527 "journal rollforward failed: %s",
2528 dns_result_totext(result));
2531 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
2532 dns_zone_log(zone, ISC_LOG_ERROR,
2533 "journal rollforward failed: "
2534 "journal out of sync with zone");
2537 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2538 "journal rollforward completed "
2540 dns_result_totext(result));
2541 if (result == ISC_R_SUCCESS)
2542 needdump = ISC_TRUE;
2545 zone->loadtime = loadtime;
2547 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded");
2549 * Obtain ns, soa and cname counts for top of zone.
2552 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
2553 &refresh, &retry, &expire, &minimum,
2555 if (result != ISC_R_SUCCESS) {
2556 dns_zone_log(zone, ISC_LOG_ERROR,
2557 "could not find NS and/or SOA records");
2561 * Master / Slave / Stub zones require both NS and SOA records at
2562 * the top of the zone.
2565 switch (zone->type) {
2566 case dns_zone_master:
2567 case dns_zone_slave:
2569 if (soacount != 1) {
2570 dns_zone_log(zone, ISC_LOG_ERROR,
2571 "has %d SOA records", soacount);
2572 result = DNS_R_BADZONE;
2575 dns_zone_log(zone, ISC_LOG_ERROR,
2576 "has no NS records");
2577 result = DNS_R_BADZONE;
2579 if (result != ISC_R_SUCCESS)
2581 if (zone->type == dns_zone_master && errors != 0) {
2582 result = DNS_R_BADZONE;
2585 if (zone->type != dns_zone_stub) {
2586 result = check_nsec3param(zone, db);
2587 if (result != ISC_R_SUCCESS)
2590 if (zone->type == dns_zone_master &&
2591 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
2592 !integrity_checks(zone, db)) {
2593 result = DNS_R_BADZONE;
2597 if (zone->db != NULL) {
2599 * This is checked in zone_replacedb() for slave zones
2600 * as they don't reload from disk.
2602 result = zone_get_from_db(zone, zone->db, NULL, NULL,
2603 &oldserial, NULL, NULL, NULL,
2605 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2606 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
2607 !isc_serial_gt(serial, oldserial)) {
2608 isc_uint32_t serialmin, serialmax;
2610 INSIST(zone->type == dns_zone_master);
2612 serialmin = (oldserial + 1) & 0xffffffffU;
2613 serialmax = (oldserial + 0x7fffffffU) &
2615 dns_zone_log(zone, ISC_LOG_ERROR,
2616 "ixfr-from-differences: "
2617 "new serial (%u) out of range "
2618 "[%u - %u]", serial, serialmin,
2620 result = DNS_R_BADZONE;
2622 } else if (!isc_serial_ge(serial, oldserial))
2623 dns_zone_log(zone, ISC_LOG_ERROR,
2624 "zone serial has gone backwards");
2625 else if (serial == oldserial && !hasinclude)
2626 dns_zone_log(zone, ISC_LOG_ERROR,
2627 "zone serial unchanged. "
2628 "zone may fail to transfer "
2632 if (zone->type == dns_zone_master &&
2633 (zone->update_acl != NULL || zone->ssutable != NULL) &&
2634 zone->sigresigninginterval < (3 * refresh) &&
2635 dns_db_issecure(db))
2637 dns_zone_log(zone, ISC_LOG_WARNING,
2638 "sig-re-signing-interval less than "
2642 zone->refresh = RANGE(refresh,
2643 zone->minrefresh, zone->maxrefresh);
2644 zone->retry = RANGE(retry,
2645 zone->minretry, zone->maxretry);
2646 zone->expire = RANGE(expire, zone->refresh + zone->retry,
2648 zone->minimum = minimum;
2649 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
2651 if (zone->type == dns_zone_slave ||
2652 zone->type == dns_zone_stub) {
2656 result = isc_file_getmodtime(zone->journal, &t);
2657 if (result != ISC_R_SUCCESS)
2658 result = isc_file_getmodtime(zone->masterfile,
2660 if (result == ISC_R_SUCCESS)
2661 DNS_ZONE_TIME_ADD(&t, zone->expire,
2664 DNS_ZONE_TIME_ADD(&now, zone->retry,
2667 delay = isc_random_jitter(zone->retry,
2668 (zone->retry * 3) / 4);
2669 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
2670 if (isc_time_compare(&zone->refreshtime,
2671 &zone->expiretime) >= 0)
2672 zone->refreshtime = now;
2676 UNEXPECTED_ERROR(__FILE__, __LINE__,
2677 "unexpected zone type %d", zone->type);
2678 result = ISC_R_UNEXPECTED;
2683 * Check for weak DNSKEY's.
2685 if (zone->type == dns_zone_master)
2686 zone_check_dnskeys(zone, db);
2689 /* destroy notification example. */
2691 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
2692 DNS_EVENT_DBDESTROYED,
2693 dns_zonemgr_dbdestroyed,
2695 sizeof(isc_event_t));
2696 dns_db_ondestroy(db, zone->task, &e);
2700 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2701 if (zone->db != NULL) {
2702 result = zone_replacedb(zone, db, ISC_FALSE);
2703 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2704 if (result != ISC_R_SUCCESS)
2707 zone_attachdb(zone, db);
2708 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2709 DNS_ZONE_SETFLAG(zone,
2710 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
2712 result = ISC_R_SUCCESS;
2714 zone_needdump(zone, DNS_DUMP_DELAY);
2715 if (zone->task != NULL) {
2716 if (zone->type == dns_zone_master) {
2717 set_resigntime(zone);
2718 resume_signingwithkey(zone);
2719 resume_addnsec3chain(zone);
2721 zone_settimer(zone, &now);
2724 if (! dns_db_ispersistent(db))
2725 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
2726 dns_db_issecure(db) ? " (signed)" : "");
2731 if (zone->type == dns_zone_slave ||
2732 zone->type == dns_zone_stub) {
2733 if (zone->journal != NULL)
2734 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
2735 if (zone->masterfile != NULL)
2736 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
2738 /* Mark the zone for immediate refresh. */
2739 zone->refreshtime = now;
2740 if (zone->task != NULL)
2741 zone_settimer(zone, &now);
2742 result = ISC_R_SUCCESS;
2743 } else if (zone->type == dns_zone_master)
2744 dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
2748 static isc_boolean_t
2749 exit_check(dns_zone_t *zone) {
2751 REQUIRE(LOCKED_ZONE(zone));
2753 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
2757 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2759 INSIST(isc_refcount_current(&zone->erefs) == 0);
2765 static isc_boolean_t
2766 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
2767 isc_result_t result;
2768 char namebuf[DNS_NAME_FORMATSIZE];
2769 char altbuf[DNS_NAME_FORMATSIZE];
2770 dns_fixedname_t fixed;
2771 dns_name_t *foundname;
2774 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
2777 if (zone->type == dns_zone_master)
2778 level = ISC_LOG_ERROR;
2780 level = ISC_LOG_WARNING;
2782 dns_fixedname_init(&fixed);
2783 foundname = dns_fixedname_name(&fixed);
2785 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2786 0, 0, NULL, foundname, NULL, NULL);
2787 if (result == ISC_R_SUCCESS)
2790 if (result == DNS_R_NXRRSET) {
2791 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2792 0, 0, NULL, foundname, NULL, NULL);
2793 if (result == ISC_R_SUCCESS)
2797 dns_name_format(name, namebuf, sizeof namebuf);
2798 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2799 result == DNS_R_EMPTYNAME) {
2800 dns_zone_log(zone, level,
2801 "NS '%s' has no address records (A or AAAA)",
2803 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2807 if (result == DNS_R_CNAME) {
2808 dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
2810 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2814 if (result == DNS_R_DNAME) {
2815 dns_name_format(foundname, altbuf, sizeof altbuf);
2816 dns_zone_log(zone, level,
2817 "NS '%s' is below a DNAME '%s' (illegal)",
2819 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2827 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
2828 dns_dbversion_t *version, unsigned int *nscount,
2829 unsigned int *errors)
2831 isc_result_t result;
2832 unsigned int count = 0;
2833 unsigned int ecount = 0;
2834 dns_rdataset_t rdataset;
2838 dns_rdataset_init(&rdataset);
2839 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
2840 dns_rdatatype_none, 0, &rdataset, NULL);
2841 if (result == ISC_R_NOTFOUND)
2843 if (result != ISC_R_SUCCESS)
2844 goto invalidate_rdataset;
2846 result = dns_rdataset_first(&rdataset);
2847 while (result == ISC_R_SUCCESS) {
2848 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
2849 (zone->type == dns_zone_master ||
2850 zone->type == dns_zone_slave)) {
2851 dns_rdata_init(&rdata);
2852 dns_rdataset_current(&rdataset, &rdata);
2853 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2854 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2855 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
2856 !zone_check_ns(zone, db, &ns.name))
2860 result = dns_rdataset_next(&rdataset);
2862 dns_rdataset_disassociate(&rdataset);
2865 if (nscount != NULL)
2870 result = ISC_R_SUCCESS;
2872 invalidate_rdataset:
2873 dns_rdataset_invalidate(&rdataset);
2879 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
2880 unsigned int *soacount,
2881 isc_uint32_t *serial, isc_uint32_t *refresh,
2882 isc_uint32_t *retry, isc_uint32_t *expire,
2883 isc_uint32_t *minimum)
2885 isc_result_t result;
2887 dns_rdataset_t rdataset;
2888 dns_rdata_t rdata = DNS_RDATA_INIT;
2889 dns_rdata_soa_t soa;
2891 dns_rdataset_init(&rdataset);
2892 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
2893 dns_rdatatype_none, 0, &rdataset, NULL);
2894 if (result == ISC_R_NOTFOUND) {
2895 if (soacount != NULL)
2899 if (refresh != NULL)
2905 if (minimum != NULL)
2907 result = ISC_R_SUCCESS;
2908 goto invalidate_rdataset;
2910 if (result != ISC_R_SUCCESS)
2911 goto invalidate_rdataset;
2914 result = dns_rdataset_first(&rdataset);
2915 while (result == ISC_R_SUCCESS) {
2916 dns_rdata_init(&rdata);
2917 dns_rdataset_current(&rdataset, &rdata);
2920 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2921 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2924 result = dns_rdataset_next(&rdataset);
2925 dns_rdata_reset(&rdata);
2927 dns_rdataset_disassociate(&rdataset);
2929 if (soacount != NULL)
2934 *serial = soa.serial;
2935 if (refresh != NULL)
2936 *refresh = soa.refresh;
2940 *expire = soa.expire;
2941 if (minimum != NULL)
2942 *minimum = soa.minimum;
2945 result = ISC_R_SUCCESS;
2947 invalidate_rdataset:
2948 dns_rdataset_invalidate(&rdataset);
2954 * zone must be locked.
2957 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
2958 unsigned int *soacount, isc_uint32_t *serial,
2959 isc_uint32_t *refresh, isc_uint32_t *retry,
2960 isc_uint32_t *expire, isc_uint32_t *minimum,
2961 unsigned int *errors)
2963 dns_dbversion_t *version;
2964 isc_result_t result;
2965 isc_result_t answer = ISC_R_SUCCESS;
2968 REQUIRE(db != NULL);
2969 REQUIRE(zone != NULL);
2972 dns_db_currentversion(db, &version);
2975 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2976 if (result != ISC_R_SUCCESS) {
2981 if (nscount != NULL || errors != NULL) {
2982 result = zone_count_ns_rr(zone, db, node, version,
2984 if (result != ISC_R_SUCCESS)
2988 if (soacount != NULL || serial != NULL || refresh != NULL
2989 || retry != NULL || expire != NULL || minimum != NULL) {
2990 result = zone_load_soa_rr(db, node, version, soacount,
2991 serial, refresh, retry, expire,
2993 if (result != ISC_R_SUCCESS)
2997 dns_db_detachnode(db, &node);
2999 dns_db_closeversion(db, &version, ISC_FALSE);
3005 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
3006 REQUIRE(DNS_ZONE_VALID(source));
3007 REQUIRE(target != NULL && *target == NULL);
3008 isc_refcount_increment(&source->erefs, NULL);
3013 dns_zone_detach(dns_zone_t **zonep) {
3016 isc_boolean_t free_now = ISC_FALSE;
3018 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3022 isc_refcount_decrement(&zone->erefs, &refs);
3027 * We just detached the last external reference.
3029 if (zone->task != NULL) {
3031 * This zone is being managed. Post
3032 * its control event and let it clean
3033 * up synchronously in the context of
3036 isc_event_t *ev = &zone->ctlevent;
3037 isc_task_send(zone->task, &ev);
3040 * This zone is not being managed; it has
3041 * no task and can have no outstanding
3042 * events. Free it immediately.
3045 * Unmanaged zones should not have non-null views;
3046 * we have no way of detaching from the view here
3047 * without causing deadlock because this code is called
3048 * with the view already locked.
3050 INSIST(zone->view == NULL);
3051 free_now = ISC_TRUE;
3061 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3062 REQUIRE(DNS_ZONE_VALID(source));
3063 REQUIRE(target != NULL && *target == NULL);
3065 zone_iattach(source, target);
3066 UNLOCK_ZONE(source);
3070 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3073 * 'source' locked by caller.
3075 REQUIRE(LOCKED_ZONE(source));
3076 REQUIRE(DNS_ZONE_VALID(source));
3077 REQUIRE(target != NULL && *target == NULL);
3078 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
3080 INSIST(source->irefs != 0);
3085 zone_idetach(dns_zone_t **zonep) {
3089 * 'zone' locked by caller.
3091 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3093 REQUIRE(LOCKED_ZONE(*zonep));
3096 INSIST(zone->irefs > 0);
3098 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
3102 dns_zone_idetach(dns_zone_t **zonep) {
3104 isc_boolean_t free_needed;
3106 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3111 INSIST(zone->irefs > 0);
3113 free_needed = exit_check(zone);
3120 dns_zone_getmctx(dns_zone_t *zone) {
3121 REQUIRE(DNS_ZONE_VALID(zone));
3123 return (zone->mctx);
3127 dns_zone_getmgr(dns_zone_t *zone) {
3128 REQUIRE(DNS_ZONE_VALID(zone));
3130 return (zone->zmgr);
3134 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
3135 REQUIRE(DNS_ZONE_VALID(zone));
3139 DNS_ZONE_SETFLAG(zone, flags);
3141 DNS_ZONE_CLRFLAG(zone, flags);
3146 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
3148 REQUIRE(DNS_ZONE_VALID(zone));
3152 zone->options |= option;
3154 zone->options &= ~option;
3159 dns_zone_getoptions(dns_zone_t *zone) {
3161 REQUIRE(DNS_ZONE_VALID(zone));
3163 return (zone->options);
3167 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3168 REQUIRE(DNS_ZONE_VALID(zone));
3171 zone->xfrsource4 = *xfrsource;
3174 return (ISC_R_SUCCESS);
3178 dns_zone_getxfrsource4(dns_zone_t *zone) {
3179 REQUIRE(DNS_ZONE_VALID(zone));
3180 return (&zone->xfrsource4);
3184 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3185 REQUIRE(DNS_ZONE_VALID(zone));
3188 zone->xfrsource6 = *xfrsource;
3191 return (ISC_R_SUCCESS);
3195 dns_zone_getxfrsource6(dns_zone_t *zone) {
3196 REQUIRE(DNS_ZONE_VALID(zone));
3197 return (&zone->xfrsource6);
3201 dns_zone_setaltxfrsource4(dns_zone_t *zone,
3202 const isc_sockaddr_t *altxfrsource)
3204 REQUIRE(DNS_ZONE_VALID(zone));
3207 zone->altxfrsource4 = *altxfrsource;
3210 return (ISC_R_SUCCESS);
3214 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
3215 REQUIRE(DNS_ZONE_VALID(zone));
3216 return (&zone->altxfrsource4);
3220 dns_zone_setaltxfrsource6(dns_zone_t *zone,
3221 const isc_sockaddr_t *altxfrsource)
3223 REQUIRE(DNS_ZONE_VALID(zone));
3226 zone->altxfrsource6 = *altxfrsource;
3229 return (ISC_R_SUCCESS);
3233 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
3234 REQUIRE(DNS_ZONE_VALID(zone));
3235 return (&zone->altxfrsource6);
3239 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3240 REQUIRE(DNS_ZONE_VALID(zone));
3243 zone->notifysrc4 = *notifysrc;
3246 return (ISC_R_SUCCESS);
3250 dns_zone_getnotifysrc4(dns_zone_t *zone) {
3251 REQUIRE(DNS_ZONE_VALID(zone));
3252 return (&zone->notifysrc4);
3256 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3257 REQUIRE(DNS_ZONE_VALID(zone));
3260 zone->notifysrc6 = *notifysrc;
3263 return (ISC_R_SUCCESS);
3267 dns_zone_getnotifysrc6(dns_zone_t *zone) {
3268 REQUIRE(DNS_ZONE_VALID(zone));
3269 return (&zone->notifysrc6);
3273 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
3276 isc_sockaddr_t *new;
3278 REQUIRE(DNS_ZONE_VALID(zone));
3279 REQUIRE(count == 0 || notify != NULL);
3282 if (zone->notify != NULL) {
3283 isc_mem_put(zone->mctx, zone->notify,
3284 zone->notifycnt * sizeof(*new));
3285 zone->notify = NULL;
3286 zone->notifycnt = 0;
3289 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3292 return (ISC_R_NOMEMORY);
3294 memcpy(new, notify, count * sizeof(*new));
3296 zone->notifycnt = count;
3299 return (ISC_R_SUCCESS);
3303 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
3306 isc_result_t result;
3308 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
3312 static isc_boolean_t
3313 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
3318 for (i = 0; i < count; i++)
3319 if (!isc_sockaddr_equal(&old[i], &new[i]))
3324 static isc_boolean_t
3325 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
3328 if (old == NULL && new == NULL)
3330 if (old == NULL || new == NULL)
3333 for (i = 0; i < count; i++) {
3334 if (old[i] == NULL && new[i] == NULL)
3336 if (old[i] == NULL || new[i] == NULL ||
3337 !dns_name_equal(old[i], new[i]))
3344 dns_zone_setmasterswithkeys(dns_zone_t *zone,
3345 const isc_sockaddr_t *masters,
3346 dns_name_t **keynames,
3349 isc_sockaddr_t *new;
3350 isc_result_t result = ISC_R_SUCCESS;
3351 dns_name_t **newname;
3352 isc_boolean_t *newok;
3355 REQUIRE(DNS_ZONE_VALID(zone));
3356 REQUIRE(count == 0 || masters != NULL);
3357 if (keynames != NULL) {
3358 REQUIRE(count != 0);
3363 * The refresh code assumes that 'masters' wouldn't change under it.
3364 * If it will change then kill off any current refresh in progress
3365 * and update the masters info. If it won't change then we can just
3368 if (count != zone->masterscnt ||
3369 !same_masters(zone->masters, masters, count) ||
3370 !same_keynames(zone->masterkeynames, keynames, count)) {
3371 if (zone->request != NULL)
3372 dns_request_cancel(zone->request);
3375 if (zone->masters != NULL) {
3376 isc_mem_put(zone->mctx, zone->masters,
3377 zone->masterscnt * sizeof(*new));
3378 zone->masters = NULL;
3380 if (zone->masterkeynames != NULL) {
3381 for (i = 0; i < zone->masterscnt; i++) {
3382 if (zone->masterkeynames[i] != NULL) {
3383 dns_name_free(zone->masterkeynames[i],
3385 isc_mem_put(zone->mctx,
3386 zone->masterkeynames[i],
3387 sizeof(dns_name_t));
3388 zone->masterkeynames[i] = NULL;
3391 isc_mem_put(zone->mctx, zone->masterkeynames,
3392 zone->masterscnt * sizeof(dns_name_t *));
3393 zone->masterkeynames = NULL;
3395 if (zone->mastersok != NULL) {
3396 isc_mem_put(zone->mctx, zone->mastersok,
3397 zone->masterscnt * sizeof(isc_boolean_t));
3398 zone->mastersok = NULL;
3400 zone->masterscnt = 0;
3402 * If count == 0, don't allocate any space for masters, mastersok or
3403 * keynames so internally, those pointers are NULL if count == 0
3409 * masters must contain count elements!
3411 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3413 result = ISC_R_NOMEMORY;
3416 memcpy(new, masters, count * sizeof(*new));
3419 * Similarly for mastersok.
3421 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
3422 if (newok == NULL) {
3423 result = ISC_R_NOMEMORY;
3424 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3427 for (i = 0; i < count; i++)
3428 newok[i] = ISC_FALSE;
3431 * if keynames is non-NULL, it must contain count elements!
3434 if (keynames != NULL) {
3435 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
3436 if (newname == NULL) {
3437 result = ISC_R_NOMEMORY;
3438 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3439 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
3442 for (i = 0; i < count; i++)
3444 for (i = 0; i < count; i++) {
3445 if (keynames[i] != NULL) {
3446 newname[i] = isc_mem_get(zone->mctx,
3447 sizeof(dns_name_t));
3448 if (newname[i] == NULL)
3450 dns_name_init(newname[i], NULL);
3451 result = dns_name_dup(keynames[i], zone->mctx,
3453 if (result != ISC_R_SUCCESS) {
3455 for (i = 0; i < count; i++)
3456 if (newname[i] != NULL)
3460 isc_mem_put(zone->mctx, new,
3461 count * sizeof(*new));
3462 isc_mem_put(zone->mctx, newok,
3463 count * sizeof(*newok));
3464 isc_mem_put(zone->mctx, newname,
3465 count * sizeof(*newname));
3473 * Everything is ok so attach to the zone.
3475 zone->masters = new;
3476 zone->mastersok = newok;
3477 zone->masterkeynames = newname;
3478 zone->masterscnt = count;
3479 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
3487 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
3488 isc_result_t result = ISC_R_SUCCESS;
3490 REQUIRE(DNS_ZONE_VALID(zone));
3492 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3493 if (zone->db == NULL)
3494 result = DNS_R_NOTLOADED;
3496 dns_db_attach(zone->db, dpb);
3497 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3503 * Co-ordinates the starting of routine jobs.
3507 dns_zone_maintenance(dns_zone_t *zone) {
3508 const char me[] = "dns_zone_maintenance";
3511 REQUIRE(DNS_ZONE_VALID(zone));
3516 zone_settimer(zone, &now);
3520 static inline isc_boolean_t
3521 was_dumping(dns_zone_t *zone) {
3522 isc_boolean_t dumping;
3524 REQUIRE(LOCKED_ZONE(zone));
3526 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
3527 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3529 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3530 isc_time_settoepoch(&zone->dumptime);
3535 #define MAXZONEKEYS 10
3538 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3541 dns_diff_t temp_diff;
3542 isc_result_t result;
3545 * Create a singleton diff.
3547 dns_diff_init(diff->mctx, &temp_diff);
3548 temp_diff.resign = diff->resign;
3549 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3552 * Apply it to the database.
3554 result = dns_diff_apply(&temp_diff, db, ver);
3555 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3556 if (result != ISC_R_SUCCESS) {
3557 dns_difftuple_free(tuple);
3562 * Merge it into the current pending journal entry.
3564 dns_diff_appendminimal(diff, tuple);
3567 * Do not clear temp_diff.
3569 return (ISC_R_SUCCESS);
3573 increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
3574 dns_diff_t *diff, isc_mem_t *mctx)
3576 dns_difftuple_t *deltuple = NULL;
3577 dns_difftuple_t *addtuple = NULL;
3578 isc_uint32_t serial;
3579 isc_result_t result;
3581 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3582 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3583 addtuple->op = DNS_DIFFOP_ADD;
3585 serial = dns_soa_getserial(&addtuple->rdata);
3588 serial = (serial + 1) & 0xFFFFFFFF;
3592 dns_soa_setserial(serial, &addtuple->rdata);
3593 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3594 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3595 result = ISC_R_SUCCESS;
3598 if (addtuple != NULL)
3599 dns_difftuple_free(&addtuple);
3600 if (deltuple != NULL)
3601 dns_difftuple_free(&deltuple);
3606 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3607 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3610 dns_difftuple_t *tuple = NULL;
3611 isc_result_t result;
3612 result = dns_difftuple_create(diff->mctx, op,
3613 name, ttl, rdata, &tuple);
3614 if (result != ISC_R_SUCCESS)
3616 return (do_one_tuple(&tuple, db, ver, diff));
3619 static isc_boolean_t
3620 ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) {
3621 isc_boolean_t ret = ISC_FALSE;
3622 isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE;
3623 isc_result_t result;
3624 dns_dbnode_t *node = NULL;
3625 dns_rdataset_t rdataset;
3626 dns_rdata_t rdata = DNS_RDATA_INIT;
3627 dns_rdata_dnskey_t dnskey;
3629 dns_rdataset_init(&rdataset);
3630 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3631 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
3633 CHECK(dns_rdataset_first(&rdataset));
3634 while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) {
3635 dns_rdataset_current(&rdataset, &rdata);
3636 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3637 if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
3638 == DNS_KEYOWNER_ZONE) {
3639 if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0)
3640 have_ksk = ISC_TRUE;
3642 have_nonksk = ISC_TRUE;
3644 dns_rdata_reset(&rdata);
3645 result = dns_rdataset_next(&rdataset);
3647 if (have_ksk && have_nonksk)
3650 if (dns_rdataset_isassociated(&rdataset))
3651 dns_rdataset_disassociate(&rdataset);
3653 dns_db_detachnode(db, &node);
3658 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3659 isc_mem_t *mctx, unsigned int maxkeys,
3660 dst_key_t **keys, unsigned int *nkeys)
3662 isc_result_t result;
3663 dns_dbnode_t *node = NULL;
3664 const char *directory = dns_zone_getkeydirectory(zone);
3666 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3667 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
3668 directory, mctx, maxkeys, keys,
3670 if (result == ISC_R_NOTFOUND)
3671 result = ISC_R_SUCCESS;
3674 dns_db_detachnode(db, &node);
3679 offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
3680 dns_ttl_t ttl, dns_rdata_t *rdata)
3682 isc_result_t result;
3684 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
3685 return (ISC_R_SUCCESS);
3686 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
3688 if (result != ISC_R_SUCCESS)
3690 rdata->flags |= DNS_RDATA_OFFLINE;
3691 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3697 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
3701 zone->key_expiry = when;
3703 dns_zone_log(zone, ISC_LOG_ERROR,
3704 "DNSKEY RRSIG(s) have expired");
3705 isc_time_settoepoch(&zone->keywarntime);
3706 } else if (when < now + 7 * 24 * 3600) {
3707 dns_zone_log(zone, ISC_LOG_WARNING,
3708 "DNSKEY RRSIG(s) will expire at %u",
3709 when); /* XXXMPA convert to date. */
3711 delta--; /* loop prevention */
3712 delta /= 24 * 3600; /* to whole days */
3713 delta *= 24 * 3600; /* to seconds */
3714 isc_time_set(&zone->keywarntime, when - delta, 0);
3716 dns_zone_log(zone, ISC_LOG_NOTICE, /* XXMPA ISC_LOG_DEBUG(1) */
3717 "setting keywarntime to %u - 7 days",
3718 when); /* XXXMPA convert to date. */
3719 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
3724 * Delete expired RRsigs and any RRsigs we are about to re-sign.
3725 * See also update.c:del_keysigs().
3728 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3729 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3730 unsigned int nkeys, isc_stdtime_t now)
3732 isc_result_t result;
3733 dns_dbnode_t *node = NULL;
3734 dns_rdataset_t rdataset;
3735 dns_rdata_t rdata = DNS_RDATA_INIT;
3737 dns_rdata_rrsig_t rrsig;
3738 isc_boolean_t found;
3739 isc_stdtime_t warn = 0, maybe = 0;
3741 dns_rdataset_init(&rdataset);
3743 if (type == dns_rdatatype_nsec3)
3744 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3746 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3747 if (result == ISC_R_NOTFOUND)
3748 return (ISC_R_SUCCESS);
3749 if (result != ISC_R_SUCCESS)
3751 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
3752 (isc_stdtime_t) 0, &rdataset, NULL);
3753 dns_db_detachnode(db, &node);
3755 if (result == ISC_R_NOTFOUND)
3756 return (ISC_R_SUCCESS);
3757 if (result != ISC_R_SUCCESS)
3760 for (result = dns_rdataset_first(&rdataset);
3761 result == ISC_R_SUCCESS;
3762 result = dns_rdataset_next(&rdataset)) {
3763 dns_rdataset_current(&rdataset, &rdata);
3764 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
3765 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3767 if (type != dns_rdatatype_dnskey) {
3768 result = update_one_rr(db, ver, diff,
3769 DNS_DIFFOP_DELRESIGN, name,
3770 rdataset.ttl, &rdata);
3771 dns_rdata_reset(&rdata);
3772 if (result != ISC_R_SUCCESS)
3778 * RRSIG(DNSKEY) requires special processing.
3781 for (i = 0; i < nkeys; i++) {
3782 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
3783 rrsig.keyid == dst_key_id(keys[i])) {
3786 * Mark offline RRSIG(DNSKEY).
3787 * We want the earliest offline expire time
3788 * iff there is a new offline signature.
3790 if (!dst_key_isprivate(keys[i])) {
3792 warn > rrsig.timeexpire)
3793 warn = rrsig.timeexpire;
3794 if (rdata.flags & DNS_RDATA_OFFLINE) {
3796 maybe > rrsig.timeexpire)
3804 warn > rrsig.timeexpire)
3805 warn = rrsig.timeexpire;
3806 result = offline(db, ver, diff, name,
3807 rdataset.ttl, &rdata);
3810 result = update_one_rr(db, ver, diff,
3811 DNS_DIFFOP_DELRESIGN,
3818 * If there is not a matching DNSKEY then
3822 result = update_one_rr(db, ver, diff,
3823 DNS_DIFFOP_DELRESIGN, name,
3824 rdataset.ttl, &rdata);
3825 dns_rdata_reset(&rdata);
3826 if (result != ISC_R_SUCCESS)
3829 dns_rdataset_disassociate(&rdataset);
3830 if (result == ISC_R_NOMORE)
3831 result = ISC_R_SUCCESS;
3833 set_key_expiry_warning(zone, warn, now);
3836 dns_db_detachnode(db, &node);
3841 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3842 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3843 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
3844 isc_stdtime_t expire, isc_boolean_t check_ksk)
3846 isc_result_t result;
3847 dns_dbnode_t *node = NULL;
3848 dns_rdataset_t rdataset;
3849 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
3850 unsigned char data[1024]; /* XXX */
3851 isc_buffer_t buffer;
3854 dns_rdataset_init(&rdataset);
3855 isc_buffer_init(&buffer, data, sizeof(data));
3857 if (type == dns_rdatatype_nsec3)
3858 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3860 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3861 if (result == ISC_R_NOTFOUND)
3862 return (ISC_R_SUCCESS);
3863 if (result != ISC_R_SUCCESS)
3865 result = dns_db_findrdataset(db, node, ver, type, 0,
3866 (isc_stdtime_t) 0, &rdataset, NULL);
3867 dns_db_detachnode(db, &node);
3868 if (result == ISC_R_NOTFOUND)
3869 return (ISC_R_SUCCESS);
3870 if (result != ISC_R_SUCCESS)
3873 for (i = 0; i < nkeys; i++) {
3874 if (check_ksk && type != dns_rdatatype_dnskey &&
3875 (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0)
3877 if (!dst_key_isprivate(keys[i]))
3879 /* Calculate the signature, creating a RRSIG RDATA. */
3880 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
3881 &inception, &expire,
3882 mctx, &buffer, &sig_rdata));
3883 /* Update the database and journal with the RRSIG. */
3884 /* XXX inefficient - will cause dataset merging */
3885 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3886 name, rdataset.ttl, &sig_rdata));
3887 dns_rdata_reset(&sig_rdata);
3888 isc_buffer_init(&buffer, data, sizeof(data));
3892 if (dns_rdataset_isassociated(&rdataset))
3893 dns_rdataset_disassociate(&rdataset);
3895 dns_db_detachnode(db, &node);
3900 zone_resigninc(dns_zone_t *zone) {
3901 const char *journalfile;
3902 dns_db_t *db = NULL;
3903 dns_dbversion_t *version = NULL;
3904 dns_diff_t sig_diff;
3905 dns_fixedname_t fixed;
3907 dns_rdataset_t rdataset;
3908 dns_rdatatype_t covers;
3909 dst_key_t *zone_keys[MAXZONEKEYS];
3910 isc_boolean_t check_ksk;
3911 isc_result_t result;
3912 isc_stdtime_t now, inception, soaexpire, expire, stop;
3913 isc_uint32_t jitter;
3915 unsigned int nkeys = 0;
3916 unsigned int resign;
3918 dns_rdataset_init(&rdataset);
3919 dns_fixedname_init(&fixed);
3920 dns_diff_init(zone->mctx, &sig_diff);
3921 sig_diff.resign = zone->sigresigninginterval;
3924 * Updates are disabled. Pause for 5 minutes.
3926 if (zone->update_disabled) {
3927 result = ISC_R_FAILURE;
3931 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3932 dns_db_attach(zone->db, &db);
3933 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3935 result = dns_db_newversion(db, &version);
3936 if (result != ISC_R_SUCCESS) {
3937 dns_zone_log(zone, ISC_LOG_ERROR,
3938 "zone_resigninc:dns_db_newversion -> %s\n",
3939 dns_result_totext(result));
3943 result = find_zone_keys(zone, db, version, zone->mctx, MAXZONEKEYS,
3945 if (result != ISC_R_SUCCESS) {
3946 dns_zone_log(zone, ISC_LOG_ERROR,
3947 "zone_resigninc:find_zone_keys -> %s\n",
3948 dns_result_totext(result));
3952 isc_stdtime_get(&now);
3953 inception = now - 3600; /* Allow for clock skew. */
3954 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
3956 * Spread out signatures over time if they happen to be
3957 * clumped. We don't do this for each add_sigs() call as
3958 * we still want some clustering to occur.
3960 isc_random_get(&jitter);
3961 expire = soaexpire - jitter % 3600;
3964 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
3966 check_ksk = ksk_sanity(db, version);
3968 name = dns_fixedname_name(&fixed);
3969 result = dns_db_getsigningtime(db, &rdataset, name);
3970 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
3971 dns_zone_log(zone, ISC_LOG_ERROR,
3972 "zone_resigninc:dns_db_getsigningtime -> %s\n",
3973 dns_result_totext(result));
3977 while (result == ISC_R_SUCCESS) {
3978 resign = rdataset.resign;
3979 covers = rdataset.covers;
3981 * Stop if we hit the SOA as that means we have walked the
3982 * entire zone. The SOA record should always be the most
3985 /* XXXMPA increase number of RRsets signed pre call */
3986 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
3989 * Ensure that we don't loop resigning the SOA.
3991 if (covers == dns_rdatatype_soa)
3992 dns_db_resigned(db, &rdataset, version);
3993 dns_rdataset_disassociate(&rdataset);
3997 dns_db_resigned(db, &rdataset, version);
3998 dns_rdataset_disassociate(&rdataset);
4000 result = del_sigs(zone, db, version, name, covers, &sig_diff,
4001 zone_keys, nkeys, now);
4002 if (result != ISC_R_SUCCESS) {
4003 dns_zone_log(zone, ISC_LOG_ERROR,
4004 "zone_resigninc:del_sigs -> %s\n",
4005 dns_result_totext(result));
4008 result = add_sigs(db, version, name, covers, &sig_diff,
4009 zone_keys, nkeys, zone->mctx, inception,
4011 if (result != ISC_R_SUCCESS) {
4012 dns_zone_log(zone, ISC_LOG_ERROR,
4013 "zone_resigninc:add_sigs -> %s\n",
4014 dns_result_totext(result));
4017 result = dns_db_getsigningtime(db, &rdataset,
4018 dns_fixedname_name(&fixed));
4019 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
4020 result = ISC_R_SUCCESS;
4023 if (result != ISC_R_SUCCESS)
4024 dns_zone_log(zone, ISC_LOG_ERROR,
4025 "zone_resigninc:dns_db_getsigningtime -> %s\n",
4026 dns_result_totext(result));
4029 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
4032 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
4033 &sig_diff, zone_keys, nkeys, now);
4034 if (result != ISC_R_SUCCESS) {
4035 dns_zone_log(zone, ISC_LOG_ERROR,
4036 "zone_resigninc:del_sigs -> %s\n",
4037 dns_result_totext(result));
4041 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
4042 if (result != ISC_R_SUCCESS) {
4043 dns_zone_log(zone, ISC_LOG_ERROR,
4044 "zone_resigninc:increment_soa_serial -> %s\n",
4045 dns_result_totext(result));
4050 * Generate maximum life time signatures so that the above loop
4051 * termination is sensible.
4053 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
4054 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
4055 soaexpire, check_ksk);
4056 if (result != ISC_R_SUCCESS) {
4057 dns_zone_log(zone, ISC_LOG_ERROR,
4058 "zone_resigninc:add_sigs -> %s\n",
4059 dns_result_totext(result));
4063 journalfile = dns_zone_getjournal(zone);
4064 if (journalfile != NULL) {
4065 dns_journal_t *journal = NULL;
4066 result = dns_journal_open(zone->mctx, journalfile,
4067 ISC_TRUE, &journal);
4068 if (result != ISC_R_SUCCESS) {
4069 dns_zone_log(zone, ISC_LOG_ERROR,
4070 "zone_resigninc:dns_journal_open -> %s\n",
4071 dns_result_totext(result));
4075 result = dns_journal_write_transaction(journal, &sig_diff);
4076 dns_journal_destroy(&journal);
4077 if (result != ISC_R_SUCCESS) {
4078 dns_zone_log(zone, ISC_LOG_ERROR,
4079 "zone_resigninc:dns_journal_write_transaction -> %s\n",
4080 dns_result_totext(result));
4086 * Everything has succeeded. Commit the changes.
4088 dns_db_closeversion(db, &version, ISC_TRUE);
4091 dns_diff_clear(&sig_diff);
4092 for (i = 0; i < nkeys; i++)
4093 dst_key_free(&zone_keys[i]);
4094 if (version != NULL) {
4095 dns_db_closeversion(zone->db, &version, ISC_FALSE);
4097 } else if (db != NULL)
4099 if (result == ISC_R_SUCCESS) {
4100 set_resigntime(zone);
4102 zone_needdump(zone, DNS_DUMP_DELAY);
4103 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
4107 * Something failed. Retry in 5 minutes.
4109 isc_interval_t ival;
4110 isc_interval_set(&ival, 300, 0);
4111 isc_time_nowplusinterval(&zone->resigntime, &ival);
4116 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
4117 dns_name_t *newname, isc_boolean_t bottom)
4119 isc_result_t result;
4120 dns_dbiterator_t *dbit = NULL;
4121 dns_rdatasetiter_t *rdsit = NULL;
4122 dns_dbnode_t *node = NULL;
4124 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
4125 CHECK(dns_dbiterator_seek(dbit, oldname));
4127 result = dns_dbiterator_next(dbit);
4128 if (result == ISC_R_NOMORE)
4129 CHECK(dns_dbiterator_first(dbit));
4130 CHECK(dns_dbiterator_current(dbit, &node, newname));
4131 if (bottom && dns_name_issubdomain(newname, oldname) &&
4132 !dns_name_equal(newname, oldname)) {
4133 dns_db_detachnode(db, &node);
4137 * Is this node empty?
4139 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
4140 result = dns_rdatasetiter_first(rdsit);
4141 dns_db_detachnode(db, &node);
4142 dns_rdatasetiter_destroy(&rdsit);
4143 if (result != ISC_R_NOMORE)
4148 dns_db_detachnode(db, &node);
4150 dns_dbiterator_destroy(&dbit);
4155 set_bit(unsigned char *array, unsigned int index) {
4156 unsigned int shift, mask;
4158 shift = 7 - (index % 8);
4161 array[index / 8] |= mask;
4164 static isc_boolean_t
4165 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4166 dns_rdatatype_t type, dst_key_t *key)
4168 isc_result_t result;
4169 dns_rdataset_t rdataset;
4170 dns_rdata_t rdata = DNS_RDATA_INIT;
4171 dns_rdata_rrsig_t rrsig;
4173 dns_rdataset_init(&rdataset);
4174 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
4175 type, 0, &rdataset, NULL);
4176 if (result != ISC_R_SUCCESS)
4178 for (result = dns_rdataset_first(&rdataset);
4179 result == ISC_R_SUCCESS;
4180 result = dns_rdataset_next(&rdataset)) {
4181 dns_rdataset_current(&rdataset, &rdata);
4182 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
4183 INSIST(result == ISC_R_SUCCESS);
4184 if (rrsig.algorithm == dst_key_alg(key) &&
4185 rrsig.keyid == dst_key_id(key)) {
4186 dns_rdataset_disassociate(&rdataset);
4189 dns_rdata_reset(&rdata);
4191 dns_rdataset_disassociate(&rdataset);
4196 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4197 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
4200 dns_fixedname_t fixed;
4202 dns_rdata_t rdata = DNS_RDATA_INIT;
4203 isc_result_t result;
4204 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4206 dns_fixedname_init(&fixed);
4207 next = dns_fixedname_name(&fixed);
4209 CHECK(next_active(db, version, name, next, bottom));
4210 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
4212 if (dns_name_equal(dns_db_origin(db), name)) {
4214 * Set the OPT bit to indicate that this is a
4215 * partially secure zone.
4217 isc_region_t region;
4219 dns_rdata_toregion(&rdata, ®ion);
4220 dns_name_fromregion(next, ®ion);
4221 isc_region_consume(®ion, next->length);
4222 INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
4223 region.base[0] == 0 &&
4224 region.base[1] > dns_rdatatype_opt / 8);
4225 set_bit(region.base + 2, dns_rdatatype_opt);
4227 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
4234 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
4235 dns_dbversion_t *version, isc_boolean_t build_nsec3,
4236 isc_boolean_t build_nsec, dst_key_t *key,
4237 isc_stdtime_t inception, isc_stdtime_t expire,
4238 unsigned int minimum, isc_boolean_t is_ksk,
4239 isc_boolean_t *delegation, dns_diff_t *diff,
4240 isc_int32_t *signatures, isc_mem_t *mctx)
4242 isc_result_t result;
4243 dns_rdatasetiter_t *iterator = NULL;
4244 dns_rdataset_t rdataset;
4245 dns_rdata_t rdata = DNS_RDATA_INIT;
4246 isc_buffer_t buffer;
4247 unsigned char data[1024];
4248 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
4249 seen_nsec3, seen_ds;
4250 isc_boolean_t bottom;
4252 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4253 if (result != ISC_R_SUCCESS) {
4254 if (result == ISC_R_NOTFOUND)
4255 result = ISC_R_SUCCESS;
4258 dns_rdataset_init(&rdataset);
4259 isc_buffer_init(&buffer, data, sizeof(data));
4260 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
4261 seen_nsec3 = seen_ds = ISC_FALSE;
4262 for (result = dns_rdatasetiter_first(iterator);
4263 result == ISC_R_SUCCESS;
4264 result = dns_rdatasetiter_next(iterator)) {
4265 dns_rdatasetiter_current(iterator, &rdataset);
4266 if (rdataset.type == dns_rdatatype_soa)
4267 seen_soa = ISC_TRUE;
4268 else if (rdataset.type == dns_rdatatype_ns)
4270 else if (rdataset.type == dns_rdatatype_ds)
4272 else if (rdataset.type == dns_rdatatype_dname)
4273 seen_dname = ISC_TRUE;
4274 else if (rdataset.type == dns_rdatatype_nsec)
4275 seen_nsec = ISC_TRUE;
4276 else if (rdataset.type == dns_rdatatype_nsec3)
4277 seen_nsec3 = ISC_TRUE;
4279 dns_rdataset_disassociate(&rdataset);
4281 if (result != ISC_R_NOMORE)
4283 if (seen_ns && !seen_soa)
4284 *delegation = ISC_TRUE;
4286 * Going from insecure to NSEC3.
4287 * Don't generate NSEC3 records for NSEC3 records.
4289 if (build_nsec3 && !seen_nsec3 && seen_rr) {
4290 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
4291 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
4296 * Going from insecure to NSEC.
4297 * Don't generate NSEC records for NSEC3 records.
4299 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
4300 /* Build and add NSEC. */
4301 bottom = (seen_ns && !seen_soa) || seen_dname;
4302 CHECK(add_nsec(db, version, name, node, minimum, bottom, diff));
4303 /* Count a NSEC generation as a signature generation. */
4306 result = dns_rdatasetiter_first(iterator);
4307 while (result == ISC_R_SUCCESS) {
4308 dns_rdatasetiter_current(iterator, &rdataset);
4309 if (rdataset.type == dns_rdatatype_soa ||
4310 rdataset.type == dns_rdatatype_rrsig)
4312 if (is_ksk && rdataset.type != dns_rdatatype_dnskey)
4315 rdataset.type != dns_rdatatype_ds &&
4316 rdataset.type != dns_rdatatype_nsec)
4318 if (signed_with_key(db, node, version, rdataset.type, key))
4320 /* Calculate the signature, creating a RRSIG RDATA. */
4321 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
4322 &expire, mctx, &buffer, &rdata));
4323 /* Update the database and journal with the RRSIG. */
4324 /* XXX inefficient - will cause dataset merging */
4325 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
4326 name, rdataset.ttl, &rdata));
4327 dns_rdata_reset(&rdata);
4330 dns_rdataset_disassociate(&rdataset);
4331 result = dns_rdatasetiter_next(iterator);
4333 if (result == ISC_R_NOMORE)
4334 result = ISC_R_SUCCESS;
4336 *delegation = ISC_TRUE;
4338 if (dns_rdataset_isassociated(&rdataset))
4339 dns_rdataset_disassociate(&rdataset);
4340 if (iterator != NULL)
4341 dns_rdatasetiter_destroy(&iterator);
4346 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4347 dns_ttl_t minimum, isc_boolean_t *secureupdated, dns_diff_t *diff)
4349 isc_result_t result;
4350 dns_rdata_t rdata = DNS_RDATA_INIT;
4351 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4352 dns_rdataset_t rdataset;
4353 dns_rdata_nsec_t nsec;
4354 dns_dbnode_t *node = NULL;
4357 * Check to see if the OPT bit has already been cleared.
4359 CHECK(dns_db_getoriginnode(db, &node));
4360 dns_rdataset_init(&rdataset);
4361 CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
4362 dns_rdatatype_none, 0, &rdataset, NULL));
4363 CHECK(dns_rdataset_first(&rdataset));
4364 dns_rdataset_current(&rdataset, &rdata);
4367 * Find the NEXT name for building the new record.
4369 CHECK(dns_rdata_tostruct(&rdata, &nsec, NULL));
4372 * Delete the old NSEC record.
4374 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_DEL, name, minimum,
4376 dns_rdata_reset(&rdata);
4379 * Add the new NSEC record.
4381 CHECK(dns_nsec_buildrdata(db, version, node, &nsec.next, nsecbuffer,
4383 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, minimum,
4385 dns_rdata_reset(&rdata);
4387 if (secureupdated != NULL)
4388 *secureupdated = ISC_TRUE;
4392 dns_db_detachnode(db, &node);
4393 if (dns_rdataset_isassociated(&rdataset))
4394 dns_rdataset_disassociate(&rdataset);
4399 updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
4400 dns_name_t *name, dns_rdatatype_t privatetype,
4403 isc_result_t result;
4404 dns_dbnode_t *node = NULL;
4405 dns_rdataset_t rdataset;
4406 dns_rdata_t rdata = DNS_RDATA_INIT;
4407 unsigned char data[5];
4408 isc_boolean_t seen_done = ISC_FALSE;
4410 dns_rdataset_init(&rdataset);
4411 result = dns_db_getoriginnode(signing->db, &node);
4412 if (result != ISC_R_SUCCESS)
4415 result = dns_db_findrdataset(signing->db, node, version, privatetype,
4416 dns_rdatatype_none, 0, &rdataset, NULL);
4417 if (result == ISC_R_NOTFOUND) {
4418 result = ISC_R_SUCCESS;
4421 if (result != ISC_R_SUCCESS)
4423 for (result = dns_rdataset_first(&rdataset);
4424 result == ISC_R_SUCCESS;
4425 result = dns_rdataset_next(&rdataset)) {
4426 dns_rdataset_current(&rdataset, &rdata);
4427 if (rdata.length != 5 ||
4428 rdata.data[0] != signing->algorithm ||
4429 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
4430 rdata.data[2] != (signing->keyid & 0xff)) {
4431 dns_rdata_reset(&rdata);
4434 if (!signing->delete && rdata.data[4] != 0)
4435 seen_done = ISC_TRUE;
4437 CHECK(update_one_rr(signing->db, version, diff,
4438 DNS_DIFFOP_DEL, name,
4439 rdataset.ttl, &rdata));
4440 dns_rdata_reset(&rdata);
4442 if (result == ISC_R_NOMORE)
4443 result = ISC_R_SUCCESS;
4444 if (!signing->delete && !seen_done) {
4446 data[0] = signing->algorithm;
4447 data[1] = (signing->keyid >> 8) & 0xff;
4448 data[2] = signing->keyid & 0xff;
4451 rdata.length = sizeof(data);
4453 rdata.type = privatetype;
4454 rdata.rdclass = dns_db_class(signing->db);
4455 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
4456 name, rdataset.ttl, &rdata));
4459 if (dns_rdataset_isassociated(&rdataset))
4460 dns_rdataset_disassociate(&rdataset);
4462 dns_db_detachnode(signing->db, &node);
4467 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
4468 isc_boolean_t active, dns_diff_t *diff)
4470 dns_dbnode_t *node = NULL;
4471 dns_name_t *name = dns_db_origin(db);
4472 dns_rdata_t rdata = DNS_RDATA_INIT;
4473 dns_rdataset_t rdataset;
4474 dns_rdata_nsec3param_t nsec3param;
4475 isc_result_t result;
4476 isc_buffer_t buffer;
4477 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
4480 dns_rdataset_init(&rdataset);
4482 result = dns_db_getoriginnode(db, &node);
4483 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4484 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4485 0, 0, &rdataset, NULL);
4486 if (result == ISC_R_NOTFOUND)
4488 if (result != ISC_R_SUCCESS)
4492 * Preserve the existing ttl.
4497 * Delete all NSEC3PARAM records which match that in nsec3chain.
4499 for (result = dns_rdataset_first(&rdataset);
4500 result == ISC_R_SUCCESS;
4501 result = dns_rdataset_next(&rdataset)) {
4503 dns_rdataset_current(&rdataset, &rdata);
4504 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
4506 if (nsec3param.hash != chain->nsec3param.hash ||
4507 (active && nsec3param.flags != 0) ||
4508 nsec3param.iterations != chain->nsec3param.iterations ||
4509 nsec3param.salt_length != chain->nsec3param.salt_length ||
4510 memcmp(nsec3param.salt, chain->nsec3param.salt,
4511 nsec3param.salt_length)) {
4512 dns_rdata_reset(&rdata);
4516 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
4517 name, rdataset.ttl, &rdata));
4518 dns_rdata_reset(&rdata);
4520 if (result != ISC_R_NOMORE)
4524 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
4525 result = ISC_R_SUCCESS;
4530 * Add a NSEC3PARAM record which matches that in nsec3chain but
4531 * with all flags bits cleared.
4533 * Note: we do not clear chain->nsec3param.flags as this change
4536 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
4537 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
4538 dns_rdatatype_nsec3param,
4539 &chain->nsec3param, &buffer));
4540 rdata.data[1] = 0; /* Clear flag bits. */
4541 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
4544 dns_db_detachnode(db, &node);
4545 if (dns_rdataset_isassociated(&rdataset))
4546 dns_rdataset_disassociate(&rdataset);
4551 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4552 dns_name_t *name, dns_diff_t *diff)
4554 dns_rdataset_t rdataset;
4555 isc_result_t result;
4557 dns_rdataset_init(&rdataset);
4559 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4560 0, 0, &rdataset, NULL);
4561 if (result == ISC_R_NOTFOUND)
4562 return (ISC_R_SUCCESS);
4563 if (result != ISC_R_SUCCESS)
4565 for (result = dns_rdataset_first(&rdataset);
4566 result == ISC_R_SUCCESS;
4567 result = dns_rdataset_next(&rdataset)) {
4568 dns_rdata_t rdata = DNS_RDATA_INIT;
4570 dns_rdataset_current(&rdataset, &rdata);
4571 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4572 rdataset.ttl, &rdata));
4574 if (result == ISC_R_NOMORE)
4575 result = ISC_R_SUCCESS;
4577 dns_rdataset_disassociate(&rdataset);
4582 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4583 dns_name_t *name, const dns_rdata_nsec3param_t *param,
4586 dns_rdataset_t rdataset;
4587 dns_rdata_nsec3_t nsec3;
4588 isc_result_t result;
4590 dns_rdataset_init(&rdataset);
4591 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
4592 0, 0, &rdataset, NULL);
4593 if (result == ISC_R_NOTFOUND)
4594 return (ISC_R_SUCCESS);
4595 if (result != ISC_R_SUCCESS)
4598 for (result = dns_rdataset_first(&rdataset);
4599 result == ISC_R_SUCCESS;
4600 result = dns_rdataset_next(&rdataset)) {
4601 dns_rdata_t rdata = DNS_RDATA_INIT;
4603 dns_rdataset_current(&rdataset, &rdata);
4604 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
4605 if (nsec3.hash != param->hash ||
4606 nsec3.iterations != param->iterations ||
4607 nsec3.salt_length != param->salt_length ||
4608 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
4610 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4611 rdataset.ttl, &rdata));
4613 if (result == ISC_R_NOMORE)
4614 result = ISC_R_SUCCESS;
4616 dns_rdataset_disassociate(&rdataset);
4621 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
4622 const dns_rdata_nsec3param_t *param,
4623 isc_boolean_t *answer, isc_boolean_t *updatensec)
4625 dns_dbnode_t *node = NULL;
4626 dns_rdata_t rdata = DNS_RDATA_INIT;
4627 dns_rdata_nsec3param_t myparam;
4628 dns_rdataset_t rdataset;
4629 isc_result_t result;
4631 *answer = ISC_FALSE;
4633 result = dns_db_getoriginnode(db, &node);
4634 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4636 dns_rdataset_init(&rdataset);
4637 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4638 0, 0, &rdataset, NULL);
4639 if (result == ISC_R_NOTFOUND)
4640 goto check_nsec3param;
4642 if (result != ISC_R_SUCCESS)
4645 CHECK(dns_rdataset_first(&rdataset));
4646 dns_rdataset_current(&rdataset, &rdata);
4648 if (!dns_nsec_typepresent(&rdata, dns_rdatatype_opt)) {
4650 * We have a complete NSEC chain. Signal to update
4651 * the apex NSEC record.
4653 *updatensec = ISC_TRUE;
4656 dns_rdataset_disassociate(&rdataset);
4657 dns_rdata_reset(&rdata);
4660 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4661 0, 0, &rdataset, NULL);
4662 if (result == ISC_R_NOTFOUND) {
4664 dns_db_detachnode(db, &node);
4665 return (ISC_R_SUCCESS);
4667 if (result != ISC_R_SUCCESS) {
4668 dns_db_detachnode(db, &node);
4672 for (result = dns_rdataset_first(&rdataset);
4673 result == ISC_R_SUCCESS;
4674 result = dns_rdataset_next(&rdataset)) {
4675 dns_rdataset_current(&rdataset, &rdata);
4676 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
4677 dns_rdata_reset(&rdata);
4679 * Ignore any NSEC3PARAM removals.
4681 if (NSEC3REMOVE(myparam.flags))
4684 * Ignore the chain that we are in the process of deleting.
4686 if (myparam.hash == param->hash &&
4687 myparam.iterations == param->iterations &&
4688 myparam.salt_length == param->salt_length &&
4689 !memcmp(myparam.salt, param->salt, myparam.salt_length))
4692 * Found an active NSEC3 chain.
4696 if (result == ISC_R_NOMORE) {
4698 result = ISC_R_SUCCESS;
4702 if (dns_rdataset_isassociated(&rdataset))
4703 dns_rdataset_disassociate(&rdataset);
4704 dns_db_detachnode(db, &node);
4709 * Incrementally build and sign a new NSEC3 chain using the parameters
4713 zone_nsec3chain(dns_zone_t *zone) {
4714 const char *journalfile;
4715 dns_db_t *db = NULL;
4716 dns_dbnode_t *node = NULL;
4717 dns_dbversion_t *version = NULL;
4718 dns_diff_t sig_diff;
4719 dns_diff_t nsec_diff;
4720 dns_diff_t nsec3_diff;
4721 dns_diff_t param_diff;
4722 dns_fixedname_t fixed;
4723 dns_fixedname_t nextfixed;
4724 dns_name_t *name, *nextname;
4725 dns_rdataset_t rdataset;
4726 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
4727 dns_nsec3chainlist_t cleanup;
4728 dst_key_t *zone_keys[MAXZONEKEYS];
4729 isc_int32_t signatures;
4730 isc_boolean_t check_ksk, is_ksk;
4731 isc_boolean_t delegation;
4732 isc_boolean_t first;
4733 isc_result_t result;
4734 isc_stdtime_t now, inception, soaexpire, expire, stop;
4735 isc_uint32_t jitter;
4737 unsigned int nkeys = 0;
4739 isc_boolean_t unsecure = ISC_FALSE;
4740 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
4741 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
4742 dns_rdatasetiter_t *iterator = NULL;
4743 dns_difftuple_t *tuple;
4744 isc_boolean_t buildnsecchain;
4745 isc_boolean_t updatensec = ISC_FALSE;
4747 dns_rdataset_init(&rdataset);
4748 dns_fixedname_init(&fixed);
4749 name = dns_fixedname_name(&fixed);
4750 dns_fixedname_init(&nextfixed);
4751 nextname = dns_fixedname_name(&nextfixed);
4752 dns_diff_init(zone->mctx, ¶m_diff);
4753 dns_diff_init(zone->mctx, &nsec3_diff);
4754 dns_diff_init(zone->mctx, &nsec_diff);
4755 dns_diff_init(zone->mctx, &sig_diff);
4756 sig_diff.resign = zone->sigresigninginterval;
4757 ISC_LIST_INIT(cleanup);
4760 * Updates are disabled. Pause for 5 minutes.
4762 if (zone->update_disabled) {
4763 result = ISC_R_FAILURE;
4767 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4768 dns_db_attach(zone->db, &db);
4769 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4771 result = dns_db_newversion(db, &version);
4772 if (result != ISC_R_SUCCESS) {
4773 dns_zone_log(zone, ISC_LOG_ERROR,
4774 "zone_nsec3chain:dns_db_newversion -> %s\n",
4775 dns_result_totext(result));
4779 result = find_zone_keys(zone, db, version, zone->mctx,
4780 MAXZONEKEYS, zone_keys, &nkeys);
4781 if (result != ISC_R_SUCCESS) {
4782 dns_zone_log(zone, ISC_LOG_ERROR,
4783 "zone_nsec3chain:find_zone_keys -> %s\n",
4784 dns_result_totext(result));
4788 isc_stdtime_get(&now);
4789 inception = now - 3600; /* Allow for clock skew. */
4790 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
4793 * Spread out signatures over time if they happen to be
4794 * clumped. We don't do this for each add_sigs() call as
4795 * we still want some clustering to occur.
4797 isc_random_get(&jitter);
4798 expire = soaexpire - jitter % 3600;
4801 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
4803 check_ksk = ksk_sanity(db, version);
4806 * We keep pulling nodes off each iterator in turn until
4807 * we have no more nodes to pull off or we reach the limits
4810 nodes = zone->nodes;
4811 signatures = zone->signatures;
4813 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
4817 if (nsec3chain != NULL)
4818 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
4820 * Generate new NSEC3 chains first.
4822 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
4824 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
4826 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4827 if (nsec3chain->done || nsec3chain->db != zone->db) {
4828 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
4829 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4831 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4833 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
4837 * Possible future db.
4839 if (nsec3chain->db != db) {
4843 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
4847 delegation = ISC_FALSE;
4848 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
4850 if (nsec3chain->delete_nsec) {
4851 delegation = ISC_FALSE;
4852 dns_dbiterator_pause(nsec3chain->dbiterator);
4853 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
4857 * On the first pass we need to check if the current node
4858 * has not been obscured.
4860 delegation = ISC_FALSE;
4861 unsecure = ISC_FALSE;
4863 dns_fixedname_t ffound;
4865 dns_fixedname_init(&ffound);
4866 found = dns_fixedname_name(&ffound);
4867 result = dns_db_find(db, name, version,
4869 DNS_DBFIND_NOWILD, 0, NULL, found,
4871 if ((result == DNS_R_DELEGATION ||
4872 result == DNS_R_DNAME) &&
4873 !dns_name_equal(name, found)) {
4875 * Remember the obscuring name so that
4876 * we skip all obscured names.
4878 dns_name_copy(found, name, NULL);
4879 delegation = ISC_TRUE;
4885 * Check to see if this is a bottom of zone node.
4887 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4888 if (result == ISC_R_NOTFOUND) /* Empty node? */
4890 if (result != ISC_R_SUCCESS)
4893 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
4895 for (result = dns_rdatasetiter_first(iterator);
4896 result == ISC_R_SUCCESS;
4897 result = dns_rdatasetiter_next(iterator)) {
4898 dns_rdatasetiter_current(iterator, &rdataset);
4899 INSIST(rdataset.type != dns_rdatatype_nsec3);
4900 if (rdataset.type == dns_rdatatype_soa)
4901 seen_soa = ISC_TRUE;
4902 else if (rdataset.type == dns_rdatatype_ns)
4904 else if (rdataset.type == dns_rdatatype_dname)
4905 seen_dname = ISC_TRUE;
4906 else if (rdataset.type == dns_rdatatype_ds)
4908 else if (rdataset.type == dns_rdatatype_nsec)
4909 seen_nsec = ISC_TRUE;
4910 dns_rdataset_disassociate(&rdataset);
4912 dns_rdatasetiter_destroy(&iterator);
4914 * Is there a NSEC chain than needs to be cleaned up?
4917 nsec3chain->seen_nsec = ISC_TRUE;
4918 if (seen_ns && !seen_soa && !seen_ds)
4919 unsecure = ISC_TRUE;
4920 if ((seen_ns && !seen_soa) || seen_dname)
4921 delegation = ISC_TRUE;
4926 dns_dbiterator_pause(nsec3chain->dbiterator);
4927 CHECK(dns_nsec3_addnsec3(db, version, name,
4928 &nsec3chain->nsec3param,
4929 zone->minimum, unsecure, &nsec3_diff));
4931 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
4932 * two signatures. Additionally there will, in general, be
4933 * two signature generated below.
4935 * If we are only changing the optout flag the cost is half
4936 * that of the cost of generating a completely new chain.
4941 * Go onto next node.
4945 dns_db_detachnode(db, &node);
4947 result = dns_dbiterator_next(nsec3chain->dbiterator);
4949 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
4950 CHECK(fixup_nsec3param(db, version, nsec3chain,
4951 ISC_FALSE, ¶m_diff));
4953 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4956 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4959 if (result == ISC_R_NOMORE) {
4960 dns_dbiterator_pause(nsec3chain->dbiterator);
4961 if (nsec3chain->seen_nsec) {
4962 CHECK(fixup_nsec3param(db, version,
4966 nsec3chain->delete_nsec = ISC_TRUE;
4969 CHECK(fixup_nsec3param(db, version, nsec3chain,
4970 ISC_FALSE, ¶m_diff));
4972 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4975 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4977 } else if (result != ISC_R_SUCCESS) {
4978 dns_zone_log(zone, ISC_LOG_ERROR,
4980 "dns_dbiterator_next -> %s\n",
4981 dns_result_totext(result));
4983 } else if (delegation) {
4984 dns_dbiterator_current(nsec3chain->dbiterator,
4986 dns_db_detachnode(db, &node);
4987 if (!dns_name_issubdomain(nextname, name))
4995 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
5000 dns_dbiterator_pause(nsec3chain->dbiterator);
5001 nsec3chain = nextnsec3chain;
5003 if (nsec3chain != NULL)
5004 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
5011 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5014 buildnsecchain = ISC_FALSE;
5015 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
5017 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
5020 if (nsec3chain->db != db)
5021 goto next_removechain;
5023 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
5024 goto next_removechain;
5027 * Work out if we need to build a NSEC chain as a consequence
5028 * of removing this NSEC3 chain.
5030 if (first && !updatensec &&
5031 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
5032 CHECK(need_nsec_chain(db, version,
5033 &nsec3chain->nsec3param,
5034 &buildnsecchain, &updatensec));
5036 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
5037 delegation = ISC_FALSE;
5039 if (!buildnsecchain) {
5041 * Delete the NSECPARAM record that matches this chain.
5044 CHECK(fixup_nsec3param(db, version, nsec3chain,
5045 ISC_TRUE, ¶m_diff));
5048 * Delete the NSEC3 records.
5050 CHECK(deletematchingnsec3(db, version, node, name,
5051 &nsec3chain->nsec3param,
5053 goto next_removenode;
5057 dns_fixedname_t ffound;
5059 dns_fixedname_init(&ffound);
5060 found = dns_fixedname_name(&ffound);
5061 result = dns_db_find(db, name, version,
5063 DNS_DBFIND_NOWILD, 0, NULL, found,
5065 if ((result == DNS_R_DELEGATION ||
5066 result == DNS_R_DNAME) &&
5067 !dns_name_equal(name, found)) {
5069 * Remember the obscuring name so that
5070 * we skip all obscured names.
5072 dns_name_copy(found, name, NULL);
5073 delegation = ISC_TRUE;
5074 goto next_removenode;
5079 * Check to see if this is a bottom of zone node.
5081 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5082 if (result == ISC_R_NOTFOUND) /* Empty node? */
5083 goto next_removenode;
5084 if (result != ISC_R_SUCCESS)
5087 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
5088 seen_rr = ISC_FALSE;
5089 for (result = dns_rdatasetiter_first(iterator);
5090 result == ISC_R_SUCCESS;
5091 result = dns_rdatasetiter_next(iterator)) {
5092 dns_rdatasetiter_current(iterator, &rdataset);
5093 if (rdataset.type == dns_rdatatype_soa)
5094 seen_soa = ISC_TRUE;
5095 else if (rdataset.type == dns_rdatatype_ns)
5097 else if (rdataset.type == dns_rdatatype_dname)
5098 seen_dname = ISC_TRUE;
5099 else if (rdataset.type == dns_rdatatype_nsec)
5100 seen_nsec = ISC_TRUE;
5101 else if (rdataset.type == dns_rdatatype_nsec3)
5102 seen_nsec3 = ISC_TRUE;
5104 dns_rdataset_disassociate(&rdataset);
5106 dns_rdatasetiter_destroy(&iterator);
5108 if (!seen_rr || seen_nsec3 || seen_nsec)
5109 goto next_removenode;
5110 if ((seen_ns && !seen_soa) || seen_dname)
5111 delegation = ISC_TRUE;
5113 CHECK(add_nsec(db, version, name, node, zone->minimum,
5114 delegation, &nsec_diff));
5118 dns_db_detachnode(db, &node);
5120 result = dns_dbiterator_next(nsec3chain->dbiterator);
5121 if (result == ISC_R_NOMORE && buildnsecchain) {
5123 * The NSEC chain should now be built.
5124 * We can now remove the NSEC3 chain.
5126 updatensec = ISC_TRUE;
5127 goto same_removechain;
5129 if (result == ISC_R_NOMORE) {
5131 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
5134 ISC_LIST_APPEND(cleanup, nsec3chain, link);
5135 dns_dbiterator_pause(nsec3chain->dbiterator);
5136 CHECK(fixup_nsec3param(db, version, nsec3chain,
5137 ISC_FALSE, ¶m_diff));
5138 goto next_removechain;
5139 } else if (result != ISC_R_SUCCESS) {
5140 dns_zone_log(zone, ISC_LOG_ERROR,
5142 "dns_dbiterator_next -> %s\n",
5143 dns_result_totext(result));
5145 } else if (delegation) {
5146 dns_dbiterator_current(nsec3chain->dbiterator,
5148 dns_db_detachnode(db, &node);
5149 if (!dns_name_issubdomain(nextname, name))
5157 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
5158 buildnsecchain = ISC_FALSE;
5163 dns_dbiterator_pause(nsec3chain->dbiterator);
5164 nsec3chain = nextnsec3chain;
5169 * Add / update signatures for the NSEC3 records.
5171 for (tuple = ISC_LIST_HEAD(nsec3_diff.tuples);
5173 tuple = ISC_LIST_HEAD(nsec3_diff.tuples)) {
5175 * We have changed the NSEC3 RRset above so we need to update
5178 result = del_sigs(zone, db, version, &tuple->name,
5179 dns_rdatatype_nsec3, &sig_diff,
5180 zone_keys, nkeys, now);
5181 if (result != ISC_R_SUCCESS) {
5182 dns_zone_log(zone, ISC_LOG_ERROR,
5183 "zone_nsec3chain:del_sigs -> %s\n",
5184 dns_result_totext(result));
5187 result = add_sigs(db, version, &tuple->name,
5188 dns_rdatatype_nsec3, &sig_diff, zone_keys,
5189 nkeys, zone->mctx, inception, expire,
5191 if (result != ISC_R_SUCCESS) {
5192 dns_zone_log(zone, ISC_LOG_ERROR,
5193 "zone_nsec3chain:add_sigs -> %s\n",
5194 dns_result_totext(result));
5199 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
5200 while (next != NULL &&
5201 !dns_name_equal(&tuple->name, &next->name))
5202 next = ISC_LIST_NEXT(next, link);
5203 ISC_LIST_UNLINK(nsec3_diff.tuples, tuple, link);
5204 dns_diff_appendminimal(&sig_diff, &tuple);
5205 INSIST(tuple == NULL);
5207 } while (tuple != NULL);
5210 for (tuple = ISC_LIST_HEAD(param_diff.tuples);
5212 tuple = ISC_LIST_HEAD(param_diff.tuples)) {
5214 * We have changed the NSEC3PARAM RRset above so we need to
5215 * update the signatures.
5217 result = del_sigs(zone, db, version, &tuple->name,
5218 dns_rdatatype_nsec3param, &sig_diff,
5219 zone_keys, nkeys, now);
5220 if (result != ISC_R_SUCCESS) {
5221 dns_zone_log(zone, ISC_LOG_ERROR,
5222 "zone_nsec3chain:del_sigs -> %s\n",
5223 dns_result_totext(result));
5226 result = add_sigs(db, version, &tuple->name,
5227 dns_rdatatype_nsec3param, &sig_diff,
5228 zone_keys, nkeys, zone->mctx, inception,
5230 if (result != ISC_R_SUCCESS) {
5231 dns_zone_log(zone, ISC_LOG_ERROR,
5232 "zone_nsec3chain:add_sigs -> %s\n",
5233 dns_result_totext(result));
5236 ISC_LIST_UNLINK(param_diff.tuples, tuple, link);
5237 dns_diff_appendminimal(&sig_diff, &tuple);
5238 INSIST(tuple == NULL);
5242 CHECK(updatesecure(db, version, &zone->origin, zone->minimum,
5245 for (tuple = ISC_LIST_HEAD(nsec_diff.tuples);
5247 tuple = ISC_LIST_HEAD(nsec_diff.tuples)) {
5248 result = del_sigs(zone, db, version, &tuple->name,
5249 dns_rdatatype_nsec, &sig_diff,
5250 zone_keys, nkeys, now);
5251 if (result != ISC_R_SUCCESS) {
5252 dns_zone_log(zone, ISC_LOG_ERROR,
5253 "zone_nsec3chain:del_sigs -> %s\n",
5254 dns_result_totext(result));
5257 result = add_sigs(db, version, &tuple->name,
5258 dns_rdatatype_nsec, &sig_diff,
5259 zone_keys, nkeys, zone->mctx, inception,
5261 if (result != ISC_R_SUCCESS) {
5262 dns_zone_log(zone, ISC_LOG_ERROR,
5263 "zone_nsec3chain:add_sigs -> %s\n",
5264 dns_result_totext(result));
5267 ISC_LIST_UNLINK(nsec_diff.tuples, tuple, link);
5268 dns_diff_appendminimal(&sig_diff, &tuple);
5269 INSIST(tuple == NULL);
5273 * If we made no effective changes to the zone then we can just
5274 * cleanup otherwise we need to increment the serial.
5276 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5279 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5280 &sig_diff, zone_keys, nkeys, now);
5281 if (result != ISC_R_SUCCESS) {
5282 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5283 "del_sigs -> %s\n", dns_result_totext(result));
5287 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5288 if (result != ISC_R_SUCCESS) {
5289 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5290 "increment_soa_serial -> %s\n",
5291 dns_result_totext(result));
5295 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5296 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5297 soaexpire, check_ksk);
5298 if (result != ISC_R_SUCCESS) {
5299 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5300 "add_sigs -> %s\n", dns_result_totext(result));
5304 journalfile = dns_zone_getjournal(zone);
5305 if (journalfile != NULL) {
5306 dns_journal_t *journal = NULL;
5307 result = dns_journal_open(zone->mctx, journalfile,
5308 ISC_TRUE, &journal);
5309 if (result != ISC_R_SUCCESS) {
5310 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5311 "dns_journal_open -> %s\n",
5312 dns_result_totext(result));
5316 result = dns_journal_write_transaction(journal, &sig_diff);
5317 dns_journal_destroy(&journal);
5318 if (result != ISC_R_SUCCESS) {
5319 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5320 "dns_journal_write_transaction -> %s\n",
5321 dns_result_totext(result));
5327 zone_needdump(zone, DNS_DUMP_DELAY);
5332 * Pause all iterators so that dns_db_closeversion() can succeed.
5335 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5337 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5338 dns_dbiterator_pause(nsec3chain->dbiterator);
5342 * Everything has succeeded. Commit the changes.
5344 dns_db_closeversion(db, &version, ISC_TRUE);
5347 * Everything succeeded so we can clean these up now.
5349 nsec3chain = ISC_LIST_HEAD(cleanup);
5350 while (nsec3chain != NULL) {
5351 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5352 dns_db_detach(&nsec3chain->db);
5353 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5354 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5355 nsec3chain = ISC_LIST_HEAD(cleanup);
5358 set_resigntime(zone);
5362 * On error roll back the current nsec3chain.
5364 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
5365 if (nsec3chain->done) {
5366 dns_db_detach(&nsec3chain->db);
5367 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5368 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5370 result = dns_dbiterator_first(nsec3chain->dbiterator);
5371 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5372 dns_dbiterator_pause(nsec3chain->dbiterator);
5373 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5378 * Rollback the cleanup list.
5380 nsec3chain = ISC_LIST_TAIL(cleanup);
5381 while (nsec3chain != NULL) {
5382 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5383 if (nsec3chain->done) {
5384 dns_db_detach(&nsec3chain->db);
5385 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5386 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5389 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
5391 result = dns_dbiterator_first(nsec3chain->dbiterator);
5392 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5393 dns_dbiterator_pause(nsec3chain->dbiterator);
5394 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5396 nsec3chain = ISC_LIST_TAIL(cleanup);
5400 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5402 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5403 dns_dbiterator_pause(nsec3chain->dbiterator);
5406 dns_diff_clear(¶m_diff);
5407 dns_diff_clear(&nsec3_diff);
5408 dns_diff_clear(&nsec_diff);
5409 dns_diff_clear(&sig_diff);
5411 if (iterator != NULL)
5412 dns_rdatasetiter_destroy(&iterator);
5414 for (i = 0; i < nkeys; i++)
5415 dst_key_free(&zone_keys[i]);
5417 if (version != NULL) {
5418 dns_db_closeversion(db, &version, ISC_FALSE);
5420 } else if (db != NULL)
5424 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
5426 if (zone->update_disabled || result != ISC_R_SUCCESS)
5427 isc_interval_set(&i, 60, 0); /* 1 minute */
5429 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5430 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
5432 isc_time_settoepoch(&zone->nsec3chaintime);
5437 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5438 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
5439 isc_uint16_t keyid, dns_diff_t *diff)
5441 dns_rdata_rrsig_t rrsig;
5442 dns_rdataset_t rdataset;
5443 dns_rdatasetiter_t *iterator = NULL;
5444 isc_result_t result;
5446 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5447 if (result != ISC_R_SUCCESS) {
5448 if (result == ISC_R_NOTFOUND)
5449 result = ISC_R_SUCCESS;
5453 dns_rdataset_init(&rdataset);
5454 for (result = dns_rdatasetiter_first(iterator);
5455 result == ISC_R_SUCCESS;
5456 result = dns_rdatasetiter_next(iterator)) {
5457 dns_rdatasetiter_current(iterator, &rdataset);
5458 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
5459 for (result = dns_rdataset_first(&rdataset);
5460 result == ISC_R_SUCCESS;
5461 result = dns_rdataset_next(&rdataset)) {
5462 dns_rdata_t rdata = DNS_RDATA_INIT;
5463 dns_rdataset_current(&rdataset, &rdata);
5464 CHECK(update_one_rr(db, version, diff,
5465 DNS_DIFFOP_DEL, name,
5466 rdataset.ttl, &rdata));
5468 if (result != ISC_R_NOMORE)
5470 dns_rdataset_disassociate(&rdataset);
5473 if (rdataset.type != dns_rdatatype_rrsig) {
5474 dns_rdataset_disassociate(&rdataset);
5477 for (result = dns_rdataset_first(&rdataset);
5478 result == ISC_R_SUCCESS;
5479 result = dns_rdataset_next(&rdataset)) {
5480 dns_rdata_t rdata = DNS_RDATA_INIT;
5481 dns_rdataset_current(&rdataset, &rdata);
5482 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
5483 if (rrsig.algorithm != algorithm ||
5484 rrsig.keyid != keyid)
5486 CHECK(update_one_rr(db, version, diff,
5487 DNS_DIFFOP_DELRESIGN, name,
5488 rdataset.ttl, &rdata));
5490 dns_rdataset_disassociate(&rdataset);
5491 if (result != ISC_R_NOMORE)
5494 if (result == ISC_R_NOMORE)
5495 result = ISC_R_SUCCESS;
5497 if (dns_rdataset_isassociated(&rdataset))
5498 dns_rdataset_disassociate(&rdataset);
5499 dns_rdatasetiter_destroy(&iterator);
5504 * Incrementally sign the zone using the keys requested.
5505 * Builds the NSEC chain if required.
5508 zone_sign(dns_zone_t *zone) {
5509 const char *journalfile;
5510 dns_db_t *db = NULL;
5511 dns_dbnode_t *node = NULL;
5512 dns_dbversion_t *version = NULL;
5513 dns_diff_t sig_diff;
5514 dns_fixedname_t fixed;
5515 dns_fixedname_t nextfixed;
5516 dns_name_t *name, *nextname;
5517 dns_rdataset_t rdataset;
5518 dns_signing_t *signing, *nextsigning;
5519 dns_signinglist_t cleanup;
5520 dst_key_t *zone_keys[MAXZONEKEYS];
5521 isc_int32_t signatures;
5522 isc_boolean_t check_ksk, is_ksk;
5523 isc_boolean_t commit = ISC_FALSE;
5524 isc_boolean_t delegation;
5525 isc_boolean_t finishedakey = ISC_FALSE;
5526 isc_boolean_t secureupdated = ISC_FALSE;
5527 isc_boolean_t build_nsec3 = ISC_FALSE, build_nsec = ISC_FALSE;
5528 isc_boolean_t first;
5529 isc_result_t result;
5530 isc_stdtime_t now, inception, soaexpire, expire, stop;
5531 isc_uint32_t jitter;
5533 unsigned int nkeys = 0;
5536 dns_rdataset_init(&rdataset);
5537 dns_fixedname_init(&fixed);
5538 name = dns_fixedname_name(&fixed);
5539 dns_fixedname_init(&nextfixed);
5540 nextname = dns_fixedname_name(&nextfixed);
5541 dns_diff_init(zone->mctx, &sig_diff);
5542 sig_diff.resign = zone->sigresigninginterval;
5543 ISC_LIST_INIT(cleanup);
5546 * Updates are disabled. Pause for 5 minutes.
5548 if (zone->update_disabled) {
5549 result = ISC_R_FAILURE;
5553 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5554 dns_db_attach(zone->db, &db);
5555 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5557 result = dns_db_newversion(db, &version);
5558 if (result != ISC_R_SUCCESS) {
5559 dns_zone_log(zone, ISC_LOG_ERROR,
5560 "zone_sign:dns_db_newversion -> %s\n",
5561 dns_result_totext(result));
5565 result = find_zone_keys(zone, db, version, zone->mctx,
5566 MAXZONEKEYS, zone_keys, &nkeys);
5567 if (result != ISC_R_SUCCESS) {
5568 dns_zone_log(zone, ISC_LOG_ERROR,
5569 "zone_sign:find_zone_keys -> %s\n",
5570 dns_result_totext(result));
5574 isc_stdtime_get(&now);
5575 inception = now - 3600; /* Allow for clock skew. */
5576 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5579 * Spread out signatures over time if they happen to be
5580 * clumped. We don't do this for each add_sigs() call as
5581 * we still want some clustering to occur.
5583 isc_random_get(&jitter);
5584 expire = soaexpire - jitter % 3600;
5587 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5589 check_ksk = ksk_sanity(db, version);
5592 * We keep pulling nodes off each iterator in turn until
5593 * we have no more nodes to pull off or we reach the limits
5596 nodes = zone->nodes;
5597 signatures = zone->signatures;
5598 signing = ISC_LIST_HEAD(zone->signing);
5601 * See if we have a NSEC chain.
5603 result = dns_db_getoriginnode(db, &node);
5604 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5605 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
5606 dns_rdatatype_none, 0, &rdataset, NULL);
5607 dns_db_detachnode(db, &node);
5608 if (result == ISC_R_SUCCESS) {
5609 build_nsec = ISC_TRUE;
5610 dns_rdataset_disassociate(&rdataset);
5611 } else if (result != ISC_R_NOTFOUND) {
5615 * No NSEC chain present.
5616 * See if we need to build a NSEC3 chain?
5618 result = dns_nsec3_active(db, version, ISC_TRUE, &build_nsec3);
5619 if (result == ISC_R_SUCCESS) {
5621 build_nsec3 = ISC_FALSE;
5623 result = dns_nsec3_active(db, version,
5627 secureupdated = ISC_TRUE;
5629 build_nsec = ISC_TRUE;
5634 while (signing != NULL && nodes-- > 0 && signatures > 0) {
5635 nextsigning = ISC_LIST_NEXT(signing, link);
5637 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5638 if (signing->done || signing->db != zone->db) {
5640 * The zone has been reloaded. We will have
5641 * created new signings as part of the reload
5642 * process so we can destroy this one.
5644 ISC_LIST_UNLINK(zone->signing, signing, link);
5645 ISC_LIST_APPEND(cleanup, signing, link);
5646 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5649 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5651 if (signing->db != db)
5655 delegation = ISC_FALSE;
5657 dns_dbiterator_current(signing->dbiterator, &node, name);
5659 if (signing->delete) {
5660 dns_dbiterator_pause(signing->dbiterator);
5661 CHECK(del_sig(db, version, name, node, nkeys,
5662 signing->algorithm, signing->keyid,
5667 * On the first pass we need to check if the current node
5668 * has not been obscured.
5671 dns_fixedname_t ffound;
5673 dns_fixedname_init(&ffound);
5674 found = dns_fixedname_name(&ffound);
5675 result = dns_db_find(db, name, version,
5677 DNS_DBFIND_NOWILD, 0, NULL, found,
5679 if ((result == DNS_R_DELEGATION ||
5680 result == DNS_R_DNAME) &&
5681 !dns_name_equal(name, found)) {
5683 * Remember the obscuring name so that
5684 * we skip all obscured names.
5686 dns_name_copy(found, name, NULL);
5687 delegation = ISC_TRUE;
5695 dns_dbiterator_pause(signing->dbiterator);
5696 for (i = 0; i < nkeys; i++) {
5698 * Find the key we want to sign with.
5700 if (dst_key_alg(zone_keys[i]) != signing->algorithm ||
5701 dst_key_id(zone_keys[i]) != signing->keyid ||
5702 !dst_key_isprivate(zone_keys[i]))
5705 * Do we do KSK processing?
5708 (dst_key_flags(zone_keys[i]) & DNS_KEYFLAG_KSK) != 0)
5710 CHECK(sign_a_node(db, name, node, version, build_nsec3,
5711 build_nsec, zone_keys[i], inception,
5712 expire, zone->minimum, is_ksk,
5713 &delegation, &sig_diff, &signatures,
5718 * Go onto next node.
5722 dns_db_detachnode(db, &node);
5724 result = dns_dbiterator_next(signing->dbiterator);
5725 if (result == ISC_R_NOMORE) {
5726 ISC_LIST_UNLINK(zone->signing, signing, link);
5727 ISC_LIST_APPEND(cleanup, signing, link);
5728 dns_dbiterator_pause(signing->dbiterator);
5729 finishedakey = ISC_TRUE;
5730 if (!is_ksk && !secureupdated && nkeys != 0 &&
5733 * We have finished regenerating the
5734 * zone with a zone signing key.
5735 * The NSEC chain is now complete and
5736 * there is a full set of signatures
5737 * for the zone. We can now clear the
5738 * OPT bit from the NSEC record.
5740 result = updatesecure(db, version,
5745 if (result != ISC_R_SUCCESS) {
5748 "updatesecure -> %s\n",
5749 dns_result_totext(result));
5753 result = updatesignwithkey(signing, version,
5757 if (result != ISC_R_SUCCESS) {
5758 dns_zone_log(zone, ISC_LOG_ERROR,
5759 "updatesignwithkey -> %s\n",
5760 dns_result_totext(result));
5764 } else if (result != ISC_R_SUCCESS) {
5765 dns_zone_log(zone, ISC_LOG_ERROR,
5766 "zone_sign:dns_dbiterator_next -> %s\n",
5767 dns_result_totext(result));
5769 } else if (delegation) {
5770 dns_dbiterator_current(signing->dbiterator,
5772 dns_db_detachnode(db, &node);
5773 if (!dns_name_issubdomain(nextname, name))
5781 dns_dbiterator_pause(signing->dbiterator);
5782 signing = nextsigning;
5786 if (secureupdated) {
5788 * We have changed the NSEC RRset above so we need to update
5791 result = del_sigs(zone, db, version, &zone->origin,
5792 dns_rdatatype_nsec, &sig_diff, zone_keys,
5794 if (result != ISC_R_SUCCESS) {
5795 dns_zone_log(zone, ISC_LOG_ERROR,
5796 "zone_sign:del_sigs -> %s\n",
5797 dns_result_totext(result));
5800 result = add_sigs(db, version, &zone->origin,
5801 dns_rdatatype_nsec, &sig_diff, zone_keys,
5802 nkeys, zone->mctx, inception, soaexpire,
5804 if (result != ISC_R_SUCCESS) {
5805 dns_zone_log(zone, ISC_LOG_ERROR,
5806 "zone_sign:add_sigs -> %s\n",
5807 dns_result_totext(result));
5814 * We have changed the RRset above so we need to update
5817 result = del_sigs(zone, db, version, &zone->origin,
5818 zone->privatetype, &sig_diff,
5819 zone_keys, nkeys, now);
5820 if (result != ISC_R_SUCCESS) {
5821 dns_zone_log(zone, ISC_LOG_ERROR,
5822 "zone_sign:del_sigs -> %s\n",
5823 dns_result_totext(result));
5826 result = add_sigs(db, version, &zone->origin,
5827 zone->privatetype, &sig_diff,
5828 zone_keys, nkeys, zone->mctx, inception,
5829 soaexpire, check_ksk);
5830 if (result != ISC_R_SUCCESS) {
5831 dns_zone_log(zone, ISC_LOG_ERROR,
5832 "zone_sign:add_sigs -> %s\n",
5833 dns_result_totext(result));
5839 * Have we changed anything?
5841 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5846 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5847 &sig_diff, zone_keys, nkeys, now);
5848 if (result != ISC_R_SUCCESS) {
5849 dns_zone_log(zone, ISC_LOG_ERROR,
5850 "zone_sign:del_sigs -> %s\n",
5851 dns_result_totext(result));
5855 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5856 if (result != ISC_R_SUCCESS) {
5857 dns_zone_log(zone, ISC_LOG_ERROR,
5858 "zone_sign:increment_soa_serial -> %s\n",
5859 dns_result_totext(result));
5864 * Generate maximum life time signatures so that the above loop
5865 * termination is sensible.
5867 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5868 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5869 soaexpire, check_ksk);
5870 if (result != ISC_R_SUCCESS) {
5871 dns_zone_log(zone, ISC_LOG_ERROR,
5872 "zone_sign:add_sigs -> %s\n",
5873 dns_result_totext(result));
5878 * Write changes to journal file.
5880 journalfile = dns_zone_getjournal(zone);
5881 if (journalfile != NULL) {
5882 dns_journal_t *journal = NULL;
5883 result = dns_journal_open(zone->mctx, journalfile,
5884 ISC_TRUE, &journal);
5885 if (result != ISC_R_SUCCESS) {
5886 dns_zone_log(zone, ISC_LOG_ERROR,
5887 "zone_sign:dns_journal_open -> %s\n",
5888 dns_result_totext(result));
5892 result = dns_journal_write_transaction(journal, &sig_diff);
5893 dns_journal_destroy(&journal);
5894 if (result != ISC_R_SUCCESS) {
5895 dns_zone_log(zone, ISC_LOG_ERROR,
5896 "zone_sign:dns_journal_write_transaction -> %s\n",
5897 dns_result_totext(result));
5904 * Pause all iterators so that dns_db_closeversion() can succeed.
5906 for (signing = ISC_LIST_HEAD(zone->signing);
5908 signing = ISC_LIST_NEXT(signing, link))
5909 dns_dbiterator_pause(signing->dbiterator);
5911 for (signing = ISC_LIST_HEAD(cleanup);
5913 signing = ISC_LIST_NEXT(signing, link))
5914 dns_dbiterator_pause(signing->dbiterator);
5917 * Everything has succeeded. Commit the changes.
5919 dns_db_closeversion(db, &version, commit);
5922 * Everything succeeded so we can clean these up now.
5924 signing = ISC_LIST_HEAD(cleanup);
5925 while (signing != NULL) {
5926 ISC_LIST_UNLINK(cleanup, signing, link);
5927 dns_db_detach(&signing->db);
5928 dns_dbiterator_destroy(&signing->dbiterator);
5929 isc_mem_put(zone->mctx, signing, sizeof *signing);
5930 signing = ISC_LIST_HEAD(cleanup);
5933 set_resigntime(zone);
5937 zone_needdump(zone, DNS_DUMP_DELAY);
5943 * Rollback the cleanup list.
5945 signing = ISC_LIST_HEAD(cleanup);
5946 while (signing != NULL) {
5947 ISC_LIST_UNLINK(cleanup, signing, link);
5948 ISC_LIST_APPEND(zone->signing, signing, link);
5949 dns_dbiterator_first(signing->dbiterator);
5950 dns_dbiterator_pause(signing->dbiterator);
5951 signing = ISC_LIST_HEAD(cleanup);
5954 for (signing = ISC_LIST_HEAD(zone->signing);
5956 signing = ISC_LIST_NEXT(signing, link))
5957 dns_dbiterator_pause(signing->dbiterator);
5959 dns_diff_clear(&sig_diff);
5961 for (i = 0; i < nkeys; i++)
5962 dst_key_free(&zone_keys[i]);
5964 if (version != NULL) {
5965 dns_db_closeversion(db, &version, ISC_FALSE);
5967 } else if (db != NULL)
5970 if (ISC_LIST_HEAD(zone->signing) != NULL) {
5972 if (zone->update_disabled || result != ISC_R_SUCCESS)
5973 isc_interval_set(&i, 60, 0); /* 1 minute */
5975 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5976 isc_time_nowplusinterval(&zone->signingtime, &i);
5978 isc_time_settoepoch(&zone->signingtime);
5982 zone_maintenance(dns_zone_t *zone) {
5983 const char me[] = "zone_maintenance";
5985 isc_result_t result;
5986 isc_boolean_t dumping;
5988 REQUIRE(DNS_ZONE_VALID(zone));
5992 * Configuring the view of this zone may have
5993 * failed, for example because the config file
5994 * had a syntax error. In that case, the view
5995 * adb or resolver, and we had better not try
5996 * to do maintenance on it.
5998 if (zone->view == NULL || zone->view->adb == NULL)
6006 switch (zone->type) {
6007 case dns_zone_slave:
6010 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
6011 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6013 zone->refreshtime = now;
6024 switch (zone->type) {
6025 case dns_zone_slave:
6027 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
6028 isc_time_compare(&now, &zone->refreshtime) >= 0)
6029 dns_zone_refresh(zone);
6036 * Do we need to consolidate the backing store?
6038 switch (zone->type) {
6039 case dns_zone_master:
6040 case dns_zone_slave:
6042 if (zone->masterfile != NULL &&
6043 isc_time_compare(&now, &zone->dumptime) >= 0 &&
6044 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
6045 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
6046 dumping = was_dumping(zone);
6051 result = zone_dump(zone, ISC_TRUE); /* task locked */
6052 if (result != ISC_R_SUCCESS)
6053 dns_zone_log(zone, ISC_LOG_WARNING,
6055 dns_result_totext(result));
6062 switch (zone->type) {
6063 case dns_zone_master:
6064 case dns_zone_slave:
6066 * Do we need to send out notify messages?
6068 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
6069 isc_time_compare(&now, &zone->notifytime) >= 0)
6070 zone_notify(zone, &now);
6072 * Do we need to sign/resign some RRsets?
6074 if (!isc_time_isepoch(&zone->signingtime) &&
6075 isc_time_compare(&now, &zone->signingtime) >= 0)
6077 else if (!isc_time_isepoch(&zone->resigntime) &&
6078 isc_time_compare(&now, &zone->resigntime) >= 0)
6079 zone_resigninc(zone);
6080 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
6081 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
6082 zone_nsec3chain(zone);
6084 * Do we need to issue a key expiry warning.
6086 if (!isc_time_isepoch(&zone->keywarntime) &&
6087 isc_time_compare(&now, &zone->keywarntime) >= 0)
6088 set_key_expiry_warning(zone, zone->key_expiry,
6089 isc_time_seconds(&now));
6094 zone_settimer(zone, &now);
6098 dns_zone_markdirty(dns_zone_t *zone) {
6101 set_resigntime(zone); /* XXXMPA make separate call back */
6102 zone_needdump(zone, DNS_DUMP_DELAY);
6107 dns_zone_expire(dns_zone_t *zone) {
6108 REQUIRE(DNS_ZONE_VALID(zone));
6116 zone_expire(dns_zone_t *zone) {
6118 * 'zone' locked by caller.
6121 REQUIRE(LOCKED_ZONE(zone));
6123 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
6125 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
6126 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
6127 zone->retry = DNS_ZONE_DEFAULTRETRY;
6128 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6133 dns_zone_refresh(dns_zone_t *zone) {
6135 isc_uint32_t oldflags;
6137 isc_result_t result;
6139 REQUIRE(DNS_ZONE_VALID(zone));
6141 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
6145 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
6146 * in progress at a time.
6150 oldflags = zone->flags;
6151 if (zone->masterscnt == 0) {
6152 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
6153 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
6154 dns_zone_log(zone, ISC_LOG_ERROR,
6155 "cannot refresh: no masters");
6158 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6159 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
6160 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6161 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
6165 * Set the next refresh time as if refresh check has failed.
6166 * Setting this to the retry time will do that. XXXMLG
6167 * If we are successful it will be reset using zone->refresh.
6169 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
6171 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
6172 if (result |= ISC_R_SUCCESS)
6173 dns_zone_log(zone, ISC_LOG_WARNING,
6174 "isc_time_nowplusinterval() failed: %s",
6175 dns_result_totext(result));
6178 * When lacking user-specified timer values from the SOA,
6179 * do exponential backoff of the retry time up to a
6180 * maximum of six hours.
6182 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
6183 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
6185 zone->curmaster = 0;
6186 for (j = 0; j < zone->masterscnt; j++)
6187 zone->mastersok[j] = ISC_FALSE;
6188 /* initiate soa query */
6189 queue_soa_query(zone);
6195 dns_zone_flush(dns_zone_t *zone) {
6196 isc_result_t result = ISC_R_SUCCESS;
6197 isc_boolean_t dumping;
6199 REQUIRE(DNS_ZONE_VALID(zone));
6202 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
6203 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6204 zone->masterfile != NULL) {
6205 result = ISC_R_ALREADYRUNNING;
6206 dumping = was_dumping(zone);
6211 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6216 dns_zone_dump(dns_zone_t *zone) {
6217 isc_result_t result = ISC_R_ALREADYRUNNING;
6218 isc_boolean_t dumping;
6220 REQUIRE(DNS_ZONE_VALID(zone));
6223 dumping = was_dumping(zone);
6226 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6231 zone_needdump(dns_zone_t *zone, unsigned int delay) {
6232 isc_time_t dumptime;
6236 * 'zone' locked by caller
6239 REQUIRE(DNS_ZONE_VALID(zone));
6240 REQUIRE(LOCKED_ZONE(zone));
6243 * Do we have a place to dump to and are we loaded?
6245 if (zone->masterfile == NULL ||
6246 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
6250 /* add some noise */
6251 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
6253 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6254 if (isc_time_isepoch(&zone->dumptime) ||
6255 isc_time_compare(&zone->dumptime, &dumptime) > 0)
6256 zone->dumptime = dumptime;
6257 if (zone->task != NULL)
6258 zone_settimer(zone, &now);
6262 dump_done(void *arg, isc_result_t result) {
6263 const char me[] = "dump_done";
6264 dns_zone_t *zone = arg;
6266 dns_dbversion_t *version;
6267 isc_boolean_t again = ISC_FALSE;
6268 isc_boolean_t compact = ISC_FALSE;
6269 isc_uint32_t serial;
6270 isc_result_t tresult;
6272 REQUIRE(DNS_ZONE_VALID(zone));
6276 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
6277 zone->journalsize != -1) {
6280 * We don't own these, zone->dctx must stay valid.
6282 db = dns_dumpctx_db(zone->dctx);
6283 version = dns_dumpctx_version(zone->dctx);
6285 tresult = dns_db_getsoaserial(db, version, &serial);
6287 * Note: we are task locked here so we can test
6290 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
6291 tresult = dns_journal_compact(zone->mctx,
6298 case ISC_R_NOTFOUND:
6299 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6300 "dns_journal_compact: %s",
6301 dns_result_totext(tresult));
6304 dns_zone_log(zone, ISC_LOG_ERROR,
6305 "dns_journal_compact failed: %s",
6306 dns_result_totext(tresult));
6309 } else if (tresult == ISC_R_SUCCESS) {
6311 zone->compact_serial = serial;
6316 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6318 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
6319 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
6321 * Try again in a short while.
6323 zone_needdump(zone, DNS_DUMP_DELAY);
6324 } else if (result == ISC_R_SUCCESS &&
6325 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6326 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6327 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6328 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6329 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6330 isc_time_settoepoch(&zone->dumptime);
6332 } else if (result == ISC_R_SUCCESS)
6333 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6335 if (zone->dctx != NULL)
6336 dns_dumpctx_detach(&zone->dctx);
6337 zonemgr_putio(&zone->writeio);
6340 (void)zone_dump(zone, ISC_FALSE);
6341 dns_zone_idetach(&zone);
6345 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
6346 const char me[] = "zone_dump";
6347 isc_result_t result;
6348 dns_dbversion_t *version = NULL;
6349 isc_boolean_t again;
6350 dns_db_t *db = NULL;
6351 char *masterfile = NULL;
6352 dns_masterformat_t masterformat = dns_masterformat_none;
6355 * 'compact' MUST only be set if we are task locked.
6358 REQUIRE(DNS_ZONE_VALID(zone));
6362 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6363 if (zone->db != NULL)
6364 dns_db_attach(zone->db, &db);
6365 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6367 if (zone->masterfile != NULL) {
6368 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
6369 masterformat = zone->masterformat;
6373 result = DNS_R_NOTLOADED;
6376 if (masterfile == NULL) {
6377 result = DNS_R_NOMASTERFILE;
6382 dns_zone_t *dummy = NULL;
6384 zone_iattach(zone, &dummy);
6385 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
6386 zone_gotwritehandle, zone,
6388 if (result != ISC_R_SUCCESS)
6389 zone_idetach(&dummy);
6391 result = DNS_R_CONTINUE;
6394 dns_db_currentversion(db, &version);
6395 result = dns_master_dump2(zone->mctx, db, version,
6396 &dns_master_style_default,
6397 masterfile, masterformat);
6398 dns_db_closeversion(db, &version, ISC_FALSE);
6403 if (masterfile != NULL)
6404 isc_mem_free(zone->mctx, masterfile);
6407 if (result == DNS_R_CONTINUE)
6408 return (ISC_R_SUCCESS); /* XXXMPA */
6412 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6413 if (result != ISC_R_SUCCESS) {
6415 * Try again in a short while.
6417 zone_needdump(zone, DNS_DUMP_DELAY);
6418 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6419 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6420 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6421 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6422 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6423 isc_time_settoepoch(&zone->dumptime);
6426 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6435 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
6436 dns_masterformat_t format)
6438 isc_result_t result;
6439 dns_dbversion_t *version = NULL;
6440 dns_db_t *db = NULL;
6442 REQUIRE(DNS_ZONE_VALID(zone));
6444 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6445 if (zone->db != NULL)
6446 dns_db_attach(zone->db, &db);
6447 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6449 return (DNS_R_NOTLOADED);
6451 dns_db_currentversion(db, &version);
6452 result = dns_master_dumptostream2(zone->mctx, db, version, style,
6454 dns_db_closeversion(db, &version, ISC_FALSE);
6460 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
6461 const dns_master_style_t *style) {
6462 return dumptostream(zone, fd, style, format);
6466 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
6467 return dumptostream(zone, fd, &dns_master_style_default,
6468 dns_masterformat_text);
6472 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
6473 return dumptostream(zone, fd, &dns_master_style_full,
6474 dns_masterformat_text);
6478 dns_zone_unload(dns_zone_t *zone) {
6479 REQUIRE(DNS_ZONE_VALID(zone));
6487 notify_cancel(dns_zone_t *zone) {
6488 dns_notify_t *notify;
6491 * 'zone' locked by caller.
6494 REQUIRE(LOCKED_ZONE(zone));
6496 for (notify = ISC_LIST_HEAD(zone->notifies);
6498 notify = ISC_LIST_NEXT(notify, link)) {
6499 if (notify->find != NULL)
6500 dns_adb_cancelfind(notify->find);
6501 if (notify->request != NULL)
6502 dns_request_cancel(notify->request);
6507 zone_unload(dns_zone_t *zone) {
6510 * 'zone' locked by caller.
6513 REQUIRE(LOCKED_ZONE(zone));
6515 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6516 zone_detachdb(zone);
6517 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6518 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
6519 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6523 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6524 REQUIRE(DNS_ZONE_VALID(zone));
6527 zone->minrefresh = val;
6531 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6532 REQUIRE(DNS_ZONE_VALID(zone));
6535 zone->maxrefresh = val;
6539 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
6540 REQUIRE(DNS_ZONE_VALID(zone));
6543 zone->minretry = val;
6547 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
6548 REQUIRE(DNS_ZONE_VALID(zone));
6551 zone->maxretry = val;
6554 static isc_boolean_t
6555 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
6556 dns_notify_t *notify;
6558 for (notify = ISC_LIST_HEAD(zone->notifies);
6560 notify = ISC_LIST_NEXT(notify, link)) {
6561 if (notify->request != NULL)
6563 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
6564 dns_name_equal(name, ¬ify->ns))
6566 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
6572 static isc_boolean_t
6573 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
6574 dns_tsigkey_t *key = NULL;
6577 isc_boolean_t isself;
6578 isc_netaddr_t dstaddr;
6579 isc_result_t result;
6581 if (zone->view == NULL || zone->isself == NULL)
6584 switch (isc_sockaddr_pf(dst)) {
6586 src = zone->notifysrc4;
6587 isc_sockaddr_any(&any);
6590 src = zone->notifysrc6;
6591 isc_sockaddr_any6(&any);
6598 * When sending from any the kernel will assign a source address
6599 * that matches the destination address.
6601 if (isc_sockaddr_eqaddr(&any, &src))
6604 isc_netaddr_fromsockaddr(&dstaddr, dst);
6605 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
6606 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
6608 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
6611 dns_tsigkey_detach(&key);
6616 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
6620 * Caller holds zone lock.
6622 REQUIRE(DNS_NOTIFY_VALID(notify));
6624 if (notify->zone != NULL) {
6626 LOCK_ZONE(notify->zone);
6627 REQUIRE(LOCKED_ZONE(notify->zone));
6628 if (ISC_LINK_LINKED(notify, link))
6629 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
6631 UNLOCK_ZONE(notify->zone);
6633 zone_idetach(¬ify->zone);
6635 dns_zone_idetach(¬ify->zone);
6637 if (notify->find != NULL)
6638 dns_adb_destroyfind(¬ify->find);
6639 if (notify->request != NULL)
6640 dns_request_destroy(¬ify->request);
6641 if (dns_name_dynamic(¬ify->ns))
6642 dns_name_free(¬ify->ns, notify->mctx);
6643 mctx = notify->mctx;
6644 isc_mem_put(notify->mctx, notify, sizeof(*notify));
6645 isc_mem_detach(&mctx);
6649 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
6650 dns_notify_t *notify;
6652 REQUIRE(notifyp != NULL && *notifyp == NULL);
6654 notify = isc_mem_get(mctx, sizeof(*notify));
6656 return (ISC_R_NOMEMORY);
6658 notify->mctx = NULL;
6659 isc_mem_attach(mctx, ¬ify->mctx);
6660 notify->flags = flags;
6661 notify->zone = NULL;
6662 notify->find = NULL;
6663 notify->request = NULL;
6664 isc_sockaddr_any(¬ify->dst);
6665 dns_name_init(¬ify->ns, NULL);
6666 ISC_LINK_INIT(notify, link);
6667 notify->magic = NOTIFY_MAGIC;
6669 return (ISC_R_SUCCESS);
6673 * XXXAG should check for DNS_ZONEFLG_EXITING
6676 process_adb_event(isc_task_t *task, isc_event_t *ev) {
6677 dns_notify_t *notify;
6678 isc_eventtype_t result;
6682 notify = ev->ev_arg;
6683 REQUIRE(DNS_NOTIFY_VALID(notify));
6684 INSIST(task == notify->zone->task);
6685 result = ev->ev_type;
6686 isc_event_free(&ev);
6687 if (result == DNS_EVENT_ADBMOREADDRESSES) {
6688 dns_adb_destroyfind(¬ify->find);
6689 notify_find_address(notify);
6692 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
6693 LOCK_ZONE(notify->zone);
6694 notify_send(notify);
6695 UNLOCK_ZONE(notify->zone);
6697 notify_destroy(notify, ISC_FALSE);
6701 notify_find_address(dns_notify_t *notify) {
6702 isc_result_t result;
6703 unsigned int options;
6705 REQUIRE(DNS_NOTIFY_VALID(notify));
6706 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
6707 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
6709 if (notify->zone->view->adb == NULL)
6712 result = dns_adb_createfind(notify->zone->view->adb,
6714 process_adb_event, notify,
6715 ¬ify->ns, dns_rootname, 0,
6717 notify->zone->view->dstport,
6720 /* Something failed? */
6721 if (result != ISC_R_SUCCESS)
6724 /* More addresses pending? */
6725 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
6728 /* We have as many addresses as we can get. */
6729 LOCK_ZONE(notify->zone);
6730 notify_send(notify);
6731 UNLOCK_ZONE(notify->zone);
6734 notify_destroy(notify, ISC_FALSE);
6739 notify_send_queue(dns_notify_t *notify) {
6741 isc_result_t result;
6743 e = isc_event_allocate(notify->mctx, NULL,
6744 DNS_EVENT_NOTIFYSENDTOADDR,
6746 notify, sizeof(isc_event_t));
6748 return (ISC_R_NOMEMORY);
6750 e->ev_sender = NULL;
6751 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
6752 notify->zone->task, &e);
6753 if (result != ISC_R_SUCCESS)
6759 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
6760 dns_notify_t *notify;
6761 isc_result_t result;
6762 dns_message_t *message = NULL;
6763 isc_netaddr_t dstip;
6764 dns_tsigkey_t *key = NULL;
6765 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6768 isc_boolean_t have_notifysource = ISC_FALSE;
6770 notify = event->ev_arg;
6771 REQUIRE(DNS_NOTIFY_VALID(notify));
6775 LOCK_ZONE(notify->zone);
6777 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
6778 result = ISC_R_CANCELED;
6782 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
6783 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
6784 notify->zone->view->requestmgr == NULL ||
6785 notify->zone->db == NULL) {
6786 result = ISC_R_CANCELED;
6791 * The raw IPv4 address should also exist. Don't send to the
6794 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
6795 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
6796 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6797 notify_log(notify->zone, ISC_LOG_DEBUG(3),
6798 "notify: ignoring IPv6 mapped IPV4 address: %s",
6800 result = ISC_R_CANCELED;
6804 result = notify_createmessage(notify->zone, notify->flags, &message);
6805 if (result != ISC_R_SUCCESS)
6808 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
6809 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6810 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
6811 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6812 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
6813 "sent. Peer TSIG key lookup failure.", addrbuf);
6814 goto cleanup_message;
6817 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
6819 if (notify->zone->view->peers != NULL) {
6820 dns_peer_t *peer = NULL;
6821 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
6823 if (result == ISC_R_SUCCESS) {
6824 result = dns_peer_getnotifysource(peer, &src);
6825 if (result == ISC_R_SUCCESS)
6826 have_notifysource = ISC_TRUE;
6829 switch (isc_sockaddr_pf(¬ify->dst)) {
6831 if (!have_notifysource)
6832 src = notify->zone->notifysrc4;
6835 if (!have_notifysource)
6836 src = notify->zone->notifysrc6;
6839 result = ISC_R_NOTIMPLEMENTED;
6843 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
6845 result = dns_request_createvia2(notify->zone->view->requestmgr,
6846 message, &src, ¬ify->dst, 0, key,
6847 timeout * 3, timeout,
6848 notify->zone->task, notify_done,
6849 notify, ¬ify->request);
6850 if (result == ISC_R_SUCCESS) {
6851 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
6852 inc_stats(notify->zone,
6853 dns_zonestatscounter_notifyoutv4);
6855 inc_stats(notify->zone,
6856 dns_zonestatscounter_notifyoutv6);
6862 dns_tsigkey_detach(&key);
6864 dns_message_destroy(&message);
6866 UNLOCK_ZONE(notify->zone);
6867 if (result != ISC_R_SUCCESS)
6868 notify_destroy(notify, ISC_FALSE);
6869 isc_event_free(&event);
6873 notify_send(dns_notify_t *notify) {
6874 dns_adbaddrinfo_t *ai;
6876 isc_result_t result;
6877 dns_notify_t *new = NULL;
6880 * Zone lock held by caller.
6882 REQUIRE(DNS_NOTIFY_VALID(notify));
6883 REQUIRE(LOCKED_ZONE(notify->zone));
6885 for (ai = ISC_LIST_HEAD(notify->find->list);
6887 ai = ISC_LIST_NEXT(ai, publink)) {
6889 if (notify_isqueued(notify->zone, NULL, &dst))
6891 if (notify_isself(notify->zone, &dst))
6894 result = notify_create(notify->mctx,
6895 (notify->flags & DNS_NOTIFY_NOSOA),
6897 if (result != ISC_R_SUCCESS)
6899 zone_iattach(notify->zone, &new->zone);
6900 ISC_LIST_APPEND(new->zone->notifies, new, link);
6902 result = notify_send_queue(new);
6903 if (result != ISC_R_SUCCESS)
6910 notify_destroy(new, ISC_TRUE);
6914 dns_zone_notify(dns_zone_t *zone) {
6917 REQUIRE(DNS_ZONE_VALID(zone));
6920 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6923 zone_settimer(zone, &now);
6928 zone_notify(dns_zone_t *zone, isc_time_t *now) {
6929 dns_dbnode_t *node = NULL;
6930 dns_db_t *zonedb = NULL;
6931 dns_dbversion_t *version = NULL;
6932 dns_name_t *origin = NULL;
6935 dns_rdata_soa_t soa;
6936 isc_uint32_t serial;
6937 dns_rdata_t rdata = DNS_RDATA_INIT;
6938 dns_rdataset_t nsrdset;
6939 dns_rdataset_t soardset;
6940 isc_result_t result;
6941 dns_notify_t *notify = NULL;
6944 isc_boolean_t isqueued;
6945 dns_notifytype_t notifytype;
6946 unsigned int flags = 0;
6947 isc_boolean_t loggednotify = ISC_FALSE;
6949 REQUIRE(DNS_ZONE_VALID(zone));
6952 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6953 notifytype = zone->notifytype;
6954 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
6957 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
6960 if (notifytype == dns_notifytype_no)
6963 if (notifytype == dns_notifytype_masteronly &&
6964 zone->type != dns_zone_master)
6967 origin = &zone->origin;
6970 * If the zone is dialup we are done as we don't want to send
6971 * the current soa so as to force a refresh query.
6973 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
6974 flags |= DNS_NOTIFY_NOSOA;
6979 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6980 if (zone->db != NULL)
6981 dns_db_attach(zone->db, &zonedb);
6982 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6985 dns_db_currentversion(zonedb, &version);
6986 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
6987 if (result != ISC_R_SUCCESS)
6990 dns_rdataset_init(&soardset);
6991 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
6992 dns_rdatatype_none, 0, &soardset, NULL);
6993 if (result != ISC_R_SUCCESS)
6997 * Find serial and master server's name.
6999 dns_name_init(&master, NULL);
7000 result = dns_rdataset_first(&soardset);
7001 if (result != ISC_R_SUCCESS)
7003 dns_rdataset_current(&soardset, &rdata);
7004 result = dns_rdata_tostruct(&rdata, &soa, NULL);
7005 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7006 dns_rdata_reset(&rdata);
7007 result = dns_name_dup(&soa.origin, zone->mctx, &master);
7008 serial = soa.serial;
7009 dns_rdataset_disassociate(&soardset);
7010 if (result != ISC_R_SUCCESS)
7014 * Enqueue notify requests for 'also-notify' servers.
7017 for (i = 0; i < zone->notifycnt; i++) {
7018 dst = zone->notify[i];
7019 if (notify_isqueued(zone, NULL, &dst))
7021 result = notify_create(zone->mctx, flags, ¬ify);
7022 if (result != ISC_R_SUCCESS)
7024 zone_iattach(zone, ¬ify->zone);
7026 ISC_LIST_APPEND(zone->notifies, notify, link);
7027 result = notify_send_queue(notify);
7028 if (result != ISC_R_SUCCESS)
7029 notify_destroy(notify, ISC_TRUE);
7030 if (!loggednotify) {
7031 notify_log(zone, ISC_LOG_INFO,
7032 "sending notifies (serial %u)",
7034 loggednotify = ISC_TRUE;
7040 if (notifytype == dns_notifytype_explicit)
7044 * Process NS RRset to generate notifies.
7047 dns_rdataset_init(&nsrdset);
7048 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
7049 dns_rdatatype_none, 0, &nsrdset, NULL);
7050 if (result != ISC_R_SUCCESS)
7053 result = dns_rdataset_first(&nsrdset);
7054 while (result == ISC_R_SUCCESS) {
7055 dns_rdataset_current(&nsrdset, &rdata);
7056 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7057 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7058 dns_rdata_reset(&rdata);
7060 * Don't notify the master server unless explicitly
7061 * configured to do so.
7063 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
7064 dns_name_compare(&master, &ns.name) == 0) {
7065 result = dns_rdataset_next(&nsrdset);
7069 if (!loggednotify) {
7070 notify_log(zone, ISC_LOG_INFO,
7071 "sending notifies (serial %u)",
7073 loggednotify = ISC_TRUE;
7077 isqueued = notify_isqueued(zone, &ns.name, NULL);
7080 result = dns_rdataset_next(&nsrdset);
7083 result = notify_create(zone->mctx, flags, ¬ify);
7084 if (result != ISC_R_SUCCESS)
7086 dns_zone_iattach(zone, ¬ify->zone);
7087 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
7088 if (result != ISC_R_SUCCESS) {
7090 notify_destroy(notify, ISC_TRUE);
7095 ISC_LIST_APPEND(zone->notifies, notify, link);
7097 notify_find_address(notify);
7099 result = dns_rdataset_next(&nsrdset);
7101 dns_rdataset_disassociate(&nsrdset);
7104 if (dns_name_dynamic(&master))
7105 dns_name_free(&master, zone->mctx);
7107 dns_db_detachnode(zonedb, &node);
7109 dns_db_closeversion(zonedb, &version, ISC_FALSE);
7110 dns_db_detach(&zonedb);
7117 static inline isc_result_t
7118 save_nsrrset(dns_message_t *message, dns_name_t *name,
7119 dns_db_t *db, dns_dbversion_t *version)
7121 dns_rdataset_t *nsrdataset = NULL;
7122 dns_rdataset_t *rdataset = NULL;
7123 dns_dbnode_t *node = NULL;
7125 isc_result_t result;
7126 dns_rdata_t rdata = DNS_RDATA_INIT;
7129 * Extract NS RRset from message.
7131 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
7132 dns_rdatatype_ns, dns_rdatatype_none,
7134 if (result != ISC_R_SUCCESS)
7140 result = dns_db_findnode(db, name, ISC_TRUE, &node);
7141 if (result != ISC_R_SUCCESS)
7143 result = dns_db_addrdataset(db, node, version, 0,
7144 nsrdataset, 0, NULL);
7145 dns_db_detachnode(db, &node);
7146 if (result != ISC_R_SUCCESS)
7149 * Add glue rdatasets.
7151 for (result = dns_rdataset_first(nsrdataset);
7152 result == ISC_R_SUCCESS;
7153 result = dns_rdataset_next(nsrdataset)) {
7154 dns_rdataset_current(nsrdataset, &rdata);
7155 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7156 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7157 dns_rdata_reset(&rdata);
7158 if (!dns_name_issubdomain(&ns.name, name))
7161 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7162 &ns.name, dns_rdatatype_aaaa,
7163 dns_rdatatype_none, NULL,
7165 if (result == ISC_R_SUCCESS) {
7166 result = dns_db_findnode(db, &ns.name,
7168 if (result != ISC_R_SUCCESS)
7170 result = dns_db_addrdataset(db, node, version, 0,
7172 dns_db_detachnode(db, &node);
7173 if (result != ISC_R_SUCCESS)
7177 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7178 &ns.name, dns_rdatatype_a,
7179 dns_rdatatype_none, NULL,
7181 if (result == ISC_R_SUCCESS) {
7182 result = dns_db_findnode(db, &ns.name,
7184 if (result != ISC_R_SUCCESS)
7186 result = dns_db_addrdataset(db, node, version, 0,
7188 dns_db_detachnode(db, &node);
7189 if (result != ISC_R_SUCCESS)
7193 if (result != ISC_R_NOMORE)
7196 return (ISC_R_SUCCESS);
7203 stub_callback(isc_task_t *task, isc_event_t *event) {
7204 const char me[] = "stub_callback";
7205 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7206 dns_stub_t *stub = NULL;
7207 dns_message_t *msg = NULL;
7208 dns_zone_t *zone = NULL;
7209 char master[ISC_SOCKADDR_FORMATSIZE];
7210 char source[ISC_SOCKADDR_FORMATSIZE];
7211 isc_uint32_t nscnt, cnamecnt;
7212 isc_result_t result;
7214 isc_boolean_t exiting = ISC_FALSE;
7218 stub = revent->ev_arg;
7219 INSIST(DNS_STUB_VALID(stub));
7229 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7230 zone_debuglog(zone, me, 1, "exiting");
7235 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7236 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7238 if (revent->result != ISC_R_SUCCESS) {
7239 if (revent->result == ISC_R_TIMEDOUT &&
7240 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7242 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7244 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7245 "refreshing stub: timeout retrying "
7246 " without EDNS master %s (source %s)",
7250 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
7251 &zone->sourceaddr, &now);
7252 dns_zone_log(zone, ISC_LOG_INFO,
7253 "could not refresh stub from master %s"
7254 " (source %s): %s", master, source,
7255 dns_result_totext(revent->result));
7259 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7260 if (result != ISC_R_SUCCESS)
7263 result = dns_request_getresponse(revent->request, msg, 0);
7264 if (result != ISC_R_SUCCESS)
7270 if (msg->rcode != dns_rcode_noerror) {
7274 isc_buffer_init(&rb, rcode, sizeof(rcode));
7275 (void)dns_rcode_totext(msg->rcode, &rb);
7277 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7278 (msg->rcode == dns_rcode_servfail ||
7279 msg->rcode == dns_rcode_notimp ||
7280 msg->rcode == dns_rcode_formerr)) {
7281 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7282 "refreshing stub: rcode (%.*s) retrying "
7283 "without EDNS master %s (source %s)",
7284 (int)rb.used, rcode, master, source);
7286 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7291 dns_zone_log(zone, ISC_LOG_INFO,
7293 "unexpected rcode (%.*s) from %s (source %s)",
7294 (int)rb.used, rcode, master, source);
7299 * We need complete messages.
7301 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7302 if (dns_request_usedtcp(revent->request)) {
7303 dns_zone_log(zone, ISC_LOG_INFO,
7304 "refreshing stub: truncated TCP "
7305 "response from master %s (source %s)",
7310 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7316 * If non-auth log and next master.
7318 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7319 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
7320 "non-authoritative answer from "
7321 "master %s (source %s)", master, source);
7328 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7329 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
7331 if (cnamecnt != 0) {
7332 dns_zone_log(zone, ISC_LOG_INFO,
7333 "refreshing stub: unexpected CNAME response "
7334 "from master %s (source %s)", master, source);
7339 dns_zone_log(zone, ISC_LOG_INFO,
7340 "refreshing stub: no NS records in response "
7341 "from master %s (source %s)", master, source);
7348 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
7349 if (result != ISC_R_SUCCESS) {
7350 dns_zone_log(zone, ISC_LOG_INFO,
7351 "refreshing stub: unable to save NS records "
7352 "from master %s (source %s)", master, source);
7359 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
7360 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
7361 if (zone->db == NULL)
7362 zone_attachdb(zone, stub->db);
7363 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
7364 dns_db_detach(&stub->db);
7366 if (zone->masterfile != NULL) {
7367 dns_zone_dump(zone);
7368 TIME_NOW(&zone->loadtime);
7371 dns_message_destroy(&msg);
7372 isc_event_free(&event);
7374 dns_request_destroy(&zone->request);
7375 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7376 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7377 isc_interval_set(&i, zone->expire, 0);
7378 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7379 zone_settimer(zone, &now);
7384 if (stub->version != NULL)
7385 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
7386 if (stub->db != NULL)
7387 dns_db_detach(&stub->db);
7389 dns_message_destroy(&msg);
7390 isc_event_free(&event);
7392 dns_request_destroy(&zone->request);
7394 * Skip to next failed / untried master.
7398 } while (zone->curmaster < zone->masterscnt &&
7399 zone->mastersok[zone->curmaster]);
7400 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7401 if (exiting || zone->curmaster >= zone->masterscnt) {
7402 isc_boolean_t done = ISC_TRUE;
7404 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7405 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7407 * Did we get a good answer from all the masters?
7409 for (j = 0; j < zone->masterscnt; j++)
7410 if (zone->mastersok[j] == ISC_FALSE) {
7417 zone->curmaster = 0;
7419 * Find the next failed master.
7421 while (zone->curmaster < zone->masterscnt &&
7422 zone->mastersok[zone->curmaster])
7424 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7426 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7428 zone_settimer(zone, &now);
7433 queue_soa_query(zone);
7439 dns_message_destroy(&msg);
7440 isc_event_free(&event);
7442 dns_request_destroy(&zone->request);
7444 ns_query(zone, NULL, stub);
7449 dns_zone_idetach(&stub->zone);
7450 INSIST(stub->db == NULL);
7451 INSIST(stub->version == NULL);
7452 isc_mem_put(stub->mctx, stub, sizeof(*stub));
7455 INSIST(event == NULL);
7460 * An SOA query has finished (successfully or not).
7463 refresh_callback(isc_task_t *task, isc_event_t *event) {
7464 const char me[] = "refresh_callback";
7465 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7467 dns_message_t *msg = NULL;
7468 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
7470 char master[ISC_SOCKADDR_FORMATSIZE];
7471 char source[ISC_SOCKADDR_FORMATSIZE];
7472 dns_rdataset_t *rdataset = NULL;
7473 dns_rdata_t rdata = DNS_RDATA_INIT;
7474 dns_rdata_soa_t soa;
7475 isc_result_t result;
7476 isc_uint32_t serial, oldserial;
7479 zone = revent->ev_arg;
7480 INSIST(DNS_ZONE_VALID(zone));
7487 * if timeout log and next master;
7490 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7491 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7495 if (revent->result != ISC_R_SUCCESS) {
7496 if (revent->result == ISC_R_TIMEDOUT &&
7497 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7499 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7501 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7502 "refresh: timeout retrying without EDNS "
7503 "master %s (source %s)", master, source);
7506 if (revent->result == ISC_R_TIMEDOUT &&
7507 !dns_request_usedtcp(revent->request)) {
7508 dns_zone_log(zone, ISC_LOG_INFO,
7509 "refresh: retry limit for "
7510 "master %s exceeded (source %s)",
7512 /* Try with slave with TCP. */
7513 if (zone->type == dns_zone_slave &&
7514 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
7515 if (!dns_zonemgr_unreachable(zone->zmgr,
7520 DNS_ZONE_SETFLAG(zone,
7521 DNS_ZONEFLG_SOABEFOREAXFR);
7525 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7526 "refresh: skipped tcp fallback"
7527 "as master %s (source %s) is "
7528 "unreachable (cached)",
7532 dns_zone_log(zone, ISC_LOG_INFO,
7533 "refresh: failure trying master "
7534 "%s (source %s): %s", master, source,
7535 dns_result_totext(revent->result));
7539 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7540 if (result != ISC_R_SUCCESS)
7542 result = dns_request_getresponse(revent->request, msg, 0);
7543 if (result != ISC_R_SUCCESS) {
7544 dns_zone_log(zone, ISC_LOG_INFO,
7545 "refresh: failure trying master "
7546 "%s (source %s): %s", master, source,
7547 dns_result_totext(result));
7554 if (msg->rcode != dns_rcode_noerror) {
7558 isc_buffer_init(&rb, rcode, sizeof(rcode));
7559 (void)dns_rcode_totext(msg->rcode, &rb);
7561 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7562 (msg->rcode == dns_rcode_servfail ||
7563 msg->rcode == dns_rcode_notimp ||
7564 msg->rcode == dns_rcode_formerr)) {
7565 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7566 "refresh: rcode (%.*s) retrying without "
7567 "EDNS master %s (source %s)",
7568 (int)rb.used, rcode, master, source);
7570 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7574 dns_zone_log(zone, ISC_LOG_INFO,
7575 "refresh: unexpected rcode (%.*s) from "
7576 "master %s (source %s)", (int)rb.used, rcode,
7579 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
7581 if (msg->rcode == dns_rcode_refused &&
7582 zone->type == dns_zone_slave)
7588 * If truncated punt to zone transfer which will query again.
7590 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7591 if (zone->type == dns_zone_slave) {
7592 dns_zone_log(zone, ISC_LOG_INFO,
7593 "refresh: truncated UDP answer, "
7594 "initiating TCP zone xfer "
7595 "for master %s (source %s)",
7598 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
7602 INSIST(zone->type == dns_zone_stub);
7603 if (dns_request_usedtcp(revent->request)) {
7604 dns_zone_log(zone, ISC_LOG_INFO,
7605 "refresh: truncated TCP response "
7606 "from master %s (source %s)",
7611 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7618 * if non-auth log and next master;
7620 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7621 dns_zone_log(zone, ISC_LOG_INFO,
7622 "refresh: non-authoritative answer from "
7623 "master %s (source %s)", master, source);
7627 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7628 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
7629 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
7630 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
7634 * There should not be a CNAME record at top of zone.
7636 if (cnamecnt != 0) {
7637 dns_zone_log(zone, ISC_LOG_INFO,
7638 "refresh: CNAME at top of zone "
7639 "in master %s (source %s)", master, source);
7644 * if referral log and next master;
7646 if (soacnt == 0 && soacount == 0 && nscount != 0) {
7647 dns_zone_log(zone, ISC_LOG_INFO,
7648 "refresh: referral response "
7649 "from master %s (source %s)", master, source);
7654 * if nodata log and next master;
7656 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
7657 dns_zone_log(zone, ISC_LOG_INFO,
7658 "refresh: NODATA response "
7659 "from master %s (source %s)", master, source);
7664 * Only one soa at top of zone.
7667 dns_zone_log(zone, ISC_LOG_INFO,
7668 "refresh: answer SOA count (%d) != 1 "
7669 "from master %s (source %s)",
7670 soacnt, master, source);
7677 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
7678 dns_rdatatype_soa, dns_rdatatype_none,
7680 if (result != ISC_R_SUCCESS) {
7681 dns_zone_log(zone, ISC_LOG_INFO,
7682 "refresh: unable to get SOA record "
7683 "from master %s (source %s)", master, source);
7687 result = dns_rdataset_first(rdataset);
7688 if (result != ISC_R_SUCCESS) {
7689 dns_zone_log(zone, ISC_LOG_INFO,
7690 "refresh: dns_rdataset_first() failed");
7694 dns_rdataset_current(rdataset, &rdata);
7695 result = dns_rdata_tostruct(&rdata, &soa, NULL);
7696 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7698 serial = soa.serial;
7699 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
7700 result = dns_zone_getserial2(zone, &oldserial);
7701 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7702 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
7705 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
7707 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
7708 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
7709 isc_serial_gt(serial, oldserial)) {
7710 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
7711 &zone->sourceaddr, &now)) {
7712 dns_zone_log(zone, ISC_LOG_INFO,
7713 "refresh: skipping %s as master %s "
7714 "(source %s) is unreachable (cached)",
7715 zone->type == dns_zone_slave ?
7716 "zone transfer" : "NS query",
7721 isc_event_free(&event);
7723 dns_request_destroy(&zone->request);
7725 if (zone->type == dns_zone_slave) {
7728 INSIST(zone->type == dns_zone_stub);
7729 ns_query(zone, rdataset, NULL);
7732 dns_message_destroy(&msg);
7733 } else if (isc_serial_eq(soa.serial, oldserial)) {
7734 if (zone->masterfile != NULL) {
7735 result = ISC_R_FAILURE;
7736 if (zone->journal != NULL)
7737 result = isc_file_settime(zone->journal, &now);
7738 if (result == ISC_R_SUCCESS &&
7739 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
7740 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
7741 result = isc_file_settime(zone->masterfile,
7743 } else if (result != ISC_R_SUCCESS)
7744 result = isc_file_settime(zone->masterfile,
7746 /* Someone removed the file from underneath us! */
7747 if (result == ISC_R_FILENOTFOUND) {
7749 zone_needdump(zone, DNS_DUMP_DELAY);
7751 } else if (result != ISC_R_SUCCESS)
7752 dns_zone_log(zone, ISC_LOG_ERROR,
7753 "refresh: could not set file "
7754 "modification time of '%s': %s",
7756 dns_result_totext(result));
7758 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7759 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7760 zone->mastersok[zone->curmaster] = ISC_TRUE;
7763 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
7764 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
7765 "received from master %s < ours (%u)",
7766 soa.serial, master, oldserial);
7768 zone_debuglog(zone, me, 1, "ahead");
7769 zone->mastersok[zone->curmaster] = ISC_TRUE;
7773 dns_message_destroy(&msg);
7778 dns_message_destroy(&msg);
7779 isc_event_free(&event);
7781 dns_request_destroy(&zone->request);
7783 * Skip to next failed / untried master.
7787 } while (zone->curmaster < zone->masterscnt &&
7788 zone->mastersok[zone->curmaster]);
7789 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7790 if (zone->curmaster >= zone->masterscnt) {
7791 isc_boolean_t done = ISC_TRUE;
7792 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7793 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7795 * Did we get a good answer from all the masters?
7797 for (j = 0; j < zone->masterscnt; j++)
7798 if (zone->mastersok[j] == ISC_FALSE) {
7805 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7806 zone->curmaster = 0;
7808 * Find the next failed master.
7810 while (zone->curmaster < zone->masterscnt &&
7811 zone->mastersok[zone->curmaster])
7815 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7816 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
7817 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
7818 zone->refreshtime = now;
7820 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7821 zone_settimer(zone, &now);
7827 queue_soa_query(zone);
7833 dns_message_destroy(&msg);
7834 isc_event_free(&event);
7836 dns_request_destroy(&zone->request);
7837 queue_soa_query(zone);
7841 dns_zone_idetach(&zone);
7846 queue_soa_query(dns_zone_t *zone) {
7847 const char me[] = "queue_soa_query";
7849 dns_zone_t *dummy = NULL;
7850 isc_result_t result;
7856 REQUIRE(LOCKED_ZONE(zone));
7858 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7859 cancel_refresh(zone);
7863 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
7864 soa_query, zone, sizeof(isc_event_t));
7866 cancel_refresh(zone);
7871 * Attach so that we won't clean up
7872 * until the event is delivered.
7874 zone_iattach(zone, &dummy);
7877 e->ev_sender = NULL;
7878 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
7879 if (result != ISC_R_SUCCESS) {
7880 zone_idetach(&dummy);
7882 cancel_refresh(zone);
7886 static inline isc_result_t
7887 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
7888 dns_message_t **messagep)
7890 dns_message_t *message = NULL;
7891 dns_name_t *qname = NULL;
7892 dns_rdataset_t *qrdataset = NULL;
7893 isc_result_t result;
7895 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
7897 if (result != ISC_R_SUCCESS)
7900 message->opcode = dns_opcode_query;
7901 message->rdclass = zone->rdclass;
7903 result = dns_message_gettempname(message, &qname);
7904 if (result != ISC_R_SUCCESS)
7907 result = dns_message_gettemprdataset(message, &qrdataset);
7908 if (result != ISC_R_SUCCESS)
7914 dns_name_init(qname, NULL);
7915 dns_name_clone(&zone->origin, qname);
7916 dns_rdataset_init(qrdataset);
7917 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
7918 ISC_LIST_APPEND(qname->list, qrdataset, link);
7919 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
7921 *messagep = message;
7922 return (ISC_R_SUCCESS);
7926 dns_message_puttempname(message, &qname);
7927 if (qrdataset != NULL)
7928 dns_message_puttemprdataset(message, &qrdataset);
7929 if (message != NULL)
7930 dns_message_destroy(&message);
7935 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
7936 dns_rdataset_t *rdataset = NULL;
7937 dns_rdatalist_t *rdatalist = NULL;
7938 dns_rdata_t *rdata = NULL;
7939 isc_result_t result;
7941 result = dns_message_gettemprdatalist(message, &rdatalist);
7942 if (result != ISC_R_SUCCESS)
7944 result = dns_message_gettemprdata(message, &rdata);
7945 if (result != ISC_R_SUCCESS)
7947 result = dns_message_gettemprdataset(message, &rdataset);
7948 if (result != ISC_R_SUCCESS)
7950 dns_rdataset_init(rdataset);
7952 rdatalist->type = dns_rdatatype_opt;
7953 rdatalist->covers = 0;
7956 * Set Maximum UDP buffer size.
7958 rdatalist->rdclass = udpsize;
7961 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
7965 /* Set EDNS options if applicable */
7967 unsigned char data[4];
7970 isc_buffer_init(&buf, data, sizeof(data));
7971 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
7972 isc_buffer_putuint16(&buf, 0);
7974 rdata->length = sizeof(data);
7980 rdata->rdclass = rdatalist->rdclass;
7981 rdata->type = rdatalist->type;
7984 ISC_LIST_INIT(rdatalist->rdata);
7985 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
7986 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
7989 return (dns_message_setopt(message, rdataset));
7992 if (rdatalist != NULL)
7993 dns_message_puttemprdatalist(message, &rdatalist);
7994 if (rdataset != NULL)
7995 dns_message_puttemprdataset(message, &rdataset);
7997 dns_message_puttemprdata(message, &rdata);
8003 soa_query(isc_task_t *task, isc_event_t *event) {
8004 const char me[] = "soa_query";
8005 isc_result_t result = ISC_R_FAILURE;
8006 dns_message_t *message = NULL;
8007 dns_zone_t *zone = event->ev_arg;
8008 dns_zone_t *dummy = NULL;
8009 isc_netaddr_t masterip;
8010 dns_tsigkey_t *key = NULL;
8011 isc_uint32_t options;
8012 isc_boolean_t cancel = ISC_TRUE;
8014 isc_boolean_t have_xfrsource, reqnsid;
8015 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8017 REQUIRE(DNS_ZONE_VALID(zone));
8024 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
8025 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
8026 zone->view->requestmgr == NULL) {
8027 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8033 * XXX Optimisation: Create message when zone is setup and reuse.
8035 result = create_query(zone, dns_rdatatype_soa, &message);
8036 if (result != ISC_R_SUCCESS)
8040 INSIST(zone->masterscnt > 0);
8041 INSIST(zone->curmaster < zone->masterscnt);
8043 zone->masteraddr = zone->masters[zone->curmaster];
8045 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8047 * First, look for a tsig key in the master statement, then
8048 * try for a server key.
8050 if ((zone->masterkeynames != NULL) &&
8051 (zone->masterkeynames[zone->curmaster] != NULL)) {
8052 dns_view_t *view = dns_zone_getview(zone);
8053 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8054 result = dns_view_gettsig(view, keyname, &key);
8055 if (result != ISC_R_SUCCESS) {
8056 char namebuf[DNS_NAME_FORMATSIZE];
8057 dns_name_format(keyname, namebuf, sizeof(namebuf));
8058 dns_zone_log(zone, ISC_LOG_ERROR,
8059 "unable to find key: %s", namebuf);
8064 result = dns_view_getpeertsig(zone->view, &masterip, &key);
8065 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
8066 char addrbuf[ISC_NETADDR_FORMATSIZE];
8067 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
8068 dns_zone_log(zone, ISC_LOG_ERROR,
8069 "unable to find TSIG key for %s", addrbuf);
8074 have_xfrsource = ISC_FALSE;
8075 reqnsid = zone->view->requestnsid;
8076 if (zone->view->peers != NULL) {
8077 dns_peer_t *peer = NULL;
8079 result = dns_peerlist_peerbyaddr(zone->view->peers,
8081 if (result == ISC_R_SUCCESS) {
8082 result = dns_peer_getsupportedns(peer, &edns);
8083 if (result == ISC_R_SUCCESS && !edns)
8084 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8085 result = dns_peer_gettransfersource(peer,
8087 if (result == ISC_R_SUCCESS)
8088 have_xfrsource = ISC_TRUE;
8089 if (zone->view->resolver != NULL)
8091 dns_resolver_getudpsize(zone->view->resolver);
8092 (void)dns_peer_getudpsize(peer, &udpsize);
8093 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8097 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8099 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8100 if (isc_sockaddr_equal(&zone->altxfrsource4,
8103 zone->sourceaddr = zone->altxfrsource4;
8104 } else if (!have_xfrsource)
8105 zone->sourceaddr = zone->xfrsource4;
8108 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8109 if (isc_sockaddr_equal(&zone->altxfrsource6,
8112 zone->sourceaddr = zone->altxfrsource6;
8113 } else if (!have_xfrsource)
8114 zone->sourceaddr = zone->xfrsource6;
8117 result = ISC_R_NOTIMPLEMENTED;
8121 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
8122 DNS_REQUESTOPT_TCP : 0;
8124 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8125 result = add_opt(message, udpsize, reqnsid);
8126 if (result != ISC_R_SUCCESS)
8127 zone_debuglog(zone, me, 1,
8128 "unable to add opt record: %s",
8129 dns_result_totext(result));
8132 zone_iattach(zone, &dummy);
8134 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8136 result = dns_request_createvia2(zone->view->requestmgr, message,
8137 &zone->sourceaddr, &zone->masteraddr,
8138 options, key, timeout * 3, timeout,
8139 zone->task, refresh_callback, zone,
8141 if (result != ISC_R_SUCCESS) {
8142 zone_idetach(&dummy);
8143 zone_debuglog(zone, me, 1,
8144 "dns_request_createvia2() failed: %s",
8145 dns_result_totext(result));
8148 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
8149 inc_stats(zone, dns_zonestatscounter_soaoutv4);
8151 inc_stats(zone, dns_zonestatscounter_soaoutv6);
8157 dns_tsigkey_detach(&key);
8158 if (result != ISC_R_SUCCESS)
8159 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8160 if (message != NULL)
8161 dns_message_destroy(&message);
8163 cancel_refresh(zone);
8164 isc_event_free(&event);
8166 dns_zone_idetach(&zone);
8171 dns_tsigkey_detach(&key);
8173 * Skip to next failed / untried master.
8177 } while (zone->curmaster < zone->masterscnt &&
8178 zone->mastersok[zone->curmaster]);
8179 if (zone->curmaster < zone->masterscnt)
8181 zone->curmaster = 0;
8186 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
8187 const char me[] = "ns_query";
8188 isc_result_t result;
8189 dns_message_t *message = NULL;
8190 isc_netaddr_t masterip;
8191 dns_tsigkey_t *key = NULL;
8192 dns_dbnode_t *node = NULL;
8194 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
8195 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8197 REQUIRE(DNS_ZONE_VALID(zone));
8198 REQUIRE((soardataset != NULL && stub == NULL) ||
8199 (soardataset == NULL && stub != NULL));
8200 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
8206 stub = isc_mem_get(zone->mctx, sizeof(*stub));
8209 stub->magic = STUB_MAGIC;
8210 stub->mctx = zone->mctx;
8213 stub->version = NULL;
8216 * Attach so that the zone won't disappear from under us.
8218 zone_iattach(zone, &stub->zone);
8221 * If a db exists we will update it, otherwise we create a
8222 * new one and attach it to the zone once we have the NS
8225 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8226 if (zone->db != NULL) {
8227 dns_db_attach(zone->db, &stub->db);
8228 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8230 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8232 INSIST(zone->db_argc >= 1);
8233 result = dns_db_create(zone->mctx, zone->db_argv[0],
8234 &zone->origin, dns_dbtype_stub,
8239 if (result != ISC_R_SUCCESS) {
8240 dns_zone_log(zone, ISC_LOG_ERROR,
8244 dns_result_totext(result));
8247 dns_db_settask(stub->db, zone->task);
8250 dns_db_newversion(stub->db, &stub->version);
8253 * Update SOA record.
8255 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
8257 if (result != ISC_R_SUCCESS) {
8258 dns_zone_log(zone, ISC_LOG_INFO,
8260 "dns_db_findnode() failed: %s",
8261 dns_result_totext(result));
8265 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
8266 soardataset, 0, NULL);
8267 dns_db_detachnode(stub->db, &node);
8268 if (result != ISC_R_SUCCESS) {
8269 dns_zone_log(zone, ISC_LOG_INFO,
8271 "dns_db_addrdataset() failed: %s",
8272 dns_result_totext(result));
8278 * XXX Optimisation: Create message when zone is setup and reuse.
8280 result = create_query(zone, dns_rdatatype_ns, &message);
8282 INSIST(zone->masterscnt > 0);
8283 INSIST(zone->curmaster < zone->masterscnt);
8284 zone->masteraddr = zone->masters[zone->curmaster];
8286 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8288 * First, look for a tsig key in the master statement, then
8289 * try for a server key.
8291 if ((zone->masterkeynames != NULL) &&
8292 (zone->masterkeynames[zone->curmaster] != NULL)) {
8293 dns_view_t *view = dns_zone_getview(zone);
8294 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8295 result = dns_view_gettsig(view, keyname, &key);
8296 if (result != ISC_R_SUCCESS) {
8297 char namebuf[DNS_NAME_FORMATSIZE];
8298 dns_name_format(keyname, namebuf, sizeof(namebuf));
8299 dns_zone_log(zone, ISC_LOG_ERROR,
8300 "unable to find key: %s", namebuf);
8304 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
8306 reqnsid = zone->view->requestnsid;
8307 if (zone->view->peers != NULL) {
8308 dns_peer_t *peer = NULL;
8310 result = dns_peerlist_peerbyaddr(zone->view->peers,
8312 if (result == ISC_R_SUCCESS) {
8313 result = dns_peer_getsupportedns(peer, &edns);
8314 if (result == ISC_R_SUCCESS && !edns)
8315 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8316 result = dns_peer_gettransfersource(peer,
8318 if (result == ISC_R_SUCCESS)
8319 have_xfrsource = ISC_TRUE;
8320 if (zone->view->resolver != NULL)
8322 dns_resolver_getudpsize(zone->view->resolver);
8323 (void)dns_peer_getudpsize(peer, &udpsize);
8324 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8328 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8329 result = add_opt(message, udpsize, reqnsid);
8330 if (result != ISC_R_SUCCESS)
8331 zone_debuglog(zone, me, 1,
8332 "unable to add opt record: %s",
8333 dns_result_totext(result));
8337 * Always use TCP so that we shouldn't truncate in additional section.
8339 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8341 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8342 zone->sourceaddr = zone->altxfrsource4;
8343 else if (!have_xfrsource)
8344 zone->sourceaddr = zone->xfrsource4;
8347 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8348 zone->sourceaddr = zone->altxfrsource6;
8349 else if (!have_xfrsource)
8350 zone->sourceaddr = zone->xfrsource6;
8353 result = ISC_R_NOTIMPLEMENTED;
8357 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8359 result = dns_request_createvia2(zone->view->requestmgr, message,
8360 &zone->sourceaddr, &zone->masteraddr,
8361 DNS_REQUESTOPT_TCP, key, timeout * 3,
8362 timeout, zone->task, stub_callback,
8363 stub, &zone->request);
8364 if (result != ISC_R_SUCCESS) {
8365 zone_debuglog(zone, me, 1,
8366 "dns_request_createvia() failed: %s",
8367 dns_result_totext(result));
8370 dns_message_destroy(&message);
8374 cancel_refresh(zone);
8377 if (stub->version != NULL)
8378 dns_db_closeversion(stub->db, &stub->version,
8380 if (stub->db != NULL)
8381 dns_db_detach(&stub->db);
8382 if (stub->zone != NULL)
8383 zone_idetach(&stub->zone);
8384 isc_mem_put(stub->mctx, stub, sizeof(*stub));
8386 if (message != NULL)
8387 dns_message_destroy(&message);
8390 dns_tsigkey_detach(&key);
8396 * Handle the control event. Note that although this event causes the zone
8397 * to shut down, it is not a shutdown event in the sense of the task library.
8400 zone_shutdown(isc_task_t *task, isc_event_t *event) {
8401 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
8402 isc_boolean_t free_needed, linked = ISC_FALSE;
8405 REQUIRE(DNS_ZONE_VALID(zone));
8406 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
8407 INSIST(isc_refcount_current(&zone->erefs) == 0);
8408 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
8411 * Stop things being restarted after we cancel them below.
8414 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
8418 * If we were waiting for xfrin quota, step out of
8420 * If there's no zone manager, we can't be waiting for the
8423 if (zone->zmgr != NULL) {
8424 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8425 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
8426 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
8429 zone->statelist = NULL;
8431 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8435 * In task context, no locking required. See zone_xfrdone().
8437 if (zone->xfr != NULL)
8438 dns_xfrin_shutdown(zone->xfr);
8442 INSIST(zone->irefs > 0);
8445 if (zone->request != NULL) {
8446 dns_request_cancel(zone->request);
8449 if (zone->readio != NULL)
8450 zonemgr_cancelio(zone->readio);
8452 if (zone->lctx != NULL)
8453 dns_loadctx_cancel(zone->lctx);
8455 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8456 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8457 if (zone->writeio != NULL)
8458 zonemgr_cancelio(zone->writeio);
8460 if (zone->dctx != NULL)
8461 dns_dumpctx_cancel(zone->dctx);
8464 notify_cancel(zone);
8466 if (zone->timer != NULL) {
8467 isc_timer_detach(&zone->timer);
8468 INSIST(zone->irefs > 0);
8472 if (zone->view != NULL)
8473 dns_view_weakdetach(&zone->view);
8476 * We have now canceled everything set the flag to allow exit_check()
8477 * to succeed. We must not unlock between setting this flag and
8478 * calling exit_check().
8480 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
8481 free_needed = exit_check(zone);
8488 zone_timer(isc_task_t *task, isc_event_t *event) {
8489 const char me[] = "zone_timer";
8490 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
8493 REQUIRE(DNS_ZONE_VALID(zone));
8497 zone_maintenance(zone);
8499 isc_event_free(&event);
8503 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
8504 const char me[] = "zone_settimer";
8506 isc_result_t result;
8508 REQUIRE(DNS_ZONE_VALID(zone));
8509 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8512 isc_time_settoepoch(&next);
8514 switch (zone->type) {
8515 case dns_zone_master:
8516 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8517 next = zone->notifytime;
8518 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8519 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8520 INSIST(!isc_time_isepoch(&zone->dumptime));
8521 if (isc_time_isepoch(&next) ||
8522 isc_time_compare(&zone->dumptime, &next) < 0)
8523 next = zone->dumptime;
8525 if (!isc_time_isepoch(&zone->resigntime)) {
8526 if (isc_time_isepoch(&next) ||
8527 isc_time_compare(&zone->resigntime, &next) < 0)
8528 next = zone->resigntime;
8530 if (!isc_time_isepoch(&zone->keywarntime)) {
8531 if (isc_time_isepoch(&next) ||
8532 isc_time_compare(&zone->keywarntime, &next) < 0)
8533 next = zone->keywarntime;
8535 if (!isc_time_isepoch(&zone->signingtime)) {
8536 if (isc_time_isepoch(&next) ||
8537 isc_time_compare(&zone->signingtime, &next) < 0)
8538 next = zone->signingtime;
8540 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
8541 if (isc_time_isepoch(&next) ||
8542 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
8543 next = zone->nsec3chaintime;
8547 case dns_zone_slave:
8548 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8549 next = zone->notifytime;
8553 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
8554 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
8555 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
8556 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
8557 INSIST(!isc_time_isepoch(&zone->refreshtime));
8558 if (isc_time_isepoch(&next) ||
8559 isc_time_compare(&zone->refreshtime, &next) < 0)
8560 next = zone->refreshtime;
8562 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8563 INSIST(!isc_time_isepoch(&zone->expiretime));
8564 if (isc_time_isepoch(&next) ||
8565 isc_time_compare(&zone->expiretime, &next) < 0)
8566 next = zone->expiretime;
8568 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8569 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8570 INSIST(!isc_time_isepoch(&zone->dumptime));
8571 if (isc_time_isepoch(&next) ||
8572 isc_time_compare(&zone->dumptime, &next) < 0)
8573 next = zone->dumptime;
8581 if (isc_time_isepoch(&next)) {
8582 zone_debuglog(zone, me, 10, "settimer inactive");
8583 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
8584 NULL, NULL, ISC_TRUE);
8585 if (result != ISC_R_SUCCESS)
8586 dns_zone_log(zone, ISC_LOG_ERROR,
8587 "could not deactivate zone timer: %s",
8588 isc_result_totext(result));
8590 if (isc_time_compare(&next, now) <= 0)
8592 result = isc_timer_reset(zone->timer, isc_timertype_once,
8593 &next, NULL, ISC_TRUE);
8594 if (result != ISC_R_SUCCESS)
8595 dns_zone_log(zone, ISC_LOG_ERROR,
8596 "could not reset zone timer: %s",
8597 isc_result_totext(result));
8602 cancel_refresh(dns_zone_t *zone) {
8603 const char me[] = "cancel_refresh";
8607 * 'zone' locked by caller.
8610 REQUIRE(DNS_ZONE_VALID(zone));
8611 REQUIRE(LOCKED_ZONE(zone));
8615 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8617 zone_settimer(zone, &now);
8621 notify_createmessage(dns_zone_t *zone, unsigned int flags,
8622 dns_message_t **messagep)
8624 dns_db_t *zonedb = NULL;
8625 dns_dbnode_t *node = NULL;
8626 dns_dbversion_t *version = NULL;
8627 dns_message_t *message = NULL;
8628 dns_rdataset_t rdataset;
8629 dns_rdata_t rdata = DNS_RDATA_INIT;
8631 dns_name_t *tempname = NULL;
8632 dns_rdata_t *temprdata = NULL;
8633 dns_rdatalist_t *temprdatalist = NULL;
8634 dns_rdataset_t *temprdataset = NULL;
8636 isc_result_t result;
8638 isc_buffer_t *b = NULL;
8640 REQUIRE(DNS_ZONE_VALID(zone));
8641 REQUIRE(messagep != NULL && *messagep == NULL);
8643 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
8645 if (result != ISC_R_SUCCESS)
8648 message->opcode = dns_opcode_notify;
8649 message->flags |= DNS_MESSAGEFLAG_AA;
8650 message->rdclass = zone->rdclass;
8652 result = dns_message_gettempname(message, &tempname);
8653 if (result != ISC_R_SUCCESS)
8656 result = dns_message_gettemprdataset(message, &temprdataset);
8657 if (result != ISC_R_SUCCESS)
8663 dns_name_init(tempname, NULL);
8664 dns_name_clone(&zone->origin, tempname);
8665 dns_rdataset_init(temprdataset);
8666 dns_rdataset_makequestion(temprdataset, zone->rdclass,
8668 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8669 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
8671 temprdataset = NULL;
8673 if ((flags & DNS_NOTIFY_NOSOA) != 0)
8676 result = dns_message_gettempname(message, &tempname);
8677 if (result != ISC_R_SUCCESS)
8679 result = dns_message_gettemprdata(message, &temprdata);
8680 if (result != ISC_R_SUCCESS)
8682 result = dns_message_gettemprdataset(message, &temprdataset);
8683 if (result != ISC_R_SUCCESS)
8685 result = dns_message_gettemprdatalist(message, &temprdatalist);
8686 if (result != ISC_R_SUCCESS)
8689 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8690 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
8691 dns_db_attach(zone->db, &zonedb);
8692 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8694 dns_name_init(tempname, NULL);
8695 dns_name_clone(&zone->origin, tempname);
8696 dns_db_currentversion(zonedb, &version);
8697 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
8698 if (result != ISC_R_SUCCESS)
8701 dns_rdataset_init(&rdataset);
8702 result = dns_db_findrdataset(zonedb, node, version,
8704 dns_rdatatype_none, 0, &rdataset,
8706 if (result != ISC_R_SUCCESS)
8708 result = dns_rdataset_first(&rdataset);
8709 if (result != ISC_R_SUCCESS)
8711 dns_rdataset_current(&rdataset, &rdata);
8712 dns_rdata_toregion(&rdata, &r);
8713 result = isc_buffer_allocate(zone->mctx, &b, r.length);
8714 if (result != ISC_R_SUCCESS)
8716 isc_buffer_putmem(b, r.base, r.length);
8717 isc_buffer_usedregion(b, &r);
8718 dns_rdata_init(temprdata);
8719 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
8720 dns_message_takebuffer(message, &b);
8721 result = dns_rdataset_next(&rdataset);
8722 dns_rdataset_disassociate(&rdataset);
8723 if (result != ISC_R_NOMORE)
8725 temprdatalist->rdclass = rdata.rdclass;
8726 temprdatalist->type = rdata.type;
8727 temprdatalist->covers = 0;
8728 temprdatalist->ttl = rdataset.ttl;
8729 ISC_LIST_INIT(temprdatalist->rdata);
8730 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
8732 dns_rdataset_init(temprdataset);
8733 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
8734 if (result != ISC_R_SUCCESS)
8737 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8738 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
8739 temprdatalist = NULL;
8740 temprdataset = NULL;
8746 dns_db_detachnode(zonedb, &node);
8747 if (version != NULL)
8748 dns_db_closeversion(zonedb, &version, ISC_FALSE);
8750 dns_db_detach(&zonedb);
8751 if (tempname != NULL)
8752 dns_message_puttempname(message, &tempname);
8753 if (temprdata != NULL)
8754 dns_message_puttemprdata(message, &temprdata);
8755 if (temprdataset != NULL)
8756 dns_message_puttemprdataset(message, &temprdataset);
8757 if (temprdatalist != NULL)
8758 dns_message_puttemprdatalist(message, &temprdatalist);
8761 *messagep = message;
8762 return (ISC_R_SUCCESS);
8765 if (tempname != NULL)
8766 dns_message_puttempname(message, &tempname);
8767 if (temprdataset != NULL)
8768 dns_message_puttemprdataset(message, &temprdataset);
8769 dns_message_destroy(&message);
8774 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
8778 dns_rdata_soa_t soa;
8779 dns_rdataset_t *rdataset = NULL;
8780 dns_rdata_t rdata = DNS_RDATA_INIT;
8781 isc_result_t result;
8782 char fromtext[ISC_SOCKADDR_FORMATSIZE];
8784 isc_netaddr_t netaddr;
8786 REQUIRE(DNS_ZONE_VALID(zone));
8789 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
8793 * Check that 'from' is a valid notify source, (zone->masters).
8794 * Return DNS_R_REFUSED if not.
8796 * If the notify message contains a serial number check it
8797 * against the zones serial and return if <= current serial
8799 * If a refresh check is progress, if so just record the
8800 * fact we received a NOTIFY and from where and return.
8801 * We will perform a new refresh check when the current one
8802 * completes. Return ISC_R_SUCCESS.
8804 * Otherwise initiate a refresh check using 'from' as the
8805 * first address to check. Return ISC_R_SUCCESS.
8808 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
8811 * We only handle NOTIFY (SOA) at the present.
8814 if (isc_sockaddr_pf(from) == PF_INET)
8815 inc_stats(zone, dns_zonestatscounter_notifyinv4);
8817 inc_stats(zone, dns_zonestatscounter_notifyinv6);
8818 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
8819 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
8820 dns_rdatatype_soa, dns_rdatatype_none,
8821 NULL, NULL) != ISC_R_SUCCESS) {
8823 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
8824 dns_zone_log(zone, ISC_LOG_NOTICE,
8826 "question section from: %s", fromtext);
8827 return (DNS_R_FORMERR);
8829 dns_zone_log(zone, ISC_LOG_NOTICE,
8830 "NOTIFY zone does not match");
8831 return (DNS_R_NOTIMP);
8835 * If we are a master zone just succeed.
8837 if (zone->type == dns_zone_master) {
8839 return (ISC_R_SUCCESS);
8842 isc_netaddr_fromsockaddr(&netaddr, from);
8843 for (i = 0; i < zone->masterscnt; i++) {
8844 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
8846 if (zone->view->aclenv.match_mapped &&
8847 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
8848 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
8849 isc_netaddr_t na1, na2;
8850 isc_netaddr_fromv4mapped(&na1, &netaddr);
8851 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
8852 if (isc_netaddr_equal(&na1, &na2))
8858 * Accept notify requests from non masters if they are on
8859 * 'zone->notify_acl'.
8861 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
8862 dns_acl_match(&netaddr, NULL, zone->notify_acl,
8863 &zone->view->aclenv,
8864 &match, NULL) == ISC_R_SUCCESS &&
8867 /* Accept notify. */
8868 } else if (i >= zone->masterscnt) {
8870 dns_zone_log(zone, ISC_LOG_INFO,
8871 "refused notify from non-master: %s", fromtext);
8872 inc_stats(zone, dns_zonestatscounter_notifyrej);
8873 return (DNS_R_REFUSED);
8877 * If the zone is loaded and there are answers check the serial
8878 * to see if we need to do a refresh. Do not worry about this
8879 * check if we are a dialup zone as we use the notify request
8880 * to trigger a refresh check.
8882 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
8883 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8884 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
8885 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
8888 dns_rdatatype_none, NULL,
8890 if (result == ISC_R_SUCCESS)
8891 result = dns_rdataset_first(rdataset);
8892 if (result == ISC_R_SUCCESS) {
8893 isc_uint32_t serial = 0, oldserial;
8895 dns_rdataset_current(rdataset, &rdata);
8896 result = dns_rdata_tostruct(&rdata, &soa, NULL);
8897 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8898 serial = soa.serial;
8900 * The following should safely be performed without DB
8901 * lock and succeed in this context.
8903 result = zone_get_from_db(zone, zone->db, NULL, NULL,
8904 &oldserial, NULL, NULL, NULL,
8906 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8907 if (isc_serial_le(serial, oldserial)) {
8908 dns_zone_log(zone, ISC_LOG_INFO,
8910 "zone is up to date",
8913 return (ISC_R_SUCCESS);
8919 * If we got this far and there was a refresh in progress just
8920 * let it complete. Record where we got the notify from so we
8921 * can perform a refresh check when the current one completes
8923 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
8924 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
8925 zone->notifyfrom = *from;
8927 dns_zone_log(zone, ISC_LOG_INFO,
8928 "notify from %s: refresh in progress, "
8929 "refresh check queued",
8931 return (ISC_R_SUCCESS);
8933 zone->notifyfrom = *from;
8935 dns_zone_refresh(zone);
8936 return (ISC_R_SUCCESS);
8940 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
8942 REQUIRE(DNS_ZONE_VALID(zone));
8945 if (zone->notify_acl != NULL)
8946 dns_acl_detach(&zone->notify_acl);
8947 dns_acl_attach(acl, &zone->notify_acl);
8952 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
8954 REQUIRE(DNS_ZONE_VALID(zone));
8957 if (zone->query_acl != NULL)
8958 dns_acl_detach(&zone->query_acl);
8959 dns_acl_attach(acl, &zone->query_acl);
8964 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
8966 REQUIRE(DNS_ZONE_VALID(zone));
8969 if (zone->queryon_acl != NULL)
8970 dns_acl_detach(&zone->queryon_acl);
8971 dns_acl_attach(acl, &zone->queryon_acl);
8976 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
8978 REQUIRE(DNS_ZONE_VALID(zone));
8981 if (zone->update_acl != NULL)
8982 dns_acl_detach(&zone->update_acl);
8983 dns_acl_attach(acl, &zone->update_acl);
8988 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
8990 REQUIRE(DNS_ZONE_VALID(zone));
8993 if (zone->forward_acl != NULL)
8994 dns_acl_detach(&zone->forward_acl);
8995 dns_acl_attach(acl, &zone->forward_acl);
9000 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
9002 REQUIRE(DNS_ZONE_VALID(zone));
9005 if (zone->xfr_acl != NULL)
9006 dns_acl_detach(&zone->xfr_acl);
9007 dns_acl_attach(acl, &zone->xfr_acl);
9012 dns_zone_getnotifyacl(dns_zone_t *zone) {
9014 REQUIRE(DNS_ZONE_VALID(zone));
9016 return (zone->notify_acl);
9020 dns_zone_getqueryacl(dns_zone_t *zone) {
9022 REQUIRE(DNS_ZONE_VALID(zone));
9024 return (zone->query_acl);
9028 dns_zone_getqueryonacl(dns_zone_t *zone) {
9030 REQUIRE(DNS_ZONE_VALID(zone));
9032 return (zone->queryon_acl);
9036 dns_zone_getupdateacl(dns_zone_t *zone) {
9038 REQUIRE(DNS_ZONE_VALID(zone));
9040 return (zone->update_acl);
9044 dns_zone_getforwardacl(dns_zone_t *zone) {
9046 REQUIRE(DNS_ZONE_VALID(zone));
9048 return (zone->forward_acl);
9052 dns_zone_getxfracl(dns_zone_t *zone) {
9054 REQUIRE(DNS_ZONE_VALID(zone));
9056 return (zone->xfr_acl);
9060 dns_zone_clearupdateacl(dns_zone_t *zone) {
9062 REQUIRE(DNS_ZONE_VALID(zone));
9065 if (zone->update_acl != NULL)
9066 dns_acl_detach(&zone->update_acl);
9071 dns_zone_clearforwardacl(dns_zone_t *zone) {
9073 REQUIRE(DNS_ZONE_VALID(zone));
9076 if (zone->forward_acl != NULL)
9077 dns_acl_detach(&zone->forward_acl);
9082 dns_zone_clearnotifyacl(dns_zone_t *zone) {
9084 REQUIRE(DNS_ZONE_VALID(zone));
9087 if (zone->notify_acl != NULL)
9088 dns_acl_detach(&zone->notify_acl);
9093 dns_zone_clearqueryacl(dns_zone_t *zone) {
9095 REQUIRE(DNS_ZONE_VALID(zone));
9098 if (zone->query_acl != NULL)
9099 dns_acl_detach(&zone->query_acl);
9104 dns_zone_clearqueryonacl(dns_zone_t *zone) {
9106 REQUIRE(DNS_ZONE_VALID(zone));
9109 if (zone->queryon_acl != NULL)
9110 dns_acl_detach(&zone->queryon_acl);
9115 dns_zone_clearxfracl(dns_zone_t *zone) {
9117 REQUIRE(DNS_ZONE_VALID(zone));
9120 if (zone->xfr_acl != NULL)
9121 dns_acl_detach(&zone->xfr_acl);
9126 dns_zone_getupdatedisabled(dns_zone_t *zone) {
9127 REQUIRE(DNS_ZONE_VALID(zone));
9128 return (zone->update_disabled);
9133 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
9134 REQUIRE(DNS_ZONE_VALID(zone));
9135 zone->update_disabled = state;
9139 dns_zone_getzeronosoattl(dns_zone_t *zone) {
9140 REQUIRE(DNS_ZONE_VALID(zone));
9141 return (zone->zero_no_soa_ttl);
9146 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
9147 REQUIRE(DNS_ZONE_VALID(zone));
9148 zone->zero_no_soa_ttl = state;
9152 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
9154 REQUIRE(DNS_ZONE_VALID(zone));
9156 zone->check_names = severity;
9160 dns_zone_getchecknames(dns_zone_t *zone) {
9162 REQUIRE(DNS_ZONE_VALID(zone));
9164 return (zone->check_names);
9168 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
9170 REQUIRE(DNS_ZONE_VALID(zone));
9172 zone->journalsize = size;
9176 dns_zone_getjournalsize(dns_zone_t *zone) {
9178 REQUIRE(DNS_ZONE_VALID(zone));
9180 return (zone->journalsize);
9184 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
9185 isc_result_t result = ISC_R_FAILURE;
9186 isc_buffer_t buffer;
9188 REQUIRE(buf != NULL);
9189 REQUIRE(length > 1U);
9192 * Leave space for terminating '\0'.
9194 isc_buffer_init(&buffer, buf, length - 1);
9195 if (dns_name_dynamic(&zone->origin))
9196 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9197 if (result != ISC_R_SUCCESS &&
9198 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9199 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9201 if (isc_buffer_availablelength(&buffer) > 0)
9202 isc_buffer_putstr(&buffer, "/");
9203 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9205 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
9206 strcmp(zone->view->name, "_default") != 0 &&
9207 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
9208 isc_buffer_putstr(&buffer, "/");
9209 isc_buffer_putstr(&buffer, zone->view->name);
9212 buf[isc_buffer_usedlength(&buffer)] = '\0';
9216 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
9217 isc_result_t result = ISC_R_FAILURE;
9218 isc_buffer_t buffer;
9220 REQUIRE(buf != NULL);
9221 REQUIRE(length > 1U);
9224 * Leave space for terminating '\0'.
9226 isc_buffer_init(&buffer, buf, length - 1);
9227 if (dns_name_dynamic(&zone->origin))
9228 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9229 if (result != ISC_R_SUCCESS &&
9230 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9231 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9233 buf[isc_buffer_usedlength(&buffer)] = '\0';
9237 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
9238 isc_buffer_t buffer;
9240 REQUIRE(buf != NULL);
9241 REQUIRE(length > 1U);
9244 * Leave space for terminating '\0'.
9246 isc_buffer_init(&buffer, buf, length - 1);
9247 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9249 buf[isc_buffer_usedlength(&buffer)] = '\0';
9253 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
9254 isc_buffer_t buffer;
9256 REQUIRE(buf != NULL);
9257 REQUIRE(length > 1U);
9261 * Leave space for terminating '\0'.
9263 isc_buffer_init(&buffer, buf, length - 1);
9265 if (zone->view == NULL) {
9266 isc_buffer_putstr(&buffer, "_none");
9267 } else if (strlen(zone->view->name)
9268 < isc_buffer_availablelength(&buffer)) {
9269 isc_buffer_putstr(&buffer, zone->view->name);
9271 isc_buffer_putstr(&buffer, "_toolong");
9274 buf[isc_buffer_usedlength(&buffer)] = '\0';
9278 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
9279 REQUIRE(DNS_ZONE_VALID(zone));
9280 REQUIRE(buf != NULL);
9281 zone_namerd_tostr(zone, buf, length);
9285 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9289 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9293 vsnprintf(message, sizeof(message), fmt, ap);
9295 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
9296 level, "zone %s: %s", zone->strnamerd, message);
9300 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
9301 int level, const char *fmt, ...) {
9305 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9309 vsnprintf(message, sizeof(message), fmt, ap);
9311 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
9312 level, "zone %s: %s", zone->strnamerd, message);
9316 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9320 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9324 vsnprintf(message, sizeof(message), fmt, ap);
9326 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9327 level, "zone %s: %s", zone->strnamerd, message);
9331 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
9332 const char *fmt, ...)
9336 int level = ISC_LOG_DEBUG(debuglevel);
9338 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9342 vsnprintf(message, sizeof(message), fmt, ap);
9344 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9345 level, "%s: zone %s: %s", me, zone->strnamerd, message);
9349 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
9351 isc_result_t result;
9353 dns_rdataset_t *curr;
9356 result = dns_message_firstname(msg, section);
9357 while (result == ISC_R_SUCCESS) {
9359 dns_message_currentname(msg, section, &name);
9361 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
9362 curr = ISC_LIST_PREV(curr, link)) {
9363 if (curr->type == type)
9366 result = dns_message_nextname(msg, section);
9373 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
9374 REQUIRE(DNS_ZONE_VALID(zone));
9376 zone->maxxfrin = maxxfrin;
9380 dns_zone_getmaxxfrin(dns_zone_t *zone) {
9381 REQUIRE(DNS_ZONE_VALID(zone));
9383 return (zone->maxxfrin);
9387 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
9388 REQUIRE(DNS_ZONE_VALID(zone));
9389 zone->maxxfrout = maxxfrout;
9393 dns_zone_getmaxxfrout(dns_zone_t *zone) {
9394 REQUIRE(DNS_ZONE_VALID(zone));
9396 return (zone->maxxfrout);
9400 dns_zone_gettype(dns_zone_t *zone) {
9401 REQUIRE(DNS_ZONE_VALID(zone));
9403 return (zone->type);
9407 dns_zone_getorigin(dns_zone_t *zone) {
9408 REQUIRE(DNS_ZONE_VALID(zone));
9410 return (&zone->origin);
9414 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
9415 REQUIRE(DNS_ZONE_VALID(zone));
9418 if (zone->task != NULL)
9419 isc_task_detach(&zone->task);
9420 isc_task_attach(task, &zone->task);
9421 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9422 if (zone->db != NULL)
9423 dns_db_settask(zone->db, zone->task);
9424 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9429 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
9430 REQUIRE(DNS_ZONE_VALID(zone));
9431 isc_task_attach(zone->task, target);
9435 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
9436 REQUIRE(DNS_ZONE_VALID(zone));
9439 idlein = DNS_DEFAULT_IDLEIN;
9440 zone->idlein = idlein;
9444 dns_zone_getidlein(dns_zone_t *zone) {
9445 REQUIRE(DNS_ZONE_VALID(zone));
9447 return (zone->idlein);
9451 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
9452 REQUIRE(DNS_ZONE_VALID(zone));
9454 zone->idleout = idleout;
9458 dns_zone_getidleout(dns_zone_t *zone) {
9459 REQUIRE(DNS_ZONE_VALID(zone));
9461 return (zone->idleout);
9465 notify_done(isc_task_t *task, isc_event_t *event) {
9466 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9467 dns_notify_t *notify;
9468 isc_result_t result;
9469 dns_message_t *message = NULL;
9472 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9476 notify = event->ev_arg;
9477 REQUIRE(DNS_NOTIFY_VALID(notify));
9478 INSIST(task == notify->zone->task);
9480 isc_buffer_init(&buf, rcode, sizeof(rcode));
9481 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9483 result = revent->result;
9484 if (result == ISC_R_SUCCESS)
9485 result = dns_message_create(notify->zone->mctx,
9486 DNS_MESSAGE_INTENTPARSE, &message);
9487 if (result == ISC_R_SUCCESS)
9488 result = dns_request_getresponse(revent->request, message,
9489 DNS_MESSAGEPARSE_PRESERVEORDER);
9490 if (result == ISC_R_SUCCESS)
9491 result = dns_rcode_totext(message->rcode, &buf);
9492 if (result == ISC_R_SUCCESS)
9493 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9494 "notify response from %s: %.*s",
9495 addrbuf, (int)buf.used, rcode);
9497 notify_log(notify->zone, ISC_LOG_DEBUG(2),
9498 "notify to %s failed: %s", addrbuf,
9499 dns_result_totext(result));
9502 * Old bind's return formerr if they see a soa record. Retry w/o
9503 * the soa if we see a formerr and had sent a SOA.
9505 isc_event_free(&event);
9506 if (message != NULL && message->rcode == dns_rcode_formerr &&
9507 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
9508 notify->flags |= DNS_NOTIFY_NOSOA;
9509 dns_request_destroy(¬ify->request);
9510 result = notify_send_queue(notify);
9511 if (result != ISC_R_SUCCESS)
9512 notify_destroy(notify, ISC_FALSE);
9514 if (result == ISC_R_TIMEDOUT)
9515 notify_log(notify->zone, ISC_LOG_DEBUG(1),
9516 "notify to %s: retries exceeded", addrbuf);
9517 notify_destroy(notify, ISC_FALSE);
9519 if (message != NULL)
9520 dns_message_destroy(&message);
9524 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9525 isc_result_t result;
9527 REQUIRE(DNS_ZONE_VALID(zone));
9529 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9530 result = zone_replacedb(zone, db, dump);
9531 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9537 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9538 dns_dbversion_t *ver;
9539 isc_result_t result;
9540 unsigned int soacount = 0;
9541 unsigned int nscount = 0;
9544 * 'zone' and 'zonedb' locked by caller.
9546 REQUIRE(DNS_ZONE_VALID(zone));
9547 REQUIRE(LOCKED_ZONE(zone));
9549 result = zone_get_from_db(zone, db, &nscount, &soacount,
9550 NULL, NULL, NULL, NULL, NULL, NULL);
9551 if (result == ISC_R_SUCCESS) {
9552 if (soacount != 1) {
9553 dns_zone_log(zone, ISC_LOG_ERROR,
9554 "has %d SOA records", soacount);
9555 result = DNS_R_BADZONE;
9558 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
9559 result = DNS_R_BADZONE;
9561 if (result != ISC_R_SUCCESS)
9564 dns_zone_log(zone, ISC_LOG_ERROR,
9565 "retrieving SOA and NS records failed: %s",
9566 dns_result_totext(result));
9570 result = check_nsec3param(zone, db);
9571 if (result != ISC_R_SUCCESS)
9575 dns_db_currentversion(db, &ver);
9578 * The initial version of a slave zone is always dumped;
9579 * subsequent versions may be journaled instead if this
9580 * is enabled in the configuration.
9582 if (zone->db != NULL && zone->journal != NULL &&
9583 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
9584 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
9585 isc_uint32_t serial, oldserial;
9587 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
9589 result = dns_db_getsoaserial(db, ver, &serial);
9590 if (result != ISC_R_SUCCESS) {
9591 dns_zone_log(zone, ISC_LOG_ERROR,
9592 "ixfr-from-differences: unable to get "
9598 * This is checked in zone_postload() for master zones.
9600 result = zone_get_from_db(zone, zone->db, NULL, NULL,
9601 &oldserial, NULL, NULL, NULL, NULL,
9603 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9604 if (zone->type == dns_zone_slave &&
9605 !isc_serial_gt(serial, oldserial)) {
9606 isc_uint32_t serialmin, serialmax;
9607 serialmin = (oldserial + 1) & 0xffffffffU;
9608 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
9609 dns_zone_log(zone, ISC_LOG_ERROR,
9610 "ixfr-from-differences: failed: "
9611 "new serial (%u) out of range [%u - %u]",
9612 serial, serialmin, serialmax);
9613 result = ISC_R_RANGE;
9617 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
9619 if (result != ISC_R_SUCCESS)
9622 zone_needdump(zone, DNS_DUMP_DELAY);
9623 else if (zone->journalsize != -1) {
9624 result = dns_journal_compact(zone->mctx, zone->journal,
9625 serial, zone->journalsize);
9629 case ISC_R_NOTFOUND:
9630 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9631 "dns_journal_compact: %s",
9632 dns_result_totext(result));
9635 dns_zone_log(zone, ISC_LOG_ERROR,
9636 "dns_journal_compact failed: %s",
9637 dns_result_totext(result));
9642 if (dump && zone->masterfile != NULL) {
9643 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9644 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9645 "dumping new zone version");
9646 result = dns_db_dump2(db, ver, zone->masterfile,
9647 zone->masterformat);
9648 if (result != ISC_R_SUCCESS)
9652 * Update the time the zone was updated, so
9653 * dns_zone_load can avoid loading it when
9654 * the server is reloaded. If isc_time_now
9655 * fails for some reason, all that happens is
9656 * the timestamp is not updated.
9658 TIME_NOW(&zone->loadtime);
9661 if (dump && zone->journal != NULL) {
9663 * The in-memory database just changed, and
9664 * because 'dump' is set, it didn't change by
9665 * being loaded from disk. Also, we have not
9666 * journaled diffs for this change.
9667 * Therefore, the on-disk journal is missing
9668 * the deltas for this change. Since it can
9669 * no longer be used to bring the zone
9670 * up-to-date, it is useless and should be
9673 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9674 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9675 "removing journal file");
9676 if (remove(zone->journal) < 0 && errno != ENOENT) {
9677 char strbuf[ISC_STRERRORSIZE];
9678 isc__strerror(errno, strbuf, sizeof(strbuf));
9679 isc_log_write(dns_lctx,
9680 DNS_LOGCATEGORY_GENERAL,
9683 "unable to remove journal "
9685 zone->journal, strbuf);
9690 dns_db_closeversion(db, &ver, ISC_FALSE);
9692 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9693 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9694 "replacing zone database");
9696 if (zone->db != NULL)
9697 zone_detachdb(zone);
9698 zone_attachdb(zone, db);
9699 dns_db_settask(zone->db, zone->task);
9700 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
9701 return (ISC_R_SUCCESS);
9704 dns_db_closeversion(db, &ver, ISC_FALSE);
9708 /* The caller must hold the dblock as a writer. */
9710 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
9711 REQUIRE(zone->db == NULL && db != NULL);
9713 dns_db_attach(db, &zone->db);
9714 if (zone->acache != NULL) {
9715 isc_result_t result;
9716 result = dns_acache_setdb(zone->acache, db);
9717 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
9718 UNEXPECTED_ERROR(__FILE__, __LINE__,
9719 "dns_acache_setdb() failed: %s",
9720 isc_result_totext(result));
9725 /* The caller must hold the dblock as a writer. */
9727 zone_detachdb(dns_zone_t *zone) {
9728 REQUIRE(zone->db != NULL);
9730 if (zone->acache != NULL)
9731 (void)dns_acache_putdb(zone->acache, zone->db);
9732 dns_db_detach(&zone->db);
9736 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
9738 isc_boolean_t again = ISC_FALSE;
9739 unsigned int soacount;
9740 unsigned int nscount;
9741 isc_uint32_t serial, refresh, retry, expire, minimum;
9742 isc_result_t xfrresult = result;
9743 isc_boolean_t free_needed;
9745 REQUIRE(DNS_ZONE_VALID(zone));
9747 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9748 "zone transfer finished: %s", dns_result_totext(result));
9751 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
9752 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9753 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9758 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9760 case DNS_R_UPTODATE:
9761 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
9763 * Has the zone expired underneath us?
9765 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9766 if (zone->db == NULL) {
9767 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9772 * Update the zone structure's data from the actual
9777 INSIST(zone->db != NULL);
9778 result = zone_get_from_db(zone, zone->db, &nscount,
9779 &soacount, &serial, &refresh,
9780 &retry, &expire, &minimum, NULL);
9781 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9782 if (result == ISC_R_SUCCESS) {
9784 dns_zone_log(zone, ISC_LOG_ERROR,
9786 "has %d SOA record%s", soacount,
9787 (soacount != 0) ? "s" : "");
9789 dns_zone_log(zone, ISC_LOG_ERROR,
9791 "has no NS records");
9792 if (DNS_ZONE_FLAG(zone,
9793 DNS_ZONEFLG_HAVETIMERS)) {
9794 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9795 zone->retry = DNS_ZONE_DEFAULTRETRY;
9797 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9801 zone->refresh = RANGE(refresh, zone->minrefresh,
9803 zone->retry = RANGE(retry, zone->minretry,
9805 zone->expire = RANGE(expire,
9806 zone->refresh + zone->retry,
9808 zone->minimum = minimum;
9809 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9813 * Set our next update/expire times.
9815 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
9816 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
9817 zone->refreshtime = now;
9818 DNS_ZONE_TIME_ADD(&now, zone->expire,
9821 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
9822 &zone->refreshtime);
9823 DNS_ZONE_TIME_ADD(&now, zone->expire,
9826 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
9827 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
9828 if (zone->tsigkey != NULL) {
9829 char namebuf[DNS_NAME_FORMATSIZE];
9830 dns_name_format(&zone->tsigkey->name, namebuf,
9832 snprintf(buf, sizeof(buf), ": TSIG '%s'",
9836 dns_zone_log(zone, ISC_LOG_INFO,
9837 "transferred serial %u%s",
9842 * This is not necessary if we just performed a AXFR
9843 * however it is necessary for an IXFR / UPTODATE and
9844 * won't hurt with an AXFR.
9846 if (zone->masterfile != NULL || zone->journal != NULL) {
9847 result = ISC_R_FAILURE;
9848 if (zone->journal != NULL)
9849 result = isc_file_settime(zone->journal, &now);
9850 if (result != ISC_R_SUCCESS &&
9851 zone->masterfile != NULL)
9852 result = isc_file_settime(zone->masterfile,
9854 /* Someone removed the file from underneath us! */
9855 if (result == ISC_R_FILENOTFOUND &&
9856 zone->masterfile != NULL)
9857 zone_needdump(zone, DNS_DUMP_DELAY);
9858 else if (result != ISC_R_SUCCESS)
9859 dns_zone_log(zone, ISC_LOG_ERROR,
9860 "transfer: could not set file "
9861 "modification time of '%s': %s",
9863 dns_result_totext(result));
9866 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
9870 /* Force retry with AXFR. */
9871 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
9877 * Skip to next failed / untried master.
9881 } while (zone->curmaster < zone->masterscnt &&
9882 zone->mastersok[zone->curmaster]);
9885 if (zone->curmaster >= zone->masterscnt) {
9886 zone->curmaster = 0;
9887 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9888 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9889 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9890 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9891 while (zone->curmaster < zone->masterscnt &&
9892 zone->mastersok[zone->curmaster])
9896 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9898 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9901 inc_stats(zone, dns_zonestatscounter_xfrfail);
9904 zone_settimer(zone, &now);
9907 * If creating the transfer object failed, zone->xfr is NULL.
9908 * Otherwise, we are called as the done callback of a zone
9909 * transfer object that just entered its shutting-down
9910 * state. Since we are no longer responsible for shutting
9911 * it down, we can detach our reference.
9913 if (zone->xfr != NULL)
9914 dns_xfrin_detach(&zone->xfr);
9916 if (zone->tsigkey != NULL)
9917 dns_tsigkey_detach(&zone->tsigkey);
9920 * Handle any deferred journal compaction.
9922 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
9923 result = dns_journal_compact(zone->mctx, zone->journal,
9924 zone->compact_serial,
9929 case ISC_R_NOTFOUND:
9930 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9931 "dns_journal_compact: %s",
9932 dns_result_totext(result));
9935 dns_zone_log(zone, ISC_LOG_ERROR,
9936 "dns_journal_compact failed: %s",
9937 dns_result_totext(result));
9940 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9944 * This transfer finishing freed up a transfer quota slot.
9945 * Let any other zones waiting for quota have it.
9947 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9948 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
9949 zone->statelist = NULL;
9950 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
9951 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9954 * Retry with a different server if necessary.
9956 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9957 queue_soa_query(zone);
9959 INSIST(zone->irefs > 0);
9961 free_needed = exit_check(zone);
9968 zone_loaddone(void *arg, isc_result_t result) {
9969 static char me[] = "zone_loaddone";
9970 dns_load_t *load = arg;
9972 isc_result_t tresult;
9974 REQUIRE(DNS_LOAD_VALID(load));
9979 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
9980 if (tresult != ISC_R_SUCCESS &&
9981 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
9984 LOCK_ZONE(load->zone);
9985 (void)zone_postload(load->zone, load->db, load->loadtime, result);
9986 zonemgr_putio(&load->zone->readio);
9987 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
9989 * Leave the zone frozen if the reload fails.
9991 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
9992 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
9993 zone->update_disabled = ISC_FALSE;
9994 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
9995 UNLOCK_ZONE(load->zone);
9998 dns_db_detach(&load->db);
9999 if (load->zone->lctx != NULL)
10000 dns_loadctx_detach(&load->zone->lctx);
10001 dns_zone_idetach(&load->zone);
10002 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
10006 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
10007 REQUIRE(DNS_ZONE_VALID(zone));
10008 REQUIRE(table != NULL);
10009 REQUIRE(*table == NULL);
10012 if (zone->ssutable != NULL)
10013 dns_ssutable_attach(zone->ssutable, table);
10018 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
10019 REQUIRE(DNS_ZONE_VALID(zone));
10022 if (zone->ssutable != NULL)
10023 dns_ssutable_detach(&zone->ssutable);
10025 dns_ssutable_attach(table, &zone->ssutable);
10030 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
10031 REQUIRE(DNS_ZONE_VALID(zone));
10033 zone->sigvalidityinterval = interval;
10037 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
10038 REQUIRE(DNS_ZONE_VALID(zone));
10040 return (zone->sigvalidityinterval);
10044 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
10045 REQUIRE(DNS_ZONE_VALID(zone));
10047 zone->sigresigninginterval = interval;
10051 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
10052 REQUIRE(DNS_ZONE_VALID(zone));
10054 return (zone->sigresigninginterval);
10058 queue_xfrin(dns_zone_t *zone) {
10059 const char me[] = "queue_xfrin";
10060 isc_result_t result;
10061 dns_zonemgr_t *zmgr = zone->zmgr;
10065 INSIST(zone->statelist == NULL);
10067 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10068 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
10072 zone->statelist = &zmgr->waiting_for_xfrin;
10073 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10074 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10076 if (result == ISC_R_QUOTA) {
10077 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
10078 "zone transfer deferred due to quota");
10079 } else if (result != ISC_R_SUCCESS) {
10080 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
10081 "starting zone transfer: %s",
10082 isc_result_totext(result));
10087 * This event callback is called when a zone has received
10088 * any necessary zone transfer quota. This is the time
10089 * to go ahead and start the transfer.
10092 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
10093 isc_result_t result;
10094 dns_peer_t *peer = NULL;
10095 char master[ISC_SOCKADDR_FORMATSIZE];
10096 char source[ISC_SOCKADDR_FORMATSIZE];
10097 dns_rdatatype_t xfrtype;
10098 dns_zone_t *zone = event->ev_arg;
10099 isc_netaddr_t masterip;
10100 isc_sockaddr_t sourceaddr;
10101 isc_sockaddr_t masteraddr;
10103 const char *soa_before = "";
10107 INSIST(task == zone->task);
10109 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10110 result = ISC_R_CANCELED;
10116 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10117 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10118 &zone->sourceaddr, &now)) {
10119 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10120 dns_zone_log(zone, ISC_LOG_INFO,
10121 "got_transfer_quota: skipping zone transfer as "
10122 "master %s (source %s) is unreachable (cached)",
10124 result = ISC_R_CANCELED;
10128 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10129 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
10131 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10132 soa_before = "SOA before ";
10134 * Decide whether we should request IXFR or AXFR.
10136 if (zone->db == NULL) {
10137 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10138 "no database exists yet, requesting AXFR of "
10139 "initial version from %s", master);
10140 xfrtype = dns_rdatatype_axfr;
10141 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
10142 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
10143 "set, requesting %sAXFR from %s", soa_before,
10145 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10146 xfrtype = dns_rdatatype_soa;
10148 xfrtype = dns_rdatatype_axfr;
10149 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
10150 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10151 "forced reload, requesting AXFR of "
10152 "initial version from %s", master);
10153 xfrtype = dns_rdatatype_axfr;
10154 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
10155 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10156 "retrying with AXFR from %s due to "
10157 "previous IXFR failure", master);
10158 xfrtype = dns_rdatatype_axfr;
10160 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
10163 isc_boolean_t use_ixfr = ISC_TRUE;
10164 if (peer != NULL &&
10165 dns_peer_getrequestixfr(peer, &use_ixfr) ==
10167 ; /* Using peer setting */
10169 use_ixfr = zone->view->requestixfr;
10171 if (use_ixfr == ISC_FALSE) {
10172 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10173 "IXFR disabled, requesting %sAXFR from %s",
10174 soa_before, master);
10175 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10176 xfrtype = dns_rdatatype_soa;
10178 xfrtype = dns_rdatatype_axfr;
10180 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10181 "requesting IXFR from %s", master);
10182 xfrtype = dns_rdatatype_ixfr;
10187 * Determine if we should attempt to sign the request with TSIG.
10189 result = ISC_R_NOTFOUND;
10191 * First, look for a tsig key in the master statement, then
10192 * try for a server key.
10194 if ((zone->masterkeynames != NULL) &&
10195 (zone->masterkeynames[zone->curmaster] != NULL)) {
10196 dns_view_t *view = dns_zone_getview(zone);
10197 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10198 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
10200 if (zone->tsigkey == NULL)
10201 result = dns_view_getpeertsig(zone->view, &masterip,
10204 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10205 dns_zone_log(zone, ISC_LOG_ERROR,
10206 "could not get TSIG key for zone transfer: %s",
10207 isc_result_totext(result));
10211 masteraddr = zone->masteraddr;
10212 sourceaddr = zone->sourceaddr;
10214 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
10215 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
10216 zone->tsigkey, zone->mctx,
10217 zone->zmgr->timermgr, zone->zmgr->socketmgr,
10218 zone->task, zone_xfrdone, &zone->xfr);
10219 if (result == ISC_R_SUCCESS) {
10221 if (xfrtype == dns_rdatatype_axfr) {
10222 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10223 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
10225 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
10226 } else if (xfrtype == dns_rdatatype_ixfr) {
10227 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10228 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
10230 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
10236 * Any failure in this function is handled like a failed
10237 * zone transfer. This ensures that we get removed from
10238 * zmgr->xfrin_in_progress.
10240 if (result != ISC_R_SUCCESS)
10241 zone_xfrdone(zone, result);
10243 isc_event_free(&event);
10247 * Update forwarding support.
10251 forward_destroy(dns_forward_t *forward) {
10253 forward->magic = 0;
10254 if (forward->request != NULL)
10255 dns_request_destroy(&forward->request);
10256 if (forward->msgbuf != NULL)
10257 isc_buffer_free(&forward->msgbuf);
10258 if (forward->zone != NULL)
10259 dns_zone_idetach(&forward->zone);
10260 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
10263 static isc_result_t
10264 sendtomaster(dns_forward_t *forward) {
10265 isc_result_t result;
10266 isc_sockaddr_t src;
10268 LOCK_ZONE(forward->zone);
10269 if (forward->which >= forward->zone->masterscnt) {
10270 UNLOCK_ZONE(forward->zone);
10271 return (ISC_R_NOMORE);
10274 forward->addr = forward->zone->masters[forward->which];
10276 * Always use TCP regardless of whether the original update
10278 * XXX The timeout may but a bit small if we are far down a
10279 * transfer graph and the master has to try several masters.
10281 switch (isc_sockaddr_pf(&forward->addr)) {
10283 src = forward->zone->xfrsource4;
10286 src = forward->zone->xfrsource6;
10289 result = ISC_R_NOTIMPLEMENTED;
10292 result = dns_request_createraw(forward->zone->view->requestmgr,
10294 &src, &forward->addr,
10295 DNS_REQUESTOPT_TCP, 15 /* XXX */,
10296 forward->zone->task,
10297 forward_callback, forward,
10298 &forward->request);
10300 UNLOCK_ZONE(forward->zone);
10305 forward_callback(isc_task_t *task, isc_event_t *event) {
10306 const char me[] = "forward_callback";
10307 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10308 dns_message_t *msg = NULL;
10309 char master[ISC_SOCKADDR_FORMATSIZE];
10310 isc_result_t result;
10311 dns_forward_t *forward;
10316 forward = revent->ev_arg;
10317 INSIST(DNS_FORWARD_VALID(forward));
10318 zone = forward->zone;
10319 INSIST(DNS_ZONE_VALID(zone));
10323 isc_sockaddr_format(&forward->addr, master, sizeof(master));
10325 if (revent->result != ISC_R_SUCCESS) {
10326 dns_zone_log(zone, ISC_LOG_INFO,
10327 "could not forward dynamic update to %s: %s",
10328 master, dns_result_totext(revent->result));
10332 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10333 if (result != ISC_R_SUCCESS)
10336 result = dns_request_getresponse(revent->request, msg,
10337 DNS_MESSAGEPARSE_PRESERVEORDER |
10338 DNS_MESSAGEPARSE_CLONEBUFFER);
10339 if (result != ISC_R_SUCCESS)
10342 switch (msg->rcode) {
10344 * Pass these rcodes back to client.
10346 case dns_rcode_noerror:
10347 case dns_rcode_yxdomain:
10348 case dns_rcode_yxrrset:
10349 case dns_rcode_nxrrset:
10350 case dns_rcode_refused:
10351 case dns_rcode_nxdomain:
10354 /* These should not occur if the masters/zone are valid. */
10355 case dns_rcode_notzone:
10356 case dns_rcode_notauth: {
10360 isc_buffer_init(&rb, rcode, sizeof(rcode));
10361 (void)dns_rcode_totext(msg->rcode, &rb);
10362 dns_zone_log(zone, ISC_LOG_WARNING,
10363 "forwarding dynamic update: "
10364 "unexpected response: master %s returned: %.*s",
10365 master, (int)rb.used, rcode);
10369 /* Try another server for these rcodes. */
10370 case dns_rcode_formerr:
10371 case dns_rcode_servfail:
10372 case dns_rcode_notimp:
10373 case dns_rcode_badvers:
10378 /* call callback */
10379 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
10381 dns_request_destroy(&forward->request);
10382 forward_destroy(forward);
10383 isc_event_free(&event);
10388 dns_message_destroy(&msg);
10389 isc_event_free(&event);
10391 dns_request_destroy(&forward->request);
10392 result = sendtomaster(forward);
10393 if (result != ISC_R_SUCCESS) {
10394 /* call callback */
10395 dns_zone_log(zone, ISC_LOG_DEBUG(3),
10396 "exhausted dynamic update forwarder list");
10397 (forward->callback)(forward->callback_arg, result, NULL);
10398 forward_destroy(forward);
10403 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
10404 dns_updatecallback_t callback, void *callback_arg)
10406 dns_forward_t *forward;
10407 isc_result_t result;
10410 REQUIRE(DNS_ZONE_VALID(zone));
10411 REQUIRE(msg != NULL);
10412 REQUIRE(callback != NULL);
10414 forward = isc_mem_get(zone->mctx, sizeof(*forward));
10415 if (forward == NULL)
10416 return (ISC_R_NOMEMORY);
10418 forward->request = NULL;
10419 forward->zone = NULL;
10420 forward->msgbuf = NULL;
10421 forward->which = 0;
10423 forward->callback = callback;
10424 forward->callback_arg = callback_arg;
10425 forward->magic = FORWARD_MAGIC;
10427 mr = dns_message_getrawmessage(msg);
10429 result = ISC_R_UNEXPECTEDEND;
10433 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
10434 if (result != ISC_R_SUCCESS)
10436 result = isc_buffer_copyregion(forward->msgbuf, mr);
10437 if (result != ISC_R_SUCCESS)
10440 isc_mem_attach(zone->mctx, &forward->mctx);
10441 dns_zone_iattach(zone, &forward->zone);
10442 result = sendtomaster(forward);
10445 if (result != ISC_R_SUCCESS) {
10446 forward_destroy(forward);
10452 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
10453 REQUIRE(DNS_ZONE_VALID(zone));
10454 REQUIRE(next != NULL && *next == NULL);
10456 *next = ISC_LIST_NEXT(zone, link);
10458 return (ISC_R_NOMORE);
10460 return (ISC_R_SUCCESS);
10464 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
10465 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10466 REQUIRE(first != NULL && *first == NULL);
10468 *first = ISC_LIST_HEAD(zmgr->zones);
10469 if (*first == NULL)
10470 return (ISC_R_NOMORE);
10472 return (ISC_R_SUCCESS);
10480 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
10481 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
10482 dns_zonemgr_t **zmgrp)
10484 dns_zonemgr_t *zmgr;
10485 isc_result_t result;
10486 isc_interval_t interval;
10488 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
10490 return (ISC_R_NOMEMORY);
10493 isc_mem_attach(mctx, &zmgr->mctx);
10494 zmgr->taskmgr = taskmgr;
10495 zmgr->timermgr = timermgr;
10496 zmgr->socketmgr = socketmgr;
10497 zmgr->zonetasks = NULL;
10500 ISC_LIST_INIT(zmgr->zones);
10501 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
10502 ISC_LIST_INIT(zmgr->xfrin_in_progress);
10503 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
10504 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
10505 if (result != ISC_R_SUCCESS)
10508 zmgr->transfersin = 10;
10509 zmgr->transfersperns = 2;
10511 /* Create the zone task pool. */
10512 result = isc_taskpool_create(taskmgr, mctx,
10513 8 /* XXX */, 2, &zmgr->zonetasks);
10514 if (result != ISC_R_SUCCESS)
10517 /* Create a single task for queueing of SOA queries. */
10518 result = isc_task_create(taskmgr, 1, &zmgr->task);
10519 if (result != ISC_R_SUCCESS)
10520 goto free_taskpool;
10521 isc_task_setname(zmgr->task, "zmgr", zmgr);
10522 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
10524 if (result != ISC_R_SUCCESS)
10526 /* default to 20 refresh queries / notifies per second. */
10527 isc_interval_set(&interval, 0, 1000000000/2);
10528 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
10529 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10530 isc_ratelimiter_setpertic(zmgr->rl, 10);
10533 zmgr->ioactive = 0;
10534 ISC_LIST_INIT(zmgr->high);
10535 ISC_LIST_INIT(zmgr->low);
10537 result = isc_mutex_init(&zmgr->iolock);
10538 if (result != ISC_R_SUCCESS)
10541 zmgr->magic = ZONEMGR_MAGIC;
10544 return (ISC_R_SUCCESS);
10548 DESTROYLOCK(&zmgr->iolock);
10551 isc_ratelimiter_detach(&zmgr->rl);
10553 isc_task_detach(&zmgr->task);
10555 isc_taskpool_destroy(&zmgr->zonetasks);
10557 isc_rwlock_destroy(&zmgr->rwlock);
10559 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10560 isc_mem_detach(&mctx);
10565 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10566 isc_result_t result;
10568 REQUIRE(DNS_ZONE_VALID(zone));
10569 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10571 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10573 REQUIRE(zone->task == NULL);
10574 REQUIRE(zone->timer == NULL);
10575 REQUIRE(zone->zmgr == NULL);
10577 isc_taskpool_gettask(zmgr->zonetasks,
10578 dns_name_hash(dns_zone_getorigin(zone),
10583 * Set the task name. The tag will arbitrarily point to one
10584 * of the zones sharing the task (in practice, the one
10585 * to be managed last).
10587 isc_task_setname(zone->task, "zone", zone);
10589 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
10591 zone->task, zone_timer, zone,
10594 if (result != ISC_R_SUCCESS)
10598 * The timer "holds" a iref.
10601 INSIST(zone->irefs != 0);
10603 ISC_LIST_APPEND(zmgr->zones, zone, link);
10610 isc_task_detach(&zone->task);
10614 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10619 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10620 isc_boolean_t free_now = ISC_FALSE;
10622 REQUIRE(DNS_ZONE_VALID(zone));
10623 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10624 REQUIRE(zone->zmgr == zmgr);
10626 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10629 ISC_LIST_UNLINK(zmgr->zones, zone, link);
10632 if (zmgr->refs == 0)
10633 free_now = ISC_TRUE;
10636 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10639 zonemgr_free(zmgr);
10640 ENSURE(zone->zmgr == NULL);
10644 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
10645 REQUIRE(DNS_ZONEMGR_VALID(source));
10646 REQUIRE(target != NULL && *target == NULL);
10648 RWLOCK(&source->rwlock, isc_rwlocktype_write);
10649 REQUIRE(source->refs > 0);
10651 INSIST(source->refs > 0);
10652 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
10657 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
10658 dns_zonemgr_t *zmgr;
10659 isc_boolean_t free_now = ISC_FALSE;
10661 REQUIRE(zmgrp != NULL);
10663 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10665 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10667 if (zmgr->refs == 0)
10668 free_now = ISC_TRUE;
10669 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10672 zonemgr_free(zmgr);
10676 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
10679 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10681 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10682 for (p = ISC_LIST_HEAD(zmgr->zones);
10684 p = ISC_LIST_NEXT(p, link))
10686 dns_zone_maintenance(p);
10688 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10691 * Recent configuration changes may have increased the
10692 * amount of available transfers quota. Make sure any
10693 * transfers currently blocked on quota get started if
10696 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10697 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10698 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10699 return (ISC_R_SUCCESS);
10703 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
10705 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10707 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10708 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10709 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10713 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
10714 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10716 isc_ratelimiter_shutdown(zmgr->rl);
10718 if (zmgr->task != NULL)
10719 isc_task_destroy(&zmgr->task);
10720 if (zmgr->zonetasks != NULL)
10721 isc_taskpool_destroy(&zmgr->zonetasks);
10725 zonemgr_free(dns_zonemgr_t *zmgr) {
10728 INSIST(zmgr->refs == 0);
10729 INSIST(ISC_LIST_EMPTY(zmgr->zones));
10733 DESTROYLOCK(&zmgr->iolock);
10734 isc_ratelimiter_detach(&zmgr->rl);
10736 isc_rwlock_destroy(&zmgr->rwlock);
10738 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10739 isc_mem_detach(&mctx);
10743 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10744 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10746 zmgr->transfersin = value;
10750 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
10751 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10753 return (zmgr->transfersin);
10757 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10758 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10760 zmgr->transfersperns = value;
10764 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
10765 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10767 return (zmgr->transfersperns);
10771 * Try to start a new incoming zone transfer to fill a quota
10772 * slot that was just vacated.
10775 * The zone manager is locked by the caller.
10778 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
10782 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
10786 isc_result_t result;
10787 next = ISC_LIST_NEXT(zone, statelink);
10788 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10789 if (result == ISC_R_SUCCESS) {
10793 * We successfully filled the slot. We're done.
10796 } else if (result == ISC_R_QUOTA) {
10798 * Not enough quota. This is probably the per-server
10799 * quota, because we usually get called when a unit of
10800 * global quota has just been freed. Try the next
10801 * zone, it may succeed if it uses another master.
10805 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10806 "starting zone transfer: %s",
10807 isc_result_totext(result));
10814 * Try to start an incoming zone transfer for 'zone', quota permitting.
10817 * The zone manager is locked by the caller.
10820 * ISC_R_SUCCESS There was enough quota and we attempted to
10821 * start a transfer. zone_xfrdone() has been or will
10823 * ISC_R_QUOTA Not enough quota.
10826 static isc_result_t
10827 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10828 dns_peer_t *peer = NULL;
10829 isc_netaddr_t masterip;
10830 isc_uint32_t nxfrsin, nxfrsperns;
10832 isc_uint32_t maxtransfersin, maxtransfersperns;
10836 * Find any configured information about the server we'd
10837 * like to transfer this zone from.
10839 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10840 (void)dns_peerlist_peerbyaddr(zone->view->peers,
10844 * Determine the total maximum number of simultaneous
10845 * transfers allowed, and the maximum for this specific
10848 maxtransfersin = zmgr->transfersin;
10849 maxtransfersperns = zmgr->transfersperns;
10851 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
10854 * Count the total number of transfers that are in progress,
10855 * and the number of transfers in progress from this master.
10856 * We linearly scan a list of all transfers; if this turns
10857 * out to be too slow, we could hash on the master address.
10859 nxfrsin = nxfrsperns = 0;
10860 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
10862 x = ISC_LIST_NEXT(x, statelink))
10865 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
10867 if (isc_netaddr_equal(&xip, &masterip))
10871 /* Enforce quota. */
10872 if (nxfrsin >= maxtransfersin)
10873 return (ISC_R_QUOTA);
10875 if (nxfrsperns >= maxtransfersperns)
10876 return (ISC_R_QUOTA);
10879 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
10880 * list and send it an event to let it start the actual transfer in the
10881 * context of its own task.
10883 e = isc_event_allocate(zmgr->mctx, zmgr,
10884 DNS_EVENT_ZONESTARTXFRIN,
10885 got_transfer_quota, zone,
10886 sizeof(isc_event_t));
10888 return (ISC_R_NOMEMORY);
10891 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
10892 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
10893 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
10894 zone->statelist = &zmgr->xfrin_in_progress;
10895 isc_task_send(zone->task, &e);
10896 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
10899 return (ISC_R_SUCCESS);
10903 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
10905 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10906 REQUIRE(iolimit > 0);
10908 zmgr->iolimit = iolimit;
10912 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
10914 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10916 return (zmgr->iolimit);
10920 * Get permission to request a file handle from the OS.
10921 * An event will be sent to action when one is available.
10922 * There are two queues available (high and low), the high
10923 * queue will be serviced before the low one.
10925 * zonemgr_putio() must be called after the event is delivered to
10929 static isc_result_t
10930 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
10931 isc_task_t *task, isc_taskaction_t action, void *arg,
10935 isc_boolean_t queue;
10937 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10938 REQUIRE(iop != NULL && *iop == NULL);
10940 io = isc_mem_get(zmgr->mctx, sizeof(*io));
10942 return (ISC_R_NOMEMORY);
10943 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
10944 action, arg, sizeof(*io->event));
10945 if (io->event == NULL) {
10946 isc_mem_put(zmgr->mctx, io, sizeof(*io));
10947 return (ISC_R_NOMEMORY);
10952 isc_task_attach(task, &io->task);
10953 ISC_LINK_INIT(io, link);
10954 io->magic = IO_MAGIC;
10956 LOCK(&zmgr->iolock);
10958 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
10961 ISC_LIST_APPEND(zmgr->high, io, link);
10963 ISC_LIST_APPEND(zmgr->low, io, link);
10965 UNLOCK(&zmgr->iolock);
10969 isc_task_send(io->task, &io->event);
10971 return (ISC_R_SUCCESS);
10975 zonemgr_putio(dns_io_t **iop) {
10978 dns_zonemgr_t *zmgr;
10980 REQUIRE(iop != NULL);
10982 REQUIRE(DNS_IO_VALID(io));
10986 INSIST(!ISC_LINK_LINKED(io, link));
10987 INSIST(io->event == NULL);
10990 isc_task_detach(&io->task);
10992 isc_mem_put(zmgr->mctx, io, sizeof(*io));
10994 LOCK(&zmgr->iolock);
10995 INSIST(zmgr->ioactive > 0);
10997 next = HEAD(zmgr->high);
10999 next = HEAD(zmgr->low);
11000 if (next != NULL) {
11002 ISC_LIST_UNLINK(zmgr->high, next, link);
11004 ISC_LIST_UNLINK(zmgr->low, next, link);
11005 INSIST(next->event != NULL);
11007 UNLOCK(&zmgr->iolock);
11009 isc_task_send(next->task, &next->event);
11013 zonemgr_cancelio(dns_io_t *io) {
11014 isc_boolean_t send_event = ISC_FALSE;
11016 REQUIRE(DNS_IO_VALID(io));
11019 * If we are queued to be run then dequeue.
11021 LOCK(&io->zmgr->iolock);
11022 if (ISC_LINK_LINKED(io, link)) {
11024 ISC_LIST_UNLINK(io->zmgr->high, io, link);
11026 ISC_LIST_UNLINK(io->zmgr->low, io, link);
11028 send_event = ISC_TRUE;
11029 INSIST(io->event != NULL);
11031 UNLOCK(&io->zmgr->iolock);
11033 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
11034 isc_task_send(io->task, &io->event);
11039 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
11042 isc_result_t result;
11044 buflen = strlen(path) + strlen(templat) + 2;
11046 buf = isc_mem_get(zone->mctx, buflen);
11050 result = isc_file_template(path, templat, buf, buflen);
11051 if (result != ISC_R_SUCCESS)
11054 result = isc_file_renameunique(path, buf);
11055 if (result != ISC_R_SUCCESS)
11058 dns_zone_log(zone, ISC_LOG_WARNING, "saved '%s' as '%s'",
11062 isc_mem_put(zone->mctx, buf, buflen);
11066 /* Hook for ondestroy notification from a database. */
11069 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
11070 dns_db_t *db = event->sender;
11073 isc_event_free(&event);
11075 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11076 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11077 "database (%p) destroyed", (void*) db);
11082 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
11083 isc_interval_t interval;
11084 isc_uint32_t s, ns;
11085 isc_uint32_t pertic;
11086 isc_result_t result;
11088 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11097 } else if (value <= 10) {
11099 ns = 1000000000 / value;
11103 ns = (1000000000 / value) * 10;
11107 isc_interval_set(&interval, s, ns);
11108 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
11109 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11110 isc_ratelimiter_setpertic(zmgr->rl, pertic);
11112 zmgr->serialqueryrate = value;
11116 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
11117 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11119 return (zmgr->serialqueryrate);
11122 static isc_boolean_t
11123 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11124 isc_sockaddr_t *local, isc_time_t *now)
11127 isc_rwlocktype_t locktype;
11128 isc_result_t result;
11129 isc_uint32_t seconds = isc_time_seconds(now);
11131 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11133 locktype = isc_rwlocktype_read;
11134 RWLOCK(&zmgr->rwlock, locktype);
11135 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11136 if (zmgr->unreachable[i].expire >= seconds &&
11137 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11138 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
11139 result = isc_rwlock_tryupgrade(&zmgr->rwlock);
11140 if (result == ISC_R_SUCCESS) {
11141 locktype = isc_rwlocktype_write;
11142 zmgr->unreachable[i].last = seconds;
11147 RWUNLOCK(&zmgr->rwlock, locktype);
11148 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
11152 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11153 isc_sockaddr_t *local, isc_time_t *now)
11155 isc_uint32_t seconds = isc_time_seconds(now);
11156 isc_uint32_t last = seconds;
11157 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
11159 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11161 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
11162 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11163 /* Existing entry? */
11164 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11165 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
11168 if (zmgr->unreachable[i].expire < seconds)
11170 /* Least recently used slot? */
11171 if (zmgr->unreachable[i].last < last) {
11172 last = zmgr->unreachable[i].last;
11176 if (i < UNREACH_CHACHE_SIZE) {
11178 * Found a existing entry. Update the expire timer and
11179 * last usage timestamps.
11181 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
11182 zmgr->unreachable[i].last = seconds;
11183 } else if (slot != UNREACH_CHACHE_SIZE) {
11185 * Found a empty slot. Add a new entry to the cache.
11187 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
11188 zmgr->unreachable[slot].last = seconds;
11189 zmgr->unreachable[slot].remote = *remote;
11190 zmgr->unreachable[slot].local = *local;
11193 * Replace the least recently used entry in the cache.
11195 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
11196 zmgr->unreachable[oldest].last = seconds;
11197 zmgr->unreachable[oldest].remote = *remote;
11198 zmgr->unreachable[oldest].local = *local;
11200 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
11204 dns_zone_forcereload(dns_zone_t *zone) {
11205 REQUIRE(DNS_ZONE_VALID(zone));
11207 if (zone->type == dns_zone_master)
11211 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
11213 dns_zone_refresh(zone);
11217 dns_zone_isforced(dns_zone_t *zone) {
11218 REQUIRE(DNS_ZONE_VALID(zone));
11220 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
11224 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
11226 * This function is obsoleted.
11230 return (ISC_R_NOTIMPLEMENTED);
11234 dns_zone_getstatscounters(dns_zone_t *zone) {
11236 * This function is obsoleted.
11243 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
11244 REQUIRE(DNS_ZONE_VALID(zone));
11245 REQUIRE(zone->stats == NULL);
11248 zone->stats = NULL;
11249 isc_stats_attach(stats, &zone->stats);
11254 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
11255 REQUIRE(DNS_ZONE_VALID(zone));
11258 if (zone->requeststats_on && stats == NULL)
11259 zone->requeststats_on = ISC_FALSE;
11260 else if (!zone->requeststats_on && stats != NULL) {
11261 if (zone->requeststats == NULL) {
11262 isc_stats_attach(stats, &zone->requeststats);
11263 zone->requeststats_on = ISC_TRUE;
11272 dns_zone_getrequeststats(dns_zone_t *zone) {
11274 * We don't lock zone for efficiency reason. This is not catastrophic
11275 * because requeststats must always be valid when requeststats_on is
11277 * Some counters may be incremented while requeststats_on is becoming
11278 * false, or some cannot be incremented just after the statistics are
11279 * installed, but it shouldn't matter much in practice.
11281 if (zone->requeststats_on)
11282 return (zone->requeststats);
11288 dns_zone_dialup(dns_zone_t *zone) {
11290 REQUIRE(DNS_ZONE_VALID(zone));
11292 zone_debuglog(zone, "dns_zone_dialup", 3,
11293 "notify = %d, refresh = %d",
11294 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
11295 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
11297 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
11298 dns_zone_notify(zone);
11299 if (zone->type != dns_zone_master &&
11300 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11301 dns_zone_refresh(zone);
11305 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
11306 REQUIRE(DNS_ZONE_VALID(zone));
11309 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
11310 DNS_ZONEFLG_DIALREFRESH |
11311 DNS_ZONEFLG_NOREFRESH);
11313 case dns_dialuptype_no:
11315 case dns_dialuptype_yes:
11316 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
11317 DNS_ZONEFLG_DIALREFRESH |
11318 DNS_ZONEFLG_NOREFRESH));
11320 case dns_dialuptype_notify:
11321 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11323 case dns_dialuptype_notifypassive:
11324 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11325 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11327 case dns_dialuptype_refresh:
11328 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
11329 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11331 case dns_dialuptype_passive:
11332 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11341 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
11342 isc_result_t result = ISC_R_SUCCESS;
11344 REQUIRE(DNS_ZONE_VALID(zone));
11347 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
11354 dns_zone_getkeydirectory(dns_zone_t *zone) {
11355 REQUIRE(DNS_ZONE_VALID(zone));
11357 return (zone->keydirectory);
11361 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
11363 unsigned int count = 0;
11365 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11367 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11369 case DNS_ZONESTATE_XFERRUNNING:
11370 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
11372 zone = ISC_LIST_NEXT(zone, statelink))
11375 case DNS_ZONESTATE_XFERDEFERRED:
11376 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
11378 zone = ISC_LIST_NEXT(zone, statelink))
11381 case DNS_ZONESTATE_SOAQUERY:
11382 for (zone = ISC_LIST_HEAD(zmgr->zones);
11384 zone = ISC_LIST_NEXT(zone, link))
11385 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
11388 case DNS_ZONESTATE_ANY:
11389 for (zone = ISC_LIST_HEAD(zmgr->zones);
11391 zone = ISC_LIST_NEXT(zone, link)) {
11392 dns_view_t *view = zone->view;
11393 if (view != NULL && strcmp(view->name, "_bind") == 0)
11402 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11408 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
11409 isc_boolean_t ok = ISC_TRUE;
11410 isc_boolean_t fail = ISC_FALSE;
11411 char namebuf[DNS_NAME_FORMATSIZE];
11412 char namebuf2[DNS_NAME_FORMATSIZE];
11413 char typebuf[DNS_RDATATYPE_FORMATSIZE];
11414 int level = ISC_LOG_WARNING;
11417 REQUIRE(DNS_ZONE_VALID(zone));
11419 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
11420 return (ISC_R_SUCCESS);
11422 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
11423 level = ISC_LOG_ERROR;
11427 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
11429 dns_name_format(name, namebuf, sizeof(namebuf));
11430 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11431 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
11432 dns_result_totext(DNS_R_BADOWNERNAME));
11434 return (DNS_R_BADOWNERNAME);
11437 dns_name_init(&bad, NULL);
11438 ok = dns_rdata_checknames(rdata, name, &bad);
11440 dns_name_format(name, namebuf, sizeof(namebuf));
11441 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
11442 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11443 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
11444 namebuf2, dns_result_totext(DNS_R_BADNAME));
11446 return (DNS_R_BADNAME);
11449 return (ISC_R_SUCCESS);
11453 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
11454 REQUIRE(DNS_ZONE_VALID(zone));
11455 zone->checkmx = checkmx;
11459 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
11460 REQUIRE(DNS_ZONE_VALID(zone));
11461 zone->checksrv = checksrv;
11465 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
11466 REQUIRE(DNS_ZONE_VALID(zone));
11467 zone->checkns = checkns;
11471 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
11472 REQUIRE(DNS_ZONE_VALID(zone));
11475 zone->isself = isself;
11476 zone->isselfarg = arg;
11481 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
11482 REQUIRE(DNS_ZONE_VALID(zone));
11485 zone->notifydelay = delay;
11490 dns_zone_getnotifydelay(dns_zone_t *zone) {
11491 REQUIRE(DNS_ZONE_VALID(zone));
11493 return (zone->notifydelay);
11497 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
11498 isc_uint16_t keyid, isc_boolean_t delete)
11500 isc_result_t result;
11501 REQUIRE(DNS_ZONE_VALID(zone));
11503 dns_zone_log(zone, ISC_LOG_NOTICE,
11504 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
11507 result = zone_signwithkey(zone, algorithm, keyid, delete);
11513 static const char *hex = "0123456789ABCDEF";
11516 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
11517 isc_result_t result;
11518 char salt[255*2+1];
11521 REQUIRE(DNS_ZONE_VALID(zone));
11523 if (nsec3param->salt_length != 0) {
11524 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
11525 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
11526 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
11527 salt[j++] = hex[nsec3param->salt[i] & 0xf];
11532 dns_zone_log(zone, ISC_LOG_NOTICE,
11533 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
11534 nsec3param->hash, nsec3param->iterations,
11537 result = zone_addnsec3chain(zone, nsec3param);
11544 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
11545 REQUIRE(DNS_ZONE_VALID(zone));
11549 zone->nodes = nodes;
11553 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
11554 REQUIRE(DNS_ZONE_VALID(zone));
11557 * We treat signatures as a signed value so explicitly
11558 * limit its range here.
11560 if (signatures > ISC_INT32_MAX)
11561 signatures = ISC_INT32_MAX;
11562 else if (signatures == 0)
11564 zone->signatures = signatures;
11568 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
11569 REQUIRE(DNS_ZONE_VALID(zone));
11570 zone->privatetype = type;
11574 dns_zone_getprivatetype(dns_zone_t *zone) {
11575 REQUIRE(DNS_ZONE_VALID(zone));
11576 return (zone->privatetype);
11579 static isc_result_t
11580 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
11581 isc_boolean_t delete)
11583 dns_signing_t *signing;
11584 dns_signing_t *current;
11585 isc_result_t result = ISC_R_SUCCESS;
11588 signing = isc_mem_get(zone->mctx, sizeof *signing);
11589 if (signing == NULL)
11590 return (ISC_R_NOMEMORY);
11592 signing->magic = 0;
11593 signing->db = NULL;
11594 signing->dbiterator = NULL;
11595 signing->algorithm = algorithm;
11596 signing->keyid = keyid;
11597 signing->delete = delete;
11598 signing->done = ISC_FALSE;
11602 for (current = ISC_LIST_HEAD(zone->signing);
11604 current = ISC_LIST_NEXT(current, link)) {
11605 if (current->db == zone->db &&
11606 current->algorithm == signing->algorithm &&
11607 current->keyid == signing->keyid) {
11608 if (current->delete != signing->delete)
11609 current->done = ISC_TRUE;
11615 if (zone->db != NULL) {
11616 dns_db_attach(zone->db, &signing->db);
11617 result = dns_db_createiterator(signing->db, 0,
11618 &signing->dbiterator);
11620 if (result == ISC_R_SUCCESS)
11621 result = dns_dbiterator_first(signing->dbiterator);
11622 if (result == ISC_R_SUCCESS) {
11623 dns_dbiterator_pause(signing->dbiterator);
11624 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
11626 if (isc_time_isepoch(&zone->signingtime)) {
11627 zone->signingtime = now;
11628 if (zone->task != NULL)
11629 zone_settimer(zone, &now);
11633 result = ISC_R_NOTFOUND;
11636 if (signing != NULL) {
11637 if (signing->db != NULL)
11638 dns_db_detach(&signing->db);
11639 if (signing->dbiterator != NULL)
11640 dns_dbiterator_destroy(&signing->dbiterator);
11641 isc_mem_put(zone->mctx, signing, sizeof *signing);