2 * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: zone.c,v 1.483.36.33 2011-07-21 06:23:20 marka Exp $ */
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>
74 #include <dns/xfrin.h>
79 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
80 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
82 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
83 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
85 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
86 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
88 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
89 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
91 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
92 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
94 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
95 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
97 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
98 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
101 * Ensure 'a' is at least 'min' but not more than 'max'.
103 #define RANGE(a, min, max) \
104 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
106 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
111 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
112 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
113 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
115 #ifndef DNS_MAX_EXPIRE
116 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
119 #ifndef DNS_DUMP_DELAY
120 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
123 typedef struct dns_notify dns_notify_t;
124 typedef struct dns_stub dns_stub_t;
125 typedef struct dns_load dns_load_t;
126 typedef struct dns_forward dns_forward_t;
127 typedef struct dns_io dns_io_t;
128 typedef ISC_LIST(dns_io_t) dns_iolist_t;
129 typedef struct dns_signing dns_signing_t;
130 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
131 typedef struct dns_nsec3chain dns_nsec3chain_t;
132 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
134 #define DNS_ZONE_CHECKLOCK
135 #ifdef DNS_ZONE_CHECKLOCK
136 #define LOCK_ZONE(z) \
137 do { LOCK(&(z)->lock); \
138 INSIST((z)->locked == ISC_FALSE); \
139 (z)->locked = ISC_TRUE; \
141 #define UNLOCK_ZONE(z) \
142 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
143 #define LOCKED_ZONE(z) ((z)->locked)
145 #define LOCK_ZONE(z) LOCK(&(z)->lock)
146 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
147 #define LOCKED_ZONE(z) ISC_TRUE
150 #ifdef ISC_RWLOCK_USEATOMIC
151 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
152 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
153 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
154 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
156 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
157 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
158 #define ZONEDB_LOCK(l, t) LOCK(l)
159 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
166 #ifdef DNS_ZONE_CHECKLOCK
167 isc_boolean_t locked;
170 isc_refcount_t erefs;
172 #ifdef ISC_RWLOCK_USEATOMIC
177 dns_db_t *db; /* Locked by dblock */
181 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
186 dns_masterformat_t masterformat;
188 isc_int32_t journalsize;
189 dns_rdataclass_t rdclass;
192 unsigned int options;
193 unsigned int db_argc;
195 isc_time_t expiretime;
196 isc_time_t refreshtime;
199 isc_time_t notifytime;
200 isc_time_t resigntime;
201 isc_time_t keywarntime;
202 isc_time_t signingtime;
203 isc_time_t nsec3chaintime;
204 isc_uint32_t refresh;
207 isc_uint32_t minimum;
208 isc_stdtime_t key_expiry;
211 isc_uint32_t maxrefresh;
212 isc_uint32_t minrefresh;
213 isc_uint32_t maxretry;
214 isc_uint32_t minretry;
216 isc_sockaddr_t *masters;
217 dns_name_t **masterkeynames;
218 isc_boolean_t *mastersok;
219 unsigned int masterscnt;
220 unsigned int curmaster;
221 isc_sockaddr_t masteraddr;
222 dns_notifytype_t notifytype;
223 isc_sockaddr_t *notify;
224 unsigned int notifycnt;
225 isc_sockaddr_t notifyfrom;
227 isc_sockaddr_t notifysrc4;
228 isc_sockaddr_t notifysrc6;
229 isc_sockaddr_t xfrsource4;
230 isc_sockaddr_t xfrsource6;
231 isc_sockaddr_t altxfrsource4;
232 isc_sockaddr_t altxfrsource6;
233 isc_sockaddr_t sourceaddr;
234 dns_xfrin_ctx_t *xfr; /* task locked */
235 dns_tsigkey_t *tsigkey; /* key used for xfr */
236 /* Access Control Lists */
237 dns_acl_t *update_acl;
238 dns_acl_t *forward_acl;
239 dns_acl_t *notify_acl;
240 dns_acl_t *query_acl;
241 dns_acl_t *queryon_acl;
243 isc_boolean_t update_disabled;
244 isc_boolean_t zero_no_soa_ttl;
245 dns_severity_t check_names;
246 ISC_LIST(dns_notify_t) notifies;
247 dns_request_t *request;
252 isc_uint32_t maxxfrin;
253 isc_uint32_t maxxfrout;
255 isc_uint32_t idleout;
256 isc_event_t ctlevent;
257 dns_ssutable_t *ssutable;
258 isc_uint32_t sigvalidityinterval;
259 isc_uint32_t sigresigninginterval;
261 dns_acache_t *acache;
262 dns_checkmxfunc_t checkmx;
263 dns_checksrvfunc_t checksrv;
264 dns_checknsfunc_t checkns;
266 * Zones in certain states such as "waiting for zone transfer"
267 * or "zone transfer in progress" are kept on per-state linked lists
268 * in the zone manager using the 'statelink' field. The 'statelist'
269 * field points at the list the zone is currently on. It the zone
270 * is not on any such list, statelist is NULL.
272 ISC_LINK(dns_zone_t) statelink;
273 dns_zonelist_t *statelist;
275 * Statistics counters about zone management.
279 * Optional per-zone statistics counters. Counted outside of this
282 isc_boolean_t requeststats_on;
283 isc_stats_t *requeststats;
284 isc_uint32_t notifydelay;
285 dns_isselffunc_t isself;
294 * Serial number for deferred journal compaction.
296 isc_uint32_t compact_serial;
298 * Keys that are signing the zone for the first time.
300 dns_signinglist_t signing;
301 dns_nsec3chainlist_t nsec3chain;
303 * Signing / re-signing quantum stopping parameters.
305 isc_uint32_t signatures;
307 dns_rdatatype_t privatetype;
310 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
311 #define DNS_ZONE_SETFLAG(z,f) do { \
312 INSIST(LOCKED_ZONE(z)); \
315 #define DNS_ZONE_CLRFLAG(z,f) do { \
316 INSIST(LOCKED_ZONE(z)); \
317 (z)->flags &= ~(f); \
319 /* XXX MPA these may need to go back into zone.h */
320 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
321 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
322 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
323 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
324 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
325 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
326 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
327 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
328 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
329 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
331 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
333 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
335 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
336 * zone with no masters
338 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
339 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
340 * from SOA (if not set, we
342 * default timer values) */
343 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
344 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
345 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
346 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
347 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
348 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
349 #define DNS_ZONEFLG_FLUSH 0x00200000U
350 #define DNS_ZONEFLG_NOEDNS 0x00400000U
351 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
352 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
353 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
354 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
355 #define DNS_ZONEFLG_THAW 0x08000000U
357 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
359 /* Flags for zone_load() */
360 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
361 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
364 #define UNREACH_CHACHE_SIZE 10U
365 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
368 do { result = (op); \
369 if (result != ISC_R_SUCCESS) goto failure; \
372 struct dns_unreachable {
373 isc_sockaddr_t remote;
374 isc_sockaddr_t local;
382 int refs; /* Locked by rwlock */
383 isc_taskmgr_t * taskmgr;
384 isc_timermgr_t * timermgr;
385 isc_socketmgr_t * socketmgr;
386 isc_taskpool_t * zonetasks;
388 isc_ratelimiter_t * rl;
392 /* Locked by rwlock. */
393 dns_zonelist_t zones;
394 dns_zonelist_t waiting_for_xfrin;
395 dns_zonelist_t xfrin_in_progress;
397 /* Configuration data. */
398 isc_uint32_t transfersin;
399 isc_uint32_t transfersperns;
400 unsigned int serialqueryrate;
402 /* Locked by iolock */
403 isc_uint32_t iolimit;
404 isc_uint32_t ioactive;
408 /* Locked by rwlock. */
410 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
422 dns_request_t *request;
425 ISC_LINK(dns_notify_t) link;
428 #define DNS_NOTIFY_NOSOA 0x0001U
431 * dns_stub holds state while performing a 'stub' transfer.
432 * 'db' is the zone's 'db' or a new one if this is the initial
441 dns_dbversion_t *version;
453 dns_rdatacallbacks_t callbacks;
457 * Hold forward state.
463 isc_buffer_t *msgbuf;
464 dns_request_t *request;
467 dns_updatecallback_t callback;
472 * Hold IO request state.
479 ISC_LINK(dns_io_t) link;
484 * Hold state for when we are signing a zone with a new
485 * DNSKEY as result of an update.
490 dns_dbiterator_t *dbiterator;
491 dns_secalg_t algorithm;
493 isc_boolean_t delete;
495 ISC_LINK(dns_signing_t) link;
498 struct dns_nsec3chain {
501 dns_dbiterator_t *dbiterator;
502 dns_rdata_nsec3param_t nsec3param;
503 unsigned char salt[255];
505 isc_boolean_t seen_nsec;
506 isc_boolean_t delete_nsec;
507 isc_boolean_t save_delete_nsec;
508 ISC_LINK(dns_nsec3chain_t) link;
511 * 'dbiterator' contains a iterator for the database. If we are creating
512 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
513 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
516 * 'nsec3param' contains the parameters of the NSEC3 chain being created
519 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
521 * 'seen_nsec' will be set to true if, while iterating the zone to create a
522 * NSEC3 chain, a NSEC record is seen.
524 * 'delete_nsec' will be set to true if, at the completion of the creation
525 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
526 * are in the process of deleting the NSEC chain.
528 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
529 * so it can be recovered in the event of a error.
533 #define SEND_BUFFER_SIZE 2048
535 static void zone_settimer(dns_zone_t *, isc_time_t *);
536 static void cancel_refresh(dns_zone_t *);
537 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
538 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
539 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
540 ISC_FORMAT_PRINTF(3, 4);
541 static void queue_xfrin(dns_zone_t *zone);
542 static void zone_unload(dns_zone_t *zone);
543 static void zone_expire(dns_zone_t *zone);
544 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
545 static void zone_idetach(dns_zone_t **zonep);
546 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
548 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
549 static inline void zone_detachdb(dns_zone_t *zone);
550 static isc_result_t default_journal(dns_zone_t *zone);
551 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
552 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
553 isc_time_t loadtime, isc_result_t result);
554 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
555 static void zone_shutdown(isc_task_t *, isc_event_t *);
556 static void zone_loaddone(void *arg, isc_result_t result);
557 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
558 isc_time_t loadtime);
559 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
560 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
561 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
562 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
565 /* ondestroy example */
566 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
569 static void refresh_callback(isc_task_t *, isc_event_t *);
570 static void stub_callback(isc_task_t *, isc_event_t *);
571 static void queue_soa_query(dns_zone_t *zone);
572 static void soa_query(isc_task_t *, isc_event_t *);
573 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
575 static int message_count(dns_message_t *msg, dns_section_t section,
576 dns_rdatatype_t type);
577 static void notify_cancel(dns_zone_t *zone);
578 static void notify_find_address(dns_notify_t *notify);
579 static void notify_send(dns_notify_t *notify);
580 static isc_result_t notify_createmessage(dns_zone_t *zone,
582 dns_message_t **messagep);
583 static void notify_done(isc_task_t *task, isc_event_t *event);
584 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
585 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
586 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
587 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
589 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
590 static void zonemgr_free(dns_zonemgr_t *zmgr);
591 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
592 isc_task_t *task, isc_taskaction_t action,
593 void *arg, dns_io_t **iop);
594 static void zonemgr_putio(dns_io_t **iop);
595 static void zonemgr_cancelio(dns_io_t *io);
598 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
599 unsigned int *soacount, isc_uint32_t *serial,
600 isc_uint32_t *refresh, isc_uint32_t *retry,
601 isc_uint32_t *expire, isc_uint32_t *minimum,
602 unsigned int *errors);
604 static void zone_freedbargs(dns_zone_t *zone);
605 static void forward_callback(isc_task_t *task, isc_event_t *event);
606 static void zone_saveunique(dns_zone_t *zone, const char *path,
607 const char *templat);
608 static void zone_maintenance(dns_zone_t *zone);
609 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
610 static void dump_done(void *arg, isc_result_t result);
611 static isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr,
612 isc_sockaddr_t *remote,
613 isc_sockaddr_t *local,
615 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
616 isc_uint16_t keyid, isc_boolean_t delete);
618 #define ENTER zone_debuglog(zone, me, 1, "enter")
620 static const unsigned int dbargc_default = 1;
621 static const char *dbargv_default[] = { "rbt" };
623 #define DNS_ZONE_JITTER_ADD(a, b, c) \
627 _j = isc_random_jitter((b), (b)/4); \
628 isc_interval_set(&_i, _j, 0); \
629 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
630 dns_zone_log(zone, ISC_LOG_WARNING, \
631 "epoch approaching: upgrade required: " \
632 "now + %s failed", #b); \
633 isc_interval_set(&_i, _j/2, 0); \
634 (void)isc_time_add((a), &_i, (c)); \
638 #define DNS_ZONE_TIME_ADD(a, b, c) \
641 isc_interval_set(&_i, (b), 0); \
642 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
643 dns_zone_log(zone, ISC_LOG_WARNING, \
644 "epoch approaching: upgrade required: " \
645 "now + %s failed", #b); \
646 isc_interval_set(&_i, (b)/2, 0); \
647 (void)isc_time_add((a), &_i, (c)); \
652 * Increment resolver-related statistics counters. Zone must be locked.
655 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
656 if (zone->stats != NULL)
657 isc_stats_increment(zone->stats, counter);
661 *** Public functions.
665 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
670 REQUIRE(zonep != NULL && *zonep == NULL);
671 REQUIRE(mctx != NULL);
674 zone = isc_mem_get(mctx, sizeof(*zone));
676 return (ISC_R_NOMEMORY);
679 isc_mem_attach(mctx, &zone->mctx);
681 result = isc_mutex_init(&zone->lock);
682 if (result != ISC_R_SUCCESS)
685 result = ZONEDB_INITLOCK(&zone->dblock);
686 if (result != ISC_R_SUCCESS)
689 /* XXX MPA check that all elements are initialised */
690 #ifdef DNS_ZONE_CHECKLOCK
691 zone->locked = ISC_FALSE;
695 ISC_LINK_INIT(zone, link);
696 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
697 if (result != ISC_R_SUCCESS)
700 dns_name_init(&zone->origin, NULL);
701 zone->strnamerd = NULL;
702 zone->strname = NULL;
703 zone->strrdclass = NULL;
704 zone->strviewname = NULL;
705 zone->masterfile = NULL;
706 zone->masterformat = dns_masterformat_none;
707 zone->keydirectory = NULL;
708 zone->journalsize = -1;
709 zone->journal = NULL;
710 zone->rdclass = dns_rdataclass_none;
711 zone->type = dns_zone_none;
715 zone->db_argv = NULL;
716 isc_time_settoepoch(&zone->expiretime);
717 isc_time_settoepoch(&zone->refreshtime);
718 isc_time_settoepoch(&zone->dumptime);
719 isc_time_settoepoch(&zone->loadtime);
720 zone->notifytime = now;
721 isc_time_settoepoch(&zone->resigntime);
722 isc_time_settoepoch(&zone->keywarntime);
723 isc_time_settoepoch(&zone->signingtime);
724 isc_time_settoepoch(&zone->nsec3chaintime);
725 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
726 zone->retry = DNS_ZONE_DEFAULTRETRY;
729 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
730 zone->minrefresh = DNS_ZONE_MINREFRESH;
731 zone->maxretry = DNS_ZONE_MAXRETRY;
732 zone->minretry = DNS_ZONE_MINRETRY;
733 zone->masters = NULL;
734 zone->masterkeynames = NULL;
735 zone->mastersok = NULL;
736 zone->masterscnt = 0;
739 zone->notifytype = dns_notifytype_yes;
742 zone->update_acl = NULL;
743 zone->forward_acl = NULL;
744 zone->notify_acl = NULL;
745 zone->query_acl = NULL;
746 zone->queryon_acl = NULL;
747 zone->xfr_acl = NULL;
748 zone->update_disabled = ISC_FALSE;
749 zone->zero_no_soa_ttl = ISC_TRUE;
750 zone->check_names = dns_severity_ignore;
751 zone->request = NULL;
755 zone->writeio = NULL;
757 zone->idlein = DNS_DEFAULT_IDLEIN;
758 zone->idleout = DNS_DEFAULT_IDLEOUT;
759 ISC_LIST_INIT(zone->notifies);
760 isc_sockaddr_any(&zone->notifysrc4);
761 isc_sockaddr_any6(&zone->notifysrc6);
762 isc_sockaddr_any(&zone->xfrsource4);
763 isc_sockaddr_any6(&zone->xfrsource6);
764 isc_sockaddr_any(&zone->altxfrsource4);
765 isc_sockaddr_any6(&zone->altxfrsource6);
767 zone->tsigkey = NULL;
768 zone->maxxfrin = MAX_XFER_TIME;
769 zone->maxxfrout = MAX_XFER_TIME;
770 zone->ssutable = NULL;
771 zone->sigvalidityinterval = 30 * 24 * 3600;
772 zone->sigresigninginterval = 7 * 24 * 3600;
775 zone->checkmx = NULL;
776 zone->checksrv = NULL;
777 zone->checkns = NULL;
778 ISC_LINK_INIT(zone, statelink);
779 zone->statelist = NULL;
781 zone->requeststats_on = ISC_FALSE;
782 zone->requeststats = NULL;
783 zone->notifydelay = 5;
785 zone->isselfarg = NULL;
786 ISC_LIST_INIT(zone->signing);
787 ISC_LIST_INIT(zone->nsec3chain);
788 zone->signatures = 10;
790 zone->privatetype = (dns_rdatatype_t)0xffffU;
792 zone->magic = ZONE_MAGIC;
794 /* Must be after magic is set. */
795 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
796 if (result != ISC_R_SUCCESS)
799 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
800 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
803 return (ISC_R_SUCCESS);
806 isc_refcount_decrement(&zone->erefs, NULL);
807 isc_refcount_destroy(&zone->erefs);
810 ZONEDB_DESTROYLOCK(&zone->dblock);
813 DESTROYLOCK(&zone->lock);
816 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
821 * Free a zone. Because we require that there be no more
822 * outstanding events or references, no locking is necessary.
825 zone_free(dns_zone_t *zone) {
826 isc_mem_t *mctx = NULL;
827 dns_signing_t *signing;
828 dns_nsec3chain_t *nsec3chain;
830 REQUIRE(DNS_ZONE_VALID(zone));
831 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
832 REQUIRE(zone->irefs == 0);
833 REQUIRE(!LOCKED_ZONE(zone));
834 REQUIRE(zone->timer == NULL);
837 * Managed objects. Order is important.
839 if (zone->request != NULL)
840 dns_request_destroy(&zone->request); /* XXXMPA */
841 INSIST(zone->readio == NULL);
842 INSIST(zone->statelist == NULL);
843 INSIST(zone->writeio == NULL);
845 if (zone->task != NULL)
846 isc_task_detach(&zone->task);
847 if (zone->zmgr != NULL)
848 dns_zonemgr_releasezone(zone->zmgr, zone);
850 /* Unmanaged objects */
851 for (signing = ISC_LIST_HEAD(zone->signing);
853 signing = ISC_LIST_HEAD(zone->signing)) {
854 ISC_LIST_UNLINK(zone->signing, signing, link);
855 dns_db_detach(&signing->db);
856 dns_dbiterator_destroy(&signing->dbiterator);
857 isc_mem_put(zone->mctx, signing, sizeof *signing);
859 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
861 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
862 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
863 dns_db_detach(&nsec3chain->db);
864 dns_dbiterator_destroy(&nsec3chain->dbiterator);
865 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
867 if (zone->masterfile != NULL)
868 isc_mem_free(zone->mctx, zone->masterfile);
869 zone->masterfile = NULL;
870 if (zone->keydirectory != NULL)
871 isc_mem_free(zone->mctx, zone->keydirectory);
872 zone->keydirectory = NULL;
873 zone->journalsize = -1;
874 if (zone->journal != NULL)
875 isc_mem_free(zone->mctx, zone->journal);
876 zone->journal = NULL;
877 if (zone->stats != NULL)
878 isc_stats_detach(&zone->stats);
879 if (zone->requeststats != NULL)
880 isc_stats_detach(&zone->requeststats);
881 if (zone->db != NULL)
883 if (zone->acache != NULL)
884 dns_acache_detach(&zone->acache);
885 zone_freedbargs(zone);
886 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
888 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
890 zone->check_names = dns_severity_ignore;
891 if (zone->update_acl != NULL)
892 dns_acl_detach(&zone->update_acl);
893 if (zone->forward_acl != NULL)
894 dns_acl_detach(&zone->forward_acl);
895 if (zone->notify_acl != NULL)
896 dns_acl_detach(&zone->notify_acl);
897 if (zone->query_acl != NULL)
898 dns_acl_detach(&zone->query_acl);
899 if (zone->queryon_acl != NULL)
900 dns_acl_detach(&zone->queryon_acl);
901 if (zone->xfr_acl != NULL)
902 dns_acl_detach(&zone->xfr_acl);
903 if (dns_name_dynamic(&zone->origin))
904 dns_name_free(&zone->origin, zone->mctx);
905 if (zone->strnamerd != NULL)
906 isc_mem_free(zone->mctx, zone->strnamerd);
907 if (zone->strname != NULL)
908 isc_mem_free(zone->mctx, zone->strname);
909 if (zone->strrdclass != NULL)
910 isc_mem_free(zone->mctx, zone->strrdclass);
911 if (zone->strviewname != NULL)
912 isc_mem_free(zone->mctx, zone->strviewname);
913 if (zone->ssutable != NULL)
914 dns_ssutable_detach(&zone->ssutable);
917 ZONEDB_DESTROYLOCK(&zone->dblock);
918 DESTROYLOCK(&zone->lock);
919 isc_refcount_destroy(&zone->erefs);
922 isc_mem_put(mctx, zone, sizeof(*zone));
923 isc_mem_detach(&mctx);
930 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
933 REQUIRE(DNS_ZONE_VALID(zone));
934 REQUIRE(rdclass != dns_rdataclass_none);
940 REQUIRE(zone->rdclass == dns_rdataclass_none ||
941 zone->rdclass == rdclass);
942 zone->rdclass = rdclass;
944 if (zone->strnamerd != NULL)
945 isc_mem_free(zone->mctx, zone->strnamerd);
946 if (zone->strrdclass != NULL)
947 isc_mem_free(zone->mctx, zone->strrdclass);
949 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
950 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
951 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
952 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
958 dns_zone_getclass(dns_zone_t *zone) {
959 REQUIRE(DNS_ZONE_VALID(zone));
961 return (zone->rdclass);
965 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
966 REQUIRE(DNS_ZONE_VALID(zone));
969 zone->notifytype = notifytype;
974 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
977 REQUIRE(DNS_ZONE_VALID(zone));
978 REQUIRE(serialp != NULL);
981 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
982 if (zone->db != NULL) {
983 result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
984 NULL, NULL, NULL, NULL, NULL);
986 result = DNS_R_NOTLOADED;
987 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
994 dns_zone_getserial(dns_zone_t *zone) {
998 result = dns_zone_getserial2(zone, &serial);
999 if (result != ISC_R_SUCCESS)
1000 serial = 0; /* XXX: not really correct, but no other choice */
1009 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1011 REQUIRE(DNS_ZONE_VALID(zone));
1012 REQUIRE(type != dns_zone_none);
1018 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1024 zone_freedbargs(dns_zone_t *zone) {
1027 /* Free the old database argument list. */
1028 if (zone->db_argv != NULL) {
1029 for (i = 0; i < zone->db_argc; i++)
1030 isc_mem_free(zone->mctx, zone->db_argv[i]);
1031 isc_mem_put(zone->mctx, zone->db_argv,
1032 zone->db_argc * sizeof(*zone->db_argv));
1035 zone->db_argv = NULL;
1039 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1042 isc_result_t result = ISC_R_SUCCESS;
1046 REQUIRE(DNS_ZONE_VALID(zone));
1047 REQUIRE(argv != NULL && *argv == NULL);
1050 size = (zone->db_argc + 1) * sizeof(char *);
1051 for (i = 0; i < zone->db_argc; i++)
1052 size += strlen(zone->db_argv[i]) + 1;
1053 mem = isc_mem_allocate(mctx, size);
1057 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1058 for (i = 0; i < zone->db_argc; i++) {
1060 strcpy(tmp2, zone->db_argv[i]);
1061 tmp2 += strlen(tmp2) + 1;
1065 result = ISC_R_NOMEMORY;
1072 dns_zone_setdbtype(dns_zone_t *zone,
1073 unsigned int dbargc, const char * const *dbargv) {
1074 isc_result_t result = ISC_R_SUCCESS;
1078 REQUIRE(DNS_ZONE_VALID(zone));
1079 REQUIRE(dbargc >= 1);
1080 REQUIRE(dbargv != NULL);
1084 /* Set up a new database argument list. */
1085 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1088 for (i = 0; i < dbargc; i++)
1090 for (i = 0; i < dbargc; i++) {
1091 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1096 /* Free the old list. */
1097 zone_freedbargs(zone);
1099 zone->db_argc = dbargc;
1100 zone->db_argv = new;
1101 result = ISC_R_SUCCESS;
1106 for (i = 0; i < dbargc; i++)
1108 isc_mem_free(zone->mctx, new[i]);
1109 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1111 result = ISC_R_NOMEMORY;
1119 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1121 REQUIRE(DNS_ZONE_VALID(zone));
1124 if (zone->view != NULL)
1125 dns_view_weakdetach(&zone->view);
1126 dns_view_weakattach(view, &zone->view);
1128 if (zone->strviewname != NULL)
1129 isc_mem_free(zone->mctx, zone->strviewname);
1130 if (zone->strnamerd != NULL)
1131 isc_mem_free(zone->mctx, zone->strnamerd);
1133 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1134 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1135 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1136 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1143 dns_zone_getview(dns_zone_t *zone) {
1144 REQUIRE(DNS_ZONE_VALID(zone));
1146 return (zone->view);
1151 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1152 isc_result_t result;
1155 REQUIRE(DNS_ZONE_VALID(zone));
1156 REQUIRE(origin != NULL);
1159 if (dns_name_dynamic(&zone->origin)) {
1160 dns_name_free(&zone->origin, zone->mctx);
1161 dns_name_init(&zone->origin, NULL);
1163 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1165 if (zone->strnamerd != NULL)
1166 isc_mem_free(zone->mctx, zone->strnamerd);
1167 if (zone->strname != NULL)
1168 isc_mem_free(zone->mctx, zone->strname);
1170 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1171 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1172 zone_name_tostr(zone, namebuf, sizeof namebuf);
1173 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1180 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1181 REQUIRE(DNS_ZONE_VALID(zone));
1182 REQUIRE(acache != NULL);
1185 if (zone->acache != NULL)
1186 dns_acache_detach(&zone->acache);
1187 dns_acache_attach(acache, &zone->acache);
1188 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1189 if (zone->db != NULL) {
1190 isc_result_t result;
1193 * If the zone reuses an existing DB, the DB needs to be
1194 * set in the acache explicitly. We can safely ignore the
1195 * case where the DB is already set. If other error happens,
1196 * the acache will not work effectively.
1198 result = dns_acache_setdb(acache, zone->db);
1199 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1200 UNEXPECTED_ERROR(__FILE__, __LINE__,
1201 "dns_acache_setdb() failed: %s",
1202 isc_result_totext(result));
1205 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1210 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1213 if (value != NULL) {
1214 copy = isc_mem_strdup(zone->mctx, value);
1216 return (ISC_R_NOMEMORY);
1222 isc_mem_free(zone->mctx, *field);
1225 return (ISC_R_SUCCESS);
1229 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1230 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1234 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1235 dns_masterformat_t format) {
1236 isc_result_t result = ISC_R_SUCCESS;
1238 REQUIRE(DNS_ZONE_VALID(zone));
1241 result = dns_zone_setstring(zone, &zone->masterfile, file);
1242 if (result == ISC_R_SUCCESS) {
1243 zone->masterformat = format;
1244 result = default_journal(zone);
1252 dns_zone_getfile(dns_zone_t *zone) {
1253 REQUIRE(DNS_ZONE_VALID(zone));
1255 return (zone->masterfile);
1259 default_journal(dns_zone_t *zone) {
1260 isc_result_t result;
1263 REQUIRE(DNS_ZONE_VALID(zone));
1264 REQUIRE(LOCKED_ZONE(zone));
1266 if (zone->masterfile != NULL) {
1267 /* Calculate string length including '\0'. */
1268 int len = strlen(zone->masterfile) + sizeof(".jnl");
1269 journal = isc_mem_allocate(zone->mctx, len);
1270 if (journal == NULL)
1271 return (ISC_R_NOMEMORY);
1272 strcpy(journal, zone->masterfile);
1273 strcat(journal, ".jnl");
1277 result = dns_zone_setstring(zone, &zone->journal, journal);
1278 if (journal != NULL)
1279 isc_mem_free(zone->mctx, journal);
1284 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1285 isc_result_t result = ISC_R_SUCCESS;
1287 REQUIRE(DNS_ZONE_VALID(zone));
1290 result = dns_zone_setstring(zone, &zone->journal, journal);
1297 dns_zone_getjournal(dns_zone_t *zone) {
1298 REQUIRE(DNS_ZONE_VALID(zone));
1300 return (zone->journal);
1304 * Return true iff the zone is "dynamic", in the sense that the zone's
1305 * master file (if any) is written by the server, rather than being
1306 * updated manually and read by the server.
1308 * This is true for slave zones, stub zones, and zones that allow
1309 * dynamic updates either by having an update policy ("ssutable")
1310 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1312 static isc_boolean_t
1313 zone_isdynamic(dns_zone_t *zone) {
1314 REQUIRE(DNS_ZONE_VALID(zone));
1316 return (ISC_TF(zone->type == dns_zone_slave ||
1317 zone->type == dns_zone_stub ||
1318 (!zone->update_disabled && zone->ssutable != NULL) ||
1319 (!zone->update_disabled && zone->update_acl != NULL &&
1320 !dns_acl_isnone(zone->update_acl))));
1325 zone_load(dns_zone_t *zone, unsigned int flags) {
1326 isc_result_t result;
1328 isc_time_t loadtime, filetime;
1329 dns_db_t *db = NULL;
1332 REQUIRE(DNS_ZONE_VALID(zone));
1337 INSIST(zone->type != dns_zone_none);
1339 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1340 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1341 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1342 result = DNS_R_CONTINUE;
1347 INSIST(zone->db_argc >= 1);
1349 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1350 strcmp(zone->db_argv[0], "rbt64") == 0;
1352 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1354 * The zone has no master file configured.
1356 result = ISC_R_SUCCESS;
1360 if (zone->db != NULL && zone_isdynamic(zone)) {
1362 * This is a slave, stub, or dynamically updated
1363 * zone being reloaded. Do nothing - the database
1364 * we already have is guaranteed to be up-to-date.
1366 if (zone->type == dns_zone_master)
1367 result = DNS_R_DYNAMIC;
1369 result = ISC_R_SUCCESS;
1374 * Store the current time before the zone is loaded, so that if the
1375 * file changes between the time of the load and the time that
1376 * zone->loadtime is set, then the file will still be reloaded
1377 * the next time dns_zone_load is called.
1379 TIME_NOW(&loadtime);
1382 * Don't do the load if the file that stores the zone is older
1383 * than the last time the zone was loaded. If the zone has not
1384 * been loaded yet, zone->loadtime will be the epoch.
1386 if (zone->masterfile != NULL) {
1388 * The file is already loaded. If we are just doing a
1389 * "rndc reconfig", we are done.
1391 if (!isc_time_isepoch(&zone->loadtime) &&
1392 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1393 result = ISC_R_SUCCESS;
1397 result = isc_file_getmodtime(zone->masterfile, &filetime);
1398 if (result == ISC_R_SUCCESS) {
1399 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1400 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1401 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1402 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1403 "skipping load: master file "
1404 "older than last load");
1405 result = DNS_R_UPTODATE;
1408 loadtime = filetime;
1413 * Built in zones (with the exception of empty zones) don't need
1416 if (zone->type == dns_zone_master &&
1417 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1418 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1419 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1420 result = ISC_R_SUCCESS;
1424 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1426 if (zone->masterfile == NULL ||
1427 !isc_file_exists(zone->masterfile)) {
1428 if (zone->masterfile != NULL) {
1429 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1432 zone->refreshtime = now;
1433 if (zone->task != NULL)
1434 zone_settimer(zone, &now);
1435 result = ISC_R_SUCCESS;
1440 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1442 result = dns_db_create(zone->mctx, zone->db_argv[0],
1443 &zone->origin, (zone->type == dns_zone_stub) ?
1444 dns_dbtype_stub : dns_dbtype_zone,
1446 zone->db_argc - 1, zone->db_argv + 1,
1449 if (result != ISC_R_SUCCESS) {
1450 dns_zone_log(zone, ISC_LOG_ERROR,
1451 "loading zone: creating database: %s",
1452 isc_result_totext(result));
1455 dns_db_settask(db, zone->task);
1457 if (! dns_db_ispersistent(db)) {
1458 if (zone->masterfile != NULL) {
1459 result = zone_startload(db, zone, loadtime);
1461 result = DNS_R_NOMASTERFILE;
1462 if (zone->type == dns_zone_master) {
1463 dns_zone_log(zone, ISC_LOG_ERROR,
1465 "no master file configured");
1468 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1469 "no master file configured: continuing");
1473 if (result == DNS_R_CONTINUE) {
1474 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1475 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1476 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1480 result = zone_postload(zone, db, loadtime, result);
1490 dns_zone_load(dns_zone_t *zone) {
1491 return (zone_load(zone, 0));
1495 dns_zone_loadnew(dns_zone_t *zone) {
1496 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1500 dns_zone_loadandthaw(dns_zone_t *zone) {
1501 isc_result_t result;
1503 result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1505 case DNS_R_CONTINUE:
1506 /* Deferred thaw. */
1509 case DNS_R_UPTODATE:
1510 case DNS_R_SEENINCLUDE:
1511 zone->update_disabled = ISC_FALSE;
1513 case DNS_R_NOMASTERFILE:
1514 zone->update_disabled = ISC_FALSE;
1517 /* Error, remain in disabled state. */
1524 get_master_options(dns_zone_t *zone) {
1525 unsigned int options;
1527 options = DNS_MASTER_ZONE;
1528 if (zone->type == dns_zone_slave)
1529 options |= DNS_MASTER_SLAVE;
1530 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1531 options |= DNS_MASTER_CHECKNS;
1532 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1533 options |= DNS_MASTER_FATALNS;
1534 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1535 options |= DNS_MASTER_CHECKNAMES;
1536 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1537 options |= DNS_MASTER_CHECKNAMESFAIL;
1538 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1539 options |= DNS_MASTER_CHECKMX;
1540 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1541 options |= DNS_MASTER_CHECKMXFAIL;
1542 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1543 options |= DNS_MASTER_CHECKWILDCARD;
1544 if (zone->type == dns_zone_master &&
1545 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1546 zone->ssutable != NULL))
1547 options |= DNS_MASTER_RESIGN;
1552 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1553 dns_load_t *load = event->ev_arg;
1554 isc_result_t result = ISC_R_SUCCESS;
1555 unsigned int options;
1557 REQUIRE(DNS_LOAD_VALID(load));
1559 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1560 result = ISC_R_CANCELED;
1561 isc_event_free(&event);
1562 if (result == ISC_R_CANCELED)
1565 options = get_master_options(load->zone);
1567 result = dns_master_loadfileinc3(load->zone->masterfile,
1568 dns_db_origin(load->db),
1569 dns_db_origin(load->db),
1570 load->zone->rdclass,
1572 load->zone->sigresigninginterval,
1573 &load->callbacks, task,
1574 zone_loaddone, load,
1575 &load->zone->lctx, load->zone->mctx,
1576 load->zone->masterformat);
1577 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1578 result != DNS_R_SEENINCLUDE)
1583 zone_loaddone(load, result);
1587 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1588 const char me[] = "zone_gotwritehandle";
1589 dns_zone_t *zone = event->ev_arg;
1590 isc_result_t result = ISC_R_SUCCESS;
1591 dns_dbversion_t *version = NULL;
1593 REQUIRE(DNS_ZONE_VALID(zone));
1594 INSIST(task == zone->task);
1597 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1598 result = ISC_R_CANCELED;
1599 isc_event_free(&event);
1600 if (result == ISC_R_CANCELED)
1604 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1605 dns_db_currentversion(zone->db, &version);
1606 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1607 &dns_master_style_default,
1608 zone->masterfile, zone->task, dump_done,
1609 zone, &zone->dctx, zone->masterformat);
1610 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1611 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1613 if (result != DNS_R_CONTINUE)
1618 dump_done(zone, result);
1622 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1624 isc_result_t result;
1625 isc_result_t tresult;
1626 unsigned int options;
1628 options = get_master_options(zone);
1630 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1631 options |= DNS_MASTER_MANYERRORS;
1633 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1634 load = isc_mem_get(zone->mctx, sizeof(*load));
1636 return (ISC_R_NOMEMORY);
1641 load->loadtime = loadtime;
1642 load->magic = LOAD_MAGIC;
1644 isc_mem_attach(zone->mctx, &load->mctx);
1645 zone_iattach(zone, &load->zone);
1646 dns_db_attach(db, &load->db);
1647 dns_rdatacallbacks_init(&load->callbacks);
1648 result = dns_db_beginload(db, &load->callbacks.add,
1649 &load->callbacks.add_private);
1650 if (result != ISC_R_SUCCESS)
1652 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1653 zone_gotreadhandle, load,
1655 if (result != ISC_R_SUCCESS) {
1657 * We can't report multiple errors so ignore
1658 * the result of dns_db_endload().
1660 (void)dns_db_endload(load->db,
1661 &load->callbacks.add_private);
1664 result = DNS_R_CONTINUE;
1666 dns_rdatacallbacks_t callbacks;
1668 dns_rdatacallbacks_init(&callbacks);
1669 result = dns_db_beginload(db, &callbacks.add,
1670 &callbacks.add_private);
1671 if (result != ISC_R_SUCCESS)
1673 result = dns_master_loadfile3(zone->masterfile, &zone->origin,
1674 &zone->origin, zone->rdclass,
1675 options, zone->sigresigninginterval,
1676 &callbacks, zone->mctx,
1677 zone->masterformat);
1678 tresult = dns_db_endload(db, &callbacks.add_private);
1679 if (result == ISC_R_SUCCESS)
1687 dns_db_detach(&load->db);
1688 zone_idetach(&load->zone);
1689 isc_mem_detach(&load->mctx);
1690 isc_mem_put(zone->mctx, load, sizeof(*load));
1694 static isc_boolean_t
1695 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1698 isc_result_t result;
1699 char ownerbuf[DNS_NAME_FORMATSIZE];
1700 char namebuf[DNS_NAME_FORMATSIZE];
1701 char altbuf[DNS_NAME_FORMATSIZE];
1702 dns_fixedname_t fixed;
1703 dns_name_t *foundname;
1707 * "." means the services does not exist.
1709 if (dns_name_equal(name, dns_rootname))
1715 if (!dns_name_issubdomain(name, &zone->origin)) {
1716 if (zone->checkmx != NULL)
1717 return ((zone->checkmx)(zone, name, owner));
1721 if (zone->type == dns_zone_master)
1722 level = ISC_LOG_ERROR;
1724 level = ISC_LOG_WARNING;
1726 dns_fixedname_init(&fixed);
1727 foundname = dns_fixedname_name(&fixed);
1729 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1730 0, 0, NULL, foundname, NULL, NULL);
1731 if (result == ISC_R_SUCCESS)
1734 if (result == DNS_R_NXRRSET) {
1735 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1736 0, 0, NULL, foundname, NULL, NULL);
1737 if (result == ISC_R_SUCCESS)
1741 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1742 dns_name_format(name, namebuf, sizeof namebuf);
1743 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1744 result == DNS_R_EMPTYNAME) {
1745 dns_zone_log(zone, level,
1746 "%s/MX '%s' has no address records (A or AAAA)",
1748 /* XXX950 make fatal for 9.5.0. */
1752 if (result == DNS_R_CNAME) {
1753 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1754 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1755 level = ISC_LOG_WARNING;
1756 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1757 dns_zone_log(zone, level,
1758 "%s/MX '%s' is a CNAME (illegal)",
1760 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1763 if (result == DNS_R_DNAME) {
1764 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1765 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1766 level = ISC_LOG_WARNING;
1767 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1768 dns_name_format(foundname, altbuf, sizeof altbuf);
1769 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1770 " '%s' (illegal)", ownerbuf, namebuf,
1773 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1776 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1777 return ((zone->checkmx)(zone, name, owner));
1782 static isc_boolean_t
1783 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1786 isc_result_t result;
1787 char ownerbuf[DNS_NAME_FORMATSIZE];
1788 char namebuf[DNS_NAME_FORMATSIZE];
1789 char altbuf[DNS_NAME_FORMATSIZE];
1790 dns_fixedname_t fixed;
1791 dns_name_t *foundname;
1795 * "." means the services does not exist.
1797 if (dns_name_equal(name, dns_rootname))
1803 if (!dns_name_issubdomain(name, &zone->origin)) {
1804 if (zone->checksrv != NULL)
1805 return ((zone->checksrv)(zone, name, owner));
1809 if (zone->type == dns_zone_master)
1810 level = ISC_LOG_ERROR;
1812 level = ISC_LOG_WARNING;
1814 dns_fixedname_init(&fixed);
1815 foundname = dns_fixedname_name(&fixed);
1817 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1818 0, 0, NULL, foundname, NULL, NULL);
1819 if (result == ISC_R_SUCCESS)
1822 if (result == DNS_R_NXRRSET) {
1823 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1824 0, 0, NULL, foundname, NULL, NULL);
1825 if (result == ISC_R_SUCCESS)
1829 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1830 dns_name_format(name, namebuf, sizeof namebuf);
1831 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1832 result == DNS_R_EMPTYNAME) {
1833 dns_zone_log(zone, level,
1834 "%s/SRV '%s' has no address records (A or AAAA)",
1836 /* XXX950 make fatal for 9.5.0. */
1840 if (result == DNS_R_CNAME) {
1841 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1842 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1843 level = ISC_LOG_WARNING;
1844 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1845 dns_zone_log(zone, level,
1846 "%s/SRV '%s' is a CNAME (illegal)",
1848 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1851 if (result == DNS_R_DNAME) {
1852 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1853 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1854 level = ISC_LOG_WARNING;
1855 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1856 dns_name_format(foundname, altbuf, sizeof altbuf);
1857 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1858 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1861 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1864 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1865 return ((zone->checksrv)(zone, name, owner));
1870 static isc_boolean_t
1871 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1874 isc_boolean_t answer = ISC_TRUE;
1875 isc_result_t result, tresult;
1876 char ownerbuf[DNS_NAME_FORMATSIZE];
1877 char namebuf[DNS_NAME_FORMATSIZE];
1878 char altbuf[DNS_NAME_FORMATSIZE];
1879 dns_fixedname_t fixed;
1880 dns_name_t *foundname;
1882 dns_rdataset_t aaaa;
1888 if (!dns_name_issubdomain(name, &zone->origin)) {
1889 if (zone->checkns != NULL)
1890 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1894 if (zone->type == dns_zone_master)
1895 level = ISC_LOG_ERROR;
1897 level = ISC_LOG_WARNING;
1899 dns_fixedname_init(&fixed);
1900 foundname = dns_fixedname_name(&fixed);
1901 dns_rdataset_init(&a);
1902 dns_rdataset_init(&aaaa);
1904 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1905 DNS_DBFIND_GLUEOK, 0, NULL,
1906 foundname, &a, NULL);
1908 if (result == ISC_R_SUCCESS) {
1909 dns_rdataset_disassociate(&a);
1911 } else if (result == DNS_R_DELEGATION)
1912 dns_rdataset_disassociate(&a);
1914 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1915 result == DNS_R_GLUE) {
1916 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1917 DNS_DBFIND_GLUEOK, 0, NULL,
1918 foundname, &aaaa, NULL);
1919 if (tresult == ISC_R_SUCCESS) {
1920 dns_rdataset_disassociate(&aaaa);
1923 if (tresult == DNS_R_DELEGATION)
1924 dns_rdataset_disassociate(&aaaa);
1925 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1927 * Check glue against child zone.
1929 if (zone->checkns != NULL)
1930 answer = (zone->checkns)(zone, name, owner,
1932 if (dns_rdataset_isassociated(&a))
1933 dns_rdataset_disassociate(&a);
1934 if (dns_rdataset_isassociated(&aaaa))
1935 dns_rdataset_disassociate(&aaaa);
1940 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1941 dns_name_format(name, namebuf, sizeof namebuf);
1942 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1943 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
1945 isc_boolean_t required = ISC_FALSE;
1946 if (dns_name_issubdomain(name, owner)) {
1947 what = "REQUIRED GLUE ";
1948 required = ISC_TRUE;
1949 } else if (result == DNS_R_DELEGATION)
1950 what = "SIBLING GLUE ";
1954 if (result != DNS_R_DELEGATION || required ||
1955 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
1956 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
1957 "address records (A or AAAA)",
1958 ownerbuf, namebuf, what);
1960 * Log missing address record.
1962 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
1963 (void)(zone->checkns)(zone, name, owner,
1965 /* XXX950 make fatal for 9.5.0. */
1966 /* answer = ISC_FALSE; */
1968 } else if (result == DNS_R_CNAME) {
1969 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
1971 /* XXX950 make fatal for 9.5.0. */
1972 /* answer = ISC_FALSE; */
1973 } else if (result == DNS_R_DNAME) {
1974 dns_name_format(foundname, altbuf, sizeof altbuf);
1975 dns_zone_log(zone, level,
1976 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1977 ownerbuf, namebuf, altbuf);
1978 /* XXX950 make fatal for 9.5.0. */
1979 /* answer = ISC_FALSE; */
1982 if (dns_rdataset_isassociated(&a))
1983 dns_rdataset_disassociate(&a);
1984 if (dns_rdataset_isassociated(&aaaa))
1985 dns_rdataset_disassociate(&aaaa);
1989 static isc_boolean_t
1990 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
1991 dns_dbiterator_t *dbiterator = NULL;
1992 dns_dbnode_t *node = NULL;
1993 dns_rdataset_t rdataset;
1994 dns_fixedname_t fixed;
1995 dns_fixedname_t fixedbottom;
1998 dns_rdata_in_srv_t srv;
2002 isc_result_t result;
2003 isc_boolean_t ok = ISC_TRUE;
2005 dns_fixedname_init(&fixed);
2006 name = dns_fixedname_name(&fixed);
2007 dns_fixedname_init(&fixedbottom);
2008 bottom = dns_fixedname_name(&fixedbottom);
2009 dns_rdataset_init(&rdataset);
2010 dns_rdata_init(&rdata);
2012 result = dns_db_createiterator(db, 0, &dbiterator);
2013 if (result != ISC_R_SUCCESS)
2016 result = dns_dbiterator_first(dbiterator);
2017 while (result == ISC_R_SUCCESS) {
2018 result = dns_dbiterator_current(dbiterator, &node, name);
2019 if (result != ISC_R_SUCCESS)
2023 * Is this name visible in the zone?
2025 if (!dns_name_issubdomain(name, &zone->origin) ||
2026 (dns_name_countlabels(bottom) > 0 &&
2027 dns_name_issubdomain(name, bottom)))
2031 * Don't check the NS records at the origin.
2033 if (dns_name_equal(name, &zone->origin))
2036 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2037 0, 0, &rdataset, NULL);
2038 if (result != ISC_R_SUCCESS)
2041 * Remember bottom of zone.
2043 dns_name_copy(name, bottom, NULL);
2045 result = dns_rdataset_first(&rdataset);
2046 while (result == ISC_R_SUCCESS) {
2047 dns_rdataset_current(&rdataset, &rdata);
2048 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2049 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2050 if (!zone_check_glue(zone, db, &ns.name, name))
2052 dns_rdata_reset(&rdata);
2053 result = dns_rdataset_next(&rdataset);
2055 dns_rdataset_disassociate(&rdataset);
2058 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2059 0, 0, &rdataset, NULL);
2060 if (result != ISC_R_SUCCESS)
2062 result = dns_rdataset_first(&rdataset);
2063 while (result == ISC_R_SUCCESS) {
2064 dns_rdataset_current(&rdataset, &rdata);
2065 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2066 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2067 if (!zone_check_mx(zone, db, &mx.mx, name))
2069 dns_rdata_reset(&rdata);
2070 result = dns_rdataset_next(&rdataset);
2072 dns_rdataset_disassociate(&rdataset);
2075 if (zone->rdclass != dns_rdataclass_in)
2077 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2078 0, 0, &rdataset, NULL);
2079 if (result != ISC_R_SUCCESS)
2081 result = dns_rdataset_first(&rdataset);
2082 while (result == ISC_R_SUCCESS) {
2083 dns_rdataset_current(&rdataset, &rdata);
2084 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2085 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2086 if (!zone_check_srv(zone, db, &srv.target, name))
2088 dns_rdata_reset(&rdata);
2089 result = dns_rdataset_next(&rdataset);
2091 dns_rdataset_disassociate(&rdataset);
2094 dns_db_detachnode(db, &node);
2095 result = dns_dbiterator_next(dbiterator);
2100 dns_db_detachnode(db, &node);
2101 dns_dbiterator_destroy(&dbiterator);
2107 * OpenSSL verification of RSA keys with exponent 3 is known to be
2108 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2109 * if they are in use.
2112 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2113 dns_dbnode_t *node = NULL;
2114 dns_dbversion_t *version = NULL;
2115 dns_rdata_dnskey_t dnskey;
2116 dns_rdata_t rdata = DNS_RDATA_INIT;
2117 dns_rdataset_t rdataset;
2118 isc_result_t result;
2119 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2120 const char *algorithm;
2122 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2123 if (result != ISC_R_SUCCESS)
2126 dns_db_currentversion(db, &version);
2127 dns_rdataset_init(&rdataset);
2128 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2129 dns_rdatatype_none, 0, &rdataset, NULL);
2130 if (result != ISC_R_SUCCESS)
2133 for (result = dns_rdataset_first(&rdataset);
2134 result == ISC_R_SUCCESS;
2135 result = dns_rdataset_next(&rdataset))
2137 dns_rdataset_current(&rdataset, &rdata);
2138 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2139 INSIST(result == ISC_R_SUCCESS);
2141 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2142 dnskey.algorithm == DST_ALG_RSAMD5) &&
2143 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2144 dnskey.data[1] == 3)
2146 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2148 foundrsa = ISC_TRUE;
2149 algorithm = "RSASHA1";
2152 foundmd5 = ISC_TRUE;
2153 algorithm = "RSAMD5";
2156 dns_zone_log(zone, ISC_LOG_WARNING,
2157 "weak %s (%u) key found "
2158 "(exponent=3)", algorithm,
2160 if (foundrsa && foundmd5)
2163 dns_rdata_reset(&rdata);
2165 dns_rdataset_disassociate(&rdataset);
2169 dns_db_detachnode(db, &node);
2170 if (version != NULL)
2171 dns_db_closeversion(db, &version, ISC_FALSE);
2176 resume_signingwithkey(dns_zone_t *zone) {
2177 dns_dbnode_t *node = NULL;
2178 dns_dbversion_t *version = NULL;
2179 dns_rdata_t rdata = DNS_RDATA_INIT;
2180 dns_rdataset_t rdataset;
2181 isc_result_t result;
2183 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2184 if (result != ISC_R_SUCCESS)
2187 dns_db_currentversion(zone->db, &version);
2188 dns_rdataset_init(&rdataset);
2189 result = dns_db_findrdataset(zone->db, node, version,
2191 dns_rdatatype_none, 0,
2193 if (result != ISC_R_SUCCESS)
2196 for (result = dns_rdataset_first(&rdataset);
2197 result == ISC_R_SUCCESS;
2198 result = dns_rdataset_next(&rdataset))
2200 dns_rdataset_current(&rdataset, &rdata);
2201 if (rdata.length != 5 || rdata.data[4] != 0) {
2202 dns_rdata_reset(&rdata);
2206 result = zone_signwithkey(zone, rdata.data[0],
2207 (rdata.data[1] << 8) | rdata.data[2],
2208 ISC_TF(rdata.data[3]));
2209 if (result != ISC_R_SUCCESS) {
2210 dns_zone_log(zone, ISC_LOG_ERROR,
2211 "zone_signwithkey failed: %s",
2212 dns_result_totext(result));
2214 dns_rdata_reset(&rdata);
2216 dns_rdataset_disassociate(&rdataset);
2220 dns_db_detachnode(zone->db, &node);
2221 if (version != NULL)
2222 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2227 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2228 dns_nsec3chain_t *nsec3chain, *current;
2229 isc_result_t result;
2231 unsigned int options = 0;
2233 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2234 if (nsec3chain == NULL)
2235 return (ISC_R_NOMEMORY);
2237 nsec3chain->magic = 0;
2238 nsec3chain->done = ISC_FALSE;
2239 nsec3chain->db = NULL;
2240 nsec3chain->dbiterator = NULL;
2241 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2242 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2243 nsec3chain->nsec3param.hash = nsec3param->hash;
2244 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2245 nsec3chain->nsec3param.flags = nsec3param->flags;
2246 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2247 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2248 nsec3chain->nsec3param.salt = nsec3chain->salt;
2249 nsec3chain->seen_nsec = ISC_FALSE;
2250 nsec3chain->delete_nsec = ISC_FALSE;
2251 nsec3chain->save_delete_nsec = ISC_FALSE;
2253 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2255 current = ISC_LIST_NEXT(current, link)) {
2256 if (current->db == zone->db &&
2257 current->nsec3param.hash == nsec3param->hash &&
2258 current->nsec3param.iterations == nsec3param->iterations &&
2259 current->nsec3param.salt_length == nsec3param->salt_length
2260 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2261 nsec3param->salt_length))
2262 current->done = ISC_TRUE;
2265 if (zone->db != NULL) {
2266 dns_db_attach(zone->db, &nsec3chain->db);
2267 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2268 options = DNS_DB_NONSEC3;
2269 result = dns_db_createiterator(nsec3chain->db, options,
2270 &nsec3chain->dbiterator);
2271 if (result == ISC_R_SUCCESS)
2272 dns_dbiterator_first(nsec3chain->dbiterator);
2273 if (result == ISC_R_SUCCESS) {
2274 dns_dbiterator_pause(nsec3chain->dbiterator);
2275 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2278 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2280 zone->nsec3chaintime = now;
2281 if (zone->task != NULL)
2282 zone_settimer(zone, &now);
2286 result = ISC_R_NOTFOUND;
2288 if (nsec3chain != NULL) {
2289 if (nsec3chain->db != NULL)
2290 dns_db_detach(&nsec3chain->db);
2291 if (nsec3chain->dbiterator != NULL)
2292 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2293 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2299 resume_addnsec3chain(dns_zone_t *zone) {
2300 dns_dbnode_t *node = NULL;
2301 dns_dbversion_t *version = NULL;
2302 dns_rdata_t rdata = DNS_RDATA_INIT;
2303 dns_rdataset_t rdataset;
2304 isc_result_t result;
2305 dns_rdata_nsec3param_t nsec3param;
2307 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2308 if (result != ISC_R_SUCCESS)
2311 dns_db_currentversion(zone->db, &version);
2312 dns_rdataset_init(&rdataset);
2313 result = dns_db_findrdataset(zone->db, node, version,
2314 dns_rdatatype_nsec3param,
2315 dns_rdatatype_none, 0,
2317 if (result != ISC_R_SUCCESS)
2320 for (result = dns_rdataset_first(&rdataset);
2321 result == ISC_R_SUCCESS;
2322 result = dns_rdataset_next(&rdataset))
2324 dns_rdataset_current(&rdataset, &rdata);
2325 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2326 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2327 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
2328 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
2329 result = zone_addnsec3chain(zone, &nsec3param);
2330 if (result != ISC_R_SUCCESS) {
2331 dns_zone_log(zone, ISC_LOG_ERROR,
2332 "zone_addnsec3chain failed: %s",
2333 dns_result_totext(result));
2336 dns_rdata_reset(&rdata);
2338 dns_rdataset_disassociate(&rdataset);
2342 dns_db_detachnode(zone->db, &node);
2343 if (version != NULL)
2344 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2348 set_resigntime(dns_zone_t *zone) {
2349 dns_rdataset_t rdataset;
2350 dns_fixedname_t fixed;
2351 unsigned int resign;
2352 isc_result_t result;
2353 isc_uint32_t nanosecs;
2355 dns_rdataset_init(&rdataset);
2356 dns_fixedname_init(&fixed);
2357 result = dns_db_getsigningtime(zone->db, &rdataset,
2358 dns_fixedname_name(&fixed));
2359 if (result != ISC_R_SUCCESS) {
2360 isc_time_settoepoch(&zone->resigntime);
2363 resign = rdataset.resign;
2364 dns_rdataset_disassociate(&rdataset);
2365 isc_random_get(&nanosecs);
2366 nanosecs %= 1000000000;
2367 isc_time_set(&zone->resigntime, resign, nanosecs);
2371 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2372 dns_dbnode_t *node = NULL;
2373 dns_rdataset_t rdataset;
2374 dns_dbversion_t *version = NULL;
2375 dns_rdata_nsec3param_t nsec3param;
2376 isc_boolean_t ok = ISC_FALSE;
2377 isc_result_t result;
2378 dns_rdata_t rdata = DNS_RDATA_INIT;
2379 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
2380 zone_isdynamic(zone) : ISC_FALSE;
2382 dns_rdataset_init(&rdataset);
2383 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2384 if (result != ISC_R_SUCCESS) {
2385 dns_zone_log(zone, ISC_LOG_ERROR,
2386 "nsec3param lookup failure: %s",
2387 dns_result_totext(result));
2390 dns_db_currentversion(db, &version);
2392 result = dns_db_findrdataset(db, node, version,
2393 dns_rdatatype_nsec3param,
2394 dns_rdatatype_none, 0, &rdataset, NULL);
2395 if (result == ISC_R_NOTFOUND) {
2396 result = ISC_R_SUCCESS;
2399 if (result != ISC_R_SUCCESS) {
2400 dns_zone_log(zone, ISC_LOG_ERROR,
2401 "nsec3param lookup failure: %s",
2402 dns_result_totext(result));
2407 * For dynamic zones we must support every algorithm so we can
2408 * regenerate all the NSEC3 chains.
2409 * For non-dynamic zones we only need to find a supported algorithm.
2411 for (result = dns_rdataset_first(&rdataset);
2412 result == ISC_R_SUCCESS;
2413 result = dns_rdataset_next(&rdataset))
2415 dns_rdataset_current(&rdataset, &rdata);
2416 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2417 dns_rdata_reset(&rdata);
2418 INSIST(result == ISC_R_SUCCESS);
2419 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
2420 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
2422 dns_zone_log(zone, ISC_LOG_WARNING,
2423 "nsec3 test \"unknown\" hash algorithm found: %u",
2426 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
2428 dns_zone_log(zone, ISC_LOG_ERROR,
2429 "unsupported nsec3 hash algorithm"
2430 " in dynamic zone: %u",
2432 result = DNS_R_BADZONE;
2433 /* Stop second error message. */
2437 dns_zone_log(zone, ISC_LOG_WARNING,
2438 "unsupported nsec3 hash algorithm: %u",
2443 if (result == ISC_R_NOMORE)
2444 result = ISC_R_SUCCESS;
2447 result = DNS_R_BADZONE;
2448 dns_zone_log(zone, ISC_LOG_ERROR,
2449 "no supported nsec3 hash algorithm");
2453 if (dns_rdataset_isassociated(&rdataset))
2454 dns_rdataset_disassociate(&rdataset);
2455 dns_db_closeversion(db, &version, ISC_FALSE);
2456 dns_db_detachnode(db, &node);
2461 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
2462 isc_result_t result)
2464 unsigned int soacount = 0;
2465 unsigned int nscount = 0;
2466 unsigned int errors = 0;
2467 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
2469 isc_boolean_t needdump = ISC_FALSE;
2470 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2471 unsigned int options;
2476 * Initiate zone transfer? We may need a error code that
2477 * indicates that the "permanent" form does not exist.
2478 * XXX better error feedback to log.
2480 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
2481 if (zone->type == dns_zone_slave ||
2482 zone->type == dns_zone_stub) {
2483 if (result == ISC_R_FILENOTFOUND)
2484 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2486 else if (result != DNS_R_NOMASTERFILE)
2487 dns_zone_log(zone, ISC_LOG_ERROR,
2488 "loading from master file %s "
2491 dns_result_totext(result));
2493 dns_zone_log(zone, ISC_LOG_ERROR,
2494 "loading from master file %s failed: %s",
2496 dns_result_totext(result));
2500 dns_zone_log(zone, ISC_LOG_DEBUG(2),
2501 "number of nodes in database: %u",
2502 dns_db_nodecount(db));
2504 if (result == DNS_R_SEENINCLUDE)
2505 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2507 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2510 * Apply update log, if any, on initial load.
2512 if (zone->journal != NULL &&
2513 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
2514 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
2516 if (zone->type == dns_zone_master &&
2517 (zone->update_acl != NULL || zone->ssutable != NULL))
2518 options = DNS_JOURNALOPT_RESIGN;
2521 result = dns_journal_rollforward2(zone->mctx, db, options,
2522 zone->sigresigninginterval,
2524 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
2525 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
2526 result != ISC_R_RANGE) {
2527 dns_zone_log(zone, ISC_LOG_ERROR,
2528 "journal rollforward failed: %s",
2529 dns_result_totext(result));
2532 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
2533 dns_zone_log(zone, ISC_LOG_ERROR,
2534 "journal rollforward failed: "
2535 "journal out of sync with zone");
2538 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2539 "journal rollforward completed "
2541 dns_result_totext(result));
2542 if (result == ISC_R_SUCCESS)
2543 needdump = ISC_TRUE;
2546 zone->loadtime = loadtime;
2548 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded");
2550 * Obtain ns, soa and cname counts for top of zone.
2553 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
2554 &refresh, &retry, &expire, &minimum,
2556 if (result != ISC_R_SUCCESS) {
2557 dns_zone_log(zone, ISC_LOG_ERROR,
2558 "could not find NS and/or SOA records");
2562 * Master / Slave / Stub zones require both NS and SOA records at
2563 * the top of the zone.
2566 switch (zone->type) {
2567 case dns_zone_master:
2568 case dns_zone_slave:
2570 if (soacount != 1) {
2571 dns_zone_log(zone, ISC_LOG_ERROR,
2572 "has %d SOA records", soacount);
2573 result = DNS_R_BADZONE;
2576 dns_zone_log(zone, ISC_LOG_ERROR,
2577 "has no NS records");
2578 result = DNS_R_BADZONE;
2580 if (result != ISC_R_SUCCESS)
2582 if (zone->type == dns_zone_master && errors != 0) {
2583 result = DNS_R_BADZONE;
2586 if (zone->type != dns_zone_stub) {
2587 result = check_nsec3param(zone, db);
2588 if (result != ISC_R_SUCCESS)
2591 if (zone->type == dns_zone_master &&
2592 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
2593 !integrity_checks(zone, db)) {
2594 result = DNS_R_BADZONE;
2598 if (zone->db != NULL) {
2600 * This is checked in zone_replacedb() for slave zones
2601 * as they don't reload from disk.
2603 result = zone_get_from_db(zone, zone->db, NULL, NULL,
2604 &oldserial, NULL, NULL, NULL,
2606 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2607 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
2608 !isc_serial_gt(serial, oldserial)) {
2609 isc_uint32_t serialmin, serialmax;
2611 INSIST(zone->type == dns_zone_master);
2613 serialmin = (oldserial + 1) & 0xffffffffU;
2614 serialmax = (oldserial + 0x7fffffffU) &
2616 dns_zone_log(zone, ISC_LOG_ERROR,
2617 "ixfr-from-differences: "
2618 "new serial (%u) out of range "
2619 "[%u - %u]", serial, serialmin,
2621 result = DNS_R_BADZONE;
2623 } else if (!isc_serial_ge(serial, oldserial))
2624 dns_zone_log(zone, ISC_LOG_ERROR,
2625 "zone serial has gone backwards");
2626 else if (serial == oldserial && !hasinclude)
2627 dns_zone_log(zone, ISC_LOG_ERROR,
2628 "zone serial unchanged. "
2629 "zone may fail to transfer "
2633 if (zone->type == dns_zone_master &&
2634 (zone->update_acl != NULL || zone->ssutable != NULL) &&
2635 zone->sigresigninginterval < (3 * refresh) &&
2636 dns_db_issecure(db))
2638 dns_zone_log(zone, ISC_LOG_WARNING,
2639 "sig-re-signing-interval less than "
2643 zone->refresh = RANGE(refresh,
2644 zone->minrefresh, zone->maxrefresh);
2645 zone->retry = RANGE(retry,
2646 zone->minretry, zone->maxretry);
2647 zone->expire = RANGE(expire, zone->refresh + zone->retry,
2649 zone->minimum = minimum;
2650 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
2652 if (zone->type == dns_zone_slave ||
2653 zone->type == dns_zone_stub) {
2657 result = isc_file_getmodtime(zone->journal, &t);
2658 if (result != ISC_R_SUCCESS)
2659 result = isc_file_getmodtime(zone->masterfile,
2661 if (result == ISC_R_SUCCESS)
2662 DNS_ZONE_TIME_ADD(&t, zone->expire,
2665 DNS_ZONE_TIME_ADD(&now, zone->retry,
2668 delay = isc_random_jitter(zone->retry,
2669 (zone->retry * 3) / 4);
2670 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
2671 if (isc_time_compare(&zone->refreshtime,
2672 &zone->expiretime) >= 0)
2673 zone->refreshtime = now;
2677 UNEXPECTED_ERROR(__FILE__, __LINE__,
2678 "unexpected zone type %d", zone->type);
2679 result = ISC_R_UNEXPECTED;
2684 * Check for weak DNSKEY's.
2686 if (zone->type == dns_zone_master)
2687 zone_check_dnskeys(zone, db);
2690 /* destroy notification example. */
2692 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
2693 DNS_EVENT_DBDESTROYED,
2694 dns_zonemgr_dbdestroyed,
2696 sizeof(isc_event_t));
2697 dns_db_ondestroy(db, zone->task, &e);
2701 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2702 if (zone->db != NULL) {
2703 result = zone_replacedb(zone, db, ISC_FALSE);
2704 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2705 if (result != ISC_R_SUCCESS)
2708 zone_attachdb(zone, db);
2709 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2710 DNS_ZONE_SETFLAG(zone,
2711 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
2713 result = ISC_R_SUCCESS;
2715 zone_needdump(zone, DNS_DUMP_DELAY);
2716 if (zone->task != NULL) {
2717 if (zone->type == dns_zone_master) {
2718 set_resigntime(zone);
2719 resume_signingwithkey(zone);
2720 resume_addnsec3chain(zone);
2722 zone_settimer(zone, &now);
2725 if (! dns_db_ispersistent(db))
2726 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
2727 dns_db_issecure(db) ? " (signed)" : "");
2732 if (zone->type == dns_zone_slave ||
2733 zone->type == dns_zone_stub) {
2734 if (zone->journal != NULL)
2735 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
2736 if (zone->masterfile != NULL)
2737 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
2739 /* Mark the zone for immediate refresh. */
2740 zone->refreshtime = now;
2741 if (zone->task != NULL)
2742 zone_settimer(zone, &now);
2743 result = ISC_R_SUCCESS;
2744 } else if (zone->type == dns_zone_master)
2745 dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
2749 static isc_boolean_t
2750 exit_check(dns_zone_t *zone) {
2752 REQUIRE(LOCKED_ZONE(zone));
2754 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
2758 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2760 INSIST(isc_refcount_current(&zone->erefs) == 0);
2766 static isc_boolean_t
2767 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
2768 isc_result_t result;
2769 char namebuf[DNS_NAME_FORMATSIZE];
2770 char altbuf[DNS_NAME_FORMATSIZE];
2771 dns_fixedname_t fixed;
2772 dns_name_t *foundname;
2775 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
2778 if (zone->type == dns_zone_master)
2779 level = ISC_LOG_ERROR;
2781 level = ISC_LOG_WARNING;
2783 dns_fixedname_init(&fixed);
2784 foundname = dns_fixedname_name(&fixed);
2786 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2787 0, 0, NULL, foundname, NULL, NULL);
2788 if (result == ISC_R_SUCCESS)
2791 if (result == DNS_R_NXRRSET) {
2792 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2793 0, 0, NULL, foundname, NULL, NULL);
2794 if (result == ISC_R_SUCCESS)
2798 dns_name_format(name, namebuf, sizeof namebuf);
2799 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2800 result == DNS_R_EMPTYNAME) {
2801 dns_zone_log(zone, level,
2802 "NS '%s' has no address records (A or AAAA)",
2804 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2808 if (result == DNS_R_CNAME) {
2809 dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
2811 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2815 if (result == DNS_R_DNAME) {
2816 dns_name_format(foundname, altbuf, sizeof altbuf);
2817 dns_zone_log(zone, level,
2818 "NS '%s' is below a DNAME '%s' (illegal)",
2820 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2828 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
2829 dns_dbversion_t *version, unsigned int *nscount,
2830 unsigned int *errors)
2832 isc_result_t result;
2833 unsigned int count = 0;
2834 unsigned int ecount = 0;
2835 dns_rdataset_t rdataset;
2839 dns_rdataset_init(&rdataset);
2840 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
2841 dns_rdatatype_none, 0, &rdataset, NULL);
2842 if (result == ISC_R_NOTFOUND)
2844 if (result != ISC_R_SUCCESS)
2845 goto invalidate_rdataset;
2847 result = dns_rdataset_first(&rdataset);
2848 while (result == ISC_R_SUCCESS) {
2849 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
2850 (zone->type == dns_zone_master ||
2851 zone->type == dns_zone_slave)) {
2852 dns_rdata_init(&rdata);
2853 dns_rdataset_current(&rdataset, &rdata);
2854 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2855 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2856 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
2857 !zone_check_ns(zone, db, &ns.name))
2861 result = dns_rdataset_next(&rdataset);
2863 dns_rdataset_disassociate(&rdataset);
2866 if (nscount != NULL)
2871 result = ISC_R_SUCCESS;
2873 invalidate_rdataset:
2874 dns_rdataset_invalidate(&rdataset);
2880 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
2881 unsigned int *soacount,
2882 isc_uint32_t *serial, isc_uint32_t *refresh,
2883 isc_uint32_t *retry, isc_uint32_t *expire,
2884 isc_uint32_t *minimum)
2886 isc_result_t result;
2888 dns_rdataset_t rdataset;
2889 dns_rdata_t rdata = DNS_RDATA_INIT;
2890 dns_rdata_soa_t soa;
2892 dns_rdataset_init(&rdataset);
2893 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
2894 dns_rdatatype_none, 0, &rdataset, NULL);
2895 if (result == ISC_R_NOTFOUND) {
2896 if (soacount != NULL)
2900 if (refresh != NULL)
2906 if (minimum != NULL)
2908 result = ISC_R_SUCCESS;
2909 goto invalidate_rdataset;
2911 if (result != ISC_R_SUCCESS)
2912 goto invalidate_rdataset;
2915 result = dns_rdataset_first(&rdataset);
2916 while (result == ISC_R_SUCCESS) {
2917 dns_rdata_init(&rdata);
2918 dns_rdataset_current(&rdataset, &rdata);
2921 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2922 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2925 result = dns_rdataset_next(&rdataset);
2926 dns_rdata_reset(&rdata);
2928 dns_rdataset_disassociate(&rdataset);
2930 if (soacount != NULL)
2935 *serial = soa.serial;
2936 if (refresh != NULL)
2937 *refresh = soa.refresh;
2941 *expire = soa.expire;
2942 if (minimum != NULL)
2943 *minimum = soa.minimum;
2946 result = ISC_R_SUCCESS;
2948 invalidate_rdataset:
2949 dns_rdataset_invalidate(&rdataset);
2955 * zone must be locked.
2958 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
2959 unsigned int *soacount, isc_uint32_t *serial,
2960 isc_uint32_t *refresh, isc_uint32_t *retry,
2961 isc_uint32_t *expire, isc_uint32_t *minimum,
2962 unsigned int *errors)
2964 dns_dbversion_t *version;
2965 isc_result_t result;
2966 isc_result_t answer = ISC_R_SUCCESS;
2969 REQUIRE(db != NULL);
2970 REQUIRE(zone != NULL);
2973 dns_db_currentversion(db, &version);
2976 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2977 if (result != ISC_R_SUCCESS) {
2982 if (nscount != NULL || errors != NULL) {
2983 result = zone_count_ns_rr(zone, db, node, version,
2985 if (result != ISC_R_SUCCESS)
2989 if (soacount != NULL || serial != NULL || refresh != NULL
2990 || retry != NULL || expire != NULL || minimum != NULL) {
2991 result = zone_load_soa_rr(db, node, version, soacount,
2992 serial, refresh, retry, expire,
2994 if (result != ISC_R_SUCCESS)
2998 dns_db_detachnode(db, &node);
3000 dns_db_closeversion(db, &version, ISC_FALSE);
3006 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
3007 REQUIRE(DNS_ZONE_VALID(source));
3008 REQUIRE(target != NULL && *target == NULL);
3009 isc_refcount_increment(&source->erefs, NULL);
3014 dns_zone_detach(dns_zone_t **zonep) {
3017 isc_boolean_t free_now = ISC_FALSE;
3019 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3023 isc_refcount_decrement(&zone->erefs, &refs);
3028 * We just detached the last external reference.
3030 if (zone->task != NULL) {
3032 * This zone is being managed. Post
3033 * its control event and let it clean
3034 * up synchronously in the context of
3037 isc_event_t *ev = &zone->ctlevent;
3038 isc_task_send(zone->task, &ev);
3041 * This zone is not being managed; it has
3042 * no task and can have no outstanding
3043 * events. Free it immediately.
3046 * Unmanaged zones should not have non-null views;
3047 * we have no way of detaching from the view here
3048 * without causing deadlock because this code is called
3049 * with the view already locked.
3051 INSIST(zone->view == NULL);
3052 free_now = ISC_TRUE;
3062 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3063 REQUIRE(DNS_ZONE_VALID(source));
3064 REQUIRE(target != NULL && *target == NULL);
3066 zone_iattach(source, target);
3067 UNLOCK_ZONE(source);
3071 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3074 * 'source' locked by caller.
3076 REQUIRE(LOCKED_ZONE(source));
3077 REQUIRE(DNS_ZONE_VALID(source));
3078 REQUIRE(target != NULL && *target == NULL);
3079 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
3081 INSIST(source->irefs != 0);
3086 zone_idetach(dns_zone_t **zonep) {
3090 * 'zone' locked by caller.
3092 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3094 REQUIRE(LOCKED_ZONE(*zonep));
3097 INSIST(zone->irefs > 0);
3099 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
3103 dns_zone_idetach(dns_zone_t **zonep) {
3105 isc_boolean_t free_needed;
3107 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3112 INSIST(zone->irefs > 0);
3114 free_needed = exit_check(zone);
3121 dns_zone_getmctx(dns_zone_t *zone) {
3122 REQUIRE(DNS_ZONE_VALID(zone));
3124 return (zone->mctx);
3128 dns_zone_getmgr(dns_zone_t *zone) {
3129 REQUIRE(DNS_ZONE_VALID(zone));
3131 return (zone->zmgr);
3135 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
3136 REQUIRE(DNS_ZONE_VALID(zone));
3140 DNS_ZONE_SETFLAG(zone, flags);
3142 DNS_ZONE_CLRFLAG(zone, flags);
3147 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
3149 REQUIRE(DNS_ZONE_VALID(zone));
3153 zone->options |= option;
3155 zone->options &= ~option;
3160 dns_zone_getoptions(dns_zone_t *zone) {
3162 REQUIRE(DNS_ZONE_VALID(zone));
3164 return (zone->options);
3168 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3169 REQUIRE(DNS_ZONE_VALID(zone));
3172 zone->xfrsource4 = *xfrsource;
3175 return (ISC_R_SUCCESS);
3179 dns_zone_getxfrsource4(dns_zone_t *zone) {
3180 REQUIRE(DNS_ZONE_VALID(zone));
3181 return (&zone->xfrsource4);
3185 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3186 REQUIRE(DNS_ZONE_VALID(zone));
3189 zone->xfrsource6 = *xfrsource;
3192 return (ISC_R_SUCCESS);
3196 dns_zone_getxfrsource6(dns_zone_t *zone) {
3197 REQUIRE(DNS_ZONE_VALID(zone));
3198 return (&zone->xfrsource6);
3202 dns_zone_setaltxfrsource4(dns_zone_t *zone,
3203 const isc_sockaddr_t *altxfrsource)
3205 REQUIRE(DNS_ZONE_VALID(zone));
3208 zone->altxfrsource4 = *altxfrsource;
3211 return (ISC_R_SUCCESS);
3215 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
3216 REQUIRE(DNS_ZONE_VALID(zone));
3217 return (&zone->altxfrsource4);
3221 dns_zone_setaltxfrsource6(dns_zone_t *zone,
3222 const isc_sockaddr_t *altxfrsource)
3224 REQUIRE(DNS_ZONE_VALID(zone));
3227 zone->altxfrsource6 = *altxfrsource;
3230 return (ISC_R_SUCCESS);
3234 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
3235 REQUIRE(DNS_ZONE_VALID(zone));
3236 return (&zone->altxfrsource6);
3240 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3241 REQUIRE(DNS_ZONE_VALID(zone));
3244 zone->notifysrc4 = *notifysrc;
3247 return (ISC_R_SUCCESS);
3251 dns_zone_getnotifysrc4(dns_zone_t *zone) {
3252 REQUIRE(DNS_ZONE_VALID(zone));
3253 return (&zone->notifysrc4);
3257 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3258 REQUIRE(DNS_ZONE_VALID(zone));
3261 zone->notifysrc6 = *notifysrc;
3264 return (ISC_R_SUCCESS);
3268 dns_zone_getnotifysrc6(dns_zone_t *zone) {
3269 REQUIRE(DNS_ZONE_VALID(zone));
3270 return (&zone->notifysrc6);
3274 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
3277 isc_sockaddr_t *new;
3279 REQUIRE(DNS_ZONE_VALID(zone));
3280 REQUIRE(count == 0 || notify != NULL);
3283 if (zone->notify != NULL) {
3284 isc_mem_put(zone->mctx, zone->notify,
3285 zone->notifycnt * sizeof(*new));
3286 zone->notify = NULL;
3287 zone->notifycnt = 0;
3290 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3293 return (ISC_R_NOMEMORY);
3295 memcpy(new, notify, count * sizeof(*new));
3297 zone->notifycnt = count;
3300 return (ISC_R_SUCCESS);
3304 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
3307 isc_result_t result;
3309 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
3313 static isc_boolean_t
3314 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
3319 for (i = 0; i < count; i++)
3320 if (!isc_sockaddr_equal(&old[i], &new[i]))
3325 static isc_boolean_t
3326 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
3329 if (old == NULL && new == NULL)
3331 if (old == NULL || new == NULL)
3334 for (i = 0; i < count; i++) {
3335 if (old[i] == NULL && new[i] == NULL)
3337 if (old[i] == NULL || new[i] == NULL ||
3338 !dns_name_equal(old[i], new[i]))
3345 dns_zone_setmasterswithkeys(dns_zone_t *zone,
3346 const isc_sockaddr_t *masters,
3347 dns_name_t **keynames,
3350 isc_sockaddr_t *new;
3351 isc_result_t result = ISC_R_SUCCESS;
3352 dns_name_t **newname;
3353 isc_boolean_t *newok;
3356 REQUIRE(DNS_ZONE_VALID(zone));
3357 REQUIRE(count == 0 || masters != NULL);
3358 if (keynames != NULL) {
3359 REQUIRE(count != 0);
3364 * The refresh code assumes that 'masters' wouldn't change under it.
3365 * If it will change then kill off any current refresh in progress
3366 * and update the masters info. If it won't change then we can just
3369 if (count != zone->masterscnt ||
3370 !same_masters(zone->masters, masters, count) ||
3371 !same_keynames(zone->masterkeynames, keynames, count)) {
3372 if (zone->request != NULL)
3373 dns_request_cancel(zone->request);
3376 if (zone->masters != NULL) {
3377 isc_mem_put(zone->mctx, zone->masters,
3378 zone->masterscnt * sizeof(*new));
3379 zone->masters = NULL;
3381 if (zone->masterkeynames != NULL) {
3382 for (i = 0; i < zone->masterscnt; i++) {
3383 if (zone->masterkeynames[i] != NULL) {
3384 dns_name_free(zone->masterkeynames[i],
3386 isc_mem_put(zone->mctx,
3387 zone->masterkeynames[i],
3388 sizeof(dns_name_t));
3389 zone->masterkeynames[i] = NULL;
3392 isc_mem_put(zone->mctx, zone->masterkeynames,
3393 zone->masterscnt * sizeof(dns_name_t *));
3394 zone->masterkeynames = NULL;
3396 if (zone->mastersok != NULL) {
3397 isc_mem_put(zone->mctx, zone->mastersok,
3398 zone->masterscnt * sizeof(isc_boolean_t));
3399 zone->mastersok = NULL;
3401 zone->masterscnt = 0;
3403 * If count == 0, don't allocate any space for masters, mastersok or
3404 * keynames so internally, those pointers are NULL if count == 0
3410 * masters must contain count elements!
3412 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3414 result = ISC_R_NOMEMORY;
3417 memcpy(new, masters, count * sizeof(*new));
3420 * Similarly for mastersok.
3422 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
3423 if (newok == NULL) {
3424 result = ISC_R_NOMEMORY;
3425 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3428 for (i = 0; i < count; i++)
3429 newok[i] = ISC_FALSE;
3432 * if keynames is non-NULL, it must contain count elements!
3435 if (keynames != NULL) {
3436 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
3437 if (newname == NULL) {
3438 result = ISC_R_NOMEMORY;
3439 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3440 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
3443 for (i = 0; i < count; i++)
3445 for (i = 0; i < count; i++) {
3446 if (keynames[i] != NULL) {
3447 newname[i] = isc_mem_get(zone->mctx,
3448 sizeof(dns_name_t));
3449 if (newname[i] == NULL)
3451 dns_name_init(newname[i], NULL);
3452 result = dns_name_dup(keynames[i], zone->mctx,
3454 if (result != ISC_R_SUCCESS) {
3456 for (i = 0; i < count; i++)
3457 if (newname[i] != NULL)
3461 isc_mem_put(zone->mctx, new,
3462 count * sizeof(*new));
3463 isc_mem_put(zone->mctx, newok,
3464 count * sizeof(*newok));
3465 isc_mem_put(zone->mctx, newname,
3466 count * sizeof(*newname));
3474 * Everything is ok so attach to the zone.
3476 zone->masters = new;
3477 zone->mastersok = newok;
3478 zone->masterkeynames = newname;
3479 zone->masterscnt = count;
3480 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
3488 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
3489 isc_result_t result = ISC_R_SUCCESS;
3491 REQUIRE(DNS_ZONE_VALID(zone));
3493 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3494 if (zone->db == NULL)
3495 result = DNS_R_NOTLOADED;
3497 dns_db_attach(zone->db, dpb);
3498 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3504 * Co-ordinates the starting of routine jobs.
3508 dns_zone_maintenance(dns_zone_t *zone) {
3509 const char me[] = "dns_zone_maintenance";
3512 REQUIRE(DNS_ZONE_VALID(zone));
3517 zone_settimer(zone, &now);
3521 static inline isc_boolean_t
3522 was_dumping(dns_zone_t *zone) {
3523 isc_boolean_t dumping;
3525 REQUIRE(LOCKED_ZONE(zone));
3527 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
3528 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3530 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3531 isc_time_settoepoch(&zone->dumptime);
3536 #define MAXZONEKEYS 10
3539 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3542 dns_diff_t temp_diff;
3543 isc_result_t result;
3546 * Create a singleton diff.
3548 dns_diff_init(diff->mctx, &temp_diff);
3549 temp_diff.resign = diff->resign;
3550 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3553 * Apply it to the database.
3555 result = dns_diff_apply(&temp_diff, db, ver);
3556 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3557 if (result != ISC_R_SUCCESS) {
3558 dns_difftuple_free(tuple);
3563 * Merge it into the current pending journal entry.
3565 dns_diff_appendminimal(diff, tuple);
3568 * Do not clear temp_diff.
3570 return (ISC_R_SUCCESS);
3574 increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
3575 dns_diff_t *diff, isc_mem_t *mctx)
3577 dns_difftuple_t *deltuple = NULL;
3578 dns_difftuple_t *addtuple = NULL;
3579 isc_uint32_t serial;
3580 isc_result_t result;
3582 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3583 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3584 addtuple->op = DNS_DIFFOP_ADD;
3586 serial = dns_soa_getserial(&addtuple->rdata);
3589 serial = (serial + 1) & 0xFFFFFFFF;
3593 dns_soa_setserial(serial, &addtuple->rdata);
3594 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3595 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3596 result = ISC_R_SUCCESS;
3599 if (addtuple != NULL)
3600 dns_difftuple_free(&addtuple);
3601 if (deltuple != NULL)
3602 dns_difftuple_free(&deltuple);
3607 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3608 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3611 dns_difftuple_t *tuple = NULL;
3612 isc_result_t result;
3613 result = dns_difftuple_create(diff->mctx, op,
3614 name, ttl, rdata, &tuple);
3615 if (result != ISC_R_SUCCESS)
3617 return (do_one_tuple(&tuple, db, ver, diff));
3620 static isc_boolean_t
3621 ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) {
3622 isc_boolean_t ret = ISC_FALSE;
3623 isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE;
3624 isc_result_t result;
3625 dns_dbnode_t *node = NULL;
3626 dns_rdataset_t rdataset;
3627 dns_rdata_t rdata = DNS_RDATA_INIT;
3628 dns_rdata_dnskey_t dnskey;
3630 dns_rdataset_init(&rdataset);
3631 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3632 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
3634 CHECK(dns_rdataset_first(&rdataset));
3635 while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) {
3636 dns_rdataset_current(&rdataset, &rdata);
3637 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3638 if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
3639 == DNS_KEYOWNER_ZONE) {
3640 if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0)
3641 have_ksk = ISC_TRUE;
3643 have_nonksk = ISC_TRUE;
3645 dns_rdata_reset(&rdata);
3646 result = dns_rdataset_next(&rdataset);
3648 if (have_ksk && have_nonksk)
3651 if (dns_rdataset_isassociated(&rdataset))
3652 dns_rdataset_disassociate(&rdataset);
3654 dns_db_detachnode(db, &node);
3659 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3660 isc_mem_t *mctx, unsigned int maxkeys,
3661 dst_key_t **keys, unsigned int *nkeys)
3663 isc_result_t result;
3664 dns_dbnode_t *node = NULL;
3665 const char *directory = dns_zone_getkeydirectory(zone);
3667 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3668 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
3669 directory, mctx, maxkeys, keys,
3671 if (result == ISC_R_NOTFOUND)
3672 result = ISC_R_SUCCESS;
3675 dns_db_detachnode(db, &node);
3680 offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
3681 dns_ttl_t ttl, dns_rdata_t *rdata)
3683 isc_result_t result;
3685 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
3686 return (ISC_R_SUCCESS);
3687 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
3689 if (result != ISC_R_SUCCESS)
3691 rdata->flags |= DNS_RDATA_OFFLINE;
3692 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3698 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
3702 zone->key_expiry = when;
3704 dns_zone_log(zone, ISC_LOG_ERROR,
3705 "DNSKEY RRSIG(s) have expired");
3706 isc_time_settoepoch(&zone->keywarntime);
3707 } else if (when < now + 7 * 24 * 3600) {
3708 dns_zone_log(zone, ISC_LOG_WARNING,
3709 "DNSKEY RRSIG(s) will expire at %u",
3710 when); /* XXXMPA convert to date. */
3712 delta--; /* loop prevention */
3713 delta /= 24 * 3600; /* to whole days */
3714 delta *= 24 * 3600; /* to seconds */
3715 isc_time_set(&zone->keywarntime, when - delta, 0);
3717 dns_zone_log(zone, ISC_LOG_NOTICE, /* XXMPA ISC_LOG_DEBUG(1) */
3718 "setting keywarntime to %u - 7 days",
3719 when); /* XXXMPA convert to date. */
3720 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
3725 * Delete expired RRsigs and any RRsigs we are about to re-sign.
3726 * See also update.c:del_keysigs().
3729 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3730 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3731 unsigned int nkeys, isc_stdtime_t now)
3733 isc_result_t result;
3734 dns_dbnode_t *node = NULL;
3735 dns_rdataset_t rdataset;
3736 dns_rdata_t rdata = DNS_RDATA_INIT;
3738 dns_rdata_rrsig_t rrsig;
3739 isc_boolean_t found;
3740 isc_stdtime_t warn = 0, maybe = 0;
3742 dns_rdataset_init(&rdataset);
3744 if (type == dns_rdatatype_nsec3)
3745 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3747 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3748 if (result == ISC_R_NOTFOUND)
3749 return (ISC_R_SUCCESS);
3750 if (result != ISC_R_SUCCESS)
3752 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
3753 (isc_stdtime_t) 0, &rdataset, NULL);
3754 dns_db_detachnode(db, &node);
3756 if (result == ISC_R_NOTFOUND)
3757 return (ISC_R_SUCCESS);
3758 if (result != ISC_R_SUCCESS)
3761 for (result = dns_rdataset_first(&rdataset);
3762 result == ISC_R_SUCCESS;
3763 result = dns_rdataset_next(&rdataset)) {
3764 dns_rdataset_current(&rdataset, &rdata);
3765 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
3766 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3768 if (type != dns_rdatatype_dnskey) {
3769 result = update_one_rr(db, ver, diff,
3770 DNS_DIFFOP_DELRESIGN, name,
3771 rdataset.ttl, &rdata);
3772 dns_rdata_reset(&rdata);
3773 if (result != ISC_R_SUCCESS)
3779 * RRSIG(DNSKEY) requires special processing.
3782 for (i = 0; i < nkeys; i++) {
3783 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
3784 rrsig.keyid == dst_key_id(keys[i])) {
3787 * Mark offline RRSIG(DNSKEY).
3788 * We want the earliest offline expire time
3789 * iff there is a new offline signature.
3791 if (!dst_key_isprivate(keys[i])) {
3793 warn > rrsig.timeexpire)
3794 warn = rrsig.timeexpire;
3795 if (rdata.flags & DNS_RDATA_OFFLINE) {
3797 maybe > rrsig.timeexpire)
3805 warn > rrsig.timeexpire)
3806 warn = rrsig.timeexpire;
3807 result = offline(db, ver, diff, name,
3808 rdataset.ttl, &rdata);
3811 result = update_one_rr(db, ver, diff,
3812 DNS_DIFFOP_DELRESIGN,
3819 * If there is not a matching DNSKEY then
3823 result = update_one_rr(db, ver, diff,
3824 DNS_DIFFOP_DELRESIGN, name,
3825 rdataset.ttl, &rdata);
3826 dns_rdata_reset(&rdata);
3827 if (result != ISC_R_SUCCESS)
3830 dns_rdataset_disassociate(&rdataset);
3831 if (result == ISC_R_NOMORE)
3832 result = ISC_R_SUCCESS;
3834 set_key_expiry_warning(zone, warn, now);
3837 dns_db_detachnode(db, &node);
3842 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3843 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3844 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
3845 isc_stdtime_t expire, isc_boolean_t check_ksk)
3847 isc_result_t result;
3848 dns_dbnode_t *node = NULL;
3849 dns_rdataset_t rdataset;
3850 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
3851 unsigned char data[1024]; /* XXX */
3852 isc_buffer_t buffer;
3855 dns_rdataset_init(&rdataset);
3856 isc_buffer_init(&buffer, data, sizeof(data));
3858 if (type == dns_rdatatype_nsec3)
3859 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3861 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3862 if (result == ISC_R_NOTFOUND)
3863 return (ISC_R_SUCCESS);
3864 if (result != ISC_R_SUCCESS)
3866 result = dns_db_findrdataset(db, node, ver, type, 0,
3867 (isc_stdtime_t) 0, &rdataset, NULL);
3868 dns_db_detachnode(db, &node);
3869 if (result == ISC_R_NOTFOUND)
3870 return (ISC_R_SUCCESS);
3871 if (result != ISC_R_SUCCESS)
3874 for (i = 0; i < nkeys; i++) {
3875 if (check_ksk && type != dns_rdatatype_dnskey &&
3876 (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0)
3878 if (!dst_key_isprivate(keys[i]))
3880 /* Calculate the signature, creating a RRSIG RDATA. */
3881 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
3882 &inception, &expire,
3883 mctx, &buffer, &sig_rdata));
3884 /* Update the database and journal with the RRSIG. */
3885 /* XXX inefficient - will cause dataset merging */
3886 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3887 name, rdataset.ttl, &sig_rdata));
3888 dns_rdata_reset(&sig_rdata);
3889 isc_buffer_init(&buffer, data, sizeof(data));
3893 if (dns_rdataset_isassociated(&rdataset))
3894 dns_rdataset_disassociate(&rdataset);
3896 dns_db_detachnode(db, &node);
3901 zone_resigninc(dns_zone_t *zone) {
3902 const char *journalfile;
3903 dns_db_t *db = NULL;
3904 dns_dbversion_t *version = NULL;
3905 dns_diff_t sig_diff;
3906 dns_fixedname_t fixed;
3908 dns_rdataset_t rdataset;
3909 dns_rdatatype_t covers;
3910 dst_key_t *zone_keys[MAXZONEKEYS];
3911 isc_boolean_t check_ksk;
3912 isc_result_t result;
3913 isc_stdtime_t now, inception, soaexpire, expire, stop;
3914 isc_uint32_t jitter;
3916 unsigned int nkeys = 0;
3917 unsigned int resign;
3919 dns_rdataset_init(&rdataset);
3920 dns_fixedname_init(&fixed);
3921 dns_diff_init(zone->mctx, &sig_diff);
3922 sig_diff.resign = zone->sigresigninginterval;
3925 * Updates are disabled. Pause for 5 minutes.
3927 if (zone->update_disabled) {
3928 result = ISC_R_FAILURE;
3932 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3933 dns_db_attach(zone->db, &db);
3934 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3936 result = dns_db_newversion(db, &version);
3937 if (result != ISC_R_SUCCESS) {
3938 dns_zone_log(zone, ISC_LOG_ERROR,
3939 "zone_resigninc:dns_db_newversion -> %s\n",
3940 dns_result_totext(result));
3944 result = find_zone_keys(zone, db, version, zone->mctx, MAXZONEKEYS,
3946 if (result != ISC_R_SUCCESS) {
3947 dns_zone_log(zone, ISC_LOG_ERROR,
3948 "zone_resigninc:find_zone_keys -> %s\n",
3949 dns_result_totext(result));
3953 isc_stdtime_get(&now);
3954 inception = now - 3600; /* Allow for clock skew. */
3955 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
3957 * Spread out signatures over time if they happen to be
3958 * clumped. We don't do this for each add_sigs() call as
3959 * we still want some clustering to occur.
3961 isc_random_get(&jitter);
3962 expire = soaexpire - jitter % 3600;
3965 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
3967 check_ksk = ksk_sanity(db, version);
3969 name = dns_fixedname_name(&fixed);
3970 result = dns_db_getsigningtime(db, &rdataset, name);
3971 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
3972 dns_zone_log(zone, ISC_LOG_ERROR,
3973 "zone_resigninc:dns_db_getsigningtime -> %s\n",
3974 dns_result_totext(result));
3978 while (result == ISC_R_SUCCESS) {
3979 resign = rdataset.resign;
3980 covers = rdataset.covers;
3982 * Stop if we hit the SOA as that means we have walked the
3983 * entire zone. The SOA record should always be the most
3986 /* XXXMPA increase number of RRsets signed pre call */
3987 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
3990 * Ensure that we don't loop resigning the SOA.
3992 if (covers == dns_rdatatype_soa)
3993 dns_db_resigned(db, &rdataset, version);
3994 dns_rdataset_disassociate(&rdataset);
3998 dns_db_resigned(db, &rdataset, version);
3999 dns_rdataset_disassociate(&rdataset);
4001 result = del_sigs(zone, db, version, name, covers, &sig_diff,
4002 zone_keys, nkeys, now);
4003 if (result != ISC_R_SUCCESS) {
4004 dns_zone_log(zone, ISC_LOG_ERROR,
4005 "zone_resigninc:del_sigs -> %s\n",
4006 dns_result_totext(result));
4009 result = add_sigs(db, version, name, covers, &sig_diff,
4010 zone_keys, nkeys, zone->mctx, inception,
4012 if (result != ISC_R_SUCCESS) {
4013 dns_zone_log(zone, ISC_LOG_ERROR,
4014 "zone_resigninc:add_sigs -> %s\n",
4015 dns_result_totext(result));
4018 result = dns_db_getsigningtime(db, &rdataset,
4019 dns_fixedname_name(&fixed));
4020 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
4021 result = ISC_R_SUCCESS;
4024 if (result != ISC_R_SUCCESS)
4025 dns_zone_log(zone, ISC_LOG_ERROR,
4026 "zone_resigninc:dns_db_getsigningtime -> %s\n",
4027 dns_result_totext(result));
4030 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
4033 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
4034 &sig_diff, zone_keys, nkeys, now);
4035 if (result != ISC_R_SUCCESS) {
4036 dns_zone_log(zone, ISC_LOG_ERROR,
4037 "zone_resigninc:del_sigs -> %s\n",
4038 dns_result_totext(result));
4042 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
4043 if (result != ISC_R_SUCCESS) {
4044 dns_zone_log(zone, ISC_LOG_ERROR,
4045 "zone_resigninc:increment_soa_serial -> %s\n",
4046 dns_result_totext(result));
4051 * Generate maximum life time signatures so that the above loop
4052 * termination is sensible.
4054 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
4055 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
4056 soaexpire, check_ksk);
4057 if (result != ISC_R_SUCCESS) {
4058 dns_zone_log(zone, ISC_LOG_ERROR,
4059 "zone_resigninc:add_sigs -> %s\n",
4060 dns_result_totext(result));
4064 journalfile = dns_zone_getjournal(zone);
4065 if (journalfile != NULL) {
4066 dns_journal_t *journal = NULL;
4067 result = dns_journal_open(zone->mctx, journalfile,
4068 ISC_TRUE, &journal);
4069 if (result != ISC_R_SUCCESS) {
4070 dns_zone_log(zone, ISC_LOG_ERROR,
4071 "zone_resigninc:dns_journal_open -> %s\n",
4072 dns_result_totext(result));
4076 result = dns_journal_write_transaction(journal, &sig_diff);
4077 dns_journal_destroy(&journal);
4078 if (result != ISC_R_SUCCESS) {
4079 dns_zone_log(zone, ISC_LOG_ERROR,
4080 "zone_resigninc:dns_journal_write_transaction -> %s\n",
4081 dns_result_totext(result));
4087 * Everything has succeeded. Commit the changes.
4089 dns_db_closeversion(db, &version, ISC_TRUE);
4092 dns_diff_clear(&sig_diff);
4093 for (i = 0; i < nkeys; i++)
4094 dst_key_free(&zone_keys[i]);
4095 if (version != NULL) {
4096 dns_db_closeversion(zone->db, &version, ISC_FALSE);
4098 } else if (db != NULL)
4100 if (result == ISC_R_SUCCESS) {
4101 set_resigntime(zone);
4103 zone_needdump(zone, DNS_DUMP_DELAY);
4104 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
4108 * Something failed. Retry in 5 minutes.
4110 isc_interval_t ival;
4111 isc_interval_set(&ival, 300, 0);
4112 isc_time_nowplusinterval(&zone->resigntime, &ival);
4117 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
4118 dns_name_t *newname, isc_boolean_t bottom)
4120 isc_result_t result;
4121 dns_dbiterator_t *dbit = NULL;
4122 dns_rdatasetiter_t *rdsit = NULL;
4123 dns_dbnode_t *node = NULL;
4125 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
4126 CHECK(dns_dbiterator_seek(dbit, oldname));
4128 result = dns_dbiterator_next(dbit);
4129 if (result == ISC_R_NOMORE)
4130 CHECK(dns_dbiterator_first(dbit));
4131 CHECK(dns_dbiterator_current(dbit, &node, newname));
4132 if (bottom && dns_name_issubdomain(newname, oldname) &&
4133 !dns_name_equal(newname, oldname)) {
4134 dns_db_detachnode(db, &node);
4138 * Is this node empty?
4140 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
4141 result = dns_rdatasetiter_first(rdsit);
4142 dns_db_detachnode(db, &node);
4143 dns_rdatasetiter_destroy(&rdsit);
4144 if (result != ISC_R_NOMORE)
4149 dns_db_detachnode(db, &node);
4151 dns_dbiterator_destroy(&dbit);
4156 set_bit(unsigned char *array, unsigned int index) {
4157 unsigned int shift, mask;
4159 shift = 7 - (index % 8);
4162 array[index / 8] |= mask;
4165 static isc_boolean_t
4166 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4167 dns_rdatatype_t type, dst_key_t *key)
4169 isc_result_t result;
4170 dns_rdataset_t rdataset;
4171 dns_rdata_t rdata = DNS_RDATA_INIT;
4172 dns_rdata_rrsig_t rrsig;
4174 dns_rdataset_init(&rdataset);
4175 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
4176 type, 0, &rdataset, NULL);
4177 if (result != ISC_R_SUCCESS)
4179 for (result = dns_rdataset_first(&rdataset);
4180 result == ISC_R_SUCCESS;
4181 result = dns_rdataset_next(&rdataset)) {
4182 dns_rdataset_current(&rdataset, &rdata);
4183 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
4184 INSIST(result == ISC_R_SUCCESS);
4185 if (rrsig.algorithm == dst_key_alg(key) &&
4186 rrsig.keyid == dst_key_id(key)) {
4187 dns_rdataset_disassociate(&rdataset);
4190 dns_rdata_reset(&rdata);
4192 dns_rdataset_disassociate(&rdataset);
4197 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4198 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
4201 dns_fixedname_t fixed;
4203 dns_rdata_t rdata = DNS_RDATA_INIT;
4204 isc_result_t result;
4205 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4207 dns_fixedname_init(&fixed);
4208 next = dns_fixedname_name(&fixed);
4210 CHECK(next_active(db, version, name, next, bottom));
4211 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
4213 if (dns_name_equal(dns_db_origin(db), name)) {
4215 * Set the OPT bit to indicate that this is a
4216 * partially secure zone.
4218 isc_region_t region;
4220 dns_rdata_toregion(&rdata, ®ion);
4221 dns_name_fromregion(next, ®ion);
4222 isc_region_consume(®ion, next->length);
4223 INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
4224 region.base[0] == 0 &&
4225 region.base[1] > dns_rdatatype_opt / 8);
4226 set_bit(region.base + 2, dns_rdatatype_opt);
4228 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
4235 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
4236 dns_dbversion_t *version, isc_boolean_t build_nsec3,
4237 isc_boolean_t build_nsec, dst_key_t *key,
4238 isc_stdtime_t inception, isc_stdtime_t expire,
4239 unsigned int minimum, isc_boolean_t is_ksk,
4240 isc_boolean_t *delegation, dns_diff_t *diff,
4241 isc_int32_t *signatures, isc_mem_t *mctx)
4243 isc_result_t result;
4244 dns_rdatasetiter_t *iterator = NULL;
4245 dns_rdataset_t rdataset;
4246 dns_rdata_t rdata = DNS_RDATA_INIT;
4247 isc_buffer_t buffer;
4248 unsigned char data[1024];
4249 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
4250 seen_nsec3, seen_ds;
4251 isc_boolean_t bottom;
4253 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4254 if (result != ISC_R_SUCCESS) {
4255 if (result == ISC_R_NOTFOUND)
4256 result = ISC_R_SUCCESS;
4259 dns_rdataset_init(&rdataset);
4260 isc_buffer_init(&buffer, data, sizeof(data));
4261 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
4262 seen_nsec3 = seen_ds = ISC_FALSE;
4263 for (result = dns_rdatasetiter_first(iterator);
4264 result == ISC_R_SUCCESS;
4265 result = dns_rdatasetiter_next(iterator)) {
4266 dns_rdatasetiter_current(iterator, &rdataset);
4267 if (rdataset.type == dns_rdatatype_soa)
4268 seen_soa = ISC_TRUE;
4269 else if (rdataset.type == dns_rdatatype_ns)
4271 else if (rdataset.type == dns_rdatatype_ds)
4273 else if (rdataset.type == dns_rdatatype_dname)
4274 seen_dname = ISC_TRUE;
4275 else if (rdataset.type == dns_rdatatype_nsec)
4276 seen_nsec = ISC_TRUE;
4277 else if (rdataset.type == dns_rdatatype_nsec3)
4278 seen_nsec3 = ISC_TRUE;
4280 dns_rdataset_disassociate(&rdataset);
4282 if (result != ISC_R_NOMORE)
4284 if (seen_ns && !seen_soa)
4285 *delegation = ISC_TRUE;
4287 * Going from insecure to NSEC3.
4288 * Don't generate NSEC3 records for NSEC3 records.
4290 if (build_nsec3 && !seen_nsec3 && seen_rr) {
4291 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
4292 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
4297 * Going from insecure to NSEC.
4298 * Don't generate NSEC records for NSEC3 records.
4300 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
4301 /* Build and add NSEC. */
4302 bottom = (seen_ns && !seen_soa) || seen_dname;
4303 CHECK(add_nsec(db, version, name, node, minimum, bottom, diff));
4304 /* Count a NSEC generation as a signature generation. */
4307 result = dns_rdatasetiter_first(iterator);
4308 while (result == ISC_R_SUCCESS) {
4309 dns_rdatasetiter_current(iterator, &rdataset);
4310 if (rdataset.type == dns_rdatatype_soa ||
4311 rdataset.type == dns_rdatatype_rrsig)
4313 if (is_ksk && rdataset.type != dns_rdatatype_dnskey)
4316 rdataset.type != dns_rdatatype_ds &&
4317 rdataset.type != dns_rdatatype_nsec)
4319 if (signed_with_key(db, node, version, rdataset.type, key))
4321 /* Calculate the signature, creating a RRSIG RDATA. */
4322 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
4323 &expire, mctx, &buffer, &rdata));
4324 /* Update the database and journal with the RRSIG. */
4325 /* XXX inefficient - will cause dataset merging */
4326 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
4327 name, rdataset.ttl, &rdata));
4328 dns_rdata_reset(&rdata);
4331 dns_rdataset_disassociate(&rdataset);
4332 result = dns_rdatasetiter_next(iterator);
4334 if (result == ISC_R_NOMORE)
4335 result = ISC_R_SUCCESS;
4337 *delegation = ISC_TRUE;
4339 if (dns_rdataset_isassociated(&rdataset))
4340 dns_rdataset_disassociate(&rdataset);
4341 if (iterator != NULL)
4342 dns_rdatasetiter_destroy(&iterator);
4347 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4348 dns_ttl_t minimum, isc_boolean_t *secureupdated, dns_diff_t *diff)
4350 isc_result_t result;
4351 dns_rdata_t rdata = DNS_RDATA_INIT;
4352 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4353 dns_rdataset_t rdataset;
4354 dns_rdata_nsec_t nsec;
4355 dns_dbnode_t *node = NULL;
4358 * Check to see if the OPT bit has already been cleared.
4360 CHECK(dns_db_getoriginnode(db, &node));
4361 dns_rdataset_init(&rdataset);
4362 CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
4363 dns_rdatatype_none, 0, &rdataset, NULL));
4364 CHECK(dns_rdataset_first(&rdataset));
4365 dns_rdataset_current(&rdataset, &rdata);
4368 * Find the NEXT name for building the new record.
4370 CHECK(dns_rdata_tostruct(&rdata, &nsec, NULL));
4373 * Delete the old NSEC record.
4375 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_DEL, name, minimum,
4377 dns_rdata_reset(&rdata);
4380 * Add the new NSEC record.
4382 CHECK(dns_nsec_buildrdata(db, version, node, &nsec.next, nsecbuffer,
4384 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, minimum,
4386 dns_rdata_reset(&rdata);
4388 if (secureupdated != NULL)
4389 *secureupdated = ISC_TRUE;
4393 dns_db_detachnode(db, &node);
4394 if (dns_rdataset_isassociated(&rdataset))
4395 dns_rdataset_disassociate(&rdataset);
4400 updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
4401 dns_name_t *name, dns_rdatatype_t privatetype,
4404 isc_result_t result;
4405 dns_dbnode_t *node = NULL;
4406 dns_rdataset_t rdataset;
4407 dns_rdata_t rdata = DNS_RDATA_INIT;
4408 unsigned char data[5];
4409 isc_boolean_t seen_done = ISC_FALSE;
4411 dns_rdataset_init(&rdataset);
4412 result = dns_db_getoriginnode(signing->db, &node);
4413 if (result != ISC_R_SUCCESS)
4416 result = dns_db_findrdataset(signing->db, node, version, privatetype,
4417 dns_rdatatype_none, 0, &rdataset, NULL);
4418 if (result == ISC_R_NOTFOUND) {
4419 result = ISC_R_SUCCESS;
4422 if (result != ISC_R_SUCCESS)
4424 for (result = dns_rdataset_first(&rdataset);
4425 result == ISC_R_SUCCESS;
4426 result = dns_rdataset_next(&rdataset)) {
4427 dns_rdataset_current(&rdataset, &rdata);
4428 if (rdata.length != 5 ||
4429 rdata.data[0] != signing->algorithm ||
4430 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
4431 rdata.data[2] != (signing->keyid & 0xff)) {
4432 dns_rdata_reset(&rdata);
4435 if (!signing->delete && rdata.data[4] != 0)
4436 seen_done = ISC_TRUE;
4438 CHECK(update_one_rr(signing->db, version, diff,
4439 DNS_DIFFOP_DEL, name,
4440 rdataset.ttl, &rdata));
4441 dns_rdata_reset(&rdata);
4443 if (result == ISC_R_NOMORE)
4444 result = ISC_R_SUCCESS;
4445 if (!signing->delete && !seen_done) {
4447 data[0] = signing->algorithm;
4448 data[1] = (signing->keyid >> 8) & 0xff;
4449 data[2] = signing->keyid & 0xff;
4452 rdata.length = sizeof(data);
4454 rdata.type = privatetype;
4455 rdata.rdclass = dns_db_class(signing->db);
4456 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
4457 name, rdataset.ttl, &rdata));
4460 if (dns_rdataset_isassociated(&rdataset))
4461 dns_rdataset_disassociate(&rdataset);
4463 dns_db_detachnode(signing->db, &node);
4468 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
4469 isc_boolean_t active, dns_diff_t *diff)
4471 dns_dbnode_t *node = NULL;
4472 dns_name_t *name = dns_db_origin(db);
4473 dns_rdata_t rdata = DNS_RDATA_INIT;
4474 dns_rdataset_t rdataset;
4475 dns_rdata_nsec3param_t nsec3param;
4476 isc_result_t result;
4477 isc_buffer_t buffer;
4478 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
4481 dns_rdataset_init(&rdataset);
4483 result = dns_db_getoriginnode(db, &node);
4484 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4485 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4486 0, 0, &rdataset, NULL);
4487 if (result == ISC_R_NOTFOUND)
4489 if (result != ISC_R_SUCCESS)
4493 * Preserve the existing ttl.
4498 * Delete all NSEC3PARAM records which match that in nsec3chain.
4500 for (result = dns_rdataset_first(&rdataset);
4501 result == ISC_R_SUCCESS;
4502 result = dns_rdataset_next(&rdataset)) {
4504 dns_rdataset_current(&rdataset, &rdata);
4505 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
4507 if (nsec3param.hash != chain->nsec3param.hash ||
4508 (active && nsec3param.flags != 0) ||
4509 nsec3param.iterations != chain->nsec3param.iterations ||
4510 nsec3param.salt_length != chain->nsec3param.salt_length ||
4511 memcmp(nsec3param.salt, chain->nsec3param.salt,
4512 nsec3param.salt_length)) {
4513 dns_rdata_reset(&rdata);
4517 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
4518 name, rdataset.ttl, &rdata));
4519 dns_rdata_reset(&rdata);
4521 if (result != ISC_R_NOMORE)
4525 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
4526 result = ISC_R_SUCCESS;
4531 * Add a NSEC3PARAM record which matches that in nsec3chain but
4532 * with all flags bits cleared.
4534 * Note: we do not clear chain->nsec3param.flags as this change
4537 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
4538 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
4539 dns_rdatatype_nsec3param,
4540 &chain->nsec3param, &buffer));
4541 rdata.data[1] = 0; /* Clear flag bits. */
4542 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
4545 dns_db_detachnode(db, &node);
4546 if (dns_rdataset_isassociated(&rdataset))
4547 dns_rdataset_disassociate(&rdataset);
4552 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4553 dns_name_t *name, dns_diff_t *diff)
4555 dns_rdataset_t rdataset;
4556 isc_result_t result;
4558 dns_rdataset_init(&rdataset);
4560 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4561 0, 0, &rdataset, NULL);
4562 if (result == ISC_R_NOTFOUND)
4563 return (ISC_R_SUCCESS);
4564 if (result != ISC_R_SUCCESS)
4566 for (result = dns_rdataset_first(&rdataset);
4567 result == ISC_R_SUCCESS;
4568 result = dns_rdataset_next(&rdataset)) {
4569 dns_rdata_t rdata = DNS_RDATA_INIT;
4571 dns_rdataset_current(&rdataset, &rdata);
4572 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4573 rdataset.ttl, &rdata));
4575 if (result == ISC_R_NOMORE)
4576 result = ISC_R_SUCCESS;
4578 dns_rdataset_disassociate(&rdataset);
4583 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4584 dns_name_t *name, const dns_rdata_nsec3param_t *param,
4587 dns_rdataset_t rdataset;
4588 dns_rdata_nsec3_t nsec3;
4589 isc_result_t result;
4591 dns_rdataset_init(&rdataset);
4592 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
4593 0, 0, &rdataset, NULL);
4594 if (result == ISC_R_NOTFOUND)
4595 return (ISC_R_SUCCESS);
4596 if (result != ISC_R_SUCCESS)
4599 for (result = dns_rdataset_first(&rdataset);
4600 result == ISC_R_SUCCESS;
4601 result = dns_rdataset_next(&rdataset)) {
4602 dns_rdata_t rdata = DNS_RDATA_INIT;
4604 dns_rdataset_current(&rdataset, &rdata);
4605 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
4606 if (nsec3.hash != param->hash ||
4607 nsec3.iterations != param->iterations ||
4608 nsec3.salt_length != param->salt_length ||
4609 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
4611 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4612 rdataset.ttl, &rdata));
4614 if (result == ISC_R_NOMORE)
4615 result = ISC_R_SUCCESS;
4617 dns_rdataset_disassociate(&rdataset);
4622 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
4623 const dns_rdata_nsec3param_t *param,
4624 isc_boolean_t *answer, isc_boolean_t *updatensec)
4626 dns_dbnode_t *node = NULL;
4627 dns_rdata_t rdata = DNS_RDATA_INIT;
4628 dns_rdata_nsec3param_t myparam;
4629 dns_rdataset_t rdataset;
4630 isc_result_t result;
4632 *answer = ISC_FALSE;
4634 result = dns_db_getoriginnode(db, &node);
4635 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4637 dns_rdataset_init(&rdataset);
4638 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4639 0, 0, &rdataset, NULL);
4640 if (result == ISC_R_NOTFOUND)
4641 goto check_nsec3param;
4643 if (result != ISC_R_SUCCESS)
4646 CHECK(dns_rdataset_first(&rdataset));
4647 dns_rdataset_current(&rdataset, &rdata);
4649 if (!dns_nsec_typepresent(&rdata, dns_rdatatype_opt)) {
4651 * We have a complete NSEC chain. Signal to update
4652 * the apex NSEC record.
4654 *updatensec = ISC_TRUE;
4657 dns_rdataset_disassociate(&rdataset);
4658 dns_rdata_reset(&rdata);
4661 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4662 0, 0, &rdataset, NULL);
4663 if (result == ISC_R_NOTFOUND) {
4665 dns_db_detachnode(db, &node);
4666 return (ISC_R_SUCCESS);
4668 if (result != ISC_R_SUCCESS) {
4669 dns_db_detachnode(db, &node);
4673 for (result = dns_rdataset_first(&rdataset);
4674 result == ISC_R_SUCCESS;
4675 result = dns_rdataset_next(&rdataset)) {
4676 dns_rdataset_current(&rdataset, &rdata);
4677 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
4678 dns_rdata_reset(&rdata);
4680 * Ignore any NSEC3PARAM removals.
4682 if (NSEC3REMOVE(myparam.flags))
4685 * Ignore the chain that we are in the process of deleting.
4687 if (myparam.hash == param->hash &&
4688 myparam.iterations == param->iterations &&
4689 myparam.salt_length == param->salt_length &&
4690 !memcmp(myparam.salt, param->salt, myparam.salt_length))
4693 * Found an active NSEC3 chain.
4697 if (result == ISC_R_NOMORE) {
4699 result = ISC_R_SUCCESS;
4703 if (dns_rdataset_isassociated(&rdataset))
4704 dns_rdataset_disassociate(&rdataset);
4705 dns_db_detachnode(db, &node);
4710 * Incrementally build and sign a new NSEC3 chain using the parameters
4714 zone_nsec3chain(dns_zone_t *zone) {
4715 const char *journalfile;
4716 dns_db_t *db = NULL;
4717 dns_dbnode_t *node = NULL;
4718 dns_dbversion_t *version = NULL;
4719 dns_diff_t sig_diff;
4720 dns_diff_t nsec_diff;
4721 dns_diff_t nsec3_diff;
4722 dns_diff_t param_diff;
4723 dns_fixedname_t fixed;
4724 dns_fixedname_t nextfixed;
4725 dns_name_t *name, *nextname;
4726 dns_rdataset_t rdataset;
4727 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
4728 dns_nsec3chainlist_t cleanup;
4729 dst_key_t *zone_keys[MAXZONEKEYS];
4730 isc_int32_t signatures;
4731 isc_boolean_t check_ksk, is_ksk;
4732 isc_boolean_t delegation;
4733 isc_boolean_t first;
4734 isc_result_t result;
4735 isc_stdtime_t now, inception, soaexpire, expire, stop;
4736 isc_uint32_t jitter;
4738 unsigned int nkeys = 0;
4740 isc_boolean_t unsecure = ISC_FALSE;
4741 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
4742 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
4743 dns_rdatasetiter_t *iterator = NULL;
4744 dns_difftuple_t *tuple;
4745 isc_boolean_t buildnsecchain;
4746 isc_boolean_t updatensec = ISC_FALSE;
4748 dns_rdataset_init(&rdataset);
4749 dns_fixedname_init(&fixed);
4750 name = dns_fixedname_name(&fixed);
4751 dns_fixedname_init(&nextfixed);
4752 nextname = dns_fixedname_name(&nextfixed);
4753 dns_diff_init(zone->mctx, ¶m_diff);
4754 dns_diff_init(zone->mctx, &nsec3_diff);
4755 dns_diff_init(zone->mctx, &nsec_diff);
4756 dns_diff_init(zone->mctx, &sig_diff);
4757 sig_diff.resign = zone->sigresigninginterval;
4758 ISC_LIST_INIT(cleanup);
4761 * Updates are disabled. Pause for 5 minutes.
4763 if (zone->update_disabled) {
4764 result = ISC_R_FAILURE;
4768 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4769 dns_db_attach(zone->db, &db);
4770 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4772 result = dns_db_newversion(db, &version);
4773 if (result != ISC_R_SUCCESS) {
4774 dns_zone_log(zone, ISC_LOG_ERROR,
4775 "zone_nsec3chain:dns_db_newversion -> %s\n",
4776 dns_result_totext(result));
4780 result = find_zone_keys(zone, db, version, zone->mctx,
4781 MAXZONEKEYS, zone_keys, &nkeys);
4782 if (result != ISC_R_SUCCESS) {
4783 dns_zone_log(zone, ISC_LOG_ERROR,
4784 "zone_nsec3chain:find_zone_keys -> %s\n",
4785 dns_result_totext(result));
4789 isc_stdtime_get(&now);
4790 inception = now - 3600; /* Allow for clock skew. */
4791 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
4794 * Spread out signatures over time if they happen to be
4795 * clumped. We don't do this for each add_sigs() call as
4796 * we still want some clustering to occur.
4798 isc_random_get(&jitter);
4799 expire = soaexpire - jitter % 3600;
4802 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
4804 check_ksk = ksk_sanity(db, version);
4807 * We keep pulling nodes off each iterator in turn until
4808 * we have no more nodes to pull off or we reach the limits
4811 nodes = zone->nodes;
4812 signatures = zone->signatures;
4814 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
4818 if (nsec3chain != NULL)
4819 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
4821 * Generate new NSEC3 chains first.
4823 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
4825 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
4827 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4828 if (nsec3chain->done || nsec3chain->db != zone->db) {
4829 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
4830 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4832 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4834 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
4838 * Possible future db.
4840 if (nsec3chain->db != db) {
4844 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
4848 delegation = ISC_FALSE;
4849 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
4851 if (nsec3chain->delete_nsec) {
4852 delegation = ISC_FALSE;
4853 dns_dbiterator_pause(nsec3chain->dbiterator);
4854 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
4858 * On the first pass we need to check if the current node
4859 * has not been obscured.
4861 delegation = ISC_FALSE;
4862 unsecure = ISC_FALSE;
4864 dns_fixedname_t ffound;
4866 dns_fixedname_init(&ffound);
4867 found = dns_fixedname_name(&ffound);
4868 result = dns_db_find(db, name, version,
4870 DNS_DBFIND_NOWILD, 0, NULL, found,
4872 if ((result == DNS_R_DELEGATION ||
4873 result == DNS_R_DNAME) &&
4874 !dns_name_equal(name, found)) {
4876 * Remember the obscuring name so that
4877 * we skip all obscured names.
4879 dns_name_copy(found, name, NULL);
4880 delegation = ISC_TRUE;
4886 * Check to see if this is a bottom of zone node.
4888 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4889 if (result == ISC_R_NOTFOUND) /* Empty node? */
4891 if (result != ISC_R_SUCCESS)
4894 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
4896 for (result = dns_rdatasetiter_first(iterator);
4897 result == ISC_R_SUCCESS;
4898 result = dns_rdatasetiter_next(iterator)) {
4899 dns_rdatasetiter_current(iterator, &rdataset);
4900 INSIST(rdataset.type != dns_rdatatype_nsec3);
4901 if (rdataset.type == dns_rdatatype_soa)
4902 seen_soa = ISC_TRUE;
4903 else if (rdataset.type == dns_rdatatype_ns)
4905 else if (rdataset.type == dns_rdatatype_dname)
4906 seen_dname = ISC_TRUE;
4907 else if (rdataset.type == dns_rdatatype_ds)
4909 else if (rdataset.type == dns_rdatatype_nsec)
4910 seen_nsec = ISC_TRUE;
4911 dns_rdataset_disassociate(&rdataset);
4913 dns_rdatasetiter_destroy(&iterator);
4915 * Is there a NSEC chain than needs to be cleaned up?
4918 nsec3chain->seen_nsec = ISC_TRUE;
4919 if (seen_ns && !seen_soa && !seen_ds)
4920 unsecure = ISC_TRUE;
4921 if ((seen_ns && !seen_soa) || seen_dname)
4922 delegation = ISC_TRUE;
4927 dns_dbiterator_pause(nsec3chain->dbiterator);
4928 CHECK(dns_nsec3_addnsec3(db, version, name,
4929 &nsec3chain->nsec3param,
4930 zone->minimum, unsecure, &nsec3_diff));
4932 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
4933 * two signatures. Additionally there will, in general, be
4934 * two signature generated below.
4936 * If we are only changing the optout flag the cost is half
4937 * that of the cost of generating a completely new chain.
4942 * Go onto next node.
4946 dns_db_detachnode(db, &node);
4948 result = dns_dbiterator_next(nsec3chain->dbiterator);
4950 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
4951 CHECK(fixup_nsec3param(db, version, nsec3chain,
4952 ISC_FALSE, ¶m_diff));
4954 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4957 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4960 if (result == ISC_R_NOMORE) {
4961 dns_dbiterator_pause(nsec3chain->dbiterator);
4962 if (nsec3chain->seen_nsec) {
4963 CHECK(fixup_nsec3param(db, version,
4967 nsec3chain->delete_nsec = ISC_TRUE;
4970 CHECK(fixup_nsec3param(db, version, nsec3chain,
4971 ISC_FALSE, ¶m_diff));
4973 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4976 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4978 } else if (result != ISC_R_SUCCESS) {
4979 dns_zone_log(zone, ISC_LOG_ERROR,
4981 "dns_dbiterator_next -> %s\n",
4982 dns_result_totext(result));
4984 } else if (delegation) {
4985 dns_dbiterator_current(nsec3chain->dbiterator,
4987 dns_db_detachnode(db, &node);
4988 if (!dns_name_issubdomain(nextname, name))
4996 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
5001 dns_dbiterator_pause(nsec3chain->dbiterator);
5002 nsec3chain = nextnsec3chain;
5004 if (nsec3chain != NULL)
5005 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
5012 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5015 buildnsecchain = ISC_FALSE;
5016 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
5018 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
5021 if (nsec3chain->db != db)
5022 goto next_removechain;
5024 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
5025 goto next_removechain;
5028 * Work out if we need to build a NSEC chain as a consequence
5029 * of removing this NSEC3 chain.
5031 if (first && !updatensec &&
5032 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
5033 CHECK(need_nsec_chain(db, version,
5034 &nsec3chain->nsec3param,
5035 &buildnsecchain, &updatensec));
5037 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
5038 delegation = ISC_FALSE;
5040 if (!buildnsecchain) {
5042 * Delete the NSECPARAM record that matches this chain.
5045 CHECK(fixup_nsec3param(db, version, nsec3chain,
5046 ISC_TRUE, ¶m_diff));
5049 * Delete the NSEC3 records.
5051 CHECK(deletematchingnsec3(db, version, node, name,
5052 &nsec3chain->nsec3param,
5054 goto next_removenode;
5058 dns_fixedname_t ffound;
5060 dns_fixedname_init(&ffound);
5061 found = dns_fixedname_name(&ffound);
5062 result = dns_db_find(db, name, version,
5064 DNS_DBFIND_NOWILD, 0, NULL, found,
5066 if ((result == DNS_R_DELEGATION ||
5067 result == DNS_R_DNAME) &&
5068 !dns_name_equal(name, found)) {
5070 * Remember the obscuring name so that
5071 * we skip all obscured names.
5073 dns_name_copy(found, name, NULL);
5074 delegation = ISC_TRUE;
5075 goto next_removenode;
5080 * Check to see if this is a bottom of zone node.
5082 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5083 if (result == ISC_R_NOTFOUND) /* Empty node? */
5084 goto next_removenode;
5085 if (result != ISC_R_SUCCESS)
5088 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
5089 seen_rr = ISC_FALSE;
5090 for (result = dns_rdatasetiter_first(iterator);
5091 result == ISC_R_SUCCESS;
5092 result = dns_rdatasetiter_next(iterator)) {
5093 dns_rdatasetiter_current(iterator, &rdataset);
5094 if (rdataset.type == dns_rdatatype_soa)
5095 seen_soa = ISC_TRUE;
5096 else if (rdataset.type == dns_rdatatype_ns)
5098 else if (rdataset.type == dns_rdatatype_dname)
5099 seen_dname = ISC_TRUE;
5100 else if (rdataset.type == dns_rdatatype_nsec)
5101 seen_nsec = ISC_TRUE;
5102 else if (rdataset.type == dns_rdatatype_nsec3)
5103 seen_nsec3 = ISC_TRUE;
5105 dns_rdataset_disassociate(&rdataset);
5107 dns_rdatasetiter_destroy(&iterator);
5109 if (!seen_rr || seen_nsec3 || seen_nsec)
5110 goto next_removenode;
5111 if ((seen_ns && !seen_soa) || seen_dname)
5112 delegation = ISC_TRUE;
5114 CHECK(add_nsec(db, version, name, node, zone->minimum,
5115 delegation, &nsec_diff));
5119 dns_db_detachnode(db, &node);
5121 result = dns_dbiterator_next(nsec3chain->dbiterator);
5122 if (result == ISC_R_NOMORE && buildnsecchain) {
5124 * The NSEC chain should now be built.
5125 * We can now remove the NSEC3 chain.
5127 updatensec = ISC_TRUE;
5128 goto same_removechain;
5130 if (result == ISC_R_NOMORE) {
5132 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
5135 ISC_LIST_APPEND(cleanup, nsec3chain, link);
5136 dns_dbiterator_pause(nsec3chain->dbiterator);
5137 CHECK(fixup_nsec3param(db, version, nsec3chain,
5138 ISC_FALSE, ¶m_diff));
5139 goto next_removechain;
5140 } else if (result != ISC_R_SUCCESS) {
5141 dns_zone_log(zone, ISC_LOG_ERROR,
5143 "dns_dbiterator_next -> %s\n",
5144 dns_result_totext(result));
5146 } else if (delegation) {
5147 dns_dbiterator_current(nsec3chain->dbiterator,
5149 dns_db_detachnode(db, &node);
5150 if (!dns_name_issubdomain(nextname, name))
5158 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
5159 buildnsecchain = ISC_FALSE;
5164 dns_dbiterator_pause(nsec3chain->dbiterator);
5165 nsec3chain = nextnsec3chain;
5170 * Add / update signatures for the NSEC3 records.
5172 for (tuple = ISC_LIST_HEAD(nsec3_diff.tuples);
5174 tuple = ISC_LIST_HEAD(nsec3_diff.tuples)) {
5176 * We have changed the NSEC3 RRset above so we need to update
5179 result = del_sigs(zone, db, version, &tuple->name,
5180 dns_rdatatype_nsec3, &sig_diff,
5181 zone_keys, nkeys, now);
5182 if (result != ISC_R_SUCCESS) {
5183 dns_zone_log(zone, ISC_LOG_ERROR,
5184 "zone_nsec3chain:del_sigs -> %s\n",
5185 dns_result_totext(result));
5188 result = add_sigs(db, version, &tuple->name,
5189 dns_rdatatype_nsec3, &sig_diff, zone_keys,
5190 nkeys, zone->mctx, inception, expire,
5192 if (result != ISC_R_SUCCESS) {
5193 dns_zone_log(zone, ISC_LOG_ERROR,
5194 "zone_nsec3chain:add_sigs -> %s\n",
5195 dns_result_totext(result));
5200 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
5201 while (next != NULL &&
5202 !dns_name_equal(&tuple->name, &next->name))
5203 next = ISC_LIST_NEXT(next, link);
5204 ISC_LIST_UNLINK(nsec3_diff.tuples, tuple, link);
5205 dns_diff_appendminimal(&sig_diff, &tuple);
5206 INSIST(tuple == NULL);
5208 } while (tuple != NULL);
5211 for (tuple = ISC_LIST_HEAD(param_diff.tuples);
5213 tuple = ISC_LIST_HEAD(param_diff.tuples)) {
5215 * We have changed the NSEC3PARAM RRset above so we need to
5216 * update the signatures.
5218 result = del_sigs(zone, db, version, &tuple->name,
5219 dns_rdatatype_nsec3param, &sig_diff,
5220 zone_keys, nkeys, now);
5221 if (result != ISC_R_SUCCESS) {
5222 dns_zone_log(zone, ISC_LOG_ERROR,
5223 "zone_nsec3chain:del_sigs -> %s\n",
5224 dns_result_totext(result));
5227 result = add_sigs(db, version, &tuple->name,
5228 dns_rdatatype_nsec3param, &sig_diff,
5229 zone_keys, nkeys, zone->mctx, inception,
5231 if (result != ISC_R_SUCCESS) {
5232 dns_zone_log(zone, ISC_LOG_ERROR,
5233 "zone_nsec3chain:add_sigs -> %s\n",
5234 dns_result_totext(result));
5237 ISC_LIST_UNLINK(param_diff.tuples, tuple, link);
5238 dns_diff_appendminimal(&sig_diff, &tuple);
5239 INSIST(tuple == NULL);
5243 CHECK(updatesecure(db, version, &zone->origin, zone->minimum,
5246 for (tuple = ISC_LIST_HEAD(nsec_diff.tuples);
5248 tuple = ISC_LIST_HEAD(nsec_diff.tuples)) {
5249 result = del_sigs(zone, db, version, &tuple->name,
5250 dns_rdatatype_nsec, &sig_diff,
5251 zone_keys, nkeys, now);
5252 if (result != ISC_R_SUCCESS) {
5253 dns_zone_log(zone, ISC_LOG_ERROR,
5254 "zone_nsec3chain:del_sigs -> %s\n",
5255 dns_result_totext(result));
5258 result = add_sigs(db, version, &tuple->name,
5259 dns_rdatatype_nsec, &sig_diff,
5260 zone_keys, nkeys, zone->mctx, inception,
5262 if (result != ISC_R_SUCCESS) {
5263 dns_zone_log(zone, ISC_LOG_ERROR,
5264 "zone_nsec3chain:add_sigs -> %s\n",
5265 dns_result_totext(result));
5268 ISC_LIST_UNLINK(nsec_diff.tuples, tuple, link);
5269 dns_diff_appendminimal(&sig_diff, &tuple);
5270 INSIST(tuple == NULL);
5274 * If we made no effective changes to the zone then we can just
5275 * cleanup otherwise we need to increment the serial.
5277 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5280 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5281 &sig_diff, zone_keys, nkeys, now);
5282 if (result != ISC_R_SUCCESS) {
5283 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5284 "del_sigs -> %s\n", dns_result_totext(result));
5288 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5289 if (result != ISC_R_SUCCESS) {
5290 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5291 "increment_soa_serial -> %s\n",
5292 dns_result_totext(result));
5296 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5297 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5298 soaexpire, check_ksk);
5299 if (result != ISC_R_SUCCESS) {
5300 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5301 "add_sigs -> %s\n", dns_result_totext(result));
5305 journalfile = dns_zone_getjournal(zone);
5306 if (journalfile != NULL) {
5307 dns_journal_t *journal = NULL;
5308 result = dns_journal_open(zone->mctx, journalfile,
5309 ISC_TRUE, &journal);
5310 if (result != ISC_R_SUCCESS) {
5311 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5312 "dns_journal_open -> %s\n",
5313 dns_result_totext(result));
5317 result = dns_journal_write_transaction(journal, &sig_diff);
5318 dns_journal_destroy(&journal);
5319 if (result != ISC_R_SUCCESS) {
5320 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5321 "dns_journal_write_transaction -> %s\n",
5322 dns_result_totext(result));
5328 zone_needdump(zone, DNS_DUMP_DELAY);
5329 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5334 * Pause all iterators so that dns_db_closeversion() can succeed.
5337 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5339 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5340 dns_dbiterator_pause(nsec3chain->dbiterator);
5344 * Everything has succeeded. Commit the changes.
5346 dns_db_closeversion(db, &version, ISC_TRUE);
5349 * Everything succeeded so we can clean these up now.
5351 nsec3chain = ISC_LIST_HEAD(cleanup);
5352 while (nsec3chain != NULL) {
5353 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5354 dns_db_detach(&nsec3chain->db);
5355 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5356 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5357 nsec3chain = ISC_LIST_HEAD(cleanup);
5360 set_resigntime(zone);
5364 * On error roll back the current nsec3chain.
5366 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
5367 if (nsec3chain->done) {
5368 dns_db_detach(&nsec3chain->db);
5369 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5370 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5372 result = dns_dbiterator_first(nsec3chain->dbiterator);
5373 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5374 dns_dbiterator_pause(nsec3chain->dbiterator);
5375 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5380 * Rollback the cleanup list.
5382 nsec3chain = ISC_LIST_TAIL(cleanup);
5383 while (nsec3chain != NULL) {
5384 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5385 if (nsec3chain->done) {
5386 dns_db_detach(&nsec3chain->db);
5387 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5388 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5391 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
5393 result = dns_dbiterator_first(nsec3chain->dbiterator);
5394 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5395 dns_dbiterator_pause(nsec3chain->dbiterator);
5396 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5398 nsec3chain = ISC_LIST_TAIL(cleanup);
5402 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5404 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5405 dns_dbiterator_pause(nsec3chain->dbiterator);
5408 dns_diff_clear(¶m_diff);
5409 dns_diff_clear(&nsec3_diff);
5410 dns_diff_clear(&nsec_diff);
5411 dns_diff_clear(&sig_diff);
5413 if (iterator != NULL)
5414 dns_rdatasetiter_destroy(&iterator);
5416 for (i = 0; i < nkeys; i++)
5417 dst_key_free(&zone_keys[i]);
5419 if (version != NULL) {
5420 dns_db_closeversion(db, &version, ISC_FALSE);
5422 } else if (db != NULL)
5426 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
5428 if (zone->update_disabled || result != ISC_R_SUCCESS)
5429 isc_interval_set(&i, 60, 0); /* 1 minute */
5431 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5432 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
5434 isc_time_settoepoch(&zone->nsec3chaintime);
5439 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5440 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
5441 isc_uint16_t keyid, dns_diff_t *diff)
5443 dns_rdata_rrsig_t rrsig;
5444 dns_rdataset_t rdataset;
5445 dns_rdatasetiter_t *iterator = NULL;
5446 isc_result_t result;
5448 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5449 if (result != ISC_R_SUCCESS) {
5450 if (result == ISC_R_NOTFOUND)
5451 result = ISC_R_SUCCESS;
5455 dns_rdataset_init(&rdataset);
5456 for (result = dns_rdatasetiter_first(iterator);
5457 result == ISC_R_SUCCESS;
5458 result = dns_rdatasetiter_next(iterator)) {
5459 dns_rdatasetiter_current(iterator, &rdataset);
5460 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
5461 for (result = dns_rdataset_first(&rdataset);
5462 result == ISC_R_SUCCESS;
5463 result = dns_rdataset_next(&rdataset)) {
5464 dns_rdata_t rdata = DNS_RDATA_INIT;
5465 dns_rdataset_current(&rdataset, &rdata);
5466 CHECK(update_one_rr(db, version, diff,
5467 DNS_DIFFOP_DEL, name,
5468 rdataset.ttl, &rdata));
5470 if (result != ISC_R_NOMORE)
5472 dns_rdataset_disassociate(&rdataset);
5475 if (rdataset.type != dns_rdatatype_rrsig) {
5476 dns_rdataset_disassociate(&rdataset);
5479 for (result = dns_rdataset_first(&rdataset);
5480 result == ISC_R_SUCCESS;
5481 result = dns_rdataset_next(&rdataset)) {
5482 dns_rdata_t rdata = DNS_RDATA_INIT;
5483 dns_rdataset_current(&rdataset, &rdata);
5484 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
5485 if (rrsig.algorithm != algorithm ||
5486 rrsig.keyid != keyid)
5488 CHECK(update_one_rr(db, version, diff,
5489 DNS_DIFFOP_DELRESIGN, name,
5490 rdataset.ttl, &rdata));
5492 dns_rdataset_disassociate(&rdataset);
5493 if (result != ISC_R_NOMORE)
5496 if (result == ISC_R_NOMORE)
5497 result = ISC_R_SUCCESS;
5499 if (dns_rdataset_isassociated(&rdataset))
5500 dns_rdataset_disassociate(&rdataset);
5501 dns_rdatasetiter_destroy(&iterator);
5506 * Incrementally sign the zone using the keys requested.
5507 * Builds the NSEC chain if required.
5510 zone_sign(dns_zone_t *zone) {
5511 const char *journalfile;
5512 dns_db_t *db = NULL;
5513 dns_dbnode_t *node = NULL;
5514 dns_dbversion_t *version = NULL;
5515 dns_diff_t sig_diff;
5516 dns_fixedname_t fixed;
5517 dns_fixedname_t nextfixed;
5518 dns_name_t *name, *nextname;
5519 dns_rdataset_t rdataset;
5520 dns_signing_t *signing, *nextsigning;
5521 dns_signinglist_t cleanup;
5522 dst_key_t *zone_keys[MAXZONEKEYS];
5523 isc_int32_t signatures;
5524 isc_boolean_t check_ksk, is_ksk;
5525 isc_boolean_t commit = ISC_FALSE;
5526 isc_boolean_t delegation;
5527 isc_boolean_t finishedakey = ISC_FALSE;
5528 isc_boolean_t secureupdated = ISC_FALSE;
5529 isc_boolean_t build_nsec3 = ISC_FALSE, build_nsec = ISC_FALSE;
5530 isc_boolean_t first;
5531 isc_result_t result;
5532 isc_stdtime_t now, inception, soaexpire, expire;
5533 isc_uint32_t jitter;
5535 unsigned int nkeys = 0;
5538 dns_rdataset_init(&rdataset);
5539 dns_fixedname_init(&fixed);
5540 name = dns_fixedname_name(&fixed);
5541 dns_fixedname_init(&nextfixed);
5542 nextname = dns_fixedname_name(&nextfixed);
5543 dns_diff_init(zone->mctx, &sig_diff);
5544 sig_diff.resign = zone->sigresigninginterval;
5545 ISC_LIST_INIT(cleanup);
5548 * Updates are disabled. Pause for 5 minutes.
5550 if (zone->update_disabled) {
5551 result = ISC_R_FAILURE;
5555 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5556 dns_db_attach(zone->db, &db);
5557 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5559 result = dns_db_newversion(db, &version);
5560 if (result != ISC_R_SUCCESS) {
5561 dns_zone_log(zone, ISC_LOG_ERROR,
5562 "zone_sign:dns_db_newversion -> %s\n",
5563 dns_result_totext(result));
5567 result = find_zone_keys(zone, db, version, zone->mctx,
5568 MAXZONEKEYS, zone_keys, &nkeys);
5569 if (result != ISC_R_SUCCESS) {
5570 dns_zone_log(zone, ISC_LOG_ERROR,
5571 "zone_sign:find_zone_keys -> %s\n",
5572 dns_result_totext(result));
5576 isc_stdtime_get(&now);
5577 inception = now - 3600; /* Allow for clock skew. */
5578 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5581 * Spread out signatures over time if they happen to be
5582 * clumped. We don't do this for each add_sigs() call as
5583 * we still want some clustering to occur.
5585 isc_random_get(&jitter);
5586 expire = soaexpire - jitter % 3600;
5588 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5590 check_ksk = ksk_sanity(db, version);
5593 * We keep pulling nodes off each iterator in turn until
5594 * we have no more nodes to pull off or we reach the limits
5597 nodes = zone->nodes;
5598 signatures = zone->signatures;
5599 signing = ISC_LIST_HEAD(zone->signing);
5602 * See if we have a NSEC chain.
5604 result = dns_db_getoriginnode(db, &node);
5605 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5606 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
5607 dns_rdatatype_none, 0, &rdataset, NULL);
5608 dns_db_detachnode(db, &node);
5609 if (result == ISC_R_SUCCESS) {
5610 build_nsec = ISC_TRUE;
5611 dns_rdataset_disassociate(&rdataset);
5612 } else if (result != ISC_R_NOTFOUND) {
5616 * No NSEC chain present.
5617 * See if we need to build a NSEC3 chain?
5619 result = dns_nsec3_active(db, version, ISC_TRUE, &build_nsec3);
5620 if (result == ISC_R_SUCCESS) {
5622 build_nsec3 = ISC_FALSE;
5624 result = dns_nsec3_active(db, version,
5628 secureupdated = ISC_TRUE;
5630 build_nsec = ISC_TRUE;
5635 while (signing != NULL && nodes-- > 0 && signatures > 0) {
5636 nextsigning = ISC_LIST_NEXT(signing, link);
5638 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5639 if (signing->done || signing->db != zone->db) {
5641 * The zone has been reloaded. We will have
5642 * created new signings as part of the reload
5643 * process so we can destroy this one.
5645 ISC_LIST_UNLINK(zone->signing, signing, link);
5646 ISC_LIST_APPEND(cleanup, signing, link);
5647 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5650 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5652 if (signing->db != db)
5656 delegation = ISC_FALSE;
5658 dns_dbiterator_current(signing->dbiterator, &node, name);
5660 if (signing->delete) {
5661 dns_dbiterator_pause(signing->dbiterator);
5662 CHECK(del_sig(db, version, name, node, nkeys,
5663 signing->algorithm, signing->keyid,
5668 * On the first pass we need to check if the current node
5669 * has not been obscured.
5672 dns_fixedname_t ffound;
5674 dns_fixedname_init(&ffound);
5675 found = dns_fixedname_name(&ffound);
5676 result = dns_db_find(db, name, version,
5678 DNS_DBFIND_NOWILD, 0, NULL, found,
5680 if ((result == DNS_R_DELEGATION ||
5681 result == DNS_R_DNAME) &&
5682 !dns_name_equal(name, found)) {
5684 * Remember the obscuring name so that
5685 * we skip all obscured names.
5687 dns_name_copy(found, name, NULL);
5688 delegation = ISC_TRUE;
5696 dns_dbiterator_pause(signing->dbiterator);
5697 for (i = 0; i < nkeys; i++) {
5699 * Find the key we want to sign with.
5701 if (dst_key_alg(zone_keys[i]) != signing->algorithm ||
5702 dst_key_id(zone_keys[i]) != signing->keyid ||
5703 !dst_key_isprivate(zone_keys[i]))
5706 * Do we do KSK processing?
5709 (dst_key_flags(zone_keys[i]) & DNS_KEYFLAG_KSK) != 0)
5711 CHECK(sign_a_node(db, name, node, version, build_nsec3,
5712 build_nsec, zone_keys[i], inception,
5713 expire, zone->minimum, is_ksk,
5714 &delegation, &sig_diff, &signatures,
5719 * Go onto next node.
5723 dns_db_detachnode(db, &node);
5725 result = dns_dbiterator_next(signing->dbiterator);
5726 if (result == ISC_R_NOMORE) {
5727 ISC_LIST_UNLINK(zone->signing, signing, link);
5728 ISC_LIST_APPEND(cleanup, signing, link);
5729 dns_dbiterator_pause(signing->dbiterator);
5730 finishedakey = ISC_TRUE;
5731 if (!is_ksk && !secureupdated && nkeys != 0 &&
5734 * We have finished regenerating the
5735 * zone with a zone signing key.
5736 * The NSEC chain is now complete and
5737 * there is a full set of signatures
5738 * for the zone. We can now clear the
5739 * OPT bit from the NSEC record.
5741 result = updatesecure(db, version,
5746 if (result != ISC_R_SUCCESS) {
5749 "updatesecure -> %s\n",
5750 dns_result_totext(result));
5754 result = updatesignwithkey(signing, version,
5758 if (result != ISC_R_SUCCESS) {
5759 dns_zone_log(zone, ISC_LOG_ERROR,
5760 "updatesignwithkey -> %s\n",
5761 dns_result_totext(result));
5765 } else if (result != ISC_R_SUCCESS) {
5766 dns_zone_log(zone, ISC_LOG_ERROR,
5767 "zone_sign:dns_dbiterator_next -> %s\n",
5768 dns_result_totext(result));
5770 } else if (delegation) {
5771 dns_dbiterator_current(signing->dbiterator,
5773 dns_db_detachnode(db, &node);
5774 if (!dns_name_issubdomain(nextname, name))
5782 dns_dbiterator_pause(signing->dbiterator);
5783 signing = nextsigning;
5787 if (secureupdated) {
5789 * We have changed the NSEC RRset above so we need to update
5792 result = del_sigs(zone, db, version, &zone->origin,
5793 dns_rdatatype_nsec, &sig_diff, zone_keys,
5795 if (result != ISC_R_SUCCESS) {
5796 dns_zone_log(zone, ISC_LOG_ERROR,
5797 "zone_sign:del_sigs -> %s\n",
5798 dns_result_totext(result));
5801 result = add_sigs(db, version, &zone->origin,
5802 dns_rdatatype_nsec, &sig_diff, zone_keys,
5803 nkeys, zone->mctx, inception, soaexpire,
5805 if (result != ISC_R_SUCCESS) {
5806 dns_zone_log(zone, ISC_LOG_ERROR,
5807 "zone_sign:add_sigs -> %s\n",
5808 dns_result_totext(result));
5815 * We have changed the RRset above so we need to update
5818 result = del_sigs(zone, db, version, &zone->origin,
5819 zone->privatetype, &sig_diff,
5820 zone_keys, nkeys, now);
5821 if (result != ISC_R_SUCCESS) {
5822 dns_zone_log(zone, ISC_LOG_ERROR,
5823 "zone_sign:del_sigs -> %s\n",
5824 dns_result_totext(result));
5827 result = add_sigs(db, version, &zone->origin,
5828 zone->privatetype, &sig_diff,
5829 zone_keys, nkeys, zone->mctx, inception,
5830 soaexpire, check_ksk);
5831 if (result != ISC_R_SUCCESS) {
5832 dns_zone_log(zone, ISC_LOG_ERROR,
5833 "zone_sign:add_sigs -> %s\n",
5834 dns_result_totext(result));
5840 * Have we changed anything?
5842 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5847 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5848 &sig_diff, zone_keys, nkeys, now);
5849 if (result != ISC_R_SUCCESS) {
5850 dns_zone_log(zone, ISC_LOG_ERROR,
5851 "zone_sign:del_sigs -> %s\n",
5852 dns_result_totext(result));
5856 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5857 if (result != ISC_R_SUCCESS) {
5858 dns_zone_log(zone, ISC_LOG_ERROR,
5859 "zone_sign:increment_soa_serial -> %s\n",
5860 dns_result_totext(result));
5865 * Generate maximum life time signatures so that the above loop
5866 * termination is sensible.
5868 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5869 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5870 soaexpire, check_ksk);
5871 if (result != ISC_R_SUCCESS) {
5872 dns_zone_log(zone, ISC_LOG_ERROR,
5873 "zone_sign:add_sigs -> %s\n",
5874 dns_result_totext(result));
5879 * Write changes to journal file.
5881 journalfile = dns_zone_getjournal(zone);
5882 if (journalfile != NULL) {
5883 dns_journal_t *journal = NULL;
5884 result = dns_journal_open(zone->mctx, journalfile,
5885 ISC_TRUE, &journal);
5886 if (result != ISC_R_SUCCESS) {
5887 dns_zone_log(zone, ISC_LOG_ERROR,
5888 "zone_sign:dns_journal_open -> %s\n",
5889 dns_result_totext(result));
5893 result = dns_journal_write_transaction(journal, &sig_diff);
5894 dns_journal_destroy(&journal);
5895 if (result != ISC_R_SUCCESS) {
5896 dns_zone_log(zone, ISC_LOG_ERROR,
5897 "zone_sign:dns_journal_write_transaction -> %s\n",
5898 dns_result_totext(result));
5905 * Pause all iterators so that dns_db_closeversion() can succeed.
5907 for (signing = ISC_LIST_HEAD(zone->signing);
5909 signing = ISC_LIST_NEXT(signing, link))
5910 dns_dbiterator_pause(signing->dbiterator);
5912 for (signing = ISC_LIST_HEAD(cleanup);
5914 signing = ISC_LIST_NEXT(signing, link))
5915 dns_dbiterator_pause(signing->dbiterator);
5918 * Everything has succeeded. Commit the changes.
5920 dns_db_closeversion(db, &version, commit);
5923 * Everything succeeded so we can clean these up now.
5925 signing = ISC_LIST_HEAD(cleanup);
5926 while (signing != NULL) {
5927 ISC_LIST_UNLINK(cleanup, signing, link);
5928 dns_db_detach(&signing->db);
5929 dns_dbiterator_destroy(&signing->dbiterator);
5930 isc_mem_put(zone->mctx, signing, sizeof *signing);
5931 signing = ISC_LIST_HEAD(cleanup);
5934 set_resigntime(zone);
5938 zone_needdump(zone, DNS_DUMP_DELAY);
5944 * Rollback the cleanup list.
5946 signing = ISC_LIST_HEAD(cleanup);
5947 while (signing != NULL) {
5948 ISC_LIST_UNLINK(cleanup, signing, link);
5949 ISC_LIST_APPEND(zone->signing, signing, link);
5950 dns_dbiterator_first(signing->dbiterator);
5951 dns_dbiterator_pause(signing->dbiterator);
5952 signing = ISC_LIST_HEAD(cleanup);
5955 for (signing = ISC_LIST_HEAD(zone->signing);
5957 signing = ISC_LIST_NEXT(signing, link))
5958 dns_dbiterator_pause(signing->dbiterator);
5960 dns_diff_clear(&sig_diff);
5962 for (i = 0; i < nkeys; i++)
5963 dst_key_free(&zone_keys[i]);
5965 if (version != NULL) {
5966 dns_db_closeversion(db, &version, ISC_FALSE);
5968 } else if (db != NULL)
5971 if (ISC_LIST_HEAD(zone->signing) != NULL) {
5973 if (zone->update_disabled || result != ISC_R_SUCCESS)
5974 isc_interval_set(&i, 60, 0); /* 1 minute */
5976 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5977 isc_time_nowplusinterval(&zone->signingtime, &i);
5979 isc_time_settoepoch(&zone->signingtime);
5983 zone_maintenance(dns_zone_t *zone) {
5984 const char me[] = "zone_maintenance";
5986 isc_result_t result;
5987 isc_boolean_t dumping;
5989 REQUIRE(DNS_ZONE_VALID(zone));
5993 * Configuring the view of this zone may have
5994 * failed, for example because the config file
5995 * had a syntax error. In that case, the view
5996 * adb or resolver, and we had better not try
5997 * to do maintenance on it.
5999 if (zone->view == NULL || zone->view->adb == NULL)
6007 switch (zone->type) {
6008 case dns_zone_slave:
6011 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
6012 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6014 zone->refreshtime = now;
6025 switch (zone->type) {
6026 case dns_zone_slave:
6028 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
6029 isc_time_compare(&now, &zone->refreshtime) >= 0)
6030 dns_zone_refresh(zone);
6037 * Do we need to consolidate the backing store?
6039 switch (zone->type) {
6040 case dns_zone_master:
6041 case dns_zone_slave:
6043 if (zone->masterfile != NULL &&
6044 isc_time_compare(&now, &zone->dumptime) >= 0 &&
6045 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
6046 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
6047 dumping = was_dumping(zone);
6052 result = zone_dump(zone, ISC_TRUE); /* task locked */
6053 if (result != ISC_R_SUCCESS)
6054 dns_zone_log(zone, ISC_LOG_WARNING,
6056 dns_result_totext(result));
6063 switch (zone->type) {
6064 case dns_zone_master:
6065 case dns_zone_slave:
6067 * Do we need to send out notify messages?
6069 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
6070 isc_time_compare(&now, &zone->notifytime) >= 0)
6071 zone_notify(zone, &now);
6073 * Do we need to sign/resign some RRsets?
6075 if (!isc_time_isepoch(&zone->signingtime) &&
6076 isc_time_compare(&now, &zone->signingtime) >= 0)
6078 else if (!isc_time_isepoch(&zone->resigntime) &&
6079 isc_time_compare(&now, &zone->resigntime) >= 0)
6080 zone_resigninc(zone);
6081 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
6082 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
6083 zone_nsec3chain(zone);
6085 * Do we need to issue a key expiry warning.
6087 if (!isc_time_isepoch(&zone->keywarntime) &&
6088 isc_time_compare(&now, &zone->keywarntime) >= 0)
6089 set_key_expiry_warning(zone, zone->key_expiry,
6090 isc_time_seconds(&now));
6095 zone_settimer(zone, &now);
6099 dns_zone_markdirty(dns_zone_t *zone) {
6102 if (zone->type == dns_zone_master)
6103 set_resigntime(zone); /* XXXMPA make separate call back */
6104 zone_needdump(zone, DNS_DUMP_DELAY);
6109 dns_zone_expire(dns_zone_t *zone) {
6110 REQUIRE(DNS_ZONE_VALID(zone));
6118 zone_expire(dns_zone_t *zone) {
6120 * 'zone' locked by caller.
6123 REQUIRE(LOCKED_ZONE(zone));
6125 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
6127 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
6128 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
6129 zone->retry = DNS_ZONE_DEFAULTRETRY;
6130 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6135 dns_zone_refresh(dns_zone_t *zone) {
6137 isc_uint32_t oldflags;
6139 isc_result_t result;
6141 REQUIRE(DNS_ZONE_VALID(zone));
6143 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
6147 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
6148 * in progress at a time.
6152 oldflags = zone->flags;
6153 if (zone->masterscnt == 0) {
6154 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
6155 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
6156 dns_zone_log(zone, ISC_LOG_ERROR,
6157 "cannot refresh: no masters");
6160 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6161 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
6162 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6163 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
6167 * Set the next refresh time as if refresh check has failed.
6168 * Setting this to the retry time will do that. XXXMLG
6169 * If we are successful it will be reset using zone->refresh.
6171 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
6173 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
6174 if (result != ISC_R_SUCCESS)
6175 dns_zone_log(zone, ISC_LOG_WARNING,
6176 "isc_time_nowplusinterval() failed: %s",
6177 dns_result_totext(result));
6180 * When lacking user-specified timer values from the SOA,
6181 * do exponential backoff of the retry time up to a
6182 * maximum of six hours.
6184 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
6185 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
6187 zone->curmaster = 0;
6188 for (j = 0; j < zone->masterscnt; j++)
6189 zone->mastersok[j] = ISC_FALSE;
6190 /* initiate soa query */
6191 queue_soa_query(zone);
6197 dns_zone_flush(dns_zone_t *zone) {
6198 isc_result_t result = ISC_R_SUCCESS;
6199 isc_boolean_t dumping;
6201 REQUIRE(DNS_ZONE_VALID(zone));
6204 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
6205 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6206 zone->masterfile != NULL) {
6207 result = ISC_R_ALREADYRUNNING;
6208 dumping = was_dumping(zone);
6213 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6218 dns_zone_dump(dns_zone_t *zone) {
6219 isc_result_t result = ISC_R_ALREADYRUNNING;
6220 isc_boolean_t dumping;
6222 REQUIRE(DNS_ZONE_VALID(zone));
6225 dumping = was_dumping(zone);
6228 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6233 zone_needdump(dns_zone_t *zone, unsigned int delay) {
6234 isc_time_t dumptime;
6238 * 'zone' locked by caller
6241 REQUIRE(DNS_ZONE_VALID(zone));
6242 REQUIRE(LOCKED_ZONE(zone));
6245 * Do we have a place to dump to and are we loaded?
6247 if (zone->masterfile == NULL ||
6248 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
6252 /* add some noise */
6253 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
6255 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6256 if (isc_time_isepoch(&zone->dumptime) ||
6257 isc_time_compare(&zone->dumptime, &dumptime) > 0)
6258 zone->dumptime = dumptime;
6259 if (zone->task != NULL)
6260 zone_settimer(zone, &now);
6264 dump_done(void *arg, isc_result_t result) {
6265 const char me[] = "dump_done";
6266 dns_zone_t *zone = arg;
6268 dns_dbversion_t *version;
6269 isc_boolean_t again = ISC_FALSE;
6270 isc_boolean_t compact = ISC_FALSE;
6271 isc_uint32_t serial;
6272 isc_result_t tresult;
6274 REQUIRE(DNS_ZONE_VALID(zone));
6278 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
6279 zone->journalsize != -1) {
6282 * We don't own these, zone->dctx must stay valid.
6284 db = dns_dumpctx_db(zone->dctx);
6285 version = dns_dumpctx_version(zone->dctx);
6287 tresult = dns_db_getsoaserial(db, version, &serial);
6289 * Note: we are task locked here so we can test
6292 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
6293 tresult = dns_journal_compact(zone->mctx,
6300 case ISC_R_NOTFOUND:
6301 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6302 "dns_journal_compact: %s",
6303 dns_result_totext(tresult));
6306 dns_zone_log(zone, ISC_LOG_ERROR,
6307 "dns_journal_compact failed: %s",
6308 dns_result_totext(tresult));
6311 } else if (tresult == ISC_R_SUCCESS) {
6313 zone->compact_serial = serial;
6318 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6320 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
6321 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
6323 * Try again in a short while.
6325 zone_needdump(zone, DNS_DUMP_DELAY);
6326 } else if (result == ISC_R_SUCCESS &&
6327 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6328 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6329 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6330 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6331 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6332 isc_time_settoepoch(&zone->dumptime);
6334 } else if (result == ISC_R_SUCCESS)
6335 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6337 if (zone->dctx != NULL)
6338 dns_dumpctx_detach(&zone->dctx);
6339 zonemgr_putio(&zone->writeio);
6342 (void)zone_dump(zone, ISC_FALSE);
6343 dns_zone_idetach(&zone);
6347 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
6348 const char me[] = "zone_dump";
6349 isc_result_t result;
6350 dns_dbversion_t *version = NULL;
6351 isc_boolean_t again;
6352 dns_db_t *db = NULL;
6353 char *masterfile = NULL;
6354 dns_masterformat_t masterformat = dns_masterformat_none;
6357 * 'compact' MUST only be set if we are task locked.
6360 REQUIRE(DNS_ZONE_VALID(zone));
6364 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6365 if (zone->db != NULL)
6366 dns_db_attach(zone->db, &db);
6367 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6369 if (zone->masterfile != NULL) {
6370 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
6371 masterformat = zone->masterformat;
6375 result = DNS_R_NOTLOADED;
6378 if (masterfile == NULL) {
6379 result = DNS_R_NOMASTERFILE;
6384 dns_zone_t *dummy = NULL;
6386 zone_iattach(zone, &dummy);
6387 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
6388 zone_gotwritehandle, zone,
6390 if (result != ISC_R_SUCCESS)
6391 zone_idetach(&dummy);
6393 result = DNS_R_CONTINUE;
6396 dns_db_currentversion(db, &version);
6397 result = dns_master_dump2(zone->mctx, db, version,
6398 &dns_master_style_default,
6399 masterfile, masterformat);
6400 dns_db_closeversion(db, &version, ISC_FALSE);
6405 if (masterfile != NULL)
6406 isc_mem_free(zone->mctx, masterfile);
6409 if (result == DNS_R_CONTINUE)
6410 return (ISC_R_SUCCESS); /* XXXMPA */
6414 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6415 if (result != ISC_R_SUCCESS) {
6417 * Try again in a short while.
6419 zone_needdump(zone, DNS_DUMP_DELAY);
6420 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6421 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6422 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6423 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6424 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6425 isc_time_settoepoch(&zone->dumptime);
6428 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6437 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
6438 dns_masterformat_t format)
6440 isc_result_t result;
6441 dns_dbversion_t *version = NULL;
6442 dns_db_t *db = NULL;
6444 REQUIRE(DNS_ZONE_VALID(zone));
6446 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6447 if (zone->db != NULL)
6448 dns_db_attach(zone->db, &db);
6449 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6451 return (DNS_R_NOTLOADED);
6453 dns_db_currentversion(db, &version);
6454 result = dns_master_dumptostream2(zone->mctx, db, version, style,
6456 dns_db_closeversion(db, &version, ISC_FALSE);
6462 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
6463 const dns_master_style_t *style) {
6464 return dumptostream(zone, fd, style, format);
6468 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
6469 return dumptostream(zone, fd, &dns_master_style_default,
6470 dns_masterformat_text);
6474 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
6475 return dumptostream(zone, fd, &dns_master_style_full,
6476 dns_masterformat_text);
6480 dns_zone_unload(dns_zone_t *zone) {
6481 REQUIRE(DNS_ZONE_VALID(zone));
6489 notify_cancel(dns_zone_t *zone) {
6490 dns_notify_t *notify;
6493 * 'zone' locked by caller.
6496 REQUIRE(LOCKED_ZONE(zone));
6498 for (notify = ISC_LIST_HEAD(zone->notifies);
6500 notify = ISC_LIST_NEXT(notify, link)) {
6501 if (notify->find != NULL)
6502 dns_adb_cancelfind(notify->find);
6503 if (notify->request != NULL)
6504 dns_request_cancel(notify->request);
6509 zone_unload(dns_zone_t *zone) {
6512 * 'zone' locked by caller.
6515 REQUIRE(LOCKED_ZONE(zone));
6517 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6518 zone_detachdb(zone);
6519 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6520 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
6521 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6525 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6526 REQUIRE(DNS_ZONE_VALID(zone));
6529 zone->minrefresh = val;
6533 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6534 REQUIRE(DNS_ZONE_VALID(zone));
6537 zone->maxrefresh = val;
6541 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
6542 REQUIRE(DNS_ZONE_VALID(zone));
6545 zone->minretry = val;
6549 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
6550 REQUIRE(DNS_ZONE_VALID(zone));
6553 zone->maxretry = val;
6556 static isc_boolean_t
6557 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
6558 dns_notify_t *notify;
6560 for (notify = ISC_LIST_HEAD(zone->notifies);
6562 notify = ISC_LIST_NEXT(notify, link)) {
6563 if (notify->request != NULL)
6565 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
6566 dns_name_equal(name, ¬ify->ns))
6568 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
6574 static isc_boolean_t
6575 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
6576 dns_tsigkey_t *key = NULL;
6579 isc_boolean_t isself;
6580 isc_netaddr_t dstaddr;
6581 isc_result_t result;
6583 if (zone->view == NULL || zone->isself == NULL)
6586 switch (isc_sockaddr_pf(dst)) {
6588 src = zone->notifysrc4;
6589 isc_sockaddr_any(&any);
6592 src = zone->notifysrc6;
6593 isc_sockaddr_any6(&any);
6600 * When sending from any the kernel will assign a source address
6601 * that matches the destination address.
6603 if (isc_sockaddr_eqaddr(&any, &src))
6606 isc_netaddr_fromsockaddr(&dstaddr, dst);
6607 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
6608 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
6610 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
6613 dns_tsigkey_detach(&key);
6618 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
6622 * Caller holds zone lock.
6624 REQUIRE(DNS_NOTIFY_VALID(notify));
6626 if (notify->zone != NULL) {
6628 LOCK_ZONE(notify->zone);
6629 REQUIRE(LOCKED_ZONE(notify->zone));
6630 if (ISC_LINK_LINKED(notify, link))
6631 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
6633 UNLOCK_ZONE(notify->zone);
6635 zone_idetach(¬ify->zone);
6637 dns_zone_idetach(¬ify->zone);
6639 if (notify->find != NULL)
6640 dns_adb_destroyfind(¬ify->find);
6641 if (notify->request != NULL)
6642 dns_request_destroy(¬ify->request);
6643 if (dns_name_dynamic(¬ify->ns))
6644 dns_name_free(¬ify->ns, notify->mctx);
6645 mctx = notify->mctx;
6646 isc_mem_put(notify->mctx, notify, sizeof(*notify));
6647 isc_mem_detach(&mctx);
6651 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
6652 dns_notify_t *notify;
6654 REQUIRE(notifyp != NULL && *notifyp == NULL);
6656 notify = isc_mem_get(mctx, sizeof(*notify));
6658 return (ISC_R_NOMEMORY);
6660 notify->mctx = NULL;
6661 isc_mem_attach(mctx, ¬ify->mctx);
6662 notify->flags = flags;
6663 notify->zone = NULL;
6664 notify->find = NULL;
6665 notify->request = NULL;
6666 isc_sockaddr_any(¬ify->dst);
6667 dns_name_init(¬ify->ns, NULL);
6668 ISC_LINK_INIT(notify, link);
6669 notify->magic = NOTIFY_MAGIC;
6671 return (ISC_R_SUCCESS);
6675 * XXXAG should check for DNS_ZONEFLG_EXITING
6678 process_adb_event(isc_task_t *task, isc_event_t *ev) {
6679 dns_notify_t *notify;
6680 isc_eventtype_t result;
6684 notify = ev->ev_arg;
6685 REQUIRE(DNS_NOTIFY_VALID(notify));
6686 INSIST(task == notify->zone->task);
6687 result = ev->ev_type;
6688 isc_event_free(&ev);
6689 if (result == DNS_EVENT_ADBMOREADDRESSES) {
6690 dns_adb_destroyfind(¬ify->find);
6691 notify_find_address(notify);
6694 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
6695 LOCK_ZONE(notify->zone);
6696 notify_send(notify);
6697 UNLOCK_ZONE(notify->zone);
6699 notify_destroy(notify, ISC_FALSE);
6703 notify_find_address(dns_notify_t *notify) {
6704 isc_result_t result;
6705 unsigned int options;
6707 REQUIRE(DNS_NOTIFY_VALID(notify));
6708 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
6709 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
6711 if (notify->zone->view->adb == NULL)
6714 result = dns_adb_createfind(notify->zone->view->adb,
6716 process_adb_event, notify,
6717 ¬ify->ns, dns_rootname, 0,
6719 notify->zone->view->dstport,
6722 /* Something failed? */
6723 if (result != ISC_R_SUCCESS)
6726 /* More addresses pending? */
6727 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
6730 /* We have as many addresses as we can get. */
6731 LOCK_ZONE(notify->zone);
6732 notify_send(notify);
6733 UNLOCK_ZONE(notify->zone);
6736 notify_destroy(notify, ISC_FALSE);
6741 notify_send_queue(dns_notify_t *notify) {
6743 isc_result_t result;
6745 e = isc_event_allocate(notify->mctx, NULL,
6746 DNS_EVENT_NOTIFYSENDTOADDR,
6748 notify, sizeof(isc_event_t));
6750 return (ISC_R_NOMEMORY);
6752 e->ev_sender = NULL;
6753 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
6754 notify->zone->task, &e);
6755 if (result != ISC_R_SUCCESS)
6761 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
6762 dns_notify_t *notify;
6763 isc_result_t result;
6764 dns_message_t *message = NULL;
6765 isc_netaddr_t dstip;
6766 dns_tsigkey_t *key = NULL;
6767 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6770 isc_boolean_t have_notifysource = ISC_FALSE;
6772 notify = event->ev_arg;
6773 REQUIRE(DNS_NOTIFY_VALID(notify));
6777 LOCK_ZONE(notify->zone);
6779 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
6780 result = ISC_R_CANCELED;
6784 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
6785 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
6786 notify->zone->view->requestmgr == NULL ||
6787 notify->zone->db == NULL) {
6788 result = ISC_R_CANCELED;
6793 * The raw IPv4 address should also exist. Don't send to the
6796 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
6797 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
6798 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6799 notify_log(notify->zone, ISC_LOG_DEBUG(3),
6800 "notify: ignoring IPv6 mapped IPV4 address: %s",
6802 result = ISC_R_CANCELED;
6806 result = notify_createmessage(notify->zone, notify->flags, &message);
6807 if (result != ISC_R_SUCCESS)
6810 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
6811 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6812 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
6813 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6814 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
6815 "sent. Peer TSIG key lookup failure.", addrbuf);
6816 goto cleanup_message;
6819 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
6821 if (notify->zone->view->peers != NULL) {
6822 dns_peer_t *peer = NULL;
6823 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
6825 if (result == ISC_R_SUCCESS) {
6826 result = dns_peer_getnotifysource(peer, &src);
6827 if (result == ISC_R_SUCCESS)
6828 have_notifysource = ISC_TRUE;
6831 switch (isc_sockaddr_pf(¬ify->dst)) {
6833 if (!have_notifysource)
6834 src = notify->zone->notifysrc4;
6837 if (!have_notifysource)
6838 src = notify->zone->notifysrc6;
6841 result = ISC_R_NOTIMPLEMENTED;
6845 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
6847 result = dns_request_createvia2(notify->zone->view->requestmgr,
6848 message, &src, ¬ify->dst, 0, key,
6849 timeout * 3, timeout,
6850 notify->zone->task, notify_done,
6851 notify, ¬ify->request);
6852 if (result == ISC_R_SUCCESS) {
6853 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
6854 inc_stats(notify->zone,
6855 dns_zonestatscounter_notifyoutv4);
6857 inc_stats(notify->zone,
6858 dns_zonestatscounter_notifyoutv6);
6864 dns_tsigkey_detach(&key);
6866 dns_message_destroy(&message);
6868 UNLOCK_ZONE(notify->zone);
6869 if (result != ISC_R_SUCCESS)
6870 notify_destroy(notify, ISC_FALSE);
6871 isc_event_free(&event);
6875 notify_send(dns_notify_t *notify) {
6876 dns_adbaddrinfo_t *ai;
6878 isc_result_t result;
6879 dns_notify_t *new = NULL;
6882 * Zone lock held by caller.
6884 REQUIRE(DNS_NOTIFY_VALID(notify));
6885 REQUIRE(LOCKED_ZONE(notify->zone));
6887 for (ai = ISC_LIST_HEAD(notify->find->list);
6889 ai = ISC_LIST_NEXT(ai, publink)) {
6891 if (notify_isqueued(notify->zone, NULL, &dst))
6893 if (notify_isself(notify->zone, &dst))
6896 result = notify_create(notify->mctx,
6897 (notify->flags & DNS_NOTIFY_NOSOA),
6899 if (result != ISC_R_SUCCESS)
6901 zone_iattach(notify->zone, &new->zone);
6902 ISC_LIST_APPEND(new->zone->notifies, new, link);
6904 result = notify_send_queue(new);
6905 if (result != ISC_R_SUCCESS)
6912 notify_destroy(new, ISC_TRUE);
6916 dns_zone_notify(dns_zone_t *zone) {
6919 REQUIRE(DNS_ZONE_VALID(zone));
6922 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6925 zone_settimer(zone, &now);
6930 zone_notify(dns_zone_t *zone, isc_time_t *now) {
6931 dns_dbnode_t *node = NULL;
6932 dns_db_t *zonedb = NULL;
6933 dns_dbversion_t *version = NULL;
6934 dns_name_t *origin = NULL;
6937 dns_rdata_soa_t soa;
6938 isc_uint32_t serial;
6939 dns_rdata_t rdata = DNS_RDATA_INIT;
6940 dns_rdataset_t nsrdset;
6941 dns_rdataset_t soardset;
6942 isc_result_t result;
6943 dns_notify_t *notify = NULL;
6946 isc_boolean_t isqueued;
6947 dns_notifytype_t notifytype;
6948 unsigned int flags = 0;
6949 isc_boolean_t loggednotify = ISC_FALSE;
6951 REQUIRE(DNS_ZONE_VALID(zone));
6954 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6955 notifytype = zone->notifytype;
6956 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
6959 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
6962 if (notifytype == dns_notifytype_no)
6965 if (notifytype == dns_notifytype_masteronly &&
6966 zone->type != dns_zone_master)
6969 origin = &zone->origin;
6972 * If the zone is dialup we are done as we don't want to send
6973 * the current soa so as to force a refresh query.
6975 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
6976 flags |= DNS_NOTIFY_NOSOA;
6981 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6982 if (zone->db != NULL)
6983 dns_db_attach(zone->db, &zonedb);
6984 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6987 dns_db_currentversion(zonedb, &version);
6988 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
6989 if (result != ISC_R_SUCCESS)
6992 dns_rdataset_init(&soardset);
6993 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
6994 dns_rdatatype_none, 0, &soardset, NULL);
6995 if (result != ISC_R_SUCCESS)
6999 * Find serial and master server's name.
7001 dns_name_init(&master, NULL);
7002 result = dns_rdataset_first(&soardset);
7003 if (result != ISC_R_SUCCESS)
7005 dns_rdataset_current(&soardset, &rdata);
7006 result = dns_rdata_tostruct(&rdata, &soa, NULL);
7007 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7008 dns_rdata_reset(&rdata);
7009 result = dns_name_dup(&soa.origin, zone->mctx, &master);
7010 serial = soa.serial;
7011 dns_rdataset_disassociate(&soardset);
7012 if (result != ISC_R_SUCCESS)
7016 * Enqueue notify requests for 'also-notify' servers.
7019 for (i = 0; i < zone->notifycnt; i++) {
7020 dst = zone->notify[i];
7021 if (notify_isqueued(zone, NULL, &dst))
7023 result = notify_create(zone->mctx, flags, ¬ify);
7024 if (result != ISC_R_SUCCESS)
7026 zone_iattach(zone, ¬ify->zone);
7028 ISC_LIST_APPEND(zone->notifies, notify, link);
7029 result = notify_send_queue(notify);
7030 if (result != ISC_R_SUCCESS)
7031 notify_destroy(notify, ISC_TRUE);
7032 if (!loggednotify) {
7033 notify_log(zone, ISC_LOG_INFO,
7034 "sending notifies (serial %u)",
7036 loggednotify = ISC_TRUE;
7042 if (notifytype == dns_notifytype_explicit)
7046 * Process NS RRset to generate notifies.
7049 dns_rdataset_init(&nsrdset);
7050 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
7051 dns_rdatatype_none, 0, &nsrdset, NULL);
7052 if (result != ISC_R_SUCCESS)
7055 result = dns_rdataset_first(&nsrdset);
7056 while (result == ISC_R_SUCCESS) {
7057 dns_rdataset_current(&nsrdset, &rdata);
7058 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7059 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7060 dns_rdata_reset(&rdata);
7062 * Don't notify the master server unless explicitly
7063 * configured to do so.
7065 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
7066 dns_name_compare(&master, &ns.name) == 0) {
7067 result = dns_rdataset_next(&nsrdset);
7071 if (!loggednotify) {
7072 notify_log(zone, ISC_LOG_INFO,
7073 "sending notifies (serial %u)",
7075 loggednotify = ISC_TRUE;
7079 isqueued = notify_isqueued(zone, &ns.name, NULL);
7082 result = dns_rdataset_next(&nsrdset);
7085 result = notify_create(zone->mctx, flags, ¬ify);
7086 if (result != ISC_R_SUCCESS)
7088 dns_zone_iattach(zone, ¬ify->zone);
7089 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
7090 if (result != ISC_R_SUCCESS) {
7092 notify_destroy(notify, ISC_TRUE);
7097 ISC_LIST_APPEND(zone->notifies, notify, link);
7099 notify_find_address(notify);
7101 result = dns_rdataset_next(&nsrdset);
7103 dns_rdataset_disassociate(&nsrdset);
7106 if (dns_name_dynamic(&master))
7107 dns_name_free(&master, zone->mctx);
7109 dns_db_detachnode(zonedb, &node);
7111 dns_db_closeversion(zonedb, &version, ISC_FALSE);
7112 dns_db_detach(&zonedb);
7119 static inline isc_result_t
7120 save_nsrrset(dns_message_t *message, dns_name_t *name,
7121 dns_db_t *db, dns_dbversion_t *version)
7123 dns_rdataset_t *nsrdataset = NULL;
7124 dns_rdataset_t *rdataset = NULL;
7125 dns_dbnode_t *node = NULL;
7127 isc_result_t result;
7128 dns_rdata_t rdata = DNS_RDATA_INIT;
7131 * Extract NS RRset from message.
7133 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
7134 dns_rdatatype_ns, dns_rdatatype_none,
7136 if (result != ISC_R_SUCCESS)
7142 result = dns_db_findnode(db, name, ISC_TRUE, &node);
7143 if (result != ISC_R_SUCCESS)
7145 result = dns_db_addrdataset(db, node, version, 0,
7146 nsrdataset, 0, NULL);
7147 dns_db_detachnode(db, &node);
7148 if (result != ISC_R_SUCCESS)
7151 * Add glue rdatasets.
7153 for (result = dns_rdataset_first(nsrdataset);
7154 result == ISC_R_SUCCESS;
7155 result = dns_rdataset_next(nsrdataset)) {
7156 dns_rdataset_current(nsrdataset, &rdata);
7157 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7158 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7159 dns_rdata_reset(&rdata);
7160 if (!dns_name_issubdomain(&ns.name, name))
7163 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7164 &ns.name, dns_rdatatype_aaaa,
7165 dns_rdatatype_none, NULL,
7167 if (result == ISC_R_SUCCESS) {
7168 result = dns_db_findnode(db, &ns.name,
7170 if (result != ISC_R_SUCCESS)
7172 result = dns_db_addrdataset(db, node, version, 0,
7174 dns_db_detachnode(db, &node);
7175 if (result != ISC_R_SUCCESS)
7179 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7180 &ns.name, dns_rdatatype_a,
7181 dns_rdatatype_none, NULL,
7183 if (result == ISC_R_SUCCESS) {
7184 result = dns_db_findnode(db, &ns.name,
7186 if (result != ISC_R_SUCCESS)
7188 result = dns_db_addrdataset(db, node, version, 0,
7190 dns_db_detachnode(db, &node);
7191 if (result != ISC_R_SUCCESS)
7195 if (result != ISC_R_NOMORE)
7198 return (ISC_R_SUCCESS);
7205 stub_callback(isc_task_t *task, isc_event_t *event) {
7206 const char me[] = "stub_callback";
7207 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7208 dns_stub_t *stub = NULL;
7209 dns_message_t *msg = NULL;
7210 dns_zone_t *zone = NULL;
7211 char master[ISC_SOCKADDR_FORMATSIZE];
7212 char source[ISC_SOCKADDR_FORMATSIZE];
7213 isc_uint32_t nscnt, cnamecnt;
7214 isc_result_t result;
7216 isc_boolean_t exiting = ISC_FALSE;
7220 stub = revent->ev_arg;
7221 INSIST(DNS_STUB_VALID(stub));
7231 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7232 zone_debuglog(zone, me, 1, "exiting");
7237 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7238 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7240 if (revent->result != ISC_R_SUCCESS) {
7241 if (revent->result == ISC_R_TIMEDOUT &&
7242 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7244 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7246 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7247 "refreshing stub: timeout retrying "
7248 " without EDNS master %s (source %s)",
7252 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
7253 &zone->sourceaddr, &now);
7254 dns_zone_log(zone, ISC_LOG_INFO,
7255 "could not refresh stub from master %s"
7256 " (source %s): %s", master, source,
7257 dns_result_totext(revent->result));
7261 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7262 if (result != ISC_R_SUCCESS)
7265 result = dns_request_getresponse(revent->request, msg, 0);
7266 if (result != ISC_R_SUCCESS)
7272 if (msg->rcode != dns_rcode_noerror) {
7276 isc_buffer_init(&rb, rcode, sizeof(rcode));
7277 (void)dns_rcode_totext(msg->rcode, &rb);
7279 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7280 (msg->rcode == dns_rcode_servfail ||
7281 msg->rcode == dns_rcode_notimp ||
7282 msg->rcode == dns_rcode_formerr)) {
7283 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7284 "refreshing stub: rcode (%.*s) retrying "
7285 "without EDNS master %s (source %s)",
7286 (int)rb.used, rcode, master, source);
7288 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7293 dns_zone_log(zone, ISC_LOG_INFO,
7295 "unexpected rcode (%.*s) from %s (source %s)",
7296 (int)rb.used, rcode, master, source);
7301 * We need complete messages.
7303 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7304 if (dns_request_usedtcp(revent->request)) {
7305 dns_zone_log(zone, ISC_LOG_INFO,
7306 "refreshing stub: truncated TCP "
7307 "response from master %s (source %s)",
7312 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7318 * If non-auth log and next master.
7320 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7321 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
7322 "non-authoritative answer from "
7323 "master %s (source %s)", master, source);
7330 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7331 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
7333 if (cnamecnt != 0) {
7334 dns_zone_log(zone, ISC_LOG_INFO,
7335 "refreshing stub: unexpected CNAME response "
7336 "from master %s (source %s)", master, source);
7341 dns_zone_log(zone, ISC_LOG_INFO,
7342 "refreshing stub: no NS records in response "
7343 "from master %s (source %s)", master, source);
7350 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
7351 if (result != ISC_R_SUCCESS) {
7352 dns_zone_log(zone, ISC_LOG_INFO,
7353 "refreshing stub: unable to save NS records "
7354 "from master %s (source %s)", master, source);
7361 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
7362 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
7363 if (zone->db == NULL)
7364 zone_attachdb(zone, stub->db);
7365 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
7366 dns_db_detach(&stub->db);
7368 if (zone->masterfile != NULL) {
7369 dns_zone_dump(zone);
7370 TIME_NOW(&zone->loadtime);
7373 dns_message_destroy(&msg);
7374 isc_event_free(&event);
7376 dns_request_destroy(&zone->request);
7377 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7378 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7379 isc_interval_set(&i, zone->expire, 0);
7380 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7381 zone_settimer(zone, &now);
7386 if (stub->version != NULL)
7387 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
7388 if (stub->db != NULL)
7389 dns_db_detach(&stub->db);
7391 dns_message_destroy(&msg);
7392 isc_event_free(&event);
7394 dns_request_destroy(&zone->request);
7396 * Skip to next failed / untried master.
7400 } while (zone->curmaster < zone->masterscnt &&
7401 zone->mastersok[zone->curmaster]);
7402 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7403 if (exiting || zone->curmaster >= zone->masterscnt) {
7404 isc_boolean_t done = ISC_TRUE;
7406 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7407 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7409 * Did we get a good answer from all the masters?
7411 for (j = 0; j < zone->masterscnt; j++)
7412 if (zone->mastersok[j] == ISC_FALSE) {
7419 zone->curmaster = 0;
7421 * Find the next failed master.
7423 while (zone->curmaster < zone->masterscnt &&
7424 zone->mastersok[zone->curmaster])
7426 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7428 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7430 zone_settimer(zone, &now);
7435 queue_soa_query(zone);
7441 dns_message_destroy(&msg);
7442 isc_event_free(&event);
7444 dns_request_destroy(&zone->request);
7446 ns_query(zone, NULL, stub);
7451 dns_zone_idetach(&stub->zone);
7452 INSIST(stub->db == NULL);
7453 INSIST(stub->version == NULL);
7454 isc_mem_put(stub->mctx, stub, sizeof(*stub));
7457 INSIST(event == NULL);
7462 * An SOA query has finished (successfully or not).
7465 refresh_callback(isc_task_t *task, isc_event_t *event) {
7466 const char me[] = "refresh_callback";
7467 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7469 dns_message_t *msg = NULL;
7470 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
7472 char master[ISC_SOCKADDR_FORMATSIZE];
7473 char source[ISC_SOCKADDR_FORMATSIZE];
7474 dns_rdataset_t *rdataset = NULL;
7475 dns_rdata_t rdata = DNS_RDATA_INIT;
7476 dns_rdata_soa_t soa;
7477 isc_result_t result;
7478 isc_uint32_t serial, oldserial;
7481 zone = revent->ev_arg;
7482 INSIST(DNS_ZONE_VALID(zone));
7489 * if timeout log and next master;
7492 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7493 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7497 if (revent->result != ISC_R_SUCCESS) {
7498 if (revent->result == ISC_R_TIMEDOUT &&
7499 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7501 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7503 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7504 "refresh: timeout retrying without EDNS "
7505 "master %s (source %s)", master, source);
7508 if (revent->result == ISC_R_TIMEDOUT &&
7509 !dns_request_usedtcp(revent->request)) {
7510 dns_zone_log(zone, ISC_LOG_INFO,
7511 "refresh: retry limit for "
7512 "master %s exceeded (source %s)",
7514 /* Try with slave with TCP. */
7515 if (zone->type == dns_zone_slave &&
7516 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
7517 if (!dns_zonemgr_unreachable(zone->zmgr,
7522 DNS_ZONE_SETFLAG(zone,
7523 DNS_ZONEFLG_SOABEFOREAXFR);
7527 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7528 "refresh: skipped tcp fallback "
7529 "as master %s (source %s) is "
7530 "unreachable (cached)",
7534 dns_zone_log(zone, ISC_LOG_INFO,
7535 "refresh: failure trying master "
7536 "%s (source %s): %s", master, source,
7537 dns_result_totext(revent->result));
7541 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7542 if (result != ISC_R_SUCCESS)
7544 result = dns_request_getresponse(revent->request, msg, 0);
7545 if (result != ISC_R_SUCCESS) {
7546 dns_zone_log(zone, ISC_LOG_INFO,
7547 "refresh: failure trying master "
7548 "%s (source %s): %s", master, source,
7549 dns_result_totext(result));
7556 if (msg->rcode != dns_rcode_noerror) {
7560 isc_buffer_init(&rb, rcode, sizeof(rcode));
7561 (void)dns_rcode_totext(msg->rcode, &rb);
7563 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7564 (msg->rcode == dns_rcode_servfail ||
7565 msg->rcode == dns_rcode_notimp ||
7566 msg->rcode == dns_rcode_formerr)) {
7567 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7568 "refresh: rcode (%.*s) retrying without "
7569 "EDNS master %s (source %s)",
7570 (int)rb.used, rcode, master, source);
7572 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7576 dns_zone_log(zone, ISC_LOG_INFO,
7577 "refresh: unexpected rcode (%.*s) from "
7578 "master %s (source %s)", (int)rb.used, rcode,
7581 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
7583 if (msg->rcode == dns_rcode_refused &&
7584 zone->type == dns_zone_slave)
7590 * If truncated punt to zone transfer which will query again.
7592 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7593 if (zone->type == dns_zone_slave) {
7594 dns_zone_log(zone, ISC_LOG_INFO,
7595 "refresh: truncated UDP answer, "
7596 "initiating TCP zone xfer "
7597 "for master %s (source %s)",
7600 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
7604 INSIST(zone->type == dns_zone_stub);
7605 if (dns_request_usedtcp(revent->request)) {
7606 dns_zone_log(zone, ISC_LOG_INFO,
7607 "refresh: truncated TCP response "
7608 "from master %s (source %s)",
7613 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7620 * if non-auth log and next master;
7622 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7623 dns_zone_log(zone, ISC_LOG_INFO,
7624 "refresh: non-authoritative answer from "
7625 "master %s (source %s)", master, source);
7629 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7630 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
7631 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
7632 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
7636 * There should not be a CNAME record at top of zone.
7638 if (cnamecnt != 0) {
7639 dns_zone_log(zone, ISC_LOG_INFO,
7640 "refresh: CNAME at top of zone "
7641 "in master %s (source %s)", master, source);
7646 * if referral log and next master;
7648 if (soacnt == 0 && soacount == 0 && nscount != 0) {
7649 dns_zone_log(zone, ISC_LOG_INFO,
7650 "refresh: referral response "
7651 "from master %s (source %s)", master, source);
7656 * if nodata log and next master;
7658 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
7659 dns_zone_log(zone, ISC_LOG_INFO,
7660 "refresh: NODATA response "
7661 "from master %s (source %s)", master, source);
7666 * Only one soa at top of zone.
7669 dns_zone_log(zone, ISC_LOG_INFO,
7670 "refresh: answer SOA count (%d) != 1 "
7671 "from master %s (source %s)",
7672 soacnt, master, source);
7679 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
7680 dns_rdatatype_soa, dns_rdatatype_none,
7682 if (result != ISC_R_SUCCESS) {
7683 dns_zone_log(zone, ISC_LOG_INFO,
7684 "refresh: unable to get SOA record "
7685 "from master %s (source %s)", master, source);
7689 result = dns_rdataset_first(rdataset);
7690 if (result != ISC_R_SUCCESS) {
7691 dns_zone_log(zone, ISC_LOG_INFO,
7692 "refresh: dns_rdataset_first() failed");
7696 dns_rdataset_current(rdataset, &rdata);
7697 result = dns_rdata_tostruct(&rdata, &soa, NULL);
7698 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7700 serial = soa.serial;
7701 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
7702 result = dns_zone_getserial2(zone, &oldserial);
7703 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7704 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
7707 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
7710 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
7711 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
7712 isc_serial_gt(serial, oldserial)) {
7713 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
7714 &zone->sourceaddr, &now)) {
7715 dns_zone_log(zone, ISC_LOG_INFO,
7716 "refresh: skipping %s as master %s "
7717 "(source %s) is unreachable (cached)",
7718 zone->type == dns_zone_slave ?
7719 "zone transfer" : "NS query",
7724 isc_event_free(&event);
7726 dns_request_destroy(&zone->request);
7728 if (zone->type == dns_zone_slave) {
7731 INSIST(zone->type == dns_zone_stub);
7732 ns_query(zone, rdataset, NULL);
7735 dns_message_destroy(&msg);
7736 } else if (isc_serial_eq(soa.serial, oldserial)) {
7737 if (zone->masterfile != NULL) {
7738 result = ISC_R_FAILURE;
7739 if (zone->journal != NULL)
7740 result = isc_file_settime(zone->journal, &now);
7741 if (result == ISC_R_SUCCESS &&
7742 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
7743 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
7744 result = isc_file_settime(zone->masterfile,
7746 } else if (result != ISC_R_SUCCESS)
7747 result = isc_file_settime(zone->masterfile,
7749 /* Someone removed the file from underneath us! */
7750 if (result == ISC_R_FILENOTFOUND) {
7752 zone_needdump(zone, DNS_DUMP_DELAY);
7754 } else if (result != ISC_R_SUCCESS)
7755 dns_zone_log(zone, ISC_LOG_ERROR,
7756 "refresh: could not set file "
7757 "modification time of '%s': %s",
7759 dns_result_totext(result));
7761 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7762 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7763 zone->mastersok[zone->curmaster] = ISC_TRUE;
7766 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
7767 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
7768 "received from master %s < ours (%u)",
7769 soa.serial, master, oldserial);
7771 zone_debuglog(zone, me, 1, "ahead");
7772 zone->mastersok[zone->curmaster] = ISC_TRUE;
7776 dns_message_destroy(&msg);
7781 dns_message_destroy(&msg);
7782 isc_event_free(&event);
7784 dns_request_destroy(&zone->request);
7786 * Skip to next failed / untried master.
7790 } while (zone->curmaster < zone->masterscnt &&
7791 zone->mastersok[zone->curmaster]);
7792 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7793 if (zone->curmaster >= zone->masterscnt) {
7794 isc_boolean_t done = ISC_TRUE;
7795 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7796 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7798 * Did we get a good answer from all the masters?
7800 for (j = 0; j < zone->masterscnt; j++)
7801 if (zone->mastersok[j] == ISC_FALSE) {
7808 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7809 zone->curmaster = 0;
7811 * Find the next failed master.
7813 while (zone->curmaster < zone->masterscnt &&
7814 zone->mastersok[zone->curmaster])
7818 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7819 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
7820 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
7821 zone->refreshtime = now;
7823 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7824 zone_settimer(zone, &now);
7830 queue_soa_query(zone);
7836 dns_message_destroy(&msg);
7837 isc_event_free(&event);
7839 dns_request_destroy(&zone->request);
7840 queue_soa_query(zone);
7844 dns_zone_idetach(&zone);
7849 queue_soa_query(dns_zone_t *zone) {
7850 const char me[] = "queue_soa_query";
7852 dns_zone_t *dummy = NULL;
7853 isc_result_t result;
7859 REQUIRE(LOCKED_ZONE(zone));
7861 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7862 cancel_refresh(zone);
7866 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
7867 soa_query, zone, sizeof(isc_event_t));
7869 cancel_refresh(zone);
7874 * Attach so that we won't clean up
7875 * until the event is delivered.
7877 zone_iattach(zone, &dummy);
7880 e->ev_sender = NULL;
7881 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
7882 if (result != ISC_R_SUCCESS) {
7883 zone_idetach(&dummy);
7885 cancel_refresh(zone);
7889 static inline isc_result_t
7890 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
7891 dns_message_t **messagep)
7893 dns_message_t *message = NULL;
7894 dns_name_t *qname = NULL;
7895 dns_rdataset_t *qrdataset = NULL;
7896 isc_result_t result;
7898 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
7900 if (result != ISC_R_SUCCESS)
7903 message->opcode = dns_opcode_query;
7904 message->rdclass = zone->rdclass;
7906 result = dns_message_gettempname(message, &qname);
7907 if (result != ISC_R_SUCCESS)
7910 result = dns_message_gettemprdataset(message, &qrdataset);
7911 if (result != ISC_R_SUCCESS)
7917 dns_name_init(qname, NULL);
7918 dns_name_clone(&zone->origin, qname);
7919 dns_rdataset_init(qrdataset);
7920 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
7921 ISC_LIST_APPEND(qname->list, qrdataset, link);
7922 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
7924 *messagep = message;
7925 return (ISC_R_SUCCESS);
7929 dns_message_puttempname(message, &qname);
7930 if (qrdataset != NULL)
7931 dns_message_puttemprdataset(message, &qrdataset);
7932 if (message != NULL)
7933 dns_message_destroy(&message);
7938 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
7939 dns_rdataset_t *rdataset = NULL;
7940 dns_rdatalist_t *rdatalist = NULL;
7941 dns_rdata_t *rdata = NULL;
7942 isc_result_t result;
7944 result = dns_message_gettemprdatalist(message, &rdatalist);
7945 if (result != ISC_R_SUCCESS)
7947 result = dns_message_gettemprdata(message, &rdata);
7948 if (result != ISC_R_SUCCESS)
7950 result = dns_message_gettemprdataset(message, &rdataset);
7951 if (result != ISC_R_SUCCESS)
7953 dns_rdataset_init(rdataset);
7955 rdatalist->type = dns_rdatatype_opt;
7956 rdatalist->covers = 0;
7959 * Set Maximum UDP buffer size.
7961 rdatalist->rdclass = udpsize;
7964 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
7968 /* Set EDNS options if applicable */
7970 unsigned char data[4];
7973 isc_buffer_init(&buf, data, sizeof(data));
7974 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
7975 isc_buffer_putuint16(&buf, 0);
7977 rdata->length = sizeof(data);
7983 rdata->rdclass = rdatalist->rdclass;
7984 rdata->type = rdatalist->type;
7987 ISC_LIST_INIT(rdatalist->rdata);
7988 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
7989 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
7992 return (dns_message_setopt(message, rdataset));
7995 if (rdatalist != NULL)
7996 dns_message_puttemprdatalist(message, &rdatalist);
7997 if (rdataset != NULL)
7998 dns_message_puttemprdataset(message, &rdataset);
8000 dns_message_puttemprdata(message, &rdata);
8006 soa_query(isc_task_t *task, isc_event_t *event) {
8007 const char me[] = "soa_query";
8008 isc_result_t result = ISC_R_FAILURE;
8009 dns_message_t *message = NULL;
8010 dns_zone_t *zone = event->ev_arg;
8011 dns_zone_t *dummy = NULL;
8012 isc_netaddr_t masterip;
8013 dns_tsigkey_t *key = NULL;
8014 isc_uint32_t options;
8015 isc_boolean_t cancel = ISC_TRUE;
8017 isc_boolean_t have_xfrsource, reqnsid;
8018 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8020 REQUIRE(DNS_ZONE_VALID(zone));
8027 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
8028 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
8029 zone->view->requestmgr == NULL) {
8030 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8036 * XXX Optimisation: Create message when zone is setup and reuse.
8038 result = create_query(zone, dns_rdatatype_soa, &message);
8039 if (result != ISC_R_SUCCESS)
8043 INSIST(zone->masterscnt > 0);
8044 INSIST(zone->curmaster < zone->masterscnt);
8046 zone->masteraddr = zone->masters[zone->curmaster];
8048 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8050 * First, look for a tsig key in the master statement, then
8051 * try for a server key.
8053 if ((zone->masterkeynames != NULL) &&
8054 (zone->masterkeynames[zone->curmaster] != NULL)) {
8055 dns_view_t *view = dns_zone_getview(zone);
8056 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8057 result = dns_view_gettsig(view, keyname, &key);
8058 if (result != ISC_R_SUCCESS) {
8059 char namebuf[DNS_NAME_FORMATSIZE];
8060 dns_name_format(keyname, namebuf, sizeof(namebuf));
8061 dns_zone_log(zone, ISC_LOG_ERROR,
8062 "unable to find key: %s", namebuf);
8067 result = dns_view_getpeertsig(zone->view, &masterip, &key);
8068 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
8069 char addrbuf[ISC_NETADDR_FORMATSIZE];
8070 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
8071 dns_zone_log(zone, ISC_LOG_ERROR,
8072 "unable to find TSIG key for %s", addrbuf);
8077 have_xfrsource = ISC_FALSE;
8078 reqnsid = zone->view->requestnsid;
8079 if (zone->view->peers != NULL) {
8080 dns_peer_t *peer = NULL;
8082 result = dns_peerlist_peerbyaddr(zone->view->peers,
8084 if (result == ISC_R_SUCCESS) {
8085 result = dns_peer_getsupportedns(peer, &edns);
8086 if (result == ISC_R_SUCCESS && !edns)
8087 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8088 result = dns_peer_gettransfersource(peer,
8090 if (result == ISC_R_SUCCESS)
8091 have_xfrsource = ISC_TRUE;
8092 if (zone->view->resolver != NULL)
8094 dns_resolver_getudpsize(zone->view->resolver);
8095 (void)dns_peer_getudpsize(peer, &udpsize);
8096 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8100 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8102 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8103 if (isc_sockaddr_equal(&zone->altxfrsource4,
8106 zone->sourceaddr = zone->altxfrsource4;
8107 } else if (!have_xfrsource)
8108 zone->sourceaddr = zone->xfrsource4;
8111 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8112 if (isc_sockaddr_equal(&zone->altxfrsource6,
8115 zone->sourceaddr = zone->altxfrsource6;
8116 } else if (!have_xfrsource)
8117 zone->sourceaddr = zone->xfrsource6;
8120 result = ISC_R_NOTIMPLEMENTED;
8124 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
8125 DNS_REQUESTOPT_TCP : 0;
8127 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8128 result = add_opt(message, udpsize, reqnsid);
8129 if (result != ISC_R_SUCCESS)
8130 zone_debuglog(zone, me, 1,
8131 "unable to add opt record: %s",
8132 dns_result_totext(result));
8135 zone_iattach(zone, &dummy);
8137 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8139 result = dns_request_createvia2(zone->view->requestmgr, message,
8140 &zone->sourceaddr, &zone->masteraddr,
8141 options, key, timeout * 3, timeout,
8142 zone->task, refresh_callback, zone,
8144 if (result != ISC_R_SUCCESS) {
8145 zone_idetach(&dummy);
8146 zone_debuglog(zone, me, 1,
8147 "dns_request_createvia2() failed: %s",
8148 dns_result_totext(result));
8151 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
8152 inc_stats(zone, dns_zonestatscounter_soaoutv4);
8154 inc_stats(zone, dns_zonestatscounter_soaoutv6);
8160 dns_tsigkey_detach(&key);
8161 if (result != ISC_R_SUCCESS)
8162 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8163 if (message != NULL)
8164 dns_message_destroy(&message);
8166 cancel_refresh(zone);
8167 isc_event_free(&event);
8169 dns_zone_idetach(&zone);
8174 dns_tsigkey_detach(&key);
8176 * Skip to next failed / untried master.
8180 } while (zone->curmaster < zone->masterscnt &&
8181 zone->mastersok[zone->curmaster]);
8182 if (zone->curmaster < zone->masterscnt)
8184 zone->curmaster = 0;
8189 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
8190 const char me[] = "ns_query";
8191 isc_result_t result;
8192 dns_message_t *message = NULL;
8193 isc_netaddr_t masterip;
8194 dns_tsigkey_t *key = NULL;
8195 dns_dbnode_t *node = NULL;
8197 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
8198 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8200 REQUIRE(DNS_ZONE_VALID(zone));
8201 REQUIRE((soardataset != NULL && stub == NULL) ||
8202 (soardataset == NULL && stub != NULL));
8203 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
8209 stub = isc_mem_get(zone->mctx, sizeof(*stub));
8212 stub->magic = STUB_MAGIC;
8213 stub->mctx = zone->mctx;
8216 stub->version = NULL;
8219 * Attach so that the zone won't disappear from under us.
8221 zone_iattach(zone, &stub->zone);
8224 * If a db exists we will update it, otherwise we create a
8225 * new one and attach it to the zone once we have the NS
8228 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8229 if (zone->db != NULL) {
8230 dns_db_attach(zone->db, &stub->db);
8231 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8233 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8235 INSIST(zone->db_argc >= 1);
8236 result = dns_db_create(zone->mctx, zone->db_argv[0],
8237 &zone->origin, dns_dbtype_stub,
8242 if (result != ISC_R_SUCCESS) {
8243 dns_zone_log(zone, ISC_LOG_ERROR,
8247 dns_result_totext(result));
8250 dns_db_settask(stub->db, zone->task);
8253 dns_db_newversion(stub->db, &stub->version);
8256 * Update SOA record.
8258 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
8260 if (result != ISC_R_SUCCESS) {
8261 dns_zone_log(zone, ISC_LOG_INFO,
8263 "dns_db_findnode() failed: %s",
8264 dns_result_totext(result));
8268 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
8269 soardataset, 0, NULL);
8270 dns_db_detachnode(stub->db, &node);
8271 if (result != ISC_R_SUCCESS) {
8272 dns_zone_log(zone, ISC_LOG_INFO,
8274 "dns_db_addrdataset() failed: %s",
8275 dns_result_totext(result));
8281 * XXX Optimisation: Create message when zone is setup and reuse.
8283 result = create_query(zone, dns_rdatatype_ns, &message);
8284 INSIST(result == ISC_R_SUCCESS);
8286 INSIST(zone->masterscnt > 0);
8287 INSIST(zone->curmaster < zone->masterscnt);
8288 zone->masteraddr = zone->masters[zone->curmaster];
8290 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8292 * First, look for a tsig key in the master statement, then
8293 * try for a server key.
8295 if ((zone->masterkeynames != NULL) &&
8296 (zone->masterkeynames[zone->curmaster] != NULL)) {
8297 dns_view_t *view = dns_zone_getview(zone);
8298 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8299 result = dns_view_gettsig(view, keyname, &key);
8300 if (result != ISC_R_SUCCESS) {
8301 char namebuf[DNS_NAME_FORMATSIZE];
8302 dns_name_format(keyname, namebuf, sizeof(namebuf));
8303 dns_zone_log(zone, ISC_LOG_ERROR,
8304 "unable to find key: %s", namebuf);
8308 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
8310 reqnsid = zone->view->requestnsid;
8311 if (zone->view->peers != NULL) {
8312 dns_peer_t *peer = NULL;
8314 result = dns_peerlist_peerbyaddr(zone->view->peers,
8316 if (result == ISC_R_SUCCESS) {
8317 result = dns_peer_getsupportedns(peer, &edns);
8318 if (result == ISC_R_SUCCESS && !edns)
8319 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8320 result = dns_peer_gettransfersource(peer,
8322 if (result == ISC_R_SUCCESS)
8323 have_xfrsource = ISC_TRUE;
8324 if (zone->view->resolver != NULL)
8326 dns_resolver_getudpsize(zone->view->resolver);
8327 (void)dns_peer_getudpsize(peer, &udpsize);
8328 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8332 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8333 result = add_opt(message, udpsize, reqnsid);
8334 if (result != ISC_R_SUCCESS)
8335 zone_debuglog(zone, me, 1,
8336 "unable to add opt record: %s",
8337 dns_result_totext(result));
8341 * Always use TCP so that we shouldn't truncate in additional section.
8343 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8345 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8346 zone->sourceaddr = zone->altxfrsource4;
8347 else if (!have_xfrsource)
8348 zone->sourceaddr = zone->xfrsource4;
8351 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8352 zone->sourceaddr = zone->altxfrsource6;
8353 else if (!have_xfrsource)
8354 zone->sourceaddr = zone->xfrsource6;
8357 result = ISC_R_NOTIMPLEMENTED;
8362 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8364 result = dns_request_createvia2(zone->view->requestmgr, message,
8365 &zone->sourceaddr, &zone->masteraddr,
8366 DNS_REQUESTOPT_TCP, key, timeout * 3,
8367 timeout, zone->task, stub_callback,
8368 stub, &zone->request);
8369 if (result != ISC_R_SUCCESS) {
8370 zone_debuglog(zone, me, 1,
8371 "dns_request_createvia() failed: %s",
8372 dns_result_totext(result));
8375 dns_message_destroy(&message);
8379 cancel_refresh(zone);
8382 if (stub->version != NULL)
8383 dns_db_closeversion(stub->db, &stub->version,
8385 if (stub->db != NULL)
8386 dns_db_detach(&stub->db);
8387 if (stub->zone != NULL)
8388 zone_idetach(&stub->zone);
8389 isc_mem_put(stub->mctx, stub, sizeof(*stub));
8391 if (message != NULL)
8392 dns_message_destroy(&message);
8395 dns_tsigkey_detach(&key);
8401 * Handle the control event. Note that although this event causes the zone
8402 * to shut down, it is not a shutdown event in the sense of the task library.
8405 zone_shutdown(isc_task_t *task, isc_event_t *event) {
8406 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
8407 isc_boolean_t free_needed, linked = ISC_FALSE;
8410 REQUIRE(DNS_ZONE_VALID(zone));
8411 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
8412 INSIST(isc_refcount_current(&zone->erefs) == 0);
8413 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
8416 * Stop things being restarted after we cancel them below.
8419 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
8423 * If we were waiting for xfrin quota, step out of
8425 * If there's no zone manager, we can't be waiting for the
8428 if (zone->zmgr != NULL) {
8429 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8430 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
8431 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
8434 zone->statelist = NULL;
8436 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8440 * In task context, no locking required. See zone_xfrdone().
8442 if (zone->xfr != NULL)
8443 dns_xfrin_shutdown(zone->xfr);
8447 INSIST(zone->irefs > 0);
8450 if (zone->request != NULL) {
8451 dns_request_cancel(zone->request);
8454 if (zone->readio != NULL)
8455 zonemgr_cancelio(zone->readio);
8457 if (zone->lctx != NULL)
8458 dns_loadctx_cancel(zone->lctx);
8460 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8461 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8462 if (zone->writeio != NULL)
8463 zonemgr_cancelio(zone->writeio);
8465 if (zone->dctx != NULL)
8466 dns_dumpctx_cancel(zone->dctx);
8469 notify_cancel(zone);
8471 if (zone->timer != NULL) {
8472 isc_timer_detach(&zone->timer);
8473 INSIST(zone->irefs > 0);
8477 if (zone->view != NULL)
8478 dns_view_weakdetach(&zone->view);
8481 * We have now canceled everything set the flag to allow exit_check()
8482 * to succeed. We must not unlock between setting this flag and
8483 * calling exit_check().
8485 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
8486 free_needed = exit_check(zone);
8493 zone_timer(isc_task_t *task, isc_event_t *event) {
8494 const char me[] = "zone_timer";
8495 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
8498 REQUIRE(DNS_ZONE_VALID(zone));
8502 zone_maintenance(zone);
8504 isc_event_free(&event);
8508 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
8509 const char me[] = "zone_settimer";
8511 isc_result_t result;
8513 REQUIRE(DNS_ZONE_VALID(zone));
8514 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8517 isc_time_settoepoch(&next);
8519 switch (zone->type) {
8520 case dns_zone_master:
8521 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8522 next = zone->notifytime;
8523 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8524 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8525 INSIST(!isc_time_isepoch(&zone->dumptime));
8526 if (isc_time_isepoch(&next) ||
8527 isc_time_compare(&zone->dumptime, &next) < 0)
8528 next = zone->dumptime;
8530 if (!isc_time_isepoch(&zone->resigntime)) {
8531 if (isc_time_isepoch(&next) ||
8532 isc_time_compare(&zone->resigntime, &next) < 0)
8533 next = zone->resigntime;
8535 if (!isc_time_isepoch(&zone->keywarntime)) {
8536 if (isc_time_isepoch(&next) ||
8537 isc_time_compare(&zone->keywarntime, &next) < 0)
8538 next = zone->keywarntime;
8540 if (!isc_time_isepoch(&zone->signingtime)) {
8541 if (isc_time_isepoch(&next) ||
8542 isc_time_compare(&zone->signingtime, &next) < 0)
8543 next = zone->signingtime;
8545 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
8546 if (isc_time_isepoch(&next) ||
8547 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
8548 next = zone->nsec3chaintime;
8552 case dns_zone_slave:
8553 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8554 next = zone->notifytime;
8558 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
8559 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
8560 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
8561 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
8562 INSIST(!isc_time_isepoch(&zone->refreshtime));
8563 if (isc_time_isepoch(&next) ||
8564 isc_time_compare(&zone->refreshtime, &next) < 0)
8565 next = zone->refreshtime;
8567 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8568 INSIST(!isc_time_isepoch(&zone->expiretime));
8569 if (isc_time_isepoch(&next) ||
8570 isc_time_compare(&zone->expiretime, &next) < 0)
8571 next = zone->expiretime;
8573 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8574 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8575 INSIST(!isc_time_isepoch(&zone->dumptime));
8576 if (isc_time_isepoch(&next) ||
8577 isc_time_compare(&zone->dumptime, &next) < 0)
8578 next = zone->dumptime;
8586 if (isc_time_isepoch(&next)) {
8587 zone_debuglog(zone, me, 10, "settimer inactive");
8588 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
8589 NULL, NULL, ISC_TRUE);
8590 if (result != ISC_R_SUCCESS)
8591 dns_zone_log(zone, ISC_LOG_ERROR,
8592 "could not deactivate zone timer: %s",
8593 isc_result_totext(result));
8595 if (isc_time_compare(&next, now) <= 0)
8597 result = isc_timer_reset(zone->timer, isc_timertype_once,
8598 &next, NULL, ISC_TRUE);
8599 if (result != ISC_R_SUCCESS)
8600 dns_zone_log(zone, ISC_LOG_ERROR,
8601 "could not reset zone timer: %s",
8602 isc_result_totext(result));
8607 cancel_refresh(dns_zone_t *zone) {
8608 const char me[] = "cancel_refresh";
8612 * 'zone' locked by caller.
8615 REQUIRE(DNS_ZONE_VALID(zone));
8616 REQUIRE(LOCKED_ZONE(zone));
8620 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8622 zone_settimer(zone, &now);
8626 notify_createmessage(dns_zone_t *zone, unsigned int flags,
8627 dns_message_t **messagep)
8629 dns_db_t *zonedb = NULL;
8630 dns_dbnode_t *node = NULL;
8631 dns_dbversion_t *version = NULL;
8632 dns_message_t *message = NULL;
8633 dns_rdataset_t rdataset;
8634 dns_rdata_t rdata = DNS_RDATA_INIT;
8636 dns_name_t *tempname = NULL;
8637 dns_rdata_t *temprdata = NULL;
8638 dns_rdatalist_t *temprdatalist = NULL;
8639 dns_rdataset_t *temprdataset = NULL;
8641 isc_result_t result;
8643 isc_buffer_t *b = NULL;
8645 REQUIRE(DNS_ZONE_VALID(zone));
8646 REQUIRE(messagep != NULL && *messagep == NULL);
8648 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
8650 if (result != ISC_R_SUCCESS)
8653 message->opcode = dns_opcode_notify;
8654 message->flags |= DNS_MESSAGEFLAG_AA;
8655 message->rdclass = zone->rdclass;
8657 result = dns_message_gettempname(message, &tempname);
8658 if (result != ISC_R_SUCCESS)
8661 result = dns_message_gettemprdataset(message, &temprdataset);
8662 if (result != ISC_R_SUCCESS)
8668 dns_name_init(tempname, NULL);
8669 dns_name_clone(&zone->origin, tempname);
8670 dns_rdataset_init(temprdataset);
8671 dns_rdataset_makequestion(temprdataset, zone->rdclass,
8673 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8674 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
8676 temprdataset = NULL;
8678 if ((flags & DNS_NOTIFY_NOSOA) != 0)
8681 result = dns_message_gettempname(message, &tempname);
8682 if (result != ISC_R_SUCCESS)
8684 result = dns_message_gettemprdata(message, &temprdata);
8685 if (result != ISC_R_SUCCESS)
8687 result = dns_message_gettemprdataset(message, &temprdataset);
8688 if (result != ISC_R_SUCCESS)
8690 result = dns_message_gettemprdatalist(message, &temprdatalist);
8691 if (result != ISC_R_SUCCESS)
8694 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8695 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
8696 dns_db_attach(zone->db, &zonedb);
8697 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8699 dns_name_init(tempname, NULL);
8700 dns_name_clone(&zone->origin, tempname);
8701 dns_db_currentversion(zonedb, &version);
8702 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
8703 if (result != ISC_R_SUCCESS)
8706 dns_rdataset_init(&rdataset);
8707 result = dns_db_findrdataset(zonedb, node, version,
8709 dns_rdatatype_none, 0, &rdataset,
8711 if (result != ISC_R_SUCCESS)
8713 result = dns_rdataset_first(&rdataset);
8714 if (result != ISC_R_SUCCESS)
8716 dns_rdataset_current(&rdataset, &rdata);
8717 dns_rdata_toregion(&rdata, &r);
8718 result = isc_buffer_allocate(zone->mctx, &b, r.length);
8719 if (result != ISC_R_SUCCESS)
8721 isc_buffer_putmem(b, r.base, r.length);
8722 isc_buffer_usedregion(b, &r);
8723 dns_rdata_init(temprdata);
8724 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
8725 dns_message_takebuffer(message, &b);
8726 result = dns_rdataset_next(&rdataset);
8727 dns_rdataset_disassociate(&rdataset);
8728 if (result != ISC_R_NOMORE)
8730 temprdatalist->rdclass = rdata.rdclass;
8731 temprdatalist->type = rdata.type;
8732 temprdatalist->covers = 0;
8733 temprdatalist->ttl = rdataset.ttl;
8734 ISC_LIST_INIT(temprdatalist->rdata);
8735 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
8737 dns_rdataset_init(temprdataset);
8738 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
8739 if (result != ISC_R_SUCCESS)
8742 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8743 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
8744 temprdatalist = NULL;
8745 temprdataset = NULL;
8751 dns_db_detachnode(zonedb, &node);
8752 if (version != NULL)
8753 dns_db_closeversion(zonedb, &version, ISC_FALSE);
8755 dns_db_detach(&zonedb);
8756 if (tempname != NULL)
8757 dns_message_puttempname(message, &tempname);
8758 if (temprdata != NULL)
8759 dns_message_puttemprdata(message, &temprdata);
8760 if (temprdataset != NULL)
8761 dns_message_puttemprdataset(message, &temprdataset);
8762 if (temprdatalist != NULL)
8763 dns_message_puttemprdatalist(message, &temprdatalist);
8766 *messagep = message;
8767 return (ISC_R_SUCCESS);
8770 if (tempname != NULL)
8771 dns_message_puttempname(message, &tempname);
8772 if (temprdataset != NULL)
8773 dns_message_puttemprdataset(message, &temprdataset);
8774 dns_message_destroy(&message);
8779 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
8783 dns_rdata_soa_t soa;
8784 dns_rdataset_t *rdataset = NULL;
8785 dns_rdata_t rdata = DNS_RDATA_INIT;
8786 isc_result_t result;
8787 char fromtext[ISC_SOCKADDR_FORMATSIZE];
8789 isc_netaddr_t netaddr;
8791 REQUIRE(DNS_ZONE_VALID(zone));
8794 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
8798 * Check that 'from' is a valid notify source, (zone->masters).
8799 * Return DNS_R_REFUSED if not.
8801 * If the notify message contains a serial number check it
8802 * against the zones serial and return if <= current serial
8804 * If a refresh check is progress, if so just record the
8805 * fact we received a NOTIFY and from where and return.
8806 * We will perform a new refresh check when the current one
8807 * completes. Return ISC_R_SUCCESS.
8809 * Otherwise initiate a refresh check using 'from' as the
8810 * first address to check. Return ISC_R_SUCCESS.
8813 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
8816 * We only handle NOTIFY (SOA) at the present.
8819 if (isc_sockaddr_pf(from) == PF_INET)
8820 inc_stats(zone, dns_zonestatscounter_notifyinv4);
8822 inc_stats(zone, dns_zonestatscounter_notifyinv6);
8823 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
8824 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
8825 dns_rdatatype_soa, dns_rdatatype_none,
8826 NULL, NULL) != ISC_R_SUCCESS) {
8828 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
8829 dns_zone_log(zone, ISC_LOG_NOTICE,
8831 "question section from: %s", fromtext);
8832 return (DNS_R_FORMERR);
8834 dns_zone_log(zone, ISC_LOG_NOTICE,
8835 "NOTIFY zone does not match");
8836 return (DNS_R_NOTIMP);
8840 * If we are a master zone just succeed.
8842 if (zone->type == dns_zone_master) {
8844 return (ISC_R_SUCCESS);
8847 isc_netaddr_fromsockaddr(&netaddr, from);
8848 for (i = 0; i < zone->masterscnt; i++) {
8849 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
8851 if (zone->view->aclenv.match_mapped &&
8852 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
8853 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
8854 isc_netaddr_t na1, na2;
8855 isc_netaddr_fromv4mapped(&na1, &netaddr);
8856 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
8857 if (isc_netaddr_equal(&na1, &na2))
8863 * Accept notify requests from non masters if they are on
8864 * 'zone->notify_acl'.
8866 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
8867 dns_acl_match(&netaddr, NULL, zone->notify_acl,
8868 &zone->view->aclenv,
8869 &match, NULL) == ISC_R_SUCCESS &&
8872 /* Accept notify. */
8873 } else if (i >= zone->masterscnt) {
8875 dns_zone_log(zone, ISC_LOG_INFO,
8876 "refused notify from non-master: %s", fromtext);
8877 inc_stats(zone, dns_zonestatscounter_notifyrej);
8878 return (DNS_R_REFUSED);
8882 * If the zone is loaded and there are answers check the serial
8883 * to see if we need to do a refresh. Do not worry about this
8884 * check if we are a dialup zone as we use the notify request
8885 * to trigger a refresh check.
8887 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
8888 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8889 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
8890 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
8893 dns_rdatatype_none, NULL,
8895 if (result == ISC_R_SUCCESS)
8896 result = dns_rdataset_first(rdataset);
8897 if (result == ISC_R_SUCCESS) {
8898 isc_uint32_t serial = 0, oldserial;
8900 dns_rdataset_current(rdataset, &rdata);
8901 result = dns_rdata_tostruct(&rdata, &soa, NULL);
8902 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8903 serial = soa.serial;
8905 * The following should safely be performed without DB
8906 * lock and succeed in this context.
8908 result = zone_get_from_db(zone, zone->db, NULL, NULL,
8909 &oldserial, NULL, NULL, NULL,
8911 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8912 if (isc_serial_le(serial, oldserial)) {
8913 dns_zone_log(zone, ISC_LOG_INFO,
8915 "zone is up to date",
8918 return (ISC_R_SUCCESS);
8924 * If we got this far and there was a refresh in progress just
8925 * let it complete. Record where we got the notify from so we
8926 * can perform a refresh check when the current one completes
8928 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
8929 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
8930 zone->notifyfrom = *from;
8932 dns_zone_log(zone, ISC_LOG_INFO,
8933 "notify from %s: refresh in progress, "
8934 "refresh check queued",
8936 return (ISC_R_SUCCESS);
8938 zone->notifyfrom = *from;
8940 dns_zone_refresh(zone);
8941 return (ISC_R_SUCCESS);
8945 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
8947 REQUIRE(DNS_ZONE_VALID(zone));
8950 if (zone->notify_acl != NULL)
8951 dns_acl_detach(&zone->notify_acl);
8952 dns_acl_attach(acl, &zone->notify_acl);
8957 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
8959 REQUIRE(DNS_ZONE_VALID(zone));
8962 if (zone->query_acl != NULL)
8963 dns_acl_detach(&zone->query_acl);
8964 dns_acl_attach(acl, &zone->query_acl);
8969 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
8971 REQUIRE(DNS_ZONE_VALID(zone));
8974 if (zone->queryon_acl != NULL)
8975 dns_acl_detach(&zone->queryon_acl);
8976 dns_acl_attach(acl, &zone->queryon_acl);
8981 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
8983 REQUIRE(DNS_ZONE_VALID(zone));
8986 if (zone->update_acl != NULL)
8987 dns_acl_detach(&zone->update_acl);
8988 dns_acl_attach(acl, &zone->update_acl);
8993 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
8995 REQUIRE(DNS_ZONE_VALID(zone));
8998 if (zone->forward_acl != NULL)
8999 dns_acl_detach(&zone->forward_acl);
9000 dns_acl_attach(acl, &zone->forward_acl);
9005 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
9007 REQUIRE(DNS_ZONE_VALID(zone));
9010 if (zone->xfr_acl != NULL)
9011 dns_acl_detach(&zone->xfr_acl);
9012 dns_acl_attach(acl, &zone->xfr_acl);
9017 dns_zone_getnotifyacl(dns_zone_t *zone) {
9019 REQUIRE(DNS_ZONE_VALID(zone));
9021 return (zone->notify_acl);
9025 dns_zone_getqueryacl(dns_zone_t *zone) {
9027 REQUIRE(DNS_ZONE_VALID(zone));
9029 return (zone->query_acl);
9033 dns_zone_getqueryonacl(dns_zone_t *zone) {
9035 REQUIRE(DNS_ZONE_VALID(zone));
9037 return (zone->queryon_acl);
9041 dns_zone_getupdateacl(dns_zone_t *zone) {
9043 REQUIRE(DNS_ZONE_VALID(zone));
9045 return (zone->update_acl);
9049 dns_zone_getforwardacl(dns_zone_t *zone) {
9051 REQUIRE(DNS_ZONE_VALID(zone));
9053 return (zone->forward_acl);
9057 dns_zone_getxfracl(dns_zone_t *zone) {
9059 REQUIRE(DNS_ZONE_VALID(zone));
9061 return (zone->xfr_acl);
9065 dns_zone_clearupdateacl(dns_zone_t *zone) {
9067 REQUIRE(DNS_ZONE_VALID(zone));
9070 if (zone->update_acl != NULL)
9071 dns_acl_detach(&zone->update_acl);
9076 dns_zone_clearforwardacl(dns_zone_t *zone) {
9078 REQUIRE(DNS_ZONE_VALID(zone));
9081 if (zone->forward_acl != NULL)
9082 dns_acl_detach(&zone->forward_acl);
9087 dns_zone_clearnotifyacl(dns_zone_t *zone) {
9089 REQUIRE(DNS_ZONE_VALID(zone));
9092 if (zone->notify_acl != NULL)
9093 dns_acl_detach(&zone->notify_acl);
9098 dns_zone_clearqueryacl(dns_zone_t *zone) {
9100 REQUIRE(DNS_ZONE_VALID(zone));
9103 if (zone->query_acl != NULL)
9104 dns_acl_detach(&zone->query_acl);
9109 dns_zone_clearqueryonacl(dns_zone_t *zone) {
9111 REQUIRE(DNS_ZONE_VALID(zone));
9114 if (zone->queryon_acl != NULL)
9115 dns_acl_detach(&zone->queryon_acl);
9120 dns_zone_clearxfracl(dns_zone_t *zone) {
9122 REQUIRE(DNS_ZONE_VALID(zone));
9125 if (zone->xfr_acl != NULL)
9126 dns_acl_detach(&zone->xfr_acl);
9131 dns_zone_getupdatedisabled(dns_zone_t *zone) {
9132 REQUIRE(DNS_ZONE_VALID(zone));
9133 return (zone->update_disabled);
9138 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
9139 REQUIRE(DNS_ZONE_VALID(zone));
9140 zone->update_disabled = state;
9144 dns_zone_getzeronosoattl(dns_zone_t *zone) {
9145 REQUIRE(DNS_ZONE_VALID(zone));
9146 return (zone->zero_no_soa_ttl);
9151 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
9152 REQUIRE(DNS_ZONE_VALID(zone));
9153 zone->zero_no_soa_ttl = state;
9157 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
9159 REQUIRE(DNS_ZONE_VALID(zone));
9161 zone->check_names = severity;
9165 dns_zone_getchecknames(dns_zone_t *zone) {
9167 REQUIRE(DNS_ZONE_VALID(zone));
9169 return (zone->check_names);
9173 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
9175 REQUIRE(DNS_ZONE_VALID(zone));
9177 zone->journalsize = size;
9181 dns_zone_getjournalsize(dns_zone_t *zone) {
9183 REQUIRE(DNS_ZONE_VALID(zone));
9185 return (zone->journalsize);
9189 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
9190 isc_result_t result = ISC_R_FAILURE;
9191 isc_buffer_t buffer;
9193 REQUIRE(buf != NULL);
9194 REQUIRE(length > 1U);
9197 * Leave space for terminating '\0'.
9199 isc_buffer_init(&buffer, buf, length - 1);
9200 if (dns_name_dynamic(&zone->origin))
9201 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9202 if (result != ISC_R_SUCCESS &&
9203 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9204 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9206 if (isc_buffer_availablelength(&buffer) > 0)
9207 isc_buffer_putstr(&buffer, "/");
9208 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9210 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
9211 strcmp(zone->view->name, "_default") != 0 &&
9212 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
9213 isc_buffer_putstr(&buffer, "/");
9214 isc_buffer_putstr(&buffer, zone->view->name);
9217 buf[isc_buffer_usedlength(&buffer)] = '\0';
9221 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
9222 isc_result_t result = ISC_R_FAILURE;
9223 isc_buffer_t buffer;
9225 REQUIRE(buf != NULL);
9226 REQUIRE(length > 1U);
9229 * Leave space for terminating '\0'.
9231 isc_buffer_init(&buffer, buf, length - 1);
9232 if (dns_name_dynamic(&zone->origin))
9233 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9234 if (result != ISC_R_SUCCESS &&
9235 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9236 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9238 buf[isc_buffer_usedlength(&buffer)] = '\0';
9242 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
9243 isc_buffer_t buffer;
9245 REQUIRE(buf != NULL);
9246 REQUIRE(length > 1U);
9249 * Leave space for terminating '\0'.
9251 isc_buffer_init(&buffer, buf, length - 1);
9252 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9254 buf[isc_buffer_usedlength(&buffer)] = '\0';
9258 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
9259 isc_buffer_t buffer;
9261 REQUIRE(buf != NULL);
9262 REQUIRE(length > 1U);
9266 * Leave space for terminating '\0'.
9268 isc_buffer_init(&buffer, buf, length - 1);
9270 if (zone->view == NULL) {
9271 isc_buffer_putstr(&buffer, "_none");
9272 } else if (strlen(zone->view->name)
9273 < isc_buffer_availablelength(&buffer)) {
9274 isc_buffer_putstr(&buffer, zone->view->name);
9276 isc_buffer_putstr(&buffer, "_toolong");
9279 buf[isc_buffer_usedlength(&buffer)] = '\0';
9283 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
9284 REQUIRE(DNS_ZONE_VALID(zone));
9285 REQUIRE(buf != NULL);
9286 zone_namerd_tostr(zone, buf, length);
9290 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9294 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9298 vsnprintf(message, sizeof(message), fmt, ap);
9300 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
9301 level, "zone %s: %s", zone->strnamerd, message);
9305 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
9306 int level, const char *fmt, ...) {
9310 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9314 vsnprintf(message, sizeof(message), fmt, ap);
9316 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
9317 level, "zone %s: %s", zone->strnamerd, message);
9321 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9325 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9329 vsnprintf(message, sizeof(message), fmt, ap);
9331 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9332 level, "zone %s: %s", zone->strnamerd, message);
9336 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
9337 const char *fmt, ...)
9341 int level = ISC_LOG_DEBUG(debuglevel);
9343 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9347 vsnprintf(message, sizeof(message), fmt, ap);
9349 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9350 level, "%s: zone %s: %s", me, zone->strnamerd, message);
9354 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
9356 isc_result_t result;
9358 dns_rdataset_t *curr;
9361 result = dns_message_firstname(msg, section);
9362 while (result == ISC_R_SUCCESS) {
9364 dns_message_currentname(msg, section, &name);
9366 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
9367 curr = ISC_LIST_PREV(curr, link)) {
9368 if (curr->type == type)
9371 result = dns_message_nextname(msg, section);
9378 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
9379 REQUIRE(DNS_ZONE_VALID(zone));
9381 zone->maxxfrin = maxxfrin;
9385 dns_zone_getmaxxfrin(dns_zone_t *zone) {
9386 REQUIRE(DNS_ZONE_VALID(zone));
9388 return (zone->maxxfrin);
9392 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
9393 REQUIRE(DNS_ZONE_VALID(zone));
9394 zone->maxxfrout = maxxfrout;
9398 dns_zone_getmaxxfrout(dns_zone_t *zone) {
9399 REQUIRE(DNS_ZONE_VALID(zone));
9401 return (zone->maxxfrout);
9405 dns_zone_gettype(dns_zone_t *zone) {
9406 REQUIRE(DNS_ZONE_VALID(zone));
9408 return (zone->type);
9412 dns_zone_getorigin(dns_zone_t *zone) {
9413 REQUIRE(DNS_ZONE_VALID(zone));
9415 return (&zone->origin);
9419 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
9420 REQUIRE(DNS_ZONE_VALID(zone));
9423 if (zone->task != NULL)
9424 isc_task_detach(&zone->task);
9425 isc_task_attach(task, &zone->task);
9426 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9427 if (zone->db != NULL)
9428 dns_db_settask(zone->db, zone->task);
9429 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9434 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
9435 REQUIRE(DNS_ZONE_VALID(zone));
9436 isc_task_attach(zone->task, target);
9440 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
9441 REQUIRE(DNS_ZONE_VALID(zone));
9444 idlein = DNS_DEFAULT_IDLEIN;
9445 zone->idlein = idlein;
9449 dns_zone_getidlein(dns_zone_t *zone) {
9450 REQUIRE(DNS_ZONE_VALID(zone));
9452 return (zone->idlein);
9456 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
9457 REQUIRE(DNS_ZONE_VALID(zone));
9459 zone->idleout = idleout;
9463 dns_zone_getidleout(dns_zone_t *zone) {
9464 REQUIRE(DNS_ZONE_VALID(zone));
9466 return (zone->idleout);
9470 notify_done(isc_task_t *task, isc_event_t *event) {
9471 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9472 dns_notify_t *notify;
9473 isc_result_t result;
9474 dns_message_t *message = NULL;
9477 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9481 notify = event->ev_arg;
9482 REQUIRE(DNS_NOTIFY_VALID(notify));
9483 INSIST(task == notify->zone->task);
9485 isc_buffer_init(&buf, rcode, sizeof(rcode));
9486 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9488 result = revent->result;
9489 if (result == ISC_R_SUCCESS)
9490 result = dns_message_create(notify->zone->mctx,
9491 DNS_MESSAGE_INTENTPARSE, &message);
9492 if (result == ISC_R_SUCCESS)
9493 result = dns_request_getresponse(revent->request, message,
9494 DNS_MESSAGEPARSE_PRESERVEORDER);
9495 if (result == ISC_R_SUCCESS)
9496 result = dns_rcode_totext(message->rcode, &buf);
9497 if (result == ISC_R_SUCCESS)
9498 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9499 "notify response from %s: %.*s",
9500 addrbuf, (int)buf.used, rcode);
9502 notify_log(notify->zone, ISC_LOG_DEBUG(2),
9503 "notify to %s failed: %s", addrbuf,
9504 dns_result_totext(result));
9507 * Old bind's return formerr if they see a soa record. Retry w/o
9508 * the soa if we see a formerr and had sent a SOA.
9510 isc_event_free(&event);
9511 if (message != NULL && message->rcode == dns_rcode_formerr &&
9512 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
9513 notify->flags |= DNS_NOTIFY_NOSOA;
9514 dns_request_destroy(¬ify->request);
9515 result = notify_send_queue(notify);
9516 if (result != ISC_R_SUCCESS)
9517 notify_destroy(notify, ISC_FALSE);
9519 if (result == ISC_R_TIMEDOUT)
9520 notify_log(notify->zone, ISC_LOG_DEBUG(1),
9521 "notify to %s: retries exceeded", addrbuf);
9522 notify_destroy(notify, ISC_FALSE);
9524 if (message != NULL)
9525 dns_message_destroy(&message);
9529 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9530 isc_result_t result;
9532 REQUIRE(DNS_ZONE_VALID(zone));
9534 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9535 result = zone_replacedb(zone, db, dump);
9536 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9542 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9543 dns_dbversion_t *ver;
9544 isc_result_t result;
9545 unsigned int soacount = 0;
9546 unsigned int nscount = 0;
9549 * 'zone' and 'zonedb' locked by caller.
9551 REQUIRE(DNS_ZONE_VALID(zone));
9552 REQUIRE(LOCKED_ZONE(zone));
9554 result = zone_get_from_db(zone, db, &nscount, &soacount,
9555 NULL, NULL, NULL, NULL, NULL, NULL);
9556 if (result == ISC_R_SUCCESS) {
9557 if (soacount != 1) {
9558 dns_zone_log(zone, ISC_LOG_ERROR,
9559 "has %d SOA records", soacount);
9560 result = DNS_R_BADZONE;
9563 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
9564 result = DNS_R_BADZONE;
9566 if (result != ISC_R_SUCCESS)
9569 dns_zone_log(zone, ISC_LOG_ERROR,
9570 "retrieving SOA and NS records failed: %s",
9571 dns_result_totext(result));
9575 result = check_nsec3param(zone, db);
9576 if (result != ISC_R_SUCCESS)
9580 dns_db_currentversion(db, &ver);
9583 * The initial version of a slave zone is always dumped;
9584 * subsequent versions may be journaled instead if this
9585 * is enabled in the configuration.
9587 if (zone->db != NULL && zone->journal != NULL &&
9588 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
9589 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
9590 isc_uint32_t serial, oldserial;
9592 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
9594 result = dns_db_getsoaserial(db, ver, &serial);
9595 if (result != ISC_R_SUCCESS) {
9596 dns_zone_log(zone, ISC_LOG_ERROR,
9597 "ixfr-from-differences: unable to get "
9603 * This is checked in zone_postload() for master zones.
9605 result = zone_get_from_db(zone, zone->db, NULL, NULL,
9606 &oldserial, NULL, NULL, NULL, NULL,
9608 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9609 if (zone->type == dns_zone_slave &&
9610 !isc_serial_gt(serial, oldserial)) {
9611 isc_uint32_t serialmin, serialmax;
9612 serialmin = (oldserial + 1) & 0xffffffffU;
9613 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
9614 dns_zone_log(zone, ISC_LOG_ERROR,
9615 "ixfr-from-differences: failed: "
9616 "new serial (%u) out of range [%u - %u]",
9617 serial, serialmin, serialmax);
9618 result = ISC_R_RANGE;
9622 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
9624 if (result != ISC_R_SUCCESS)
9627 zone_needdump(zone, DNS_DUMP_DELAY);
9628 else if (zone->journalsize != -1) {
9629 result = dns_journal_compact(zone->mctx, zone->journal,
9630 serial, zone->journalsize);
9634 case ISC_R_NOTFOUND:
9635 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9636 "dns_journal_compact: %s",
9637 dns_result_totext(result));
9640 dns_zone_log(zone, ISC_LOG_ERROR,
9641 "dns_journal_compact failed: %s",
9642 dns_result_totext(result));
9647 if (dump && zone->masterfile != NULL) {
9648 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9649 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9650 "dumping new zone version");
9651 result = dns_db_dump2(db, ver, zone->masterfile,
9652 zone->masterformat);
9653 if (result != ISC_R_SUCCESS)
9657 * Update the time the zone was updated, so
9658 * dns_zone_load can avoid loading it when
9659 * the server is reloaded. If isc_time_now
9660 * fails for some reason, all that happens is
9661 * the timestamp is not updated.
9663 TIME_NOW(&zone->loadtime);
9666 if (dump && zone->journal != NULL) {
9668 * The in-memory database just changed, and
9669 * because 'dump' is set, it didn't change by
9670 * being loaded from disk. Also, we have not
9671 * journaled diffs for this change.
9672 * Therefore, the on-disk journal is missing
9673 * the deltas for this change. Since it can
9674 * no longer be used to bring the zone
9675 * up-to-date, it is useless and should be
9678 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9679 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9680 "removing journal file");
9681 if (remove(zone->journal) < 0 && errno != ENOENT) {
9682 char strbuf[ISC_STRERRORSIZE];
9683 isc__strerror(errno, strbuf, sizeof(strbuf));
9684 isc_log_write(dns_lctx,
9685 DNS_LOGCATEGORY_GENERAL,
9688 "unable to remove journal "
9690 zone->journal, strbuf);
9695 dns_db_closeversion(db, &ver, ISC_FALSE);
9697 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9698 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9699 "replacing zone database");
9701 if (zone->db != NULL)
9702 zone_detachdb(zone);
9703 zone_attachdb(zone, db);
9704 dns_db_settask(zone->db, zone->task);
9705 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
9706 return (ISC_R_SUCCESS);
9709 dns_db_closeversion(db, &ver, ISC_FALSE);
9713 /* The caller must hold the dblock as a writer. */
9715 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
9716 REQUIRE(zone->db == NULL && db != NULL);
9718 dns_db_attach(db, &zone->db);
9719 if (zone->acache != NULL) {
9720 isc_result_t result;
9721 result = dns_acache_setdb(zone->acache, db);
9722 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
9723 UNEXPECTED_ERROR(__FILE__, __LINE__,
9724 "dns_acache_setdb() failed: %s",
9725 isc_result_totext(result));
9730 /* The caller must hold the dblock as a writer. */
9732 zone_detachdb(dns_zone_t *zone) {
9733 REQUIRE(zone->db != NULL);
9735 if (zone->acache != NULL)
9736 (void)dns_acache_putdb(zone->acache, zone->db);
9737 dns_db_detach(&zone->db);
9741 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
9743 isc_boolean_t again = ISC_FALSE;
9744 unsigned int soacount;
9745 unsigned int nscount;
9746 isc_uint32_t serial, refresh, retry, expire, minimum;
9747 isc_result_t xfrresult = result;
9748 isc_boolean_t free_needed;
9750 REQUIRE(DNS_ZONE_VALID(zone));
9752 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9753 "zone transfer finished: %s", dns_result_totext(result));
9756 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
9757 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9758 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9763 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9765 case DNS_R_UPTODATE:
9766 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
9768 * Has the zone expired underneath us?
9770 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9771 if (zone->db == NULL) {
9772 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9777 * Update the zone structure's data from the actual
9782 INSIST(zone->db != NULL);
9783 result = zone_get_from_db(zone, zone->db, &nscount,
9784 &soacount, &serial, &refresh,
9785 &retry, &expire, &minimum, NULL);
9786 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9787 if (result == ISC_R_SUCCESS) {
9789 dns_zone_log(zone, ISC_LOG_ERROR,
9791 "has %d SOA record%s", soacount,
9792 (soacount != 0) ? "s" : "");
9794 dns_zone_log(zone, ISC_LOG_ERROR,
9796 "has no NS records");
9797 if (DNS_ZONE_FLAG(zone,
9798 DNS_ZONEFLG_HAVETIMERS)) {
9799 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9800 zone->retry = DNS_ZONE_DEFAULTRETRY;
9802 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9806 zone->refresh = RANGE(refresh, zone->minrefresh,
9808 zone->retry = RANGE(retry, zone->minretry,
9810 zone->expire = RANGE(expire,
9811 zone->refresh + zone->retry,
9813 zone->minimum = minimum;
9814 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9818 * Set our next update/expire times.
9820 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
9821 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
9822 zone->refreshtime = now;
9823 DNS_ZONE_TIME_ADD(&now, zone->expire,
9826 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
9827 &zone->refreshtime);
9828 DNS_ZONE_TIME_ADD(&now, zone->expire,
9831 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
9832 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
9833 if (zone->tsigkey != NULL) {
9834 char namebuf[DNS_NAME_FORMATSIZE];
9835 dns_name_format(&zone->tsigkey->name, namebuf,
9837 snprintf(buf, sizeof(buf), ": TSIG '%s'",
9841 dns_zone_log(zone, ISC_LOG_INFO,
9842 "transferred serial %u%s",
9847 * This is not necessary if we just performed a AXFR
9848 * however it is necessary for an IXFR / UPTODATE and
9849 * won't hurt with an AXFR.
9851 if (zone->masterfile != NULL || zone->journal != NULL) {
9852 result = ISC_R_FAILURE;
9853 if (zone->journal != NULL)
9854 result = isc_file_settime(zone->journal, &now);
9855 if (result != ISC_R_SUCCESS &&
9856 zone->masterfile != NULL)
9857 result = isc_file_settime(zone->masterfile,
9859 /* Someone removed the file from underneath us! */
9860 if (result == ISC_R_FILENOTFOUND &&
9861 zone->masterfile != NULL)
9862 zone_needdump(zone, DNS_DUMP_DELAY);
9863 else if (result != ISC_R_SUCCESS)
9864 dns_zone_log(zone, ISC_LOG_ERROR,
9865 "transfer: could not set file "
9866 "modification time of '%s': %s",
9868 dns_result_totext(result));
9871 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
9875 /* Force retry with AXFR. */
9876 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
9882 * Skip to next failed / untried master.
9886 } while (zone->curmaster < zone->masterscnt &&
9887 zone->mastersok[zone->curmaster]);
9890 if (zone->curmaster >= zone->masterscnt) {
9891 zone->curmaster = 0;
9892 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9893 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9894 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9895 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9896 while (zone->curmaster < zone->masterscnt &&
9897 zone->mastersok[zone->curmaster])
9901 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9903 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9906 inc_stats(zone, dns_zonestatscounter_xfrfail);
9909 zone_settimer(zone, &now);
9912 * If creating the transfer object failed, zone->xfr is NULL.
9913 * Otherwise, we are called as the done callback of a zone
9914 * transfer object that just entered its shutting-down
9915 * state. Since we are no longer responsible for shutting
9916 * it down, we can detach our reference.
9918 if (zone->xfr != NULL)
9919 dns_xfrin_detach(&zone->xfr);
9921 if (zone->tsigkey != NULL)
9922 dns_tsigkey_detach(&zone->tsigkey);
9925 * Handle any deferred journal compaction.
9927 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
9928 result = dns_journal_compact(zone->mctx, zone->journal,
9929 zone->compact_serial,
9934 case ISC_R_NOTFOUND:
9935 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9936 "dns_journal_compact: %s",
9937 dns_result_totext(result));
9940 dns_zone_log(zone, ISC_LOG_ERROR,
9941 "dns_journal_compact failed: %s",
9942 dns_result_totext(result));
9945 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9949 * This transfer finishing freed up a transfer quota slot.
9950 * Let any other zones waiting for quota have it.
9952 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9953 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
9954 zone->statelist = NULL;
9955 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
9956 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9959 * Retry with a different server if necessary.
9961 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9962 queue_soa_query(zone);
9964 INSIST(zone->irefs > 0);
9966 free_needed = exit_check(zone);
9973 zone_loaddone(void *arg, isc_result_t result) {
9974 static char me[] = "zone_loaddone";
9975 dns_load_t *load = arg;
9977 isc_result_t tresult;
9979 REQUIRE(DNS_LOAD_VALID(load));
9984 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
9985 if (tresult != ISC_R_SUCCESS &&
9986 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
9989 LOCK_ZONE(load->zone);
9990 (void)zone_postload(load->zone, load->db, load->loadtime, result);
9991 zonemgr_putio(&load->zone->readio);
9992 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
9994 * Leave the zone frozen if the reload fails.
9996 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
9997 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
9998 zone->update_disabled = ISC_FALSE;
9999 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
10000 UNLOCK_ZONE(load->zone);
10003 dns_db_detach(&load->db);
10004 if (load->zone->lctx != NULL)
10005 dns_loadctx_detach(&load->zone->lctx);
10006 dns_zone_idetach(&load->zone);
10007 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
10011 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
10012 REQUIRE(DNS_ZONE_VALID(zone));
10013 REQUIRE(table != NULL);
10014 REQUIRE(*table == NULL);
10017 if (zone->ssutable != NULL)
10018 dns_ssutable_attach(zone->ssutable, table);
10023 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
10024 REQUIRE(DNS_ZONE_VALID(zone));
10027 if (zone->ssutable != NULL)
10028 dns_ssutable_detach(&zone->ssutable);
10030 dns_ssutable_attach(table, &zone->ssutable);
10035 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
10036 REQUIRE(DNS_ZONE_VALID(zone));
10038 zone->sigvalidityinterval = interval;
10042 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
10043 REQUIRE(DNS_ZONE_VALID(zone));
10045 return (zone->sigvalidityinterval);
10049 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
10050 REQUIRE(DNS_ZONE_VALID(zone));
10052 zone->sigresigninginterval = interval;
10056 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
10057 REQUIRE(DNS_ZONE_VALID(zone));
10059 return (zone->sigresigninginterval);
10063 queue_xfrin(dns_zone_t *zone) {
10064 const char me[] = "queue_xfrin";
10065 isc_result_t result;
10066 dns_zonemgr_t *zmgr = zone->zmgr;
10070 INSIST(zone->statelist == NULL);
10072 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10073 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
10077 zone->statelist = &zmgr->waiting_for_xfrin;
10078 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10079 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10081 if (result == ISC_R_QUOTA) {
10082 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
10083 "zone transfer deferred due to quota");
10084 } else if (result != ISC_R_SUCCESS) {
10085 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
10086 "starting zone transfer: %s",
10087 isc_result_totext(result));
10092 * This event callback is called when a zone has received
10093 * any necessary zone transfer quota. This is the time
10094 * to go ahead and start the transfer.
10097 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
10098 isc_result_t result;
10099 dns_peer_t *peer = NULL;
10100 char master[ISC_SOCKADDR_FORMATSIZE];
10101 char source[ISC_SOCKADDR_FORMATSIZE];
10102 dns_rdatatype_t xfrtype;
10103 dns_zone_t *zone = event->ev_arg;
10104 isc_netaddr_t masterip;
10105 isc_sockaddr_t sourceaddr;
10106 isc_sockaddr_t masteraddr;
10108 const char *soa_before = "";
10112 INSIST(task == zone->task);
10114 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10115 result = ISC_R_CANCELED;
10121 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10122 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10123 &zone->sourceaddr, &now)) {
10124 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10125 dns_zone_log(zone, ISC_LOG_INFO,
10126 "got_transfer_quota: skipping zone transfer as "
10127 "master %s (source %s) is unreachable (cached)",
10129 result = ISC_R_CANCELED;
10133 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10134 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
10136 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10137 soa_before = "SOA before ";
10139 * Decide whether we should request IXFR or AXFR.
10141 if (zone->db == NULL) {
10142 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10143 "no database exists yet, requesting AXFR of "
10144 "initial version from %s", master);
10145 xfrtype = dns_rdatatype_axfr;
10146 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
10147 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
10148 "set, requesting %sAXFR from %s", soa_before,
10150 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10151 xfrtype = dns_rdatatype_soa;
10153 xfrtype = dns_rdatatype_axfr;
10154 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
10155 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10156 "forced reload, requesting AXFR of "
10157 "initial version from %s", master);
10158 xfrtype = dns_rdatatype_axfr;
10159 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
10160 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10161 "retrying with AXFR from %s due to "
10162 "previous IXFR failure", master);
10163 xfrtype = dns_rdatatype_axfr;
10165 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
10168 isc_boolean_t use_ixfr = ISC_TRUE;
10169 if (peer != NULL &&
10170 dns_peer_getrequestixfr(peer, &use_ixfr) ==
10172 ; /* Using peer setting */
10174 use_ixfr = zone->view->requestixfr;
10176 if (use_ixfr == ISC_FALSE) {
10177 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10178 "IXFR disabled, requesting %sAXFR from %s",
10179 soa_before, master);
10180 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10181 xfrtype = dns_rdatatype_soa;
10183 xfrtype = dns_rdatatype_axfr;
10185 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10186 "requesting IXFR from %s", master);
10187 xfrtype = dns_rdatatype_ixfr;
10192 * Determine if we should attempt to sign the request with TSIG.
10194 result = ISC_R_NOTFOUND;
10196 * First, look for a tsig key in the master statement, then
10197 * try for a server key.
10199 if ((zone->masterkeynames != NULL) &&
10200 (zone->masterkeynames[zone->curmaster] != NULL)) {
10201 dns_view_t *view = dns_zone_getview(zone);
10202 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10203 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
10205 if (zone->tsigkey == NULL)
10206 result = dns_view_getpeertsig(zone->view, &masterip,
10209 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10210 dns_zone_log(zone, ISC_LOG_ERROR,
10211 "could not get TSIG key for zone transfer: %s",
10212 isc_result_totext(result));
10216 masteraddr = zone->masteraddr;
10217 sourceaddr = zone->sourceaddr;
10219 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
10220 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
10221 zone->tsigkey, zone->mctx,
10222 zone->zmgr->timermgr, zone->zmgr->socketmgr,
10223 zone->task, zone_xfrdone, &zone->xfr);
10224 if (result == ISC_R_SUCCESS) {
10226 if (xfrtype == dns_rdatatype_axfr) {
10227 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10228 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
10230 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
10231 } else if (xfrtype == dns_rdatatype_ixfr) {
10232 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10233 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
10235 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
10241 * Any failure in this function is handled like a failed
10242 * zone transfer. This ensures that we get removed from
10243 * zmgr->xfrin_in_progress.
10245 if (result != ISC_R_SUCCESS)
10246 zone_xfrdone(zone, result);
10248 isc_event_free(&event);
10252 * Update forwarding support.
10256 forward_destroy(dns_forward_t *forward) {
10258 forward->magic = 0;
10259 if (forward->request != NULL)
10260 dns_request_destroy(&forward->request);
10261 if (forward->msgbuf != NULL)
10262 isc_buffer_free(&forward->msgbuf);
10263 if (forward->zone != NULL)
10264 dns_zone_idetach(&forward->zone);
10265 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
10268 static isc_result_t
10269 sendtomaster(dns_forward_t *forward) {
10270 isc_result_t result;
10271 isc_sockaddr_t src;
10273 LOCK_ZONE(forward->zone);
10274 if (forward->which >= forward->zone->masterscnt) {
10275 UNLOCK_ZONE(forward->zone);
10276 return (ISC_R_NOMORE);
10279 forward->addr = forward->zone->masters[forward->which];
10281 * Always use TCP regardless of whether the original update
10283 * XXX The timeout may but a bit small if we are far down a
10284 * transfer graph and the master has to try several masters.
10286 switch (isc_sockaddr_pf(&forward->addr)) {
10288 src = forward->zone->xfrsource4;
10291 src = forward->zone->xfrsource6;
10294 result = ISC_R_NOTIMPLEMENTED;
10297 result = dns_request_createraw(forward->zone->view->requestmgr,
10299 &src, &forward->addr,
10300 DNS_REQUESTOPT_TCP, 15 /* XXX */,
10301 forward->zone->task,
10302 forward_callback, forward,
10303 &forward->request);
10305 UNLOCK_ZONE(forward->zone);
10310 forward_callback(isc_task_t *task, isc_event_t *event) {
10311 const char me[] = "forward_callback";
10312 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10313 dns_message_t *msg = NULL;
10314 char master[ISC_SOCKADDR_FORMATSIZE];
10315 isc_result_t result;
10316 dns_forward_t *forward;
10321 forward = revent->ev_arg;
10322 INSIST(DNS_FORWARD_VALID(forward));
10323 zone = forward->zone;
10324 INSIST(DNS_ZONE_VALID(zone));
10328 isc_sockaddr_format(&forward->addr, master, sizeof(master));
10330 if (revent->result != ISC_R_SUCCESS) {
10331 dns_zone_log(zone, ISC_LOG_INFO,
10332 "could not forward dynamic update to %s: %s",
10333 master, dns_result_totext(revent->result));
10337 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10338 if (result != ISC_R_SUCCESS)
10341 result = dns_request_getresponse(revent->request, msg,
10342 DNS_MESSAGEPARSE_PRESERVEORDER |
10343 DNS_MESSAGEPARSE_CLONEBUFFER);
10344 if (result != ISC_R_SUCCESS)
10347 switch (msg->rcode) {
10349 * Pass these rcodes back to client.
10351 case dns_rcode_noerror:
10352 case dns_rcode_yxdomain:
10353 case dns_rcode_yxrrset:
10354 case dns_rcode_nxrrset:
10355 case dns_rcode_refused:
10356 case dns_rcode_nxdomain:
10359 /* These should not occur if the masters/zone are valid. */
10360 case dns_rcode_notzone:
10361 case dns_rcode_notauth: {
10365 isc_buffer_init(&rb, rcode, sizeof(rcode));
10366 (void)dns_rcode_totext(msg->rcode, &rb);
10367 dns_zone_log(zone, ISC_LOG_WARNING,
10368 "forwarding dynamic update: "
10369 "unexpected response: master %s returned: %.*s",
10370 master, (int)rb.used, rcode);
10374 /* Try another server for these rcodes. */
10375 case dns_rcode_formerr:
10376 case dns_rcode_servfail:
10377 case dns_rcode_notimp:
10378 case dns_rcode_badvers:
10383 /* call callback */
10384 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
10386 dns_request_destroy(&forward->request);
10387 forward_destroy(forward);
10388 isc_event_free(&event);
10393 dns_message_destroy(&msg);
10394 isc_event_free(&event);
10396 dns_request_destroy(&forward->request);
10397 result = sendtomaster(forward);
10398 if (result != ISC_R_SUCCESS) {
10399 /* call callback */
10400 dns_zone_log(zone, ISC_LOG_DEBUG(3),
10401 "exhausted dynamic update forwarder list");
10402 (forward->callback)(forward->callback_arg, result, NULL);
10403 forward_destroy(forward);
10408 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
10409 dns_updatecallback_t callback, void *callback_arg)
10411 dns_forward_t *forward;
10412 isc_result_t result;
10415 REQUIRE(DNS_ZONE_VALID(zone));
10416 REQUIRE(msg != NULL);
10417 REQUIRE(callback != NULL);
10419 forward = isc_mem_get(zone->mctx, sizeof(*forward));
10420 if (forward == NULL)
10421 return (ISC_R_NOMEMORY);
10423 forward->request = NULL;
10424 forward->zone = NULL;
10425 forward->msgbuf = NULL;
10426 forward->which = 0;
10428 forward->callback = callback;
10429 forward->callback_arg = callback_arg;
10430 forward->magic = FORWARD_MAGIC;
10432 mr = dns_message_getrawmessage(msg);
10434 result = ISC_R_UNEXPECTEDEND;
10438 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
10439 if (result != ISC_R_SUCCESS)
10441 result = isc_buffer_copyregion(forward->msgbuf, mr);
10442 if (result != ISC_R_SUCCESS)
10445 isc_mem_attach(zone->mctx, &forward->mctx);
10446 dns_zone_iattach(zone, &forward->zone);
10447 result = sendtomaster(forward);
10450 if (result != ISC_R_SUCCESS) {
10451 forward_destroy(forward);
10457 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
10458 REQUIRE(DNS_ZONE_VALID(zone));
10459 REQUIRE(next != NULL && *next == NULL);
10461 *next = ISC_LIST_NEXT(zone, link);
10463 return (ISC_R_NOMORE);
10465 return (ISC_R_SUCCESS);
10469 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
10470 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10471 REQUIRE(first != NULL && *first == NULL);
10473 *first = ISC_LIST_HEAD(zmgr->zones);
10474 if (*first == NULL)
10475 return (ISC_R_NOMORE);
10477 return (ISC_R_SUCCESS);
10481 * Size of the zone task table. For best results, this should be a
10482 * prime number, approximately 1% of the maximum number of authoritative
10483 * zones expected to be served by this server.
10485 #define DEFAULT_ZONE_TASKS 101
10487 calculate_zone_tasks(void) {
10488 int ntasks = DEFAULT_ZONE_TASKS;
10491 char *env = getenv("BIND9_ZONE_TASKS_HINT");
10493 ntasks = atoi(env);
10495 if (ntasks < DEFAULT_ZONE_TASKS)
10496 ntasks = DEFAULT_ZONE_TASKS;
10507 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
10508 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
10509 dns_zonemgr_t **zmgrp)
10511 dns_zonemgr_t *zmgr;
10512 isc_result_t result;
10513 isc_interval_t interval;
10514 int zone_tasks = calculate_zone_tasks();
10516 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
10518 return (ISC_R_NOMEMORY);
10521 isc_mem_attach(mctx, &zmgr->mctx);
10522 zmgr->taskmgr = taskmgr;
10523 zmgr->timermgr = timermgr;
10524 zmgr->socketmgr = socketmgr;
10525 zmgr->zonetasks = NULL;
10528 ISC_LIST_INIT(zmgr->zones);
10529 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
10530 ISC_LIST_INIT(zmgr->xfrin_in_progress);
10531 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
10532 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
10533 if (result != ISC_R_SUCCESS)
10536 zmgr->transfersin = 10;
10537 zmgr->transfersperns = 2;
10539 /* Create the zone task pool. */
10540 result = isc_taskpool_create(taskmgr, mctx, zone_tasks, 2,
10542 if (result != ISC_R_SUCCESS)
10545 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
10546 ISC_LOG_NOTICE, "Using %d tasks for zone loading", zone_tasks);
10548 /* Create a single task for queueing of SOA queries. */
10549 result = isc_task_create(taskmgr, 1, &zmgr->task);
10550 if (result != ISC_R_SUCCESS)
10551 goto free_taskpool;
10552 isc_task_setname(zmgr->task, "zmgr", zmgr);
10553 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
10555 if (result != ISC_R_SUCCESS)
10557 /* default to 20 refresh queries / notifies per second. */
10558 isc_interval_set(&interval, 0, 1000000000/2);
10559 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
10560 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10561 isc_ratelimiter_setpertic(zmgr->rl, 10);
10564 zmgr->ioactive = 0;
10565 ISC_LIST_INIT(zmgr->high);
10566 ISC_LIST_INIT(zmgr->low);
10568 result = isc_mutex_init(&zmgr->iolock);
10569 if (result != ISC_R_SUCCESS)
10572 zmgr->magic = ZONEMGR_MAGIC;
10575 return (ISC_R_SUCCESS);
10579 DESTROYLOCK(&zmgr->iolock);
10582 isc_ratelimiter_detach(&zmgr->rl);
10584 isc_task_detach(&zmgr->task);
10586 isc_taskpool_destroy(&zmgr->zonetasks);
10588 isc_rwlock_destroy(&zmgr->rwlock);
10590 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10591 isc_mem_detach(&mctx);
10596 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10597 isc_result_t result;
10599 REQUIRE(DNS_ZONE_VALID(zone));
10600 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10602 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10604 REQUIRE(zone->task == NULL);
10605 REQUIRE(zone->timer == NULL);
10606 REQUIRE(zone->zmgr == NULL);
10608 isc_taskpool_gettask(zmgr->zonetasks,
10609 dns_name_hash(dns_zone_getorigin(zone),
10614 * Set the task name. The tag will arbitrarily point to one
10615 * of the zones sharing the task (in practice, the one
10616 * to be managed last).
10618 isc_task_setname(zone->task, "zone", zone);
10620 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
10622 zone->task, zone_timer, zone,
10625 if (result != ISC_R_SUCCESS)
10629 * The timer "holds" a iref.
10632 INSIST(zone->irefs != 0);
10634 ISC_LIST_APPEND(zmgr->zones, zone, link);
10641 isc_task_detach(&zone->task);
10645 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10650 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10651 isc_boolean_t free_now = ISC_FALSE;
10653 REQUIRE(DNS_ZONE_VALID(zone));
10654 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10655 REQUIRE(zone->zmgr == zmgr);
10657 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10660 ISC_LIST_UNLINK(zmgr->zones, zone, link);
10663 if (zmgr->refs == 0)
10664 free_now = ISC_TRUE;
10667 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10670 zonemgr_free(zmgr);
10671 ENSURE(zone->zmgr == NULL);
10675 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
10676 REQUIRE(DNS_ZONEMGR_VALID(source));
10677 REQUIRE(target != NULL && *target == NULL);
10679 RWLOCK(&source->rwlock, isc_rwlocktype_write);
10680 REQUIRE(source->refs > 0);
10682 INSIST(source->refs > 0);
10683 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
10688 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
10689 dns_zonemgr_t *zmgr;
10690 isc_boolean_t free_now = ISC_FALSE;
10692 REQUIRE(zmgrp != NULL);
10694 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10696 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10698 if (zmgr->refs == 0)
10699 free_now = ISC_TRUE;
10700 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10703 zonemgr_free(zmgr);
10707 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
10710 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10712 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10713 for (p = ISC_LIST_HEAD(zmgr->zones);
10715 p = ISC_LIST_NEXT(p, link))
10717 dns_zone_maintenance(p);
10719 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10722 * Recent configuration changes may have increased the
10723 * amount of available transfers quota. Make sure any
10724 * transfers currently blocked on quota get started if
10727 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10728 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10729 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10730 return (ISC_R_SUCCESS);
10734 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
10736 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10738 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10739 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10740 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10744 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
10745 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10747 isc_ratelimiter_shutdown(zmgr->rl);
10749 if (zmgr->task != NULL)
10750 isc_task_destroy(&zmgr->task);
10751 if (zmgr->zonetasks != NULL)
10752 isc_taskpool_destroy(&zmgr->zonetasks);
10756 zonemgr_free(dns_zonemgr_t *zmgr) {
10759 INSIST(zmgr->refs == 0);
10760 INSIST(ISC_LIST_EMPTY(zmgr->zones));
10764 DESTROYLOCK(&zmgr->iolock);
10765 isc_ratelimiter_detach(&zmgr->rl);
10767 isc_rwlock_destroy(&zmgr->rwlock);
10769 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10770 isc_mem_detach(&mctx);
10774 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10775 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10777 zmgr->transfersin = value;
10781 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
10782 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10784 return (zmgr->transfersin);
10788 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10789 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10791 zmgr->transfersperns = value;
10795 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
10796 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10798 return (zmgr->transfersperns);
10802 * Try to start a new incoming zone transfer to fill a quota
10803 * slot that was just vacated.
10806 * The zone manager is locked by the caller.
10809 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
10813 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
10817 isc_result_t result;
10818 next = ISC_LIST_NEXT(zone, statelink);
10819 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10820 if (result == ISC_R_SUCCESS) {
10824 * We successfully filled the slot. We're done.
10827 } else if (result == ISC_R_QUOTA) {
10829 * Not enough quota. This is probably the per-server
10830 * quota, because we usually get called when a unit of
10831 * global quota has just been freed. Try the next
10832 * zone, it may succeed if it uses another master.
10836 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10837 "starting zone transfer: %s",
10838 isc_result_totext(result));
10845 * Try to start an incoming zone transfer for 'zone', quota permitting.
10848 * The zone manager is locked by the caller.
10851 * ISC_R_SUCCESS There was enough quota and we attempted to
10852 * start a transfer. zone_xfrdone() has been or will
10854 * ISC_R_QUOTA Not enough quota.
10857 static isc_result_t
10858 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10859 dns_peer_t *peer = NULL;
10860 isc_netaddr_t masterip;
10861 isc_uint32_t nxfrsin, nxfrsperns;
10863 isc_uint32_t maxtransfersin, maxtransfersperns;
10867 * Find any configured information about the server we'd
10868 * like to transfer this zone from.
10870 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10871 (void)dns_peerlist_peerbyaddr(zone->view->peers,
10875 * Determine the total maximum number of simultaneous
10876 * transfers allowed, and the maximum for this specific
10879 maxtransfersin = zmgr->transfersin;
10880 maxtransfersperns = zmgr->transfersperns;
10882 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
10885 * Count the total number of transfers that are in progress,
10886 * and the number of transfers in progress from this master.
10887 * We linearly scan a list of all transfers; if this turns
10888 * out to be too slow, we could hash on the master address.
10890 nxfrsin = nxfrsperns = 0;
10891 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
10893 x = ISC_LIST_NEXT(x, statelink))
10896 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
10898 if (isc_netaddr_equal(&xip, &masterip))
10902 /* Enforce quota. */
10903 if (nxfrsin >= maxtransfersin)
10904 return (ISC_R_QUOTA);
10906 if (nxfrsperns >= maxtransfersperns)
10907 return (ISC_R_QUOTA);
10910 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
10911 * list and send it an event to let it start the actual transfer in the
10912 * context of its own task.
10914 e = isc_event_allocate(zmgr->mctx, zmgr,
10915 DNS_EVENT_ZONESTARTXFRIN,
10916 got_transfer_quota, zone,
10917 sizeof(isc_event_t));
10919 return (ISC_R_NOMEMORY);
10922 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
10923 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
10924 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
10925 zone->statelist = &zmgr->xfrin_in_progress;
10926 isc_task_send(zone->task, &e);
10927 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
10930 return (ISC_R_SUCCESS);
10934 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
10936 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10937 REQUIRE(iolimit > 0);
10939 zmgr->iolimit = iolimit;
10943 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
10945 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10947 return (zmgr->iolimit);
10951 * Get permission to request a file handle from the OS.
10952 * An event will be sent to action when one is available.
10953 * There are two queues available (high and low), the high
10954 * queue will be serviced before the low one.
10956 * zonemgr_putio() must be called after the event is delivered to
10960 static isc_result_t
10961 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
10962 isc_task_t *task, isc_taskaction_t action, void *arg,
10966 isc_boolean_t queue;
10968 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10969 REQUIRE(iop != NULL && *iop == NULL);
10971 io = isc_mem_get(zmgr->mctx, sizeof(*io));
10973 return (ISC_R_NOMEMORY);
10974 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
10975 action, arg, sizeof(*io->event));
10976 if (io->event == NULL) {
10977 isc_mem_put(zmgr->mctx, io, sizeof(*io));
10978 return (ISC_R_NOMEMORY);
10983 isc_task_attach(task, &io->task);
10984 ISC_LINK_INIT(io, link);
10985 io->magic = IO_MAGIC;
10987 LOCK(&zmgr->iolock);
10989 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
10992 ISC_LIST_APPEND(zmgr->high, io, link);
10994 ISC_LIST_APPEND(zmgr->low, io, link);
10996 UNLOCK(&zmgr->iolock);
11000 isc_task_send(io->task, &io->event);
11002 return (ISC_R_SUCCESS);
11006 zonemgr_putio(dns_io_t **iop) {
11009 dns_zonemgr_t *zmgr;
11011 REQUIRE(iop != NULL);
11013 REQUIRE(DNS_IO_VALID(io));
11017 INSIST(!ISC_LINK_LINKED(io, link));
11018 INSIST(io->event == NULL);
11021 isc_task_detach(&io->task);
11023 isc_mem_put(zmgr->mctx, io, sizeof(*io));
11025 LOCK(&zmgr->iolock);
11026 INSIST(zmgr->ioactive > 0);
11028 next = HEAD(zmgr->high);
11030 next = HEAD(zmgr->low);
11031 if (next != NULL) {
11033 ISC_LIST_UNLINK(zmgr->high, next, link);
11035 ISC_LIST_UNLINK(zmgr->low, next, link);
11036 INSIST(next->event != NULL);
11038 UNLOCK(&zmgr->iolock);
11040 isc_task_send(next->task, &next->event);
11044 zonemgr_cancelio(dns_io_t *io) {
11045 isc_boolean_t send_event = ISC_FALSE;
11047 REQUIRE(DNS_IO_VALID(io));
11050 * If we are queued to be run then dequeue.
11052 LOCK(&io->zmgr->iolock);
11053 if (ISC_LINK_LINKED(io, link)) {
11055 ISC_LIST_UNLINK(io->zmgr->high, io, link);
11057 ISC_LIST_UNLINK(io->zmgr->low, io, link);
11059 send_event = ISC_TRUE;
11060 INSIST(io->event != NULL);
11062 UNLOCK(&io->zmgr->iolock);
11064 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
11065 isc_task_send(io->task, &io->event);
11070 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
11073 isc_result_t result;
11075 buflen = strlen(path) + strlen(templat) + 2;
11077 buf = isc_mem_get(zone->mctx, buflen);
11081 result = isc_file_template(path, templat, buf, buflen);
11082 if (result != ISC_R_SUCCESS)
11085 result = isc_file_renameunique(path, buf);
11086 if (result != ISC_R_SUCCESS)
11089 dns_zone_log(zone, ISC_LOG_WARNING, "saved '%s' as '%s'",
11093 isc_mem_put(zone->mctx, buf, buflen);
11097 /* Hook for ondestroy notification from a database. */
11100 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
11101 dns_db_t *db = event->sender;
11104 isc_event_free(&event);
11106 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11107 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11108 "database (%p) destroyed", (void*) db);
11113 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
11114 isc_interval_t interval;
11115 isc_uint32_t s, ns;
11116 isc_uint32_t pertic;
11117 isc_result_t result;
11119 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11128 } else if (value <= 10) {
11130 ns = 1000000000 / value;
11134 ns = (1000000000 / value) * 10;
11138 isc_interval_set(&interval, s, ns);
11139 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
11140 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11141 isc_ratelimiter_setpertic(zmgr->rl, pertic);
11143 zmgr->serialqueryrate = value;
11147 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
11148 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11150 return (zmgr->serialqueryrate);
11153 static isc_boolean_t
11154 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11155 isc_sockaddr_t *local, isc_time_t *now)
11158 isc_rwlocktype_t locktype;
11159 isc_result_t result;
11160 isc_uint32_t seconds = isc_time_seconds(now);
11162 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11164 locktype = isc_rwlocktype_read;
11165 RWLOCK(&zmgr->rwlock, locktype);
11166 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11167 if (zmgr->unreachable[i].expire >= seconds &&
11168 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11169 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
11170 result = isc_rwlock_tryupgrade(&zmgr->rwlock);
11171 if (result == ISC_R_SUCCESS) {
11172 locktype = isc_rwlocktype_write;
11173 zmgr->unreachable[i].last = seconds;
11178 RWUNLOCK(&zmgr->rwlock, locktype);
11179 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
11183 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11184 isc_sockaddr_t *local, isc_time_t *now)
11186 isc_uint32_t seconds = isc_time_seconds(now);
11187 isc_uint32_t last = seconds;
11188 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
11190 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11192 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
11193 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11194 /* Existing entry? */
11195 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11196 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
11199 if (zmgr->unreachable[i].expire < seconds)
11201 /* Least recently used slot? */
11202 if (zmgr->unreachable[i].last < last) {
11203 last = zmgr->unreachable[i].last;
11207 if (i < UNREACH_CHACHE_SIZE) {
11209 * Found a existing entry. Update the expire timer and
11210 * last usage timestamps.
11212 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
11213 zmgr->unreachable[i].last = seconds;
11214 } else if (slot != UNREACH_CHACHE_SIZE) {
11216 * Found a empty slot. Add a new entry to the cache.
11218 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
11219 zmgr->unreachable[slot].last = seconds;
11220 zmgr->unreachable[slot].remote = *remote;
11221 zmgr->unreachable[slot].local = *local;
11224 * Replace the least recently used entry in the cache.
11226 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
11227 zmgr->unreachable[oldest].last = seconds;
11228 zmgr->unreachable[oldest].remote = *remote;
11229 zmgr->unreachable[oldest].local = *local;
11231 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
11235 dns_zone_forcereload(dns_zone_t *zone) {
11236 REQUIRE(DNS_ZONE_VALID(zone));
11238 if (zone->type == dns_zone_master)
11242 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
11244 dns_zone_refresh(zone);
11248 dns_zone_isforced(dns_zone_t *zone) {
11249 REQUIRE(DNS_ZONE_VALID(zone));
11251 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
11255 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
11257 * This function is obsoleted.
11261 return (ISC_R_NOTIMPLEMENTED);
11265 dns_zone_getstatscounters(dns_zone_t *zone) {
11267 * This function is obsoleted.
11274 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
11275 REQUIRE(DNS_ZONE_VALID(zone));
11276 REQUIRE(zone->stats == NULL);
11279 zone->stats = NULL;
11280 isc_stats_attach(stats, &zone->stats);
11285 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
11286 REQUIRE(DNS_ZONE_VALID(zone));
11289 if (zone->requeststats_on && stats == NULL)
11290 zone->requeststats_on = ISC_FALSE;
11291 else if (!zone->requeststats_on && stats != NULL) {
11292 if (zone->requeststats == NULL) {
11293 isc_stats_attach(stats, &zone->requeststats);
11294 zone->requeststats_on = ISC_TRUE;
11303 dns_zone_getrequeststats(dns_zone_t *zone) {
11305 * We don't lock zone for efficiency reason. This is not catastrophic
11306 * because requeststats must always be valid when requeststats_on is
11308 * Some counters may be incremented while requeststats_on is becoming
11309 * false, or some cannot be incremented just after the statistics are
11310 * installed, but it shouldn't matter much in practice.
11312 if (zone->requeststats_on)
11313 return (zone->requeststats);
11319 dns_zone_dialup(dns_zone_t *zone) {
11321 REQUIRE(DNS_ZONE_VALID(zone));
11323 zone_debuglog(zone, "dns_zone_dialup", 3,
11324 "notify = %d, refresh = %d",
11325 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
11326 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
11328 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
11329 dns_zone_notify(zone);
11330 if (zone->type != dns_zone_master &&
11331 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11332 dns_zone_refresh(zone);
11336 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
11337 REQUIRE(DNS_ZONE_VALID(zone));
11340 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
11341 DNS_ZONEFLG_DIALREFRESH |
11342 DNS_ZONEFLG_NOREFRESH);
11344 case dns_dialuptype_no:
11346 case dns_dialuptype_yes:
11347 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
11348 DNS_ZONEFLG_DIALREFRESH |
11349 DNS_ZONEFLG_NOREFRESH));
11351 case dns_dialuptype_notify:
11352 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11354 case dns_dialuptype_notifypassive:
11355 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11356 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11358 case dns_dialuptype_refresh:
11359 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
11360 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11362 case dns_dialuptype_passive:
11363 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11372 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
11373 isc_result_t result = ISC_R_SUCCESS;
11375 REQUIRE(DNS_ZONE_VALID(zone));
11378 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
11385 dns_zone_getkeydirectory(dns_zone_t *zone) {
11386 REQUIRE(DNS_ZONE_VALID(zone));
11388 return (zone->keydirectory);
11392 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
11394 unsigned int count = 0;
11396 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11398 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11400 case DNS_ZONESTATE_XFERRUNNING:
11401 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
11403 zone = ISC_LIST_NEXT(zone, statelink))
11406 case DNS_ZONESTATE_XFERDEFERRED:
11407 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
11409 zone = ISC_LIST_NEXT(zone, statelink))
11412 case DNS_ZONESTATE_SOAQUERY:
11413 for (zone = ISC_LIST_HEAD(zmgr->zones);
11415 zone = ISC_LIST_NEXT(zone, link))
11416 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
11419 case DNS_ZONESTATE_ANY:
11420 for (zone = ISC_LIST_HEAD(zmgr->zones);
11422 zone = ISC_LIST_NEXT(zone, link)) {
11423 dns_view_t *view = zone->view;
11424 if (view != NULL && strcmp(view->name, "_bind") == 0)
11433 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11439 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
11440 isc_boolean_t ok = ISC_TRUE;
11441 isc_boolean_t fail = ISC_FALSE;
11442 char namebuf[DNS_NAME_FORMATSIZE];
11443 char namebuf2[DNS_NAME_FORMATSIZE];
11444 char typebuf[DNS_RDATATYPE_FORMATSIZE];
11445 int level = ISC_LOG_WARNING;
11448 REQUIRE(DNS_ZONE_VALID(zone));
11450 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
11451 return (ISC_R_SUCCESS);
11453 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
11454 level = ISC_LOG_ERROR;
11458 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
11460 dns_name_format(name, namebuf, sizeof(namebuf));
11461 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11462 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
11463 dns_result_totext(DNS_R_BADOWNERNAME));
11465 return (DNS_R_BADOWNERNAME);
11468 dns_name_init(&bad, NULL);
11469 ok = dns_rdata_checknames(rdata, name, &bad);
11471 dns_name_format(name, namebuf, sizeof(namebuf));
11472 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
11473 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11474 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
11475 namebuf2, dns_result_totext(DNS_R_BADNAME));
11477 return (DNS_R_BADNAME);
11480 return (ISC_R_SUCCESS);
11484 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
11485 REQUIRE(DNS_ZONE_VALID(zone));
11486 zone->checkmx = checkmx;
11490 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
11491 REQUIRE(DNS_ZONE_VALID(zone));
11492 zone->checksrv = checksrv;
11496 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
11497 REQUIRE(DNS_ZONE_VALID(zone));
11498 zone->checkns = checkns;
11502 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
11503 REQUIRE(DNS_ZONE_VALID(zone));
11506 zone->isself = isself;
11507 zone->isselfarg = arg;
11512 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
11513 REQUIRE(DNS_ZONE_VALID(zone));
11516 zone->notifydelay = delay;
11521 dns_zone_getnotifydelay(dns_zone_t *zone) {
11522 REQUIRE(DNS_ZONE_VALID(zone));
11524 return (zone->notifydelay);
11528 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
11529 isc_uint16_t keyid, isc_boolean_t delete)
11531 isc_result_t result;
11532 REQUIRE(DNS_ZONE_VALID(zone));
11534 dns_zone_log(zone, ISC_LOG_NOTICE,
11535 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
11538 result = zone_signwithkey(zone, algorithm, keyid, delete);
11544 static const char *hex = "0123456789ABCDEF";
11547 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
11548 isc_result_t result;
11549 char salt[255*2+1];
11552 REQUIRE(DNS_ZONE_VALID(zone));
11554 if (nsec3param->salt_length != 0) {
11555 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
11556 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
11557 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
11558 salt[j++] = hex[nsec3param->salt[i] & 0xf];
11563 dns_zone_log(zone, ISC_LOG_NOTICE,
11564 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
11565 nsec3param->hash, nsec3param->iterations,
11568 result = zone_addnsec3chain(zone, nsec3param);
11575 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
11576 REQUIRE(DNS_ZONE_VALID(zone));
11580 zone->nodes = nodes;
11584 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
11585 REQUIRE(DNS_ZONE_VALID(zone));
11588 * We treat signatures as a signed value so explicitly
11589 * limit its range here.
11591 if (signatures > ISC_INT32_MAX)
11592 signatures = ISC_INT32_MAX;
11593 else if (signatures == 0)
11595 zone->signatures = signatures;
11599 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
11600 REQUIRE(DNS_ZONE_VALID(zone));
11601 zone->privatetype = type;
11605 dns_zone_getprivatetype(dns_zone_t *zone) {
11606 REQUIRE(DNS_ZONE_VALID(zone));
11607 return (zone->privatetype);
11610 static isc_result_t
11611 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
11612 isc_boolean_t delete)
11614 dns_signing_t *signing;
11615 dns_signing_t *current;
11616 isc_result_t result = ISC_R_SUCCESS;
11619 signing = isc_mem_get(zone->mctx, sizeof *signing);
11620 if (signing == NULL)
11621 return (ISC_R_NOMEMORY);
11623 signing->magic = 0;
11624 signing->db = NULL;
11625 signing->dbiterator = NULL;
11626 signing->algorithm = algorithm;
11627 signing->keyid = keyid;
11628 signing->delete = delete;
11629 signing->done = ISC_FALSE;
11633 for (current = ISC_LIST_HEAD(zone->signing);
11635 current = ISC_LIST_NEXT(current, link)) {
11636 if (current->db == zone->db &&
11637 current->algorithm == signing->algorithm &&
11638 current->keyid == signing->keyid) {
11639 if (current->delete != signing->delete)
11640 current->done = ISC_TRUE;
11646 if (zone->db != NULL) {
11647 dns_db_attach(zone->db, &signing->db);
11648 result = dns_db_createiterator(signing->db, 0,
11649 &signing->dbiterator);
11651 if (result == ISC_R_SUCCESS)
11652 result = dns_dbiterator_first(signing->dbiterator);
11653 if (result == ISC_R_SUCCESS) {
11654 dns_dbiterator_pause(signing->dbiterator);
11655 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
11657 if (isc_time_isepoch(&zone->signingtime)) {
11658 zone->signingtime = now;
11659 if (zone->task != NULL)
11660 zone_settimer(zone, &now);
11664 result = ISC_R_NOTFOUND;
11667 if (signing != NULL) {
11668 if (signing->db != NULL)
11669 dns_db_detach(&signing->db);
11670 if (signing->dbiterator != NULL)
11671 dns_dbiterator_destroy(&signing->dbiterator);
11672 isc_mem_put(zone->mctx, signing, sizeof *signing);