2 * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
27 #include <isc/mutex.h>
28 #include <isc/print.h>
29 #include <isc/random.h>
30 #include <isc/ratelimiter.h>
31 #include <isc/refcount.h>
32 #include <isc/rwlock.h>
33 #include <isc/serial.h>
34 #include <isc/strerror.h>
35 #include <isc/stats.h>
36 #include <isc/stdtime.h>
37 #include <isc/string.h>
38 #include <isc/taskpool.h>
39 #include <isc/timer.h>
42 #include <dns/acache.h>
45 #include <dns/callbacks.h>
47 #include <dns/dbiterator.h>
48 #include <dns/dnssec.h>
49 #include <dns/events.h>
50 #include <dns/journal.h>
51 #include <dns/keyvalues.h>
53 #include <dns/master.h>
54 #include <dns/masterdump.h>
55 #include <dns/message.h>
58 #include <dns/nsec3.h>
60 #include <dns/rcode.h>
61 #include <dns/rdataclass.h>
62 #include <dns/rdatalist.h>
63 #include <dns/rdataset.h>
64 #include <dns/rdatasetiter.h>
65 #include <dns/rdatastruct.h>
66 #include <dns/rdatatype.h>
67 #include <dns/request.h>
68 #include <dns/resolver.h>
69 #include <dns/result.h>
72 #include <dns/stats.h>
75 #include <dns/xfrin.h>
80 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
81 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
83 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
84 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
86 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
87 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
89 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
90 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
92 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
93 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
95 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
96 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
98 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
99 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
102 * Ensure 'a' is at least 'min' but not more than 'max'.
104 #define RANGE(a, min, max) \
105 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
107 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
112 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
113 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
114 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
116 #ifndef DNS_MAX_EXPIRE
117 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
120 #ifndef DNS_DUMP_DELAY
121 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
124 typedef struct dns_notify dns_notify_t;
125 typedef struct dns_stub dns_stub_t;
126 typedef struct dns_load dns_load_t;
127 typedef struct dns_forward dns_forward_t;
128 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
129 typedef struct dns_io dns_io_t;
130 typedef ISC_LIST(dns_io_t) dns_iolist_t;
131 typedef struct dns_signing dns_signing_t;
132 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
133 typedef struct dns_nsec3chain dns_nsec3chain_t;
134 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
136 #define DNS_ZONE_CHECKLOCK
137 #ifdef DNS_ZONE_CHECKLOCK
138 #define LOCK_ZONE(z) \
139 do { LOCK(&(z)->lock); \
140 INSIST((z)->locked == ISC_FALSE); \
141 (z)->locked = ISC_TRUE; \
143 #define UNLOCK_ZONE(z) \
144 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
145 #define LOCKED_ZONE(z) ((z)->locked)
147 #define LOCK_ZONE(z) LOCK(&(z)->lock)
148 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
149 #define LOCKED_ZONE(z) ISC_TRUE
152 #ifdef ISC_RWLOCK_USEATOMIC
153 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
154 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
155 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
156 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
158 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
159 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
160 #define ZONEDB_LOCK(l, t) LOCK(l)
161 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
168 #ifdef DNS_ZONE_CHECKLOCK
169 isc_boolean_t locked;
172 isc_refcount_t erefs;
174 #ifdef ISC_RWLOCK_USEATOMIC
179 dns_db_t *db; /* Locked by dblock */
183 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
188 dns_masterformat_t masterformat;
190 isc_int32_t journalsize;
191 dns_rdataclass_t rdclass;
194 unsigned int options;
195 unsigned int db_argc;
197 isc_time_t expiretime;
198 isc_time_t refreshtime;
201 isc_time_t notifytime;
202 isc_time_t resigntime;
203 isc_time_t keywarntime;
204 isc_time_t signingtime;
205 isc_time_t nsec3chaintime;
206 isc_uint32_t refresh;
209 isc_uint32_t minimum;
210 isc_stdtime_t key_expiry;
213 isc_uint32_t maxrefresh;
214 isc_uint32_t minrefresh;
215 isc_uint32_t maxretry;
216 isc_uint32_t minretry;
218 isc_sockaddr_t *masters;
219 dns_name_t **masterkeynames;
220 isc_boolean_t *mastersok;
221 unsigned int masterscnt;
222 unsigned int curmaster;
223 isc_sockaddr_t masteraddr;
224 dns_notifytype_t notifytype;
225 isc_sockaddr_t *notify;
226 unsigned int notifycnt;
227 isc_sockaddr_t notifyfrom;
229 isc_sockaddr_t notifysrc4;
230 isc_sockaddr_t notifysrc6;
231 isc_sockaddr_t xfrsource4;
232 isc_sockaddr_t xfrsource6;
233 isc_sockaddr_t altxfrsource4;
234 isc_sockaddr_t altxfrsource6;
235 isc_sockaddr_t sourceaddr;
236 dns_xfrin_ctx_t *xfr; /* task locked */
237 dns_tsigkey_t *tsigkey; /* key used for xfr */
238 /* Access Control Lists */
239 dns_acl_t *update_acl;
240 dns_acl_t *forward_acl;
241 dns_acl_t *notify_acl;
242 dns_acl_t *query_acl;
243 dns_acl_t *queryon_acl;
245 isc_boolean_t update_disabled;
246 isc_boolean_t zero_no_soa_ttl;
247 dns_severity_t check_names;
248 ISC_LIST(dns_notify_t) notifies;
249 dns_request_t *request;
254 isc_uint32_t maxxfrin;
255 isc_uint32_t maxxfrout;
257 isc_uint32_t idleout;
258 isc_event_t ctlevent;
259 dns_ssutable_t *ssutable;
260 isc_uint32_t sigvalidityinterval;
261 isc_uint32_t sigresigninginterval;
263 dns_acache_t *acache;
264 dns_checkmxfunc_t checkmx;
265 dns_checksrvfunc_t checksrv;
266 dns_checknsfunc_t checkns;
268 * Zones in certain states such as "waiting for zone transfer"
269 * or "zone transfer in progress" are kept on per-state linked lists
270 * in the zone manager using the 'statelink' field. The 'statelist'
271 * field points at the list the zone is currently on. It the zone
272 * is not on any such list, statelist is NULL.
274 ISC_LINK(dns_zone_t) statelink;
275 dns_zonelist_t *statelist;
277 * Statistics counters about zone management.
281 * Optional per-zone statistics counters. Counted outside of this
284 isc_boolean_t requeststats_on;
285 isc_stats_t *requeststats;
286 isc_uint32_t notifydelay;
287 dns_isselffunc_t isself;
296 * Serial number for deferred journal compaction.
298 isc_uint32_t compact_serial;
300 * Keys that are signing the zone for the first time.
302 dns_signinglist_t signing;
303 dns_nsec3chainlist_t nsec3chain;
305 * Signing / re-signing quantum stopping parameters.
307 isc_uint32_t signatures;
309 dns_rdatatype_t privatetype;
312 * Outstanding forwarded UPDATE requests.
314 dns_forwardlist_t forwards;
317 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
318 #define DNS_ZONE_SETFLAG(z,f) do { \
319 INSIST(LOCKED_ZONE(z)); \
322 #define DNS_ZONE_CLRFLAG(z,f) do { \
323 INSIST(LOCKED_ZONE(z)); \
324 (z)->flags &= ~(f); \
326 /* XXX MPA these may need to go back into zone.h */
327 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
328 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
329 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
330 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
331 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
332 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
333 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
334 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
335 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
336 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
338 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
340 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
342 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
343 * zone with no masters
345 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
346 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
347 * from SOA (if not set, we
349 * default timer values) */
350 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
351 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
352 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
353 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
354 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
355 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
356 #define DNS_ZONEFLG_FLUSH 0x00200000U
357 #define DNS_ZONEFLG_NOEDNS 0x00400000U
358 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
359 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
360 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
361 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
362 #define DNS_ZONEFLG_THAW 0x08000000U
364 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
366 /* Flags for zone_load() */
367 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
368 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
371 #define UNREACH_CHACHE_SIZE 10U
372 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
375 do { result = (op); \
376 if (result != ISC_R_SUCCESS) goto failure; \
379 struct dns_unreachable {
380 isc_sockaddr_t remote;
381 isc_sockaddr_t local;
389 int refs; /* Locked by rwlock */
390 isc_taskmgr_t * taskmgr;
391 isc_timermgr_t * timermgr;
392 isc_socketmgr_t * socketmgr;
393 isc_taskpool_t * zonetasks;
395 isc_ratelimiter_t * rl;
400 /* Locked by rwlock. */
401 dns_zonelist_t zones;
402 dns_zonelist_t waiting_for_xfrin;
403 dns_zonelist_t xfrin_in_progress;
405 /* Configuration data. */
406 isc_uint32_t transfersin;
407 isc_uint32_t transfersperns;
408 unsigned int serialqueryrate;
410 /* Locked by iolock */
411 isc_uint32_t iolimit;
412 isc_uint32_t ioactive;
416 /* Locked by urlock. */
418 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
430 dns_request_t *request;
433 ISC_LINK(dns_notify_t) link;
436 #define DNS_NOTIFY_NOSOA 0x0001U
439 * dns_stub holds state while performing a 'stub' transfer.
440 * 'db' is the zone's 'db' or a new one if this is the initial
449 dns_dbversion_t *version;
461 dns_rdatacallbacks_t callbacks;
465 * Hold forward state.
471 isc_buffer_t *msgbuf;
472 dns_request_t *request;
475 dns_updatecallback_t callback;
477 ISC_LINK(dns_forward_t) link;
481 * Hold IO request state.
488 ISC_LINK(dns_io_t) link;
493 * Hold state for when we are signing a zone with a new
494 * DNSKEY as result of an update.
499 dns_dbiterator_t *dbiterator;
500 dns_secalg_t algorithm;
502 isc_boolean_t delete;
504 ISC_LINK(dns_signing_t) link;
507 struct dns_nsec3chain {
510 dns_dbiterator_t *dbiterator;
511 dns_rdata_nsec3param_t nsec3param;
512 unsigned char salt[255];
514 isc_boolean_t seen_nsec;
515 isc_boolean_t delete_nsec;
516 isc_boolean_t save_delete_nsec;
517 ISC_LINK(dns_nsec3chain_t) link;
520 * 'dbiterator' contains a iterator for the database. If we are creating
521 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
522 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
525 * 'nsec3param' contains the parameters of the NSEC3 chain being created
528 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
530 * 'seen_nsec' will be set to true if, while iterating the zone to create a
531 * NSEC3 chain, a NSEC record is seen.
533 * 'delete_nsec' will be set to true if, at the completion of the creation
534 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
535 * are in the process of deleting the NSEC chain.
537 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
538 * so it can be recovered in the event of a error.
542 #define SEND_BUFFER_SIZE 2048
544 static void zone_settimer(dns_zone_t *, isc_time_t *);
545 static void cancel_refresh(dns_zone_t *);
546 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
547 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
548 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
549 ISC_FORMAT_PRINTF(3, 4);
550 static void queue_xfrin(dns_zone_t *zone);
551 static void zone_unload(dns_zone_t *zone);
552 static void zone_expire(dns_zone_t *zone);
553 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
554 static void zone_idetach(dns_zone_t **zonep);
555 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
557 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
558 static inline void zone_detachdb(dns_zone_t *zone);
559 static isc_result_t default_journal(dns_zone_t *zone);
560 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
561 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
562 isc_time_t loadtime, isc_result_t result);
563 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
564 static void zone_shutdown(isc_task_t *, isc_event_t *);
565 static void zone_loaddone(void *arg, isc_result_t result);
566 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
567 isc_time_t loadtime);
568 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
569 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
570 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
571 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
574 /* ondestroy example */
575 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
578 static void refresh_callback(isc_task_t *, isc_event_t *);
579 static void stub_callback(isc_task_t *, isc_event_t *);
580 static void queue_soa_query(dns_zone_t *zone);
581 static void soa_query(isc_task_t *, isc_event_t *);
582 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
584 static int message_count(dns_message_t *msg, dns_section_t section,
585 dns_rdatatype_t type);
586 static void notify_cancel(dns_zone_t *zone);
587 static void notify_find_address(dns_notify_t *notify);
588 static void notify_send(dns_notify_t *notify);
589 static isc_result_t notify_createmessage(dns_zone_t *zone,
591 dns_message_t **messagep);
592 static void notify_done(isc_task_t *task, isc_event_t *event);
593 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
594 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
595 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
596 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
598 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
599 static void zonemgr_free(dns_zonemgr_t *zmgr);
600 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
601 isc_task_t *task, isc_taskaction_t action,
602 void *arg, dns_io_t **iop);
603 static void zonemgr_putio(dns_io_t **iop);
604 static void zonemgr_cancelio(dns_io_t *io);
607 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
608 unsigned int *soacount, isc_uint32_t *serial,
609 isc_uint32_t *refresh, isc_uint32_t *retry,
610 isc_uint32_t *expire, isc_uint32_t *minimum,
611 unsigned int *errors);
613 static void zone_freedbargs(dns_zone_t *zone);
614 static void forward_callback(isc_task_t *task, isc_event_t *event);
615 static void zone_saveunique(dns_zone_t *zone, const char *path,
616 const char *templat);
617 static void zone_maintenance(dns_zone_t *zone);
618 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
619 static void dump_done(void *arg, isc_result_t result);
620 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
621 isc_uint16_t keyid, isc_boolean_t delete);
623 #define ENTER zone_debuglog(zone, me, 1, "enter")
625 static const unsigned int dbargc_default = 1;
626 static const char *dbargv_default[] = { "rbt" };
628 #define DNS_ZONE_JITTER_ADD(a, b, c) \
632 _j = isc_random_jitter((b), (b)/4); \
633 isc_interval_set(&_i, _j, 0); \
634 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
635 dns_zone_log(zone, ISC_LOG_WARNING, \
636 "epoch approaching: upgrade required: " \
637 "now + %s failed", #b); \
638 isc_interval_set(&_i, _j/2, 0); \
639 (void)isc_time_add((a), &_i, (c)); \
643 #define DNS_ZONE_TIME_ADD(a, b, c) \
646 isc_interval_set(&_i, (b), 0); \
647 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
648 dns_zone_log(zone, ISC_LOG_WARNING, \
649 "epoch approaching: upgrade required: " \
650 "now + %s failed", #b); \
651 isc_interval_set(&_i, (b)/2, 0); \
652 (void)isc_time_add((a), &_i, (c)); \
657 * Increment resolver-related statistics counters. Zone must be locked.
660 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
661 if (zone->stats != NULL)
662 isc_stats_increment(zone->stats, counter);
666 *** Public functions.
670 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
675 REQUIRE(zonep != NULL && *zonep == NULL);
676 REQUIRE(mctx != NULL);
679 zone = isc_mem_get(mctx, sizeof(*zone));
681 return (ISC_R_NOMEMORY);
684 isc_mem_attach(mctx, &zone->mctx);
686 result = isc_mutex_init(&zone->lock);
687 if (result != ISC_R_SUCCESS)
690 result = ZONEDB_INITLOCK(&zone->dblock);
691 if (result != ISC_R_SUCCESS)
694 /* XXX MPA check that all elements are initialised */
695 #ifdef DNS_ZONE_CHECKLOCK
696 zone->locked = ISC_FALSE;
700 ISC_LINK_INIT(zone, link);
701 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
702 if (result != ISC_R_SUCCESS)
705 dns_name_init(&zone->origin, NULL);
706 zone->strnamerd = NULL;
707 zone->strname = NULL;
708 zone->strrdclass = NULL;
709 zone->strviewname = NULL;
710 zone->masterfile = NULL;
711 zone->masterformat = dns_masterformat_none;
712 zone->keydirectory = NULL;
713 zone->journalsize = -1;
714 zone->journal = NULL;
715 zone->rdclass = dns_rdataclass_none;
716 zone->type = dns_zone_none;
720 zone->db_argv = NULL;
721 isc_time_settoepoch(&zone->expiretime);
722 isc_time_settoepoch(&zone->refreshtime);
723 isc_time_settoepoch(&zone->dumptime);
724 isc_time_settoepoch(&zone->loadtime);
725 zone->notifytime = now;
726 isc_time_settoepoch(&zone->resigntime);
727 isc_time_settoepoch(&zone->keywarntime);
728 isc_time_settoepoch(&zone->signingtime);
729 isc_time_settoepoch(&zone->nsec3chaintime);
730 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
731 zone->retry = DNS_ZONE_DEFAULTRETRY;
734 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
735 zone->minrefresh = DNS_ZONE_MINREFRESH;
736 zone->maxretry = DNS_ZONE_MAXRETRY;
737 zone->minretry = DNS_ZONE_MINRETRY;
738 zone->masters = NULL;
739 zone->masterkeynames = NULL;
740 zone->mastersok = NULL;
741 zone->masterscnt = 0;
744 zone->notifytype = dns_notifytype_yes;
747 zone->update_acl = NULL;
748 zone->forward_acl = NULL;
749 zone->notify_acl = NULL;
750 zone->query_acl = NULL;
751 zone->queryon_acl = NULL;
752 zone->xfr_acl = NULL;
753 zone->update_disabled = ISC_FALSE;
754 zone->zero_no_soa_ttl = ISC_TRUE;
755 zone->check_names = dns_severity_ignore;
756 zone->request = NULL;
760 zone->writeio = NULL;
762 zone->idlein = DNS_DEFAULT_IDLEIN;
763 zone->idleout = DNS_DEFAULT_IDLEOUT;
764 ISC_LIST_INIT(zone->notifies);
765 isc_sockaddr_any(&zone->notifysrc4);
766 isc_sockaddr_any6(&zone->notifysrc6);
767 isc_sockaddr_any(&zone->xfrsource4);
768 isc_sockaddr_any6(&zone->xfrsource6);
769 isc_sockaddr_any(&zone->altxfrsource4);
770 isc_sockaddr_any6(&zone->altxfrsource6);
772 zone->tsigkey = NULL;
773 zone->maxxfrin = MAX_XFER_TIME;
774 zone->maxxfrout = MAX_XFER_TIME;
775 zone->ssutable = NULL;
776 zone->sigvalidityinterval = 30 * 24 * 3600;
777 zone->sigresigninginterval = 7 * 24 * 3600;
780 zone->checkmx = NULL;
781 zone->checksrv = NULL;
782 zone->checkns = NULL;
783 ISC_LINK_INIT(zone, statelink);
784 zone->statelist = NULL;
786 zone->requeststats_on = ISC_FALSE;
787 zone->requeststats = NULL;
788 zone->notifydelay = 5;
790 zone->isselfarg = NULL;
791 ISC_LIST_INIT(zone->signing);
792 ISC_LIST_INIT(zone->nsec3chain);
793 zone->signatures = 10;
795 zone->privatetype = (dns_rdatatype_t)0xffffU;
796 ISC_LIST_INIT(zone->forwards);
798 zone->magic = ZONE_MAGIC;
800 /* Must be after magic is set. */
801 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
802 if (result != ISC_R_SUCCESS)
805 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
806 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
809 return (ISC_R_SUCCESS);
812 isc_refcount_decrement(&zone->erefs, NULL);
813 isc_refcount_destroy(&zone->erefs);
816 ZONEDB_DESTROYLOCK(&zone->dblock);
819 DESTROYLOCK(&zone->lock);
822 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
827 * Free a zone. Because we require that there be no more
828 * outstanding events or references, no locking is necessary.
831 zone_free(dns_zone_t *zone) {
832 isc_mem_t *mctx = NULL;
833 dns_signing_t *signing;
834 dns_nsec3chain_t *nsec3chain;
836 REQUIRE(DNS_ZONE_VALID(zone));
837 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
838 REQUIRE(zone->irefs == 0);
839 REQUIRE(!LOCKED_ZONE(zone));
840 REQUIRE(zone->timer == NULL);
843 * Managed objects. Order is important.
845 if (zone->request != NULL)
846 dns_request_destroy(&zone->request); /* XXXMPA */
847 INSIST(zone->readio == NULL);
848 INSIST(zone->statelist == NULL);
849 INSIST(zone->writeio == NULL);
851 if (zone->task != NULL)
852 isc_task_detach(&zone->task);
853 if (zone->zmgr != NULL)
854 dns_zonemgr_releasezone(zone->zmgr, zone);
856 /* Unmanaged objects */
857 for (signing = ISC_LIST_HEAD(zone->signing);
859 signing = ISC_LIST_HEAD(zone->signing)) {
860 ISC_LIST_UNLINK(zone->signing, signing, link);
861 dns_db_detach(&signing->db);
862 dns_dbiterator_destroy(&signing->dbiterator);
863 isc_mem_put(zone->mctx, signing, sizeof *signing);
865 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
867 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
868 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
869 dns_db_detach(&nsec3chain->db);
870 dns_dbiterator_destroy(&nsec3chain->dbiterator);
871 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
873 if (zone->masterfile != NULL)
874 isc_mem_free(zone->mctx, zone->masterfile);
875 zone->masterfile = NULL;
876 if (zone->keydirectory != NULL)
877 isc_mem_free(zone->mctx, zone->keydirectory);
878 zone->keydirectory = NULL;
879 zone->journalsize = -1;
880 if (zone->journal != NULL)
881 isc_mem_free(zone->mctx, zone->journal);
882 zone->journal = NULL;
883 if (zone->stats != NULL)
884 isc_stats_detach(&zone->stats);
885 if (zone->requeststats != NULL)
886 isc_stats_detach(&zone->requeststats);
887 if (zone->db != NULL)
889 if (zone->acache != NULL)
890 dns_acache_detach(&zone->acache);
891 zone_freedbargs(zone);
892 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
894 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
896 zone->check_names = dns_severity_ignore;
897 if (zone->update_acl != NULL)
898 dns_acl_detach(&zone->update_acl);
899 if (zone->forward_acl != NULL)
900 dns_acl_detach(&zone->forward_acl);
901 if (zone->notify_acl != NULL)
902 dns_acl_detach(&zone->notify_acl);
903 if (zone->query_acl != NULL)
904 dns_acl_detach(&zone->query_acl);
905 if (zone->queryon_acl != NULL)
906 dns_acl_detach(&zone->queryon_acl);
907 if (zone->xfr_acl != NULL)
908 dns_acl_detach(&zone->xfr_acl);
909 if (dns_name_dynamic(&zone->origin))
910 dns_name_free(&zone->origin, zone->mctx);
911 if (zone->strnamerd != NULL)
912 isc_mem_free(zone->mctx, zone->strnamerd);
913 if (zone->strname != NULL)
914 isc_mem_free(zone->mctx, zone->strname);
915 if (zone->strrdclass != NULL)
916 isc_mem_free(zone->mctx, zone->strrdclass);
917 if (zone->strviewname != NULL)
918 isc_mem_free(zone->mctx, zone->strviewname);
919 if (zone->ssutable != NULL)
920 dns_ssutable_detach(&zone->ssutable);
923 ZONEDB_DESTROYLOCK(&zone->dblock);
924 DESTROYLOCK(&zone->lock);
925 isc_refcount_destroy(&zone->erefs);
928 isc_mem_put(mctx, zone, sizeof(*zone));
929 isc_mem_detach(&mctx);
936 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
939 REQUIRE(DNS_ZONE_VALID(zone));
940 REQUIRE(rdclass != dns_rdataclass_none);
946 REQUIRE(zone->rdclass == dns_rdataclass_none ||
947 zone->rdclass == rdclass);
948 zone->rdclass = rdclass;
950 if (zone->strnamerd != NULL)
951 isc_mem_free(zone->mctx, zone->strnamerd);
952 if (zone->strrdclass != NULL)
953 isc_mem_free(zone->mctx, zone->strrdclass);
955 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
956 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
957 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
958 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
964 dns_zone_getclass(dns_zone_t *zone) {
965 REQUIRE(DNS_ZONE_VALID(zone));
967 return (zone->rdclass);
971 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
972 REQUIRE(DNS_ZONE_VALID(zone));
975 zone->notifytype = notifytype;
980 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
983 REQUIRE(DNS_ZONE_VALID(zone));
984 REQUIRE(serialp != NULL);
987 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
988 if (zone->db != NULL) {
989 result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
990 NULL, NULL, NULL, NULL, NULL);
992 result = DNS_R_NOTLOADED;
993 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1000 dns_zone_getserial(dns_zone_t *zone) {
1001 isc_result_t result;
1002 isc_uint32_t serial;
1004 result = dns_zone_getserial2(zone, &serial);
1005 if (result != ISC_R_SUCCESS)
1006 serial = 0; /* XXX: not really correct, but no other choice */
1015 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1017 REQUIRE(DNS_ZONE_VALID(zone));
1018 REQUIRE(type != dns_zone_none);
1024 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1030 zone_freedbargs(dns_zone_t *zone) {
1033 /* Free the old database argument list. */
1034 if (zone->db_argv != NULL) {
1035 for (i = 0; i < zone->db_argc; i++)
1036 isc_mem_free(zone->mctx, zone->db_argv[i]);
1037 isc_mem_put(zone->mctx, zone->db_argv,
1038 zone->db_argc * sizeof(*zone->db_argv));
1041 zone->db_argv = NULL;
1045 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1048 isc_result_t result = ISC_R_SUCCESS;
1052 REQUIRE(DNS_ZONE_VALID(zone));
1053 REQUIRE(argv != NULL && *argv == NULL);
1056 size = (zone->db_argc + 1) * sizeof(char *);
1057 for (i = 0; i < zone->db_argc; i++)
1058 size += strlen(zone->db_argv[i]) + 1;
1059 mem = isc_mem_allocate(mctx, size);
1063 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1064 for (i = 0; i < zone->db_argc; i++) {
1066 strcpy(tmp2, zone->db_argv[i]);
1067 tmp2 += strlen(tmp2) + 1;
1071 result = ISC_R_NOMEMORY;
1078 dns_zone_setdbtype(dns_zone_t *zone,
1079 unsigned int dbargc, const char * const *dbargv) {
1080 isc_result_t result = ISC_R_SUCCESS;
1084 REQUIRE(DNS_ZONE_VALID(zone));
1085 REQUIRE(dbargc >= 1);
1086 REQUIRE(dbargv != NULL);
1090 /* Set up a new database argument list. */
1091 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1094 for (i = 0; i < dbargc; i++)
1096 for (i = 0; i < dbargc; i++) {
1097 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1102 /* Free the old list. */
1103 zone_freedbargs(zone);
1105 zone->db_argc = dbargc;
1106 zone->db_argv = new;
1107 result = ISC_R_SUCCESS;
1112 for (i = 0; i < dbargc; i++)
1114 isc_mem_free(zone->mctx, new[i]);
1115 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1117 result = ISC_R_NOMEMORY;
1125 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1127 REQUIRE(DNS_ZONE_VALID(zone));
1130 if (zone->view != NULL)
1131 dns_view_weakdetach(&zone->view);
1132 dns_view_weakattach(view, &zone->view);
1134 if (zone->strviewname != NULL)
1135 isc_mem_free(zone->mctx, zone->strviewname);
1136 if (zone->strnamerd != NULL)
1137 isc_mem_free(zone->mctx, zone->strnamerd);
1139 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1140 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1141 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1142 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1149 dns_zone_getview(dns_zone_t *zone) {
1150 REQUIRE(DNS_ZONE_VALID(zone));
1152 return (zone->view);
1157 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1158 isc_result_t result;
1161 REQUIRE(DNS_ZONE_VALID(zone));
1162 REQUIRE(origin != NULL);
1165 if (dns_name_dynamic(&zone->origin)) {
1166 dns_name_free(&zone->origin, zone->mctx);
1167 dns_name_init(&zone->origin, NULL);
1169 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1171 if (zone->strnamerd != NULL)
1172 isc_mem_free(zone->mctx, zone->strnamerd);
1173 if (zone->strname != NULL)
1174 isc_mem_free(zone->mctx, zone->strname);
1176 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1177 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1178 zone_name_tostr(zone, namebuf, sizeof namebuf);
1179 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1186 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1187 REQUIRE(DNS_ZONE_VALID(zone));
1188 REQUIRE(acache != NULL);
1191 if (zone->acache != NULL)
1192 dns_acache_detach(&zone->acache);
1193 dns_acache_attach(acache, &zone->acache);
1194 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1195 if (zone->db != NULL) {
1196 isc_result_t result;
1199 * If the zone reuses an existing DB, the DB needs to be
1200 * set in the acache explicitly. We can safely ignore the
1201 * case where the DB is already set. If other error happens,
1202 * the acache will not work effectively.
1204 result = dns_acache_setdb(acache, zone->db);
1205 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1206 UNEXPECTED_ERROR(__FILE__, __LINE__,
1207 "dns_acache_setdb() failed: %s",
1208 isc_result_totext(result));
1211 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1216 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1219 if (value != NULL) {
1220 copy = isc_mem_strdup(zone->mctx, value);
1222 return (ISC_R_NOMEMORY);
1228 isc_mem_free(zone->mctx, *field);
1231 return (ISC_R_SUCCESS);
1235 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1236 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1240 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1241 dns_masterformat_t format) {
1242 isc_result_t result = ISC_R_SUCCESS;
1244 REQUIRE(DNS_ZONE_VALID(zone));
1247 result = dns_zone_setstring(zone, &zone->masterfile, file);
1248 if (result == ISC_R_SUCCESS) {
1249 zone->masterformat = format;
1250 result = default_journal(zone);
1258 dns_zone_getfile(dns_zone_t *zone) {
1259 REQUIRE(DNS_ZONE_VALID(zone));
1261 return (zone->masterfile);
1265 default_journal(dns_zone_t *zone) {
1266 isc_result_t result;
1269 REQUIRE(DNS_ZONE_VALID(zone));
1270 REQUIRE(LOCKED_ZONE(zone));
1272 if (zone->masterfile != NULL) {
1273 /* Calculate string length including '\0'. */
1274 int len = strlen(zone->masterfile) + sizeof(".jnl");
1275 journal = isc_mem_allocate(zone->mctx, len);
1276 if (journal == NULL)
1277 return (ISC_R_NOMEMORY);
1278 strcpy(journal, zone->masterfile);
1279 strcat(journal, ".jnl");
1283 result = dns_zone_setstring(zone, &zone->journal, journal);
1284 if (journal != NULL)
1285 isc_mem_free(zone->mctx, journal);
1290 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1291 isc_result_t result = ISC_R_SUCCESS;
1293 REQUIRE(DNS_ZONE_VALID(zone));
1296 result = dns_zone_setstring(zone, &zone->journal, journal);
1303 dns_zone_getjournal(dns_zone_t *zone) {
1304 REQUIRE(DNS_ZONE_VALID(zone));
1306 return (zone->journal);
1310 * Return true iff the zone is "dynamic", in the sense that the zone's
1311 * master file (if any) is written by the server, rather than being
1312 * updated manually and read by the server.
1314 * This is true for slave zones, stub zones, and zones that allow
1315 * dynamic updates either by having an update policy ("ssutable")
1316 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1318 static isc_boolean_t
1319 zone_isdynamic(dns_zone_t *zone) {
1320 REQUIRE(DNS_ZONE_VALID(zone));
1322 return (ISC_TF(zone->type == dns_zone_slave ||
1323 zone->type == dns_zone_stub ||
1324 (!zone->update_disabled && zone->ssutable != NULL) ||
1325 (!zone->update_disabled && zone->update_acl != NULL &&
1326 !dns_acl_isnone(zone->update_acl))));
1331 zone_load(dns_zone_t *zone, unsigned int flags) {
1332 isc_result_t result;
1334 isc_time_t loadtime, filetime;
1335 dns_db_t *db = NULL;
1338 REQUIRE(DNS_ZONE_VALID(zone));
1343 INSIST(zone->type != dns_zone_none);
1345 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1346 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1347 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1348 result = DNS_R_CONTINUE;
1353 INSIST(zone->db_argc >= 1);
1355 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1356 strcmp(zone->db_argv[0], "rbt64") == 0;
1358 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1360 * The zone has no master file configured.
1362 result = ISC_R_SUCCESS;
1366 if (zone->db != NULL && zone_isdynamic(zone)) {
1368 * This is a slave, stub, or dynamically updated
1369 * zone being reloaded. Do nothing - the database
1370 * we already have is guaranteed to be up-to-date.
1372 if (zone->type == dns_zone_master)
1373 result = DNS_R_DYNAMIC;
1375 result = ISC_R_SUCCESS;
1380 * Store the current time before the zone is loaded, so that if the
1381 * file changes between the time of the load and the time that
1382 * zone->loadtime is set, then the file will still be reloaded
1383 * the next time dns_zone_load is called.
1385 TIME_NOW(&loadtime);
1388 * Don't do the load if the file that stores the zone is older
1389 * than the last time the zone was loaded. If the zone has not
1390 * been loaded yet, zone->loadtime will be the epoch.
1392 if (zone->masterfile != NULL) {
1394 * The file is already loaded. If we are just doing a
1395 * "rndc reconfig", we are done.
1397 if (!isc_time_isepoch(&zone->loadtime) &&
1398 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1399 result = ISC_R_SUCCESS;
1403 result = isc_file_getmodtime(zone->masterfile, &filetime);
1404 if (result == ISC_R_SUCCESS) {
1405 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1406 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1407 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1408 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1409 "skipping load: master file "
1410 "older than last load");
1411 result = DNS_R_UPTODATE;
1414 loadtime = filetime;
1419 * Built in zones (with the exception of empty zones) don't need
1422 if (zone->type == dns_zone_master &&
1423 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1424 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1425 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1426 result = ISC_R_SUCCESS;
1430 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1432 if (zone->masterfile == NULL ||
1433 !isc_file_exists(zone->masterfile)) {
1434 if (zone->masterfile != NULL) {
1435 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1438 zone->refreshtime = now;
1439 if (zone->task != NULL)
1440 zone_settimer(zone, &now);
1441 result = ISC_R_SUCCESS;
1446 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1448 result = dns_db_create(zone->mctx, zone->db_argv[0],
1449 &zone->origin, (zone->type == dns_zone_stub) ?
1450 dns_dbtype_stub : dns_dbtype_zone,
1452 zone->db_argc - 1, zone->db_argv + 1,
1455 if (result != ISC_R_SUCCESS) {
1456 dns_zone_log(zone, ISC_LOG_ERROR,
1457 "loading zone: creating database: %s",
1458 isc_result_totext(result));
1461 dns_db_settask(db, zone->task);
1463 if (! dns_db_ispersistent(db)) {
1464 if (zone->masterfile != NULL) {
1465 result = zone_startload(db, zone, loadtime);
1467 result = DNS_R_NOMASTERFILE;
1468 if (zone->type == dns_zone_master) {
1469 dns_zone_log(zone, ISC_LOG_ERROR,
1471 "no master file configured");
1474 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1475 "no master file configured: continuing");
1479 if (result == DNS_R_CONTINUE) {
1480 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1481 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1482 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1486 result = zone_postload(zone, db, loadtime, result);
1496 dns_zone_load(dns_zone_t *zone) {
1497 return (zone_load(zone, 0));
1501 dns_zone_loadnew(dns_zone_t *zone) {
1502 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1506 dns_zone_loadandthaw(dns_zone_t *zone) {
1507 isc_result_t result;
1509 result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1511 case DNS_R_CONTINUE:
1512 /* Deferred thaw. */
1515 case DNS_R_UPTODATE:
1516 case DNS_R_SEENINCLUDE:
1517 zone->update_disabled = ISC_FALSE;
1519 case DNS_R_NOMASTERFILE:
1520 zone->update_disabled = ISC_FALSE;
1523 /* Error, remain in disabled state. */
1530 get_master_options(dns_zone_t *zone) {
1531 unsigned int options;
1533 options = DNS_MASTER_ZONE;
1534 if (zone->type == dns_zone_slave)
1535 options |= DNS_MASTER_SLAVE;
1536 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1537 options |= DNS_MASTER_CHECKNS;
1538 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1539 options |= DNS_MASTER_FATALNS;
1540 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1541 options |= DNS_MASTER_CHECKNAMES;
1542 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1543 options |= DNS_MASTER_CHECKNAMESFAIL;
1544 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1545 options |= DNS_MASTER_CHECKMX;
1546 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1547 options |= DNS_MASTER_CHECKMXFAIL;
1548 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1549 options |= DNS_MASTER_CHECKWILDCARD;
1550 if (zone->type == dns_zone_master &&
1551 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1552 zone->ssutable != NULL))
1553 options |= DNS_MASTER_RESIGN;
1558 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1559 dns_load_t *load = event->ev_arg;
1560 isc_result_t result = ISC_R_SUCCESS;
1561 unsigned int options;
1563 REQUIRE(DNS_LOAD_VALID(load));
1565 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1566 result = ISC_R_CANCELED;
1567 isc_event_free(&event);
1568 if (result == ISC_R_CANCELED)
1571 options = get_master_options(load->zone);
1573 result = dns_master_loadfileinc3(load->zone->masterfile,
1574 dns_db_origin(load->db),
1575 dns_db_origin(load->db),
1576 load->zone->rdclass,
1578 load->zone->sigresigninginterval,
1579 &load->callbacks, task,
1580 zone_loaddone, load,
1581 &load->zone->lctx, load->zone->mctx,
1582 load->zone->masterformat);
1583 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1584 result != DNS_R_SEENINCLUDE)
1589 zone_loaddone(load, result);
1593 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1594 const char me[] = "zone_gotwritehandle";
1595 dns_zone_t *zone = event->ev_arg;
1596 isc_result_t result = ISC_R_SUCCESS;
1597 dns_dbversion_t *version = NULL;
1599 REQUIRE(DNS_ZONE_VALID(zone));
1600 INSIST(task == zone->task);
1603 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1604 result = ISC_R_CANCELED;
1605 isc_event_free(&event);
1606 if (result == ISC_R_CANCELED)
1610 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1611 if (zone->db != NULL) {
1612 dns_db_currentversion(zone->db, &version);
1613 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1614 &dns_master_style_default,
1615 zone->masterfile, zone->task,
1616 dump_done, zone, &zone->dctx,
1617 zone->masterformat);
1618 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1620 result = ISC_R_CANCELED;
1621 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1623 if (result != DNS_R_CONTINUE)
1628 dump_done(zone, result);
1632 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1634 isc_result_t result;
1635 isc_result_t tresult;
1636 unsigned int options;
1638 options = get_master_options(zone);
1640 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1641 options |= DNS_MASTER_MANYERRORS;
1643 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1644 load = isc_mem_get(zone->mctx, sizeof(*load));
1646 return (ISC_R_NOMEMORY);
1651 load->loadtime = loadtime;
1652 load->magic = LOAD_MAGIC;
1654 isc_mem_attach(zone->mctx, &load->mctx);
1655 zone_iattach(zone, &load->zone);
1656 dns_db_attach(db, &load->db);
1657 dns_rdatacallbacks_init(&load->callbacks);
1658 result = dns_db_beginload(db, &load->callbacks.add,
1659 &load->callbacks.add_private);
1660 if (result != ISC_R_SUCCESS)
1662 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1663 zone_gotreadhandle, load,
1665 if (result != ISC_R_SUCCESS) {
1667 * We can't report multiple errors so ignore
1668 * the result of dns_db_endload().
1670 (void)dns_db_endload(load->db,
1671 &load->callbacks.add_private);
1674 result = DNS_R_CONTINUE;
1676 dns_rdatacallbacks_t callbacks;
1678 dns_rdatacallbacks_init(&callbacks);
1679 result = dns_db_beginload(db, &callbacks.add,
1680 &callbacks.add_private);
1681 if (result != ISC_R_SUCCESS)
1683 result = dns_master_loadfile3(zone->masterfile, &zone->origin,
1684 &zone->origin, zone->rdclass,
1685 options, zone->sigresigninginterval,
1686 &callbacks, zone->mctx,
1687 zone->masterformat);
1688 tresult = dns_db_endload(db, &callbacks.add_private);
1689 if (result == ISC_R_SUCCESS)
1697 dns_db_detach(&load->db);
1698 zone_idetach(&load->zone);
1699 isc_mem_detach(&load->mctx);
1700 isc_mem_put(zone->mctx, load, sizeof(*load));
1704 static isc_boolean_t
1705 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1708 isc_result_t result;
1709 char ownerbuf[DNS_NAME_FORMATSIZE];
1710 char namebuf[DNS_NAME_FORMATSIZE];
1711 char altbuf[DNS_NAME_FORMATSIZE];
1712 dns_fixedname_t fixed;
1713 dns_name_t *foundname;
1717 * "." means the services does not exist.
1719 if (dns_name_equal(name, dns_rootname))
1725 if (!dns_name_issubdomain(name, &zone->origin)) {
1726 if (zone->checkmx != NULL)
1727 return ((zone->checkmx)(zone, name, owner));
1731 if (zone->type == dns_zone_master)
1732 level = ISC_LOG_ERROR;
1734 level = ISC_LOG_WARNING;
1736 dns_fixedname_init(&fixed);
1737 foundname = dns_fixedname_name(&fixed);
1739 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1740 0, 0, NULL, foundname, NULL, NULL);
1741 if (result == ISC_R_SUCCESS)
1744 if (result == DNS_R_NXRRSET) {
1745 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1746 0, 0, NULL, foundname, NULL, NULL);
1747 if (result == ISC_R_SUCCESS)
1751 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1752 dns_name_format(name, namebuf, sizeof namebuf);
1753 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1754 result == DNS_R_EMPTYNAME) {
1755 dns_zone_log(zone, level,
1756 "%s/MX '%s' has no address records (A or AAAA)",
1758 /* XXX950 make fatal for 9.5.0. */
1762 if (result == DNS_R_CNAME) {
1763 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1764 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1765 level = ISC_LOG_WARNING;
1766 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1767 dns_zone_log(zone, level,
1768 "%s/MX '%s' is a CNAME (illegal)",
1770 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1773 if (result == DNS_R_DNAME) {
1774 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1775 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1776 level = ISC_LOG_WARNING;
1777 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1778 dns_name_format(foundname, altbuf, sizeof altbuf);
1779 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1780 " '%s' (illegal)", ownerbuf, namebuf,
1783 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1786 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1787 return ((zone->checkmx)(zone, name, owner));
1792 static isc_boolean_t
1793 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1796 isc_result_t result;
1797 char ownerbuf[DNS_NAME_FORMATSIZE];
1798 char namebuf[DNS_NAME_FORMATSIZE];
1799 char altbuf[DNS_NAME_FORMATSIZE];
1800 dns_fixedname_t fixed;
1801 dns_name_t *foundname;
1805 * "." means the services does not exist.
1807 if (dns_name_equal(name, dns_rootname))
1813 if (!dns_name_issubdomain(name, &zone->origin)) {
1814 if (zone->checksrv != NULL)
1815 return ((zone->checksrv)(zone, name, owner));
1819 if (zone->type == dns_zone_master)
1820 level = ISC_LOG_ERROR;
1822 level = ISC_LOG_WARNING;
1824 dns_fixedname_init(&fixed);
1825 foundname = dns_fixedname_name(&fixed);
1827 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1828 0, 0, NULL, foundname, NULL, NULL);
1829 if (result == ISC_R_SUCCESS)
1832 if (result == DNS_R_NXRRSET) {
1833 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1834 0, 0, NULL, foundname, NULL, NULL);
1835 if (result == ISC_R_SUCCESS)
1839 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1840 dns_name_format(name, namebuf, sizeof namebuf);
1841 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1842 result == DNS_R_EMPTYNAME) {
1843 dns_zone_log(zone, level,
1844 "%s/SRV '%s' has no address records (A or AAAA)",
1846 /* XXX950 make fatal for 9.5.0. */
1850 if (result == DNS_R_CNAME) {
1851 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1852 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1853 level = ISC_LOG_WARNING;
1854 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1855 dns_zone_log(zone, level,
1856 "%s/SRV '%s' is a CNAME (illegal)",
1858 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1861 if (result == DNS_R_DNAME) {
1862 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1863 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1864 level = ISC_LOG_WARNING;
1865 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1866 dns_name_format(foundname, altbuf, sizeof altbuf);
1867 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1868 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1871 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1874 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1875 return ((zone->checksrv)(zone, name, owner));
1880 static isc_boolean_t
1881 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1884 isc_boolean_t answer = ISC_TRUE;
1885 isc_result_t result, tresult;
1886 char ownerbuf[DNS_NAME_FORMATSIZE];
1887 char namebuf[DNS_NAME_FORMATSIZE];
1888 char altbuf[DNS_NAME_FORMATSIZE];
1889 dns_fixedname_t fixed;
1890 dns_name_t *foundname;
1892 dns_rdataset_t aaaa;
1898 if (!dns_name_issubdomain(name, &zone->origin)) {
1899 if (zone->checkns != NULL)
1900 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1904 if (zone->type == dns_zone_master)
1905 level = ISC_LOG_ERROR;
1907 level = ISC_LOG_WARNING;
1909 dns_fixedname_init(&fixed);
1910 foundname = dns_fixedname_name(&fixed);
1911 dns_rdataset_init(&a);
1912 dns_rdataset_init(&aaaa);
1914 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1915 DNS_DBFIND_GLUEOK, 0, NULL,
1916 foundname, &a, NULL);
1918 if (result == ISC_R_SUCCESS) {
1919 dns_rdataset_disassociate(&a);
1921 } else if (result == DNS_R_DELEGATION)
1922 dns_rdataset_disassociate(&a);
1924 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1925 result == DNS_R_GLUE) {
1926 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1927 DNS_DBFIND_GLUEOK, 0, NULL,
1928 foundname, &aaaa, NULL);
1929 if (tresult == ISC_R_SUCCESS) {
1930 dns_rdataset_disassociate(&aaaa);
1933 if (tresult == DNS_R_DELEGATION)
1934 dns_rdataset_disassociate(&aaaa);
1935 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1937 * Check glue against child zone.
1939 if (zone->checkns != NULL)
1940 answer = (zone->checkns)(zone, name, owner,
1942 if (dns_rdataset_isassociated(&a))
1943 dns_rdataset_disassociate(&a);
1944 if (dns_rdataset_isassociated(&aaaa))
1945 dns_rdataset_disassociate(&aaaa);
1950 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1951 dns_name_format(name, namebuf, sizeof namebuf);
1952 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1953 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
1955 isc_boolean_t required = ISC_FALSE;
1956 if (dns_name_issubdomain(name, owner)) {
1957 what = "REQUIRED GLUE ";
1958 required = ISC_TRUE;
1959 } else if (result == DNS_R_DELEGATION)
1960 what = "SIBLING GLUE ";
1964 if (result != DNS_R_DELEGATION || required ||
1965 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
1966 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
1967 "address records (A or AAAA)",
1968 ownerbuf, namebuf, what);
1970 * Log missing address record.
1972 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
1973 (void)(zone->checkns)(zone, name, owner,
1975 /* XXX950 make fatal for 9.5.0. */
1976 /* answer = ISC_FALSE; */
1978 } else if (result == DNS_R_CNAME) {
1979 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
1981 /* XXX950 make fatal for 9.5.0. */
1982 /* answer = ISC_FALSE; */
1983 } else if (result == DNS_R_DNAME) {
1984 dns_name_format(foundname, altbuf, sizeof altbuf);
1985 dns_zone_log(zone, level,
1986 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1987 ownerbuf, namebuf, altbuf);
1988 /* XXX950 make fatal for 9.5.0. */
1989 /* answer = ISC_FALSE; */
1992 if (dns_rdataset_isassociated(&a))
1993 dns_rdataset_disassociate(&a);
1994 if (dns_rdataset_isassociated(&aaaa))
1995 dns_rdataset_disassociate(&aaaa);
1999 static isc_boolean_t
2000 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2001 dns_dbiterator_t *dbiterator = NULL;
2002 dns_dbnode_t *node = NULL;
2003 dns_rdataset_t rdataset;
2004 dns_fixedname_t fixed;
2005 dns_fixedname_t fixedbottom;
2008 dns_rdata_in_srv_t srv;
2012 isc_result_t result;
2013 isc_boolean_t ok = ISC_TRUE;
2015 dns_fixedname_init(&fixed);
2016 name = dns_fixedname_name(&fixed);
2017 dns_fixedname_init(&fixedbottom);
2018 bottom = dns_fixedname_name(&fixedbottom);
2019 dns_rdataset_init(&rdataset);
2020 dns_rdata_init(&rdata);
2022 result = dns_db_createiterator(db, 0, &dbiterator);
2023 if (result != ISC_R_SUCCESS)
2026 result = dns_dbiterator_first(dbiterator);
2027 while (result == ISC_R_SUCCESS) {
2028 result = dns_dbiterator_current(dbiterator, &node, name);
2029 if (result != ISC_R_SUCCESS)
2033 * Is this name visible in the zone?
2035 if (!dns_name_issubdomain(name, &zone->origin) ||
2036 (dns_name_countlabels(bottom) > 0 &&
2037 dns_name_issubdomain(name, bottom)))
2041 * Don't check the NS records at the origin.
2043 if (dns_name_equal(name, &zone->origin))
2046 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2047 0, 0, &rdataset, NULL);
2048 if (result != ISC_R_SUCCESS)
2051 * Remember bottom of zone.
2053 dns_name_copy(name, bottom, NULL);
2055 result = dns_rdataset_first(&rdataset);
2056 while (result == ISC_R_SUCCESS) {
2057 dns_rdataset_current(&rdataset, &rdata);
2058 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2059 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2060 if (!zone_check_glue(zone, db, &ns.name, name))
2062 dns_rdata_reset(&rdata);
2063 result = dns_rdataset_next(&rdataset);
2065 dns_rdataset_disassociate(&rdataset);
2068 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2069 0, 0, &rdataset, NULL);
2070 if (result != ISC_R_SUCCESS)
2072 result = dns_rdataset_first(&rdataset);
2073 while (result == ISC_R_SUCCESS) {
2074 dns_rdataset_current(&rdataset, &rdata);
2075 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2076 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2077 if (!zone_check_mx(zone, db, &mx.mx, name))
2079 dns_rdata_reset(&rdata);
2080 result = dns_rdataset_next(&rdataset);
2082 dns_rdataset_disassociate(&rdataset);
2085 if (zone->rdclass != dns_rdataclass_in)
2087 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2088 0, 0, &rdataset, NULL);
2089 if (result != ISC_R_SUCCESS)
2091 result = dns_rdataset_first(&rdataset);
2092 while (result == ISC_R_SUCCESS) {
2093 dns_rdataset_current(&rdataset, &rdata);
2094 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2095 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2096 if (!zone_check_srv(zone, db, &srv.target, name))
2098 dns_rdata_reset(&rdata);
2099 result = dns_rdataset_next(&rdataset);
2101 dns_rdataset_disassociate(&rdataset);
2104 dns_db_detachnode(db, &node);
2105 result = dns_dbiterator_next(dbiterator);
2110 dns_db_detachnode(db, &node);
2111 dns_dbiterator_destroy(&dbiterator);
2117 * OpenSSL verification of RSA keys with exponent 3 is known to be
2118 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2119 * if they are in use.
2122 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2123 dns_dbnode_t *node = NULL;
2124 dns_dbversion_t *version = NULL;
2125 dns_rdata_dnskey_t dnskey;
2126 dns_rdata_t rdata = DNS_RDATA_INIT;
2127 dns_rdataset_t rdataset;
2128 isc_result_t result;
2129 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2130 const char *algorithm;
2132 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2133 if (result != ISC_R_SUCCESS)
2136 dns_db_currentversion(db, &version);
2137 dns_rdataset_init(&rdataset);
2138 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2139 dns_rdatatype_none, 0, &rdataset, NULL);
2140 if (result != ISC_R_SUCCESS)
2143 for (result = dns_rdataset_first(&rdataset);
2144 result == ISC_R_SUCCESS;
2145 result = dns_rdataset_next(&rdataset))
2147 dns_rdataset_current(&rdataset, &rdata);
2148 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2149 INSIST(result == ISC_R_SUCCESS);
2151 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2152 dnskey.algorithm == DST_ALG_RSAMD5) &&
2153 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2154 dnskey.data[1] == 3)
2156 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2158 foundrsa = ISC_TRUE;
2159 algorithm = "RSASHA1";
2162 foundmd5 = ISC_TRUE;
2163 algorithm = "RSAMD5";
2166 dns_zone_log(zone, ISC_LOG_WARNING,
2167 "weak %s (%u) key found "
2168 "(exponent=3)", algorithm,
2170 if (foundrsa && foundmd5)
2173 dns_rdata_reset(&rdata);
2175 dns_rdataset_disassociate(&rdataset);
2179 dns_db_detachnode(db, &node);
2180 if (version != NULL)
2181 dns_db_closeversion(db, &version, ISC_FALSE);
2186 resume_signingwithkey(dns_zone_t *zone) {
2187 dns_dbnode_t *node = NULL;
2188 dns_dbversion_t *version = NULL;
2189 dns_rdata_t rdata = DNS_RDATA_INIT;
2190 dns_rdataset_t rdataset;
2191 isc_result_t result;
2193 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2194 if (result != ISC_R_SUCCESS)
2197 dns_db_currentversion(zone->db, &version);
2198 dns_rdataset_init(&rdataset);
2199 result = dns_db_findrdataset(zone->db, node, version,
2201 dns_rdatatype_none, 0,
2203 if (result != ISC_R_SUCCESS)
2206 for (result = dns_rdataset_first(&rdataset);
2207 result == ISC_R_SUCCESS;
2208 result = dns_rdataset_next(&rdataset))
2210 dns_rdataset_current(&rdataset, &rdata);
2211 if (rdata.length != 5 || rdata.data[4] != 0) {
2212 dns_rdata_reset(&rdata);
2216 result = zone_signwithkey(zone, rdata.data[0],
2217 (rdata.data[1] << 8) | rdata.data[2],
2218 ISC_TF(rdata.data[3]));
2219 if (result != ISC_R_SUCCESS) {
2220 dns_zone_log(zone, ISC_LOG_ERROR,
2221 "zone_signwithkey failed: %s",
2222 dns_result_totext(result));
2224 dns_rdata_reset(&rdata);
2226 dns_rdataset_disassociate(&rdataset);
2230 dns_db_detachnode(zone->db, &node);
2231 if (version != NULL)
2232 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2237 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2238 dns_nsec3chain_t *nsec3chain, *current;
2239 isc_result_t result;
2241 unsigned int options = 0;
2243 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2244 if (nsec3chain == NULL)
2245 return (ISC_R_NOMEMORY);
2247 nsec3chain->magic = 0;
2248 nsec3chain->done = ISC_FALSE;
2249 nsec3chain->db = NULL;
2250 nsec3chain->dbiterator = NULL;
2251 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2252 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2253 nsec3chain->nsec3param.hash = nsec3param->hash;
2254 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2255 nsec3chain->nsec3param.flags = nsec3param->flags;
2256 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2257 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2258 nsec3chain->nsec3param.salt = nsec3chain->salt;
2259 nsec3chain->seen_nsec = ISC_FALSE;
2260 nsec3chain->delete_nsec = ISC_FALSE;
2261 nsec3chain->save_delete_nsec = ISC_FALSE;
2263 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2265 current = ISC_LIST_NEXT(current, link)) {
2266 if (current->db == zone->db &&
2267 current->nsec3param.hash == nsec3param->hash &&
2268 current->nsec3param.iterations == nsec3param->iterations &&
2269 current->nsec3param.salt_length == nsec3param->salt_length
2270 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2271 nsec3param->salt_length))
2272 current->done = ISC_TRUE;
2275 if (zone->db != NULL) {
2276 dns_db_attach(zone->db, &nsec3chain->db);
2277 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2278 options = DNS_DB_NONSEC3;
2279 result = dns_db_createiterator(nsec3chain->db, options,
2280 &nsec3chain->dbiterator);
2281 if (result == ISC_R_SUCCESS)
2282 dns_dbiterator_first(nsec3chain->dbiterator);
2283 if (result == ISC_R_SUCCESS) {
2284 dns_dbiterator_pause(nsec3chain->dbiterator);
2285 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2288 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2290 zone->nsec3chaintime = now;
2291 if (zone->task != NULL)
2292 zone_settimer(zone, &now);
2296 result = ISC_R_NOTFOUND;
2298 if (nsec3chain != NULL) {
2299 if (nsec3chain->db != NULL)
2300 dns_db_detach(&nsec3chain->db);
2301 if (nsec3chain->dbiterator != NULL)
2302 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2303 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2309 resume_addnsec3chain(dns_zone_t *zone) {
2310 dns_dbnode_t *node = NULL;
2311 dns_dbversion_t *version = NULL;
2312 dns_rdata_t rdata = DNS_RDATA_INIT;
2313 dns_rdataset_t rdataset;
2314 isc_result_t result;
2315 dns_rdata_nsec3param_t nsec3param;
2317 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2318 if (result != ISC_R_SUCCESS)
2321 dns_db_currentversion(zone->db, &version);
2322 dns_rdataset_init(&rdataset);
2323 result = dns_db_findrdataset(zone->db, node, version,
2324 dns_rdatatype_nsec3param,
2325 dns_rdatatype_none, 0,
2327 if (result != ISC_R_SUCCESS)
2330 for (result = dns_rdataset_first(&rdataset);
2331 result == ISC_R_SUCCESS;
2332 result = dns_rdataset_next(&rdataset))
2334 dns_rdataset_current(&rdataset, &rdata);
2335 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2336 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2337 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
2338 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
2339 result = zone_addnsec3chain(zone, &nsec3param);
2340 if (result != ISC_R_SUCCESS) {
2341 dns_zone_log(zone, ISC_LOG_ERROR,
2342 "zone_addnsec3chain failed: %s",
2343 dns_result_totext(result));
2346 dns_rdata_reset(&rdata);
2348 dns_rdataset_disassociate(&rdataset);
2352 dns_db_detachnode(zone->db, &node);
2353 if (version != NULL)
2354 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2358 set_resigntime(dns_zone_t *zone) {
2359 dns_rdataset_t rdataset;
2360 dns_fixedname_t fixed;
2361 unsigned int resign;
2362 isc_result_t result;
2363 isc_uint32_t nanosecs;
2365 dns_rdataset_init(&rdataset);
2366 dns_fixedname_init(&fixed);
2367 result = dns_db_getsigningtime(zone->db, &rdataset,
2368 dns_fixedname_name(&fixed));
2369 if (result != ISC_R_SUCCESS) {
2370 isc_time_settoepoch(&zone->resigntime);
2373 resign = rdataset.resign;
2374 dns_rdataset_disassociate(&rdataset);
2375 isc_random_get(&nanosecs);
2376 nanosecs %= 1000000000;
2377 isc_time_set(&zone->resigntime, resign, nanosecs);
2381 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2382 dns_dbnode_t *node = NULL;
2383 dns_rdataset_t rdataset;
2384 dns_dbversion_t *version = NULL;
2385 dns_rdata_nsec3param_t nsec3param;
2386 isc_boolean_t ok = ISC_FALSE;
2387 isc_result_t result;
2388 dns_rdata_t rdata = DNS_RDATA_INIT;
2389 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
2390 zone_isdynamic(zone) : ISC_FALSE;
2392 dns_rdataset_init(&rdataset);
2393 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2394 if (result != ISC_R_SUCCESS) {
2395 dns_zone_log(zone, ISC_LOG_ERROR,
2396 "nsec3param lookup failure: %s",
2397 dns_result_totext(result));
2400 dns_db_currentversion(db, &version);
2402 result = dns_db_findrdataset(db, node, version,
2403 dns_rdatatype_nsec3param,
2404 dns_rdatatype_none, 0, &rdataset, NULL);
2405 if (result == ISC_R_NOTFOUND) {
2406 result = ISC_R_SUCCESS;
2409 if (result != ISC_R_SUCCESS) {
2410 dns_zone_log(zone, ISC_LOG_ERROR,
2411 "nsec3param lookup failure: %s",
2412 dns_result_totext(result));
2417 * For dynamic zones we must support every algorithm so we can
2418 * regenerate all the NSEC3 chains.
2419 * For non-dynamic zones we only need to find a supported algorithm.
2421 for (result = dns_rdataset_first(&rdataset);
2422 result == ISC_R_SUCCESS;
2423 result = dns_rdataset_next(&rdataset))
2425 dns_rdataset_current(&rdataset, &rdata);
2426 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2427 dns_rdata_reset(&rdata);
2428 INSIST(result == ISC_R_SUCCESS);
2429 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
2430 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
2432 dns_zone_log(zone, ISC_LOG_WARNING,
2433 "nsec3 test \"unknown\" hash algorithm found: %u",
2436 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
2438 dns_zone_log(zone, ISC_LOG_ERROR,
2439 "unsupported nsec3 hash algorithm"
2440 " in dynamic zone: %u",
2442 result = DNS_R_BADZONE;
2443 /* Stop second error message. */
2447 dns_zone_log(zone, ISC_LOG_WARNING,
2448 "unsupported nsec3 hash algorithm: %u",
2453 if (result == ISC_R_NOMORE)
2454 result = ISC_R_SUCCESS;
2457 result = DNS_R_BADZONE;
2458 dns_zone_log(zone, ISC_LOG_ERROR,
2459 "no supported nsec3 hash algorithm");
2463 if (dns_rdataset_isassociated(&rdataset))
2464 dns_rdataset_disassociate(&rdataset);
2465 dns_db_closeversion(db, &version, ISC_FALSE);
2466 dns_db_detachnode(db, &node);
2471 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
2472 isc_result_t result)
2474 unsigned int soacount = 0;
2475 unsigned int nscount = 0;
2476 unsigned int errors = 0;
2477 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
2479 isc_boolean_t needdump = ISC_FALSE;
2480 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2481 unsigned int options;
2486 * Initiate zone transfer? We may need a error code that
2487 * indicates that the "permanent" form does not exist.
2488 * XXX better error feedback to log.
2490 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
2491 if (zone->type == dns_zone_slave ||
2492 zone->type == dns_zone_stub) {
2493 if (result == ISC_R_FILENOTFOUND)
2494 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2496 else if (result != DNS_R_NOMASTERFILE)
2497 dns_zone_log(zone, ISC_LOG_ERROR,
2498 "loading from master file %s "
2501 dns_result_totext(result));
2503 dns_zone_log(zone, ISC_LOG_ERROR,
2504 "loading from master file %s failed: %s",
2506 dns_result_totext(result));
2510 dns_zone_log(zone, ISC_LOG_DEBUG(2),
2511 "number of nodes in database: %u",
2512 dns_db_nodecount(db));
2514 if (result == DNS_R_SEENINCLUDE)
2515 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2517 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2520 * Apply update log, if any, on initial load.
2522 if (zone->journal != NULL &&
2523 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
2524 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
2526 if (zone->type == dns_zone_master &&
2527 (zone->update_acl != NULL || zone->ssutable != NULL))
2528 options = DNS_JOURNALOPT_RESIGN;
2531 result = dns_journal_rollforward2(zone->mctx, db, options,
2532 zone->sigresigninginterval,
2534 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
2535 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
2536 result != ISC_R_RANGE) {
2537 dns_zone_log(zone, ISC_LOG_ERROR,
2538 "journal rollforward failed: %s",
2539 dns_result_totext(result));
2542 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
2543 dns_zone_log(zone, ISC_LOG_ERROR,
2544 "journal rollforward failed: "
2545 "journal out of sync with zone");
2548 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2549 "journal rollforward completed "
2551 dns_result_totext(result));
2552 if (result == ISC_R_SUCCESS)
2553 needdump = ISC_TRUE;
2556 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
2558 * Obtain ns, soa and cname counts for top of zone.
2561 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
2562 &refresh, &retry, &expire, &minimum,
2564 if (result != ISC_R_SUCCESS) {
2565 dns_zone_log(zone, ISC_LOG_ERROR,
2566 "could not find NS and/or SOA records");
2570 * Master / Slave / Stub zones require both NS and SOA records at
2571 * the top of the zone.
2574 switch (zone->type) {
2575 case dns_zone_master:
2576 case dns_zone_slave:
2578 if (soacount != 1) {
2579 dns_zone_log(zone, ISC_LOG_ERROR,
2580 "has %d SOA records", soacount);
2581 result = DNS_R_BADZONE;
2584 dns_zone_log(zone, ISC_LOG_ERROR,
2585 "has no NS records");
2586 result = DNS_R_BADZONE;
2588 if (result != ISC_R_SUCCESS)
2590 if (zone->type == dns_zone_master && errors != 0) {
2591 result = DNS_R_BADZONE;
2594 if (zone->type != dns_zone_stub) {
2595 result = check_nsec3param(zone, db);
2596 if (result != ISC_R_SUCCESS)
2599 if (zone->type == dns_zone_master &&
2600 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
2601 !integrity_checks(zone, db)) {
2602 result = DNS_R_BADZONE;
2606 if (zone->db != NULL) {
2608 * This is checked in zone_replacedb() for slave zones
2609 * as they don't reload from disk.
2611 result = zone_get_from_db(zone, zone->db, NULL, NULL,
2612 &oldserial, NULL, NULL, NULL,
2614 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2615 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
2616 !isc_serial_gt(serial, oldserial)) {
2617 isc_uint32_t serialmin, serialmax;
2619 INSIST(zone->type == dns_zone_master);
2621 serialmin = (oldserial + 1) & 0xffffffffU;
2622 serialmax = (oldserial + 0x7fffffffU) &
2624 dns_zone_log(zone, ISC_LOG_ERROR,
2625 "ixfr-from-differences: "
2626 "new serial (%u) out of range "
2627 "[%u - %u]", serial, serialmin,
2629 result = DNS_R_BADZONE;
2631 } else if (!isc_serial_ge(serial, oldserial))
2632 dns_zone_log(zone, ISC_LOG_ERROR,
2633 "zone serial has gone backwards");
2634 else if (serial == oldserial && !hasinclude &&
2635 strcmp(zone->db_argv[0], "_builtin") != 0)
2636 dns_zone_log(zone, ISC_LOG_ERROR,
2637 "zone serial unchanged. "
2638 "zone may fail to transfer "
2642 if (zone->type == dns_zone_master &&
2643 (zone->update_acl != NULL || zone->ssutable != NULL) &&
2644 zone->sigresigninginterval < (3 * refresh) &&
2645 dns_db_issecure(db))
2647 dns_zone_log(zone, ISC_LOG_WARNING,
2648 "sig-re-signing-interval less than "
2652 zone->refresh = RANGE(refresh,
2653 zone->minrefresh, zone->maxrefresh);
2654 zone->retry = RANGE(retry,
2655 zone->minretry, zone->maxretry);
2656 zone->expire = RANGE(expire, zone->refresh + zone->retry,
2658 zone->minimum = minimum;
2659 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
2661 if (zone->type == dns_zone_slave ||
2662 zone->type == dns_zone_stub) {
2666 result = isc_file_getmodtime(zone->journal, &t);
2667 if (result != ISC_R_SUCCESS)
2668 result = isc_file_getmodtime(zone->masterfile,
2670 if (result == ISC_R_SUCCESS)
2671 DNS_ZONE_TIME_ADD(&t, zone->expire,
2674 DNS_ZONE_TIME_ADD(&now, zone->retry,
2677 delay = isc_random_jitter(zone->retry,
2678 (zone->retry * 3) / 4);
2679 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
2680 if (isc_time_compare(&zone->refreshtime,
2681 &zone->expiretime) >= 0)
2682 zone->refreshtime = now;
2686 UNEXPECTED_ERROR(__FILE__, __LINE__,
2687 "unexpected zone type %d", zone->type);
2688 result = ISC_R_UNEXPECTED;
2693 * Check for weak DNSKEY's.
2695 if (zone->type == dns_zone_master)
2696 zone_check_dnskeys(zone, db);
2699 /* destroy notification example. */
2701 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
2702 DNS_EVENT_DBDESTROYED,
2703 dns_zonemgr_dbdestroyed,
2705 sizeof(isc_event_t));
2706 dns_db_ondestroy(db, zone->task, &e);
2710 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2711 if (zone->db != NULL) {
2712 result = zone_replacedb(zone, db, ISC_FALSE);
2713 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2714 if (result != ISC_R_SUCCESS)
2717 zone_attachdb(zone, db);
2718 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2719 DNS_ZONE_SETFLAG(zone,
2720 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
2722 result = ISC_R_SUCCESS;
2724 zone_needdump(zone, DNS_DUMP_DELAY);
2725 if (zone->task != NULL) {
2726 if (zone->type == dns_zone_master) {
2727 set_resigntime(zone);
2728 resume_signingwithkey(zone);
2729 resume_addnsec3chain(zone);
2731 zone_settimer(zone, &now);
2734 if (! dns_db_ispersistent(db))
2735 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
2736 dns_db_issecure(db) ? " (signed)" : "");
2738 zone->loadtime = loadtime;
2742 if (zone->type == dns_zone_slave ||
2743 zone->type == dns_zone_stub) {
2744 if (zone->journal != NULL)
2745 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
2746 if (zone->masterfile != NULL)
2747 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
2749 /* Mark the zone for immediate refresh. */
2750 zone->refreshtime = now;
2751 if (zone->task != NULL)
2752 zone_settimer(zone, &now);
2753 result = ISC_R_SUCCESS;
2754 } else if (zone->type == dns_zone_master)
2755 dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
2759 static isc_boolean_t
2760 exit_check(dns_zone_t *zone) {
2762 REQUIRE(LOCKED_ZONE(zone));
2764 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
2768 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2770 INSIST(isc_refcount_current(&zone->erefs) == 0);
2776 static isc_boolean_t
2777 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
2778 isc_result_t result;
2779 char namebuf[DNS_NAME_FORMATSIZE];
2780 char altbuf[DNS_NAME_FORMATSIZE];
2781 dns_fixedname_t fixed;
2782 dns_name_t *foundname;
2785 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
2788 if (zone->type == dns_zone_master)
2789 level = ISC_LOG_ERROR;
2791 level = ISC_LOG_WARNING;
2793 dns_fixedname_init(&fixed);
2794 foundname = dns_fixedname_name(&fixed);
2796 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2797 0, 0, NULL, foundname, NULL, NULL);
2798 if (result == ISC_R_SUCCESS)
2801 if (result == DNS_R_NXRRSET) {
2802 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2803 0, 0, NULL, foundname, NULL, NULL);
2804 if (result == ISC_R_SUCCESS)
2808 dns_name_format(name, namebuf, sizeof namebuf);
2809 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2810 result == DNS_R_EMPTYNAME) {
2811 dns_zone_log(zone, level,
2812 "NS '%s' has no address records (A or AAAA)",
2814 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2818 if (result == DNS_R_CNAME) {
2819 dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
2821 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2825 if (result == DNS_R_DNAME) {
2826 dns_name_format(foundname, altbuf, sizeof altbuf);
2827 dns_zone_log(zone, level,
2828 "NS '%s' is below a DNAME '%s' (illegal)",
2830 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2838 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
2839 dns_dbversion_t *version, unsigned int *nscount,
2840 unsigned int *errors)
2842 isc_result_t result;
2843 unsigned int count = 0;
2844 unsigned int ecount = 0;
2845 dns_rdataset_t rdataset;
2849 dns_rdataset_init(&rdataset);
2850 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
2851 dns_rdatatype_none, 0, &rdataset, NULL);
2852 if (result == ISC_R_NOTFOUND)
2854 if (result != ISC_R_SUCCESS)
2855 goto invalidate_rdataset;
2857 result = dns_rdataset_first(&rdataset);
2858 while (result == ISC_R_SUCCESS) {
2859 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
2860 (zone->type == dns_zone_master ||
2861 zone->type == dns_zone_slave)) {
2862 dns_rdata_init(&rdata);
2863 dns_rdataset_current(&rdataset, &rdata);
2864 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2865 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2866 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
2867 !zone_check_ns(zone, db, &ns.name))
2871 result = dns_rdataset_next(&rdataset);
2873 dns_rdataset_disassociate(&rdataset);
2876 if (nscount != NULL)
2881 result = ISC_R_SUCCESS;
2883 invalidate_rdataset:
2884 dns_rdataset_invalidate(&rdataset);
2890 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
2891 unsigned int *soacount,
2892 isc_uint32_t *serial, isc_uint32_t *refresh,
2893 isc_uint32_t *retry, isc_uint32_t *expire,
2894 isc_uint32_t *minimum)
2896 isc_result_t result;
2898 dns_rdataset_t rdataset;
2899 dns_rdata_t rdata = DNS_RDATA_INIT;
2900 dns_rdata_soa_t soa;
2902 dns_rdataset_init(&rdataset);
2903 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
2904 dns_rdatatype_none, 0, &rdataset, NULL);
2905 if (result == ISC_R_NOTFOUND) {
2906 if (soacount != NULL)
2910 if (refresh != NULL)
2916 if (minimum != NULL)
2918 result = ISC_R_SUCCESS;
2919 goto invalidate_rdataset;
2921 if (result != ISC_R_SUCCESS)
2922 goto invalidate_rdataset;
2925 result = dns_rdataset_first(&rdataset);
2926 while (result == ISC_R_SUCCESS) {
2927 dns_rdata_init(&rdata);
2928 dns_rdataset_current(&rdataset, &rdata);
2931 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2932 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2935 result = dns_rdataset_next(&rdataset);
2936 dns_rdata_reset(&rdata);
2938 dns_rdataset_disassociate(&rdataset);
2940 if (soacount != NULL)
2945 *serial = soa.serial;
2946 if (refresh != NULL)
2947 *refresh = soa.refresh;
2951 *expire = soa.expire;
2952 if (minimum != NULL)
2953 *minimum = soa.minimum;
2956 result = ISC_R_SUCCESS;
2958 invalidate_rdataset:
2959 dns_rdataset_invalidate(&rdataset);
2965 * zone must be locked.
2968 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
2969 unsigned int *soacount, isc_uint32_t *serial,
2970 isc_uint32_t *refresh, isc_uint32_t *retry,
2971 isc_uint32_t *expire, isc_uint32_t *minimum,
2972 unsigned int *errors)
2974 dns_dbversion_t *version;
2975 isc_result_t result;
2976 isc_result_t answer = ISC_R_SUCCESS;
2979 REQUIRE(db != NULL);
2980 REQUIRE(zone != NULL);
2983 dns_db_currentversion(db, &version);
2986 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2987 if (result != ISC_R_SUCCESS) {
2992 if (nscount != NULL || errors != NULL) {
2993 result = zone_count_ns_rr(zone, db, node, version,
2995 if (result != ISC_R_SUCCESS)
2999 if (soacount != NULL || serial != NULL || refresh != NULL
3000 || retry != NULL || expire != NULL || minimum != NULL) {
3001 result = zone_load_soa_rr(db, node, version, soacount,
3002 serial, refresh, retry, expire,
3004 if (result != ISC_R_SUCCESS)
3008 dns_db_detachnode(db, &node);
3010 dns_db_closeversion(db, &version, ISC_FALSE);
3016 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
3017 REQUIRE(DNS_ZONE_VALID(source));
3018 REQUIRE(target != NULL && *target == NULL);
3019 isc_refcount_increment(&source->erefs, NULL);
3024 dns_zone_detach(dns_zone_t **zonep) {
3027 isc_boolean_t free_now = ISC_FALSE;
3029 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3033 isc_refcount_decrement(&zone->erefs, &refs);
3038 * We just detached the last external reference.
3040 if (zone->task != NULL) {
3042 * This zone is being managed. Post
3043 * its control event and let it clean
3044 * up synchronously in the context of
3047 isc_event_t *ev = &zone->ctlevent;
3048 isc_task_send(zone->task, &ev);
3051 * This zone is not being managed; it has
3052 * no task and can have no outstanding
3053 * events. Free it immediately.
3056 * Unmanaged zones should not have non-null views;
3057 * we have no way of detaching from the view here
3058 * without causing deadlock because this code is called
3059 * with the view already locked.
3061 INSIST(zone->view == NULL);
3062 free_now = ISC_TRUE;
3072 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3073 REQUIRE(DNS_ZONE_VALID(source));
3074 REQUIRE(target != NULL && *target == NULL);
3076 zone_iattach(source, target);
3077 UNLOCK_ZONE(source);
3081 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3084 * 'source' locked by caller.
3086 REQUIRE(LOCKED_ZONE(source));
3087 REQUIRE(DNS_ZONE_VALID(source));
3088 REQUIRE(target != NULL && *target == NULL);
3089 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
3091 INSIST(source->irefs != 0);
3096 zone_idetach(dns_zone_t **zonep) {
3100 * 'zone' locked by caller.
3102 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3104 REQUIRE(LOCKED_ZONE(*zonep));
3107 INSIST(zone->irefs > 0);
3109 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
3113 dns_zone_idetach(dns_zone_t **zonep) {
3115 isc_boolean_t free_needed;
3117 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3122 INSIST(zone->irefs > 0);
3124 free_needed = exit_check(zone);
3131 dns_zone_getmctx(dns_zone_t *zone) {
3132 REQUIRE(DNS_ZONE_VALID(zone));
3134 return (zone->mctx);
3138 dns_zone_getmgr(dns_zone_t *zone) {
3139 REQUIRE(DNS_ZONE_VALID(zone));
3141 return (zone->zmgr);
3145 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
3146 REQUIRE(DNS_ZONE_VALID(zone));
3150 DNS_ZONE_SETFLAG(zone, flags);
3152 DNS_ZONE_CLRFLAG(zone, flags);
3157 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
3159 REQUIRE(DNS_ZONE_VALID(zone));
3163 zone->options |= option;
3165 zone->options &= ~option;
3170 dns_zone_getoptions(dns_zone_t *zone) {
3172 REQUIRE(DNS_ZONE_VALID(zone));
3174 return (zone->options);
3178 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3179 REQUIRE(DNS_ZONE_VALID(zone));
3182 zone->xfrsource4 = *xfrsource;
3185 return (ISC_R_SUCCESS);
3189 dns_zone_getxfrsource4(dns_zone_t *zone) {
3190 REQUIRE(DNS_ZONE_VALID(zone));
3191 return (&zone->xfrsource4);
3195 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3196 REQUIRE(DNS_ZONE_VALID(zone));
3199 zone->xfrsource6 = *xfrsource;
3202 return (ISC_R_SUCCESS);
3206 dns_zone_getxfrsource6(dns_zone_t *zone) {
3207 REQUIRE(DNS_ZONE_VALID(zone));
3208 return (&zone->xfrsource6);
3212 dns_zone_setaltxfrsource4(dns_zone_t *zone,
3213 const isc_sockaddr_t *altxfrsource)
3215 REQUIRE(DNS_ZONE_VALID(zone));
3218 zone->altxfrsource4 = *altxfrsource;
3221 return (ISC_R_SUCCESS);
3225 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
3226 REQUIRE(DNS_ZONE_VALID(zone));
3227 return (&zone->altxfrsource4);
3231 dns_zone_setaltxfrsource6(dns_zone_t *zone,
3232 const isc_sockaddr_t *altxfrsource)
3234 REQUIRE(DNS_ZONE_VALID(zone));
3237 zone->altxfrsource6 = *altxfrsource;
3240 return (ISC_R_SUCCESS);
3244 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
3245 REQUIRE(DNS_ZONE_VALID(zone));
3246 return (&zone->altxfrsource6);
3250 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3251 REQUIRE(DNS_ZONE_VALID(zone));
3254 zone->notifysrc4 = *notifysrc;
3257 return (ISC_R_SUCCESS);
3261 dns_zone_getnotifysrc4(dns_zone_t *zone) {
3262 REQUIRE(DNS_ZONE_VALID(zone));
3263 return (&zone->notifysrc4);
3267 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3268 REQUIRE(DNS_ZONE_VALID(zone));
3271 zone->notifysrc6 = *notifysrc;
3274 return (ISC_R_SUCCESS);
3278 dns_zone_getnotifysrc6(dns_zone_t *zone) {
3279 REQUIRE(DNS_ZONE_VALID(zone));
3280 return (&zone->notifysrc6);
3284 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
3287 isc_sockaddr_t *new;
3289 REQUIRE(DNS_ZONE_VALID(zone));
3290 REQUIRE(count == 0 || notify != NULL);
3293 if (zone->notify != NULL) {
3294 isc_mem_put(zone->mctx, zone->notify,
3295 zone->notifycnt * sizeof(*new));
3296 zone->notify = NULL;
3297 zone->notifycnt = 0;
3300 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3303 return (ISC_R_NOMEMORY);
3305 memcpy(new, notify, count * sizeof(*new));
3307 zone->notifycnt = count;
3310 return (ISC_R_SUCCESS);
3314 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
3317 isc_result_t result;
3319 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
3323 static isc_boolean_t
3324 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
3329 for (i = 0; i < count; i++)
3330 if (!isc_sockaddr_equal(&old[i], &new[i]))
3335 static isc_boolean_t
3336 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
3339 if (old == NULL && new == NULL)
3341 if (old == NULL || new == NULL)
3344 for (i = 0; i < count; i++) {
3345 if (old[i] == NULL && new[i] == NULL)
3347 if (old[i] == NULL || new[i] == NULL ||
3348 !dns_name_equal(old[i], new[i]))
3355 dns_zone_setmasterswithkeys(dns_zone_t *zone,
3356 const isc_sockaddr_t *masters,
3357 dns_name_t **keynames,
3360 isc_sockaddr_t *new;
3361 isc_result_t result = ISC_R_SUCCESS;
3362 dns_name_t **newname;
3363 isc_boolean_t *newok;
3366 REQUIRE(DNS_ZONE_VALID(zone));
3367 REQUIRE(count == 0 || masters != NULL);
3368 if (keynames != NULL) {
3369 REQUIRE(count != 0);
3374 * The refresh code assumes that 'masters' wouldn't change under it.
3375 * If it will change then kill off any current refresh in progress
3376 * and update the masters info. If it won't change then we can just
3379 if (count != zone->masterscnt ||
3380 !same_masters(zone->masters, masters, count) ||
3381 !same_keynames(zone->masterkeynames, keynames, count)) {
3382 if (zone->request != NULL)
3383 dns_request_cancel(zone->request);
3386 if (zone->masters != NULL) {
3387 isc_mem_put(zone->mctx, zone->masters,
3388 zone->masterscnt * sizeof(*new));
3389 zone->masters = NULL;
3391 if (zone->masterkeynames != NULL) {
3392 for (i = 0; i < zone->masterscnt; i++) {
3393 if (zone->masterkeynames[i] != NULL) {
3394 dns_name_free(zone->masterkeynames[i],
3396 isc_mem_put(zone->mctx,
3397 zone->masterkeynames[i],
3398 sizeof(dns_name_t));
3399 zone->masterkeynames[i] = NULL;
3402 isc_mem_put(zone->mctx, zone->masterkeynames,
3403 zone->masterscnt * sizeof(dns_name_t *));
3404 zone->masterkeynames = NULL;
3406 if (zone->mastersok != NULL) {
3407 isc_mem_put(zone->mctx, zone->mastersok,
3408 zone->masterscnt * sizeof(isc_boolean_t));
3409 zone->mastersok = NULL;
3411 zone->masterscnt = 0;
3413 * If count == 0, don't allocate any space for masters, mastersok or
3414 * keynames so internally, those pointers are NULL if count == 0
3420 * masters must contain count elements!
3422 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3424 result = ISC_R_NOMEMORY;
3427 memcpy(new, masters, count * sizeof(*new));
3430 * Similarly for mastersok.
3432 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
3433 if (newok == NULL) {
3434 result = ISC_R_NOMEMORY;
3435 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3438 for (i = 0; i < count; i++)
3439 newok[i] = ISC_FALSE;
3442 * if keynames is non-NULL, it must contain count elements!
3445 if (keynames != NULL) {
3446 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
3447 if (newname == NULL) {
3448 result = ISC_R_NOMEMORY;
3449 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3450 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
3453 for (i = 0; i < count; i++)
3455 for (i = 0; i < count; i++) {
3456 if (keynames[i] != NULL) {
3457 newname[i] = isc_mem_get(zone->mctx,
3458 sizeof(dns_name_t));
3459 if (newname[i] == NULL)
3461 dns_name_init(newname[i], NULL);
3462 result = dns_name_dup(keynames[i], zone->mctx,
3464 if (result != ISC_R_SUCCESS) {
3466 for (i = 0; i < count; i++)
3467 if (newname[i] != NULL)
3471 isc_mem_put(zone->mctx, new,
3472 count * sizeof(*new));
3473 isc_mem_put(zone->mctx, newok,
3474 count * sizeof(*newok));
3475 isc_mem_put(zone->mctx, newname,
3476 count * sizeof(*newname));
3484 * Everything is ok so attach to the zone.
3486 zone->curmaster = 0;
3487 zone->masters = new;
3488 zone->mastersok = newok;
3489 zone->masterkeynames = newname;
3490 zone->masterscnt = count;
3491 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
3499 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
3500 isc_result_t result = ISC_R_SUCCESS;
3502 REQUIRE(DNS_ZONE_VALID(zone));
3504 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3505 if (zone->db == NULL)
3506 result = DNS_R_NOTLOADED;
3508 dns_db_attach(zone->db, dpb);
3509 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3515 * Co-ordinates the starting of routine jobs.
3519 dns_zone_maintenance(dns_zone_t *zone) {
3520 const char me[] = "dns_zone_maintenance";
3523 REQUIRE(DNS_ZONE_VALID(zone));
3528 zone_settimer(zone, &now);
3532 static inline isc_boolean_t
3533 was_dumping(dns_zone_t *zone) {
3534 isc_boolean_t dumping;
3536 REQUIRE(LOCKED_ZONE(zone));
3538 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
3539 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3541 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3542 isc_time_settoepoch(&zone->dumptime);
3548 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3551 dns_diff_t temp_diff;
3552 isc_result_t result;
3555 * Create a singleton diff.
3557 dns_diff_init(diff->mctx, &temp_diff);
3558 temp_diff.resign = diff->resign;
3559 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3562 * Apply it to the database.
3564 result = dns_diff_apply(&temp_diff, db, ver);
3565 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3566 if (result != ISC_R_SUCCESS) {
3567 dns_difftuple_free(tuple);
3572 * Merge it into the current pending journal entry.
3574 dns_diff_appendminimal(diff, tuple);
3577 * Do not clear temp_diff.
3579 return (ISC_R_SUCCESS);
3583 increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
3584 dns_diff_t *diff, isc_mem_t *mctx)
3586 dns_difftuple_t *deltuple = NULL;
3587 dns_difftuple_t *addtuple = NULL;
3588 isc_uint32_t serial;
3589 isc_result_t result;
3591 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3592 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3593 addtuple->op = DNS_DIFFOP_ADD;
3595 serial = dns_soa_getserial(&addtuple->rdata);
3598 serial = (serial + 1) & 0xFFFFFFFF;
3602 dns_soa_setserial(serial, &addtuple->rdata);
3603 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3604 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3605 result = ISC_R_SUCCESS;
3608 if (addtuple != NULL)
3609 dns_difftuple_free(&addtuple);
3610 if (deltuple != NULL)
3611 dns_difftuple_free(&deltuple);
3616 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3617 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3620 dns_difftuple_t *tuple = NULL;
3621 isc_result_t result;
3622 result = dns_difftuple_create(diff->mctx, op,
3623 name, ttl, rdata, &tuple);
3624 if (result != ISC_R_SUCCESS)
3626 return (do_one_tuple(&tuple, db, ver, diff));
3629 static isc_boolean_t
3630 ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) {
3631 isc_boolean_t ret = ISC_FALSE;
3632 isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE;
3633 isc_result_t result;
3634 dns_dbnode_t *node = NULL;
3635 dns_rdataset_t rdataset;
3636 dns_rdata_t rdata = DNS_RDATA_INIT;
3637 dns_rdata_dnskey_t dnskey;
3639 dns_rdataset_init(&rdataset);
3640 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3641 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
3643 CHECK(dns_rdataset_first(&rdataset));
3644 while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) {
3645 dns_rdataset_current(&rdataset, &rdata);
3646 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3647 if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
3648 == DNS_KEYOWNER_ZONE) {
3649 if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0)
3650 have_ksk = ISC_TRUE;
3652 have_nonksk = ISC_TRUE;
3654 dns_rdata_reset(&rdata);
3655 result = dns_rdataset_next(&rdataset);
3657 if (have_ksk && have_nonksk)
3660 if (dns_rdataset_isassociated(&rdataset))
3661 dns_rdataset_disassociate(&rdataset);
3663 dns_db_detachnode(db, &node);
3668 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3669 isc_mem_t *mctx, unsigned int maxkeys,
3670 dst_key_t **keys, unsigned int *nkeys)
3672 isc_result_t result;
3673 dns_dbnode_t *node = NULL;
3674 const char *directory = dns_zone_getkeydirectory(zone);
3676 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3677 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
3678 directory, mctx, maxkeys, keys,
3680 if (result == ISC_R_NOTFOUND)
3681 result = ISC_R_SUCCESS;
3684 dns_db_detachnode(db, &node);
3689 offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
3690 dns_ttl_t ttl, dns_rdata_t *rdata)
3692 isc_result_t result;
3694 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
3695 return (ISC_R_SUCCESS);
3696 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
3698 if (result != ISC_R_SUCCESS)
3700 rdata->flags |= DNS_RDATA_OFFLINE;
3701 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3707 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
3711 zone->key_expiry = when;
3713 dns_zone_log(zone, ISC_LOG_ERROR,
3714 "DNSKEY RRSIG(s) have expired");
3715 isc_time_settoepoch(&zone->keywarntime);
3716 } else if (when < now + 7 * 24 * 3600) {
3717 dns_zone_log(zone, ISC_LOG_WARNING,
3718 "DNSKEY RRSIG(s) will expire at %u",
3719 when); /* XXXMPA convert to date. */
3721 delta--; /* loop prevention */
3722 delta /= 24 * 3600; /* to whole days */
3723 delta *= 24 * 3600; /* to seconds */
3724 isc_time_set(&zone->keywarntime, when - delta, 0);
3726 dns_zone_log(zone, ISC_LOG_NOTICE, /* XXMPA ISC_LOG_DEBUG(1) */
3727 "setting keywarntime to %u - 7 days",
3728 when); /* XXXMPA convert to date. */
3729 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
3734 * Delete expired RRsigs and any RRsigs we are about to re-sign.
3735 * See also update.c:del_keysigs().
3738 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3739 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3740 unsigned int nkeys, isc_stdtime_t now)
3742 isc_result_t result;
3743 dns_dbnode_t *node = NULL;
3744 dns_rdataset_t rdataset;
3745 dns_rdata_t rdata = DNS_RDATA_INIT;
3747 dns_rdata_rrsig_t rrsig;
3748 isc_boolean_t found;
3749 isc_int64_t warn = 0, maybe = 0;
3751 dns_rdataset_init(&rdataset);
3753 if (type == dns_rdatatype_nsec3)
3754 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3756 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3757 if (result == ISC_R_NOTFOUND)
3758 return (ISC_R_SUCCESS);
3759 if (result != ISC_R_SUCCESS)
3761 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
3762 (isc_stdtime_t) 0, &rdataset, NULL);
3763 dns_db_detachnode(db, &node);
3765 if (result == ISC_R_NOTFOUND)
3766 return (ISC_R_SUCCESS);
3767 if (result != ISC_R_SUCCESS)
3770 for (result = dns_rdataset_first(&rdataset);
3771 result == ISC_R_SUCCESS;
3772 result = dns_rdataset_next(&rdataset)) {
3773 dns_rdataset_current(&rdataset, &rdata);
3774 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
3775 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3777 if (type != dns_rdatatype_dnskey) {
3778 result = update_one_rr(db, ver, diff,
3779 DNS_DIFFOP_DELRESIGN, name,
3780 rdataset.ttl, &rdata);
3781 dns_rdata_reset(&rdata);
3782 if (result != ISC_R_SUCCESS)
3788 * RRSIG(DNSKEY) requires special processing.
3791 for (i = 0; i < nkeys; i++) {
3792 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
3793 rrsig.keyid == dst_key_id(keys[i])) {
3796 * Mark offline RRSIG(DNSKEY).
3797 * We want the earliest offline expire time
3798 * iff there is a new offline signature.
3800 if (!dst_key_isprivate(keys[i])) {
3801 isc_int64_t timeexpire =
3802 dns_time64_from32(rrsig.timeexpire);
3803 if (warn != 0 && warn > timeexpire)
3805 if (rdata.flags & DNS_RDATA_OFFLINE) {
3813 if (warn == 0 || warn > timeexpire)
3815 result = offline(db, ver, diff, name,
3816 rdataset.ttl, &rdata);
3819 result = update_one_rr(db, ver, diff,
3820 DNS_DIFFOP_DELRESIGN,
3827 * If there is not a matching DNSKEY then
3831 result = update_one_rr(db, ver, diff,
3832 DNS_DIFFOP_DELRESIGN, name,
3833 rdataset.ttl, &rdata);
3834 dns_rdata_reset(&rdata);
3835 if (result != ISC_R_SUCCESS)
3838 dns_rdataset_disassociate(&rdataset);
3839 if (result == ISC_R_NOMORE)
3840 result = ISC_R_SUCCESS;
3842 #if defined(STDTIME_ON_32BITS)
3843 isc_stdtime_t stdwarn = (isc_stdtime_t)warn;
3844 if (warn == stdwarn)
3846 set_key_expiry_warning(zone, (isc_stdtime_t)warn, now);
3847 #if defined(STDTIME_ON_32BITS)
3849 dns_zone_log(zone, ISC_LOG_ERROR,
3850 "key expiry warning time out of range");
3855 dns_db_detachnode(db, &node);
3860 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3861 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3862 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
3863 isc_stdtime_t expire, isc_boolean_t check_ksk)
3865 isc_result_t result;
3866 dns_dbnode_t *node = NULL;
3867 dns_rdataset_t rdataset;
3868 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
3869 unsigned char data[1024]; /* XXX */
3870 isc_buffer_t buffer;
3873 dns_rdataset_init(&rdataset);
3874 isc_buffer_init(&buffer, data, sizeof(data));
3876 if (type == dns_rdatatype_nsec3)
3877 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3879 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3880 if (result == ISC_R_NOTFOUND)
3881 return (ISC_R_SUCCESS);
3882 if (result != ISC_R_SUCCESS)
3884 result = dns_db_findrdataset(db, node, ver, type, 0,
3885 (isc_stdtime_t) 0, &rdataset, NULL);
3886 dns_db_detachnode(db, &node);
3887 if (result == ISC_R_NOTFOUND)
3888 return (ISC_R_SUCCESS);
3889 if (result != ISC_R_SUCCESS)
3892 for (i = 0; i < nkeys; i++) {
3893 if (check_ksk && type != dns_rdatatype_dnskey &&
3894 (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0)
3896 if (!dst_key_isprivate(keys[i]))
3898 /* Calculate the signature, creating a RRSIG RDATA. */
3899 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
3900 &inception, &expire,
3901 mctx, &buffer, &sig_rdata));
3902 /* Update the database and journal with the RRSIG. */
3903 /* XXX inefficient - will cause dataset merging */
3904 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3905 name, rdataset.ttl, &sig_rdata));
3906 dns_rdata_reset(&sig_rdata);
3907 isc_buffer_init(&buffer, data, sizeof(data));
3911 if (dns_rdataset_isassociated(&rdataset))
3912 dns_rdataset_disassociate(&rdataset);
3914 dns_db_detachnode(db, &node);
3919 zone_resigninc(dns_zone_t *zone) {
3920 const char *journalfile;
3921 dns_db_t *db = NULL;
3922 dns_dbversion_t *version = NULL;
3923 dns_diff_t sig_diff;
3924 dns_fixedname_t fixed;
3926 dns_rdataset_t rdataset;
3927 dns_rdatatype_t covers;
3928 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
3929 isc_boolean_t check_ksk;
3930 isc_result_t result;
3931 isc_stdtime_t now, inception, soaexpire, expire, stop;
3932 isc_uint32_t jitter;
3934 unsigned int nkeys = 0;
3935 unsigned int resign;
3937 dns_rdataset_init(&rdataset);
3938 dns_fixedname_init(&fixed);
3939 dns_diff_init(zone->mctx, &sig_diff);
3940 sig_diff.resign = zone->sigresigninginterval;
3943 * Updates are disabled. Pause for 5 minutes.
3945 if (zone->update_disabled) {
3946 result = ISC_R_FAILURE;
3950 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3951 dns_db_attach(zone->db, &db);
3952 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3954 result = dns_db_newversion(db, &version);
3955 if (result != ISC_R_SUCCESS) {
3956 dns_zone_log(zone, ISC_LOG_ERROR,
3957 "zone_resigninc:dns_db_newversion -> %s",
3958 dns_result_totext(result));
3962 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
3964 if (result != ISC_R_SUCCESS) {
3965 dns_zone_log(zone, ISC_LOG_ERROR,
3966 "zone_resigninc:find_zone_keys -> %s",
3967 dns_result_totext(result));
3971 isc_stdtime_get(&now);
3972 inception = now - 3600; /* Allow for clock skew. */
3973 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
3975 * Spread out signatures over time if they happen to be
3976 * clumped. We don't do this for each add_sigs() call as
3977 * we still want some clustering to occur.
3979 isc_random_get(&jitter);
3980 expire = soaexpire - jitter % 3600;
3983 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
3985 check_ksk = ksk_sanity(db, version);
3987 name = dns_fixedname_name(&fixed);
3988 result = dns_db_getsigningtime(db, &rdataset, name);
3989 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
3990 dns_zone_log(zone, ISC_LOG_ERROR,
3991 "zone_resigninc:dns_db_getsigningtime -> %s",
3992 dns_result_totext(result));
3996 while (result == ISC_R_SUCCESS) {
3997 resign = rdataset.resign;
3998 covers = rdataset.covers;
4000 * Stop if we hit the SOA as that means we have walked the
4001 * entire zone. The SOA record should always be the most
4004 /* XXXMPA increase number of RRsets signed pre call */
4005 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
4008 * Ensure that we don't loop resigning the SOA.
4010 if (covers == dns_rdatatype_soa)
4011 dns_db_resigned(db, &rdataset, version);
4012 dns_rdataset_disassociate(&rdataset);
4016 dns_db_resigned(db, &rdataset, version);
4017 dns_rdataset_disassociate(&rdataset);
4019 result = del_sigs(zone, db, version, name, covers, &sig_diff,
4020 zone_keys, nkeys, now);
4021 if (result != ISC_R_SUCCESS) {
4022 dns_zone_log(zone, ISC_LOG_ERROR,
4023 "zone_resigninc:del_sigs -> %s",
4024 dns_result_totext(result));
4027 result = add_sigs(db, version, name, covers, &sig_diff,
4028 zone_keys, nkeys, zone->mctx, inception,
4030 if (result != ISC_R_SUCCESS) {
4031 dns_zone_log(zone, ISC_LOG_ERROR,
4032 "zone_resigninc:add_sigs -> %s",
4033 dns_result_totext(result));
4036 result = dns_db_getsigningtime(db, &rdataset,
4037 dns_fixedname_name(&fixed));
4038 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
4039 result = ISC_R_SUCCESS;
4042 if (result != ISC_R_SUCCESS)
4043 dns_zone_log(zone, ISC_LOG_ERROR,
4044 "zone_resigninc:dns_db_getsigningtime -> %s",
4045 dns_result_totext(result));
4048 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
4051 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
4052 &sig_diff, zone_keys, nkeys, now);
4053 if (result != ISC_R_SUCCESS) {
4054 dns_zone_log(zone, ISC_LOG_ERROR,
4055 "zone_resigninc:del_sigs -> %s",
4056 dns_result_totext(result));
4060 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
4061 if (result != ISC_R_SUCCESS) {
4062 dns_zone_log(zone, ISC_LOG_ERROR,
4063 "zone_resigninc:increment_soa_serial -> %s",
4064 dns_result_totext(result));
4069 * Generate maximum life time signatures so that the above loop
4070 * termination is sensible.
4072 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
4073 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
4074 soaexpire, check_ksk);
4075 if (result != ISC_R_SUCCESS) {
4076 dns_zone_log(zone, ISC_LOG_ERROR,
4077 "zone_resigninc:add_sigs -> %s",
4078 dns_result_totext(result));
4082 journalfile = dns_zone_getjournal(zone);
4083 if (journalfile != NULL) {
4084 dns_journal_t *journal = NULL;
4085 result = dns_journal_open(zone->mctx, journalfile,
4086 ISC_TRUE, &journal);
4087 if (result != ISC_R_SUCCESS) {
4088 dns_zone_log(zone, ISC_LOG_ERROR,
4089 "zone_resigninc:dns_journal_open -> %s",
4090 dns_result_totext(result));
4094 result = dns_journal_write_transaction(journal, &sig_diff);
4095 dns_journal_destroy(&journal);
4096 if (result != ISC_R_SUCCESS) {
4097 dns_zone_log(zone, ISC_LOG_ERROR,
4098 "zone_resigninc:dns_journal_write_transaction -> %s",
4099 dns_result_totext(result));
4105 * Everything has succeeded. Commit the changes.
4107 dns_db_closeversion(db, &version, ISC_TRUE);
4110 dns_diff_clear(&sig_diff);
4111 for (i = 0; i < nkeys; i++)
4112 dst_key_free(&zone_keys[i]);
4113 if (version != NULL) {
4114 dns_db_closeversion(zone->db, &version, ISC_FALSE);
4116 } else if (db != NULL)
4118 if (result == ISC_R_SUCCESS) {
4119 set_resigntime(zone);
4121 zone_needdump(zone, DNS_DUMP_DELAY);
4122 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
4126 * Something failed. Retry in 5 minutes.
4128 isc_interval_t ival;
4129 isc_interval_set(&ival, 300, 0);
4130 isc_time_nowplusinterval(&zone->resigntime, &ival);
4135 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
4136 dns_name_t *newname, isc_boolean_t bottom)
4138 isc_result_t result;
4139 dns_dbiterator_t *dbit = NULL;
4140 dns_rdatasetiter_t *rdsit = NULL;
4141 dns_dbnode_t *node = NULL;
4143 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
4144 CHECK(dns_dbiterator_seek(dbit, oldname));
4146 result = dns_dbiterator_next(dbit);
4147 if (result == ISC_R_NOMORE)
4148 CHECK(dns_dbiterator_first(dbit));
4149 CHECK(dns_dbiterator_current(dbit, &node, newname));
4150 if (bottom && dns_name_issubdomain(newname, oldname) &&
4151 !dns_name_equal(newname, oldname)) {
4152 dns_db_detachnode(db, &node);
4156 * Is this node empty?
4158 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
4159 result = dns_rdatasetiter_first(rdsit);
4160 dns_db_detachnode(db, &node);
4161 dns_rdatasetiter_destroy(&rdsit);
4162 if (result != ISC_R_NOMORE)
4167 dns_db_detachnode(db, &node);
4169 dns_dbiterator_destroy(&dbit);
4174 set_bit(unsigned char *array, unsigned int index) {
4175 unsigned int shift, mask;
4177 shift = 7 - (index % 8);
4180 array[index / 8] |= mask;
4183 static isc_boolean_t
4184 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4185 dns_rdatatype_t type, dst_key_t *key)
4187 isc_result_t result;
4188 dns_rdataset_t rdataset;
4189 dns_rdata_t rdata = DNS_RDATA_INIT;
4190 dns_rdata_rrsig_t rrsig;
4192 dns_rdataset_init(&rdataset);
4193 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
4194 type, 0, &rdataset, NULL);
4195 if (result != ISC_R_SUCCESS)
4197 for (result = dns_rdataset_first(&rdataset);
4198 result == ISC_R_SUCCESS;
4199 result = dns_rdataset_next(&rdataset)) {
4200 dns_rdataset_current(&rdataset, &rdata);
4201 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
4202 INSIST(result == ISC_R_SUCCESS);
4203 if (rrsig.algorithm == dst_key_alg(key) &&
4204 rrsig.keyid == dst_key_id(key)) {
4205 dns_rdataset_disassociate(&rdataset);
4208 dns_rdata_reset(&rdata);
4210 dns_rdataset_disassociate(&rdataset);
4215 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4216 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
4219 dns_fixedname_t fixed;
4221 dns_rdata_t rdata = DNS_RDATA_INIT;
4222 isc_result_t result;
4223 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4225 dns_fixedname_init(&fixed);
4226 next = dns_fixedname_name(&fixed);
4228 CHECK(next_active(db, version, name, next, bottom));
4229 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
4231 if (dns_name_equal(dns_db_origin(db), name)) {
4233 * Set the OPT bit to indicate that this is a
4234 * partially secure zone.
4236 isc_region_t region;
4238 dns_rdata_toregion(&rdata, ®ion);
4239 dns_name_fromregion(next, ®ion);
4240 isc_region_consume(®ion, next->length);
4241 INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
4242 region.base[0] == 0 &&
4243 region.base[1] > dns_rdatatype_opt / 8);
4244 set_bit(region.base + 2, dns_rdatatype_opt);
4246 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
4253 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
4254 dns_dbversion_t *version, isc_boolean_t build_nsec3,
4255 isc_boolean_t build_nsec, dst_key_t *key,
4256 isc_stdtime_t inception, isc_stdtime_t expire,
4257 unsigned int minimum, isc_boolean_t is_ksk,
4258 isc_boolean_t *delegation, dns_diff_t *diff,
4259 isc_int32_t *signatures, isc_mem_t *mctx)
4261 isc_result_t result;
4262 dns_rdatasetiter_t *iterator = NULL;
4263 dns_rdataset_t rdataset;
4264 dns_rdata_t rdata = DNS_RDATA_INIT;
4265 isc_buffer_t buffer;
4266 unsigned char data[1024];
4267 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
4268 seen_nsec3, seen_ds;
4269 isc_boolean_t bottom;
4271 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4272 if (result != ISC_R_SUCCESS) {
4273 if (result == ISC_R_NOTFOUND)
4274 result = ISC_R_SUCCESS;
4277 dns_rdataset_init(&rdataset);
4278 isc_buffer_init(&buffer, data, sizeof(data));
4279 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
4280 seen_nsec3 = seen_ds = ISC_FALSE;
4281 for (result = dns_rdatasetiter_first(iterator);
4282 result == ISC_R_SUCCESS;
4283 result = dns_rdatasetiter_next(iterator)) {
4284 dns_rdatasetiter_current(iterator, &rdataset);
4285 if (rdataset.type == dns_rdatatype_soa)
4286 seen_soa = ISC_TRUE;
4287 else if (rdataset.type == dns_rdatatype_ns)
4289 else if (rdataset.type == dns_rdatatype_ds)
4291 else if (rdataset.type == dns_rdatatype_dname)
4292 seen_dname = ISC_TRUE;
4293 else if (rdataset.type == dns_rdatatype_nsec)
4294 seen_nsec = ISC_TRUE;
4295 else if (rdataset.type == dns_rdatatype_nsec3)
4296 seen_nsec3 = ISC_TRUE;
4298 dns_rdataset_disassociate(&rdataset);
4300 if (result != ISC_R_NOMORE)
4302 if (seen_ns && !seen_soa)
4303 *delegation = ISC_TRUE;
4305 * Going from insecure to NSEC3.
4306 * Don't generate NSEC3 records for NSEC3 records.
4308 if (build_nsec3 && !seen_nsec3 && seen_rr) {
4309 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
4310 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
4315 * Going from insecure to NSEC.
4316 * Don't generate NSEC records for NSEC3 records.
4318 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
4319 /* Build and add NSEC. */
4320 bottom = (seen_ns && !seen_soa) || seen_dname;
4321 CHECK(add_nsec(db, version, name, node, minimum, bottom, diff));
4322 /* Count a NSEC generation as a signature generation. */
4325 result = dns_rdatasetiter_first(iterator);
4326 while (result == ISC_R_SUCCESS) {
4327 dns_rdatasetiter_current(iterator, &rdataset);
4328 if (rdataset.type == dns_rdatatype_soa ||
4329 rdataset.type == dns_rdatatype_rrsig)
4331 if (is_ksk && rdataset.type != dns_rdatatype_dnskey)
4334 rdataset.type != dns_rdatatype_ds &&
4335 rdataset.type != dns_rdatatype_nsec)
4337 if (signed_with_key(db, node, version, rdataset.type, key))
4339 /* Calculate the signature, creating a RRSIG RDATA. */
4340 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
4341 &expire, mctx, &buffer, &rdata));
4342 /* Update the database and journal with the RRSIG. */
4343 /* XXX inefficient - will cause dataset merging */
4344 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
4345 name, rdataset.ttl, &rdata));
4346 dns_rdata_reset(&rdata);
4349 dns_rdataset_disassociate(&rdataset);
4350 result = dns_rdatasetiter_next(iterator);
4352 if (result == ISC_R_NOMORE)
4353 result = ISC_R_SUCCESS;
4355 *delegation = ISC_TRUE;
4357 if (dns_rdataset_isassociated(&rdataset))
4358 dns_rdataset_disassociate(&rdataset);
4359 if (iterator != NULL)
4360 dns_rdatasetiter_destroy(&iterator);
4365 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4366 dns_ttl_t minimum, isc_boolean_t *secureupdated, dns_diff_t *diff)
4368 isc_result_t result;
4369 dns_rdata_t rdata = DNS_RDATA_INIT;
4370 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4371 dns_rdataset_t rdataset;
4372 dns_rdata_nsec_t nsec;
4373 dns_dbnode_t *node = NULL;
4376 * Check to see if the OPT bit has already been cleared.
4378 CHECK(dns_db_getoriginnode(db, &node));
4379 dns_rdataset_init(&rdataset);
4380 CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
4381 dns_rdatatype_none, 0, &rdataset, NULL));
4382 CHECK(dns_rdataset_first(&rdataset));
4383 dns_rdataset_current(&rdataset, &rdata);
4386 * Find the NEXT name for building the new record.
4388 CHECK(dns_rdata_tostruct(&rdata, &nsec, NULL));
4391 * Delete the old NSEC record.
4393 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_DEL, name, minimum,
4395 dns_rdata_reset(&rdata);
4398 * Add the new NSEC record.
4400 CHECK(dns_nsec_buildrdata(db, version, node, &nsec.next, nsecbuffer,
4402 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, minimum,
4404 dns_rdata_reset(&rdata);
4406 if (secureupdated != NULL)
4407 *secureupdated = ISC_TRUE;
4411 dns_db_detachnode(db, &node);
4412 if (dns_rdataset_isassociated(&rdataset))
4413 dns_rdataset_disassociate(&rdataset);
4418 updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
4419 dns_name_t *name, dns_rdatatype_t privatetype,
4422 isc_result_t result;
4423 dns_dbnode_t *node = NULL;
4424 dns_rdataset_t rdataset;
4425 dns_rdata_t rdata = DNS_RDATA_INIT;
4426 unsigned char data[5];
4427 isc_boolean_t seen_done = ISC_FALSE;
4429 dns_rdataset_init(&rdataset);
4430 result = dns_db_getoriginnode(signing->db, &node);
4431 if (result != ISC_R_SUCCESS)
4434 result = dns_db_findrdataset(signing->db, node, version, privatetype,
4435 dns_rdatatype_none, 0, &rdataset, NULL);
4436 if (result == ISC_R_NOTFOUND) {
4437 result = ISC_R_SUCCESS;
4440 if (result != ISC_R_SUCCESS)
4442 for (result = dns_rdataset_first(&rdataset);
4443 result == ISC_R_SUCCESS;
4444 result = dns_rdataset_next(&rdataset)) {
4445 dns_rdataset_current(&rdataset, &rdata);
4446 if (rdata.length != 5 ||
4447 rdata.data[0] != signing->algorithm ||
4448 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
4449 rdata.data[2] != (signing->keyid & 0xff)) {
4450 dns_rdata_reset(&rdata);
4453 if (!signing->delete && rdata.data[4] != 0)
4454 seen_done = ISC_TRUE;
4456 CHECK(update_one_rr(signing->db, version, diff,
4457 DNS_DIFFOP_DEL, name,
4458 rdataset.ttl, &rdata));
4459 dns_rdata_reset(&rdata);
4461 if (result == ISC_R_NOMORE)
4462 result = ISC_R_SUCCESS;
4463 if (!signing->delete && !seen_done) {
4465 data[0] = signing->algorithm;
4466 data[1] = (signing->keyid >> 8) & 0xff;
4467 data[2] = signing->keyid & 0xff;
4470 rdata.length = sizeof(data);
4472 rdata.type = privatetype;
4473 rdata.rdclass = dns_db_class(signing->db);
4474 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
4475 name, rdataset.ttl, &rdata));
4478 if (dns_rdataset_isassociated(&rdataset))
4479 dns_rdataset_disassociate(&rdataset);
4481 dns_db_detachnode(signing->db, &node);
4486 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
4487 isc_boolean_t active, dns_diff_t *diff)
4489 dns_dbnode_t *node = NULL;
4490 dns_name_t *name = dns_db_origin(db);
4491 dns_rdata_t rdata = DNS_RDATA_INIT;
4492 dns_rdataset_t rdataset;
4493 dns_rdata_nsec3param_t nsec3param;
4494 isc_result_t result;
4495 isc_buffer_t buffer;
4496 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
4499 dns_rdataset_init(&rdataset);
4501 result = dns_db_getoriginnode(db, &node);
4502 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4503 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4504 0, 0, &rdataset, NULL);
4505 if (result == ISC_R_NOTFOUND)
4507 if (result != ISC_R_SUCCESS)
4511 * Preserve the existing ttl.
4516 * Delete all NSEC3PARAM records which match that in nsec3chain.
4518 for (result = dns_rdataset_first(&rdataset);
4519 result == ISC_R_SUCCESS;
4520 result = dns_rdataset_next(&rdataset)) {
4522 dns_rdataset_current(&rdataset, &rdata);
4523 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
4525 if (nsec3param.hash != chain->nsec3param.hash ||
4526 (active && nsec3param.flags != 0) ||
4527 nsec3param.iterations != chain->nsec3param.iterations ||
4528 nsec3param.salt_length != chain->nsec3param.salt_length ||
4529 memcmp(nsec3param.salt, chain->nsec3param.salt,
4530 nsec3param.salt_length)) {
4531 dns_rdata_reset(&rdata);
4535 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
4536 name, rdataset.ttl, &rdata));
4537 dns_rdata_reset(&rdata);
4539 if (result != ISC_R_NOMORE)
4543 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
4544 result = ISC_R_SUCCESS;
4549 * Add a NSEC3PARAM record which matches that in nsec3chain but
4550 * with all flags bits cleared.
4552 * Note: we do not clear chain->nsec3param.flags as this change
4555 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
4556 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
4557 dns_rdatatype_nsec3param,
4558 &chain->nsec3param, &buffer));
4559 rdata.data[1] = 0; /* Clear flag bits. */
4560 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
4563 dns_db_detachnode(db, &node);
4564 if (dns_rdataset_isassociated(&rdataset))
4565 dns_rdataset_disassociate(&rdataset);
4570 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4571 dns_name_t *name, dns_diff_t *diff)
4573 dns_rdataset_t rdataset;
4574 isc_result_t result;
4576 dns_rdataset_init(&rdataset);
4578 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4579 0, 0, &rdataset, NULL);
4580 if (result == ISC_R_NOTFOUND)
4581 return (ISC_R_SUCCESS);
4582 if (result != ISC_R_SUCCESS)
4584 for (result = dns_rdataset_first(&rdataset);
4585 result == ISC_R_SUCCESS;
4586 result = dns_rdataset_next(&rdataset)) {
4587 dns_rdata_t rdata = DNS_RDATA_INIT;
4589 dns_rdataset_current(&rdataset, &rdata);
4590 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4591 rdataset.ttl, &rdata));
4593 if (result == ISC_R_NOMORE)
4594 result = ISC_R_SUCCESS;
4596 dns_rdataset_disassociate(&rdataset);
4601 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4602 dns_name_t *name, const dns_rdata_nsec3param_t *param,
4605 dns_rdataset_t rdataset;
4606 dns_rdata_nsec3_t nsec3;
4607 isc_result_t result;
4609 dns_rdataset_init(&rdataset);
4610 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
4611 0, 0, &rdataset, NULL);
4612 if (result == ISC_R_NOTFOUND)
4613 return (ISC_R_SUCCESS);
4614 if (result != ISC_R_SUCCESS)
4617 for (result = dns_rdataset_first(&rdataset);
4618 result == ISC_R_SUCCESS;
4619 result = dns_rdataset_next(&rdataset)) {
4620 dns_rdata_t rdata = DNS_RDATA_INIT;
4622 dns_rdataset_current(&rdataset, &rdata);
4623 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
4624 if (nsec3.hash != param->hash ||
4625 nsec3.iterations != param->iterations ||
4626 nsec3.salt_length != param->salt_length ||
4627 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
4629 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4630 rdataset.ttl, &rdata));
4632 if (result == ISC_R_NOMORE)
4633 result = ISC_R_SUCCESS;
4635 dns_rdataset_disassociate(&rdataset);
4640 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
4641 const dns_rdata_nsec3param_t *param,
4642 isc_boolean_t *answer, isc_boolean_t *updatensec)
4644 dns_dbnode_t *node = NULL;
4645 dns_rdata_t rdata = DNS_RDATA_INIT;
4646 dns_rdata_nsec3param_t myparam;
4647 dns_rdataset_t rdataset;
4648 isc_result_t result;
4650 *answer = ISC_FALSE;
4652 result = dns_db_getoriginnode(db, &node);
4653 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4655 dns_rdataset_init(&rdataset);
4656 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4657 0, 0, &rdataset, NULL);
4658 if (result == ISC_R_NOTFOUND)
4659 goto check_nsec3param;
4661 if (result != ISC_R_SUCCESS)
4664 CHECK(dns_rdataset_first(&rdataset));
4665 dns_rdataset_current(&rdataset, &rdata);
4667 if (!dns_nsec_typepresent(&rdata, dns_rdatatype_opt)) {
4669 * We have a complete NSEC chain. Signal to update
4670 * the apex NSEC record.
4672 *updatensec = ISC_TRUE;
4675 dns_rdataset_disassociate(&rdataset);
4676 dns_rdata_reset(&rdata);
4679 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4680 0, 0, &rdataset, NULL);
4681 if (result == ISC_R_NOTFOUND) {
4683 dns_db_detachnode(db, &node);
4684 return (ISC_R_SUCCESS);
4686 if (result != ISC_R_SUCCESS) {
4687 dns_db_detachnode(db, &node);
4691 for (result = dns_rdataset_first(&rdataset);
4692 result == ISC_R_SUCCESS;
4693 result = dns_rdataset_next(&rdataset)) {
4694 dns_rdataset_current(&rdataset, &rdata);
4695 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
4696 dns_rdata_reset(&rdata);
4698 * Ignore any NSEC3PARAM removals.
4700 if (NSEC3REMOVE(myparam.flags))
4703 * Ignore the chain that we are in the process of deleting.
4705 if (myparam.hash == param->hash &&
4706 myparam.iterations == param->iterations &&
4707 myparam.salt_length == param->salt_length &&
4708 !memcmp(myparam.salt, param->salt, myparam.salt_length))
4711 * Found an active NSEC3 chain.
4715 if (result == ISC_R_NOMORE) {
4717 result = ISC_R_SUCCESS;
4721 if (dns_rdataset_isassociated(&rdataset))
4722 dns_rdataset_disassociate(&rdataset);
4723 dns_db_detachnode(db, &node);
4728 * Incrementally build and sign a new NSEC3 chain using the parameters
4732 zone_nsec3chain(dns_zone_t *zone) {
4733 const char *journalfile;
4734 dns_db_t *db = NULL;
4735 dns_dbnode_t *node = NULL;
4736 dns_dbversion_t *version = NULL;
4737 dns_diff_t sig_diff;
4738 dns_diff_t nsec_diff;
4739 dns_diff_t nsec3_diff;
4740 dns_diff_t param_diff;
4741 dns_fixedname_t fixed;
4742 dns_fixedname_t nextfixed;
4743 dns_name_t *name, *nextname;
4744 dns_rdataset_t rdataset;
4745 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
4746 dns_nsec3chainlist_t cleanup;
4747 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
4748 isc_int32_t signatures;
4749 isc_boolean_t check_ksk;
4750 isc_boolean_t delegation;
4751 isc_boolean_t first;
4752 isc_result_t result;
4753 isc_stdtime_t now, inception, soaexpire, expire;
4754 isc_uint32_t jitter;
4756 unsigned int nkeys = 0;
4758 isc_boolean_t unsecure = ISC_FALSE;
4759 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
4760 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
4761 dns_rdatasetiter_t *iterator = NULL;
4762 dns_difftuple_t *tuple;
4763 isc_boolean_t buildnsecchain;
4764 isc_boolean_t updatensec = ISC_FALSE;
4766 dns_rdataset_init(&rdataset);
4767 dns_fixedname_init(&fixed);
4768 name = dns_fixedname_name(&fixed);
4769 dns_fixedname_init(&nextfixed);
4770 nextname = dns_fixedname_name(&nextfixed);
4771 dns_diff_init(zone->mctx, ¶m_diff);
4772 dns_diff_init(zone->mctx, &nsec3_diff);
4773 dns_diff_init(zone->mctx, &nsec_diff);
4774 dns_diff_init(zone->mctx, &sig_diff);
4775 sig_diff.resign = zone->sigresigninginterval;
4776 ISC_LIST_INIT(cleanup);
4779 * Updates are disabled. Pause for 5 minutes.
4781 if (zone->update_disabled) {
4782 result = ISC_R_FAILURE;
4786 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4787 dns_db_attach(zone->db, &db);
4788 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4790 result = dns_db_newversion(db, &version);
4791 if (result != ISC_R_SUCCESS) {
4792 dns_zone_log(zone, ISC_LOG_ERROR,
4793 "zone_nsec3chain:dns_db_newversion -> %s",
4794 dns_result_totext(result));
4798 result = find_zone_keys(zone, db, version, zone->mctx,
4799 DNS_MAXZONEKEYS, zone_keys, &nkeys);
4800 if (result != ISC_R_SUCCESS) {
4801 dns_zone_log(zone, ISC_LOG_ERROR,
4802 "zone_nsec3chain:find_zone_keys -> %s",
4803 dns_result_totext(result));
4807 isc_stdtime_get(&now);
4808 inception = now - 3600; /* Allow for clock skew. */
4809 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
4812 * Spread out signatures over time if they happen to be
4813 * clumped. We don't do this for each add_sigs() call as
4814 * we still want some clustering to occur.
4816 isc_random_get(&jitter);
4817 expire = soaexpire - jitter % 3600;
4819 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
4821 check_ksk = ksk_sanity(db, version);
4824 * We keep pulling nodes off each iterator in turn until
4825 * we have no more nodes to pull off or we reach the limits
4828 nodes = zone->nodes;
4829 signatures = zone->signatures;
4831 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
4835 if (nsec3chain != NULL)
4836 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
4838 * Generate new NSEC3 chains first.
4840 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
4842 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
4844 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4845 if (nsec3chain->done || nsec3chain->db != zone->db) {
4846 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
4847 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4849 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4851 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
4855 * Possible future db.
4857 if (nsec3chain->db != db) {
4861 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
4864 delegation = ISC_FALSE;
4865 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
4867 if (nsec3chain->delete_nsec) {
4868 dns_dbiterator_pause(nsec3chain->dbiterator);
4869 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
4874 * On the first pass we need to check if the current node
4875 * has not been obscured.
4877 unsecure = ISC_FALSE;
4879 dns_fixedname_t ffound;
4881 dns_fixedname_init(&ffound);
4882 found = dns_fixedname_name(&ffound);
4883 result = dns_db_find(db, name, version,
4885 DNS_DBFIND_NOWILD, 0, NULL, found,
4887 if ((result == DNS_R_DELEGATION ||
4888 result == DNS_R_DNAME) &&
4889 !dns_name_equal(name, found)) {
4891 * Remember the obscuring name so that
4892 * we skip all obscured names.
4894 dns_name_copy(found, name, NULL);
4895 delegation = ISC_TRUE;
4901 * Check to see if this is a bottom of zone node.
4903 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4904 if (result == ISC_R_NOTFOUND) /* Empty node? */
4906 if (result != ISC_R_SUCCESS)
4909 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
4911 for (result = dns_rdatasetiter_first(iterator);
4912 result == ISC_R_SUCCESS;
4913 result = dns_rdatasetiter_next(iterator)) {
4914 dns_rdatasetiter_current(iterator, &rdataset);
4915 INSIST(rdataset.type != dns_rdatatype_nsec3);
4916 if (rdataset.type == dns_rdatatype_soa)
4917 seen_soa = ISC_TRUE;
4918 else if (rdataset.type == dns_rdatatype_ns)
4920 else if (rdataset.type == dns_rdatatype_dname)
4921 seen_dname = ISC_TRUE;
4922 else if (rdataset.type == dns_rdatatype_ds)
4924 else if (rdataset.type == dns_rdatatype_nsec)
4925 seen_nsec = ISC_TRUE;
4926 dns_rdataset_disassociate(&rdataset);
4928 dns_rdatasetiter_destroy(&iterator);
4930 * Is there a NSEC chain than needs to be cleaned up?
4933 nsec3chain->seen_nsec = ISC_TRUE;
4934 if (seen_ns && !seen_soa && !seen_ds)
4935 unsecure = ISC_TRUE;
4936 if ((seen_ns && !seen_soa) || seen_dname)
4937 delegation = ISC_TRUE;
4942 dns_dbiterator_pause(nsec3chain->dbiterator);
4943 CHECK(dns_nsec3_addnsec3(db, version, name,
4944 &nsec3chain->nsec3param,
4945 zone->minimum, unsecure, &nsec3_diff));
4947 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
4948 * two signatures. Additionally there will, in general, be
4949 * two signature generated below.
4951 * If we are only changing the optout flag the cost is half
4952 * that of the cost of generating a completely new chain.
4957 * Go onto next node.
4961 dns_db_detachnode(db, &node);
4963 result = dns_dbiterator_next(nsec3chain->dbiterator);
4965 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
4966 CHECK(fixup_nsec3param(db, version, nsec3chain,
4967 ISC_FALSE, ¶m_diff));
4969 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4972 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4975 if (result == ISC_R_NOMORE) {
4976 dns_dbiterator_pause(nsec3chain->dbiterator);
4977 if (nsec3chain->seen_nsec) {
4978 CHECK(fixup_nsec3param(db, version,
4982 nsec3chain->delete_nsec = ISC_TRUE;
4985 CHECK(fixup_nsec3param(db, version, nsec3chain,
4986 ISC_FALSE, ¶m_diff));
4988 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4991 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4993 } else if (result != ISC_R_SUCCESS) {
4994 dns_zone_log(zone, ISC_LOG_ERROR,
4996 "dns_dbiterator_next -> %s",
4997 dns_result_totext(result));
4999 } else if (delegation) {
5000 dns_dbiterator_current(nsec3chain->dbiterator,
5002 dns_db_detachnode(db, &node);
5003 if (!dns_name_issubdomain(nextname, name))
5011 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
5016 dns_dbiterator_pause(nsec3chain->dbiterator);
5017 nsec3chain = nextnsec3chain;
5019 if (nsec3chain != NULL)
5020 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
5027 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5030 buildnsecchain = ISC_FALSE;
5031 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
5033 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
5036 if (nsec3chain->db != db)
5037 goto next_removechain;
5039 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
5040 goto next_removechain;
5043 * Work out if we need to build a NSEC chain as a consequence
5044 * of removing this NSEC3 chain.
5046 if (first && !updatensec &&
5047 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
5048 CHECK(need_nsec_chain(db, version,
5049 &nsec3chain->nsec3param,
5050 &buildnsecchain, &updatensec));
5052 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
5053 delegation = ISC_FALSE;
5055 if (!buildnsecchain) {
5057 * Delete the NSECPARAM record that matches this chain.
5060 CHECK(fixup_nsec3param(db, version, nsec3chain,
5061 ISC_TRUE, ¶m_diff));
5064 * Delete the NSEC3 records.
5066 CHECK(deletematchingnsec3(db, version, node, name,
5067 &nsec3chain->nsec3param,
5069 goto next_removenode;
5073 dns_fixedname_t ffound;
5075 dns_fixedname_init(&ffound);
5076 found = dns_fixedname_name(&ffound);
5077 result = dns_db_find(db, name, version,
5079 DNS_DBFIND_NOWILD, 0, NULL, found,
5081 if ((result == DNS_R_DELEGATION ||
5082 result == DNS_R_DNAME) &&
5083 !dns_name_equal(name, found)) {
5085 * Remember the obscuring name so that
5086 * we skip all obscured names.
5088 dns_name_copy(found, name, NULL);
5089 delegation = ISC_TRUE;
5090 goto next_removenode;
5095 * Check to see if this is a bottom of zone node.
5097 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5098 if (result == ISC_R_NOTFOUND) /* Empty node? */
5099 goto next_removenode;
5100 if (result != ISC_R_SUCCESS)
5103 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
5104 seen_rr = ISC_FALSE;
5105 for (result = dns_rdatasetiter_first(iterator);
5106 result == ISC_R_SUCCESS;
5107 result = dns_rdatasetiter_next(iterator)) {
5108 dns_rdatasetiter_current(iterator, &rdataset);
5109 if (rdataset.type == dns_rdatatype_soa)
5110 seen_soa = ISC_TRUE;
5111 else if (rdataset.type == dns_rdatatype_ns)
5113 else if (rdataset.type == dns_rdatatype_dname)
5114 seen_dname = ISC_TRUE;
5115 else if (rdataset.type == dns_rdatatype_nsec)
5116 seen_nsec = ISC_TRUE;
5117 else if (rdataset.type == dns_rdatatype_nsec3)
5118 seen_nsec3 = ISC_TRUE;
5120 dns_rdataset_disassociate(&rdataset);
5122 dns_rdatasetiter_destroy(&iterator);
5124 if (!seen_rr || seen_nsec3 || seen_nsec)
5125 goto next_removenode;
5126 if ((seen_ns && !seen_soa) || seen_dname)
5127 delegation = ISC_TRUE;
5129 CHECK(add_nsec(db, version, name, node, zone->minimum,
5130 delegation, &nsec_diff));
5134 dns_db_detachnode(db, &node);
5136 result = dns_dbiterator_next(nsec3chain->dbiterator);
5137 if (result == ISC_R_NOMORE && buildnsecchain) {
5139 * The NSEC chain should now be built.
5140 * We can now remove the NSEC3 chain.
5142 updatensec = ISC_TRUE;
5143 goto same_removechain;
5145 if (result == ISC_R_NOMORE) {
5147 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
5150 ISC_LIST_APPEND(cleanup, nsec3chain, link);
5151 dns_dbiterator_pause(nsec3chain->dbiterator);
5152 CHECK(fixup_nsec3param(db, version, nsec3chain,
5153 ISC_FALSE, ¶m_diff));
5154 goto next_removechain;
5155 } else if (result != ISC_R_SUCCESS) {
5156 dns_zone_log(zone, ISC_LOG_ERROR,
5158 "dns_dbiterator_next -> %s",
5159 dns_result_totext(result));
5161 } else if (delegation) {
5162 dns_dbiterator_current(nsec3chain->dbiterator,
5164 dns_db_detachnode(db, &node);
5165 if (!dns_name_issubdomain(nextname, name))
5173 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
5174 buildnsecchain = ISC_FALSE;
5179 dns_dbiterator_pause(nsec3chain->dbiterator);
5180 nsec3chain = nextnsec3chain;
5185 * Add / update signatures for the NSEC3 records.
5187 for (tuple = ISC_LIST_HEAD(nsec3_diff.tuples);
5189 tuple = ISC_LIST_HEAD(nsec3_diff.tuples)) {
5191 * We have changed the NSEC3 RRset above so we need to update
5194 result = del_sigs(zone, db, version, &tuple->name,
5195 dns_rdatatype_nsec3, &sig_diff,
5196 zone_keys, nkeys, now);
5197 if (result != ISC_R_SUCCESS) {
5198 dns_zone_log(zone, ISC_LOG_ERROR,
5199 "zone_nsec3chain:del_sigs -> %s",
5200 dns_result_totext(result));
5203 result = add_sigs(db, version, &tuple->name,
5204 dns_rdatatype_nsec3, &sig_diff, zone_keys,
5205 nkeys, zone->mctx, inception, expire,
5207 if (result != ISC_R_SUCCESS) {
5208 dns_zone_log(zone, ISC_LOG_ERROR,
5209 "zone_nsec3chain:add_sigs -> %s",
5210 dns_result_totext(result));
5215 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
5216 while (next != NULL &&
5217 !dns_name_equal(&tuple->name, &next->name))
5218 next = ISC_LIST_NEXT(next, link);
5219 ISC_LIST_UNLINK(nsec3_diff.tuples, tuple, link);
5220 dns_diff_appendminimal(&sig_diff, &tuple);
5221 INSIST(tuple == NULL);
5223 } while (tuple != NULL);
5226 for (tuple = ISC_LIST_HEAD(param_diff.tuples);
5228 tuple = ISC_LIST_HEAD(param_diff.tuples)) {
5230 * We have changed the NSEC3PARAM RRset above so we need to
5231 * update the signatures.
5233 result = del_sigs(zone, db, version, &tuple->name,
5234 dns_rdatatype_nsec3param, &sig_diff,
5235 zone_keys, nkeys, now);
5236 if (result != ISC_R_SUCCESS) {
5237 dns_zone_log(zone, ISC_LOG_ERROR,
5238 "zone_nsec3chain:del_sigs -> %s",
5239 dns_result_totext(result));
5242 result = add_sigs(db, version, &tuple->name,
5243 dns_rdatatype_nsec3param, &sig_diff,
5244 zone_keys, nkeys, zone->mctx, inception,
5246 if (result != ISC_R_SUCCESS) {
5247 dns_zone_log(zone, ISC_LOG_ERROR,
5248 "zone_nsec3chain:add_sigs -> %s",
5249 dns_result_totext(result));
5252 ISC_LIST_UNLINK(param_diff.tuples, tuple, link);
5253 dns_diff_appendminimal(&sig_diff, &tuple);
5254 INSIST(tuple == NULL);
5258 CHECK(updatesecure(db, version, &zone->origin, zone->minimum,
5261 for (tuple = ISC_LIST_HEAD(nsec_diff.tuples);
5263 tuple = ISC_LIST_HEAD(nsec_diff.tuples)) {
5264 result = del_sigs(zone, db, version, &tuple->name,
5265 dns_rdatatype_nsec, &sig_diff,
5266 zone_keys, nkeys, now);
5267 if (result != ISC_R_SUCCESS) {
5268 dns_zone_log(zone, ISC_LOG_ERROR,
5269 "zone_nsec3chain:del_sigs -> %s",
5270 dns_result_totext(result));
5273 result = add_sigs(db, version, &tuple->name,
5274 dns_rdatatype_nsec, &sig_diff,
5275 zone_keys, nkeys, zone->mctx, inception,
5277 if (result != ISC_R_SUCCESS) {
5278 dns_zone_log(zone, ISC_LOG_ERROR,
5279 "zone_nsec3chain:add_sigs -> %s",
5280 dns_result_totext(result));
5283 ISC_LIST_UNLINK(nsec_diff.tuples, tuple, link);
5284 dns_diff_appendminimal(&sig_diff, &tuple);
5285 INSIST(tuple == NULL);
5289 * If we made no effective changes to the zone then we can just
5290 * cleanup otherwise we need to increment the serial.
5292 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5295 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5296 &sig_diff, zone_keys, nkeys, now);
5297 if (result != ISC_R_SUCCESS) {
5298 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5299 "del_sigs -> %s", dns_result_totext(result));
5303 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5304 if (result != ISC_R_SUCCESS) {
5305 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5306 "increment_soa_serial -> %s",
5307 dns_result_totext(result));
5311 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5312 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5313 soaexpire, check_ksk);
5314 if (result != ISC_R_SUCCESS) {
5315 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5316 "add_sigs -> %s", dns_result_totext(result));
5320 journalfile = dns_zone_getjournal(zone);
5321 if (journalfile != NULL) {
5322 dns_journal_t *journal = NULL;
5323 result = dns_journal_open(zone->mctx, journalfile,
5324 ISC_TRUE, &journal);
5325 if (result != ISC_R_SUCCESS) {
5326 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5327 "dns_journal_open -> %s",
5328 dns_result_totext(result));
5332 result = dns_journal_write_transaction(journal, &sig_diff);
5333 dns_journal_destroy(&journal);
5334 if (result != ISC_R_SUCCESS) {
5335 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5336 "dns_journal_write_transaction -> %s",
5337 dns_result_totext(result));
5343 zone_needdump(zone, DNS_DUMP_DELAY);
5344 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5349 * Pause all iterators so that dns_db_closeversion() can succeed.
5352 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5354 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5355 dns_dbiterator_pause(nsec3chain->dbiterator);
5359 * Everything has succeeded. Commit the changes.
5361 dns_db_closeversion(db, &version, ISC_TRUE);
5364 * Everything succeeded so we can clean these up now.
5366 nsec3chain = ISC_LIST_HEAD(cleanup);
5367 while (nsec3chain != NULL) {
5368 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5369 dns_db_detach(&nsec3chain->db);
5370 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5371 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5372 nsec3chain = ISC_LIST_HEAD(cleanup);
5375 set_resigntime(zone);
5379 * On error roll back the current nsec3chain.
5381 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
5382 if (nsec3chain->done) {
5383 dns_db_detach(&nsec3chain->db);
5384 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5385 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5387 result = dns_dbiterator_first(nsec3chain->dbiterator);
5388 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5389 dns_dbiterator_pause(nsec3chain->dbiterator);
5390 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5395 * Rollback the cleanup list.
5397 nsec3chain = ISC_LIST_TAIL(cleanup);
5398 while (nsec3chain != NULL) {
5399 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5400 if (nsec3chain->done) {
5401 dns_db_detach(&nsec3chain->db);
5402 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5403 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5406 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
5408 result = dns_dbiterator_first(nsec3chain->dbiterator);
5409 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5410 dns_dbiterator_pause(nsec3chain->dbiterator);
5411 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5413 nsec3chain = ISC_LIST_TAIL(cleanup);
5417 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5419 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5420 dns_dbiterator_pause(nsec3chain->dbiterator);
5423 dns_diff_clear(¶m_diff);
5424 dns_diff_clear(&nsec3_diff);
5425 dns_diff_clear(&nsec_diff);
5426 dns_diff_clear(&sig_diff);
5428 if (iterator != NULL)
5429 dns_rdatasetiter_destroy(&iterator);
5431 for (i = 0; i < nkeys; i++)
5432 dst_key_free(&zone_keys[i]);
5434 if (version != NULL) {
5435 dns_db_closeversion(db, &version, ISC_FALSE);
5437 } else if (db != NULL)
5441 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
5443 if (zone->update_disabled || result != ISC_R_SUCCESS)
5444 isc_interval_set(&i, 60, 0); /* 1 minute */
5446 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5447 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
5449 isc_time_settoepoch(&zone->nsec3chaintime);
5454 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5455 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
5456 isc_uint16_t keyid, dns_diff_t *diff)
5458 dns_rdata_rrsig_t rrsig;
5459 dns_rdataset_t rdataset;
5460 dns_rdatasetiter_t *iterator = NULL;
5461 isc_result_t result;
5463 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5464 if (result != ISC_R_SUCCESS) {
5465 if (result == ISC_R_NOTFOUND)
5466 result = ISC_R_SUCCESS;
5470 dns_rdataset_init(&rdataset);
5471 for (result = dns_rdatasetiter_first(iterator);
5472 result == ISC_R_SUCCESS;
5473 result = dns_rdatasetiter_next(iterator)) {
5474 dns_rdatasetiter_current(iterator, &rdataset);
5475 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
5476 for (result = dns_rdataset_first(&rdataset);
5477 result == ISC_R_SUCCESS;
5478 result = dns_rdataset_next(&rdataset)) {
5479 dns_rdata_t rdata = DNS_RDATA_INIT;
5480 dns_rdataset_current(&rdataset, &rdata);
5481 CHECK(update_one_rr(db, version, diff,
5482 DNS_DIFFOP_DEL, name,
5483 rdataset.ttl, &rdata));
5485 if (result != ISC_R_NOMORE)
5487 dns_rdataset_disassociate(&rdataset);
5490 if (rdataset.type != dns_rdatatype_rrsig) {
5491 dns_rdataset_disassociate(&rdataset);
5494 for (result = dns_rdataset_first(&rdataset);
5495 result == ISC_R_SUCCESS;
5496 result = dns_rdataset_next(&rdataset)) {
5497 dns_rdata_t rdata = DNS_RDATA_INIT;
5498 dns_rdataset_current(&rdataset, &rdata);
5499 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
5500 if (rrsig.algorithm != algorithm ||
5501 rrsig.keyid != keyid)
5503 CHECK(update_one_rr(db, version, diff,
5504 DNS_DIFFOP_DELRESIGN, name,
5505 rdataset.ttl, &rdata));
5507 dns_rdataset_disassociate(&rdataset);
5508 if (result != ISC_R_NOMORE)
5511 if (result == ISC_R_NOMORE)
5512 result = ISC_R_SUCCESS;
5514 if (dns_rdataset_isassociated(&rdataset))
5515 dns_rdataset_disassociate(&rdataset);
5516 dns_rdatasetiter_destroy(&iterator);
5521 * Incrementally sign the zone using the keys requested.
5522 * Builds the NSEC chain if required.
5525 zone_sign(dns_zone_t *zone) {
5526 const char *journalfile;
5527 dns_db_t *db = NULL;
5528 dns_dbnode_t *node = NULL;
5529 dns_dbversion_t *version = NULL;
5530 dns_diff_t sig_diff;
5531 dns_fixedname_t fixed;
5532 dns_fixedname_t nextfixed;
5533 dns_name_t *name, *nextname;
5534 dns_rdataset_t rdataset;
5535 dns_signing_t *signing, *nextsigning;
5536 dns_signinglist_t cleanup;
5537 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
5538 isc_int32_t signatures;
5539 isc_boolean_t check_ksk, is_ksk;
5540 isc_boolean_t commit = ISC_FALSE;
5541 isc_boolean_t delegation;
5542 isc_boolean_t finishedakey = ISC_FALSE;
5543 isc_boolean_t secureupdated = ISC_FALSE;
5544 isc_boolean_t build_nsec3 = ISC_FALSE, build_nsec = ISC_FALSE;
5545 isc_boolean_t first;
5546 isc_result_t result;
5547 isc_stdtime_t now, inception, soaexpire, expire;
5548 isc_uint32_t jitter;
5550 unsigned int nkeys = 0;
5553 dns_rdataset_init(&rdataset);
5554 dns_fixedname_init(&fixed);
5555 name = dns_fixedname_name(&fixed);
5556 dns_fixedname_init(&nextfixed);
5557 nextname = dns_fixedname_name(&nextfixed);
5558 dns_diff_init(zone->mctx, &sig_diff);
5559 sig_diff.resign = zone->sigresigninginterval;
5560 ISC_LIST_INIT(cleanup);
5563 * Updates are disabled. Pause for 5 minutes.
5565 if (zone->update_disabled) {
5566 result = ISC_R_FAILURE;
5570 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5571 dns_db_attach(zone->db, &db);
5572 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5574 result = dns_db_newversion(db, &version);
5575 if (result != ISC_R_SUCCESS) {
5576 dns_zone_log(zone, ISC_LOG_ERROR,
5577 "zone_sign:dns_db_newversion -> %s",
5578 dns_result_totext(result));
5582 result = find_zone_keys(zone, db, version, zone->mctx,
5583 DNS_MAXZONEKEYS, zone_keys, &nkeys);
5584 if (result != ISC_R_SUCCESS) {
5585 dns_zone_log(zone, ISC_LOG_ERROR,
5586 "zone_sign:find_zone_keys -> %s",
5587 dns_result_totext(result));
5591 isc_stdtime_get(&now);
5592 inception = now - 3600; /* Allow for clock skew. */
5593 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5596 * Spread out signatures over time if they happen to be
5597 * clumped. We don't do this for each add_sigs() call as
5598 * we still want some clustering to occur.
5600 isc_random_get(&jitter);
5601 expire = soaexpire - jitter % 3600;
5603 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5605 check_ksk = ksk_sanity(db, version);
5608 * We keep pulling nodes off each iterator in turn until
5609 * we have no more nodes to pull off or we reach the limits
5612 nodes = zone->nodes;
5613 signatures = zone->signatures;
5614 signing = ISC_LIST_HEAD(zone->signing);
5617 * See if we have a NSEC chain.
5619 result = dns_db_getoriginnode(db, &node);
5620 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5621 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
5622 dns_rdatatype_none, 0, &rdataset, NULL);
5623 dns_db_detachnode(db, &node);
5624 if (result == ISC_R_SUCCESS) {
5625 build_nsec = ISC_TRUE;
5626 dns_rdataset_disassociate(&rdataset);
5627 } else if (result != ISC_R_NOTFOUND) {
5631 * No NSEC chain present.
5632 * See if we need to build a NSEC3 chain?
5634 result = dns_nsec3_active(db, version, ISC_TRUE, &build_nsec3);
5635 if (result == ISC_R_SUCCESS) {
5637 build_nsec3 = ISC_FALSE;
5639 result = dns_nsec3_active(db, version,
5643 secureupdated = ISC_TRUE;
5645 build_nsec = ISC_TRUE;
5650 while (signing != NULL && nodes-- > 0 && signatures > 0) {
5651 nextsigning = ISC_LIST_NEXT(signing, link);
5653 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5654 if (signing->done || signing->db != zone->db) {
5656 * The zone has been reloaded. We will have
5657 * created new signings as part of the reload
5658 * process so we can destroy this one.
5660 ISC_LIST_UNLINK(zone->signing, signing, link);
5661 ISC_LIST_APPEND(cleanup, signing, link);
5662 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5665 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5667 if (signing->db != db)
5671 delegation = ISC_FALSE;
5673 dns_dbiterator_current(signing->dbiterator, &node, name);
5675 if (signing->delete) {
5676 dns_dbiterator_pause(signing->dbiterator);
5677 CHECK(del_sig(db, version, name, node, nkeys,
5678 signing->algorithm, signing->keyid,
5683 * On the first pass we need to check if the current node
5684 * has not been obscured.
5687 dns_fixedname_t ffound;
5689 dns_fixedname_init(&ffound);
5690 found = dns_fixedname_name(&ffound);
5691 result = dns_db_find(db, name, version,
5693 DNS_DBFIND_NOWILD, 0, NULL, found,
5695 if ((result == DNS_R_DELEGATION ||
5696 result == DNS_R_DNAME) &&
5697 !dns_name_equal(name, found)) {
5699 * Remember the obscuring name so that
5700 * we skip all obscured names.
5702 dns_name_copy(found, name, NULL);
5703 delegation = ISC_TRUE;
5711 dns_dbiterator_pause(signing->dbiterator);
5712 for (i = 0; i < nkeys; i++) {
5714 * Find the key we want to sign with.
5716 if (dst_key_alg(zone_keys[i]) != signing->algorithm ||
5717 dst_key_id(zone_keys[i]) != signing->keyid ||
5718 !dst_key_isprivate(zone_keys[i]))
5721 * Do we do KSK processing?
5724 (dst_key_flags(zone_keys[i]) & DNS_KEYFLAG_KSK) != 0)
5726 CHECK(sign_a_node(db, name, node, version, build_nsec3,
5727 build_nsec, zone_keys[i], inception,
5728 expire, zone->minimum, is_ksk,
5729 &delegation, &sig_diff, &signatures,
5734 * Go onto next node.
5738 dns_db_detachnode(db, &node);
5740 result = dns_dbiterator_next(signing->dbiterator);
5741 if (result == ISC_R_NOMORE) {
5742 ISC_LIST_UNLINK(zone->signing, signing, link);
5743 ISC_LIST_APPEND(cleanup, signing, link);
5744 dns_dbiterator_pause(signing->dbiterator);
5745 finishedakey = ISC_TRUE;
5746 if (!is_ksk && !secureupdated && nkeys != 0 &&
5749 * We have finished regenerating the
5750 * zone with a zone signing key.
5751 * The NSEC chain is now complete and
5752 * there is a full set of signatures
5753 * for the zone. We can now clear the
5754 * OPT bit from the NSEC record.
5756 result = updatesecure(db, version,
5761 if (result != ISC_R_SUCCESS) {
5764 "updatesecure -> %s",
5765 dns_result_totext(result));
5769 result = updatesignwithkey(signing, version,
5773 if (result != ISC_R_SUCCESS) {
5774 dns_zone_log(zone, ISC_LOG_ERROR,
5775 "updatesignwithkey -> %s",
5776 dns_result_totext(result));
5780 } else if (result != ISC_R_SUCCESS) {
5781 dns_zone_log(zone, ISC_LOG_ERROR,
5782 "zone_sign:dns_dbiterator_next -> %s",
5783 dns_result_totext(result));
5785 } else if (delegation) {
5786 dns_dbiterator_current(signing->dbiterator,
5788 dns_db_detachnode(db, &node);
5789 if (!dns_name_issubdomain(nextname, name))
5797 dns_dbiterator_pause(signing->dbiterator);
5798 signing = nextsigning;
5802 if (secureupdated) {
5804 * We have changed the NSEC RRset above so we need to update
5807 result = del_sigs(zone, db, version, &zone->origin,
5808 dns_rdatatype_nsec, &sig_diff, zone_keys,
5810 if (result != ISC_R_SUCCESS) {
5811 dns_zone_log(zone, ISC_LOG_ERROR,
5812 "zone_sign:del_sigs -> %s",
5813 dns_result_totext(result));
5816 result = add_sigs(db, version, &zone->origin,
5817 dns_rdatatype_nsec, &sig_diff, zone_keys,
5818 nkeys, zone->mctx, inception, soaexpire,
5820 if (result != ISC_R_SUCCESS) {
5821 dns_zone_log(zone, ISC_LOG_ERROR,
5822 "zone_sign:add_sigs -> %s",
5823 dns_result_totext(result));
5830 * We have changed the RRset above so we need to update
5833 result = del_sigs(zone, db, version, &zone->origin,
5834 zone->privatetype, &sig_diff,
5835 zone_keys, nkeys, now);
5836 if (result != ISC_R_SUCCESS) {
5837 dns_zone_log(zone, ISC_LOG_ERROR,
5838 "zone_sign:del_sigs -> %s",
5839 dns_result_totext(result));
5842 result = add_sigs(db, version, &zone->origin,
5843 zone->privatetype, &sig_diff,
5844 zone_keys, nkeys, zone->mctx, inception,
5845 soaexpire, check_ksk);
5846 if (result != ISC_R_SUCCESS) {
5847 dns_zone_log(zone, ISC_LOG_ERROR,
5848 "zone_sign:add_sigs -> %s",
5849 dns_result_totext(result));
5855 * Have we changed anything?
5857 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5862 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5863 &sig_diff, zone_keys, nkeys, now);
5864 if (result != ISC_R_SUCCESS) {
5865 dns_zone_log(zone, ISC_LOG_ERROR,
5866 "zone_sign:del_sigs -> %s",
5867 dns_result_totext(result));
5871 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5872 if (result != ISC_R_SUCCESS) {
5873 dns_zone_log(zone, ISC_LOG_ERROR,
5874 "zone_sign:increment_soa_serial -> %s",
5875 dns_result_totext(result));
5880 * Generate maximum life time signatures so that the above loop
5881 * termination is sensible.
5883 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5884 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5885 soaexpire, check_ksk);
5886 if (result != ISC_R_SUCCESS) {
5887 dns_zone_log(zone, ISC_LOG_ERROR,
5888 "zone_sign:add_sigs -> %s",
5889 dns_result_totext(result));
5894 * Write changes to journal file.
5896 journalfile = dns_zone_getjournal(zone);
5897 if (journalfile != NULL) {
5898 dns_journal_t *journal = NULL;
5899 result = dns_journal_open(zone->mctx, journalfile,
5900 ISC_TRUE, &journal);
5901 if (result != ISC_R_SUCCESS) {
5902 dns_zone_log(zone, ISC_LOG_ERROR,
5903 "zone_sign:dns_journal_open -> %s",
5904 dns_result_totext(result));
5908 result = dns_journal_write_transaction(journal, &sig_diff);
5909 dns_journal_destroy(&journal);
5910 if (result != ISC_R_SUCCESS) {
5911 dns_zone_log(zone, ISC_LOG_ERROR,
5912 "zone_sign:dns_journal_write_transaction -> %s",
5913 dns_result_totext(result));
5920 * Pause all iterators so that dns_db_closeversion() can succeed.
5922 for (signing = ISC_LIST_HEAD(zone->signing);
5924 signing = ISC_LIST_NEXT(signing, link))
5925 dns_dbiterator_pause(signing->dbiterator);
5927 for (signing = ISC_LIST_HEAD(cleanup);
5929 signing = ISC_LIST_NEXT(signing, link))
5930 dns_dbiterator_pause(signing->dbiterator);
5933 * Everything has succeeded. Commit the changes.
5935 dns_db_closeversion(db, &version, commit);
5938 * Everything succeeded so we can clean these up now.
5940 signing = ISC_LIST_HEAD(cleanup);
5941 while (signing != NULL) {
5942 ISC_LIST_UNLINK(cleanup, signing, link);
5943 dns_db_detach(&signing->db);
5944 dns_dbiterator_destroy(&signing->dbiterator);
5945 isc_mem_put(zone->mctx, signing, sizeof *signing);
5946 signing = ISC_LIST_HEAD(cleanup);
5949 set_resigntime(zone);
5953 zone_needdump(zone, DNS_DUMP_DELAY);
5959 * Rollback the cleanup list.
5961 signing = ISC_LIST_HEAD(cleanup);
5962 while (signing != NULL) {
5963 ISC_LIST_UNLINK(cleanup, signing, link);
5964 ISC_LIST_APPEND(zone->signing, signing, link);
5965 dns_dbiterator_first(signing->dbiterator);
5966 dns_dbiterator_pause(signing->dbiterator);
5967 signing = ISC_LIST_HEAD(cleanup);
5970 for (signing = ISC_LIST_HEAD(zone->signing);
5972 signing = ISC_LIST_NEXT(signing, link))
5973 dns_dbiterator_pause(signing->dbiterator);
5975 dns_diff_clear(&sig_diff);
5977 for (i = 0; i < nkeys; i++)
5978 dst_key_free(&zone_keys[i]);
5980 if (version != NULL) {
5981 dns_db_closeversion(db, &version, ISC_FALSE);
5983 } else if (db != NULL)
5986 if (ISC_LIST_HEAD(zone->signing) != NULL) {
5988 if (zone->update_disabled || result != ISC_R_SUCCESS)
5989 isc_interval_set(&i, 60, 0); /* 1 minute */
5991 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5992 isc_time_nowplusinterval(&zone->signingtime, &i);
5994 isc_time_settoepoch(&zone->signingtime);
5998 zone_maintenance(dns_zone_t *zone) {
5999 const char me[] = "zone_maintenance";
6001 isc_result_t result;
6002 isc_boolean_t dumping;
6004 REQUIRE(DNS_ZONE_VALID(zone));
6008 * Configuring the view of this zone may have
6009 * failed, for example because the config file
6010 * had a syntax error. In that case, the view
6011 * db or resolver will be NULL, and we had better not try
6012 * to do maintenance on it.
6014 if (zone->view == NULL || zone->view->adb == NULL)
6022 switch (zone->type) {
6023 case dns_zone_slave:
6026 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
6027 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6029 zone->refreshtime = now;
6040 switch (zone->type) {
6041 case dns_zone_slave:
6043 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
6044 isc_time_compare(&now, &zone->refreshtime) >= 0)
6045 dns_zone_refresh(zone);
6052 * Do we need to consolidate the backing store?
6054 switch (zone->type) {
6055 case dns_zone_master:
6056 case dns_zone_slave:
6059 if (zone->masterfile != NULL &&
6060 isc_time_compare(&now, &zone->dumptime) >= 0 &&
6061 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
6062 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
6063 dumping = was_dumping(zone);
6068 result = zone_dump(zone, ISC_TRUE); /* task locked */
6069 if (result != ISC_R_SUCCESS)
6070 dns_zone_log(zone, ISC_LOG_WARNING,
6072 dns_result_totext(result));
6079 switch (zone->type) {
6080 case dns_zone_master:
6081 case dns_zone_slave:
6083 * Do we need to send out notify messages?
6085 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
6086 isc_time_compare(&now, &zone->notifytime) >= 0)
6087 zone_notify(zone, &now);
6089 * Do we need to sign/resign some RRsets?
6091 if (!isc_time_isepoch(&zone->signingtime) &&
6092 isc_time_compare(&now, &zone->signingtime) >= 0)
6094 else if (!isc_time_isepoch(&zone->resigntime) &&
6095 isc_time_compare(&now, &zone->resigntime) >= 0)
6096 zone_resigninc(zone);
6097 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
6098 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
6099 zone_nsec3chain(zone);
6101 * Do we need to issue a key expiry warning.
6103 if (!isc_time_isepoch(&zone->keywarntime) &&
6104 isc_time_compare(&now, &zone->keywarntime) >= 0)
6105 set_key_expiry_warning(zone, zone->key_expiry,
6106 isc_time_seconds(&now));
6111 zone_settimer(zone, &now);
6115 dns_zone_markdirty(dns_zone_t *zone) {
6118 if (zone->type == dns_zone_master)
6119 set_resigntime(zone); /* XXXMPA make separate call back */
6120 zone_needdump(zone, DNS_DUMP_DELAY);
6125 dns_zone_expire(dns_zone_t *zone) {
6126 REQUIRE(DNS_ZONE_VALID(zone));
6134 zone_expire(dns_zone_t *zone) {
6136 * 'zone' locked by caller.
6139 REQUIRE(LOCKED_ZONE(zone));
6141 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
6143 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
6144 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
6145 zone->retry = DNS_ZONE_DEFAULTRETRY;
6146 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6151 dns_zone_refresh(dns_zone_t *zone) {
6153 isc_uint32_t oldflags;
6155 isc_result_t result;
6157 REQUIRE(DNS_ZONE_VALID(zone));
6159 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
6163 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
6164 * in progress at a time.
6168 oldflags = zone->flags;
6169 if (zone->masterscnt == 0) {
6170 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
6171 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
6172 dns_zone_log(zone, ISC_LOG_ERROR,
6173 "cannot refresh: no masters");
6176 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6177 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
6178 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6179 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
6183 * Set the next refresh time as if refresh check has failed.
6184 * Setting this to the retry time will do that. XXXMLG
6185 * If we are successful it will be reset using zone->refresh.
6187 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
6189 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
6190 if (result != ISC_R_SUCCESS)
6191 dns_zone_log(zone, ISC_LOG_WARNING,
6192 "isc_time_nowplusinterval() failed: %s",
6193 dns_result_totext(result));
6196 * When lacking user-specified timer values from the SOA,
6197 * do exponential backoff of the retry time up to a
6198 * maximum of six hours.
6200 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
6201 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
6203 zone->curmaster = 0;
6204 for (j = 0; j < zone->masterscnt; j++)
6205 zone->mastersok[j] = ISC_FALSE;
6206 /* initiate soa query */
6207 queue_soa_query(zone);
6213 dns_zone_flush(dns_zone_t *zone) {
6214 isc_result_t result = ISC_R_SUCCESS;
6215 isc_boolean_t dumping;
6217 REQUIRE(DNS_ZONE_VALID(zone));
6220 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
6221 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6222 zone->masterfile != NULL) {
6223 result = ISC_R_ALREADYRUNNING;
6224 dumping = was_dumping(zone);
6229 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6234 dns_zone_dump(dns_zone_t *zone) {
6235 isc_result_t result = ISC_R_ALREADYRUNNING;
6236 isc_boolean_t dumping;
6238 REQUIRE(DNS_ZONE_VALID(zone));
6241 dumping = was_dumping(zone);
6244 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6249 zone_needdump(dns_zone_t *zone, unsigned int delay) {
6250 isc_time_t dumptime;
6254 * 'zone' locked by caller
6257 REQUIRE(DNS_ZONE_VALID(zone));
6258 REQUIRE(LOCKED_ZONE(zone));
6261 * Do we have a place to dump to and are we loaded?
6263 if (zone->masterfile == NULL ||
6264 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
6268 /* add some noise */
6269 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
6271 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6272 if (isc_time_isepoch(&zone->dumptime) ||
6273 isc_time_compare(&zone->dumptime, &dumptime) > 0)
6274 zone->dumptime = dumptime;
6275 if (zone->task != NULL)
6276 zone_settimer(zone, &now);
6280 dump_done(void *arg, isc_result_t result) {
6281 const char me[] = "dump_done";
6282 dns_zone_t *zone = arg;
6284 dns_dbversion_t *version;
6285 isc_boolean_t again = ISC_FALSE;
6286 isc_boolean_t compact = ISC_FALSE;
6287 isc_uint32_t serial;
6288 isc_result_t tresult;
6290 REQUIRE(DNS_ZONE_VALID(zone));
6294 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
6295 zone->journalsize != -1) {
6298 * We don't own these, zone->dctx must stay valid.
6300 db = dns_dumpctx_db(zone->dctx);
6301 version = dns_dumpctx_version(zone->dctx);
6303 tresult = dns_db_getsoaserial(db, version, &serial);
6305 * Note: we are task locked here so we can test
6308 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
6309 tresult = dns_journal_compact(zone->mctx,
6316 case ISC_R_NOTFOUND:
6317 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6318 "dns_journal_compact: %s",
6319 dns_result_totext(tresult));
6322 dns_zone_log(zone, ISC_LOG_ERROR,
6323 "dns_journal_compact failed: %s",
6324 dns_result_totext(tresult));
6327 } else if (tresult == ISC_R_SUCCESS) {
6329 zone->compact_serial = serial;
6334 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6336 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
6337 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
6339 * Try again in a short while.
6341 zone_needdump(zone, DNS_DUMP_DELAY);
6342 } else if (result == ISC_R_SUCCESS &&
6343 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6344 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6345 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6346 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6347 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6348 isc_time_settoepoch(&zone->dumptime);
6350 } else if (result == ISC_R_SUCCESS)
6351 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6353 if (zone->dctx != NULL)
6354 dns_dumpctx_detach(&zone->dctx);
6355 zonemgr_putio(&zone->writeio);
6358 (void)zone_dump(zone, ISC_FALSE);
6359 dns_zone_idetach(&zone);
6363 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
6364 const char me[] = "zone_dump";
6365 isc_result_t result;
6366 dns_dbversion_t *version = NULL;
6367 isc_boolean_t again;
6368 dns_db_t *db = NULL;
6369 char *masterfile = NULL;
6370 dns_masterformat_t masterformat = dns_masterformat_none;
6373 * 'compact' MUST only be set if we are task locked.
6376 REQUIRE(DNS_ZONE_VALID(zone));
6380 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6381 if (zone->db != NULL)
6382 dns_db_attach(zone->db, &db);
6383 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6385 if (zone->masterfile != NULL) {
6386 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
6387 masterformat = zone->masterformat;
6391 result = DNS_R_NOTLOADED;
6394 if (masterfile == NULL) {
6395 result = DNS_R_NOMASTERFILE;
6399 if (compact && zone->type != dns_zone_stub) {
6400 dns_zone_t *dummy = NULL;
6402 zone_iattach(zone, &dummy);
6403 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
6404 zone_gotwritehandle, zone,
6406 if (result != ISC_R_SUCCESS)
6407 zone_idetach(&dummy);
6409 result = DNS_R_CONTINUE;
6412 dns_db_currentversion(db, &version);
6413 result = dns_master_dump2(zone->mctx, db, version,
6414 &dns_master_style_default,
6415 masterfile, masterformat);
6416 dns_db_closeversion(db, &version, ISC_FALSE);
6421 if (masterfile != NULL)
6422 isc_mem_free(zone->mctx, masterfile);
6425 if (result == DNS_R_CONTINUE)
6426 return (ISC_R_SUCCESS); /* XXXMPA */
6430 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6431 if (result != ISC_R_SUCCESS) {
6433 * Try again in a short while.
6435 zone_needdump(zone, DNS_DUMP_DELAY);
6436 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6437 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6438 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6439 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6440 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6441 isc_time_settoepoch(&zone->dumptime);
6444 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6453 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
6454 dns_masterformat_t format)
6456 isc_result_t result;
6457 dns_dbversion_t *version = NULL;
6458 dns_db_t *db = NULL;
6460 REQUIRE(DNS_ZONE_VALID(zone));
6462 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6463 if (zone->db != NULL)
6464 dns_db_attach(zone->db, &db);
6465 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6467 return (DNS_R_NOTLOADED);
6469 dns_db_currentversion(db, &version);
6470 result = dns_master_dumptostream2(zone->mctx, db, version, style,
6472 dns_db_closeversion(db, &version, ISC_FALSE);
6478 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
6479 const dns_master_style_t *style) {
6480 return dumptostream(zone, fd, style, format);
6484 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
6485 return dumptostream(zone, fd, &dns_master_style_default,
6486 dns_masterformat_text);
6490 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
6491 return dumptostream(zone, fd, &dns_master_style_full,
6492 dns_masterformat_text);
6496 dns_zone_unload(dns_zone_t *zone) {
6497 REQUIRE(DNS_ZONE_VALID(zone));
6505 notify_cancel(dns_zone_t *zone) {
6506 dns_notify_t *notify;
6509 * 'zone' locked by caller.
6512 REQUIRE(LOCKED_ZONE(zone));
6514 for (notify = ISC_LIST_HEAD(zone->notifies);
6516 notify = ISC_LIST_NEXT(notify, link)) {
6517 if (notify->find != NULL)
6518 dns_adb_cancelfind(notify->find);
6519 if (notify->request != NULL)
6520 dns_request_cancel(notify->request);
6525 forward_cancel(dns_zone_t *zone) {
6526 dns_forward_t *forward;
6529 * 'zone' locked by caller.
6532 REQUIRE(LOCKED_ZONE(zone));
6534 for (forward = ISC_LIST_HEAD(zone->forwards);
6536 forward = ISC_LIST_NEXT(forward, link)) {
6537 if (forward->request != NULL)
6538 dns_request_cancel(forward->request);
6543 zone_unload(dns_zone_t *zone) {
6546 * 'zone' locked by caller.
6549 REQUIRE(LOCKED_ZONE(zone));
6551 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
6552 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
6553 if (zone->writeio != NULL)
6554 zonemgr_cancelio(zone->writeio);
6556 if (zone->dctx != NULL)
6557 dns_dumpctx_cancel(zone->dctx);
6559 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6560 zone_detachdb(zone);
6561 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6562 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
6563 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6567 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6568 REQUIRE(DNS_ZONE_VALID(zone));
6571 zone->minrefresh = val;
6575 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6576 REQUIRE(DNS_ZONE_VALID(zone));
6579 zone->maxrefresh = val;
6583 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
6584 REQUIRE(DNS_ZONE_VALID(zone));
6587 zone->minretry = val;
6591 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
6592 REQUIRE(DNS_ZONE_VALID(zone));
6595 zone->maxretry = val;
6598 static isc_boolean_t
6599 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
6600 dns_notify_t *notify;
6602 for (notify = ISC_LIST_HEAD(zone->notifies);
6604 notify = ISC_LIST_NEXT(notify, link)) {
6605 if (notify->request != NULL)
6607 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
6608 dns_name_equal(name, ¬ify->ns))
6610 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
6616 static isc_boolean_t
6617 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
6618 dns_tsigkey_t *key = NULL;
6621 isc_boolean_t isself;
6622 isc_netaddr_t dstaddr;
6623 isc_result_t result;
6625 if (zone->view == NULL || zone->isself == NULL)
6628 switch (isc_sockaddr_pf(dst)) {
6630 src = zone->notifysrc4;
6631 isc_sockaddr_any(&any);
6634 src = zone->notifysrc6;
6635 isc_sockaddr_any6(&any);
6642 * When sending from any the kernel will assign a source address
6643 * that matches the destination address.
6645 if (isc_sockaddr_eqaddr(&any, &src))
6648 isc_netaddr_fromsockaddr(&dstaddr, dst);
6649 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
6650 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
6652 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
6655 dns_tsigkey_detach(&key);
6660 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
6664 * Caller holds zone lock.
6666 REQUIRE(DNS_NOTIFY_VALID(notify));
6668 if (notify->zone != NULL) {
6670 LOCK_ZONE(notify->zone);
6671 REQUIRE(LOCKED_ZONE(notify->zone));
6672 if (ISC_LINK_LINKED(notify, link))
6673 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
6675 UNLOCK_ZONE(notify->zone);
6677 zone_idetach(¬ify->zone);
6679 dns_zone_idetach(¬ify->zone);
6681 if (notify->find != NULL)
6682 dns_adb_destroyfind(¬ify->find);
6683 if (notify->request != NULL)
6684 dns_request_destroy(¬ify->request);
6685 if (dns_name_dynamic(¬ify->ns))
6686 dns_name_free(¬ify->ns, notify->mctx);
6687 mctx = notify->mctx;
6688 isc_mem_put(notify->mctx, notify, sizeof(*notify));
6689 isc_mem_detach(&mctx);
6693 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
6694 dns_notify_t *notify;
6696 REQUIRE(notifyp != NULL && *notifyp == NULL);
6698 notify = isc_mem_get(mctx, sizeof(*notify));
6700 return (ISC_R_NOMEMORY);
6702 notify->mctx = NULL;
6703 isc_mem_attach(mctx, ¬ify->mctx);
6704 notify->flags = flags;
6705 notify->zone = NULL;
6706 notify->find = NULL;
6707 notify->request = NULL;
6708 isc_sockaddr_any(¬ify->dst);
6709 dns_name_init(¬ify->ns, NULL);
6710 ISC_LINK_INIT(notify, link);
6711 notify->magic = NOTIFY_MAGIC;
6713 return (ISC_R_SUCCESS);
6717 * XXXAG should check for DNS_ZONEFLG_EXITING
6720 process_adb_event(isc_task_t *task, isc_event_t *ev) {
6721 dns_notify_t *notify;
6722 isc_eventtype_t result;
6726 notify = ev->ev_arg;
6727 REQUIRE(DNS_NOTIFY_VALID(notify));
6728 INSIST(task == notify->zone->task);
6729 result = ev->ev_type;
6730 isc_event_free(&ev);
6731 if (result == DNS_EVENT_ADBMOREADDRESSES) {
6732 dns_adb_destroyfind(¬ify->find);
6733 notify_find_address(notify);
6736 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
6737 LOCK_ZONE(notify->zone);
6738 notify_send(notify);
6739 UNLOCK_ZONE(notify->zone);
6741 notify_destroy(notify, ISC_FALSE);
6745 notify_find_address(dns_notify_t *notify) {
6746 isc_result_t result;
6747 unsigned int options;
6749 REQUIRE(DNS_NOTIFY_VALID(notify));
6750 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
6751 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
6753 if (notify->zone->view->adb == NULL)
6756 result = dns_adb_createfind(notify->zone->view->adb,
6758 process_adb_event, notify,
6759 ¬ify->ns, dns_rootname, 0,
6761 notify->zone->view->dstport,
6764 /* Something failed? */
6765 if (result != ISC_R_SUCCESS)
6768 /* More addresses pending? */
6769 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
6772 /* We have as many addresses as we can get. */
6773 LOCK_ZONE(notify->zone);
6774 notify_send(notify);
6775 UNLOCK_ZONE(notify->zone);
6778 notify_destroy(notify, ISC_FALSE);
6783 notify_send_queue(dns_notify_t *notify) {
6785 isc_result_t result;
6787 e = isc_event_allocate(notify->mctx, NULL,
6788 DNS_EVENT_NOTIFYSENDTOADDR,
6790 notify, sizeof(isc_event_t));
6792 return (ISC_R_NOMEMORY);
6794 e->ev_sender = NULL;
6795 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
6796 notify->zone->task, &e);
6797 if (result != ISC_R_SUCCESS)
6803 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
6804 dns_notify_t *notify;
6805 isc_result_t result;
6806 dns_message_t *message = NULL;
6807 isc_netaddr_t dstip;
6808 dns_tsigkey_t *key = NULL;
6809 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6812 isc_boolean_t have_notifysource = ISC_FALSE;
6814 notify = event->ev_arg;
6815 REQUIRE(DNS_NOTIFY_VALID(notify));
6819 LOCK_ZONE(notify->zone);
6821 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
6822 result = ISC_R_CANCELED;
6826 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
6827 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
6828 notify->zone->view->requestmgr == NULL ||
6829 notify->zone->db == NULL) {
6830 result = ISC_R_CANCELED;
6835 * The raw IPv4 address should also exist. Don't send to the
6838 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
6839 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
6840 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6841 notify_log(notify->zone, ISC_LOG_DEBUG(3),
6842 "notify: ignoring IPv6 mapped IPV4 address: %s",
6844 result = ISC_R_CANCELED;
6848 result = notify_createmessage(notify->zone, notify->flags, &message);
6849 if (result != ISC_R_SUCCESS)
6852 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
6853 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6854 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
6855 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6856 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
6857 "sent. Peer TSIG key lookup failure.", addrbuf);
6858 goto cleanup_message;
6861 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
6863 if (notify->zone->view->peers != NULL) {
6864 dns_peer_t *peer = NULL;
6865 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
6867 if (result == ISC_R_SUCCESS) {
6868 result = dns_peer_getnotifysource(peer, &src);
6869 if (result == ISC_R_SUCCESS)
6870 have_notifysource = ISC_TRUE;
6873 switch (isc_sockaddr_pf(¬ify->dst)) {
6875 if (!have_notifysource)
6876 src = notify->zone->notifysrc4;
6879 if (!have_notifysource)
6880 src = notify->zone->notifysrc6;
6883 result = ISC_R_NOTIMPLEMENTED;
6887 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
6889 result = dns_request_createvia2(notify->zone->view->requestmgr,
6890 message, &src, ¬ify->dst, 0, key,
6891 timeout * 3, timeout,
6892 notify->zone->task, notify_done,
6893 notify, ¬ify->request);
6894 if (result == ISC_R_SUCCESS) {
6895 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
6896 inc_stats(notify->zone,
6897 dns_zonestatscounter_notifyoutv4);
6899 inc_stats(notify->zone,
6900 dns_zonestatscounter_notifyoutv6);
6906 dns_tsigkey_detach(&key);
6908 dns_message_destroy(&message);
6910 UNLOCK_ZONE(notify->zone);
6911 if (result != ISC_R_SUCCESS)
6912 notify_destroy(notify, ISC_FALSE);
6913 isc_event_free(&event);
6917 notify_send(dns_notify_t *notify) {
6918 dns_adbaddrinfo_t *ai;
6920 isc_result_t result;
6921 dns_notify_t *new = NULL;
6924 * Zone lock held by caller.
6926 REQUIRE(DNS_NOTIFY_VALID(notify));
6927 REQUIRE(LOCKED_ZONE(notify->zone));
6929 for (ai = ISC_LIST_HEAD(notify->find->list);
6931 ai = ISC_LIST_NEXT(ai, publink)) {
6933 if (notify_isqueued(notify->zone, NULL, &dst))
6935 if (notify_isself(notify->zone, &dst))
6938 result = notify_create(notify->mctx,
6939 (notify->flags & DNS_NOTIFY_NOSOA),
6941 if (result != ISC_R_SUCCESS)
6943 zone_iattach(notify->zone, &new->zone);
6944 ISC_LIST_APPEND(new->zone->notifies, new, link);
6946 result = notify_send_queue(new);
6947 if (result != ISC_R_SUCCESS)
6954 notify_destroy(new, ISC_TRUE);
6958 dns_zone_notify(dns_zone_t *zone) {
6961 REQUIRE(DNS_ZONE_VALID(zone));
6964 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6967 zone_settimer(zone, &now);
6972 zone_notify(dns_zone_t *zone, isc_time_t *now) {
6973 dns_dbnode_t *node = NULL;
6974 dns_db_t *zonedb = NULL;
6975 dns_dbversion_t *version = NULL;
6976 dns_name_t *origin = NULL;
6979 dns_rdata_soa_t soa;
6980 isc_uint32_t serial;
6981 dns_rdata_t rdata = DNS_RDATA_INIT;
6982 dns_rdataset_t nsrdset;
6983 dns_rdataset_t soardset;
6984 isc_result_t result;
6985 dns_notify_t *notify = NULL;
6988 isc_boolean_t isqueued;
6989 dns_notifytype_t notifytype;
6990 unsigned int flags = 0;
6991 isc_boolean_t loggednotify = ISC_FALSE;
6993 REQUIRE(DNS_ZONE_VALID(zone));
6996 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6997 notifytype = zone->notifytype;
6998 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
7001 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
7004 if (notifytype == dns_notifytype_no)
7007 if (notifytype == dns_notifytype_masteronly &&
7008 zone->type != dns_zone_master)
7011 origin = &zone->origin;
7014 * If the zone is dialup we are done as we don't want to send
7015 * the current soa so as to force a refresh query.
7017 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
7018 flags |= DNS_NOTIFY_NOSOA;
7023 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7024 if (zone->db != NULL)
7025 dns_db_attach(zone->db, &zonedb);
7026 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7029 dns_db_currentversion(zonedb, &version);
7030 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
7031 if (result != ISC_R_SUCCESS)
7034 dns_rdataset_init(&soardset);
7035 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
7036 dns_rdatatype_none, 0, &soardset, NULL);
7037 if (result != ISC_R_SUCCESS)
7041 * Find serial and master server's name.
7043 dns_name_init(&master, NULL);
7044 result = dns_rdataset_first(&soardset);
7045 if (result != ISC_R_SUCCESS)
7047 dns_rdataset_current(&soardset, &rdata);
7048 result = dns_rdata_tostruct(&rdata, &soa, NULL);
7049 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7050 dns_rdata_reset(&rdata);
7051 result = dns_name_dup(&soa.origin, zone->mctx, &master);
7052 serial = soa.serial;
7053 dns_rdataset_disassociate(&soardset);
7054 if (result != ISC_R_SUCCESS)
7058 * Enqueue notify requests for 'also-notify' servers.
7061 for (i = 0; i < zone->notifycnt; i++) {
7062 dst = zone->notify[i];
7063 if (notify_isqueued(zone, NULL, &dst))
7065 result = notify_create(zone->mctx, flags, ¬ify);
7066 if (result != ISC_R_SUCCESS)
7068 zone_iattach(zone, ¬ify->zone);
7070 ISC_LIST_APPEND(zone->notifies, notify, link);
7071 result = notify_send_queue(notify);
7072 if (result != ISC_R_SUCCESS)
7073 notify_destroy(notify, ISC_TRUE);
7074 if (!loggednotify) {
7075 notify_log(zone, ISC_LOG_INFO,
7076 "sending notifies (serial %u)",
7078 loggednotify = ISC_TRUE;
7084 if (notifytype == dns_notifytype_explicit)
7088 * Process NS RRset to generate notifies.
7091 dns_rdataset_init(&nsrdset);
7092 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
7093 dns_rdatatype_none, 0, &nsrdset, NULL);
7094 if (result != ISC_R_SUCCESS)
7097 result = dns_rdataset_first(&nsrdset);
7098 while (result == ISC_R_SUCCESS) {
7099 dns_rdataset_current(&nsrdset, &rdata);
7100 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7101 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7102 dns_rdata_reset(&rdata);
7104 * Don't notify the master server unless explicitly
7105 * configured to do so.
7107 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
7108 dns_name_compare(&master, &ns.name) == 0) {
7109 result = dns_rdataset_next(&nsrdset);
7113 if (!loggednotify) {
7114 notify_log(zone, ISC_LOG_INFO,
7115 "sending notifies (serial %u)",
7117 loggednotify = ISC_TRUE;
7121 isqueued = notify_isqueued(zone, &ns.name, NULL);
7124 result = dns_rdataset_next(&nsrdset);
7127 result = notify_create(zone->mctx, flags, ¬ify);
7128 if (result != ISC_R_SUCCESS)
7130 dns_zone_iattach(zone, ¬ify->zone);
7131 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
7132 if (result != ISC_R_SUCCESS) {
7134 notify_destroy(notify, ISC_TRUE);
7139 ISC_LIST_APPEND(zone->notifies, notify, link);
7141 notify_find_address(notify);
7143 result = dns_rdataset_next(&nsrdset);
7145 dns_rdataset_disassociate(&nsrdset);
7148 if (dns_name_dynamic(&master))
7149 dns_name_free(&master, zone->mctx);
7151 dns_db_detachnode(zonedb, &node);
7153 dns_db_closeversion(zonedb, &version, ISC_FALSE);
7154 dns_db_detach(&zonedb);
7161 static inline isc_result_t
7162 save_nsrrset(dns_message_t *message, dns_name_t *name,
7163 dns_db_t *db, dns_dbversion_t *version)
7165 dns_rdataset_t *nsrdataset = NULL;
7166 dns_rdataset_t *rdataset = NULL;
7167 dns_dbnode_t *node = NULL;
7169 isc_result_t result;
7170 dns_rdata_t rdata = DNS_RDATA_INIT;
7173 * Extract NS RRset from message.
7175 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
7176 dns_rdatatype_ns, dns_rdatatype_none,
7178 if (result != ISC_R_SUCCESS)
7184 result = dns_db_findnode(db, name, ISC_TRUE, &node);
7185 if (result != ISC_R_SUCCESS)
7187 result = dns_db_addrdataset(db, node, version, 0,
7188 nsrdataset, 0, NULL);
7189 dns_db_detachnode(db, &node);
7190 if (result != ISC_R_SUCCESS)
7193 * Add glue rdatasets.
7195 for (result = dns_rdataset_first(nsrdataset);
7196 result == ISC_R_SUCCESS;
7197 result = dns_rdataset_next(nsrdataset)) {
7198 dns_rdataset_current(nsrdataset, &rdata);
7199 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7200 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7201 dns_rdata_reset(&rdata);
7202 if (!dns_name_issubdomain(&ns.name, name))
7205 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7206 &ns.name, dns_rdatatype_aaaa,
7207 dns_rdatatype_none, NULL,
7209 if (result == ISC_R_SUCCESS) {
7210 result = dns_db_findnode(db, &ns.name,
7212 if (result != ISC_R_SUCCESS)
7214 result = dns_db_addrdataset(db, node, version, 0,
7216 dns_db_detachnode(db, &node);
7217 if (result != ISC_R_SUCCESS)
7221 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7222 &ns.name, dns_rdatatype_a,
7223 dns_rdatatype_none, NULL,
7225 if (result == ISC_R_SUCCESS) {
7226 result = dns_db_findnode(db, &ns.name,
7228 if (result != ISC_R_SUCCESS)
7230 result = dns_db_addrdataset(db, node, version, 0,
7232 dns_db_detachnode(db, &node);
7233 if (result != ISC_R_SUCCESS)
7237 if (result != ISC_R_NOMORE)
7240 return (ISC_R_SUCCESS);
7247 stub_callback(isc_task_t *task, isc_event_t *event) {
7248 const char me[] = "stub_callback";
7249 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7250 dns_stub_t *stub = NULL;
7251 dns_message_t *msg = NULL;
7252 dns_zone_t *zone = NULL;
7253 char master[ISC_SOCKADDR_FORMATSIZE];
7254 char source[ISC_SOCKADDR_FORMATSIZE];
7255 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
7256 isc_result_t result;
7258 isc_boolean_t exiting = ISC_FALSE;
7262 stub = revent->ev_arg;
7263 INSIST(DNS_STUB_VALID(stub));
7275 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7276 zone_debuglog(zone, me, 1, "exiting");
7281 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7282 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7284 if (revent->result != ISC_R_SUCCESS) {
7285 if (revent->result == ISC_R_TIMEDOUT &&
7286 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7287 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7288 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7289 "refreshing stub: timeout retrying "
7290 " without EDNS master %s (source %s)",
7294 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
7295 &zone->sourceaddr, &now);
7296 dns_zone_log(zone, ISC_LOG_INFO,
7297 "could not refresh stub from master %s"
7298 " (source %s): %s", master, source,
7299 dns_result_totext(revent->result));
7303 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7304 if (result != ISC_R_SUCCESS)
7307 result = dns_request_getresponse(revent->request, msg, 0);
7308 if (result != ISC_R_SUCCESS)
7314 if (msg->rcode != dns_rcode_noerror) {
7318 isc_buffer_init(&rb, rcode, sizeof(rcode));
7319 (void)dns_rcode_totext(msg->rcode, &rb);
7321 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7322 (msg->rcode == dns_rcode_servfail ||
7323 msg->rcode == dns_rcode_notimp ||
7324 msg->rcode == dns_rcode_formerr)) {
7325 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7326 "refreshing stub: rcode (%.*s) retrying "
7327 "without EDNS master %s (source %s)",
7328 (int)rb.used, rcode, master, source);
7329 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7333 dns_zone_log(zone, ISC_LOG_INFO,
7335 "unexpected rcode (%.*s) from %s (source %s)",
7336 (int)rb.used, rcode, master, source);
7341 * We need complete messages.
7343 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7344 if (dns_request_usedtcp(revent->request)) {
7345 dns_zone_log(zone, ISC_LOG_INFO,
7346 "refreshing stub: truncated TCP "
7347 "response from master %s (source %s)",
7351 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7356 * If non-auth log and next master.
7358 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7359 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
7360 "non-authoritative answer from "
7361 "master %s (source %s)", master, source);
7368 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7369 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
7371 if (cnamecnt != 0) {
7372 dns_zone_log(zone, ISC_LOG_INFO,
7373 "refreshing stub: unexpected CNAME response "
7374 "from master %s (source %s)", master, source);
7379 dns_zone_log(zone, ISC_LOG_INFO,
7380 "refreshing stub: no NS records in response "
7381 "from master %s (source %s)", master, source);
7388 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
7389 if (result != ISC_R_SUCCESS) {
7390 dns_zone_log(zone, ISC_LOG_INFO,
7391 "refreshing stub: unable to save NS records "
7392 "from master %s (source %s)", master, source);
7399 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
7400 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
7401 if (zone->db == NULL)
7402 zone_attachdb(zone, stub->db);
7403 result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh,
7404 &retry, &expire, NULL, NULL);
7405 if (result == ISC_R_SUCCESS) {
7406 zone->refresh = RANGE(refresh, zone->minrefresh,
7408 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
7409 zone->expire = RANGE(expire, zone->refresh + zone->retry,
7411 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
7413 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
7414 dns_db_detach(&stub->db);
7416 dns_message_destroy(&msg);
7417 isc_event_free(&event);
7418 dns_request_destroy(&zone->request);
7420 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7421 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
7422 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7423 isc_interval_set(&i, zone->expire, 0);
7424 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7426 if (zone->masterfile != NULL)
7427 zone_needdump(zone, 0);
7429 zone_settimer(zone, &now);
7433 if (stub->version != NULL)
7434 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
7435 if (stub->db != NULL)
7436 dns_db_detach(&stub->db);
7438 dns_message_destroy(&msg);
7439 isc_event_free(&event);
7440 dns_request_destroy(&zone->request);
7442 * Skip to next failed / untried master.
7446 } while (zone->curmaster < zone->masterscnt &&
7447 zone->mastersok[zone->curmaster]);
7448 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7449 if (exiting || zone->curmaster >= zone->masterscnt) {
7450 isc_boolean_t done = ISC_TRUE;
7452 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7453 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7455 * Did we get a good answer from all the masters?
7457 for (j = 0; j < zone->masterscnt; j++)
7458 if (zone->mastersok[j] == ISC_FALSE) {
7465 zone->curmaster = 0;
7467 * Find the next failed master.
7469 while (zone->curmaster < zone->masterscnt &&
7470 zone->mastersok[zone->curmaster])
7472 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7474 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7476 zone_settimer(zone, &now);
7480 queue_soa_query(zone);
7485 dns_message_destroy(&msg);
7486 isc_event_free(&event);
7487 dns_request_destroy(&zone->request);
7488 ns_query(zone, NULL, stub);
7495 dns_zone_idetach(&stub->zone);
7496 INSIST(stub->db == NULL);
7497 INSIST(stub->version == NULL);
7498 isc_mem_put(stub->mctx, stub, sizeof(*stub));
7501 INSIST(event == NULL);
7506 * An SOA query has finished (successfully or not).
7509 refresh_callback(isc_task_t *task, isc_event_t *event) {
7510 const char me[] = "refresh_callback";
7511 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7513 dns_message_t *msg = NULL;
7514 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
7516 char master[ISC_SOCKADDR_FORMATSIZE];
7517 char source[ISC_SOCKADDR_FORMATSIZE];
7518 dns_rdataset_t *rdataset = NULL;
7519 dns_rdata_t rdata = DNS_RDATA_INIT;
7520 dns_rdata_soa_t soa;
7521 isc_result_t result;
7522 isc_uint32_t serial, oldserial = 0;
7524 isc_boolean_t do_queue_xfrin = ISC_FALSE;
7526 zone = revent->ev_arg;
7527 INSIST(DNS_ZONE_VALID(zone));
7538 * if timeout log and next master;
7541 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7542 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7544 if (revent->result != ISC_R_SUCCESS) {
7545 if (revent->result == ISC_R_TIMEDOUT &&
7546 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7547 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7548 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7549 "refresh: timeout retrying without EDNS "
7550 "master %s (source %s)", master, source);
7553 if (revent->result == ISC_R_TIMEDOUT &&
7554 !dns_request_usedtcp(revent->request)) {
7555 dns_zone_log(zone, ISC_LOG_INFO,
7556 "refresh: retry limit for "
7557 "master %s exceeded (source %s)",
7559 /* Try with slave with TCP. */
7560 if (zone->type == dns_zone_slave &&
7561 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
7562 if (!dns_zonemgr_unreachable(zone->zmgr,
7567 DNS_ZONE_SETFLAG(zone,
7568 DNS_ZONEFLG_SOABEFOREAXFR);
7571 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7572 "refresh: skipped tcp fallback "
7573 "as master %s (source %s) is "
7574 "unreachable (cached)",
7578 dns_zone_log(zone, ISC_LOG_INFO,
7579 "refresh: failure trying master "
7580 "%s (source %s): %s", master, source,
7581 dns_result_totext(revent->result));
7585 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7586 if (result != ISC_R_SUCCESS)
7588 result = dns_request_getresponse(revent->request, msg, 0);
7589 if (result != ISC_R_SUCCESS) {
7590 dns_zone_log(zone, ISC_LOG_INFO,
7591 "refresh: failure trying master "
7592 "%s (source %s): %s", master, source,
7593 dns_result_totext(result));
7600 if (msg->rcode != dns_rcode_noerror) {
7604 isc_buffer_init(&rb, rcode, sizeof(rcode));
7605 (void)dns_rcode_totext(msg->rcode, &rb);
7607 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7608 (msg->rcode == dns_rcode_servfail ||
7609 msg->rcode == dns_rcode_notimp ||
7610 msg->rcode == dns_rcode_formerr)) {
7611 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7612 "refresh: rcode (%.*s) retrying without "
7613 "EDNS master %s (source %s)",
7614 (int)rb.used, rcode, master, source);
7615 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7618 dns_zone_log(zone, ISC_LOG_INFO,
7619 "refresh: unexpected rcode (%.*s) from "
7620 "master %s (source %s)", (int)rb.used, rcode,
7623 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
7625 if (msg->rcode == dns_rcode_refused &&
7626 zone->type == dns_zone_slave)
7632 * If truncated punt to zone transfer which will query again.
7634 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7635 if (zone->type == dns_zone_slave) {
7636 dns_zone_log(zone, ISC_LOG_INFO,
7637 "refresh: truncated UDP answer, "
7638 "initiating TCP zone xfer "
7639 "for master %s (source %s)",
7641 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
7644 INSIST(zone->type == dns_zone_stub);
7645 if (dns_request_usedtcp(revent->request)) {
7646 dns_zone_log(zone, ISC_LOG_INFO,
7647 "refresh: truncated TCP response "
7648 "from master %s (source %s)",
7652 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7658 * if non-auth log and next master;
7660 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7661 dns_zone_log(zone, ISC_LOG_INFO,
7662 "refresh: non-authoritative answer from "
7663 "master %s (source %s)", master, source);
7667 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7668 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
7669 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
7670 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
7674 * There should not be a CNAME record at top of zone.
7676 if (cnamecnt != 0) {
7677 dns_zone_log(zone, ISC_LOG_INFO,
7678 "refresh: CNAME at top of zone "
7679 "in master %s (source %s)", master, source);
7684 * if referral log and next master;
7686 if (soacnt == 0 && soacount == 0 && nscount != 0) {
7687 dns_zone_log(zone, ISC_LOG_INFO,
7688 "refresh: referral response "
7689 "from master %s (source %s)", master, source);
7694 * if nodata log and next master;
7696 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
7697 dns_zone_log(zone, ISC_LOG_INFO,
7698 "refresh: NODATA response "
7699 "from master %s (source %s)", master, source);
7704 * Only one soa at top of zone.
7707 dns_zone_log(zone, ISC_LOG_INFO,
7708 "refresh: answer SOA count (%d) != 1 "
7709 "from master %s (source %s)",
7710 soacnt, master, source);
7718 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
7719 dns_rdatatype_soa, dns_rdatatype_none,
7721 if (result != ISC_R_SUCCESS) {
7722 dns_zone_log(zone, ISC_LOG_INFO,
7723 "refresh: unable to get SOA record "
7724 "from master %s (source %s)", master, source);
7728 result = dns_rdataset_first(rdataset);
7729 if (result != ISC_R_SUCCESS) {
7730 dns_zone_log(zone, ISC_LOG_INFO,
7731 "refresh: dns_rdataset_first() failed");
7735 dns_rdataset_current(rdataset, &rdata);
7736 result = dns_rdata_tostruct(&rdata, &soa, NULL);
7737 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7739 serial = soa.serial;
7740 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
7741 result = zone_get_from_db(zone, zone->db, NULL, NULL,
7742 &oldserial, NULL, NULL, NULL, NULL,
7744 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7745 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
7748 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
7751 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
7752 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
7753 isc_serial_gt(serial, oldserial)) {
7754 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
7755 &zone->sourceaddr, &now))
7757 dns_zone_log(zone, ISC_LOG_INFO,
7758 "refresh: skipping %s as master %s "
7759 "(source %s) is unreachable (cached)",
7760 zone->type == dns_zone_slave ?
7761 "zone transfer" : "NS query",
7766 isc_event_free(&event);
7767 dns_request_destroy(&zone->request);
7768 if (zone->type == dns_zone_slave) {
7769 do_queue_xfrin = ISC_TRUE;
7771 INSIST(zone->type == dns_zone_stub);
7772 ns_query(zone, rdataset, NULL);
7775 dns_message_destroy(&msg);
7776 } else if (isc_serial_eq(soa.serial, oldserial)) {
7777 if (zone->masterfile != NULL) {
7778 result = ISC_R_FAILURE;
7779 if (zone->journal != NULL)
7780 result = isc_file_settime(zone->journal, &now);
7781 if (result == ISC_R_SUCCESS &&
7782 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
7783 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
7784 result = isc_file_settime(zone->masterfile,
7786 } else if (result != ISC_R_SUCCESS)
7787 result = isc_file_settime(zone->masterfile,
7789 /* Someone removed the file from underneath us! */
7790 if (result == ISC_R_FILENOTFOUND) {
7791 zone_needdump(zone, DNS_DUMP_DELAY);
7792 } else if (result != ISC_R_SUCCESS)
7793 dns_zone_log(zone, ISC_LOG_ERROR,
7794 "refresh: could not set file "
7795 "modification time of '%s': %s",
7797 dns_result_totext(result));
7799 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7800 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7801 zone->mastersok[zone->curmaster] = ISC_TRUE;
7804 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
7805 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
7806 "received from master %s < ours (%u)",
7807 soa.serial, master, oldserial);
7809 zone_debuglog(zone, me, 1, "ahead");
7810 zone->mastersok[zone->curmaster] = ISC_TRUE;
7814 dns_message_destroy(&msg);
7819 dns_message_destroy(&msg);
7820 isc_event_free(&event);
7821 dns_request_destroy(&zone->request);
7823 * Skip to next failed / untried master.
7827 } while (zone->curmaster < zone->masterscnt &&
7828 zone->mastersok[zone->curmaster]);
7829 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7830 if (zone->curmaster >= zone->masterscnt) {
7831 isc_boolean_t done = ISC_TRUE;
7832 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7833 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7835 * Did we get a good answer from all the masters?
7837 for (j = 0; j < zone->masterscnt; j++)
7838 if (zone->mastersok[j] == ISC_FALSE) {
7845 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7846 zone->curmaster = 0;
7848 * Find the next failed master.
7850 while (zone->curmaster < zone->masterscnt &&
7851 zone->mastersok[zone->curmaster])
7855 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7856 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
7857 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
7858 zone->refreshtime = now;
7860 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7861 zone_settimer(zone, &now);
7866 queue_soa_query(zone);
7871 dns_message_destroy(&msg);
7872 isc_event_free(&event);
7873 dns_request_destroy(&zone->request);
7874 queue_soa_query(zone);
7880 dns_zone_idetach(&zone);
7885 queue_soa_query(dns_zone_t *zone) {
7886 const char me[] = "queue_soa_query";
7888 dns_zone_t *dummy = NULL;
7889 isc_result_t result;
7895 REQUIRE(LOCKED_ZONE(zone));
7897 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7898 cancel_refresh(zone);
7902 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
7903 soa_query, zone, sizeof(isc_event_t));
7905 cancel_refresh(zone);
7910 * Attach so that we won't clean up
7911 * until the event is delivered.
7913 zone_iattach(zone, &dummy);
7916 e->ev_sender = NULL;
7917 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
7918 if (result != ISC_R_SUCCESS) {
7919 zone_idetach(&dummy);
7921 cancel_refresh(zone);
7925 static inline isc_result_t
7926 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
7927 dns_message_t **messagep)
7929 dns_message_t *message = NULL;
7930 dns_name_t *qname = NULL;
7931 dns_rdataset_t *qrdataset = NULL;
7932 isc_result_t result;
7934 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
7936 if (result != ISC_R_SUCCESS)
7939 message->opcode = dns_opcode_query;
7940 message->rdclass = zone->rdclass;
7942 result = dns_message_gettempname(message, &qname);
7943 if (result != ISC_R_SUCCESS)
7946 result = dns_message_gettemprdataset(message, &qrdataset);
7947 if (result != ISC_R_SUCCESS)
7953 dns_name_init(qname, NULL);
7954 dns_name_clone(&zone->origin, qname);
7955 dns_rdataset_init(qrdataset);
7956 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
7957 ISC_LIST_APPEND(qname->list, qrdataset, link);
7958 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
7960 *messagep = message;
7961 return (ISC_R_SUCCESS);
7965 dns_message_puttempname(message, &qname);
7966 if (qrdataset != NULL)
7967 dns_message_puttemprdataset(message, &qrdataset);
7968 if (message != NULL)
7969 dns_message_destroy(&message);
7974 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
7975 dns_rdataset_t *rdataset = NULL;
7976 dns_rdatalist_t *rdatalist = NULL;
7977 dns_rdata_t *rdata = NULL;
7978 isc_result_t result;
7980 result = dns_message_gettemprdatalist(message, &rdatalist);
7981 if (result != ISC_R_SUCCESS)
7983 result = dns_message_gettemprdata(message, &rdata);
7984 if (result != ISC_R_SUCCESS)
7986 result = dns_message_gettemprdataset(message, &rdataset);
7987 if (result != ISC_R_SUCCESS)
7989 dns_rdataset_init(rdataset);
7991 rdatalist->type = dns_rdatatype_opt;
7992 rdatalist->covers = 0;
7995 * Set Maximum UDP buffer size.
7997 rdatalist->rdclass = udpsize;
8000 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
8004 /* Set EDNS options if applicable */
8006 unsigned char data[4];
8009 isc_buffer_init(&buf, data, sizeof(data));
8010 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
8011 isc_buffer_putuint16(&buf, 0);
8013 rdata->length = sizeof(data);
8019 rdata->rdclass = rdatalist->rdclass;
8020 rdata->type = rdatalist->type;
8023 ISC_LIST_INIT(rdatalist->rdata);
8024 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
8025 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
8028 return (dns_message_setopt(message, rdataset));
8031 if (rdatalist != NULL)
8032 dns_message_puttemprdatalist(message, &rdatalist);
8033 if (rdataset != NULL)
8034 dns_message_puttemprdataset(message, &rdataset);
8036 dns_message_puttemprdata(message, &rdata);
8042 soa_query(isc_task_t *task, isc_event_t *event) {
8043 const char me[] = "soa_query";
8044 isc_result_t result = ISC_R_FAILURE;
8045 dns_message_t *message = NULL;
8046 dns_zone_t *zone = event->ev_arg;
8047 dns_zone_t *dummy = NULL;
8048 isc_netaddr_t masterip;
8049 dns_tsigkey_t *key = NULL;
8050 isc_uint32_t options;
8051 isc_boolean_t cancel = ISC_TRUE;
8053 isc_boolean_t have_xfrsource, reqnsid;
8054 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8056 REQUIRE(DNS_ZONE_VALID(zone));
8063 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
8064 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
8065 zone->view->requestmgr == NULL) {
8066 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8072 * XXX Optimisation: Create message when zone is setup and reuse.
8074 result = create_query(zone, dns_rdatatype_soa, &message);
8075 if (result != ISC_R_SUCCESS)
8079 INSIST(zone->masterscnt > 0);
8080 INSIST(zone->curmaster < zone->masterscnt);
8082 zone->masteraddr = zone->masters[zone->curmaster];
8084 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8086 * First, look for a tsig key in the master statement, then
8087 * try for a server key.
8089 if ((zone->masterkeynames != NULL) &&
8090 (zone->masterkeynames[zone->curmaster] != NULL)) {
8091 dns_view_t *view = dns_zone_getview(zone);
8092 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8093 result = dns_view_gettsig(view, keyname, &key);
8094 if (result != ISC_R_SUCCESS) {
8095 char namebuf[DNS_NAME_FORMATSIZE];
8096 dns_name_format(keyname, namebuf, sizeof(namebuf));
8097 dns_zone_log(zone, ISC_LOG_ERROR,
8098 "unable to find key: %s", namebuf);
8103 result = dns_view_getpeertsig(zone->view, &masterip, &key);
8104 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
8105 char addrbuf[ISC_NETADDR_FORMATSIZE];
8106 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
8107 dns_zone_log(zone, ISC_LOG_ERROR,
8108 "unable to find TSIG key for %s", addrbuf);
8113 have_xfrsource = ISC_FALSE;
8114 reqnsid = zone->view->requestnsid;
8115 if (zone->view->peers != NULL) {
8116 dns_peer_t *peer = NULL;
8118 result = dns_peerlist_peerbyaddr(zone->view->peers,
8120 if (result == ISC_R_SUCCESS) {
8121 result = dns_peer_getsupportedns(peer, &edns);
8122 if (result == ISC_R_SUCCESS && !edns)
8123 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8124 result = dns_peer_gettransfersource(peer,
8126 if (result == ISC_R_SUCCESS)
8127 have_xfrsource = ISC_TRUE;
8128 if (zone->view->resolver != NULL)
8130 dns_resolver_getudpsize(zone->view->resolver);
8131 (void)dns_peer_getudpsize(peer, &udpsize);
8132 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8136 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8138 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8139 if (isc_sockaddr_equal(&zone->altxfrsource4,
8142 zone->sourceaddr = zone->altxfrsource4;
8143 } else if (!have_xfrsource)
8144 zone->sourceaddr = zone->xfrsource4;
8147 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8148 if (isc_sockaddr_equal(&zone->altxfrsource6,
8151 zone->sourceaddr = zone->altxfrsource6;
8152 } else if (!have_xfrsource)
8153 zone->sourceaddr = zone->xfrsource6;
8156 result = ISC_R_NOTIMPLEMENTED;
8160 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
8161 DNS_REQUESTOPT_TCP : 0;
8163 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8164 result = add_opt(message, udpsize, reqnsid);
8165 if (result != ISC_R_SUCCESS)
8166 zone_debuglog(zone, me, 1,
8167 "unable to add opt record: %s",
8168 dns_result_totext(result));
8171 zone_iattach(zone, &dummy);
8173 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8175 result = dns_request_createvia2(zone->view->requestmgr, message,
8176 &zone->sourceaddr, &zone->masteraddr,
8177 options, key, timeout * 3, timeout,
8178 zone->task, refresh_callback, zone,
8180 if (result != ISC_R_SUCCESS) {
8181 zone_idetach(&dummy);
8182 zone_debuglog(zone, me, 1,
8183 "dns_request_createvia2() failed: %s",
8184 dns_result_totext(result));
8187 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
8188 inc_stats(zone, dns_zonestatscounter_soaoutv4);
8190 inc_stats(zone, dns_zonestatscounter_soaoutv6);
8196 dns_tsigkey_detach(&key);
8197 if (result != ISC_R_SUCCESS)
8198 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8199 if (message != NULL)
8200 dns_message_destroy(&message);
8202 cancel_refresh(zone);
8203 isc_event_free(&event);
8205 dns_zone_idetach(&zone);
8210 dns_tsigkey_detach(&key);
8212 * Skip to next failed / untried master.
8216 } while (zone->curmaster < zone->masterscnt &&
8217 zone->mastersok[zone->curmaster]);
8218 if (zone->curmaster < zone->masterscnt)
8220 zone->curmaster = 0;
8225 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
8226 const char me[] = "ns_query";
8227 isc_result_t result;
8228 dns_message_t *message = NULL;
8229 isc_netaddr_t masterip;
8230 dns_tsigkey_t *key = NULL;
8231 dns_dbnode_t *node = NULL;
8233 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
8234 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8236 REQUIRE(DNS_ZONE_VALID(zone));
8237 REQUIRE(LOCKED_ZONE(zone));
8238 REQUIRE((soardataset != NULL && stub == NULL) ||
8239 (soardataset == NULL && stub != NULL));
8240 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
8245 stub = isc_mem_get(zone->mctx, sizeof(*stub));
8248 stub->magic = STUB_MAGIC;
8249 stub->mctx = zone->mctx;
8252 stub->version = NULL;
8255 * Attach so that the zone won't disappear from under us.
8257 zone_iattach(zone, &stub->zone);
8260 * If a db exists we will update it, otherwise we create a
8261 * new one and attach it to the zone once we have the NS
8264 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8265 if (zone->db != NULL) {
8266 dns_db_attach(zone->db, &stub->db);
8267 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8269 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8271 INSIST(zone->db_argc >= 1);
8272 result = dns_db_create(zone->mctx, zone->db_argv[0],
8273 &zone->origin, dns_dbtype_stub,
8278 if (result != ISC_R_SUCCESS) {
8279 dns_zone_log(zone, ISC_LOG_ERROR,
8283 dns_result_totext(result));
8286 dns_db_settask(stub->db, zone->task);
8289 dns_db_newversion(stub->db, &stub->version);
8292 * Update SOA record.
8294 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
8296 if (result != ISC_R_SUCCESS) {
8297 dns_zone_log(zone, ISC_LOG_INFO,
8299 "dns_db_findnode() failed: %s",
8300 dns_result_totext(result));
8304 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
8305 soardataset, 0, NULL);
8306 dns_db_detachnode(stub->db, &node);
8307 if (result != ISC_R_SUCCESS) {
8308 dns_zone_log(zone, ISC_LOG_INFO,
8310 "dns_db_addrdataset() failed: %s",
8311 dns_result_totext(result));
8317 * XXX Optimisation: Create message when zone is setup and reuse.
8319 result = create_query(zone, dns_rdatatype_ns, &message);
8320 INSIST(result == ISC_R_SUCCESS);
8322 INSIST(zone->masterscnt > 0);
8323 INSIST(zone->curmaster < zone->masterscnt);
8324 zone->masteraddr = zone->masters[zone->curmaster];
8326 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8328 * First, look for a tsig key in the master statement, then
8329 * try for a server key.
8331 if ((zone->masterkeynames != NULL) &&
8332 (zone->masterkeynames[zone->curmaster] != NULL)) {
8333 dns_view_t *view = dns_zone_getview(zone);
8334 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8335 result = dns_view_gettsig(view, keyname, &key);
8336 if (result != ISC_R_SUCCESS) {
8337 char namebuf[DNS_NAME_FORMATSIZE];
8338 dns_name_format(keyname, namebuf, sizeof(namebuf));
8339 dns_zone_log(zone, ISC_LOG_ERROR,
8340 "unable to find key: %s", namebuf);
8344 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
8346 reqnsid = zone->view->requestnsid;
8347 if (zone->view->peers != NULL) {
8348 dns_peer_t *peer = NULL;
8350 result = dns_peerlist_peerbyaddr(zone->view->peers,
8352 if (result == ISC_R_SUCCESS) {
8353 result = dns_peer_getsupportedns(peer, &edns);
8354 if (result == ISC_R_SUCCESS && !edns)
8355 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8356 result = dns_peer_gettransfersource(peer,
8358 if (result == ISC_R_SUCCESS)
8359 have_xfrsource = ISC_TRUE;
8360 if (zone->view->resolver != NULL)
8362 dns_resolver_getudpsize(zone->view->resolver);
8363 (void)dns_peer_getudpsize(peer, &udpsize);
8364 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8368 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8369 result = add_opt(message, udpsize, reqnsid);
8370 if (result != ISC_R_SUCCESS)
8371 zone_debuglog(zone, me, 1,
8372 "unable to add opt record: %s",
8373 dns_result_totext(result));
8377 * Always use TCP so that we shouldn't truncate in additional section.
8379 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8381 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8382 zone->sourceaddr = zone->altxfrsource4;
8383 else if (!have_xfrsource)
8384 zone->sourceaddr = zone->xfrsource4;
8387 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8388 zone->sourceaddr = zone->altxfrsource6;
8389 else if (!have_xfrsource)
8390 zone->sourceaddr = zone->xfrsource6;
8393 result = ISC_R_NOTIMPLEMENTED;
8398 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8400 result = dns_request_createvia2(zone->view->requestmgr, message,
8401 &zone->sourceaddr, &zone->masteraddr,
8402 DNS_REQUESTOPT_TCP, key, timeout * 3,
8403 timeout, zone->task, stub_callback,
8404 stub, &zone->request);
8405 if (result != ISC_R_SUCCESS) {
8406 zone_debuglog(zone, me, 1,
8407 "dns_request_createvia() failed: %s",
8408 dns_result_totext(result));
8411 dns_message_destroy(&message);
8415 cancel_refresh(zone);
8418 if (stub->version != NULL)
8419 dns_db_closeversion(stub->db, &stub->version,
8421 if (stub->db != NULL)
8422 dns_db_detach(&stub->db);
8423 if (stub->zone != NULL)
8424 zone_idetach(&stub->zone);
8425 isc_mem_put(stub->mctx, stub, sizeof(*stub));
8427 if (message != NULL)
8428 dns_message_destroy(&message);
8431 dns_tsigkey_detach(&key);
8436 * Handle the control event. Note that although this event causes the zone
8437 * to shut down, it is not a shutdown event in the sense of the task library.
8440 zone_shutdown(isc_task_t *task, isc_event_t *event) {
8441 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
8442 isc_boolean_t free_needed, linked = ISC_FALSE;
8445 REQUIRE(DNS_ZONE_VALID(zone));
8446 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
8447 INSIST(isc_refcount_current(&zone->erefs) == 0);
8449 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
8452 * Stop things being restarted after we cancel them below.
8455 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
8459 * If we were waiting for xfrin quota, step out of
8461 * If there's no zone manager, we can't be waiting for the
8464 if (zone->zmgr != NULL) {
8465 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8466 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
8467 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
8470 zone->statelist = NULL;
8472 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8476 * In task context, no locking required. See zone_xfrdone().
8478 if (zone->xfr != NULL)
8479 dns_xfrin_shutdown(zone->xfr);
8483 INSIST(zone->irefs > 0);
8486 if (zone->request != NULL) {
8487 dns_request_cancel(zone->request);
8490 if (zone->readio != NULL)
8491 zonemgr_cancelio(zone->readio);
8493 if (zone->lctx != NULL)
8494 dns_loadctx_cancel(zone->lctx);
8496 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8497 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8498 if (zone->writeio != NULL)
8499 zonemgr_cancelio(zone->writeio);
8501 if (zone->dctx != NULL)
8502 dns_dumpctx_cancel(zone->dctx);
8505 notify_cancel(zone);
8507 forward_cancel(zone);
8509 if (zone->timer != NULL) {
8510 isc_timer_detach(&zone->timer);
8511 INSIST(zone->irefs > 0);
8515 if (zone->view != NULL)
8516 dns_view_weakdetach(&zone->view);
8519 * We have now canceled everything set the flag to allow exit_check()
8520 * to succeed. We must not unlock between setting this flag and
8521 * calling exit_check().
8523 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
8524 free_needed = exit_check(zone);
8531 zone_timer(isc_task_t *task, isc_event_t *event) {
8532 const char me[] = "zone_timer";
8533 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
8536 REQUIRE(DNS_ZONE_VALID(zone));
8540 zone_maintenance(zone);
8542 isc_event_free(&event);
8546 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
8547 const char me[] = "zone_settimer";
8549 isc_result_t result;
8551 REQUIRE(DNS_ZONE_VALID(zone));
8552 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8555 isc_time_settoepoch(&next);
8557 switch (zone->type) {
8558 case dns_zone_master:
8559 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8560 next = zone->notifytime;
8561 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8562 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8563 INSIST(!isc_time_isepoch(&zone->dumptime));
8564 if (isc_time_isepoch(&next) ||
8565 isc_time_compare(&zone->dumptime, &next) < 0)
8566 next = zone->dumptime;
8568 if (!isc_time_isepoch(&zone->resigntime)) {
8569 if (isc_time_isepoch(&next) ||
8570 isc_time_compare(&zone->resigntime, &next) < 0)
8571 next = zone->resigntime;
8573 if (!isc_time_isepoch(&zone->keywarntime)) {
8574 if (isc_time_isepoch(&next) ||
8575 isc_time_compare(&zone->keywarntime, &next) < 0)
8576 next = zone->keywarntime;
8578 if (!isc_time_isepoch(&zone->signingtime)) {
8579 if (isc_time_isepoch(&next) ||
8580 isc_time_compare(&zone->signingtime, &next) < 0)
8581 next = zone->signingtime;
8583 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
8584 if (isc_time_isepoch(&next) ||
8585 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
8586 next = zone->nsec3chaintime;
8590 case dns_zone_slave:
8591 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8592 next = zone->notifytime;
8596 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
8597 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
8598 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
8599 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
8600 INSIST(!isc_time_isepoch(&zone->refreshtime));
8601 if (isc_time_isepoch(&next) ||
8602 isc_time_compare(&zone->refreshtime, &next) < 0)
8603 next = zone->refreshtime;
8605 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8606 INSIST(!isc_time_isepoch(&zone->expiretime));
8607 if (isc_time_isepoch(&next) ||
8608 isc_time_compare(&zone->expiretime, &next) < 0)
8609 next = zone->expiretime;
8611 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8612 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8613 INSIST(!isc_time_isepoch(&zone->dumptime));
8614 if (isc_time_isepoch(&next) ||
8615 isc_time_compare(&zone->dumptime, &next) < 0)
8616 next = zone->dumptime;
8624 if (isc_time_isepoch(&next)) {
8625 zone_debuglog(zone, me, 10, "settimer inactive");
8626 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
8627 NULL, NULL, ISC_TRUE);
8628 if (result != ISC_R_SUCCESS)
8629 dns_zone_log(zone, ISC_LOG_ERROR,
8630 "could not deactivate zone timer: %s",
8631 isc_result_totext(result));
8633 if (isc_time_compare(&next, now) <= 0)
8635 result = isc_timer_reset(zone->timer, isc_timertype_once,
8636 &next, NULL, ISC_TRUE);
8637 if (result != ISC_R_SUCCESS)
8638 dns_zone_log(zone, ISC_LOG_ERROR,
8639 "could not reset zone timer: %s",
8640 isc_result_totext(result));
8645 cancel_refresh(dns_zone_t *zone) {
8646 const char me[] = "cancel_refresh";
8650 * 'zone' locked by caller.
8653 REQUIRE(DNS_ZONE_VALID(zone));
8654 REQUIRE(LOCKED_ZONE(zone));
8658 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8660 zone_settimer(zone, &now);
8664 notify_createmessage(dns_zone_t *zone, unsigned int flags,
8665 dns_message_t **messagep)
8667 dns_db_t *zonedb = NULL;
8668 dns_dbnode_t *node = NULL;
8669 dns_dbversion_t *version = NULL;
8670 dns_message_t *message = NULL;
8671 dns_rdataset_t rdataset;
8672 dns_rdata_t rdata = DNS_RDATA_INIT;
8674 dns_name_t *tempname = NULL;
8675 dns_rdata_t *temprdata = NULL;
8676 dns_rdatalist_t *temprdatalist = NULL;
8677 dns_rdataset_t *temprdataset = NULL;
8679 isc_result_t result;
8681 isc_buffer_t *b = NULL;
8683 REQUIRE(DNS_ZONE_VALID(zone));
8684 REQUIRE(messagep != NULL && *messagep == NULL);
8686 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
8688 if (result != ISC_R_SUCCESS)
8691 message->opcode = dns_opcode_notify;
8692 message->flags |= DNS_MESSAGEFLAG_AA;
8693 message->rdclass = zone->rdclass;
8695 result = dns_message_gettempname(message, &tempname);
8696 if (result != ISC_R_SUCCESS)
8699 result = dns_message_gettemprdataset(message, &temprdataset);
8700 if (result != ISC_R_SUCCESS)
8706 dns_name_init(tempname, NULL);
8707 dns_name_clone(&zone->origin, tempname);
8708 dns_rdataset_init(temprdataset);
8709 dns_rdataset_makequestion(temprdataset, zone->rdclass,
8711 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8712 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
8714 temprdataset = NULL;
8716 if ((flags & DNS_NOTIFY_NOSOA) != 0)
8719 result = dns_message_gettempname(message, &tempname);
8720 if (result != ISC_R_SUCCESS)
8722 result = dns_message_gettemprdata(message, &temprdata);
8723 if (result != ISC_R_SUCCESS)
8725 result = dns_message_gettemprdataset(message, &temprdataset);
8726 if (result != ISC_R_SUCCESS)
8728 result = dns_message_gettemprdatalist(message, &temprdatalist);
8729 if (result != ISC_R_SUCCESS)
8732 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8733 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
8734 dns_db_attach(zone->db, &zonedb);
8735 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8737 dns_name_init(tempname, NULL);
8738 dns_name_clone(&zone->origin, tempname);
8739 dns_db_currentversion(zonedb, &version);
8740 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
8741 if (result != ISC_R_SUCCESS)
8744 dns_rdataset_init(&rdataset);
8745 result = dns_db_findrdataset(zonedb, node, version,
8747 dns_rdatatype_none, 0, &rdataset,
8749 if (result != ISC_R_SUCCESS)
8751 result = dns_rdataset_first(&rdataset);
8752 if (result != ISC_R_SUCCESS)
8754 dns_rdataset_current(&rdataset, &rdata);
8755 dns_rdata_toregion(&rdata, &r);
8756 result = isc_buffer_allocate(zone->mctx, &b, r.length);
8757 if (result != ISC_R_SUCCESS)
8759 isc_buffer_putmem(b, r.base, r.length);
8760 isc_buffer_usedregion(b, &r);
8761 dns_rdata_init(temprdata);
8762 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
8763 dns_message_takebuffer(message, &b);
8764 result = dns_rdataset_next(&rdataset);
8765 dns_rdataset_disassociate(&rdataset);
8766 if (result != ISC_R_NOMORE)
8768 temprdatalist->rdclass = rdata.rdclass;
8769 temprdatalist->type = rdata.type;
8770 temprdatalist->covers = 0;
8771 temprdatalist->ttl = rdataset.ttl;
8772 ISC_LIST_INIT(temprdatalist->rdata);
8773 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
8775 dns_rdataset_init(temprdataset);
8776 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
8777 if (result != ISC_R_SUCCESS)
8780 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8781 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
8782 temprdatalist = NULL;
8783 temprdataset = NULL;
8789 dns_db_detachnode(zonedb, &node);
8790 if (version != NULL)
8791 dns_db_closeversion(zonedb, &version, ISC_FALSE);
8793 dns_db_detach(&zonedb);
8794 if (tempname != NULL)
8795 dns_message_puttempname(message, &tempname);
8796 if (temprdata != NULL)
8797 dns_message_puttemprdata(message, &temprdata);
8798 if (temprdataset != NULL)
8799 dns_message_puttemprdataset(message, &temprdataset);
8800 if (temprdatalist != NULL)
8801 dns_message_puttemprdatalist(message, &temprdatalist);
8804 *messagep = message;
8805 return (ISC_R_SUCCESS);
8808 if (tempname != NULL)
8809 dns_message_puttempname(message, &tempname);
8810 if (temprdataset != NULL)
8811 dns_message_puttemprdataset(message, &temprdataset);
8812 dns_message_destroy(&message);
8817 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
8821 dns_rdata_soa_t soa;
8822 dns_rdataset_t *rdataset = NULL;
8823 dns_rdata_t rdata = DNS_RDATA_INIT;
8824 isc_result_t result;
8825 char fromtext[ISC_SOCKADDR_FORMATSIZE];
8827 isc_netaddr_t netaddr;
8828 isc_sockaddr_t local, remote;
8830 REQUIRE(DNS_ZONE_VALID(zone));
8833 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
8837 * Check that 'from' is a valid notify source, (zone->masters).
8838 * Return DNS_R_REFUSED if not.
8840 * If the notify message contains a serial number check it
8841 * against the zones serial and return if <= current serial
8843 * If a refresh check is progress, if so just record the
8844 * fact we received a NOTIFY and from where and return.
8845 * We will perform a new refresh check when the current one
8846 * completes. Return ISC_R_SUCCESS.
8848 * Otherwise initiate a refresh check using 'from' as the
8849 * first address to check. Return ISC_R_SUCCESS.
8852 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
8855 * We only handle NOTIFY (SOA) at the present.
8858 if (isc_sockaddr_pf(from) == PF_INET)
8859 inc_stats(zone, dns_zonestatscounter_notifyinv4);
8861 inc_stats(zone, dns_zonestatscounter_notifyinv6);
8862 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
8863 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
8864 dns_rdatatype_soa, dns_rdatatype_none,
8865 NULL, NULL) != ISC_R_SUCCESS) {
8867 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
8868 dns_zone_log(zone, ISC_LOG_NOTICE,
8870 "question section from: %s", fromtext);
8871 return (DNS_R_FORMERR);
8873 dns_zone_log(zone, ISC_LOG_NOTICE,
8874 "NOTIFY zone does not match");
8875 return (DNS_R_NOTIMP);
8879 * If we are a master zone just succeed.
8881 if (zone->type == dns_zone_master) {
8883 return (ISC_R_SUCCESS);
8886 isc_netaddr_fromsockaddr(&netaddr, from);
8887 for (i = 0; i < zone->masterscnt; i++) {
8888 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
8890 if (zone->view->aclenv.match_mapped &&
8891 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
8892 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
8893 isc_netaddr_t na1, na2;
8894 isc_netaddr_fromv4mapped(&na1, &netaddr);
8895 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
8896 if (isc_netaddr_equal(&na1, &na2))
8902 * Accept notify requests from non masters if they are on
8903 * 'zone->notify_acl'.
8905 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
8906 dns_acl_match(&netaddr, NULL, zone->notify_acl,
8907 &zone->view->aclenv,
8908 &match, NULL) == ISC_R_SUCCESS &&
8911 /* Accept notify. */
8912 } else if (i >= zone->masterscnt) {
8914 dns_zone_log(zone, ISC_LOG_INFO,
8915 "refused notify from non-master: %s", fromtext);
8916 inc_stats(zone, dns_zonestatscounter_notifyrej);
8917 return (DNS_R_REFUSED);
8921 * If the zone is loaded and there are answers check the serial
8922 * to see if we need to do a refresh. Do not worry about this
8923 * check if we are a dialup zone as we use the notify request
8924 * to trigger a refresh check.
8926 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
8927 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8928 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
8929 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
8932 dns_rdatatype_none, NULL,
8934 if (result == ISC_R_SUCCESS)
8935 result = dns_rdataset_first(rdataset);
8936 if (result == ISC_R_SUCCESS) {
8937 isc_uint32_t serial = 0, oldserial;
8939 dns_rdataset_current(rdataset, &rdata);
8940 result = dns_rdata_tostruct(&rdata, &soa, NULL);
8941 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8942 serial = soa.serial;
8944 * The following should safely be performed without DB
8945 * lock and succeed in this context.
8947 result = zone_get_from_db(zone, zone->db, NULL, NULL,
8948 &oldserial, NULL, NULL, NULL,
8950 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8951 if (isc_serial_le(serial, oldserial)) {
8952 dns_zone_log(zone, ISC_LOG_INFO,
8954 "zone is up to date",
8957 return (ISC_R_SUCCESS);
8963 * If we got this far and there was a refresh in progress just
8964 * let it complete. Record where we got the notify from so we
8965 * can perform a refresh check when the current one completes
8967 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
8968 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
8969 zone->notifyfrom = *from;
8971 dns_zone_log(zone, ISC_LOG_INFO,
8972 "notify from %s: refresh in progress, "
8973 "refresh check queued",
8975 return (ISC_R_SUCCESS);
8977 zone->notifyfrom = *from;
8978 local = zone->masteraddr;
8979 remote = zone->sourceaddr;
8981 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
8982 dns_zone_refresh(zone);
8983 return (ISC_R_SUCCESS);
8987 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
8989 REQUIRE(DNS_ZONE_VALID(zone));
8992 if (zone->notify_acl != NULL)
8993 dns_acl_detach(&zone->notify_acl);
8994 dns_acl_attach(acl, &zone->notify_acl);
8999 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
9001 REQUIRE(DNS_ZONE_VALID(zone));
9004 if (zone->query_acl != NULL)
9005 dns_acl_detach(&zone->query_acl);
9006 dns_acl_attach(acl, &zone->query_acl);
9011 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
9013 REQUIRE(DNS_ZONE_VALID(zone));
9016 if (zone->queryon_acl != NULL)
9017 dns_acl_detach(&zone->queryon_acl);
9018 dns_acl_attach(acl, &zone->queryon_acl);
9023 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
9025 REQUIRE(DNS_ZONE_VALID(zone));
9028 if (zone->update_acl != NULL)
9029 dns_acl_detach(&zone->update_acl);
9030 dns_acl_attach(acl, &zone->update_acl);
9035 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
9037 REQUIRE(DNS_ZONE_VALID(zone));
9040 if (zone->forward_acl != NULL)
9041 dns_acl_detach(&zone->forward_acl);
9042 dns_acl_attach(acl, &zone->forward_acl);
9047 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
9049 REQUIRE(DNS_ZONE_VALID(zone));
9052 if (zone->xfr_acl != NULL)
9053 dns_acl_detach(&zone->xfr_acl);
9054 dns_acl_attach(acl, &zone->xfr_acl);
9059 dns_zone_getnotifyacl(dns_zone_t *zone) {
9061 REQUIRE(DNS_ZONE_VALID(zone));
9063 return (zone->notify_acl);
9067 dns_zone_getqueryacl(dns_zone_t *zone) {
9069 REQUIRE(DNS_ZONE_VALID(zone));
9071 return (zone->query_acl);
9075 dns_zone_getqueryonacl(dns_zone_t *zone) {
9077 REQUIRE(DNS_ZONE_VALID(zone));
9079 return (zone->queryon_acl);
9083 dns_zone_getupdateacl(dns_zone_t *zone) {
9085 REQUIRE(DNS_ZONE_VALID(zone));
9087 return (zone->update_acl);
9091 dns_zone_getforwardacl(dns_zone_t *zone) {
9093 REQUIRE(DNS_ZONE_VALID(zone));
9095 return (zone->forward_acl);
9099 dns_zone_getxfracl(dns_zone_t *zone) {
9101 REQUIRE(DNS_ZONE_VALID(zone));
9103 return (zone->xfr_acl);
9107 dns_zone_clearupdateacl(dns_zone_t *zone) {
9109 REQUIRE(DNS_ZONE_VALID(zone));
9112 if (zone->update_acl != NULL)
9113 dns_acl_detach(&zone->update_acl);
9118 dns_zone_clearforwardacl(dns_zone_t *zone) {
9120 REQUIRE(DNS_ZONE_VALID(zone));
9123 if (zone->forward_acl != NULL)
9124 dns_acl_detach(&zone->forward_acl);
9129 dns_zone_clearnotifyacl(dns_zone_t *zone) {
9131 REQUIRE(DNS_ZONE_VALID(zone));
9134 if (zone->notify_acl != NULL)
9135 dns_acl_detach(&zone->notify_acl);
9140 dns_zone_clearqueryacl(dns_zone_t *zone) {
9142 REQUIRE(DNS_ZONE_VALID(zone));
9145 if (zone->query_acl != NULL)
9146 dns_acl_detach(&zone->query_acl);
9151 dns_zone_clearqueryonacl(dns_zone_t *zone) {
9153 REQUIRE(DNS_ZONE_VALID(zone));
9156 if (zone->queryon_acl != NULL)
9157 dns_acl_detach(&zone->queryon_acl);
9162 dns_zone_clearxfracl(dns_zone_t *zone) {
9164 REQUIRE(DNS_ZONE_VALID(zone));
9167 if (zone->xfr_acl != NULL)
9168 dns_acl_detach(&zone->xfr_acl);
9173 dns_zone_getupdatedisabled(dns_zone_t *zone) {
9174 REQUIRE(DNS_ZONE_VALID(zone));
9175 return (zone->update_disabled);
9180 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
9181 REQUIRE(DNS_ZONE_VALID(zone));
9182 zone->update_disabled = state;
9186 dns_zone_getzeronosoattl(dns_zone_t *zone) {
9187 REQUIRE(DNS_ZONE_VALID(zone));
9188 return (zone->zero_no_soa_ttl);
9193 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
9194 REQUIRE(DNS_ZONE_VALID(zone));
9195 zone->zero_no_soa_ttl = state;
9199 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
9201 REQUIRE(DNS_ZONE_VALID(zone));
9203 zone->check_names = severity;
9207 dns_zone_getchecknames(dns_zone_t *zone) {
9209 REQUIRE(DNS_ZONE_VALID(zone));
9211 return (zone->check_names);
9215 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
9217 REQUIRE(DNS_ZONE_VALID(zone));
9219 zone->journalsize = size;
9223 dns_zone_getjournalsize(dns_zone_t *zone) {
9225 REQUIRE(DNS_ZONE_VALID(zone));
9227 return (zone->journalsize);
9231 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
9232 isc_result_t result = ISC_R_FAILURE;
9233 isc_buffer_t buffer;
9235 REQUIRE(buf != NULL);
9236 REQUIRE(length > 1U);
9239 * Leave space for terminating '\0'.
9241 isc_buffer_init(&buffer, buf, length - 1);
9242 if (dns_name_dynamic(&zone->origin))
9243 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9244 if (result != ISC_R_SUCCESS &&
9245 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9246 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9248 if (isc_buffer_availablelength(&buffer) > 0)
9249 isc_buffer_putstr(&buffer, "/");
9250 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9252 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
9253 strcmp(zone->view->name, "_default") != 0 &&
9254 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
9255 isc_buffer_putstr(&buffer, "/");
9256 isc_buffer_putstr(&buffer, zone->view->name);
9259 buf[isc_buffer_usedlength(&buffer)] = '\0';
9263 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
9264 isc_result_t result = ISC_R_FAILURE;
9265 isc_buffer_t buffer;
9267 REQUIRE(buf != NULL);
9268 REQUIRE(length > 1U);
9271 * Leave space for terminating '\0'.
9273 isc_buffer_init(&buffer, buf, length - 1);
9274 if (dns_name_dynamic(&zone->origin))
9275 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9276 if (result != ISC_R_SUCCESS &&
9277 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9278 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9280 buf[isc_buffer_usedlength(&buffer)] = '\0';
9284 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
9285 isc_buffer_t buffer;
9287 REQUIRE(buf != NULL);
9288 REQUIRE(length > 1U);
9291 * Leave space for terminating '\0'.
9293 isc_buffer_init(&buffer, buf, length - 1);
9294 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9296 buf[isc_buffer_usedlength(&buffer)] = '\0';
9300 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
9301 isc_buffer_t buffer;
9303 REQUIRE(buf != NULL);
9304 REQUIRE(length > 1U);
9308 * Leave space for terminating '\0'.
9310 isc_buffer_init(&buffer, buf, length - 1);
9312 if (zone->view == NULL) {
9313 isc_buffer_putstr(&buffer, "_none");
9314 } else if (strlen(zone->view->name)
9315 < isc_buffer_availablelength(&buffer)) {
9316 isc_buffer_putstr(&buffer, zone->view->name);
9318 isc_buffer_putstr(&buffer, "_toolong");
9321 buf[isc_buffer_usedlength(&buffer)] = '\0';
9325 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
9326 REQUIRE(DNS_ZONE_VALID(zone));
9327 REQUIRE(buf != NULL);
9328 zone_namerd_tostr(zone, buf, length);
9332 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9336 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9340 vsnprintf(message, sizeof(message), fmt, ap);
9342 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
9343 level, "zone %s: %s", zone->strnamerd, message);
9347 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
9348 int level, const char *fmt, ...) {
9352 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9356 vsnprintf(message, sizeof(message), fmt, ap);
9358 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
9359 level, "zone %s: %s", zone->strnamerd, message);
9363 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9367 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9371 vsnprintf(message, sizeof(message), fmt, ap);
9373 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9374 level, "zone %s: %s", zone->strnamerd, message);
9378 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
9379 const char *fmt, ...)
9383 int level = ISC_LOG_DEBUG(debuglevel);
9385 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9389 vsnprintf(message, sizeof(message), fmt, ap);
9391 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9392 level, "%s: zone %s: %s", me, zone->strnamerd, message);
9396 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
9398 isc_result_t result;
9400 dns_rdataset_t *curr;
9403 result = dns_message_firstname(msg, section);
9404 while (result == ISC_R_SUCCESS) {
9406 dns_message_currentname(msg, section, &name);
9408 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
9409 curr = ISC_LIST_PREV(curr, link)) {
9410 if (curr->type == type)
9413 result = dns_message_nextname(msg, section);
9420 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
9421 REQUIRE(DNS_ZONE_VALID(zone));
9423 zone->maxxfrin = maxxfrin;
9427 dns_zone_getmaxxfrin(dns_zone_t *zone) {
9428 REQUIRE(DNS_ZONE_VALID(zone));
9430 return (zone->maxxfrin);
9434 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
9435 REQUIRE(DNS_ZONE_VALID(zone));
9436 zone->maxxfrout = maxxfrout;
9440 dns_zone_getmaxxfrout(dns_zone_t *zone) {
9441 REQUIRE(DNS_ZONE_VALID(zone));
9443 return (zone->maxxfrout);
9447 dns_zone_gettype(dns_zone_t *zone) {
9448 REQUIRE(DNS_ZONE_VALID(zone));
9450 return (zone->type);
9454 dns_zone_getorigin(dns_zone_t *zone) {
9455 REQUIRE(DNS_ZONE_VALID(zone));
9457 return (&zone->origin);
9461 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
9462 REQUIRE(DNS_ZONE_VALID(zone));
9465 if (zone->task != NULL)
9466 isc_task_detach(&zone->task);
9467 isc_task_attach(task, &zone->task);
9468 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9469 if (zone->db != NULL)
9470 dns_db_settask(zone->db, zone->task);
9471 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9476 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
9477 REQUIRE(DNS_ZONE_VALID(zone));
9478 isc_task_attach(zone->task, target);
9482 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
9483 REQUIRE(DNS_ZONE_VALID(zone));
9486 idlein = DNS_DEFAULT_IDLEIN;
9487 zone->idlein = idlein;
9491 dns_zone_getidlein(dns_zone_t *zone) {
9492 REQUIRE(DNS_ZONE_VALID(zone));
9494 return (zone->idlein);
9498 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
9499 REQUIRE(DNS_ZONE_VALID(zone));
9501 zone->idleout = idleout;
9505 dns_zone_getidleout(dns_zone_t *zone) {
9506 REQUIRE(DNS_ZONE_VALID(zone));
9508 return (zone->idleout);
9512 notify_done(isc_task_t *task, isc_event_t *event) {
9513 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9514 dns_notify_t *notify;
9515 isc_result_t result;
9516 dns_message_t *message = NULL;
9519 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9523 notify = event->ev_arg;
9524 REQUIRE(DNS_NOTIFY_VALID(notify));
9525 INSIST(task == notify->zone->task);
9527 isc_buffer_init(&buf, rcode, sizeof(rcode));
9528 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9530 result = revent->result;
9531 if (result == ISC_R_SUCCESS)
9532 result = dns_message_create(notify->zone->mctx,
9533 DNS_MESSAGE_INTENTPARSE, &message);
9534 if (result == ISC_R_SUCCESS)
9535 result = dns_request_getresponse(revent->request, message,
9536 DNS_MESSAGEPARSE_PRESERVEORDER);
9537 if (result == ISC_R_SUCCESS)
9538 result = dns_rcode_totext(message->rcode, &buf);
9539 if (result == ISC_R_SUCCESS)
9540 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9541 "notify response from %s: %.*s",
9542 addrbuf, (int)buf.used, rcode);
9544 notify_log(notify->zone, ISC_LOG_DEBUG(2),
9545 "notify to %s failed: %s", addrbuf,
9546 dns_result_totext(result));
9549 * Old bind's return formerr if they see a soa record. Retry w/o
9550 * the soa if we see a formerr and had sent a SOA.
9552 isc_event_free(&event);
9553 if (message != NULL && message->rcode == dns_rcode_formerr &&
9554 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
9555 notify->flags |= DNS_NOTIFY_NOSOA;
9556 dns_request_destroy(¬ify->request);
9557 result = notify_send_queue(notify);
9558 if (result != ISC_R_SUCCESS)
9559 notify_destroy(notify, ISC_FALSE);
9561 if (result == ISC_R_TIMEDOUT)
9562 notify_log(notify->zone, ISC_LOG_DEBUG(1),
9563 "notify to %s: retries exceeded", addrbuf);
9564 notify_destroy(notify, ISC_FALSE);
9566 if (message != NULL)
9567 dns_message_destroy(&message);
9571 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9572 isc_result_t result;
9574 REQUIRE(DNS_ZONE_VALID(zone));
9576 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9577 result = zone_replacedb(zone, db, dump);
9578 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9584 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9585 dns_dbversion_t *ver;
9586 isc_result_t result;
9587 unsigned int soacount = 0;
9588 unsigned int nscount = 0;
9591 * 'zone' and 'zonedb' locked by caller.
9593 REQUIRE(DNS_ZONE_VALID(zone));
9594 REQUIRE(LOCKED_ZONE(zone));
9596 result = zone_get_from_db(zone, db, &nscount, &soacount,
9597 NULL, NULL, NULL, NULL, NULL, NULL);
9598 if (result == ISC_R_SUCCESS) {
9599 if (soacount != 1) {
9600 dns_zone_log(zone, ISC_LOG_ERROR,
9601 "has %d SOA records", soacount);
9602 result = DNS_R_BADZONE;
9605 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
9606 result = DNS_R_BADZONE;
9608 if (result != ISC_R_SUCCESS)
9611 dns_zone_log(zone, ISC_LOG_ERROR,
9612 "retrieving SOA and NS records failed: %s",
9613 dns_result_totext(result));
9617 result = check_nsec3param(zone, db);
9618 if (result != ISC_R_SUCCESS)
9622 dns_db_currentversion(db, &ver);
9625 * The initial version of a slave zone is always dumped;
9626 * subsequent versions may be journaled instead if this
9627 * is enabled in the configuration.
9629 if (zone->db != NULL && zone->journal != NULL &&
9630 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
9631 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
9632 isc_uint32_t serial, oldserial;
9634 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
9636 result = dns_db_getsoaserial(db, ver, &serial);
9637 if (result != ISC_R_SUCCESS) {
9638 dns_zone_log(zone, ISC_LOG_ERROR,
9639 "ixfr-from-differences: unable to get "
9645 * This is checked in zone_postload() for master zones.
9647 result = zone_get_from_db(zone, zone->db, NULL, NULL,
9648 &oldserial, NULL, NULL, NULL, NULL,
9650 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9651 if (zone->type == dns_zone_slave &&
9652 !isc_serial_gt(serial, oldserial)) {
9653 isc_uint32_t serialmin, serialmax;
9654 serialmin = (oldserial + 1) & 0xffffffffU;
9655 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
9656 dns_zone_log(zone, ISC_LOG_ERROR,
9657 "ixfr-from-differences: failed: "
9658 "new serial (%u) out of range [%u - %u]",
9659 serial, serialmin, serialmax);
9660 result = ISC_R_RANGE;
9664 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
9666 if (result != ISC_R_SUCCESS)
9669 zone_needdump(zone, DNS_DUMP_DELAY);
9670 else if (zone->journalsize != -1) {
9671 result = dns_journal_compact(zone->mctx, zone->journal,
9672 serial, zone->journalsize);
9676 case ISC_R_NOTFOUND:
9677 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9678 "dns_journal_compact: %s",
9679 dns_result_totext(result));
9682 dns_zone_log(zone, ISC_LOG_ERROR,
9683 "dns_journal_compact failed: %s",
9684 dns_result_totext(result));
9689 if (dump && zone->masterfile != NULL) {
9690 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9691 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9692 "dumping new zone version");
9693 result = dns_db_dump2(db, ver, zone->masterfile,
9694 zone->masterformat);
9695 if (result != ISC_R_SUCCESS)
9699 * Update the time the zone was updated, so
9700 * dns_zone_load can avoid loading it when
9701 * the server is reloaded. If isc_time_now
9702 * fails for some reason, all that happens is
9703 * the timestamp is not updated.
9705 TIME_NOW(&zone->loadtime);
9708 if (dump && zone->journal != NULL) {
9710 * The in-memory database just changed, and
9711 * because 'dump' is set, it didn't change by
9712 * being loaded from disk. Also, we have not
9713 * journaled diffs for this change.
9714 * Therefore, the on-disk journal is missing
9715 * the deltas for this change. Since it can
9716 * no longer be used to bring the zone
9717 * up-to-date, it is useless and should be
9720 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9721 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9722 "removing journal file");
9723 if (remove(zone->journal) < 0 && errno != ENOENT) {
9724 char strbuf[ISC_STRERRORSIZE];
9725 isc__strerror(errno, strbuf, sizeof(strbuf));
9726 isc_log_write(dns_lctx,
9727 DNS_LOGCATEGORY_GENERAL,
9730 "unable to remove journal "
9732 zone->journal, strbuf);
9737 dns_db_closeversion(db, &ver, ISC_FALSE);
9739 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9740 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9741 "replacing zone database");
9743 if (zone->db != NULL)
9744 zone_detachdb(zone);
9745 zone_attachdb(zone, db);
9746 dns_db_settask(zone->db, zone->task);
9747 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
9748 return (ISC_R_SUCCESS);
9751 dns_db_closeversion(db, &ver, ISC_FALSE);
9755 /* The caller must hold the dblock as a writer. */
9757 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
9758 REQUIRE(zone->db == NULL && db != NULL);
9760 dns_db_attach(db, &zone->db);
9761 if (zone->acache != NULL) {
9762 isc_result_t result;
9763 result = dns_acache_setdb(zone->acache, db);
9764 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
9765 UNEXPECTED_ERROR(__FILE__, __LINE__,
9766 "dns_acache_setdb() failed: %s",
9767 isc_result_totext(result));
9772 /* The caller must hold the dblock as a writer. */
9774 zone_detachdb(dns_zone_t *zone) {
9775 REQUIRE(zone->db != NULL);
9777 if (zone->acache != NULL)
9778 (void)dns_acache_putdb(zone->acache, zone->db);
9779 dns_db_detach(&zone->db);
9783 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
9785 isc_boolean_t again = ISC_FALSE;
9786 unsigned int soacount;
9787 unsigned int nscount;
9788 isc_uint32_t serial, refresh, retry, expire, minimum;
9789 isc_result_t xfrresult = result;
9790 isc_boolean_t free_needed;
9792 REQUIRE(DNS_ZONE_VALID(zone));
9794 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9795 "zone transfer finished: %s", dns_result_totext(result));
9798 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
9799 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9800 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9805 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9807 case DNS_R_UPTODATE:
9808 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
9810 * Has the zone expired underneath us?
9812 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9813 if (zone->db == NULL) {
9814 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9819 * Update the zone structure's data from the actual
9824 INSIST(zone->db != NULL);
9825 result = zone_get_from_db(zone, zone->db, &nscount,
9826 &soacount, &serial, &refresh,
9827 &retry, &expire, &minimum, NULL);
9828 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9829 if (result == ISC_R_SUCCESS) {
9831 dns_zone_log(zone, ISC_LOG_ERROR,
9833 "has %d SOA record%s", soacount,
9834 (soacount != 0) ? "s" : "");
9836 dns_zone_log(zone, ISC_LOG_ERROR,
9838 "has no NS records");
9839 if (DNS_ZONE_FLAG(zone,
9840 DNS_ZONEFLG_HAVETIMERS)) {
9841 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9842 zone->retry = DNS_ZONE_DEFAULTRETRY;
9844 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9848 zone->refresh = RANGE(refresh, zone->minrefresh,
9850 zone->retry = RANGE(retry, zone->minretry,
9852 zone->expire = RANGE(expire,
9853 zone->refresh + zone->retry,
9855 zone->minimum = minimum;
9856 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9860 * Set our next update/expire times.
9862 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
9863 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
9864 zone->refreshtime = now;
9865 DNS_ZONE_TIME_ADD(&now, zone->expire,
9868 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
9869 &zone->refreshtime);
9870 DNS_ZONE_TIME_ADD(&now, zone->expire,
9873 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
9874 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
9875 if (zone->tsigkey != NULL) {
9876 char namebuf[DNS_NAME_FORMATSIZE];
9877 dns_name_format(&zone->tsigkey->name, namebuf,
9879 snprintf(buf, sizeof(buf), ": TSIG '%s'",
9883 dns_zone_log(zone, ISC_LOG_INFO,
9884 "transferred serial %u%s",
9889 * This is not necessary if we just performed a AXFR
9890 * however it is necessary for an IXFR / UPTODATE and
9891 * won't hurt with an AXFR.
9893 if (zone->masterfile != NULL || zone->journal != NULL) {
9894 result = ISC_R_FAILURE;
9895 if (zone->journal != NULL)
9896 result = isc_file_settime(zone->journal, &now);
9897 if (result != ISC_R_SUCCESS &&
9898 zone->masterfile != NULL)
9899 result = isc_file_settime(zone->masterfile,
9901 /* Someone removed the file from underneath us! */
9902 if (result == ISC_R_FILENOTFOUND &&
9903 zone->masterfile != NULL)
9904 zone_needdump(zone, DNS_DUMP_DELAY);
9905 else if (result != ISC_R_SUCCESS)
9906 dns_zone_log(zone, ISC_LOG_ERROR,
9907 "transfer: could not set file "
9908 "modification time of '%s': %s",
9910 dns_result_totext(result));
9913 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
9917 /* Force retry with AXFR. */
9918 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
9924 * Skip to next failed / untried master.
9928 } while (zone->curmaster < zone->masterscnt &&
9929 zone->mastersok[zone->curmaster]);
9932 if (zone->curmaster >= zone->masterscnt) {
9933 zone->curmaster = 0;
9934 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9935 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9936 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9937 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9938 while (zone->curmaster < zone->masterscnt &&
9939 zone->mastersok[zone->curmaster])
9943 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9945 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9948 inc_stats(zone, dns_zonestatscounter_xfrfail);
9951 zone_settimer(zone, &now);
9954 * If creating the transfer object failed, zone->xfr is NULL.
9955 * Otherwise, we are called as the done callback of a zone
9956 * transfer object that just entered its shutting-down
9957 * state. Since we are no longer responsible for shutting
9958 * it down, we can detach our reference.
9960 if (zone->xfr != NULL)
9961 dns_xfrin_detach(&zone->xfr);
9963 if (zone->tsigkey != NULL)
9964 dns_tsigkey_detach(&zone->tsigkey);
9967 * Handle any deferred journal compaction.
9969 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
9970 result = dns_journal_compact(zone->mctx, zone->journal,
9971 zone->compact_serial,
9976 case ISC_R_NOTFOUND:
9977 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9978 "dns_journal_compact: %s",
9979 dns_result_totext(result));
9982 dns_zone_log(zone, ISC_LOG_ERROR,
9983 "dns_journal_compact failed: %s",
9984 dns_result_totext(result));
9987 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9991 * This transfer finishing freed up a transfer quota slot.
9992 * Let any other zones waiting for quota have it.
9995 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9996 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
9997 zone->statelist = NULL;
9998 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
9999 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10003 * Retry with a different server if necessary.
10005 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10006 queue_soa_query(zone);
10008 INSIST(zone->irefs > 0);
10010 free_needed = exit_check(zone);
10017 zone_loaddone(void *arg, isc_result_t result) {
10018 static char me[] = "zone_loaddone";
10019 dns_load_t *load = arg;
10021 isc_result_t tresult;
10023 REQUIRE(DNS_LOAD_VALID(load));
10028 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
10029 if (tresult != ISC_R_SUCCESS &&
10030 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
10033 LOCK_ZONE(load->zone);
10034 (void)zone_postload(load->zone, load->db, load->loadtime, result);
10035 zonemgr_putio(&load->zone->readio);
10036 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
10038 * Leave the zone frozen if the reload fails.
10040 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
10041 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
10042 zone->update_disabled = ISC_FALSE;
10043 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
10044 UNLOCK_ZONE(load->zone);
10047 dns_db_detach(&load->db);
10048 if (load->zone->lctx != NULL)
10049 dns_loadctx_detach(&load->zone->lctx);
10050 dns_zone_idetach(&load->zone);
10051 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
10055 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
10056 REQUIRE(DNS_ZONE_VALID(zone));
10057 REQUIRE(table != NULL);
10058 REQUIRE(*table == NULL);
10061 if (zone->ssutable != NULL)
10062 dns_ssutable_attach(zone->ssutable, table);
10067 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
10068 REQUIRE(DNS_ZONE_VALID(zone));
10071 if (zone->ssutable != NULL)
10072 dns_ssutable_detach(&zone->ssutable);
10074 dns_ssutable_attach(table, &zone->ssutable);
10079 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
10080 REQUIRE(DNS_ZONE_VALID(zone));
10082 zone->sigvalidityinterval = interval;
10086 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
10087 REQUIRE(DNS_ZONE_VALID(zone));
10089 return (zone->sigvalidityinterval);
10093 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
10094 REQUIRE(DNS_ZONE_VALID(zone));
10096 zone->sigresigninginterval = interval;
10100 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
10101 REQUIRE(DNS_ZONE_VALID(zone));
10103 return (zone->sigresigninginterval);
10107 queue_xfrin(dns_zone_t *zone) {
10108 const char me[] = "queue_xfrin";
10109 isc_result_t result;
10110 dns_zonemgr_t *zmgr = zone->zmgr;
10114 INSIST(zone->statelist == NULL);
10116 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10117 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
10121 zone->statelist = &zmgr->waiting_for_xfrin;
10122 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10123 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10125 if (result == ISC_R_QUOTA) {
10126 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
10127 "zone transfer deferred due to quota");
10128 } else if (result != ISC_R_SUCCESS) {
10129 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
10130 "starting zone transfer: %s",
10131 isc_result_totext(result));
10136 * This event callback is called when a zone has received
10137 * any necessary zone transfer quota. This is the time
10138 * to go ahead and start the transfer.
10141 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
10142 isc_result_t result;
10143 dns_peer_t *peer = NULL;
10144 char master[ISC_SOCKADDR_FORMATSIZE];
10145 char source[ISC_SOCKADDR_FORMATSIZE];
10146 dns_rdatatype_t xfrtype;
10147 dns_zone_t *zone = event->ev_arg;
10148 isc_netaddr_t masterip;
10149 isc_sockaddr_t sourceaddr;
10150 isc_sockaddr_t masteraddr;
10152 const char *soa_before = "";
10156 INSIST(task == zone->task);
10158 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10159 result = ISC_R_CANCELED;
10165 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10166 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10167 &zone->sourceaddr, &now))
10169 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10170 dns_zone_log(zone, ISC_LOG_INFO,
10171 "got_transfer_quota: skipping zone transfer as "
10172 "master %s (source %s) is unreachable (cached)",
10174 result = ISC_R_CANCELED;
10178 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10179 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
10181 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10182 soa_before = "SOA before ";
10184 * Decide whether we should request IXFR or AXFR.
10186 if (zone->db == NULL) {
10187 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10188 "no database exists yet, requesting AXFR of "
10189 "initial version from %s", master);
10190 xfrtype = dns_rdatatype_axfr;
10191 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
10192 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
10193 "set, requesting %sAXFR from %s", soa_before,
10195 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10196 xfrtype = dns_rdatatype_soa;
10198 xfrtype = dns_rdatatype_axfr;
10199 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
10200 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10201 "forced reload, requesting AXFR of "
10202 "initial version from %s", master);
10203 xfrtype = dns_rdatatype_axfr;
10204 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
10205 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10206 "retrying with AXFR from %s due to "
10207 "previous IXFR failure", master);
10208 xfrtype = dns_rdatatype_axfr;
10210 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
10213 isc_boolean_t use_ixfr = ISC_TRUE;
10214 if (peer != NULL &&
10215 dns_peer_getrequestixfr(peer, &use_ixfr) ==
10217 ; /* Using peer setting */
10219 use_ixfr = zone->view->requestixfr;
10221 if (use_ixfr == ISC_FALSE) {
10222 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10223 "IXFR disabled, requesting %sAXFR from %s",
10224 soa_before, master);
10225 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10226 xfrtype = dns_rdatatype_soa;
10228 xfrtype = dns_rdatatype_axfr;
10230 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10231 "requesting IXFR from %s", master);
10232 xfrtype = dns_rdatatype_ixfr;
10237 * Determine if we should attempt to sign the request with TSIG.
10239 result = ISC_R_NOTFOUND;
10241 * First, look for a tsig key in the master statement, then
10242 * try for a server key.
10244 if ((zone->masterkeynames != NULL) &&
10245 (zone->masterkeynames[zone->curmaster] != NULL)) {
10246 dns_view_t *view = dns_zone_getview(zone);
10247 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10248 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
10250 if (zone->tsigkey == NULL)
10251 result = dns_view_getpeertsig(zone->view, &masterip,
10254 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10255 dns_zone_log(zone, ISC_LOG_ERROR,
10256 "could not get TSIG key for zone transfer: %s",
10257 isc_result_totext(result));
10261 masteraddr = zone->masteraddr;
10262 sourceaddr = zone->sourceaddr;
10264 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
10265 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
10266 zone->tsigkey, zone->mctx,
10267 zone->zmgr->timermgr, zone->zmgr->socketmgr,
10268 zone->task, zone_xfrdone, &zone->xfr);
10269 if (result == ISC_R_SUCCESS) {
10271 if (xfrtype == dns_rdatatype_axfr) {
10272 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10273 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
10275 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
10276 } else if (xfrtype == dns_rdatatype_ixfr) {
10277 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10278 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
10280 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
10286 * Any failure in this function is handled like a failed
10287 * zone transfer. This ensures that we get removed from
10288 * zmgr->xfrin_in_progress.
10290 if (result != ISC_R_SUCCESS)
10291 zone_xfrdone(zone, result);
10293 isc_event_free(&event);
10297 * Update forwarding support.
10301 forward_destroy(dns_forward_t *forward) {
10303 forward->magic = 0;
10304 if (forward->request != NULL)
10305 dns_request_destroy(&forward->request);
10306 if (forward->msgbuf != NULL)
10307 isc_buffer_free(&forward->msgbuf);
10308 if (forward->zone != NULL) {
10309 LOCK(&forward->zone->lock);
10310 if (ISC_LINK_LINKED(forward, link))
10311 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
10312 UNLOCK(&forward->zone->lock);
10313 dns_zone_idetach(&forward->zone);
10315 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
10318 static isc_result_t
10319 sendtomaster(dns_forward_t *forward) {
10320 isc_result_t result;
10321 isc_sockaddr_t src;
10323 LOCK_ZONE(forward->zone);
10325 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
10326 UNLOCK_ZONE(forward->zone);
10327 return (ISC_R_CANCELED);
10330 if (forward->which >= forward->zone->masterscnt) {
10331 UNLOCK_ZONE(forward->zone);
10332 return (ISC_R_NOMORE);
10335 forward->addr = forward->zone->masters[forward->which];
10337 * Always use TCP regardless of whether the original update
10339 * XXX The timeout may but a bit small if we are far down a
10340 * transfer graph and the master has to try several masters.
10342 switch (isc_sockaddr_pf(&forward->addr)) {
10344 src = forward->zone->xfrsource4;
10347 src = forward->zone->xfrsource6;
10350 result = ISC_R_NOTIMPLEMENTED;
10353 result = dns_request_createraw(forward->zone->view->requestmgr,
10355 &src, &forward->addr,
10356 DNS_REQUESTOPT_TCP, 15 /* XXX */,
10357 forward->zone->task,
10358 forward_callback, forward,
10359 &forward->request);
10360 if (result == ISC_R_SUCCESS) {
10361 if (!ISC_LINK_LINKED(forward, link))
10362 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
10366 UNLOCK_ZONE(forward->zone);
10371 forward_callback(isc_task_t *task, isc_event_t *event) {
10372 const char me[] = "forward_callback";
10373 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10374 dns_message_t *msg = NULL;
10375 char master[ISC_SOCKADDR_FORMATSIZE];
10376 isc_result_t result;
10377 dns_forward_t *forward;
10382 forward = revent->ev_arg;
10383 INSIST(DNS_FORWARD_VALID(forward));
10384 zone = forward->zone;
10385 INSIST(DNS_ZONE_VALID(zone));
10389 isc_sockaddr_format(&forward->addr, master, sizeof(master));
10391 if (revent->result != ISC_R_SUCCESS) {
10392 dns_zone_log(zone, ISC_LOG_INFO,
10393 "could not forward dynamic update to %s: %s",
10394 master, dns_result_totext(revent->result));
10398 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10399 if (result != ISC_R_SUCCESS)
10402 result = dns_request_getresponse(revent->request, msg,
10403 DNS_MESSAGEPARSE_PRESERVEORDER |
10404 DNS_MESSAGEPARSE_CLONEBUFFER);
10405 if (result != ISC_R_SUCCESS)
10408 switch (msg->rcode) {
10410 * Pass these rcodes back to client.
10412 case dns_rcode_noerror:
10413 case dns_rcode_yxdomain:
10414 case dns_rcode_yxrrset:
10415 case dns_rcode_nxrrset:
10416 case dns_rcode_refused:
10417 case dns_rcode_nxdomain:
10420 /* These should not occur if the masters/zone are valid. */
10421 case dns_rcode_notzone:
10422 case dns_rcode_notauth: {
10426 isc_buffer_init(&rb, rcode, sizeof(rcode));
10427 (void)dns_rcode_totext(msg->rcode, &rb);
10428 dns_zone_log(zone, ISC_LOG_WARNING,
10429 "forwarding dynamic update: "
10430 "unexpected response: master %s returned: %.*s",
10431 master, (int)rb.used, rcode);
10435 /* Try another server for these rcodes. */
10436 case dns_rcode_formerr:
10437 case dns_rcode_servfail:
10438 case dns_rcode_notimp:
10439 case dns_rcode_badvers:
10444 /* call callback */
10445 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
10447 dns_request_destroy(&forward->request);
10448 forward_destroy(forward);
10449 isc_event_free(&event);
10454 dns_message_destroy(&msg);
10455 isc_event_free(&event);
10457 dns_request_destroy(&forward->request);
10458 result = sendtomaster(forward);
10459 if (result != ISC_R_SUCCESS) {
10460 /* call callback */
10461 dns_zone_log(zone, ISC_LOG_DEBUG(3),
10462 "exhausted dynamic update forwarder list");
10463 (forward->callback)(forward->callback_arg, result, NULL);
10464 forward_destroy(forward);
10469 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
10470 dns_updatecallback_t callback, void *callback_arg)
10472 dns_forward_t *forward;
10473 isc_result_t result;
10476 REQUIRE(DNS_ZONE_VALID(zone));
10477 REQUIRE(msg != NULL);
10478 REQUIRE(callback != NULL);
10480 forward = isc_mem_get(zone->mctx, sizeof(*forward));
10481 if (forward == NULL)
10482 return (ISC_R_NOMEMORY);
10484 forward->request = NULL;
10485 forward->zone = NULL;
10486 forward->msgbuf = NULL;
10487 forward->which = 0;
10489 forward->callback = callback;
10490 forward->callback_arg = callback_arg;
10491 ISC_LINK_INIT(forward, link);
10492 forward->magic = FORWARD_MAGIC;
10494 mr = dns_message_getrawmessage(msg);
10496 result = ISC_R_UNEXPECTEDEND;
10500 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
10501 if (result != ISC_R_SUCCESS)
10503 result = isc_buffer_copyregion(forward->msgbuf, mr);
10504 if (result != ISC_R_SUCCESS)
10507 isc_mem_attach(zone->mctx, &forward->mctx);
10508 dns_zone_iattach(zone, &forward->zone);
10509 result = sendtomaster(forward);
10512 if (result != ISC_R_SUCCESS) {
10513 forward_destroy(forward);
10519 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
10520 REQUIRE(DNS_ZONE_VALID(zone));
10521 REQUIRE(next != NULL && *next == NULL);
10523 *next = ISC_LIST_NEXT(zone, link);
10525 return (ISC_R_NOMORE);
10527 return (ISC_R_SUCCESS);
10531 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
10532 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10533 REQUIRE(first != NULL && *first == NULL);
10535 *first = ISC_LIST_HEAD(zmgr->zones);
10536 if (*first == NULL)
10537 return (ISC_R_NOMORE);
10539 return (ISC_R_SUCCESS);
10547 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
10548 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
10549 dns_zonemgr_t **zmgrp)
10551 dns_zonemgr_t *zmgr;
10552 isc_result_t result;
10553 isc_interval_t interval;
10555 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
10557 return (ISC_R_NOMEMORY);
10560 isc_mem_attach(mctx, &zmgr->mctx);
10561 zmgr->taskmgr = taskmgr;
10562 zmgr->timermgr = timermgr;
10563 zmgr->socketmgr = socketmgr;
10564 zmgr->zonetasks = NULL;
10567 ISC_LIST_INIT(zmgr->zones);
10568 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
10569 ISC_LIST_INIT(zmgr->xfrin_in_progress);
10570 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
10571 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
10572 if (result != ISC_R_SUCCESS)
10575 zmgr->transfersin = 10;
10576 zmgr->transfersperns = 2;
10578 /* Unreachable lock. */
10579 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
10580 if (result != ISC_R_SUCCESS)
10583 /* Create a single task for queueing of SOA queries. */
10584 result = isc_task_create(taskmgr, 1, &zmgr->task);
10585 if (result != ISC_R_SUCCESS)
10588 isc_task_setname(zmgr->task, "zmgr", zmgr);
10589 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
10591 if (result != ISC_R_SUCCESS)
10594 /* default to 20 refresh queries / notifies per second. */
10595 isc_interval_set(&interval, 0, 1000000000/2);
10596 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
10597 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10598 isc_ratelimiter_setpertic(zmgr->rl, 10);
10601 zmgr->ioactive = 0;
10602 ISC_LIST_INIT(zmgr->high);
10603 ISC_LIST_INIT(zmgr->low);
10605 result = isc_mutex_init(&zmgr->iolock);
10606 if (result != ISC_R_SUCCESS)
10609 zmgr->magic = ZONEMGR_MAGIC;
10612 return (ISC_R_SUCCESS);
10616 DESTROYLOCK(&zmgr->iolock);
10619 isc_ratelimiter_detach(&zmgr->rl);
10621 isc_task_detach(&zmgr->task);
10623 isc_rwlock_destroy(&zmgr->urlock);
10625 isc_rwlock_destroy(&zmgr->rwlock);
10627 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10628 isc_mem_detach(&mctx);
10633 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10634 isc_result_t result;
10636 REQUIRE(DNS_ZONE_VALID(zone));
10637 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10639 if (zmgr->zonetasks == NULL)
10640 return (ISC_R_FAILURE);
10642 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10644 REQUIRE(zone->task == NULL);
10645 REQUIRE(zone->timer == NULL);
10646 REQUIRE(zone->zmgr == NULL);
10648 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
10651 * Set the task name. The tag will arbitrarily point to one
10652 * of the zones sharing the task (in practice, the one
10653 * to be managed last).
10655 isc_task_setname(zone->task, "zone", zone);
10657 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
10659 zone->task, zone_timer, zone,
10662 if (result != ISC_R_SUCCESS)
10666 * The timer "holds" a iref.
10669 INSIST(zone->irefs != 0);
10671 ISC_LIST_APPEND(zmgr->zones, zone, link);
10678 isc_task_detach(&zone->task);
10682 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10687 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10688 isc_boolean_t free_now = ISC_FALSE;
10690 REQUIRE(DNS_ZONE_VALID(zone));
10691 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10692 REQUIRE(zone->zmgr == zmgr);
10694 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10697 ISC_LIST_UNLINK(zmgr->zones, zone, link);
10700 if (zmgr->refs == 0)
10701 free_now = ISC_TRUE;
10704 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10707 zonemgr_free(zmgr);
10708 ENSURE(zone->zmgr == NULL);
10712 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
10713 REQUIRE(DNS_ZONEMGR_VALID(source));
10714 REQUIRE(target != NULL && *target == NULL);
10716 RWLOCK(&source->rwlock, isc_rwlocktype_write);
10717 REQUIRE(source->refs > 0);
10719 INSIST(source->refs > 0);
10720 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
10725 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
10726 dns_zonemgr_t *zmgr;
10727 isc_boolean_t free_now = ISC_FALSE;
10729 REQUIRE(zmgrp != NULL);
10731 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10733 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10735 if (zmgr->refs == 0)
10736 free_now = ISC_TRUE;
10737 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10740 zonemgr_free(zmgr);
10745 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
10748 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10750 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10751 for (p = ISC_LIST_HEAD(zmgr->zones);
10753 p = ISC_LIST_NEXT(p, link))
10755 dns_zone_maintenance(p);
10757 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10760 * Recent configuration changes may have increased the
10761 * amount of available transfers quota. Make sure any
10762 * transfers currently blocked on quota get started if
10765 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10766 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10767 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10768 return (ISC_R_SUCCESS);
10772 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
10774 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10776 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10777 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10778 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10782 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
10785 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10787 isc_ratelimiter_shutdown(zmgr->rl);
10789 if (zmgr->task != NULL)
10790 isc_task_destroy(&zmgr->task);
10791 if (zmgr->zonetasks != NULL)
10792 isc_taskpool_destroy(&zmgr->zonetasks);
10794 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10795 for (zone = ISC_LIST_HEAD(zmgr->zones);
10797 zone = ISC_LIST_NEXT(zone, link))
10800 forward_cancel(zone);
10803 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10807 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
10808 isc_result_t result;
10809 int ntasks = num_zones / 100;
10810 isc_taskpool_t *pool = NULL;
10812 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10815 * For anything fewer than 1000 zones we use 10 tasks in
10816 * the task pool. More than that, and we'll scale at one
10817 * task per 100 zones.
10822 /* Create or resize the zone task pool. */
10823 if (zmgr->zonetasks == NULL)
10824 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
10827 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
10829 if (result == ISC_R_SUCCESS)
10830 zmgr->zonetasks = pool;
10836 zonemgr_free(dns_zonemgr_t *zmgr) {
10839 INSIST(zmgr->refs == 0);
10840 INSIST(ISC_LIST_EMPTY(zmgr->zones));
10844 DESTROYLOCK(&zmgr->iolock);
10845 isc_ratelimiter_detach(&zmgr->rl);
10847 isc_rwlock_destroy(&zmgr->urlock);
10848 isc_rwlock_destroy(&zmgr->rwlock);
10850 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10851 isc_mem_detach(&mctx);
10855 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10856 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10858 zmgr->transfersin = value;
10862 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
10863 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10865 return (zmgr->transfersin);
10869 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10870 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10872 zmgr->transfersperns = value;
10876 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
10877 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10879 return (zmgr->transfersperns);
10883 * Try to start a new incoming zone transfer to fill a quota
10884 * slot that was just vacated.
10887 * The zone manager is locked by the caller.
10890 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
10894 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
10898 isc_result_t result;
10899 next = ISC_LIST_NEXT(zone, statelink);
10900 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10901 if (result == ISC_R_SUCCESS) {
10905 * We successfully filled the slot. We're done.
10908 } else if (result == ISC_R_QUOTA) {
10910 * Not enough quota. This is probably the per-server
10911 * quota, because we usually get called when a unit of
10912 * global quota has just been freed. Try the next
10913 * zone, it may succeed if it uses another master.
10917 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10918 "starting zone transfer: %s",
10919 isc_result_totext(result));
10926 * Try to start an incoming zone transfer for 'zone', quota permitting.
10929 * The zone manager is locked by the caller.
10932 * ISC_R_SUCCESS There was enough quota and we attempted to
10933 * start a transfer. zone_xfrdone() has been or will
10935 * ISC_R_QUOTA Not enough quota.
10938 static isc_result_t
10939 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10940 dns_peer_t *peer = NULL;
10941 isc_netaddr_t masterip;
10942 isc_uint32_t nxfrsin, nxfrsperns;
10944 isc_uint32_t maxtransfersin, maxtransfersperns;
10948 * If we are exiting just pretend we got quota so the zone will
10949 * be cleaned up in the zone's task context.
10952 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10958 * Find any configured information about the server we'd
10959 * like to transfer this zone from.
10961 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10962 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
10966 * Determine the total maximum number of simultaneous
10967 * transfers allowed, and the maximum for this specific
10970 maxtransfersin = zmgr->transfersin;
10971 maxtransfersperns = zmgr->transfersperns;
10973 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
10976 * Count the total number of transfers that are in progress,
10977 * and the number of transfers in progress from this master.
10978 * We linearly scan a list of all transfers; if this turns
10979 * out to be too slow, we could hash on the master address.
10981 nxfrsin = nxfrsperns = 0;
10982 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
10984 x = ISC_LIST_NEXT(x, statelink))
10989 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
10993 if (isc_netaddr_equal(&xip, &masterip))
10997 /* Enforce quota. */
10998 if (nxfrsin >= maxtransfersin)
10999 return (ISC_R_QUOTA);
11001 if (nxfrsperns >= maxtransfersperns)
11002 return (ISC_R_QUOTA);
11006 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
11007 * list and send it an event to let it start the actual transfer in the
11008 * context of its own task.
11010 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
11011 got_transfer_quota, zone, sizeof(isc_event_t));
11013 return (ISC_R_NOMEMORY);
11016 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
11017 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
11018 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
11019 zone->statelist = &zmgr->xfrin_in_progress;
11020 isc_task_send(zone->task, &e);
11021 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
11024 return (ISC_R_SUCCESS);
11028 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
11030 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11031 REQUIRE(iolimit > 0);
11033 zmgr->iolimit = iolimit;
11037 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
11039 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11041 return (zmgr->iolimit);
11045 * Get permission to request a file handle from the OS.
11046 * An event will be sent to action when one is available.
11047 * There are two queues available (high and low), the high
11048 * queue will be serviced before the low one.
11050 * zonemgr_putio() must be called after the event is delivered to
11054 static isc_result_t
11055 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
11056 isc_task_t *task, isc_taskaction_t action, void *arg,
11060 isc_boolean_t queue;
11062 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11063 REQUIRE(iop != NULL && *iop == NULL);
11065 io = isc_mem_get(zmgr->mctx, sizeof(*io));
11067 return (ISC_R_NOMEMORY);
11068 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
11069 action, arg, sizeof(*io->event));
11070 if (io->event == NULL) {
11071 isc_mem_put(zmgr->mctx, io, sizeof(*io));
11072 return (ISC_R_NOMEMORY);
11077 isc_task_attach(task, &io->task);
11078 ISC_LINK_INIT(io, link);
11079 io->magic = IO_MAGIC;
11081 LOCK(&zmgr->iolock);
11083 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
11086 ISC_LIST_APPEND(zmgr->high, io, link);
11088 ISC_LIST_APPEND(zmgr->low, io, link);
11090 UNLOCK(&zmgr->iolock);
11094 isc_task_send(io->task, &io->event);
11096 return (ISC_R_SUCCESS);
11100 zonemgr_putio(dns_io_t **iop) {
11103 dns_zonemgr_t *zmgr;
11105 REQUIRE(iop != NULL);
11107 REQUIRE(DNS_IO_VALID(io));
11111 INSIST(!ISC_LINK_LINKED(io, link));
11112 INSIST(io->event == NULL);
11115 isc_task_detach(&io->task);
11117 isc_mem_put(zmgr->mctx, io, sizeof(*io));
11119 LOCK(&zmgr->iolock);
11120 INSIST(zmgr->ioactive > 0);
11122 next = HEAD(zmgr->high);
11124 next = HEAD(zmgr->low);
11125 if (next != NULL) {
11127 ISC_LIST_UNLINK(zmgr->high, next, link);
11129 ISC_LIST_UNLINK(zmgr->low, next, link);
11130 INSIST(next->event != NULL);
11132 UNLOCK(&zmgr->iolock);
11134 isc_task_send(next->task, &next->event);
11138 zonemgr_cancelio(dns_io_t *io) {
11139 isc_boolean_t send_event = ISC_FALSE;
11141 REQUIRE(DNS_IO_VALID(io));
11144 * If we are queued to be run then dequeue.
11146 LOCK(&io->zmgr->iolock);
11147 if (ISC_LINK_LINKED(io, link)) {
11149 ISC_LIST_UNLINK(io->zmgr->high, io, link);
11151 ISC_LIST_UNLINK(io->zmgr->low, io, link);
11153 send_event = ISC_TRUE;
11154 INSIST(io->event != NULL);
11156 UNLOCK(&io->zmgr->iolock);
11158 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
11159 isc_task_send(io->task, &io->event);
11164 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
11167 isc_result_t result;
11169 buflen = strlen(path) + strlen(templat) + 2;
11171 buf = isc_mem_get(zone->mctx, buflen);
11175 result = isc_file_template(path, templat, buf, buflen);
11176 if (result != ISC_R_SUCCESS)
11179 result = isc_file_renameunique(path, buf);
11180 if (result != ISC_R_SUCCESS)
11183 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
11184 "renaming file to '%s' for failure analysis and "
11185 "retransferring.", path, buf);
11188 isc_mem_put(zone->mctx, buf, buflen);
11192 /* Hook for ondestroy notification from a database. */
11195 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
11196 dns_db_t *db = event->sender;
11199 isc_event_free(&event);
11201 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11202 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11203 "database (%p) destroyed", (void*) db);
11208 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
11209 isc_interval_t interval;
11210 isc_uint32_t s, ns;
11211 isc_uint32_t pertic;
11212 isc_result_t result;
11214 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11223 } else if (value <= 10) {
11225 ns = 1000000000 / value;
11229 ns = (1000000000 / value) * 10;
11233 isc_interval_set(&interval, s, ns);
11234 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
11235 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11236 isc_ratelimiter_setpertic(zmgr->rl, pertic);
11238 zmgr->serialqueryrate = value;
11242 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
11243 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11245 return (zmgr->serialqueryrate);
11249 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11250 isc_sockaddr_t *local, isc_time_t *now)
11253 isc_rwlocktype_t locktype;
11254 isc_result_t result;
11255 isc_uint32_t seconds = isc_time_seconds(now);
11257 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11259 locktype = isc_rwlocktype_read;
11260 RWLOCK(&zmgr->urlock, locktype);
11261 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11262 if (zmgr->unreachable[i].expire >= seconds &&
11263 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11264 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
11265 result = isc_rwlock_tryupgrade(&zmgr->urlock);
11266 if (result == ISC_R_SUCCESS) {
11267 locktype = isc_rwlocktype_write;
11268 zmgr->unreachable[i].last = seconds;
11273 RWUNLOCK(&zmgr->urlock, locktype);
11274 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
11278 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11279 isc_sockaddr_t *local)
11282 isc_rwlocktype_t locktype;
11283 isc_result_t result;
11285 char master[ISC_SOCKADDR_FORMATSIZE];
11286 char source[ISC_SOCKADDR_FORMATSIZE];
11288 isc_sockaddr_format(remote, master, sizeof(master));
11289 isc_sockaddr_format(local, source, sizeof(source));
11291 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11293 locktype = isc_rwlocktype_read;
11294 RWLOCK(&zmgr->urlock, locktype);
11295 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11296 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11297 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
11298 result = isc_rwlock_tryupgrade(&zmgr->urlock);
11299 if (result == ISC_R_SUCCESS) {
11300 locktype = isc_rwlocktype_write;
11301 zmgr->unreachable[i].expire = 0;
11302 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11303 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
11304 "master %s (source %s) deleted "
11305 "from unreachable cache",
11311 RWUNLOCK(&zmgr->urlock, locktype);
11315 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11316 isc_sockaddr_t *local, isc_time_t *now)
11318 isc_uint32_t seconds = isc_time_seconds(now);
11319 isc_uint32_t last = seconds;
11320 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
11322 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11324 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
11325 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11326 /* Existing entry? */
11327 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11328 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
11331 if (zmgr->unreachable[i].expire < seconds)
11333 /* Least recently used slot? */
11334 if (zmgr->unreachable[i].last < last) {
11335 last = zmgr->unreachable[i].last;
11339 if (i < UNREACH_CHACHE_SIZE) {
11341 * Found a existing entry. Update the expire timer and
11342 * last usage timestamps.
11344 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
11345 zmgr->unreachable[i].last = seconds;
11346 } else if (slot != UNREACH_CHACHE_SIZE) {
11348 * Found a empty slot. Add a new entry to the cache.
11350 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
11351 zmgr->unreachable[slot].last = seconds;
11352 zmgr->unreachable[slot].remote = *remote;
11353 zmgr->unreachable[slot].local = *local;
11356 * Replace the least recently used entry in the cache.
11358 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
11359 zmgr->unreachable[oldest].last = seconds;
11360 zmgr->unreachable[oldest].remote = *remote;
11361 zmgr->unreachable[oldest].local = *local;
11363 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
11367 dns_zone_forcereload(dns_zone_t *zone) {
11368 REQUIRE(DNS_ZONE_VALID(zone));
11370 if (zone->type == dns_zone_master)
11374 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
11376 dns_zone_refresh(zone);
11380 dns_zone_isforced(dns_zone_t *zone) {
11381 REQUIRE(DNS_ZONE_VALID(zone));
11383 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
11387 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
11389 * This function is obsoleted.
11393 return (ISC_R_NOTIMPLEMENTED);
11397 dns_zone_getstatscounters(dns_zone_t *zone) {
11399 * This function is obsoleted.
11406 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
11407 REQUIRE(DNS_ZONE_VALID(zone));
11408 REQUIRE(zone->stats == NULL);
11411 zone->stats = NULL;
11412 isc_stats_attach(stats, &zone->stats);
11417 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
11418 REQUIRE(DNS_ZONE_VALID(zone));
11421 if (zone->requeststats_on && stats == NULL)
11422 zone->requeststats_on = ISC_FALSE;
11423 else if (!zone->requeststats_on && stats != NULL) {
11424 if (zone->requeststats == NULL) {
11425 isc_stats_attach(stats, &zone->requeststats);
11426 zone->requeststats_on = ISC_TRUE;
11435 dns_zone_getrequeststats(dns_zone_t *zone) {
11437 * We don't lock zone for efficiency reason. This is not catastrophic
11438 * because requeststats must always be valid when requeststats_on is
11440 * Some counters may be incremented while requeststats_on is becoming
11441 * false, or some cannot be incremented just after the statistics are
11442 * installed, but it shouldn't matter much in practice.
11444 if (zone->requeststats_on)
11445 return (zone->requeststats);
11451 dns_zone_dialup(dns_zone_t *zone) {
11453 REQUIRE(DNS_ZONE_VALID(zone));
11455 zone_debuglog(zone, "dns_zone_dialup", 3,
11456 "notify = %d, refresh = %d",
11457 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
11458 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
11460 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
11461 dns_zone_notify(zone);
11462 if (zone->type != dns_zone_master &&
11463 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11464 dns_zone_refresh(zone);
11468 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
11469 REQUIRE(DNS_ZONE_VALID(zone));
11472 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
11473 DNS_ZONEFLG_DIALREFRESH |
11474 DNS_ZONEFLG_NOREFRESH);
11476 case dns_dialuptype_no:
11478 case dns_dialuptype_yes:
11479 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
11480 DNS_ZONEFLG_DIALREFRESH |
11481 DNS_ZONEFLG_NOREFRESH));
11483 case dns_dialuptype_notify:
11484 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11486 case dns_dialuptype_notifypassive:
11487 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11488 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11490 case dns_dialuptype_refresh:
11491 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
11492 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11494 case dns_dialuptype_passive:
11495 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11504 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
11505 isc_result_t result = ISC_R_SUCCESS;
11507 REQUIRE(DNS_ZONE_VALID(zone));
11510 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
11517 dns_zone_getkeydirectory(dns_zone_t *zone) {
11518 REQUIRE(DNS_ZONE_VALID(zone));
11520 return (zone->keydirectory);
11524 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
11526 unsigned int count = 0;
11528 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11530 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11532 case DNS_ZONESTATE_XFERRUNNING:
11533 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
11535 zone = ISC_LIST_NEXT(zone, statelink))
11538 case DNS_ZONESTATE_XFERDEFERRED:
11539 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
11541 zone = ISC_LIST_NEXT(zone, statelink))
11544 case DNS_ZONESTATE_SOAQUERY:
11545 for (zone = ISC_LIST_HEAD(zmgr->zones);
11547 zone = ISC_LIST_NEXT(zone, link))
11548 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
11551 case DNS_ZONESTATE_ANY:
11552 for (zone = ISC_LIST_HEAD(zmgr->zones);
11554 zone = ISC_LIST_NEXT(zone, link)) {
11555 dns_view_t *view = zone->view;
11556 if (view != NULL && strcmp(view->name, "_bind") == 0)
11565 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11571 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
11572 isc_boolean_t ok = ISC_TRUE;
11573 isc_boolean_t fail = ISC_FALSE;
11574 char namebuf[DNS_NAME_FORMATSIZE];
11575 char namebuf2[DNS_NAME_FORMATSIZE];
11576 char typebuf[DNS_RDATATYPE_FORMATSIZE];
11577 int level = ISC_LOG_WARNING;
11580 REQUIRE(DNS_ZONE_VALID(zone));
11582 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
11583 return (ISC_R_SUCCESS);
11585 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
11586 level = ISC_LOG_ERROR;
11590 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
11592 dns_name_format(name, namebuf, sizeof(namebuf));
11593 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11594 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
11595 dns_result_totext(DNS_R_BADOWNERNAME));
11597 return (DNS_R_BADOWNERNAME);
11600 dns_name_init(&bad, NULL);
11601 ok = dns_rdata_checknames(rdata, name, &bad);
11603 dns_name_format(name, namebuf, sizeof(namebuf));
11604 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
11605 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11606 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
11607 namebuf2, dns_result_totext(DNS_R_BADNAME));
11609 return (DNS_R_BADNAME);
11612 return (ISC_R_SUCCESS);
11616 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
11617 REQUIRE(DNS_ZONE_VALID(zone));
11618 zone->checkmx = checkmx;
11622 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
11623 REQUIRE(DNS_ZONE_VALID(zone));
11624 zone->checksrv = checksrv;
11628 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
11629 REQUIRE(DNS_ZONE_VALID(zone));
11630 zone->checkns = checkns;
11634 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
11635 REQUIRE(DNS_ZONE_VALID(zone));
11638 zone->isself = isself;
11639 zone->isselfarg = arg;
11644 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
11645 REQUIRE(DNS_ZONE_VALID(zone));
11648 zone->notifydelay = delay;
11653 dns_zone_getnotifydelay(dns_zone_t *zone) {
11654 REQUIRE(DNS_ZONE_VALID(zone));
11656 return (zone->notifydelay);
11660 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
11661 isc_uint16_t keyid, isc_boolean_t delete)
11663 isc_result_t result;
11664 REQUIRE(DNS_ZONE_VALID(zone));
11666 dns_zone_log(zone, ISC_LOG_NOTICE,
11667 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
11670 result = zone_signwithkey(zone, algorithm, keyid, delete);
11676 static const char *hex = "0123456789ABCDEF";
11679 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
11680 isc_result_t result;
11681 char salt[255*2+1];
11684 REQUIRE(DNS_ZONE_VALID(zone));
11686 if (nsec3param->salt_length != 0) {
11687 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
11688 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
11689 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
11690 salt[j++] = hex[nsec3param->salt[i] & 0xf];
11695 dns_zone_log(zone, ISC_LOG_NOTICE,
11696 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
11697 nsec3param->hash, nsec3param->iterations,
11700 result = zone_addnsec3chain(zone, nsec3param);
11707 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
11708 REQUIRE(DNS_ZONE_VALID(zone));
11712 zone->nodes = nodes;
11716 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
11717 REQUIRE(DNS_ZONE_VALID(zone));
11720 * We treat signatures as a signed value so explicitly
11721 * limit its range here.
11723 if (signatures > ISC_INT32_MAX)
11724 signatures = ISC_INT32_MAX;
11725 else if (signatures == 0)
11727 zone->signatures = signatures;
11731 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
11732 REQUIRE(DNS_ZONE_VALID(zone));
11733 zone->privatetype = type;
11737 dns_zone_getprivatetype(dns_zone_t *zone) {
11738 REQUIRE(DNS_ZONE_VALID(zone));
11739 return (zone->privatetype);
11742 static isc_result_t
11743 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
11744 isc_boolean_t delete)
11746 dns_signing_t *signing;
11747 dns_signing_t *current;
11748 isc_result_t result = ISC_R_SUCCESS;
11751 signing = isc_mem_get(zone->mctx, sizeof *signing);
11752 if (signing == NULL)
11753 return (ISC_R_NOMEMORY);
11755 signing->magic = 0;
11756 signing->db = NULL;
11757 signing->dbiterator = NULL;
11758 signing->algorithm = algorithm;
11759 signing->keyid = keyid;
11760 signing->delete = delete;
11761 signing->done = ISC_FALSE;
11765 for (current = ISC_LIST_HEAD(zone->signing);
11767 current = ISC_LIST_NEXT(current, link)) {
11768 if (current->db == zone->db &&
11769 current->algorithm == signing->algorithm &&
11770 current->keyid == signing->keyid) {
11771 if (current->delete != signing->delete)
11772 current->done = ISC_TRUE;
11778 if (zone->db != NULL) {
11779 dns_db_attach(zone->db, &signing->db);
11780 result = dns_db_createiterator(signing->db, 0,
11781 &signing->dbiterator);
11783 if (result == ISC_R_SUCCESS)
11784 result = dns_dbiterator_first(signing->dbiterator);
11785 if (result == ISC_R_SUCCESS) {
11786 dns_dbiterator_pause(signing->dbiterator);
11787 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
11789 if (isc_time_isepoch(&zone->signingtime)) {
11790 zone->signingtime = now;
11791 if (zone->task != NULL)
11792 zone_settimer(zone, &now);
11796 result = ISC_R_NOTFOUND;
11799 if (signing != NULL) {
11800 if (signing->db != NULL)
11801 dns_db_detach(&signing->db);
11802 if (signing->dbiterator != NULL)
11803 dns_dbiterator_destroy(&signing->dbiterator);
11804 isc_mem_put(zone->mctx, signing, sizeof *signing);