2 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: zone.c,v 1.483.36.6 2009/03/26 22:57:07 marka Exp $ */
26 #include <isc/mutex.h>
27 #include <isc/print.h>
28 #include <isc/random.h>
29 #include <isc/ratelimiter.h>
30 #include <isc/refcount.h>
31 #include <isc/rwlock.h>
32 #include <isc/serial.h>
33 #include <isc/strerror.h>
34 #include <isc/stats.h>
35 #include <isc/stdtime.h>
36 #include <isc/string.h>
37 #include <isc/taskpool.h>
38 #include <isc/timer.h>
41 #include <dns/acache.h>
44 #include <dns/callbacks.h>
46 #include <dns/dbiterator.h>
47 #include <dns/dnssec.h>
48 #include <dns/events.h>
49 #include <dns/journal.h>
50 #include <dns/keyvalues.h>
52 #include <dns/master.h>
53 #include <dns/masterdump.h>
54 #include <dns/message.h>
57 #include <dns/nsec3.h>
59 #include <dns/rcode.h>
60 #include <dns/rdataclass.h>
61 #include <dns/rdatalist.h>
62 #include <dns/rdataset.h>
63 #include <dns/rdatasetiter.h>
64 #include <dns/rdatastruct.h>
65 #include <dns/rdatatype.h>
66 #include <dns/request.h>
67 #include <dns/resolver.h>
68 #include <dns/result.h>
71 #include <dns/stats.h>
73 #include <dns/xfrin.h>
78 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
79 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
81 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
82 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
84 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
85 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
87 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
88 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
90 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
91 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
93 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
94 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
96 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
97 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
100 * Ensure 'a' is at least 'min' but not more than 'max'.
102 #define RANGE(a, min, max) \
103 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
105 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
110 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
111 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
112 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
114 #ifndef DNS_MAX_EXPIRE
115 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
118 #ifndef DNS_DUMP_DELAY
119 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
122 typedef struct dns_notify dns_notify_t;
123 typedef struct dns_stub dns_stub_t;
124 typedef struct dns_load dns_load_t;
125 typedef struct dns_forward dns_forward_t;
126 typedef struct dns_io dns_io_t;
127 typedef ISC_LIST(dns_io_t) dns_iolist_t;
128 typedef struct dns_signing dns_signing_t;
129 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
130 typedef struct dns_nsec3chain dns_nsec3chain_t;
131 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
133 #define DNS_ZONE_CHECKLOCK
134 #ifdef DNS_ZONE_CHECKLOCK
135 #define LOCK_ZONE(z) \
136 do { LOCK(&(z)->lock); \
137 INSIST((z)->locked == ISC_FALSE); \
138 (z)->locked = ISC_TRUE; \
140 #define UNLOCK_ZONE(z) \
141 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
142 #define LOCKED_ZONE(z) ((z)->locked)
144 #define LOCK_ZONE(z) LOCK(&(z)->lock)
145 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
146 #define LOCKED_ZONE(z) ISC_TRUE
149 #ifdef ISC_RWLOCK_USEATOMIC
150 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
151 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
152 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
153 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
155 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
156 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
157 #define ZONEDB_LOCK(l, t) LOCK(l)
158 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
165 #ifdef DNS_ZONE_CHECKLOCK
166 isc_boolean_t locked;
169 isc_refcount_t erefs;
171 #ifdef ISC_RWLOCK_USEATOMIC
176 dns_db_t *db; /* Locked by dblock */
180 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
185 dns_masterformat_t masterformat;
187 isc_int32_t journalsize;
188 dns_rdataclass_t rdclass;
191 unsigned int options;
192 unsigned int db_argc;
194 isc_time_t expiretime;
195 isc_time_t refreshtime;
198 isc_time_t notifytime;
199 isc_time_t resigntime;
200 isc_time_t keywarntime;
201 isc_time_t signingtime;
202 isc_time_t nsec3chaintime;
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
355 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
357 /* Flags for zone_load() */
358 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
360 #define UNREACH_CHACHE_SIZE 10U
361 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
364 do { result = (op); \
365 if (result != ISC_R_SUCCESS) goto failure; \
368 struct dns_unreachable {
369 isc_sockaddr_t remote;
370 isc_sockaddr_t local;
378 int refs; /* Locked by rwlock */
379 isc_taskmgr_t * taskmgr;
380 isc_timermgr_t * timermgr;
381 isc_socketmgr_t * socketmgr;
382 isc_taskpool_t * zonetasks;
384 isc_ratelimiter_t * rl;
388 /* Locked by rwlock. */
389 dns_zonelist_t zones;
390 dns_zonelist_t waiting_for_xfrin;
391 dns_zonelist_t xfrin_in_progress;
393 /* Configuration data. */
394 isc_uint32_t transfersin;
395 isc_uint32_t transfersperns;
396 unsigned int serialqueryrate;
398 /* Locked by iolock */
399 isc_uint32_t iolimit;
400 isc_uint32_t ioactive;
404 /* Locked by rwlock. */
406 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
418 dns_request_t *request;
421 ISC_LINK(dns_notify_t) link;
424 #define DNS_NOTIFY_NOSOA 0x0001U
427 * dns_stub holds state while performing a 'stub' transfer.
428 * 'db' is the zone's 'db' or a new one if this is the initial
437 dns_dbversion_t *version;
449 dns_rdatacallbacks_t callbacks;
453 * Hold forward state.
459 isc_buffer_t *msgbuf;
460 dns_request_t *request;
463 dns_updatecallback_t callback;
468 * Hold IO request state.
475 ISC_LINK(dns_io_t) link;
480 * Hold state for when we are signing a zone with a new
481 * DNSKEY as result of an update.
486 dns_dbiterator_t *dbiterator;
487 dns_secalg_t algorithm;
489 isc_boolean_t delete;
491 ISC_LINK(dns_signing_t) link;
494 struct dns_nsec3chain {
497 dns_dbiterator_t *dbiterator;
498 dns_rdata_nsec3param_t nsec3param;
499 unsigned char salt[255];
501 isc_boolean_t seen_nsec;
502 isc_boolean_t delete_nsec;
503 isc_boolean_t save_delete_nsec;
504 ISC_LINK(dns_nsec3chain_t) link;
507 * 'dbiterator' contains a iterator for the database. If we are creating
508 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
509 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
512 * 'nsec3param' contains the parameters of the NSEC3 chain being created
515 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
517 * 'seen_nsec' will be set to true if, while iterating the zone to create a
518 * NSEC3 chain, a NSEC record is seen.
520 * 'delete_nsec' will be set to true if, at the completion of the creation
521 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
522 * are in the process of deleting the NSEC chain.
524 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
525 * so it can be recovered in the event of a error.
529 #define SEND_BUFFER_SIZE 2048
531 static void zone_settimer(dns_zone_t *, isc_time_t *);
532 static void cancel_refresh(dns_zone_t *);
533 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
534 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
535 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
536 ISC_FORMAT_PRINTF(3, 4);
537 static void queue_xfrin(dns_zone_t *zone);
538 static void zone_unload(dns_zone_t *zone);
539 static void zone_expire(dns_zone_t *zone);
540 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
541 static void zone_idetach(dns_zone_t **zonep);
542 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
544 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
545 static inline void zone_detachdb(dns_zone_t *zone);
546 static isc_result_t default_journal(dns_zone_t *zone);
547 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
548 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
549 isc_time_t loadtime, isc_result_t result);
550 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
551 static void zone_shutdown(isc_task_t *, isc_event_t *);
552 static void zone_loaddone(void *arg, isc_result_t result);
553 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
554 isc_time_t loadtime);
555 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
556 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
557 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
558 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
561 /* ondestroy example */
562 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
565 static void refresh_callback(isc_task_t *, isc_event_t *);
566 static void stub_callback(isc_task_t *, isc_event_t *);
567 static void queue_soa_query(dns_zone_t *zone);
568 static void soa_query(isc_task_t *, isc_event_t *);
569 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
571 static int message_count(dns_message_t *msg, dns_section_t section,
572 dns_rdatatype_t type);
573 static void notify_cancel(dns_zone_t *zone);
574 static void notify_find_address(dns_notify_t *notify);
575 static void notify_send(dns_notify_t *notify);
576 static isc_result_t notify_createmessage(dns_zone_t *zone,
578 dns_message_t **messagep);
579 static void notify_done(isc_task_t *task, isc_event_t *event);
580 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
581 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
582 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
583 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
585 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
586 static void zonemgr_free(dns_zonemgr_t *zmgr);
587 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
588 isc_task_t *task, isc_taskaction_t action,
589 void *arg, dns_io_t **iop);
590 static void zonemgr_putio(dns_io_t **iop);
591 static void zonemgr_cancelio(dns_io_t *io);
594 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
595 unsigned int *soacount, isc_uint32_t *serial,
596 isc_uint32_t *refresh, isc_uint32_t *retry,
597 isc_uint32_t *expire, isc_uint32_t *minimum,
598 unsigned int *errors);
600 static void zone_freedbargs(dns_zone_t *zone);
601 static void forward_callback(isc_task_t *task, isc_event_t *event);
602 static void zone_saveunique(dns_zone_t *zone, const char *path,
603 const char *templat);
604 static void zone_maintenance(dns_zone_t *zone);
605 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
606 static void dump_done(void *arg, isc_result_t result);
607 static isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr,
608 isc_sockaddr_t *remote,
609 isc_sockaddr_t *local,
611 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
612 isc_uint16_t keyid, isc_boolean_t delete);
614 #define ENTER zone_debuglog(zone, me, 1, "enter")
616 static const unsigned int dbargc_default = 1;
617 static const char *dbargv_default[] = { "rbt" };
619 #define DNS_ZONE_JITTER_ADD(a, b, c) \
623 _j = isc_random_jitter((b), (b)/4); \
624 isc_interval_set(&_i, _j, 0); \
625 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
626 dns_zone_log(zone, ISC_LOG_WARNING, \
627 "epoch approaching: upgrade required: " \
628 "now + %s failed", #b); \
629 isc_interval_set(&_i, _j/2, 0); \
630 (void)isc_time_add((a), &_i, (c)); \
634 #define DNS_ZONE_TIME_ADD(a, b, c) \
637 isc_interval_set(&_i, (b), 0); \
638 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
639 dns_zone_log(zone, ISC_LOG_WARNING, \
640 "epoch approaching: upgrade required: " \
641 "now + %s failed", #b); \
642 isc_interval_set(&_i, (b)/2, 0); \
643 (void)isc_time_add((a), &_i, (c)); \
648 * Increment resolver-related statistics counters. Zone must be locked.
651 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
652 if (zone->stats != NULL)
653 isc_stats_increment(zone->stats, counter);
657 *** Public functions.
661 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
666 REQUIRE(zonep != NULL && *zonep == NULL);
667 REQUIRE(mctx != NULL);
670 zone = isc_mem_get(mctx, sizeof(*zone));
672 return (ISC_R_NOMEMORY);
675 isc_mem_attach(mctx, &zone->mctx);
677 result = isc_mutex_init(&zone->lock);
678 if (result != ISC_R_SUCCESS)
681 result = ZONEDB_INITLOCK(&zone->dblock);
682 if (result != ISC_R_SUCCESS)
685 /* XXX MPA check that all elements are initialised */
686 #ifdef DNS_ZONE_CHECKLOCK
687 zone->locked = ISC_FALSE;
691 ISC_LINK_INIT(zone, link);
692 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
693 if (result != ISC_R_SUCCESS)
696 dns_name_init(&zone->origin, NULL);
697 zone->strnamerd = NULL;
698 zone->strname = NULL;
699 zone->strrdclass = NULL;
700 zone->strviewname = NULL;
701 zone->masterfile = NULL;
702 zone->masterformat = dns_masterformat_none;
703 zone->keydirectory = NULL;
704 zone->journalsize = -1;
705 zone->journal = NULL;
706 zone->rdclass = dns_rdataclass_none;
707 zone->type = dns_zone_none;
711 zone->db_argv = NULL;
712 isc_time_settoepoch(&zone->expiretime);
713 isc_time_settoepoch(&zone->refreshtime);
714 isc_time_settoepoch(&zone->dumptime);
715 isc_time_settoepoch(&zone->loadtime);
716 zone->notifytime = now;
717 isc_time_settoepoch(&zone->resigntime);
718 isc_time_settoepoch(&zone->keywarntime);
719 isc_time_settoepoch(&zone->signingtime);
720 isc_time_settoepoch(&zone->nsec3chaintime);
722 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
723 zone->retry = DNS_ZONE_DEFAULTRETRY;
726 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
727 zone->minrefresh = DNS_ZONE_MINREFRESH;
728 zone->maxretry = DNS_ZONE_MAXRETRY;
729 zone->minretry = DNS_ZONE_MINRETRY;
730 zone->masters = NULL;
731 zone->masterkeynames = NULL;
732 zone->mastersok = NULL;
733 zone->masterscnt = 0;
736 zone->notifytype = dns_notifytype_yes;
739 zone->update_acl = NULL;
740 zone->forward_acl = NULL;
741 zone->notify_acl = NULL;
742 zone->query_acl = NULL;
743 zone->queryon_acl = NULL;
744 zone->xfr_acl = NULL;
745 zone->update_disabled = ISC_FALSE;
746 zone->zero_no_soa_ttl = ISC_TRUE;
747 zone->check_names = dns_severity_ignore;
748 zone->request = NULL;
752 zone->writeio = NULL;
754 zone->idlein = DNS_DEFAULT_IDLEIN;
755 zone->idleout = DNS_DEFAULT_IDLEOUT;
756 ISC_LIST_INIT(zone->notifies);
757 isc_sockaddr_any(&zone->notifysrc4);
758 isc_sockaddr_any6(&zone->notifysrc6);
759 isc_sockaddr_any(&zone->xfrsource4);
760 isc_sockaddr_any6(&zone->xfrsource6);
761 isc_sockaddr_any(&zone->altxfrsource4);
762 isc_sockaddr_any6(&zone->altxfrsource6);
764 zone->tsigkey = NULL;
765 zone->maxxfrin = MAX_XFER_TIME;
766 zone->maxxfrout = MAX_XFER_TIME;
767 zone->ssutable = NULL;
768 zone->sigvalidityinterval = 30 * 24 * 3600;
769 zone->sigresigninginterval = 7 * 24 * 3600;
772 zone->checkmx = NULL;
773 zone->checksrv = NULL;
774 zone->checkns = NULL;
775 ISC_LINK_INIT(zone, statelink);
776 zone->statelist = NULL;
778 zone->requeststats_on = ISC_FALSE;
779 zone->requeststats = NULL;
780 zone->notifydelay = 5;
782 zone->isselfarg = NULL;
783 ISC_LIST_INIT(zone->signing);
784 ISC_LIST_INIT(zone->nsec3chain);
785 zone->signatures = 10;
787 zone->privatetype = (dns_rdatatype_t)0xffffU;
789 zone->magic = ZONE_MAGIC;
791 /* Must be after magic is set. */
792 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
793 if (result != ISC_R_SUCCESS)
796 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
797 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
800 return (ISC_R_SUCCESS);
803 isc_refcount_decrement(&zone->erefs, NULL);
804 isc_refcount_destroy(&zone->erefs);
807 ZONEDB_DESTROYLOCK(&zone->dblock);
810 DESTROYLOCK(&zone->lock);
813 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
818 * Free a zone. Because we require that there be no more
819 * outstanding events or references, no locking is necessary.
822 zone_free(dns_zone_t *zone) {
823 isc_mem_t *mctx = NULL;
824 dns_signing_t *signing;
825 dns_nsec3chain_t *nsec3chain;
827 REQUIRE(DNS_ZONE_VALID(zone));
828 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
829 REQUIRE(zone->irefs == 0);
830 REQUIRE(!LOCKED_ZONE(zone));
831 REQUIRE(zone->timer == NULL);
834 * Managed objects. Order is important.
836 if (zone->request != NULL)
837 dns_request_destroy(&zone->request); /* XXXMPA */
838 INSIST(zone->readio == NULL);
839 INSIST(zone->statelist == NULL);
840 INSIST(zone->writeio == NULL);
842 if (zone->task != NULL)
843 isc_task_detach(&zone->task);
844 if (zone->zmgr != NULL)
845 dns_zonemgr_releasezone(zone->zmgr, zone);
847 /* Unmanaged objects */
848 for (signing = ISC_LIST_HEAD(zone->signing);
850 signing = ISC_LIST_HEAD(zone->signing)) {
851 ISC_LIST_UNLINK(zone->signing, signing, link);
852 dns_db_detach(&signing->db);
853 dns_dbiterator_destroy(&signing->dbiterator);
854 isc_mem_put(zone->mctx, signing, sizeof *signing);
856 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
858 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
859 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
860 dns_db_detach(&nsec3chain->db);
861 dns_dbiterator_destroy(&nsec3chain->dbiterator);
862 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
864 if (zone->masterfile != NULL)
865 isc_mem_free(zone->mctx, zone->masterfile);
866 zone->masterfile = NULL;
867 if (zone->keydirectory != NULL)
868 isc_mem_free(zone->mctx, zone->keydirectory);
869 zone->keydirectory = NULL;
870 zone->journalsize = -1;
871 if (zone->journal != NULL)
872 isc_mem_free(zone->mctx, zone->journal);
873 zone->journal = NULL;
874 if (zone->stats != NULL)
875 isc_stats_detach(&zone->stats);
876 if (zone->requeststats != NULL)
877 isc_stats_detach(&zone->requeststats);
878 if (zone->db != NULL)
880 if (zone->acache != NULL)
881 dns_acache_detach(&zone->acache);
882 zone_freedbargs(zone);
883 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
885 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
887 zone->check_names = dns_severity_ignore;
888 if (zone->update_acl != NULL)
889 dns_acl_detach(&zone->update_acl);
890 if (zone->forward_acl != NULL)
891 dns_acl_detach(&zone->forward_acl);
892 if (zone->notify_acl != NULL)
893 dns_acl_detach(&zone->notify_acl);
894 if (zone->query_acl != NULL)
895 dns_acl_detach(&zone->query_acl);
896 if (zone->queryon_acl != NULL)
897 dns_acl_detach(&zone->queryon_acl);
898 if (zone->xfr_acl != NULL)
899 dns_acl_detach(&zone->xfr_acl);
900 if (dns_name_dynamic(&zone->origin))
901 dns_name_free(&zone->origin, zone->mctx);
902 if (zone->strnamerd != NULL)
903 isc_mem_free(zone->mctx, zone->strnamerd);
904 if (zone->strname != NULL)
905 isc_mem_free(zone->mctx, zone->strname);
906 if (zone->strrdclass != NULL)
907 isc_mem_free(zone->mctx, zone->strrdclass);
908 if (zone->strviewname != NULL)
909 isc_mem_free(zone->mctx, zone->strviewname);
910 if (zone->ssutable != NULL)
911 dns_ssutable_detach(&zone->ssutable);
914 ZONEDB_DESTROYLOCK(&zone->dblock);
915 DESTROYLOCK(&zone->lock);
916 isc_refcount_destroy(&zone->erefs);
919 isc_mem_put(mctx, zone, sizeof(*zone));
920 isc_mem_detach(&mctx);
927 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
930 REQUIRE(DNS_ZONE_VALID(zone));
931 REQUIRE(rdclass != dns_rdataclass_none);
937 REQUIRE(zone->rdclass == dns_rdataclass_none ||
938 zone->rdclass == rdclass);
939 zone->rdclass = rdclass;
941 if (zone->strnamerd != NULL)
942 isc_mem_free(zone->mctx, zone->strnamerd);
943 if (zone->strrdclass != NULL)
944 isc_mem_free(zone->mctx, zone->strrdclass);
946 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
947 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
948 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
949 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
955 dns_zone_getclass(dns_zone_t *zone) {
956 REQUIRE(DNS_ZONE_VALID(zone));
958 return (zone->rdclass);
962 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
963 REQUIRE(DNS_ZONE_VALID(zone));
966 zone->notifytype = notifytype;
971 dns_zone_getserial(dns_zone_t *zone) {
974 REQUIRE(DNS_ZONE_VALID(zone));
977 serial = zone->serial;
987 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
989 REQUIRE(DNS_ZONE_VALID(zone));
990 REQUIRE(type != dns_zone_none);
996 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1002 zone_freedbargs(dns_zone_t *zone) {
1005 /* Free the old database argument list. */
1006 if (zone->db_argv != NULL) {
1007 for (i = 0; i < zone->db_argc; i++)
1008 isc_mem_free(zone->mctx, zone->db_argv[i]);
1009 isc_mem_put(zone->mctx, zone->db_argv,
1010 zone->db_argc * sizeof(*zone->db_argv));
1013 zone->db_argv = NULL;
1017 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1020 isc_result_t result = ISC_R_SUCCESS;
1024 REQUIRE(DNS_ZONE_VALID(zone));
1025 REQUIRE(argv != NULL && *argv == NULL);
1028 size = (zone->db_argc + 1) * sizeof(char *);
1029 for (i = 0; i < zone->db_argc; i++)
1030 size += strlen(zone->db_argv[i]) + 1;
1031 mem = isc_mem_allocate(mctx, size);
1035 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1036 for (i = 0; i < zone->db_argc; i++) {
1038 strcpy(tmp2, zone->db_argv[i]);
1039 tmp2 += strlen(tmp2) + 1;
1043 result = ISC_R_NOMEMORY;
1050 dns_zone_setdbtype(dns_zone_t *zone,
1051 unsigned int dbargc, const char * const *dbargv) {
1052 isc_result_t result = ISC_R_SUCCESS;
1056 REQUIRE(DNS_ZONE_VALID(zone));
1057 REQUIRE(dbargc >= 1);
1058 REQUIRE(dbargv != NULL);
1062 /* Set up a new database argument list. */
1063 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1066 for (i = 0; i < dbargc; i++)
1068 for (i = 0; i < dbargc; i++) {
1069 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1074 /* Free the old list. */
1075 zone_freedbargs(zone);
1077 zone->db_argc = dbargc;
1078 zone->db_argv = new;
1079 result = ISC_R_SUCCESS;
1084 for (i = 0; i < dbargc; i++)
1086 isc_mem_free(zone->mctx, new[i]);
1087 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1089 result = ISC_R_NOMEMORY;
1097 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1099 REQUIRE(DNS_ZONE_VALID(zone));
1102 if (zone->view != NULL)
1103 dns_view_weakdetach(&zone->view);
1104 dns_view_weakattach(view, &zone->view);
1106 if (zone->strviewname != NULL)
1107 isc_mem_free(zone->mctx, zone->strviewname);
1108 if (zone->strnamerd != NULL)
1109 isc_mem_free(zone->mctx, zone->strnamerd);
1111 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1112 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1113 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1114 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1121 dns_zone_getview(dns_zone_t *zone) {
1122 REQUIRE(DNS_ZONE_VALID(zone));
1124 return (zone->view);
1129 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1130 isc_result_t result;
1133 REQUIRE(DNS_ZONE_VALID(zone));
1134 REQUIRE(origin != NULL);
1137 if (dns_name_dynamic(&zone->origin)) {
1138 dns_name_free(&zone->origin, zone->mctx);
1139 dns_name_init(&zone->origin, NULL);
1141 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1143 if (zone->strnamerd != NULL)
1144 isc_mem_free(zone->mctx, zone->strnamerd);
1145 if (zone->strname != NULL)
1146 isc_mem_free(zone->mctx, zone->strname);
1148 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1149 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1150 zone_name_tostr(zone, namebuf, sizeof namebuf);
1151 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1158 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1159 REQUIRE(DNS_ZONE_VALID(zone));
1160 REQUIRE(acache != NULL);
1163 if (zone->acache != NULL)
1164 dns_acache_detach(&zone->acache);
1165 dns_acache_attach(acache, &zone->acache);
1166 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1167 if (zone->db != NULL) {
1168 isc_result_t result;
1171 * If the zone reuses an existing DB, the DB needs to be
1172 * set in the acache explicitly. We can safely ignore the
1173 * case where the DB is already set. If other error happens,
1174 * the acache will not work effectively.
1176 result = dns_acache_setdb(acache, zone->db);
1177 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1178 UNEXPECTED_ERROR(__FILE__, __LINE__,
1179 "dns_acache_setdb() failed: %s",
1180 isc_result_totext(result));
1183 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1188 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1191 if (value != NULL) {
1192 copy = isc_mem_strdup(zone->mctx, value);
1194 return (ISC_R_NOMEMORY);
1200 isc_mem_free(zone->mctx, *field);
1203 return (ISC_R_SUCCESS);
1207 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1208 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1212 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1213 dns_masterformat_t format) {
1214 isc_result_t result = ISC_R_SUCCESS;
1216 REQUIRE(DNS_ZONE_VALID(zone));
1219 result = dns_zone_setstring(zone, &zone->masterfile, file);
1220 if (result == ISC_R_SUCCESS) {
1221 zone->masterformat = format;
1222 result = default_journal(zone);
1230 dns_zone_getfile(dns_zone_t *zone) {
1231 REQUIRE(DNS_ZONE_VALID(zone));
1233 return (zone->masterfile);
1237 default_journal(dns_zone_t *zone) {
1238 isc_result_t result;
1241 REQUIRE(DNS_ZONE_VALID(zone));
1242 REQUIRE(LOCKED_ZONE(zone));
1244 if (zone->masterfile != NULL) {
1245 /* Calculate string length including '\0'. */
1246 int len = strlen(zone->masterfile) + sizeof(".jnl");
1247 journal = isc_mem_allocate(zone->mctx, len);
1248 if (journal == NULL)
1249 return (ISC_R_NOMEMORY);
1250 strcpy(journal, zone->masterfile);
1251 strcat(journal, ".jnl");
1255 result = dns_zone_setstring(zone, &zone->journal, journal);
1256 if (journal != NULL)
1257 isc_mem_free(zone->mctx, journal);
1262 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1263 isc_result_t result = ISC_R_SUCCESS;
1265 REQUIRE(DNS_ZONE_VALID(zone));
1268 result = dns_zone_setstring(zone, &zone->journal, journal);
1275 dns_zone_getjournal(dns_zone_t *zone) {
1276 REQUIRE(DNS_ZONE_VALID(zone));
1278 return (zone->journal);
1282 * Return true iff the zone is "dynamic", in the sense that the zone's
1283 * master file (if any) is written by the server, rather than being
1284 * updated manually and read by the server.
1286 * This is true for slave zones, stub zones, and zones that allow
1287 * dynamic updates either by having an update policy ("ssutable")
1288 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1290 static isc_boolean_t
1291 zone_isdynamic(dns_zone_t *zone) {
1292 REQUIRE(DNS_ZONE_VALID(zone));
1294 return (ISC_TF(zone->type == dns_zone_slave ||
1295 zone->type == dns_zone_stub ||
1296 (!zone->update_disabled && zone->ssutable != NULL) ||
1297 (!zone->update_disabled && zone->update_acl != NULL &&
1298 !dns_acl_isnone(zone->update_acl))));
1303 zone_load(dns_zone_t *zone, unsigned int flags) {
1304 isc_result_t result;
1306 isc_time_t loadtime, filetime;
1307 dns_db_t *db = NULL;
1309 REQUIRE(DNS_ZONE_VALID(zone));
1314 INSIST(zone->type != dns_zone_none);
1316 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1317 result = ISC_R_SUCCESS;
1321 if (zone->db != NULL && zone->masterfile == NULL) {
1323 * The zone has no master file configured, but it already
1324 * has a database. It could be the built-in
1325 * version.bind. CH zone, a zone with a persistent
1326 * database being reloaded, or maybe a zone that
1327 * used to have a master file but whose configuration
1328 * was changed so that it no longer has one. Do nothing.
1330 result = ISC_R_SUCCESS;
1334 if (zone->db != NULL && zone_isdynamic(zone)) {
1336 * This is a slave, stub, or dynamically updated
1337 * zone being reloaded. Do nothing - the database
1338 * we already have is guaranteed to be up-to-date.
1340 if (zone->type == dns_zone_master)
1341 result = DNS_R_DYNAMIC;
1343 result = ISC_R_SUCCESS;
1349 * Store the current time before the zone is loaded, so that if the
1350 * file changes between the time of the load and the time that
1351 * zone->loadtime is set, then the file will still be reloaded
1352 * the next time dns_zone_load is called.
1354 TIME_NOW(&loadtime);
1357 * Don't do the load if the file that stores the zone is older
1358 * than the last time the zone was loaded. If the zone has not
1359 * been loaded yet, zone->loadtime will be the epoch.
1361 if (zone->masterfile != NULL) {
1363 * The file is already loaded. If we are just doing a
1364 * "rndc reconfig", we are done.
1366 if (!isc_time_isepoch(&zone->loadtime) &&
1367 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1368 result = ISC_R_SUCCESS;
1372 result = isc_file_getmodtime(zone->masterfile, &filetime);
1373 if (result == ISC_R_SUCCESS) {
1374 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1375 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1376 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1377 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1378 "skipping load: master file "
1379 "older than last load");
1380 result = DNS_R_UPTODATE;
1383 loadtime = filetime;
1387 INSIST(zone->db_argc >= 1);
1390 * Built in zones don't need to be reloaded.
1392 if (zone->type == dns_zone_master &&
1393 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1394 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1395 result = ISC_R_SUCCESS;
1399 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1400 (strcmp(zone->db_argv[0], "rbt") == 0 ||
1401 strcmp(zone->db_argv[0], "rbt64") == 0)) {
1402 if (zone->masterfile == NULL ||
1403 !isc_file_exists(zone->masterfile)) {
1404 if (zone->masterfile != NULL) {
1405 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1408 zone->refreshtime = now;
1409 if (zone->task != NULL)
1410 zone_settimer(zone, &now);
1411 result = ISC_R_SUCCESS;
1416 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1418 result = dns_db_create(zone->mctx, zone->db_argv[0],
1419 &zone->origin, (zone->type == dns_zone_stub) ?
1420 dns_dbtype_stub : dns_dbtype_zone,
1422 zone->db_argc - 1, zone->db_argv + 1,
1425 if (result != ISC_R_SUCCESS) {
1426 dns_zone_log(zone, ISC_LOG_ERROR,
1427 "loading zone: creating database: %s",
1428 isc_result_totext(result));
1431 dns_db_settask(db, zone->task);
1433 if (! dns_db_ispersistent(db)) {
1434 if (zone->masterfile != NULL) {
1435 result = zone_startload(db, zone, loadtime);
1437 result = DNS_R_NOMASTERFILE;
1438 if (zone->type == dns_zone_master) {
1439 dns_zone_log(zone, ISC_LOG_ERROR,
1441 "no master file configured");
1444 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1445 "no master file configured: continuing");
1449 if (result == DNS_R_CONTINUE) {
1450 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1454 result = zone_postload(zone, db, loadtime, result);
1464 dns_zone_load(dns_zone_t *zone) {
1465 return (zone_load(zone, 0));
1469 dns_zone_loadnew(dns_zone_t *zone) {
1470 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1474 get_master_options(dns_zone_t *zone) {
1475 unsigned int options;
1477 options = DNS_MASTER_ZONE;
1478 if (zone->type == dns_zone_slave)
1479 options |= DNS_MASTER_SLAVE;
1480 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1481 options |= DNS_MASTER_CHECKNS;
1482 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1483 options |= DNS_MASTER_FATALNS;
1484 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1485 options |= DNS_MASTER_CHECKNAMES;
1486 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1487 options |= DNS_MASTER_CHECKNAMESFAIL;
1488 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1489 options |= DNS_MASTER_CHECKMX;
1490 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1491 options |= DNS_MASTER_CHECKMXFAIL;
1492 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1493 options |= DNS_MASTER_CHECKWILDCARD;
1494 if (zone->type == dns_zone_master &&
1495 (zone->update_acl != NULL || zone->ssutable != NULL))
1496 options |= DNS_MASTER_RESIGN;
1501 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1502 dns_load_t *load = event->ev_arg;
1503 isc_result_t result = ISC_R_SUCCESS;
1504 unsigned int options;
1506 REQUIRE(DNS_LOAD_VALID(load));
1508 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1509 result = ISC_R_CANCELED;
1510 isc_event_free(&event);
1511 if (result == ISC_R_CANCELED)
1514 options = get_master_options(load->zone);
1516 result = dns_master_loadfileinc3(load->zone->masterfile,
1517 dns_db_origin(load->db),
1518 dns_db_origin(load->db),
1519 load->zone->rdclass,
1521 load->zone->sigresigninginterval,
1522 &load->callbacks, task,
1523 zone_loaddone, load,
1524 &load->zone->lctx, load->zone->mctx,
1525 load->zone->masterformat);
1526 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1527 result != DNS_R_SEENINCLUDE)
1532 zone_loaddone(load, result);
1536 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1537 const char me[] = "zone_gotwritehandle";
1538 dns_zone_t *zone = event->ev_arg;
1539 isc_result_t result = ISC_R_SUCCESS;
1540 dns_dbversion_t *version = NULL;
1542 REQUIRE(DNS_ZONE_VALID(zone));
1543 INSIST(task == zone->task);
1546 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1547 result = ISC_R_CANCELED;
1548 isc_event_free(&event);
1549 if (result == ISC_R_CANCELED)
1553 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1554 dns_db_currentversion(zone->db, &version);
1555 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1556 &dns_master_style_default,
1557 zone->masterfile, zone->task, dump_done,
1558 zone, &zone->dctx, zone->masterformat);
1559 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1560 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1562 if (result != DNS_R_CONTINUE)
1567 dump_done(zone, result);
1571 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1573 isc_result_t result;
1574 isc_result_t tresult;
1575 unsigned int options;
1577 options = get_master_options(zone);
1579 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1580 options |= DNS_MASTER_MANYERRORS;
1582 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1583 load = isc_mem_get(zone->mctx, sizeof(*load));
1585 return (ISC_R_NOMEMORY);
1590 load->loadtime = loadtime;
1591 load->magic = LOAD_MAGIC;
1593 isc_mem_attach(zone->mctx, &load->mctx);
1594 zone_iattach(zone, &load->zone);
1595 dns_db_attach(db, &load->db);
1596 dns_rdatacallbacks_init(&load->callbacks);
1597 result = dns_db_beginload(db, &load->callbacks.add,
1598 &load->callbacks.add_private);
1599 if (result != ISC_R_SUCCESS)
1601 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1602 zone_gotreadhandle, load,
1604 if (result != ISC_R_SUCCESS) {
1606 * We can't report multiple errors so ignore
1607 * the result of dns_db_endload().
1609 (void)dns_db_endload(load->db,
1610 &load->callbacks.add_private);
1613 result = DNS_R_CONTINUE;
1615 dns_rdatacallbacks_t callbacks;
1617 dns_rdatacallbacks_init(&callbacks);
1618 result = dns_db_beginload(db, &callbacks.add,
1619 &callbacks.add_private);
1620 if (result != ISC_R_SUCCESS)
1622 result = dns_master_loadfile3(zone->masterfile, &zone->origin,
1623 &zone->origin, zone->rdclass,
1624 options, zone->sigresigninginterval,
1625 &callbacks, zone->mctx,
1626 zone->masterformat);
1627 tresult = dns_db_endload(db, &callbacks.add_private);
1628 if (result == ISC_R_SUCCESS)
1636 dns_db_detach(&load->db);
1637 zone_idetach(&load->zone);
1638 isc_mem_detach(&load->mctx);
1639 isc_mem_put(zone->mctx, load, sizeof(*load));
1643 static isc_boolean_t
1644 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1647 isc_result_t result;
1648 char ownerbuf[DNS_NAME_FORMATSIZE];
1649 char namebuf[DNS_NAME_FORMATSIZE];
1650 char altbuf[DNS_NAME_FORMATSIZE];
1651 dns_fixedname_t fixed;
1652 dns_name_t *foundname;
1658 if (!dns_name_issubdomain(name, &zone->origin)) {
1659 if (zone->checkmx != NULL)
1660 return ((zone->checkmx)(zone, name, owner));
1664 if (zone->type == dns_zone_master)
1665 level = ISC_LOG_ERROR;
1667 level = ISC_LOG_WARNING;
1669 dns_fixedname_init(&fixed);
1670 foundname = dns_fixedname_name(&fixed);
1672 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1673 0, 0, NULL, foundname, NULL, NULL);
1674 if (result == ISC_R_SUCCESS)
1677 if (result == DNS_R_NXRRSET) {
1678 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1679 0, 0, NULL, foundname, NULL, NULL);
1680 if (result == ISC_R_SUCCESS)
1684 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1685 dns_name_format(name, namebuf, sizeof namebuf);
1686 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1687 result == DNS_R_EMPTYNAME) {
1688 dns_zone_log(zone, level,
1689 "%s/MX '%s' has no address records (A or AAAA)",
1691 /* XXX950 make fatal for 9.5.0. */
1695 if (result == DNS_R_CNAME) {
1696 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1697 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1698 level = ISC_LOG_WARNING;
1699 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1700 dns_zone_log(zone, level,
1701 "%s/MX '%s' is a CNAME (illegal)",
1703 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1706 if (result == DNS_R_DNAME) {
1707 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1708 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1709 level = ISC_LOG_WARNING;
1710 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1711 dns_name_format(foundname, altbuf, sizeof altbuf);
1712 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1713 " '%s' (illegal)", ownerbuf, namebuf,
1716 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1719 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1720 return ((zone->checkmx)(zone, name, owner));
1725 static isc_boolean_t
1726 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1729 isc_result_t result;
1730 char ownerbuf[DNS_NAME_FORMATSIZE];
1731 char namebuf[DNS_NAME_FORMATSIZE];
1732 char altbuf[DNS_NAME_FORMATSIZE];
1733 dns_fixedname_t fixed;
1734 dns_name_t *foundname;
1738 * "." means the services does not exist.
1740 if (dns_name_equal(name, dns_rootname))
1746 if (!dns_name_issubdomain(name, &zone->origin)) {
1747 if (zone->checksrv != NULL)
1748 return ((zone->checksrv)(zone, name, owner));
1752 if (zone->type == dns_zone_master)
1753 level = ISC_LOG_ERROR;
1755 level = ISC_LOG_WARNING;
1757 dns_fixedname_init(&fixed);
1758 foundname = dns_fixedname_name(&fixed);
1760 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1761 0, 0, NULL, foundname, NULL, NULL);
1762 if (result == ISC_R_SUCCESS)
1765 if (result == DNS_R_NXRRSET) {
1766 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1767 0, 0, NULL, foundname, NULL, NULL);
1768 if (result == ISC_R_SUCCESS)
1772 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1773 dns_name_format(name, namebuf, sizeof namebuf);
1774 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1775 result == DNS_R_EMPTYNAME) {
1776 dns_zone_log(zone, level,
1777 "%s/SRV '%s' has no address records (A or AAAA)",
1779 /* XXX950 make fatal for 9.5.0. */
1783 if (result == DNS_R_CNAME) {
1784 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1785 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1786 level = ISC_LOG_WARNING;
1787 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1788 dns_zone_log(zone, level,
1789 "%s/SRV '%s' is a CNAME (illegal)",
1791 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1794 if (result == DNS_R_DNAME) {
1795 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1796 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1797 level = ISC_LOG_WARNING;
1798 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1799 dns_name_format(foundname, altbuf, sizeof altbuf);
1800 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1801 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1804 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1807 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1808 return ((zone->checksrv)(zone, name, owner));
1813 static isc_boolean_t
1814 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1817 isc_boolean_t answer = ISC_TRUE;
1818 isc_result_t result, tresult;
1819 char ownerbuf[DNS_NAME_FORMATSIZE];
1820 char namebuf[DNS_NAME_FORMATSIZE];
1821 char altbuf[DNS_NAME_FORMATSIZE];
1822 dns_fixedname_t fixed;
1823 dns_name_t *foundname;
1825 dns_rdataset_t aaaa;
1831 if (!dns_name_issubdomain(name, &zone->origin)) {
1832 if (zone->checkns != NULL)
1833 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1837 if (zone->type == dns_zone_master)
1838 level = ISC_LOG_ERROR;
1840 level = ISC_LOG_WARNING;
1842 dns_fixedname_init(&fixed);
1843 foundname = dns_fixedname_name(&fixed);
1844 dns_rdataset_init(&a);
1845 dns_rdataset_init(&aaaa);
1847 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1848 DNS_DBFIND_GLUEOK, 0, NULL,
1849 foundname, &a, NULL);
1851 if (result == ISC_R_SUCCESS) {
1852 dns_rdataset_disassociate(&a);
1854 } else if (result == DNS_R_DELEGATION)
1855 dns_rdataset_disassociate(&a);
1857 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1858 result == DNS_R_GLUE) {
1859 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1860 DNS_DBFIND_GLUEOK, 0, NULL,
1861 foundname, &aaaa, NULL);
1862 if (tresult == ISC_R_SUCCESS) {
1863 dns_rdataset_disassociate(&aaaa);
1866 if (tresult == DNS_R_DELEGATION)
1867 dns_rdataset_disassociate(&aaaa);
1868 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1870 * Check glue against child zone.
1872 if (zone->checkns != NULL)
1873 answer = (zone->checkns)(zone, name, owner,
1875 if (dns_rdataset_isassociated(&a))
1876 dns_rdataset_disassociate(&a);
1877 if (dns_rdataset_isassociated(&aaaa))
1878 dns_rdataset_disassociate(&aaaa);
1884 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1885 dns_name_format(name, namebuf, sizeof namebuf);
1886 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1887 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
1889 isc_boolean_t required = ISC_FALSE;
1890 if (dns_name_issubdomain(name, owner)) {
1891 what = "REQUIRED GLUE ";
1892 required = ISC_TRUE;
1893 } else if (result == DNS_R_DELEGATION)
1894 what = "SIBLING GLUE ";
1898 if (result != DNS_R_DELEGATION || required ||
1899 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
1900 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
1901 "address records (A or AAAA)",
1902 ownerbuf, namebuf, what);
1904 * Log missing address record.
1906 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
1907 (void)(zone->checkns)(zone, name, owner,
1909 /* XXX950 make fatal for 9.5.0. */
1910 /* answer = ISC_FALSE; */
1912 } else if (result == DNS_R_CNAME) {
1913 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
1915 /* XXX950 make fatal for 9.5.0. */
1916 /* answer = ISC_FALSE; */
1917 } else if (result == DNS_R_DNAME) {
1918 dns_name_format(foundname, altbuf, sizeof altbuf);
1919 dns_zone_log(zone, level,
1920 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1921 ownerbuf, namebuf, altbuf);
1922 /* XXX950 make fatal for 9.5.0. */
1923 /* answer = ISC_FALSE; */
1926 if (dns_rdataset_isassociated(&a))
1927 dns_rdataset_disassociate(&a);
1928 if (dns_rdataset_isassociated(&aaaa))
1929 dns_rdataset_disassociate(&aaaa);
1933 static isc_boolean_t
1934 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
1935 dns_dbiterator_t *dbiterator = NULL;
1936 dns_dbnode_t *node = NULL;
1937 dns_rdataset_t rdataset;
1938 dns_fixedname_t fixed;
1939 dns_fixedname_t fixedbottom;
1942 dns_rdata_in_srv_t srv;
1946 isc_result_t result;
1947 isc_boolean_t ok = ISC_TRUE;
1949 dns_fixedname_init(&fixed);
1950 name = dns_fixedname_name(&fixed);
1951 dns_fixedname_init(&fixedbottom);
1952 bottom = dns_fixedname_name(&fixedbottom);
1953 dns_rdataset_init(&rdataset);
1954 dns_rdata_init(&rdata);
1956 result = dns_db_createiterator(db, 0, &dbiterator);
1957 if (result != ISC_R_SUCCESS)
1960 result = dns_dbiterator_first(dbiterator);
1961 while (result == ISC_R_SUCCESS) {
1962 result = dns_dbiterator_current(dbiterator, &node, name);
1963 if (result != ISC_R_SUCCESS)
1967 * Is this name visible in the zone?
1969 if (!dns_name_issubdomain(name, &zone->origin) ||
1970 (dns_name_countlabels(bottom) > 0 &&
1971 dns_name_issubdomain(name, bottom)))
1975 * Don't check the NS records at the origin.
1977 if (dns_name_equal(name, &zone->origin))
1980 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
1981 0, 0, &rdataset, NULL);
1982 if (result != ISC_R_SUCCESS)
1985 * Remember bottom of zone.
1987 dns_name_copy(name, bottom, NULL);
1989 result = dns_rdataset_first(&rdataset);
1990 while (result == ISC_R_SUCCESS) {
1991 dns_rdataset_current(&rdataset, &rdata);
1992 result = dns_rdata_tostruct(&rdata, &ns, NULL);
1993 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1994 if (!zone_check_glue(zone, db, &ns.name, name))
1996 dns_rdata_reset(&rdata);
1997 result = dns_rdataset_next(&rdataset);
1999 dns_rdataset_disassociate(&rdataset);
2002 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2003 0, 0, &rdataset, NULL);
2004 if (result != ISC_R_SUCCESS)
2006 result = dns_rdataset_first(&rdataset);
2007 while (result == ISC_R_SUCCESS) {
2008 dns_rdataset_current(&rdataset, &rdata);
2009 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2010 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2011 if (!zone_check_mx(zone, db, &mx.mx, name))
2013 dns_rdata_reset(&rdata);
2014 result = dns_rdataset_next(&rdataset);
2016 dns_rdataset_disassociate(&rdataset);
2019 if (zone->rdclass != dns_rdataclass_in)
2021 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2022 0, 0, &rdataset, NULL);
2023 if (result != ISC_R_SUCCESS)
2025 result = dns_rdataset_first(&rdataset);
2026 while (result == ISC_R_SUCCESS) {
2027 dns_rdataset_current(&rdataset, &rdata);
2028 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2029 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2030 if (!zone_check_srv(zone, db, &srv.target, name))
2032 dns_rdata_reset(&rdata);
2033 result = dns_rdataset_next(&rdataset);
2035 dns_rdataset_disassociate(&rdataset);
2038 dns_db_detachnode(db, &node);
2039 result = dns_dbiterator_next(dbiterator);
2044 dns_db_detachnode(db, &node);
2045 dns_dbiterator_destroy(&dbiterator);
2051 * OpenSSL verification of RSA keys with exponent 3 is known to be
2052 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2053 * if they are in use.
2056 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2057 dns_dbnode_t *node = NULL;
2058 dns_dbversion_t *version = NULL;
2059 dns_rdata_dnskey_t dnskey;
2060 dns_rdata_t rdata = DNS_RDATA_INIT;
2061 dns_rdataset_t rdataset;
2062 isc_result_t result;
2063 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2064 const char *algorithm;
2066 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2067 if (result != ISC_R_SUCCESS)
2070 dns_db_currentversion(db, &version);
2071 dns_rdataset_init(&rdataset);
2072 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2073 dns_rdatatype_none, 0, &rdataset, NULL);
2074 if (result != ISC_R_SUCCESS)
2077 for (result = dns_rdataset_first(&rdataset);
2078 result == ISC_R_SUCCESS;
2079 result = dns_rdataset_next(&rdataset))
2081 dns_rdataset_current(&rdataset, &rdata);
2082 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2083 INSIST(result == ISC_R_SUCCESS);
2085 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2086 dnskey.algorithm == DST_ALG_RSAMD5) &&
2087 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2088 dnskey.data[1] == 3)
2090 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2092 foundrsa = ISC_TRUE;
2093 algorithm = "RSASHA1";
2096 foundmd5 = ISC_TRUE;
2097 algorithm = "RSAMD5";
2100 dns_zone_log(zone, ISC_LOG_WARNING,
2101 "weak %s (%u) key found "
2102 "(exponent=3)", algorithm,
2104 if (foundrsa && foundmd5)
2107 dns_rdata_reset(&rdata);
2109 dns_rdataset_disassociate(&rdataset);
2113 dns_db_detachnode(db, &node);
2114 if (version != NULL)
2115 dns_db_closeversion(db, &version, ISC_FALSE);
2120 resume_signingwithkey(dns_zone_t *zone) {
2121 dns_dbnode_t *node = NULL;
2122 dns_dbversion_t *version = NULL;
2123 dns_rdata_t rdata = DNS_RDATA_INIT;
2124 dns_rdataset_t rdataset;
2125 isc_result_t result;
2127 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2128 if (result != ISC_R_SUCCESS)
2131 dns_db_currentversion(zone->db, &version);
2132 dns_rdataset_init(&rdataset);
2133 result = dns_db_findrdataset(zone->db, node, version,
2135 dns_rdatatype_none, 0,
2137 if (result != ISC_R_SUCCESS)
2140 for (result = dns_rdataset_first(&rdataset);
2141 result == ISC_R_SUCCESS;
2142 result = dns_rdataset_next(&rdataset))
2144 dns_rdataset_current(&rdataset, &rdata);
2145 if (rdata.length != 5 || rdata.data[4] != 0) {
2146 dns_rdata_reset(&rdata);
2150 result = zone_signwithkey(zone, rdata.data[0],
2151 (rdata.data[1] << 8) | rdata.data[2], ISC_TF(rdata.data[3]));
2152 if (result != ISC_R_SUCCESS) {
2153 dns_zone_log(zone, ISC_LOG_ERROR,
2154 "zone_signwithkey failed: %s",
2155 dns_result_totext(result));
2157 dns_rdata_reset(&rdata);
2159 dns_rdataset_disassociate(&rdataset);
2163 dns_db_detachnode(zone->db, &node);
2164 if (version != NULL)
2165 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2170 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2171 dns_nsec3chain_t *nsec3chain, *current;
2172 isc_result_t result;
2174 unsigned int options = 0;
2176 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2177 if (nsec3chain == NULL)
2178 return (ISC_R_NOMEMORY);
2180 nsec3chain->magic = 0;
2181 nsec3chain->done = ISC_FALSE;
2182 nsec3chain->db = NULL;
2183 nsec3chain->dbiterator = NULL;
2184 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2185 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2186 nsec3chain->nsec3param.hash = nsec3param->hash;
2187 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2188 nsec3chain->nsec3param.flags = nsec3param->flags;
2189 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2190 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2191 nsec3chain->nsec3param.salt = nsec3chain->salt;
2192 nsec3chain->seen_nsec = ISC_FALSE;
2193 nsec3chain->delete_nsec = ISC_FALSE;
2194 nsec3chain->save_delete_nsec = ISC_FALSE;
2196 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2198 current = ISC_LIST_NEXT(current, link)) {
2199 if (current->db == zone->db &&
2200 current->nsec3param.hash == nsec3param->hash &&
2201 current->nsec3param.iterations == nsec3param->iterations &&
2202 current->nsec3param.salt_length == nsec3param->salt_length
2203 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2204 nsec3param->salt_length))
2205 current->done = ISC_TRUE;
2208 if (zone->db != NULL) {
2209 dns_db_attach(zone->db, &nsec3chain->db);
2210 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2211 options = DNS_DB_NONSEC3;
2212 result = dns_db_createiterator(nsec3chain->db, options,
2213 &nsec3chain->dbiterator);
2214 if (result == ISC_R_SUCCESS)
2215 dns_dbiterator_first(nsec3chain->dbiterator);
2216 if (result == ISC_R_SUCCESS) {
2217 dns_dbiterator_pause(nsec3chain->dbiterator);
2218 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2221 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2223 zone->nsec3chaintime = now;
2224 if (zone->task != NULL)
2225 zone_settimer(zone, &now);
2229 result = ISC_R_NOTFOUND;
2231 if (nsec3chain != NULL) {
2232 if (nsec3chain->db != NULL)
2233 dns_db_detach(&nsec3chain->db);
2234 if (nsec3chain->dbiterator != NULL)
2235 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2236 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2242 resume_addnsec3chain(dns_zone_t *zone) {
2243 dns_dbnode_t *node = NULL;
2244 dns_dbversion_t *version = NULL;
2245 dns_rdata_t rdata = DNS_RDATA_INIT;
2246 dns_rdataset_t rdataset;
2247 isc_result_t result;
2248 dns_rdata_nsec3param_t nsec3param;
2250 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2251 if (result != ISC_R_SUCCESS)
2254 dns_db_currentversion(zone->db, &version);
2255 dns_rdataset_init(&rdataset);
2256 result = dns_db_findrdataset(zone->db, node, version,
2257 dns_rdatatype_nsec3param,
2258 dns_rdatatype_none, 0,
2260 if (result != ISC_R_SUCCESS)
2263 for (result = dns_rdataset_first(&rdataset);
2264 result == ISC_R_SUCCESS;
2265 result = dns_rdataset_next(&rdataset))
2267 dns_rdataset_current(&rdataset, &rdata);
2268 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2269 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2270 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
2271 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
2272 result = zone_addnsec3chain(zone, &nsec3param);
2273 if (result != ISC_R_SUCCESS) {
2274 dns_zone_log(zone, ISC_LOG_ERROR,
2275 "zone_addnsec3chain failed: %s",
2276 dns_result_totext(result));
2279 dns_rdata_reset(&rdata);
2281 dns_rdataset_disassociate(&rdataset);
2285 dns_db_detachnode(zone->db, &node);
2286 if (version != NULL)
2287 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2291 set_resigntime(dns_zone_t *zone) {
2292 dns_rdataset_t rdataset;
2293 dns_fixedname_t fixed;
2294 char namebuf[DNS_NAME_FORMATSIZE];
2295 unsigned int resign;
2296 isc_result_t result;
2297 isc_uint32_t nanosecs;
2299 dns_rdataset_init(&rdataset);
2300 dns_fixedname_init(&fixed);
2301 result = dns_db_getsigningtime(zone->db, &rdataset,
2302 dns_fixedname_name(&fixed));
2303 if (result != ISC_R_SUCCESS) {
2304 isc_time_settoepoch(&zone->resigntime);
2307 resign = rdataset.resign;
2308 dns_name_format(dns_fixedname_name(&fixed), namebuf, sizeof(namebuf));
2309 dns_rdataset_disassociate(&rdataset);
2310 isc_random_get(&nanosecs);
2311 nanosecs %= 1000000000;
2312 isc_time_set(&zone->resigntime, resign, nanosecs);
2316 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2317 dns_dbnode_t *node = NULL;
2318 dns_rdataset_t rdataset;
2319 dns_dbversion_t *version = NULL;
2320 dns_rdata_nsec3param_t nsec3param;
2321 isc_boolean_t ok = ISC_FALSE;
2322 isc_result_t result;
2323 dns_rdata_t rdata = DNS_RDATA_INIT;
2324 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
2325 zone_isdynamic(zone) : ISC_FALSE;
2327 dns_rdataset_init(&rdataset);
2328 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2329 if (result != ISC_R_SUCCESS) {
2330 dns_zone_log(zone, ISC_LOG_ERROR,
2331 "nsec3param lookup failure: %s",
2332 dns_result_totext(result));
2335 dns_db_currentversion(db, &version);
2337 result = dns_db_findrdataset(db, node, version,
2338 dns_rdatatype_nsec3param,
2339 dns_rdatatype_none, 0, &rdataset, NULL);
2340 if (result == ISC_R_NOTFOUND) {
2341 result = ISC_R_SUCCESS;
2344 if (result != ISC_R_SUCCESS) {
2345 dns_zone_log(zone, ISC_LOG_ERROR,
2346 "nsec3param lookup failure: %s",
2347 dns_result_totext(result));
2352 * For dynamic zones we must support every algorithm so we can
2353 * regenerate all the NSEC3 chains.
2354 * For non-dynamic zones we only need to find a supported algorithm.
2356 for (result = dns_rdataset_first(&rdataset);
2357 result == ISC_R_SUCCESS;
2358 result = dns_rdataset_next(&rdataset))
2360 dns_rdataset_current(&rdataset, &rdata);
2361 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2362 dns_rdata_reset(&rdata);
2363 INSIST(result == ISC_R_SUCCESS);
2364 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
2365 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
2367 dns_zone_log(zone, ISC_LOG_WARNING,
2368 "nsec3 test \"unknown\" hash algorithm found: %u",
2371 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
2373 dns_zone_log(zone, ISC_LOG_ERROR,
2374 "unsupported nsec3 hash algorithm"
2375 " in dynamic zone: %u",
2377 result = DNS_R_BADZONE;
2378 /* Stop second error message. */
2382 dns_zone_log(zone, ISC_LOG_WARNING,
2383 "unsupported nsec3 hash algorithm: %u",
2388 if (result == ISC_R_NOMORE)
2389 result = ISC_R_SUCCESS;
2392 result = DNS_R_BADZONE;
2393 dns_zone_log(zone, ISC_LOG_ERROR,
2394 "no supported nsec3 hash algorithm");
2398 if (dns_rdataset_isassociated(&rdataset))
2399 dns_rdataset_disassociate(&rdataset);
2400 dns_db_closeversion(db, &version, ISC_FALSE);
2401 dns_db_detachnode(db, &node);
2406 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
2407 isc_result_t result)
2409 unsigned int soacount = 0;
2410 unsigned int nscount = 0;
2411 unsigned int errors = 0;
2412 isc_uint32_t serial, refresh, retry, expire, minimum;
2414 isc_boolean_t needdump = ISC_FALSE;
2415 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2416 unsigned int options;
2421 * Initiate zone transfer? We may need a error code that
2422 * indicates that the "permanent" form does not exist.
2423 * XXX better error feedback to log.
2425 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
2426 if (zone->type == dns_zone_slave ||
2427 zone->type == dns_zone_stub) {
2428 if (result == ISC_R_FILENOTFOUND)
2429 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2431 else if (result != DNS_R_NOMASTERFILE)
2432 dns_zone_log(zone, ISC_LOG_ERROR,
2433 "loading from master file %s "
2436 dns_result_totext(result));
2438 dns_zone_log(zone, ISC_LOG_ERROR,
2439 "loading from master file %s failed: %s",
2441 dns_result_totext(result));
2445 dns_zone_log(zone, ISC_LOG_DEBUG(2),
2446 "number of nodes in database: %u",
2447 dns_db_nodecount(db));
2449 if (result == DNS_R_SEENINCLUDE)
2450 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2452 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
2455 * Apply update log, if any, on initial load.
2457 if (zone->journal != NULL &&
2458 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
2459 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
2461 if (zone->type == dns_zone_master &&
2462 (zone->update_acl != NULL || zone->ssutable != NULL))
2463 options = DNS_JOURNALOPT_RESIGN;
2466 result = dns_journal_rollforward(zone->mctx, db, options,
2468 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
2469 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
2470 result != ISC_R_RANGE) {
2471 dns_zone_log(zone, ISC_LOG_ERROR,
2472 "journal rollforward failed: %s",
2473 dns_result_totext(result));
2476 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
2477 dns_zone_log(zone, ISC_LOG_ERROR,
2478 "journal rollforward failed: "
2479 "journal out of sync with zone");
2482 dns_zone_log(zone, ISC_LOG_DEBUG(1),
2483 "journal rollforward completed "
2485 dns_result_totext(result));
2486 if (result == ISC_R_SUCCESS)
2487 needdump = ISC_TRUE;
2490 zone->loadtime = loadtime;
2492 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded");
2494 * Obtain ns, soa and cname counts for top of zone.
2497 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
2498 &refresh, &retry, &expire, &minimum,
2500 if (result != ISC_R_SUCCESS) {
2501 dns_zone_log(zone, ISC_LOG_ERROR,
2502 "could not find NS and/or SOA records");
2506 * Master / Slave / Stub zones require both NS and SOA records at
2507 * the top of the zone.
2510 switch (zone->type) {
2511 case dns_zone_master:
2512 case dns_zone_slave:
2514 if (soacount != 1) {
2515 dns_zone_log(zone, ISC_LOG_ERROR,
2516 "has %d SOA records", soacount);
2517 result = DNS_R_BADZONE;
2520 dns_zone_log(zone, ISC_LOG_ERROR,
2521 "has no NS records");
2522 result = DNS_R_BADZONE;
2524 if (result != ISC_R_SUCCESS)
2526 if (zone->type == dns_zone_master && errors != 0) {
2527 result = DNS_R_BADZONE;
2530 if (zone->type != dns_zone_stub) {
2531 result = check_nsec3param(zone, db);
2532 if (result != ISC_R_SUCCESS)
2535 if (zone->type == dns_zone_master &&
2536 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
2537 !integrity_checks(zone, db)) {
2538 result = DNS_R_BADZONE;
2542 if (zone->db != NULL) {
2544 * This is checked in zone_replacedb() for slave zones
2545 * as they don't reload from disk.
2547 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
2548 !isc_serial_gt(serial, zone->serial)) {
2549 isc_uint32_t serialmin, serialmax;
2551 INSIST(zone->type == dns_zone_master);
2553 serialmin = (zone->serial + 1) & 0xffffffffU;
2554 serialmax = (zone->serial + 0x7fffffffU) &
2556 dns_zone_log(zone, ISC_LOG_ERROR,
2557 "ixfr-from-differences: "
2558 "new serial (%u) out of range "
2559 "[%u - %u]", serial, serialmin,
2561 result = DNS_R_BADZONE;
2563 } else if (!isc_serial_ge(serial, zone->serial))
2564 dns_zone_log(zone, ISC_LOG_ERROR,
2565 "zone serial has gone backwards");
2566 else if (serial == zone->serial && !hasinclude)
2567 dns_zone_log(zone, ISC_LOG_ERROR,
2568 "zone serial unchanged. "
2569 "zone may fail to transfer "
2573 if (zone->type == dns_zone_master &&
2574 (zone->update_acl != NULL || zone->ssutable != NULL) &&
2575 zone->sigresigninginterval < (3 * refresh) &&
2576 dns_db_issecure(db))
2578 dns_zone_log(zone, ISC_LOG_WARNING,
2579 "sig-re-signing-interval less than "
2583 zone->serial = serial;
2584 zone->refresh = RANGE(refresh,
2585 zone->minrefresh, zone->maxrefresh);
2586 zone->retry = RANGE(retry,
2587 zone->minretry, zone->maxretry);
2588 zone->expire = RANGE(expire, zone->refresh + zone->retry,
2590 zone->minimum = minimum;
2591 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
2593 if (zone->type == dns_zone_slave ||
2594 zone->type == dns_zone_stub) {
2598 result = isc_file_getmodtime(zone->journal, &t);
2599 if (result != ISC_R_SUCCESS)
2600 result = isc_file_getmodtime(zone->masterfile,
2602 if (result == ISC_R_SUCCESS)
2603 DNS_ZONE_TIME_ADD(&t, zone->expire,
2606 DNS_ZONE_TIME_ADD(&now, zone->retry,
2609 delay = isc_random_jitter(zone->retry,
2610 (zone->retry * 3) / 4);
2611 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
2612 if (isc_time_compare(&zone->refreshtime,
2613 &zone->expiretime) >= 0)
2614 zone->refreshtime = now;
2618 UNEXPECTED_ERROR(__FILE__, __LINE__,
2619 "unexpected zone type %d", zone->type);
2620 result = ISC_R_UNEXPECTED;
2625 * Check for weak DNSKEY's.
2627 if (zone->type == dns_zone_master)
2628 zone_check_dnskeys(zone, db);
2631 /* destroy notification example. */
2633 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
2634 DNS_EVENT_DBDESTROYED,
2635 dns_zonemgr_dbdestroyed,
2637 sizeof(isc_event_t));
2638 dns_db_ondestroy(db, zone->task, &e);
2642 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2643 if (zone->db != NULL) {
2644 result = zone_replacedb(zone, db, ISC_FALSE);
2645 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2646 if (result != ISC_R_SUCCESS)
2649 zone_attachdb(zone, db);
2650 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2651 DNS_ZONE_SETFLAG(zone,
2652 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
2654 result = ISC_R_SUCCESS;
2656 zone_needdump(zone, DNS_DUMP_DELAY);
2657 if (zone->task != NULL) {
2658 if (zone->type == dns_zone_master) {
2659 set_resigntime(zone);
2660 resume_signingwithkey(zone);
2661 resume_addnsec3chain(zone);
2663 zone_settimer(zone, &now);
2666 if (! dns_db_ispersistent(db))
2667 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s",
2669 dns_db_issecure(db) ? " (signed)" : "");
2674 if (zone->type == dns_zone_slave ||
2675 zone->type == dns_zone_stub) {
2676 if (zone->journal != NULL)
2677 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
2678 if (zone->masterfile != NULL)
2679 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
2681 /* Mark the zone for immediate refresh. */
2682 zone->refreshtime = now;
2683 if (zone->task != NULL)
2684 zone_settimer(zone, &now);
2685 result = ISC_R_SUCCESS;
2690 static isc_boolean_t
2691 exit_check(dns_zone_t *zone) {
2693 REQUIRE(LOCKED_ZONE(zone));
2695 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
2699 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2701 INSIST(isc_refcount_current(&zone->erefs) == 0);
2707 static isc_boolean_t
2708 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
2709 isc_result_t result;
2710 char namebuf[DNS_NAME_FORMATSIZE];
2711 char altbuf[DNS_NAME_FORMATSIZE];
2712 dns_fixedname_t fixed;
2713 dns_name_t *foundname;
2716 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
2719 if (zone->type == dns_zone_master)
2720 level = ISC_LOG_ERROR;
2722 level = ISC_LOG_WARNING;
2724 dns_fixedname_init(&fixed);
2725 foundname = dns_fixedname_name(&fixed);
2727 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2728 0, 0, NULL, foundname, NULL, NULL);
2729 if (result == ISC_R_SUCCESS)
2732 if (result == DNS_R_NXRRSET) {
2733 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2734 0, 0, NULL, foundname, NULL, NULL);
2735 if (result == ISC_R_SUCCESS)
2739 dns_name_format(name, namebuf, sizeof namebuf);
2740 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2741 result == DNS_R_EMPTYNAME) {
2742 dns_zone_log(zone, level,
2743 "NS '%s' has no address records (A or AAAA)",
2745 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2749 if (result == DNS_R_CNAME) {
2750 dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
2752 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2756 if (result == DNS_R_DNAME) {
2757 dns_name_format(foundname, altbuf, sizeof altbuf);
2758 dns_zone_log(zone, level,
2759 "NS '%s' is below a DNAME '%s' (illegal)",
2761 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2769 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
2770 dns_dbversion_t *version, unsigned int *nscount,
2771 unsigned int *errors)
2773 isc_result_t result;
2774 unsigned int count = 0;
2775 unsigned int ecount = 0;
2776 dns_rdataset_t rdataset;
2780 dns_rdataset_init(&rdataset);
2781 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
2782 dns_rdatatype_none, 0, &rdataset, NULL);
2783 if (result == ISC_R_NOTFOUND)
2785 if (result != ISC_R_SUCCESS)
2786 goto invalidate_rdataset;
2788 result = dns_rdataset_first(&rdataset);
2789 while (result == ISC_R_SUCCESS) {
2790 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
2791 (zone->type == dns_zone_master ||
2792 zone->type == dns_zone_slave)) {
2793 dns_rdata_init(&rdata);
2794 dns_rdataset_current(&rdataset, &rdata);
2795 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2796 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2797 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
2798 !zone_check_ns(zone, db, &ns.name))
2802 result = dns_rdataset_next(&rdataset);
2804 dns_rdataset_disassociate(&rdataset);
2807 if (nscount != NULL)
2812 result = ISC_R_SUCCESS;
2814 invalidate_rdataset:
2815 dns_rdataset_invalidate(&rdataset);
2821 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
2822 unsigned int *soacount,
2823 isc_uint32_t *serial, isc_uint32_t *refresh,
2824 isc_uint32_t *retry, isc_uint32_t *expire,
2825 isc_uint32_t *minimum)
2827 isc_result_t result;
2829 dns_rdataset_t rdataset;
2830 dns_rdata_t rdata = DNS_RDATA_INIT;
2831 dns_rdata_soa_t soa;
2833 dns_rdataset_init(&rdataset);
2834 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
2835 dns_rdatatype_none, 0, &rdataset, NULL);
2836 if (result == ISC_R_NOTFOUND) {
2837 if (soacount != NULL)
2841 if (refresh != NULL)
2847 if (minimum != NULL)
2849 result = ISC_R_SUCCESS;
2850 goto invalidate_rdataset;
2852 if (result != ISC_R_SUCCESS)
2853 goto invalidate_rdataset;
2856 result = dns_rdataset_first(&rdataset);
2857 while (result == ISC_R_SUCCESS) {
2858 dns_rdata_init(&rdata);
2859 dns_rdataset_current(&rdataset, &rdata);
2862 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2863 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2866 result = dns_rdataset_next(&rdataset);
2867 dns_rdata_reset(&rdata);
2869 dns_rdataset_disassociate(&rdataset);
2871 if (soacount != NULL)
2876 *serial = soa.serial;
2877 if (refresh != NULL)
2878 *refresh = soa.refresh;
2882 *expire = soa.expire;
2883 if (minimum != NULL)
2884 *minimum = soa.minimum;
2887 result = ISC_R_SUCCESS;
2889 invalidate_rdataset:
2890 dns_rdataset_invalidate(&rdataset);
2896 * zone must be locked.
2899 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
2900 unsigned int *soacount, isc_uint32_t *serial,
2901 isc_uint32_t *refresh, isc_uint32_t *retry,
2902 isc_uint32_t *expire, isc_uint32_t *minimum,
2903 unsigned int *errors)
2905 dns_dbversion_t *version;
2906 isc_result_t result;
2907 isc_result_t answer = ISC_R_SUCCESS;
2910 REQUIRE(db != NULL);
2911 REQUIRE(zone != NULL);
2914 dns_db_currentversion(db, &version);
2917 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2918 if (result != ISC_R_SUCCESS) {
2923 if (nscount != NULL || errors != NULL) {
2924 result = zone_count_ns_rr(zone, db, node, version,
2926 if (result != ISC_R_SUCCESS)
2930 if (soacount != NULL || serial != NULL || refresh != NULL
2931 || retry != NULL || expire != NULL || minimum != NULL) {
2932 result = zone_load_soa_rr(db, node, version, soacount,
2933 serial, refresh, retry, expire,
2935 if (result != ISC_R_SUCCESS)
2939 dns_db_detachnode(db, &node);
2941 dns_db_closeversion(db, &version, ISC_FALSE);
2947 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
2948 REQUIRE(DNS_ZONE_VALID(source));
2949 REQUIRE(target != NULL && *target == NULL);
2950 isc_refcount_increment(&source->erefs, NULL);
2955 dns_zone_detach(dns_zone_t **zonep) {
2958 isc_boolean_t free_now = ISC_FALSE;
2960 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2964 isc_refcount_decrement(&zone->erefs, &refs);
2969 * We just detached the last external reference.
2971 if (zone->task != NULL) {
2973 * This zone is being managed. Post
2974 * its control event and let it clean
2975 * up synchronously in the context of
2978 isc_event_t *ev = &zone->ctlevent;
2979 isc_task_send(zone->task, &ev);
2982 * This zone is not being managed; it has
2983 * no task and can have no outstanding
2984 * events. Free it immediately.
2987 * Unmanaged zones should not have non-null views;
2988 * we have no way of detaching from the view here
2989 * without causing deadlock because this code is called
2990 * with the view already locked.
2992 INSIST(zone->view == NULL);
2993 free_now = ISC_TRUE;
3003 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3004 REQUIRE(DNS_ZONE_VALID(source));
3005 REQUIRE(target != NULL && *target == NULL);
3007 zone_iattach(source, target);
3008 UNLOCK_ZONE(source);
3012 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3015 * 'source' locked by caller.
3017 REQUIRE(LOCKED_ZONE(source));
3018 REQUIRE(DNS_ZONE_VALID(source));
3019 REQUIRE(target != NULL && *target == NULL);
3020 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
3022 INSIST(source->irefs != 0);
3027 zone_idetach(dns_zone_t **zonep) {
3031 * 'zone' locked by caller.
3033 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3035 REQUIRE(LOCKED_ZONE(*zonep));
3038 INSIST(zone->irefs > 0);
3040 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
3044 dns_zone_idetach(dns_zone_t **zonep) {
3046 isc_boolean_t free_needed;
3048 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3053 INSIST(zone->irefs > 0);
3055 free_needed = exit_check(zone);
3062 dns_zone_getmctx(dns_zone_t *zone) {
3063 REQUIRE(DNS_ZONE_VALID(zone));
3065 return (zone->mctx);
3069 dns_zone_getmgr(dns_zone_t *zone) {
3070 REQUIRE(DNS_ZONE_VALID(zone));
3072 return (zone->zmgr);
3076 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
3077 REQUIRE(DNS_ZONE_VALID(zone));
3081 DNS_ZONE_SETFLAG(zone, flags);
3083 DNS_ZONE_CLRFLAG(zone, flags);
3088 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
3090 REQUIRE(DNS_ZONE_VALID(zone));
3094 zone->options |= option;
3096 zone->options &= ~option;
3101 dns_zone_getoptions(dns_zone_t *zone) {
3103 REQUIRE(DNS_ZONE_VALID(zone));
3105 return (zone->options);
3109 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3110 REQUIRE(DNS_ZONE_VALID(zone));
3113 zone->xfrsource4 = *xfrsource;
3116 return (ISC_R_SUCCESS);
3120 dns_zone_getxfrsource4(dns_zone_t *zone) {
3121 REQUIRE(DNS_ZONE_VALID(zone));
3122 return (&zone->xfrsource4);
3126 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
3127 REQUIRE(DNS_ZONE_VALID(zone));
3130 zone->xfrsource6 = *xfrsource;
3133 return (ISC_R_SUCCESS);
3137 dns_zone_getxfrsource6(dns_zone_t *zone) {
3138 REQUIRE(DNS_ZONE_VALID(zone));
3139 return (&zone->xfrsource6);
3143 dns_zone_setaltxfrsource4(dns_zone_t *zone,
3144 const isc_sockaddr_t *altxfrsource)
3146 REQUIRE(DNS_ZONE_VALID(zone));
3149 zone->altxfrsource4 = *altxfrsource;
3152 return (ISC_R_SUCCESS);
3156 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
3157 REQUIRE(DNS_ZONE_VALID(zone));
3158 return (&zone->altxfrsource4);
3162 dns_zone_setaltxfrsource6(dns_zone_t *zone,
3163 const isc_sockaddr_t *altxfrsource)
3165 REQUIRE(DNS_ZONE_VALID(zone));
3168 zone->altxfrsource6 = *altxfrsource;
3171 return (ISC_R_SUCCESS);
3175 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
3176 REQUIRE(DNS_ZONE_VALID(zone));
3177 return (&zone->altxfrsource6);
3181 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3182 REQUIRE(DNS_ZONE_VALID(zone));
3185 zone->notifysrc4 = *notifysrc;
3188 return (ISC_R_SUCCESS);
3192 dns_zone_getnotifysrc4(dns_zone_t *zone) {
3193 REQUIRE(DNS_ZONE_VALID(zone));
3194 return (&zone->notifysrc4);
3198 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
3199 REQUIRE(DNS_ZONE_VALID(zone));
3202 zone->notifysrc6 = *notifysrc;
3205 return (ISC_R_SUCCESS);
3209 dns_zone_getnotifysrc6(dns_zone_t *zone) {
3210 REQUIRE(DNS_ZONE_VALID(zone));
3211 return (&zone->notifysrc6);
3215 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
3218 isc_sockaddr_t *new;
3220 REQUIRE(DNS_ZONE_VALID(zone));
3221 REQUIRE(count == 0 || notify != NULL);
3224 if (zone->notify != NULL) {
3225 isc_mem_put(zone->mctx, zone->notify,
3226 zone->notifycnt * sizeof(*new));
3227 zone->notify = NULL;
3228 zone->notifycnt = 0;
3231 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3234 return (ISC_R_NOMEMORY);
3236 memcpy(new, notify, count * sizeof(*new));
3238 zone->notifycnt = count;
3241 return (ISC_R_SUCCESS);
3245 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
3248 isc_result_t result;
3250 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
3254 static isc_boolean_t
3255 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
3260 for (i = 0; i < count; i++)
3261 if (!isc_sockaddr_equal(&old[i], &new[i]))
3266 static isc_boolean_t
3267 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
3270 if (old == NULL && new == NULL)
3272 if (old == NULL || new == NULL)
3275 for (i = 0; i < count; i++) {
3276 if (old[i] == NULL && new[i] == NULL)
3278 if (old[i] == NULL || new[i] == NULL ||
3279 !dns_name_equal(old[i], new[i]))
3286 dns_zone_setmasterswithkeys(dns_zone_t *zone,
3287 const isc_sockaddr_t *masters,
3288 dns_name_t **keynames,
3291 isc_sockaddr_t *new;
3292 isc_result_t result = ISC_R_SUCCESS;
3293 dns_name_t **newname;
3294 isc_boolean_t *newok;
3297 REQUIRE(DNS_ZONE_VALID(zone));
3298 REQUIRE(count == 0 || masters != NULL);
3299 if (keynames != NULL) {
3300 REQUIRE(count != 0);
3305 * The refresh code assumes that 'masters' wouldn't change under it.
3306 * If it will change then kill off any current refresh in progress
3307 * and update the masters info. If it won't change then we can just
3310 if (count != zone->masterscnt ||
3311 !same_masters(zone->masters, masters, count) ||
3312 !same_keynames(zone->masterkeynames, keynames, count)) {
3313 if (zone->request != NULL)
3314 dns_request_cancel(zone->request);
3317 if (zone->masters != NULL) {
3318 isc_mem_put(zone->mctx, zone->masters,
3319 zone->masterscnt * sizeof(*new));
3320 zone->masters = NULL;
3322 if (zone->masterkeynames != NULL) {
3323 for (i = 0; i < zone->masterscnt; i++) {
3324 if (zone->masterkeynames[i] != NULL) {
3325 dns_name_free(zone->masterkeynames[i],
3327 isc_mem_put(zone->mctx,
3328 zone->masterkeynames[i],
3329 sizeof(dns_name_t));
3330 zone->masterkeynames[i] = NULL;
3333 isc_mem_put(zone->mctx, zone->masterkeynames,
3334 zone->masterscnt * sizeof(dns_name_t *));
3335 zone->masterkeynames = NULL;
3337 if (zone->mastersok != NULL) {
3338 isc_mem_put(zone->mctx, zone->mastersok,
3339 zone->masterscnt * sizeof(isc_boolean_t));
3340 zone->mastersok = NULL;
3342 zone->masterscnt = 0;
3344 * If count == 0, don't allocate any space for masters, mastersok or
3345 * keynames so internally, those pointers are NULL if count == 0
3351 * masters must contain count elements!
3353 new = isc_mem_get(zone->mctx, count * sizeof(*new));
3355 result = ISC_R_NOMEMORY;
3358 memcpy(new, masters, count * sizeof(*new));
3361 * Similarly for mastersok.
3363 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
3364 if (newok == NULL) {
3365 result = ISC_R_NOMEMORY;
3366 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3369 for (i = 0; i < count; i++)
3370 newok[i] = ISC_FALSE;
3373 * if keynames is non-NULL, it must contain count elements!
3376 if (keynames != NULL) {
3377 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
3378 if (newname == NULL) {
3379 result = ISC_R_NOMEMORY;
3380 isc_mem_put(zone->mctx, new, count * sizeof(*new));
3381 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
3384 for (i = 0; i < count; i++)
3386 for (i = 0; i < count; i++) {
3387 if (keynames[i] != NULL) {
3388 newname[i] = isc_mem_get(zone->mctx,
3389 sizeof(dns_name_t));
3390 if (newname[i] == NULL)
3392 dns_name_init(newname[i], NULL);
3393 result = dns_name_dup(keynames[i], zone->mctx,
3395 if (result != ISC_R_SUCCESS) {
3397 for (i = 0; i < count; i++)
3398 if (newname[i] != NULL)
3402 isc_mem_put(zone->mctx, new,
3403 count * sizeof(*new));
3404 isc_mem_put(zone->mctx, newok,
3405 count * sizeof(*newok));
3406 isc_mem_put(zone->mctx, newname,
3407 count * sizeof(*newname));
3415 * Everything is ok so attach to the zone.
3417 zone->masters = new;
3418 zone->mastersok = newok;
3419 zone->masterkeynames = newname;
3420 zone->masterscnt = count;
3421 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
3429 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
3430 isc_result_t result = ISC_R_SUCCESS;
3432 REQUIRE(DNS_ZONE_VALID(zone));
3434 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3435 if (zone->db == NULL)
3436 result = DNS_R_NOTLOADED;
3438 dns_db_attach(zone->db, dpb);
3439 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3445 * Co-ordinates the starting of routine jobs.
3449 dns_zone_maintenance(dns_zone_t *zone) {
3450 const char me[] = "dns_zone_maintenance";
3453 REQUIRE(DNS_ZONE_VALID(zone));
3458 zone_settimer(zone, &now);
3462 static inline isc_boolean_t
3463 was_dumping(dns_zone_t *zone) {
3464 isc_boolean_t dumping;
3466 REQUIRE(LOCKED_ZONE(zone));
3468 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
3469 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3471 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3472 isc_time_settoepoch(&zone->dumptime);
3477 #define MAXZONEKEYS 10
3480 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3483 dns_diff_t temp_diff;
3484 isc_result_t result;
3487 * Create a singleton diff.
3489 dns_diff_init(diff->mctx, &temp_diff);
3490 temp_diff.resign = diff->resign;
3491 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3494 * Apply it to the database.
3496 result = dns_diff_apply(&temp_diff, db, ver);
3497 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3498 if (result != ISC_R_SUCCESS) {
3499 dns_difftuple_free(tuple);
3504 * Merge it into the current pending journal entry.
3506 dns_diff_appendminimal(diff, tuple);
3509 * Do not clear temp_diff.
3511 return (ISC_R_SUCCESS);
3515 increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
3516 dns_diff_t *diff, isc_mem_t *mctx)
3518 dns_difftuple_t *deltuple = NULL;
3519 dns_difftuple_t *addtuple = NULL;
3520 isc_uint32_t serial;
3521 isc_result_t result;
3523 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3524 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3525 addtuple->op = DNS_DIFFOP_ADD;
3527 serial = dns_soa_getserial(&addtuple->rdata);
3530 serial = (serial + 1) & 0xFFFFFFFF;
3534 dns_soa_setserial(serial, &addtuple->rdata);
3535 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3536 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3537 result = ISC_R_SUCCESS;
3540 if (addtuple != NULL)
3541 dns_difftuple_free(&addtuple);
3542 if (deltuple != NULL)
3543 dns_difftuple_free(&deltuple);
3548 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3549 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3552 dns_difftuple_t *tuple = NULL;
3553 isc_result_t result;
3554 result = dns_difftuple_create(diff->mctx, op,
3555 name, ttl, rdata, &tuple);
3556 if (result != ISC_R_SUCCESS)
3558 return (do_one_tuple(&tuple, db, ver, diff));
3561 static isc_boolean_t
3562 ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) {
3563 isc_boolean_t ret = ISC_FALSE;
3564 isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE;
3565 isc_result_t result;
3566 dns_dbnode_t *node = NULL;
3567 dns_rdataset_t rdataset;
3568 dns_rdata_t rdata = DNS_RDATA_INIT;
3569 dns_rdata_dnskey_t dnskey;
3571 dns_rdataset_init(&rdataset);
3572 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3573 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
3575 CHECK(dns_rdataset_first(&rdataset));
3576 while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) {
3577 dns_rdataset_current(&rdataset, &rdata);
3578 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3579 if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
3580 == DNS_KEYOWNER_ZONE) {
3581 if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0)
3582 have_ksk = ISC_TRUE;
3584 have_nonksk = ISC_TRUE;
3586 dns_rdata_reset(&rdata);
3587 result = dns_rdataset_next(&rdataset);
3589 if (have_ksk && have_nonksk)
3592 if (dns_rdataset_isassociated(&rdataset))
3593 dns_rdataset_disassociate(&rdataset);
3595 dns_db_detachnode(db, &node);
3600 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3601 isc_mem_t *mctx, unsigned int maxkeys,
3602 dst_key_t **keys, unsigned int *nkeys)
3604 isc_result_t result;
3605 dns_dbnode_t *node = NULL;
3606 const char *directory = dns_zone_getkeydirectory(zone);
3607 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
3608 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
3609 directory, mctx, maxkeys, keys,
3611 if (result == ISC_R_NOTFOUND)
3612 result = ISC_R_SUCCESS;
3615 dns_db_detachnode(db, &node);
3620 offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
3621 dns_ttl_t ttl, dns_rdata_t *rdata)
3623 isc_result_t result;
3625 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
3626 return (ISC_R_SUCCESS);
3627 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
3629 if (result != ISC_R_SUCCESS)
3631 rdata->flags |= DNS_RDATA_OFFLINE;
3632 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3638 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
3642 zone->key_expiry = when;
3644 dns_zone_log(zone, ISC_LOG_ERROR,
3645 "DNSKEY RRSIG(s) have expired");
3646 isc_time_settoepoch(&zone->keywarntime);
3647 } else if (when < now + 7 * 24 * 3600) {
3648 dns_zone_log(zone, ISC_LOG_WARNING,
3649 "DNSKEY RRSIG(s) will expire at %u",
3650 when); /* XXXMPA convert to date. */
3652 delta--; /* loop prevention */
3653 delta /= 24 * 3600; /* to whole days */
3654 delta *= 24 * 3600; /* to seconds */
3655 isc_time_set(&zone->keywarntime, when - delta, 0);
3657 dns_zone_log(zone, ISC_LOG_NOTICE, /* XXMPA ISC_LOG_DEBUG(1) */
3658 "setting keywarntime to %u - 7 days",
3659 when); /* XXXMPA convert to date. */
3660 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
3665 * Delete expired RRsigs and any RRsigs we are about to re-sign.
3666 * See also update.c:del_keysigs().
3669 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3670 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3671 unsigned int nkeys, isc_stdtime_t now)
3673 isc_result_t result;
3674 dns_dbnode_t *node = NULL;
3675 dns_rdataset_t rdataset;
3676 dns_rdata_t rdata = DNS_RDATA_INIT;
3678 dns_rdata_rrsig_t rrsig;
3679 isc_boolean_t found;
3680 isc_stdtime_t warn = 0, maybe = 0;
3682 dns_rdataset_init(&rdataset);
3684 if (type == dns_rdatatype_nsec3)
3685 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3687 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3688 if (result == ISC_R_NOTFOUND)
3689 return (ISC_R_SUCCESS);
3690 if (result != ISC_R_SUCCESS)
3692 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
3693 (isc_stdtime_t) 0, &rdataset, NULL);
3694 dns_db_detachnode(db, &node);
3696 if (result == ISC_R_NOTFOUND)
3697 return (ISC_R_SUCCESS);
3698 if (result != ISC_R_SUCCESS)
3701 for (result = dns_rdataset_first(&rdataset);
3702 result == ISC_R_SUCCESS;
3703 result = dns_rdataset_next(&rdataset)) {
3704 dns_rdataset_current(&rdataset, &rdata);
3705 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
3706 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3708 if (type != dns_rdatatype_dnskey) {
3709 result = update_one_rr(db, ver, diff,
3710 DNS_DIFFOP_DEL, name,
3711 rdataset.ttl, &rdata);
3712 dns_rdata_reset(&rdata);
3713 if (result != ISC_R_SUCCESS)
3719 * RRSIG(DNSKEY) requires special processing.
3722 for (i = 0; i < nkeys; i++) {
3723 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
3724 rrsig.keyid == dst_key_id(keys[i])) {
3727 * Mark offline RRSIG(DNSKEY).
3728 * We want the earliest offline expire time
3729 * iff there is a new offline signature.
3731 if (!dst_key_isprivate(keys[i])) {
3733 warn > rrsig.timeexpire)
3734 warn = rrsig.timeexpire;
3735 if (rdata.flags & DNS_RDATA_OFFLINE) {
3737 maybe > rrsig.timeexpire)
3745 warn > rrsig.timeexpire)
3746 warn = rrsig.timeexpire;
3747 result = offline(db, ver, diff, name,
3748 rdataset.ttl, &rdata);
3751 result = update_one_rr(db, ver, diff,
3759 * If there is not a matching DNSKEY then
3763 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3764 name, rdataset.ttl, &rdata);
3765 dns_rdata_reset(&rdata);
3766 if (result != ISC_R_SUCCESS)
3769 dns_rdataset_disassociate(&rdataset);
3770 if (result == ISC_R_NOMORE)
3771 result = ISC_R_SUCCESS;
3773 set_key_expiry_warning(zone, warn, now);
3776 dns_db_detachnode(db, &node);
3781 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
3782 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
3783 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
3784 isc_stdtime_t expire, isc_boolean_t check_ksk)
3786 isc_result_t result;
3787 dns_dbnode_t *node = NULL;
3788 dns_rdataset_t rdataset;
3789 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
3790 unsigned char data[1024]; /* XXX */
3791 isc_buffer_t buffer;
3794 dns_rdataset_init(&rdataset);
3795 isc_buffer_init(&buffer, data, sizeof(data));
3797 if (type == dns_rdatatype_nsec3)
3798 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
3800 result = dns_db_findnode(db, name, ISC_FALSE, &node);
3801 if (result == ISC_R_NOTFOUND)
3802 return (ISC_R_SUCCESS);
3803 if (result != ISC_R_SUCCESS)
3805 result = dns_db_findrdataset(db, node, ver, type, 0,
3806 (isc_stdtime_t) 0, &rdataset, NULL);
3807 dns_db_detachnode(db, &node);
3808 if (result == ISC_R_NOTFOUND)
3809 return (ISC_R_SUCCESS);
3810 if (result != ISC_R_SUCCESS)
3813 for (i = 0; i < nkeys; i++) {
3814 if (check_ksk && type != dns_rdatatype_dnskey &&
3815 (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0)
3817 if (!dst_key_isprivate(keys[i]))
3819 /* Calculate the signature, creating a RRSIG RDATA. */
3820 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
3821 &inception, &expire,
3822 mctx, &buffer, &sig_rdata));
3823 /* Update the database and journal with the RRSIG. */
3824 /* XXX inefficient - will cause dataset merging */
3825 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
3826 name, rdataset.ttl, &sig_rdata));
3827 dns_rdata_reset(&sig_rdata);
3831 if (dns_rdataset_isassociated(&rdataset))
3832 dns_rdataset_disassociate(&rdataset);
3834 dns_db_detachnode(db, &node);
3839 zone_resigninc(dns_zone_t *zone) {
3840 const char *journalfile;
3841 dns_db_t *db = NULL;
3842 dns_dbversion_t *version = NULL;
3843 dns_diff_t sig_diff;
3844 dns_fixedname_t fixed;
3846 dns_rdataset_t rdataset;
3847 dns_rdatatype_t covers;
3848 dst_key_t *zone_keys[MAXZONEKEYS];
3849 isc_boolean_t check_ksk;
3850 isc_result_t result;
3851 isc_stdtime_t now, inception, soaexpire, expire, stop;
3852 isc_uint32_t jitter;
3854 unsigned int nkeys = 0;
3855 unsigned int resign;
3857 dns_rdataset_init(&rdataset);
3858 dns_fixedname_init(&fixed);
3859 dns_diff_init(zone->mctx, &sig_diff);
3860 sig_diff.resign = zone->sigresigninginterval;
3863 * Updates are disabled. Pause for 5 minutes.
3865 if (zone->update_disabled) {
3866 result = ISC_R_FAILURE;
3870 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3871 dns_db_attach(zone->db, &db);
3872 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3874 result = dns_db_newversion(db, &version);
3875 if (result != ISC_R_SUCCESS) {
3876 dns_zone_log(zone, ISC_LOG_ERROR,
3877 "zone_resigninc:dns_db_newversion -> %s\n",
3878 dns_result_totext(result));
3882 result = find_zone_keys(zone, db, version, zone->mctx, MAXZONEKEYS,
3884 if (result != ISC_R_SUCCESS) {
3885 dns_zone_log(zone, ISC_LOG_ERROR,
3886 "zone_resigninc:find_zone_keys -> %s\n",
3887 dns_result_totext(result));
3891 isc_stdtime_get(&now);
3892 inception = now - 3600; /* Allow for clock skew. */
3893 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
3895 * Spread out signatures over time if they happen to be
3896 * clumped. We don't do this for each add_sigs() call as
3897 * we still want some clustering to occur.
3899 isc_random_get(&jitter);
3900 expire = soaexpire - jitter % 3600;
3903 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
3905 check_ksk = ksk_sanity(db, version);
3907 name = dns_fixedname_name(&fixed);
3908 result = dns_db_getsigningtime(db, &rdataset, name);
3909 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
3910 dns_zone_log(zone, ISC_LOG_ERROR,
3911 "zone_resigninc:dns_db_getsigningtime -> %s\n",
3912 dns_result_totext(result));
3916 while (result == ISC_R_SUCCESS) {
3917 resign = rdataset.resign;
3918 covers = rdataset.covers;
3920 * Stop if we hit the SOA as that means we have walked the
3921 * entire zone. The SOA record should always be the most
3924 /* XXXMPA increase number of RRsets signed pre call */
3925 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
3928 * Ensure that we don't loop resigning the SOA.
3930 if (covers == dns_rdatatype_soa)
3931 dns_db_resigned(db, &rdataset, version);
3932 dns_rdataset_disassociate(&rdataset);
3936 dns_db_resigned(db, &rdataset, version);
3937 dns_rdataset_disassociate(&rdataset);
3939 result = del_sigs(zone, db, version, name, covers, &sig_diff,
3940 zone_keys, nkeys, now);
3941 if (result != ISC_R_SUCCESS) {
3942 dns_zone_log(zone, ISC_LOG_ERROR,
3943 "zone_resigninc:del_sigs -> %s\n",
3944 dns_result_totext(result));
3947 result = add_sigs(db, version, name, covers, &sig_diff,
3948 zone_keys, nkeys, zone->mctx, inception,
3950 if (result != ISC_R_SUCCESS) {
3951 dns_zone_log(zone, ISC_LOG_ERROR,
3952 "zone_resigninc:add_sigs -> %s\n",
3953 dns_result_totext(result));
3956 result = dns_db_getsigningtime(db, &rdataset,
3957 dns_fixedname_name(&fixed));
3958 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
3959 result = ISC_R_SUCCESS;
3962 if (result != ISC_R_SUCCESS)
3963 dns_zone_log(zone, ISC_LOG_ERROR,
3964 "zone_resigninc:dns_db_getsigningtime -> %s\n",
3965 dns_result_totext(result));
3968 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
3971 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
3972 &sig_diff, zone_keys, nkeys, now);
3973 if (result != ISC_R_SUCCESS) {
3974 dns_zone_log(zone, ISC_LOG_ERROR,
3975 "zone_resigninc:del_sigs -> %s\n",
3976 dns_result_totext(result));
3980 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
3981 if (result != ISC_R_SUCCESS) {
3982 dns_zone_log(zone, ISC_LOG_ERROR,
3983 "zone_resigninc:increment_soa_serial -> %s\n",
3984 dns_result_totext(result));
3989 * Generate maximum life time signatures so that the above loop
3990 * termination is sensible.
3992 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
3993 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
3994 soaexpire, check_ksk);
3995 if (result != ISC_R_SUCCESS) {
3996 dns_zone_log(zone, ISC_LOG_ERROR,
3997 "zone_resigninc:add_sigs -> %s\n",
3998 dns_result_totext(result));
4002 journalfile = dns_zone_getjournal(zone);
4003 if (journalfile != NULL) {
4004 dns_journal_t *journal = NULL;
4005 result = dns_journal_open(zone->mctx, journalfile,
4006 ISC_TRUE, &journal);
4007 if (result != ISC_R_SUCCESS) {
4008 dns_zone_log(zone, ISC_LOG_ERROR,
4009 "zone_resigninc:dns_journal_open -> %s\n",
4010 dns_result_totext(result));
4014 result = dns_journal_write_transaction(journal, &sig_diff);
4015 dns_journal_destroy(&journal);
4016 if (result != ISC_R_SUCCESS) {
4017 dns_zone_log(zone, ISC_LOG_ERROR,
4018 "zone_resigninc:dns_journal_write_transaction -> %s\n",
4019 dns_result_totext(result));
4025 * Everything has succeeded. Commit the changes.
4027 dns_db_closeversion(db, &version, ISC_TRUE);
4030 dns_diff_clear(&sig_diff);
4031 for (i = 0; i < nkeys; i++)
4032 dst_key_free(&zone_keys[i]);
4033 if (version != NULL) {
4034 dns_db_closeversion(zone->db, &version, ISC_FALSE);
4036 } else if (db != NULL)
4038 if (result == ISC_R_SUCCESS) {
4039 set_resigntime(zone);
4041 zone_needdump(zone, DNS_DUMP_DELAY);
4042 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
4046 * Something failed. Retry in 5 minutes.
4048 isc_interval_t ival;
4049 isc_interval_set(&ival, 300, 0);
4050 isc_time_nowplusinterval(&zone->resigntime, &ival);
4055 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
4056 dns_name_t *newname, isc_boolean_t bottom)
4058 isc_result_t result;
4059 dns_dbiterator_t *dbit = NULL;
4060 dns_rdatasetiter_t *rdsit = NULL;
4061 dns_dbnode_t *node = NULL;
4063 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
4064 CHECK(dns_dbiterator_seek(dbit, oldname));
4066 result = dns_dbiterator_next(dbit);
4067 if (result == ISC_R_NOMORE)
4068 CHECK(dns_dbiterator_first(dbit));
4069 CHECK(dns_dbiterator_current(dbit, &node, newname));
4070 if (bottom && dns_name_issubdomain(newname, oldname) &&
4071 !dns_name_equal(newname, oldname)) {
4072 dns_db_detachnode(db, &node);
4076 * Is this node empty?
4078 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
4079 result = dns_rdatasetiter_first(rdsit);
4080 dns_db_detachnode(db, &node);
4081 dns_rdatasetiter_destroy(&rdsit);
4082 if (result != ISC_R_NOMORE)
4087 dns_db_detachnode(db, &node);
4089 dns_dbiterator_destroy(&dbit);
4094 set_bit(unsigned char *array, unsigned int index) {
4095 unsigned int shift, mask;
4097 shift = 7 - (index % 8);
4100 array[index / 8] |= mask;
4103 static isc_boolean_t
4104 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4105 dns_rdatatype_t type, dst_key_t *key)
4107 isc_result_t result;
4108 dns_rdataset_t rdataset;
4109 dns_rdata_t rdata = DNS_RDATA_INIT;
4110 dns_rdata_rrsig_t rrsig;
4112 dns_rdataset_init(&rdataset);
4113 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
4114 type, 0, &rdataset, NULL);
4115 if (result != ISC_R_SUCCESS)
4117 for (result = dns_rdataset_first(&rdataset);
4118 result == ISC_R_SUCCESS;
4119 result = dns_rdataset_next(&rdataset)) {
4120 dns_rdataset_current(&rdataset, &rdata);
4121 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
4122 INSIST(result == ISC_R_SUCCESS);
4123 if (rrsig.algorithm == dst_key_alg(key) &&
4124 rrsig.keyid == dst_key_id(key)) {
4125 dns_rdataset_disassociate(&rdataset);
4128 dns_rdata_reset(&rdata);
4130 dns_rdataset_disassociate(&rdataset);
4135 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4136 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
4139 dns_fixedname_t fixed;
4141 dns_rdata_t rdata = DNS_RDATA_INIT;
4142 isc_result_t result;
4143 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4145 dns_fixedname_init(&fixed);
4146 next = dns_fixedname_name(&fixed);
4148 CHECK(next_active(db, version, name, next, bottom));
4149 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
4151 if (dns_name_equal(dns_db_origin(db), name)) {
4153 * Set the OPT bit to indicate that this is a
4154 * partially secure zone.
4156 isc_region_t region;
4158 dns_rdata_toregion(&rdata, ®ion);
4159 dns_name_fromregion(next, ®ion);
4160 isc_region_consume(®ion, next->length);
4161 INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
4162 region.base[0] == 0 &&
4163 region.base[1] > dns_rdatatype_opt / 8);
4164 set_bit(region.base + 2, dns_rdatatype_opt);
4166 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
4173 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
4174 dns_dbversion_t *version, isc_boolean_t build_nsec3,
4175 isc_boolean_t build_nsec, dst_key_t *key,
4176 isc_stdtime_t inception, isc_stdtime_t expire,
4177 unsigned int minimum, isc_boolean_t is_ksk,
4178 isc_boolean_t *delegation, dns_diff_t *diff,
4179 isc_int32_t *signatures, isc_mem_t *mctx)
4181 isc_result_t result;
4182 dns_rdatasetiter_t *iterator = NULL;
4183 dns_rdataset_t rdataset;
4184 dns_rdata_t rdata = DNS_RDATA_INIT;
4185 isc_buffer_t buffer;
4186 unsigned char data[1024];
4187 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
4188 seen_nsec3, seen_ds;
4189 isc_boolean_t bottom;
4191 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4192 if (result != ISC_R_SUCCESS) {
4193 if (result == ISC_R_NOTFOUND)
4194 result = ISC_R_SUCCESS;
4197 dns_rdataset_init(&rdataset);
4198 isc_buffer_init(&buffer, data, sizeof(data));
4199 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
4200 seen_nsec3 = seen_ds = ISC_FALSE;
4201 for (result = dns_rdatasetiter_first(iterator);
4202 result == ISC_R_SUCCESS;
4203 result = dns_rdatasetiter_next(iterator)) {
4204 dns_rdatasetiter_current(iterator, &rdataset);
4205 if (rdataset.type == dns_rdatatype_soa)
4206 seen_soa = ISC_TRUE;
4207 else if (rdataset.type == dns_rdatatype_ns)
4209 else if (rdataset.type == dns_rdatatype_ds)
4211 else if (rdataset.type == dns_rdatatype_dname)
4212 seen_dname = ISC_TRUE;
4213 else if (rdataset.type == dns_rdatatype_nsec)
4214 seen_nsec = ISC_TRUE;
4215 else if (rdataset.type == dns_rdatatype_nsec3)
4216 seen_nsec3 = ISC_TRUE;
4218 dns_rdataset_disassociate(&rdataset);
4220 if (result != ISC_R_NOMORE)
4222 if (seen_ns && !seen_soa)
4223 *delegation = ISC_TRUE;
4225 * Going from insecure to NSEC3.
4226 * Don't generate NSEC3 records for NSEC3 records.
4228 if (build_nsec3 && !seen_nsec3 && seen_rr) {
4229 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
4230 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
4235 * Going from insecure to NSEC.
4236 * Don't generate NSEC records for NSEC3 records.
4238 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
4239 /* Build and add NSEC. */
4240 bottom = (seen_ns && !seen_soa) || seen_dname;
4241 CHECK(add_nsec(db, version, name, node, minimum, bottom, diff));
4242 /* Count a NSEC generation as a signature generation. */
4245 result = dns_rdatasetiter_first(iterator);
4246 while (result == ISC_R_SUCCESS) {
4247 dns_rdatasetiter_current(iterator, &rdataset);
4248 if (rdataset.type == dns_rdatatype_soa ||
4249 rdataset.type == dns_rdatatype_rrsig)
4251 if (is_ksk && rdataset.type != dns_rdatatype_dnskey)
4254 rdataset.type != dns_rdatatype_ds &&
4255 rdataset.type != dns_rdatatype_nsec)
4257 if (signed_with_key(db, node, version, rdataset.type, key))
4259 /* Calculate the signature, creating a RRSIG RDATA. */
4260 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
4261 &expire, mctx, &buffer, &rdata));
4262 /* Update the database and journal with the RRSIG. */
4263 /* XXX inefficient - will cause dataset merging */
4264 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
4265 name, rdataset.ttl, &rdata));
4266 dns_rdata_reset(&rdata);
4269 dns_rdataset_disassociate(&rdataset);
4270 result = dns_rdatasetiter_next(iterator);
4272 if (result == ISC_R_NOMORE)
4273 result = ISC_R_SUCCESS;
4275 *delegation = ISC_TRUE;
4277 if (dns_rdataset_isassociated(&rdataset))
4278 dns_rdataset_disassociate(&rdataset);
4279 if (iterator != NULL)
4280 dns_rdatasetiter_destroy(&iterator);
4285 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
4286 dns_ttl_t minimum, isc_boolean_t *secureupdated, dns_diff_t *diff)
4288 isc_result_t result;
4289 dns_rdata_t rdata = DNS_RDATA_INIT;
4290 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
4291 dns_rdataset_t rdataset;
4292 dns_rdata_nsec_t nsec;
4293 dns_dbnode_t *node = NULL;
4296 * Check to see if the OPT bit has already been cleared.
4298 CHECK(dns_db_getoriginnode(db, &node));
4299 dns_rdataset_init(&rdataset);
4300 CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
4301 dns_rdatatype_none, 0, &rdataset, NULL));
4302 CHECK(dns_rdataset_first(&rdataset));
4303 dns_rdataset_current(&rdataset, &rdata);
4306 * Find the NEXT name for building the new record.
4308 CHECK(dns_rdata_tostruct(&rdata, &nsec, NULL));
4311 * Delete the old NSEC record.
4313 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_DEL, name, minimum,
4315 dns_rdata_reset(&rdata);
4318 * Add the new NSEC record.
4320 CHECK(dns_nsec_buildrdata(db, version, node, &nsec.next, nsecbuffer,
4322 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, minimum,
4324 dns_rdata_reset(&rdata);
4326 if (secureupdated != NULL)
4327 *secureupdated = ISC_TRUE;
4331 dns_db_detachnode(db, &node);
4332 if (dns_rdataset_isassociated(&rdataset))
4333 dns_rdataset_disassociate(&rdataset);
4338 updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
4339 dns_name_t *name, dns_rdatatype_t privatetype,
4342 isc_result_t result;
4343 dns_dbnode_t *node = NULL;
4344 dns_rdataset_t rdataset;
4345 dns_rdata_t rdata = DNS_RDATA_INIT;
4346 unsigned char data[5];
4347 isc_boolean_t seen_done = ISC_FALSE;
4349 dns_rdataset_init(&rdataset);
4350 result = dns_db_getoriginnode(signing->db, &node);
4351 if (result != ISC_R_SUCCESS)
4354 result = dns_db_findrdataset(signing->db, node, version, privatetype,
4355 dns_rdatatype_none, 0, &rdataset, NULL);
4356 if (result == ISC_R_NOTFOUND) {
4357 result = ISC_R_SUCCESS;
4360 if (result != ISC_R_SUCCESS)
4362 for (result = dns_rdataset_first(&rdataset);
4363 result == ISC_R_SUCCESS;
4364 result = dns_rdataset_next(&rdataset)) {
4365 dns_rdataset_current(&rdataset, &rdata);
4366 if (rdata.length != 5 ||
4367 rdata.data[0] != signing->algorithm ||
4368 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
4369 rdata.data[2] != (signing->keyid & 0xff)) {
4370 dns_rdata_reset(&rdata);
4373 if (!signing->delete && rdata.data[4] != 0)
4374 seen_done = ISC_TRUE;
4376 CHECK(update_one_rr(signing->db, version, diff,
4377 DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata));
4378 dns_rdata_reset(&rdata);
4380 if (result == ISC_R_NOMORE)
4381 result = ISC_R_SUCCESS;
4382 if (!signing->delete && !seen_done) {
4384 data[0] = signing->algorithm;
4385 data[1] = (signing->keyid >> 8) & 0xff;
4386 data[2] = signing->keyid & 0xff;
4389 rdata.length = sizeof(data);
4391 rdata.type = privatetype;
4392 rdata.rdclass = dns_db_class(signing->db);
4393 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
4394 name, rdataset.ttl, &rdata));
4397 if (dns_rdataset_isassociated(&rdataset))
4398 dns_rdataset_disassociate(&rdataset);
4400 dns_db_detachnode(signing->db, &node);
4405 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
4406 isc_boolean_t active, dns_diff_t *diff)
4408 dns_dbnode_t *node = NULL;
4409 dns_name_t *name = dns_db_origin(db);
4410 dns_rdata_t rdata = DNS_RDATA_INIT;
4411 dns_rdataset_t rdataset;
4412 dns_rdata_nsec3param_t nsec3param;
4413 isc_result_t result;
4414 isc_buffer_t buffer;
4415 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
4418 dns_rdataset_init(&rdataset);
4420 result = dns_db_getoriginnode(db, &node);
4421 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4422 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4423 0, 0, &rdataset, NULL);
4424 if (result == ISC_R_NOTFOUND)
4426 if (result != ISC_R_SUCCESS)
4430 * Preserve the existing ttl.
4435 * Delete all NSEC3PARAM records which match that in nsec3chain.
4437 for (result = dns_rdataset_first(&rdataset);
4438 result == ISC_R_SUCCESS;
4439 result = dns_rdataset_next(&rdataset)) {
4441 dns_rdataset_current(&rdataset, &rdata);
4442 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
4444 if (nsec3param.hash != chain->nsec3param.hash ||
4445 (active && nsec3param.flags != 0) ||
4446 nsec3param.iterations != chain->nsec3param.iterations ||
4447 nsec3param.salt_length != chain->nsec3param.salt_length ||
4448 memcmp(nsec3param.salt, chain->nsec3param.salt,
4449 nsec3param.salt_length)) {
4450 dns_rdata_reset(&rdata);
4454 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
4455 name, rdataset.ttl, &rdata));
4456 dns_rdata_reset(&rdata);
4458 if (result != ISC_R_NOMORE)
4462 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
4463 result = ISC_R_SUCCESS;
4468 * Add a NSEC3PARAM record which matches that in nsec3chain but
4469 * with all flags bits cleared.
4471 * Note: we do not clear chain->nsec3param.flags as this change
4474 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
4475 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
4476 dns_rdatatype_nsec3param,
4477 &chain->nsec3param, &buffer));
4478 rdata.data[1] = 0; /* Clear flag bits. */
4479 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
4482 dns_db_detachnode(db, &node);
4483 if (dns_rdataset_isassociated(&rdataset))
4484 dns_rdataset_disassociate(&rdataset);
4489 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4490 dns_name_t *name, dns_diff_t *diff)
4492 dns_rdataset_t rdataset;
4493 isc_result_t result;
4495 dns_rdataset_init(&rdataset);
4497 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4498 0, 0, &rdataset, NULL);
4499 if (result == ISC_R_NOTFOUND)
4500 return (ISC_R_SUCCESS);
4501 if (result != ISC_R_SUCCESS)
4503 for (result = dns_rdataset_first(&rdataset);
4504 result == ISC_R_SUCCESS;
4505 result = dns_rdataset_next(&rdataset)) {
4506 dns_rdata_t rdata = DNS_RDATA_INIT;
4508 dns_rdataset_current(&rdataset, &rdata);
4509 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4510 rdataset.ttl, &rdata));
4512 if (result == ISC_R_NOMORE)
4513 result = ISC_R_SUCCESS;
4515 dns_rdataset_disassociate(&rdataset);
4520 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
4521 dns_name_t *name, const dns_rdata_nsec3param_t *param,
4524 dns_rdataset_t rdataset;
4525 dns_rdata_nsec3_t nsec3;
4526 isc_result_t result;
4528 dns_rdataset_init(&rdataset);
4529 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
4530 0, 0, &rdataset, NULL);
4531 if (result == ISC_R_NOTFOUND)
4532 return (ISC_R_SUCCESS);
4533 if (result != ISC_R_SUCCESS)
4536 for (result = dns_rdataset_first(&rdataset);
4537 result == ISC_R_SUCCESS;
4538 result = dns_rdataset_next(&rdataset)) {
4539 dns_rdata_t rdata = DNS_RDATA_INIT;
4541 dns_rdataset_current(&rdataset, &rdata);
4542 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
4543 if (nsec3.hash != param->hash ||
4544 nsec3.iterations != param->iterations ||
4545 nsec3.salt_length != param->salt_length ||
4546 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
4548 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
4549 rdataset.ttl, &rdata));
4551 if (result == ISC_R_NOMORE)
4552 result = ISC_R_SUCCESS;
4554 dns_rdataset_disassociate(&rdataset);
4559 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
4560 const dns_rdata_nsec3param_t *param,
4561 isc_boolean_t *answer, isc_boolean_t *updatensec)
4563 dns_dbnode_t *node = NULL;
4564 dns_rdata_t rdata = DNS_RDATA_INIT;
4565 dns_rdata_nsec3param_t myparam;
4566 dns_rdataset_t rdataset;
4567 isc_result_t result;
4569 *answer = ISC_FALSE;
4571 result = dns_db_getoriginnode(db, &node);
4572 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4574 dns_rdataset_init(&rdataset);
4575 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
4576 0, 0, &rdataset, NULL);
4577 if (result == ISC_R_NOTFOUND)
4578 goto check_nsec3param;
4580 if (result != ISC_R_SUCCESS)
4583 CHECK(dns_rdataset_first(&rdataset));
4584 dns_rdataset_current(&rdataset, &rdata);
4586 if (!dns_nsec_typepresent(&rdata, dns_rdatatype_opt)) {
4588 * We have a complete NSEC chain. Signal to update
4589 * the apex NSEC record.
4591 *updatensec = ISC_TRUE;
4594 dns_rdataset_disassociate(&rdataset);
4595 dns_rdata_reset(&rdata);
4598 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
4599 0, 0, &rdataset, NULL);
4600 if (result == ISC_R_NOTFOUND) {
4602 dns_db_detachnode(db, &node);
4603 return (ISC_R_SUCCESS);
4605 if (result != ISC_R_SUCCESS) {
4606 dns_db_detachnode(db, &node);
4610 for (result = dns_rdataset_first(&rdataset);
4611 result == ISC_R_SUCCESS;
4612 result = dns_rdataset_next(&rdataset)) {
4613 dns_rdataset_current(&rdataset, &rdata);
4614 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
4615 dns_rdata_reset(&rdata);
4617 * Ignore any NSEC3PARAM removals.
4619 if (NSEC3REMOVE(myparam.flags))
4622 * Ignore the chain that we are in the process of deleting.
4624 if (myparam.hash == param->hash &&
4625 myparam.iterations == param->iterations &&
4626 myparam.salt_length == param->salt_length &&
4627 !memcmp(myparam.salt, param->salt, myparam.salt_length))
4630 * Found an active NSEC3 chain.
4634 if (result == ISC_R_NOMORE) {
4636 result = ISC_R_SUCCESS;
4640 if (dns_rdataset_isassociated(&rdataset))
4641 dns_rdataset_disassociate(&rdataset);
4642 dns_db_detachnode(db, &node);
4647 * Incrementally build and sign a new NSEC3 chain using the parameters
4651 zone_nsec3chain(dns_zone_t *zone) {
4652 const char *journalfile;
4653 dns_db_t *db = NULL;
4654 dns_dbnode_t *node = NULL;
4655 dns_dbversion_t *version = NULL;
4656 dns_diff_t sig_diff;
4657 dns_diff_t nsec_diff;
4658 dns_diff_t nsec3_diff;
4659 dns_diff_t param_diff;
4660 dns_fixedname_t fixed;
4661 dns_fixedname_t nextfixed;
4662 dns_name_t *name, *nextname;
4663 dns_rdataset_t rdataset;
4664 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
4665 dns_nsec3chainlist_t cleanup;
4666 dst_key_t *zone_keys[MAXZONEKEYS];
4667 isc_int32_t signatures;
4668 isc_boolean_t check_ksk, is_ksk;
4669 isc_boolean_t delegation;
4670 isc_boolean_t first;
4671 isc_result_t result;
4672 isc_stdtime_t now, inception, soaexpire, expire, stop;
4673 isc_uint32_t jitter;
4675 unsigned int nkeys = 0;
4677 isc_boolean_t unsecure = ISC_FALSE;
4678 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
4679 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
4680 dns_rdatasetiter_t *iterator = NULL;
4681 dns_difftuple_t *tuple;
4682 isc_boolean_t buildnsecchain;
4683 isc_boolean_t updatensec = ISC_FALSE;
4685 dns_rdataset_init(&rdataset);
4686 dns_fixedname_init(&fixed);
4687 name = dns_fixedname_name(&fixed);
4688 dns_fixedname_init(&nextfixed);
4689 nextname = dns_fixedname_name(&nextfixed);
4690 dns_diff_init(zone->mctx, ¶m_diff);
4691 dns_diff_init(zone->mctx, &nsec3_diff);
4692 dns_diff_init(zone->mctx, &nsec_diff);
4693 dns_diff_init(zone->mctx, &sig_diff);
4694 sig_diff.resign = zone->sigresigninginterval;
4695 ISC_LIST_INIT(cleanup);
4698 * Updates are disabled. Pause for 5 minutes.
4700 if (zone->update_disabled) {
4701 result = ISC_R_FAILURE;
4705 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4706 dns_db_attach(zone->db, &db);
4707 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4709 result = dns_db_newversion(db, &version);
4710 if (result != ISC_R_SUCCESS) {
4711 dns_zone_log(zone, ISC_LOG_ERROR,
4712 "zone_nsec3chain:dns_db_newversion -> %s\n",
4713 dns_result_totext(result));
4717 result = find_zone_keys(zone, db, version, zone->mctx,
4718 MAXZONEKEYS, zone_keys, &nkeys);
4719 if (result != ISC_R_SUCCESS) {
4720 dns_zone_log(zone, ISC_LOG_ERROR,
4721 "zone_nsec3chain:find_zone_keys -> %s\n",
4722 dns_result_totext(result));
4726 isc_stdtime_get(&now);
4727 inception = now - 3600; /* Allow for clock skew. */
4728 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
4731 * Spread out signatures over time if they happen to be
4732 * clumped. We don't do this for each add_sigs() call as
4733 * we still want some clustering to occur.
4735 isc_random_get(&jitter);
4736 expire = soaexpire - jitter % 3600;
4739 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
4741 check_ksk = ksk_sanity(db, version);
4744 * We keep pulling nodes off each iterator in turn until
4745 * we have no more nodes to pull off or we reach the limits
4748 nodes = zone->nodes;
4749 signatures = zone->signatures;
4751 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
4755 if (nsec3chain != NULL)
4756 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
4758 * Generate new NSEC3 chains first.
4760 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
4762 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
4764 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4765 if (nsec3chain->done || nsec3chain->db != zone->db) {
4766 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
4767 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4769 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4771 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
4775 * Possible future db.
4777 if (nsec3chain->db != db) {
4781 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
4785 delegation = ISC_FALSE;
4786 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
4788 if (nsec3chain->delete_nsec) {
4789 delegation = ISC_FALSE;
4790 dns_dbiterator_pause(nsec3chain->dbiterator);
4791 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
4795 * On the first pass we need to check if the current node
4796 * has not been obscured.
4798 delegation = ISC_FALSE;
4799 unsecure = ISC_FALSE;
4801 dns_fixedname_t ffound;
4803 dns_fixedname_init(&ffound);
4804 found = dns_fixedname_name(&ffound);
4805 result = dns_db_find(db, name, version,
4807 DNS_DBFIND_NOWILD, 0, NULL, found,
4809 if ((result == DNS_R_DELEGATION ||
4810 result == DNS_R_DNAME) &&
4811 !dns_name_equal(name, found)) {
4813 * Remember the obscuring name so that
4814 * we skip all obscured names.
4816 dns_name_copy(found, name, NULL);
4817 delegation = ISC_TRUE;
4823 * Check to see if this is a bottom of zone node.
4825 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
4826 if (result == ISC_R_NOTFOUND) /* Empty node? */
4828 if (result != ISC_R_SUCCESS)
4831 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
4833 for (result = dns_rdatasetiter_first(iterator);
4834 result == ISC_R_SUCCESS;
4835 result = dns_rdatasetiter_next(iterator)) {
4836 dns_rdatasetiter_current(iterator, &rdataset);
4837 INSIST(rdataset.type != dns_rdatatype_nsec3);
4838 if (rdataset.type == dns_rdatatype_soa)
4839 seen_soa = ISC_TRUE;
4840 else if (rdataset.type == dns_rdatatype_ns)
4842 else if (rdataset.type == dns_rdatatype_dname)
4843 seen_dname = ISC_TRUE;
4844 else if (rdataset.type == dns_rdatatype_ds)
4846 else if (rdataset.type == dns_rdatatype_nsec)
4847 seen_nsec = ISC_TRUE;
4848 dns_rdataset_disassociate(&rdataset);
4850 dns_rdatasetiter_destroy(&iterator);
4852 * Is there a NSEC chain than needs to be cleaned up?
4855 nsec3chain->seen_nsec = ISC_TRUE;
4856 if (seen_ns && !seen_soa && !seen_ds)
4857 unsecure = ISC_TRUE;
4858 if ((seen_ns && !seen_soa) || seen_dname)
4859 delegation = ISC_TRUE;
4864 dns_dbiterator_pause(nsec3chain->dbiterator);
4865 CHECK(dns_nsec3_addnsec3(db, version, name,
4866 &nsec3chain->nsec3param,
4867 zone->minimum, unsecure, &nsec3_diff));
4869 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
4870 * two signatures. Additionally there will, in general, be
4871 * two signature generated below.
4873 * If we are only changing the optout flag the cost is half
4874 * that of the cost of generating a completely new chain.
4879 * Go onto next node.
4883 dns_db_detachnode(db, &node);
4885 result = dns_dbiterator_next(nsec3chain->dbiterator);
4887 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
4888 CHECK(fixup_nsec3param(db, version, nsec3chain,
4889 ISC_FALSE, ¶m_diff));
4891 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4894 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4897 if (result == ISC_R_NOMORE) {
4898 dns_dbiterator_pause(nsec3chain->dbiterator);
4899 if (nsec3chain->seen_nsec) {
4900 CHECK(fixup_nsec3param(db, version,
4904 nsec3chain->delete_nsec = ISC_TRUE;
4907 CHECK(fixup_nsec3param(db, version, nsec3chain,
4908 ISC_FALSE, ¶m_diff));
4910 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
4913 ISC_LIST_APPEND(cleanup, nsec3chain, link);
4915 } else if (result != ISC_R_SUCCESS) {
4916 dns_zone_log(zone, ISC_LOG_ERROR,
4918 "dns_dbiterator_next -> %s\n",
4919 dns_result_totext(result));
4921 } else if (delegation) {
4922 dns_dbiterator_current(nsec3chain->dbiterator,
4924 dns_db_detachnode(db, &node);
4925 if (!dns_name_issubdomain(nextname, name))
4933 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
4938 dns_dbiterator_pause(nsec3chain->dbiterator);
4939 nsec3chain = nextnsec3chain;
4941 if (nsec3chain != NULL)
4942 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
4949 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
4952 buildnsecchain = ISC_FALSE;
4953 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
4955 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
4958 if (nsec3chain->db != db)
4959 goto next_removechain;
4961 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
4962 goto next_removechain;
4965 * Work out if we need to build a NSEC chain as a consequence
4966 * of removing this NSEC3 chain.
4968 if (first && !updatensec &&
4969 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
4970 CHECK(need_nsec_chain(db, version,
4971 &nsec3chain->nsec3param,
4972 &buildnsecchain, &updatensec));
4974 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
4975 delegation = ISC_FALSE;
4977 if (!buildnsecchain) {
4979 * Delete the NSECPARAM record that matches this chain.
4982 CHECK(fixup_nsec3param(db, version, nsec3chain,
4983 ISC_TRUE, ¶m_diff));
4986 * Delete the NSEC3 records.
4988 CHECK(deletematchingnsec3(db, version, node, name,
4989 &nsec3chain->nsec3param,
4991 goto next_removenode;
4995 dns_fixedname_t ffound;
4997 dns_fixedname_init(&ffound);
4998 found = dns_fixedname_name(&ffound);
4999 result = dns_db_find(db, name, version,
5001 DNS_DBFIND_NOWILD, 0, NULL, found,
5003 if ((result == DNS_R_DELEGATION ||
5004 result == DNS_R_DNAME) &&
5005 !dns_name_equal(name, found)) {
5007 * Remember the obscuring name so that
5008 * we skip all obscured names.
5010 dns_name_copy(found, name, NULL);
5011 delegation = ISC_TRUE;
5012 goto next_removenode;
5017 * Check to see if this is a bottom of zone node.
5019 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5020 if (result == ISC_R_NOTFOUND) /* Empty node? */
5021 goto next_removenode;
5022 if (result != ISC_R_SUCCESS)
5025 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
5026 seen_rr = ISC_FALSE;
5027 for (result = dns_rdatasetiter_first(iterator);
5028 result == ISC_R_SUCCESS;
5029 result = dns_rdatasetiter_next(iterator)) {
5030 dns_rdatasetiter_current(iterator, &rdataset);
5031 if (rdataset.type == dns_rdatatype_soa)
5032 seen_soa = ISC_TRUE;
5033 else if (rdataset.type == dns_rdatatype_ns)
5035 else if (rdataset.type == dns_rdatatype_dname)
5036 seen_dname = ISC_TRUE;
5037 else if (rdataset.type == dns_rdatatype_nsec)
5038 seen_nsec = ISC_TRUE;
5039 else if (rdataset.type == dns_rdatatype_nsec3)
5040 seen_nsec3 = ISC_TRUE;
5042 dns_rdataset_disassociate(&rdataset);
5044 dns_rdatasetiter_destroy(&iterator);
5046 if (!seen_rr || seen_nsec3 || seen_nsec)
5047 goto next_removenode;
5048 if ((seen_ns && !seen_soa) || seen_dname)
5049 delegation = ISC_TRUE;
5051 CHECK(add_nsec(db, version, name, node, zone->minimum,
5052 delegation, &nsec_diff));
5056 dns_db_detachnode(db, &node);
5058 result = dns_dbiterator_next(nsec3chain->dbiterator);
5059 if (result == ISC_R_NOMORE && buildnsecchain) {
5061 * The NSEC chain should now be built.
5062 * We can now remove the NSEC3 chain.
5064 updatensec = ISC_TRUE;
5065 goto same_removechain;
5067 if (result == ISC_R_NOMORE) {
5069 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
5072 ISC_LIST_APPEND(cleanup, nsec3chain, link);
5073 dns_dbiterator_pause(nsec3chain->dbiterator);
5074 CHECK(fixup_nsec3param(db, version, nsec3chain,
5075 ISC_FALSE, ¶m_diff));
5076 goto next_removechain;
5077 } else if (result != ISC_R_SUCCESS) {
5078 dns_zone_log(zone, ISC_LOG_ERROR,
5080 "dns_dbiterator_next -> %s\n",
5081 dns_result_totext(result));
5083 } else if (delegation) {
5084 dns_dbiterator_current(nsec3chain->dbiterator,
5086 dns_db_detachnode(db, &node);
5087 if (!dns_name_issubdomain(nextname, name))
5095 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
5096 buildnsecchain = ISC_FALSE;
5101 dns_dbiterator_pause(nsec3chain->dbiterator);
5102 nsec3chain = nextnsec3chain;
5107 * Add / update signatures for the NSEC3 records.
5109 for (tuple = ISC_LIST_HEAD(nsec3_diff.tuples);
5111 tuple = ISC_LIST_HEAD(nsec3_diff.tuples)) {
5113 * We have changed the NSEC3 RRset above so we need to update
5116 result = del_sigs(zone, db, version, &tuple->name,
5117 dns_rdatatype_nsec3, &sig_diff,
5118 zone_keys, nkeys, now);
5119 if (result != ISC_R_SUCCESS) {
5120 dns_zone_log(zone, ISC_LOG_ERROR,
5121 "zone_nsec3chain:del_sigs -> %s\n",
5122 dns_result_totext(result));
5125 result = add_sigs(db, version, &tuple->name,
5126 dns_rdatatype_nsec3, &sig_diff, zone_keys,
5127 nkeys, zone->mctx, inception, expire,
5129 if (result != ISC_R_SUCCESS) {
5130 dns_zone_log(zone, ISC_LOG_ERROR,
5131 "zone_nsec3chain:add_sigs -> %s\n",
5132 dns_result_totext(result));
5137 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
5138 while (next != NULL &&
5139 !dns_name_equal(&tuple->name, &next->name))
5140 next = ISC_LIST_NEXT(next, link);
5141 ISC_LIST_UNLINK(nsec3_diff.tuples, tuple, link);
5142 dns_diff_appendminimal(&sig_diff, &tuple);
5143 INSIST(tuple == NULL);
5145 } while (tuple != NULL);
5148 for (tuple = ISC_LIST_HEAD(param_diff.tuples);
5150 tuple = ISC_LIST_HEAD(param_diff.tuples)) {
5152 * We have changed the NSEC3PARAM RRset above so we need to
5153 * update the signatures.
5155 result = del_sigs(zone, db, version, &tuple->name,
5156 dns_rdatatype_nsec3param, &sig_diff,
5157 zone_keys, nkeys, now);
5158 if (result != ISC_R_SUCCESS) {
5159 dns_zone_log(zone, ISC_LOG_ERROR,
5160 "zone_nsec3chain:del_sigs -> %s\n",
5161 dns_result_totext(result));
5164 result = add_sigs(db, version, &tuple->name,
5165 dns_rdatatype_nsec3param, &sig_diff,
5166 zone_keys, nkeys, zone->mctx, inception,
5168 if (result != ISC_R_SUCCESS) {
5169 dns_zone_log(zone, ISC_LOG_ERROR,
5170 "zone_nsec3chain:add_sigs -> %s\n",
5171 dns_result_totext(result));
5174 ISC_LIST_UNLINK(param_diff.tuples, tuple, link);
5175 dns_diff_appendminimal(&sig_diff, &tuple);
5176 INSIST(tuple == NULL);
5180 CHECK(updatesecure(db, version, &zone->origin, zone->minimum,
5183 for (tuple = ISC_LIST_HEAD(nsec_diff.tuples);
5185 tuple = ISC_LIST_HEAD(nsec_diff.tuples)) {
5186 result = del_sigs(zone, db, version, &tuple->name,
5187 dns_rdatatype_nsec, &sig_diff,
5188 zone_keys, nkeys, now);
5189 if (result != ISC_R_SUCCESS) {
5190 dns_zone_log(zone, ISC_LOG_ERROR,
5191 "zone_nsec3chain:del_sigs -> %s\n",
5192 dns_result_totext(result));
5195 result = add_sigs(db, version, &tuple->name,
5196 dns_rdatatype_nsec, &sig_diff,
5197 zone_keys, nkeys, zone->mctx, inception,
5199 if (result != ISC_R_SUCCESS) {
5200 dns_zone_log(zone, ISC_LOG_ERROR,
5201 "zone_nsec3chain:add_sigs -> %s\n",
5202 dns_result_totext(result));
5205 ISC_LIST_UNLINK(nsec_diff.tuples, tuple, link);
5206 dns_diff_appendminimal(&sig_diff, &tuple);
5207 INSIST(tuple == NULL);
5211 * If we made no effective changes to the zone then we can just
5212 * cleanup otherwise we need to increment the serial.
5214 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
5217 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5218 &sig_diff, zone_keys, nkeys, now);
5219 if (result != ISC_R_SUCCESS) {
5220 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5221 "del_sigs -> %s\n", dns_result_totext(result));
5225 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5226 if (result != ISC_R_SUCCESS) {
5227 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5228 "increment_soa_serial -> %s\n",
5229 dns_result_totext(result));
5233 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5234 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5235 soaexpire, check_ksk);
5236 if (result != ISC_R_SUCCESS) {
5237 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5238 "add_sigs -> %s\n", dns_result_totext(result));
5242 journalfile = dns_zone_getjournal(zone);
5243 if (journalfile != NULL) {
5244 dns_journal_t *journal = NULL;
5245 result = dns_journal_open(zone->mctx, journalfile,
5246 ISC_TRUE, &journal);
5247 if (result != ISC_R_SUCCESS) {
5248 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5249 "dns_journal_open -> %s\n",
5250 dns_result_totext(result));
5254 result = dns_journal_write_transaction(journal, &sig_diff);
5255 dns_journal_destroy(&journal);
5256 if (result != ISC_R_SUCCESS) {
5257 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5258 "dns_journal_write_transaction -> %s\n",
5259 dns_result_totext(result));
5265 zone_needdump(zone, DNS_DUMP_DELAY);
5270 * Pause all iterators so that dns_db_closeversion() can succeed.
5273 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5275 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5276 dns_dbiterator_pause(nsec3chain->dbiterator);
5280 * Everything has succeeded. Commit the changes.
5282 dns_db_closeversion(db, &version, ISC_TRUE);
5285 * Everything succeeded so we can clean these up now.
5287 nsec3chain = ISC_LIST_HEAD(cleanup);
5288 while (nsec3chain != NULL) {
5289 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5290 dns_db_detach(&nsec3chain->db);
5291 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5292 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5293 nsec3chain = ISC_LIST_HEAD(cleanup);
5296 set_resigntime(zone);
5300 * On error roll back the current nsec3chain.
5302 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
5303 if (nsec3chain->done) {
5304 dns_db_detach(&nsec3chain->db);
5305 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5306 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5308 result = dns_dbiterator_first(nsec3chain->dbiterator);
5309 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5310 dns_dbiterator_pause(nsec3chain->dbiterator);
5311 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5316 * Rollback the cleanup list.
5318 nsec3chain = ISC_LIST_TAIL(cleanup);
5319 while (nsec3chain != NULL) {
5320 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
5321 if (nsec3chain->done) {
5322 dns_db_detach(&nsec3chain->db);
5323 dns_dbiterator_destroy(&nsec3chain->dbiterator);
5324 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
5327 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
5329 result = dns_dbiterator_first(nsec3chain->dbiterator);
5330 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5331 dns_dbiterator_pause(nsec3chain->dbiterator);
5332 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
5334 nsec3chain = ISC_LIST_TAIL(cleanup);
5338 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5340 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
5341 dns_dbiterator_pause(nsec3chain->dbiterator);
5344 dns_diff_clear(¶m_diff);
5345 dns_diff_clear(&nsec3_diff);
5346 dns_diff_clear(&nsec_diff);
5347 dns_diff_clear(&sig_diff);
5349 if (iterator != NULL)
5350 dns_rdatasetiter_destroy(&iterator);
5352 for (i = 0; i < nkeys; i++)
5353 dst_key_free(&zone_keys[i]);
5355 if (version != NULL) {
5356 dns_db_closeversion(db, &version, ISC_FALSE);
5358 } else if (db != NULL)
5362 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
5364 if (zone->update_disabled || result != ISC_R_SUCCESS)
5365 isc_interval_set(&i, 60, 0); /* 1 minute */
5367 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5368 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
5370 isc_time_settoepoch(&zone->nsec3chaintime);
5375 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5376 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
5377 isc_uint16_t keyid, dns_diff_t *diff)
5379 dns_rdata_rrsig_t rrsig;
5380 dns_rdataset_t rdataset;
5381 dns_rdatasetiter_t *iterator = NULL;
5382 isc_result_t result;
5384 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5385 if (result != ISC_R_SUCCESS) {
5386 if (result == ISC_R_NOTFOUND)
5387 result = ISC_R_SUCCESS;
5391 dns_rdataset_init(&rdataset);
5392 for (result = dns_rdatasetiter_first(iterator);
5393 result == ISC_R_SUCCESS;
5394 result = dns_rdatasetiter_next(iterator)) {
5395 dns_rdatasetiter_current(iterator, &rdataset);
5396 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
5397 for (result = dns_rdataset_first(&rdataset);
5398 result == ISC_R_SUCCESS;
5399 result = dns_rdataset_next(&rdataset)) {
5400 dns_rdata_t rdata = DNS_RDATA_INIT;
5401 dns_rdataset_current(&rdataset, &rdata);
5402 CHECK(update_one_rr(db, version, diff,
5403 DNS_DIFFOP_DEL, name,
5404 rdataset.ttl, &rdata));
5406 if (result != ISC_R_NOMORE)
5408 dns_rdataset_disassociate(&rdataset);
5411 if (rdataset.type != dns_rdatatype_rrsig) {
5412 dns_rdataset_disassociate(&rdataset);
5415 for (result = dns_rdataset_first(&rdataset);
5416 result == ISC_R_SUCCESS;
5417 result = dns_rdataset_next(&rdataset)) {
5418 dns_rdata_t rdata = DNS_RDATA_INIT;
5419 dns_rdataset_current(&rdataset, &rdata);
5420 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
5421 if (rrsig.algorithm != algorithm ||
5422 rrsig.keyid != keyid)
5424 CHECK(update_one_rr(db, version, diff,
5425 DNS_DIFFOP_DEL, name,
5426 rdataset.ttl, &rdata));
5428 dns_rdataset_disassociate(&rdataset);
5429 if (result != ISC_R_NOMORE)
5432 if (result == ISC_R_NOMORE)
5433 result = ISC_R_SUCCESS;
5435 if (dns_rdataset_isassociated(&rdataset))
5436 dns_rdataset_disassociate(&rdataset);
5437 dns_rdatasetiter_destroy(&iterator);
5442 * Incrementally sign the zone using the keys requested.
5443 * Builds the NSEC chain if required.
5446 zone_sign(dns_zone_t *zone) {
5447 const char *journalfile;
5448 dns_db_t *db = NULL;
5449 dns_dbnode_t *node = NULL;
5450 dns_dbversion_t *version = NULL;
5451 dns_diff_t sig_diff;
5452 dns_fixedname_t fixed;
5453 dns_fixedname_t nextfixed;
5454 dns_name_t *name, *nextname;
5455 dns_rdataset_t rdataset;
5456 dns_signing_t *signing, *nextsigning;
5457 dns_signinglist_t cleanup;
5458 dst_key_t *zone_keys[MAXZONEKEYS];
5459 isc_int32_t signatures;
5460 isc_boolean_t check_ksk, is_ksk;
5461 isc_boolean_t delegation;
5462 isc_boolean_t finishedakey = ISC_FALSE;
5463 isc_boolean_t secureupdated = ISC_FALSE;
5464 isc_boolean_t build_nsec3 = ISC_FALSE, build_nsec = ISC_FALSE;
5465 isc_boolean_t first;
5466 isc_result_t result;
5467 isc_stdtime_t now, inception, soaexpire, expire, stop;
5468 isc_uint32_t jitter;
5470 unsigned int nkeys = 0;
5473 dns_rdataset_init(&rdataset);
5474 dns_fixedname_init(&fixed);
5475 name = dns_fixedname_name(&fixed);
5476 dns_fixedname_init(&nextfixed);
5477 nextname = dns_fixedname_name(&nextfixed);
5478 dns_diff_init(zone->mctx, &sig_diff);
5479 sig_diff.resign = zone->sigresigninginterval;
5480 ISC_LIST_INIT(cleanup);
5483 * Updates are disabled. Pause for 5 minutes.
5485 if (zone->update_disabled) {
5486 result = ISC_R_FAILURE;
5490 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5491 dns_db_attach(zone->db, &db);
5492 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5494 result = dns_db_newversion(db, &version);
5495 if (result != ISC_R_SUCCESS) {
5496 dns_zone_log(zone, ISC_LOG_ERROR,
5497 "zone_sign:dns_db_newversion -> %s\n",
5498 dns_result_totext(result));
5502 result = find_zone_keys(zone, db, version, zone->mctx,
5503 MAXZONEKEYS, zone_keys, &nkeys);
5504 if (result != ISC_R_SUCCESS) {
5505 dns_zone_log(zone, ISC_LOG_ERROR,
5506 "zone_sign:find_zone_keys -> %s\n",
5507 dns_result_totext(result));
5511 isc_stdtime_get(&now);
5512 inception = now - 3600; /* Allow for clock skew. */
5513 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5516 * Spread out signatures over time if they happen to be
5517 * clumped. We don't do this for each add_sigs() call as
5518 * we still want some clustering to occur.
5520 isc_random_get(&jitter);
5521 expire = soaexpire - jitter % 3600;
5524 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5526 check_ksk = ksk_sanity(db, version);
5529 * We keep pulling nodes off each iterator in turn until
5530 * we have no more nodes to pull off or we reach the limits
5533 nodes = zone->nodes;
5534 signatures = zone->signatures;
5535 signing = ISC_LIST_HEAD(zone->signing);
5538 * See if we have a NSEC chain.
5540 result = dns_db_getoriginnode(db, &node);
5541 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5542 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
5543 dns_rdatatype_none, 0, &rdataset, NULL);
5544 dns_db_detachnode(db, &node);
5545 if (result == ISC_R_SUCCESS) {
5546 build_nsec = ISC_TRUE;
5547 dns_rdataset_disassociate(&rdataset);
5548 } else if (result != ISC_R_NOTFOUND) {
5552 * No NSEC chain present.
5553 * See if we need to build a NSEC3 chain?
5555 result = dns_nsec3_active(db, version, ISC_TRUE, &build_nsec3);
5556 if (result == ISC_R_SUCCESS) {
5558 build_nsec3 = ISC_FALSE;
5560 result = dns_nsec3_active(db, version,
5564 secureupdated = ISC_TRUE;
5566 build_nsec = ISC_TRUE;
5571 while (signing != NULL && nodes-- > 0 && signatures > 0) {
5572 nextsigning = ISC_LIST_NEXT(signing, link);
5574 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5575 if (signing->done || signing->db != zone->db) {
5577 * The zone has been reloaded. We will have
5578 * created new signings as part of the reload
5579 * process so we can destroy this one.
5581 ISC_LIST_UNLINK(zone->signing, signing, link);
5582 ISC_LIST_APPEND(cleanup, signing, link);
5583 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5586 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5588 if (signing->db != db)
5592 delegation = ISC_FALSE;
5594 dns_dbiterator_current(signing->dbiterator, &node, name);
5596 if (signing->delete) {
5597 dns_dbiterator_pause(signing->dbiterator);
5598 CHECK(del_sig(db, version, name, node, nkeys,
5599 signing->algorithm, signing->keyid,
5604 * On the first pass we need to check if the current node
5605 * has not been obscured.
5608 dns_fixedname_t ffound;
5610 dns_fixedname_init(&ffound);
5611 found = dns_fixedname_name(&ffound);
5612 result = dns_db_find(db, name, version,
5614 DNS_DBFIND_NOWILD, 0, NULL, found,
5616 if ((result == DNS_R_DELEGATION ||
5617 result == DNS_R_DNAME) &&
5618 !dns_name_equal(name, found)) {
5620 * Remember the obscuring name so that
5621 * we skip all obscured names.
5623 dns_name_copy(found, name, NULL);
5624 delegation = ISC_TRUE;
5632 dns_dbiterator_pause(signing->dbiterator);
5633 for (i = 0; i < nkeys; i++) {
5635 * Find the key we want to sign with.
5637 if (dst_key_alg(zone_keys[i]) != signing->algorithm ||
5638 dst_key_id(zone_keys[i]) != signing->keyid ||
5639 !dst_key_isprivate(zone_keys[i]))
5642 * Do we do KSK processing?
5645 (dst_key_flags(zone_keys[i]) & DNS_KEYFLAG_KSK) != 0)
5647 CHECK(sign_a_node(db, name, node, version, build_nsec3,
5648 build_nsec, zone_keys[i], inception,
5649 expire, zone->minimum, is_ksk,
5650 &delegation, &sig_diff, &signatures,
5655 * Go onto next node.
5659 dns_db_detachnode(db, &node);
5661 result = dns_dbiterator_next(signing->dbiterator);
5662 if (result == ISC_R_NOMORE) {
5663 ISC_LIST_UNLINK(zone->signing, signing, link);
5664 ISC_LIST_APPEND(cleanup, signing, link);
5665 dns_dbiterator_pause(signing->dbiterator);
5666 finishedakey = ISC_TRUE;
5667 if (!is_ksk && !secureupdated && nkeys != 0 &&
5670 * We have finished regenerating the
5671 * zone with a zone signing key.
5672 * The NSEC chain is now complete and
5673 * there is a full set of signatures
5674 * for the zone. We can now clear the
5675 * OPT bit from the NSEC record.
5677 result = updatesecure(db, version,
5682 if (result != ISC_R_SUCCESS) {
5685 "updatesecure -> %s\n",
5686 dns_result_totext(result));
5690 result = updatesignwithkey(signing, version,
5694 if (result != ISC_R_SUCCESS) {
5695 dns_zone_log(zone, ISC_LOG_ERROR,
5696 "updatesignwithkey -> %s\n",
5697 dns_result_totext(result));
5701 } else if (result != ISC_R_SUCCESS) {
5702 dns_zone_log(zone, ISC_LOG_ERROR,
5703 "zone_sign:dns_dbiterator_next -> %s\n",
5704 dns_result_totext(result));
5706 } else if (delegation) {
5707 dns_dbiterator_current(signing->dbiterator,
5709 dns_db_detachnode(db, &node);
5710 if (!dns_name_issubdomain(nextname, name))
5718 dns_dbiterator_pause(signing->dbiterator);
5719 signing = nextsigning;
5723 if (secureupdated) {
5725 * We have changed the NSEC RRset above so we need to update
5728 result = del_sigs(zone, db, version, &zone->origin,
5729 dns_rdatatype_nsec, &sig_diff, zone_keys,
5731 if (result != ISC_R_SUCCESS) {
5732 dns_zone_log(zone, ISC_LOG_ERROR,
5733 "zone_sign:del_sigs -> %s\n",
5734 dns_result_totext(result));
5737 result = add_sigs(db, version, &zone->origin,
5738 dns_rdatatype_nsec, &sig_diff, zone_keys,
5739 nkeys, zone->mctx, inception, soaexpire,
5741 if (result != ISC_R_SUCCESS) {
5742 dns_zone_log(zone, ISC_LOG_ERROR,
5743 "zone_sign:add_sigs -> %s\n",
5744 dns_result_totext(result));
5750 * We have changed the RRset above so we need to update
5753 result = del_sigs(zone, db, version, &zone->origin,
5754 zone->privatetype, &sig_diff,
5755 zone_keys, nkeys, now);
5756 if (result != ISC_R_SUCCESS) {
5757 dns_zone_log(zone, ISC_LOG_ERROR,
5758 "zone_sign:del_sigs -> %s\n",
5759 dns_result_totext(result));
5762 result = add_sigs(db, version, &zone->origin,
5763 zone->privatetype, &sig_diff,
5764 zone_keys, nkeys, zone->mctx, inception,
5765 soaexpire, check_ksk);
5766 if (result != ISC_R_SUCCESS) {
5767 dns_zone_log(zone, ISC_LOG_ERROR,
5768 "zone_sign:add_sigs -> %s\n",
5769 dns_result_totext(result));
5773 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5774 &sig_diff, zone_keys, nkeys, now);
5775 if (result != ISC_R_SUCCESS) {
5776 dns_zone_log(zone, ISC_LOG_ERROR,
5777 "zone_sign:del_sigs -> %s\n",
5778 dns_result_totext(result));
5782 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5783 if (result != ISC_R_SUCCESS) {
5784 dns_zone_log(zone, ISC_LOG_ERROR,
5785 "zone_sign:increment_soa_serial -> %s\n",
5786 dns_result_totext(result));
5791 * Generate maximum life time signatures so that the above loop
5792 * termination is sensible.
5794 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5795 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5796 soaexpire, check_ksk);
5797 if (result != ISC_R_SUCCESS) {
5798 dns_zone_log(zone, ISC_LOG_ERROR,
5799 "zone_sign:add_sigs -> %s\n",
5800 dns_result_totext(result));
5804 journalfile = dns_zone_getjournal(zone);
5805 if (journalfile != NULL) {
5806 dns_journal_t *journal = NULL;
5807 result = dns_journal_open(zone->mctx, journalfile,
5808 ISC_TRUE, &journal);
5809 if (result != ISC_R_SUCCESS) {
5810 dns_zone_log(zone, ISC_LOG_ERROR,
5811 "zone_sign:dns_journal_open -> %s\n",
5812 dns_result_totext(result));
5816 result = dns_journal_write_transaction(journal, &sig_diff);
5817 dns_journal_destroy(&journal);
5818 if (result != ISC_R_SUCCESS) {
5819 dns_zone_log(zone, ISC_LOG_ERROR,
5820 "zone_sign:dns_journal_write_transaction -> %s\n",
5821 dns_result_totext(result));
5828 * Pause all iterators so that dns_db_closeversion() can succeed.
5830 for (signing = ISC_LIST_HEAD(zone->signing);
5832 signing = ISC_LIST_NEXT(signing, link))
5833 dns_dbiterator_pause(signing->dbiterator);
5835 for (signing = ISC_LIST_HEAD(cleanup);
5837 signing = ISC_LIST_NEXT(signing, link))
5838 dns_dbiterator_pause(signing->dbiterator);
5841 * Everything has succeeded. Commit the changes.
5843 dns_db_closeversion(db, &version, ISC_TRUE);
5846 * Everything succeeded so we can clean these up now.
5848 signing = ISC_LIST_HEAD(cleanup);
5849 while (signing != NULL) {
5850 ISC_LIST_UNLINK(cleanup, signing, link);
5851 dns_db_detach(&signing->db);
5852 dns_dbiterator_destroy(&signing->dbiterator);
5853 isc_mem_put(zone->mctx, signing, sizeof *signing);
5854 signing = ISC_LIST_HEAD(cleanup);
5857 set_resigntime(zone);
5860 zone_needdump(zone, DNS_DUMP_DELAY);
5865 * Rollback the cleanup list.
5867 signing = ISC_LIST_HEAD(cleanup);
5868 while (signing != NULL) {
5869 ISC_LIST_UNLINK(cleanup, signing, link);
5870 ISC_LIST_APPEND(zone->signing, signing, link);
5871 dns_dbiterator_first(signing->dbiterator);
5872 dns_dbiterator_pause(signing->dbiterator);
5873 signing = ISC_LIST_HEAD(cleanup);
5876 for (signing = ISC_LIST_HEAD(zone->signing);
5878 signing = ISC_LIST_NEXT(signing, link))
5879 dns_dbiterator_pause(signing->dbiterator);
5881 dns_diff_clear(&sig_diff);
5883 for (i = 0; i < nkeys; i++)
5884 dst_key_free(&zone_keys[i]);
5886 if (version != NULL) {
5887 dns_db_closeversion(db, &version, ISC_FALSE);
5889 } else if (db != NULL)
5892 if (ISC_LIST_HEAD(zone->signing) != NULL) {
5894 if (zone->update_disabled || result != ISC_R_SUCCESS)
5895 isc_interval_set(&i, 60, 0); /* 1 minute */
5897 isc_interval_set(&i, 0, 10000000); /* 10 ms */
5898 isc_time_nowplusinterval(&zone->signingtime, &i);
5900 isc_time_settoepoch(&zone->signingtime);
5904 zone_maintenance(dns_zone_t *zone) {
5905 const char me[] = "zone_maintenance";
5907 isc_result_t result;
5908 isc_boolean_t dumping;
5910 REQUIRE(DNS_ZONE_VALID(zone));
5914 * Configuring the view of this zone may have
5915 * failed, for example because the config file
5916 * had a syntax error. In that case, the view
5917 * adb or resolver, and we had better not try
5918 * to do maintenance on it.
5920 if (zone->view == NULL || zone->view->adb == NULL)
5928 switch (zone->type) {
5929 case dns_zone_slave:
5932 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
5933 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
5935 zone->refreshtime = now;
5946 switch (zone->type) {
5947 case dns_zone_slave:
5949 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
5950 isc_time_compare(&now, &zone->refreshtime) >= 0)
5951 dns_zone_refresh(zone);
5958 * Do we need to consolidate the backing store?
5960 switch (zone->type) {
5961 case dns_zone_master:
5962 case dns_zone_slave:
5964 if (zone->masterfile != NULL &&
5965 isc_time_compare(&now, &zone->dumptime) >= 0 &&
5966 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
5967 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
5968 dumping = was_dumping(zone);
5973 result = zone_dump(zone, ISC_TRUE); /* task locked */
5974 if (result != ISC_R_SUCCESS)
5975 dns_zone_log(zone, ISC_LOG_WARNING,
5977 dns_result_totext(result));
5984 switch (zone->type) {
5985 case dns_zone_master:
5986 case dns_zone_slave:
5988 * Do we need to send out notify messages?
5990 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
5991 isc_time_compare(&now, &zone->notifytime) >= 0)
5992 zone_notify(zone, &now);
5994 * Do we need to sign/resign some RRsets?
5996 if (!isc_time_isepoch(&zone->signingtime) &&
5997 isc_time_compare(&now, &zone->signingtime) >= 0)
5999 else if (!isc_time_isepoch(&zone->resigntime) &&
6000 isc_time_compare(&now, &zone->resigntime) >= 0)
6001 zone_resigninc(zone);
6002 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
6003 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
6004 zone_nsec3chain(zone);
6006 * Do we need to issue a key expiry warning.
6008 if (!isc_time_isepoch(&zone->keywarntime) &&
6009 isc_time_compare(&now, &zone->keywarntime) >= 0)
6010 set_key_expiry_warning(zone, zone->key_expiry,
6011 isc_time_seconds(&now));
6016 zone_settimer(zone, &now);
6020 dns_zone_markdirty(dns_zone_t *zone) {
6023 set_resigntime(zone); /* XXXMPA make separate call back */
6024 zone_needdump(zone, DNS_DUMP_DELAY);
6029 dns_zone_expire(dns_zone_t *zone) {
6030 REQUIRE(DNS_ZONE_VALID(zone));
6038 zone_expire(dns_zone_t *zone) {
6040 * 'zone' locked by caller.
6043 REQUIRE(LOCKED_ZONE(zone));
6045 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
6047 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
6048 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
6049 zone->retry = DNS_ZONE_DEFAULTRETRY;
6050 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6055 dns_zone_refresh(dns_zone_t *zone) {
6057 isc_uint32_t oldflags;
6059 isc_result_t result;
6061 REQUIRE(DNS_ZONE_VALID(zone));
6063 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
6067 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
6068 * in progress at a time.
6072 oldflags = zone->flags;
6073 if (zone->masterscnt == 0) {
6074 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
6075 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
6076 dns_zone_log(zone, ISC_LOG_ERROR,
6077 "cannot refresh: no masters");
6080 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6081 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
6082 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6083 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
6087 * Set the next refresh time as if refresh check has failed.
6088 * Setting this to the retry time will do that. XXXMLG
6089 * If we are successful it will be reset using zone->refresh.
6091 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
6093 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
6094 if (result |= ISC_R_SUCCESS)
6095 dns_zone_log(zone, ISC_LOG_WARNING,
6096 "isc_time_nowplusinterval() failed: %s",
6097 dns_result_totext(result));
6100 * When lacking user-specified timer values from the SOA,
6101 * do exponential backoff of the retry time up to a
6102 * maximum of six hours.
6104 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
6105 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
6107 zone->curmaster = 0;
6108 for (j = 0; j < zone->masterscnt; j++)
6109 zone->mastersok[j] = ISC_FALSE;
6110 /* initiate soa query */
6111 queue_soa_query(zone);
6117 dns_zone_flush(dns_zone_t *zone) {
6118 isc_result_t result = ISC_R_SUCCESS;
6119 isc_boolean_t dumping;
6121 REQUIRE(DNS_ZONE_VALID(zone));
6124 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
6125 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6126 zone->masterfile != NULL) {
6127 result = ISC_R_ALREADYRUNNING;
6128 dumping = was_dumping(zone);
6133 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6138 dns_zone_dump(dns_zone_t *zone) {
6139 isc_result_t result = ISC_R_ALREADYRUNNING;
6140 isc_boolean_t dumping;
6142 REQUIRE(DNS_ZONE_VALID(zone));
6145 dumping = was_dumping(zone);
6148 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
6153 zone_needdump(dns_zone_t *zone, unsigned int delay) {
6154 isc_time_t dumptime;
6158 * 'zone' locked by caller
6161 REQUIRE(DNS_ZONE_VALID(zone));
6162 REQUIRE(LOCKED_ZONE(zone));
6165 * Do we have a place to dump to and are we loaded?
6167 if (zone->masterfile == NULL ||
6168 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
6172 /* add some noise */
6173 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
6175 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6176 if (isc_time_isepoch(&zone->dumptime) ||
6177 isc_time_compare(&zone->dumptime, &dumptime) > 0)
6178 zone->dumptime = dumptime;
6179 if (zone->task != NULL)
6180 zone_settimer(zone, &now);
6184 dump_done(void *arg, isc_result_t result) {
6185 const char me[] = "dump_done";
6186 dns_zone_t *zone = arg;
6188 dns_dbversion_t *version;
6189 isc_boolean_t again = ISC_FALSE;
6190 isc_boolean_t compact = ISC_FALSE;
6191 isc_uint32_t serial;
6192 isc_result_t tresult;
6194 REQUIRE(DNS_ZONE_VALID(zone));
6198 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
6199 zone->journalsize != -1) {
6202 * We don't own these, zone->dctx must stay valid.
6204 db = dns_dumpctx_db(zone->dctx);
6205 version = dns_dumpctx_version(zone->dctx);
6207 tresult = dns_db_getsoaserial(db, version, &serial);
6209 * Note: we are task locked here so we can test
6212 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
6213 tresult = dns_journal_compact(zone->mctx,
6220 case ISC_R_NOTFOUND:
6221 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6222 "dns_journal_compact: %s",
6223 dns_result_totext(tresult));
6226 dns_zone_log(zone, ISC_LOG_ERROR,
6227 "dns_journal_compact failed: %s",
6228 dns_result_totext(tresult));
6231 } else if (tresult == ISC_R_SUCCESS) {
6233 zone->compact_serial = serial;
6238 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6240 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
6241 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
6243 * Try again in a short while.
6245 zone_needdump(zone, DNS_DUMP_DELAY);
6246 } else if (result == ISC_R_SUCCESS &&
6247 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6248 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6249 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6250 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6251 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6252 isc_time_settoepoch(&zone->dumptime);
6254 } else if (result == ISC_R_SUCCESS)
6255 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6257 if (zone->dctx != NULL)
6258 dns_dumpctx_detach(&zone->dctx);
6259 zonemgr_putio(&zone->writeio);
6262 (void)zone_dump(zone, ISC_FALSE);
6263 dns_zone_idetach(&zone);
6267 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
6268 const char me[] = "zone_dump";
6269 isc_result_t result;
6270 dns_dbversion_t *version = NULL;
6271 isc_boolean_t again;
6272 dns_db_t *db = NULL;
6273 char *masterfile = NULL;
6274 dns_masterformat_t masterformat = dns_masterformat_none;
6277 * 'compact' MUST only be set if we are task locked.
6280 REQUIRE(DNS_ZONE_VALID(zone));
6284 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6285 if (zone->db != NULL)
6286 dns_db_attach(zone->db, &db);
6287 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6289 if (zone->masterfile != NULL) {
6290 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
6291 masterformat = zone->masterformat;
6295 result = DNS_R_NOTLOADED;
6298 if (masterfile == NULL) {
6299 result = DNS_R_NOMASTERFILE;
6304 dns_zone_t *dummy = NULL;
6306 zone_iattach(zone, &dummy);
6307 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
6308 zone_gotwritehandle, zone,
6310 if (result != ISC_R_SUCCESS)
6311 zone_idetach(&dummy);
6313 result = DNS_R_CONTINUE;
6316 dns_db_currentversion(db, &version);
6317 result = dns_master_dump2(zone->mctx, db, version,
6318 &dns_master_style_default,
6319 masterfile, masterformat);
6320 dns_db_closeversion(db, &version, ISC_FALSE);
6325 if (masterfile != NULL)
6326 isc_mem_free(zone->mctx, masterfile);
6329 if (result == DNS_R_CONTINUE)
6330 return (ISC_R_SUCCESS); /* XXXMPA */
6334 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
6335 if (result != ISC_R_SUCCESS) {
6337 * Try again in a short while.
6339 zone_needdump(zone, DNS_DUMP_DELAY);
6340 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
6341 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
6342 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
6343 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6344 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6345 isc_time_settoepoch(&zone->dumptime);
6348 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
6357 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
6358 dns_masterformat_t format)
6360 isc_result_t result;
6361 dns_dbversion_t *version = NULL;
6362 dns_db_t *db = NULL;
6364 REQUIRE(DNS_ZONE_VALID(zone));
6366 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6367 if (zone->db != NULL)
6368 dns_db_attach(zone->db, &db);
6369 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6371 return (DNS_R_NOTLOADED);
6373 dns_db_currentversion(db, &version);
6374 result = dns_master_dumptostream2(zone->mctx, db, version, style,
6376 dns_db_closeversion(db, &version, ISC_FALSE);
6382 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
6383 const dns_master_style_t *style) {
6384 return dumptostream(zone, fd, style, format);
6388 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
6389 return dumptostream(zone, fd, &dns_master_style_default,
6390 dns_masterformat_text);
6394 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
6395 return dumptostream(zone, fd, &dns_master_style_full,
6396 dns_masterformat_text);
6400 dns_zone_unload(dns_zone_t *zone) {
6401 REQUIRE(DNS_ZONE_VALID(zone));
6409 notify_cancel(dns_zone_t *zone) {
6410 dns_notify_t *notify;
6413 * 'zone' locked by caller.
6416 REQUIRE(LOCKED_ZONE(zone));
6418 for (notify = ISC_LIST_HEAD(zone->notifies);
6420 notify = ISC_LIST_NEXT(notify, link)) {
6421 if (notify->find != NULL)
6422 dns_adb_cancelfind(notify->find);
6423 if (notify->request != NULL)
6424 dns_request_cancel(notify->request);
6429 zone_unload(dns_zone_t *zone) {
6432 * 'zone' locked by caller.
6435 REQUIRE(LOCKED_ZONE(zone));
6437 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6438 zone_detachdb(zone);
6439 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6440 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
6441 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6445 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6446 REQUIRE(DNS_ZONE_VALID(zone));
6449 zone->minrefresh = val;
6453 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
6454 REQUIRE(DNS_ZONE_VALID(zone));
6457 zone->maxrefresh = val;
6461 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
6462 REQUIRE(DNS_ZONE_VALID(zone));
6465 zone->minretry = val;
6469 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
6470 REQUIRE(DNS_ZONE_VALID(zone));
6473 zone->maxretry = val;
6476 static isc_boolean_t
6477 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
6478 dns_notify_t *notify;
6480 for (notify = ISC_LIST_HEAD(zone->notifies);
6482 notify = ISC_LIST_NEXT(notify, link)) {
6483 if (notify->request != NULL)
6485 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
6486 dns_name_equal(name, ¬ify->ns))
6488 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
6494 static isc_boolean_t
6495 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
6496 dns_tsigkey_t *key = NULL;
6499 isc_boolean_t isself;
6500 isc_netaddr_t dstaddr;
6502 if (zone->view == NULL || zone->isself == NULL)
6505 switch (isc_sockaddr_pf(dst)) {
6507 src = zone->notifysrc4;
6508 isc_sockaddr_any(&any);
6511 src = zone->notifysrc6;
6512 isc_sockaddr_any6(&any);
6519 * When sending from any the kernel will assign a source address
6520 * that matches the destination address.
6522 if (isc_sockaddr_eqaddr(&any, &src))
6525 isc_netaddr_fromsockaddr(&dstaddr, dst);
6526 (void)dns_view_getpeertsig(zone->view, &dstaddr, &key);
6527 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
6530 dns_tsigkey_detach(&key);
6535 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
6539 * Caller holds zone lock.
6541 REQUIRE(DNS_NOTIFY_VALID(notify));
6543 if (notify->zone != NULL) {
6545 LOCK_ZONE(notify->zone);
6546 REQUIRE(LOCKED_ZONE(notify->zone));
6547 if (ISC_LINK_LINKED(notify, link))
6548 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
6550 UNLOCK_ZONE(notify->zone);
6552 zone_idetach(¬ify->zone);
6554 dns_zone_idetach(¬ify->zone);
6556 if (notify->find != NULL)
6557 dns_adb_destroyfind(¬ify->find);
6558 if (notify->request != NULL)
6559 dns_request_destroy(¬ify->request);
6560 if (dns_name_dynamic(¬ify->ns))
6561 dns_name_free(¬ify->ns, notify->mctx);
6562 mctx = notify->mctx;
6563 isc_mem_put(notify->mctx, notify, sizeof(*notify));
6564 isc_mem_detach(&mctx);
6568 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
6569 dns_notify_t *notify;
6571 REQUIRE(notifyp != NULL && *notifyp == NULL);
6573 notify = isc_mem_get(mctx, sizeof(*notify));
6575 return (ISC_R_NOMEMORY);
6577 notify->mctx = NULL;
6578 isc_mem_attach(mctx, ¬ify->mctx);
6579 notify->flags = flags;
6580 notify->zone = NULL;
6581 notify->find = NULL;
6582 notify->request = NULL;
6583 isc_sockaddr_any(¬ify->dst);
6584 dns_name_init(¬ify->ns, NULL);
6585 ISC_LINK_INIT(notify, link);
6586 notify->magic = NOTIFY_MAGIC;
6588 return (ISC_R_SUCCESS);
6592 * XXXAG should check for DNS_ZONEFLG_EXITING
6595 process_adb_event(isc_task_t *task, isc_event_t *ev) {
6596 dns_notify_t *notify;
6597 isc_eventtype_t result;
6601 notify = ev->ev_arg;
6602 REQUIRE(DNS_NOTIFY_VALID(notify));
6603 INSIST(task == notify->zone->task);
6604 result = ev->ev_type;
6605 isc_event_free(&ev);
6606 if (result == DNS_EVENT_ADBMOREADDRESSES) {
6607 dns_adb_destroyfind(¬ify->find);
6608 notify_find_address(notify);
6611 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
6612 LOCK_ZONE(notify->zone);
6613 notify_send(notify);
6614 UNLOCK_ZONE(notify->zone);
6616 notify_destroy(notify, ISC_FALSE);
6620 notify_find_address(dns_notify_t *notify) {
6621 isc_result_t result;
6622 unsigned int options;
6624 REQUIRE(DNS_NOTIFY_VALID(notify));
6625 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
6626 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
6628 if (notify->zone->view->adb == NULL)
6631 result = dns_adb_createfind(notify->zone->view->adb,
6633 process_adb_event, notify,
6634 ¬ify->ns, dns_rootname, 0,
6636 notify->zone->view->dstport,
6639 /* Something failed? */
6640 if (result != ISC_R_SUCCESS)
6643 /* More addresses pending? */
6644 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
6647 /* We have as many addresses as we can get. */
6648 LOCK_ZONE(notify->zone);
6649 notify_send(notify);
6650 UNLOCK_ZONE(notify->zone);
6653 notify_destroy(notify, ISC_FALSE);
6658 notify_send_queue(dns_notify_t *notify) {
6660 isc_result_t result;
6662 e = isc_event_allocate(notify->mctx, NULL,
6663 DNS_EVENT_NOTIFYSENDTOADDR,
6665 notify, sizeof(isc_event_t));
6667 return (ISC_R_NOMEMORY);
6669 e->ev_sender = NULL;
6670 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
6671 notify->zone->task, &e);
6672 if (result != ISC_R_SUCCESS)
6678 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
6679 dns_notify_t *notify;
6680 isc_result_t result;
6681 dns_message_t *message = NULL;
6682 isc_netaddr_t dstip;
6683 dns_tsigkey_t *key = NULL;
6684 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6687 isc_boolean_t have_notifysource = ISC_FALSE;
6689 notify = event->ev_arg;
6690 REQUIRE(DNS_NOTIFY_VALID(notify));
6694 LOCK_ZONE(notify->zone);
6696 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
6697 result = ISC_R_CANCELED;
6701 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
6702 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
6703 notify->zone->view->requestmgr == NULL ||
6704 notify->zone->db == NULL) {
6705 result = ISC_R_CANCELED;
6710 * The raw IPv4 address should also exist. Don't send to the
6713 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
6714 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
6715 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6716 notify_log(notify->zone, ISC_LOG_DEBUG(3),
6717 "notify: ignoring IPv6 mapped IPV4 address: %s",
6719 result = ISC_R_CANCELED;
6723 result = notify_createmessage(notify->zone, notify->flags, &message);
6724 if (result != ISC_R_SUCCESS)
6727 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
6728 (void)dns_view_getpeertsig(notify->zone->view, &dstip, &key);
6730 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6731 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
6733 if (notify->zone->view->peers != NULL) {
6734 dns_peer_t *peer = NULL;
6735 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
6737 if (result == ISC_R_SUCCESS) {
6738 result = dns_peer_getnotifysource(peer, &src);
6739 if (result == ISC_R_SUCCESS)
6740 have_notifysource = ISC_TRUE;
6743 switch (isc_sockaddr_pf(¬ify->dst)) {
6745 if (!have_notifysource)
6746 src = notify->zone->notifysrc4;
6749 if (!have_notifysource)
6750 src = notify->zone->notifysrc6;
6753 result = ISC_R_NOTIMPLEMENTED;
6757 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
6759 result = dns_request_createvia2(notify->zone->view->requestmgr,
6760 message, &src, ¬ify->dst, 0, key,
6761 timeout * 3, timeout,
6762 notify->zone->task, notify_done,
6763 notify, ¬ify->request);
6764 if (result == ISC_R_SUCCESS) {
6765 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
6766 inc_stats(notify->zone,
6767 dns_zonestatscounter_notifyoutv4);
6769 inc_stats(notify->zone,
6770 dns_zonestatscounter_notifyoutv6);
6776 dns_tsigkey_detach(&key);
6777 dns_message_destroy(&message);
6779 UNLOCK_ZONE(notify->zone);
6780 if (result != ISC_R_SUCCESS)
6781 notify_destroy(notify, ISC_FALSE);
6782 isc_event_free(&event);
6786 notify_send(dns_notify_t *notify) {
6787 dns_adbaddrinfo_t *ai;
6789 isc_result_t result;
6790 dns_notify_t *new = NULL;
6793 * Zone lock held by caller.
6795 REQUIRE(DNS_NOTIFY_VALID(notify));
6796 REQUIRE(LOCKED_ZONE(notify->zone));
6798 for (ai = ISC_LIST_HEAD(notify->find->list);
6800 ai = ISC_LIST_NEXT(ai, publink)) {
6802 if (notify_isqueued(notify->zone, NULL, &dst))
6804 if (notify_isself(notify->zone, &dst))
6807 result = notify_create(notify->mctx,
6808 (notify->flags & DNS_NOTIFY_NOSOA),
6810 if (result != ISC_R_SUCCESS)
6812 zone_iattach(notify->zone, &new->zone);
6813 ISC_LIST_APPEND(new->zone->notifies, new, link);
6815 result = notify_send_queue(new);
6816 if (result != ISC_R_SUCCESS)
6823 notify_destroy(new, ISC_TRUE);
6827 dns_zone_notify(dns_zone_t *zone) {
6830 REQUIRE(DNS_ZONE_VALID(zone));
6833 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6836 zone_settimer(zone, &now);
6841 zone_notify(dns_zone_t *zone, isc_time_t *now) {
6842 dns_dbnode_t *node = NULL;
6843 dns_db_t *zonedb = NULL;
6844 dns_dbversion_t *version = NULL;
6845 dns_name_t *origin = NULL;
6848 dns_rdata_soa_t soa;
6849 isc_uint32_t serial;
6850 dns_rdata_t rdata = DNS_RDATA_INIT;
6851 dns_rdataset_t nsrdset;
6852 dns_rdataset_t soardset;
6853 isc_result_t result;
6854 dns_notify_t *notify = NULL;
6857 isc_boolean_t isqueued;
6858 dns_notifytype_t notifytype;
6859 unsigned int flags = 0;
6860 isc_boolean_t loggednotify = ISC_FALSE;
6862 REQUIRE(DNS_ZONE_VALID(zone));
6865 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6866 notifytype = zone->notifytype;
6867 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
6870 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
6873 if (notifytype == dns_notifytype_no)
6876 if (notifytype == dns_notifytype_masteronly &&
6877 zone->type != dns_zone_master)
6880 origin = &zone->origin;
6883 * If the zone is dialup we are done as we don't want to send
6884 * the current soa so as to force a refresh query.
6886 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
6887 flags |= DNS_NOTIFY_NOSOA;
6892 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6893 if (zone->db != NULL)
6894 dns_db_attach(zone->db, &zonedb);
6895 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6898 dns_db_currentversion(zonedb, &version);
6899 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
6900 if (result != ISC_R_SUCCESS)
6903 dns_rdataset_init(&soardset);
6904 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
6905 dns_rdatatype_none, 0, &soardset, NULL);
6906 if (result != ISC_R_SUCCESS)
6910 * Find serial and master server's name.
6912 dns_name_init(&master, NULL);
6913 result = dns_rdataset_first(&soardset);
6914 if (result != ISC_R_SUCCESS)
6916 dns_rdataset_current(&soardset, &rdata);
6917 result = dns_rdata_tostruct(&rdata, &soa, NULL);
6918 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6919 dns_rdata_reset(&rdata);
6920 result = dns_name_dup(&soa.origin, zone->mctx, &master);
6921 serial = soa.serial;
6922 dns_rdataset_disassociate(&soardset);
6923 if (result != ISC_R_SUCCESS)
6927 * Enqueue notify requests for 'also-notify' servers.
6930 for (i = 0; i < zone->notifycnt; i++) {
6931 dst = zone->notify[i];
6932 if (notify_isqueued(zone, NULL, &dst))
6934 result = notify_create(zone->mctx, flags, ¬ify);
6935 if (result != ISC_R_SUCCESS)
6937 zone_iattach(zone, ¬ify->zone);
6939 ISC_LIST_APPEND(zone->notifies, notify, link);
6940 result = notify_send_queue(notify);
6941 if (result != ISC_R_SUCCESS)
6942 notify_destroy(notify, ISC_TRUE);
6943 if (!loggednotify) {
6944 notify_log(zone, ISC_LOG_INFO,
6945 "sending notifies (serial %u)",
6947 loggednotify = ISC_TRUE;
6953 if (notifytype == dns_notifytype_explicit)
6957 * Process NS RRset to generate notifies.
6960 dns_rdataset_init(&nsrdset);
6961 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
6962 dns_rdatatype_none, 0, &nsrdset, NULL);
6963 if (result != ISC_R_SUCCESS)
6966 result = dns_rdataset_first(&nsrdset);
6967 while (result == ISC_R_SUCCESS) {
6968 dns_rdataset_current(&nsrdset, &rdata);
6969 result = dns_rdata_tostruct(&rdata, &ns, NULL);
6970 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6971 dns_rdata_reset(&rdata);
6973 * Don't notify the master server unless explicitly
6974 * configured to do so.
6976 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
6977 dns_name_compare(&master, &ns.name) == 0) {
6978 result = dns_rdataset_next(&nsrdset);
6982 if (!loggednotify) {
6983 notify_log(zone, ISC_LOG_INFO,
6984 "sending notifies (serial %u)",
6986 loggednotify = ISC_TRUE;
6990 isqueued = notify_isqueued(zone, &ns.name, NULL);
6993 result = dns_rdataset_next(&nsrdset);
6996 result = notify_create(zone->mctx, flags, ¬ify);
6997 if (result != ISC_R_SUCCESS)
6999 dns_zone_iattach(zone, ¬ify->zone);
7000 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
7001 if (result != ISC_R_SUCCESS) {
7003 notify_destroy(notify, ISC_TRUE);
7008 ISC_LIST_APPEND(zone->notifies, notify, link);
7010 notify_find_address(notify);
7012 result = dns_rdataset_next(&nsrdset);
7014 dns_rdataset_disassociate(&nsrdset);
7017 if (dns_name_dynamic(&master))
7018 dns_name_free(&master, zone->mctx);
7020 dns_db_detachnode(zonedb, &node);
7022 dns_db_closeversion(zonedb, &version, ISC_FALSE);
7023 dns_db_detach(&zonedb);
7030 static inline isc_result_t
7031 save_nsrrset(dns_message_t *message, dns_name_t *name,
7032 dns_db_t *db, dns_dbversion_t *version)
7034 dns_rdataset_t *nsrdataset = NULL;
7035 dns_rdataset_t *rdataset = NULL;
7036 dns_dbnode_t *node = NULL;
7038 isc_result_t result;
7039 dns_rdata_t rdata = DNS_RDATA_INIT;
7042 * Extract NS RRset from message.
7044 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
7045 dns_rdatatype_ns, dns_rdatatype_none,
7047 if (result != ISC_R_SUCCESS)
7053 result = dns_db_findnode(db, name, ISC_TRUE, &node);
7054 if (result != ISC_R_SUCCESS)
7056 result = dns_db_addrdataset(db, node, version, 0,
7057 nsrdataset, 0, NULL);
7058 dns_db_detachnode(db, &node);
7059 if (result != ISC_R_SUCCESS)
7062 * Add glue rdatasets.
7064 for (result = dns_rdataset_first(nsrdataset);
7065 result == ISC_R_SUCCESS;
7066 result = dns_rdataset_next(nsrdataset)) {
7067 dns_rdataset_current(nsrdataset, &rdata);
7068 result = dns_rdata_tostruct(&rdata, &ns, NULL);
7069 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7070 dns_rdata_reset(&rdata);
7071 if (!dns_name_issubdomain(&ns.name, name))
7074 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7075 &ns.name, dns_rdatatype_aaaa,
7076 dns_rdatatype_none, NULL,
7078 if (result == ISC_R_SUCCESS) {
7079 result = dns_db_findnode(db, &ns.name,
7081 if (result != ISC_R_SUCCESS)
7083 result = dns_db_addrdataset(db, node, version, 0,
7085 dns_db_detachnode(db, &node);
7086 if (result != ISC_R_SUCCESS)
7090 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
7091 &ns.name, dns_rdatatype_a,
7092 dns_rdatatype_none, NULL,
7094 if (result == ISC_R_SUCCESS) {
7095 result = dns_db_findnode(db, &ns.name,
7097 if (result != ISC_R_SUCCESS)
7099 result = dns_db_addrdataset(db, node, version, 0,
7101 dns_db_detachnode(db, &node);
7102 if (result != ISC_R_SUCCESS)
7106 if (result != ISC_R_NOMORE)
7109 return (ISC_R_SUCCESS);
7116 stub_callback(isc_task_t *task, isc_event_t *event) {
7117 const char me[] = "stub_callback";
7118 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7119 dns_stub_t *stub = NULL;
7120 dns_message_t *msg = NULL;
7121 dns_zone_t *zone = NULL;
7122 char master[ISC_SOCKADDR_FORMATSIZE];
7123 char source[ISC_SOCKADDR_FORMATSIZE];
7124 isc_uint32_t nscnt, cnamecnt;
7125 isc_result_t result;
7127 isc_boolean_t exiting = ISC_FALSE;
7131 stub = revent->ev_arg;
7132 INSIST(DNS_STUB_VALID(stub));
7142 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7143 zone_debuglog(zone, me, 1, "exiting");
7148 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7149 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7151 if (revent->result != ISC_R_SUCCESS) {
7152 if (revent->result == ISC_R_TIMEDOUT &&
7153 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7155 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7157 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7158 "refreshing stub: timeout retrying "
7159 " without EDNS master %s (source %s)",
7163 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
7164 &zone->sourceaddr, &now);
7165 dns_zone_log(zone, ISC_LOG_INFO,
7166 "could not refresh stub from master %s"
7167 " (source %s): %s", master, source,
7168 dns_result_totext(revent->result));
7172 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7173 if (result != ISC_R_SUCCESS)
7176 result = dns_request_getresponse(revent->request, msg, 0);
7177 if (result != ISC_R_SUCCESS)
7183 if (msg->rcode != dns_rcode_noerror) {
7187 isc_buffer_init(&rb, rcode, sizeof(rcode));
7188 (void)dns_rcode_totext(msg->rcode, &rb);
7190 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7191 (msg->rcode == dns_rcode_servfail ||
7192 msg->rcode == dns_rcode_notimp ||
7193 msg->rcode == dns_rcode_formerr)) {
7194 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7195 "refreshing stub: rcode (%.*s) retrying "
7196 "without EDNS master %s (source %s)",
7197 (int)rb.used, rcode, master, source);
7199 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7204 dns_zone_log(zone, ISC_LOG_INFO,
7206 "unexpected rcode (%.*s) from %s (source %s)",
7207 (int)rb.used, rcode, master, source);
7212 * We need complete messages.
7214 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7215 if (dns_request_usedtcp(revent->request)) {
7216 dns_zone_log(zone, ISC_LOG_INFO,
7217 "refreshing stub: truncated TCP "
7218 "response from master %s (source %s)",
7223 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7229 * If non-auth log and next master.
7231 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7232 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
7233 "non-authoritative answer from "
7234 "master %s (source %s)", master, source);
7241 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7242 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
7244 if (cnamecnt != 0) {
7245 dns_zone_log(zone, ISC_LOG_INFO,
7246 "refreshing stub: unexpected CNAME response "
7247 "from master %s (source %s)", master, source);
7252 dns_zone_log(zone, ISC_LOG_INFO,
7253 "refreshing stub: no NS records in response "
7254 "from master %s (source %s)", master, source);
7261 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
7262 if (result != ISC_R_SUCCESS) {
7263 dns_zone_log(zone, ISC_LOG_INFO,
7264 "refreshing stub: unable to save NS records "
7265 "from master %s (source %s)", master, source);
7272 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
7273 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
7274 if (zone->db == NULL)
7275 zone_attachdb(zone, stub->db);
7276 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
7277 dns_db_detach(&stub->db);
7279 if (zone->masterfile != NULL) {
7280 dns_zone_dump(zone);
7281 TIME_NOW(&zone->loadtime);
7284 dns_message_destroy(&msg);
7285 isc_event_free(&event);
7287 dns_request_destroy(&zone->request);
7288 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7289 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7290 isc_interval_set(&i, zone->expire, 0);
7291 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7292 zone_settimer(zone, &now);
7297 if (stub->version != NULL)
7298 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
7299 if (stub->db != NULL)
7300 dns_db_detach(&stub->db);
7302 dns_message_destroy(&msg);
7303 isc_event_free(&event);
7305 dns_request_destroy(&zone->request);
7307 * Skip to next failed / untried master.
7311 } while (zone->curmaster < zone->masterscnt &&
7312 zone->mastersok[zone->curmaster]);
7313 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7314 if (exiting || zone->curmaster >= zone->masterscnt) {
7315 isc_boolean_t done = ISC_TRUE;
7317 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7318 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7320 * Did we get a good answer from all the masters?
7322 for (j = 0; j < zone->masterscnt; j++)
7323 if (zone->mastersok[j] == ISC_FALSE) {
7330 zone->curmaster = 0;
7332 * Find the next failed master.
7334 while (zone->curmaster < zone->masterscnt &&
7335 zone->mastersok[zone->curmaster])
7337 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7339 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7341 zone_settimer(zone, &now);
7346 queue_soa_query(zone);
7352 dns_message_destroy(&msg);
7353 isc_event_free(&event);
7355 dns_request_destroy(&zone->request);
7357 ns_query(zone, NULL, stub);
7362 dns_zone_idetach(&stub->zone);
7363 INSIST(stub->db == NULL);
7364 INSIST(stub->version == NULL);
7365 isc_mem_put(stub->mctx, stub, sizeof(*stub));
7368 INSIST(event == NULL);
7373 * An SOA query has finished (successfully or not).
7376 refresh_callback(isc_task_t *task, isc_event_t *event) {
7377 const char me[] = "refresh_callback";
7378 dns_requestevent_t *revent = (dns_requestevent_t *)event;
7380 dns_message_t *msg = NULL;
7381 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
7383 char master[ISC_SOCKADDR_FORMATSIZE];
7384 char source[ISC_SOCKADDR_FORMATSIZE];
7385 dns_rdataset_t *rdataset = NULL;
7386 dns_rdata_t rdata = DNS_RDATA_INIT;
7387 dns_rdata_soa_t soa;
7388 isc_result_t result;
7389 isc_uint32_t serial;
7392 zone = revent->ev_arg;
7393 INSIST(DNS_ZONE_VALID(zone));
7400 * if timeout log and next master;
7403 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
7404 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
7408 if (revent->result != ISC_R_SUCCESS) {
7409 if (revent->result == ISC_R_TIMEDOUT &&
7410 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
7412 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7414 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7415 "refresh: timeout retrying without EDNS "
7416 "master %s (source %s)", master, source);
7419 if (revent->result == ISC_R_TIMEDOUT &&
7420 !dns_request_usedtcp(revent->request)) {
7421 dns_zone_log(zone, ISC_LOG_INFO,
7422 "refresh: retry limit for "
7423 "master %s exceeded (source %s)",
7425 /* Try with slave with TCP. */
7426 if (zone->type == dns_zone_slave &&
7427 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
7428 if (!dns_zonemgr_unreachable(zone->zmgr,
7433 DNS_ZONE_SETFLAG(zone,
7434 DNS_ZONEFLG_SOABEFOREAXFR);
7438 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7439 "refresh: skipped tcp fallback"
7440 "as master %s (source %s) is "
7441 "unreachable (cached)",
7445 dns_zone_log(zone, ISC_LOG_INFO,
7446 "refresh: failure trying master "
7447 "%s (source %s): %s", master, source,
7448 dns_result_totext(revent->result));
7452 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7453 if (result != ISC_R_SUCCESS)
7455 result = dns_request_getresponse(revent->request, msg, 0);
7456 if (result != ISC_R_SUCCESS) {
7457 dns_zone_log(zone, ISC_LOG_INFO,
7458 "refresh: failure trying master "
7459 "%s (source %s): %s", master, source,
7460 dns_result_totext(result));
7467 if (msg->rcode != dns_rcode_noerror) {
7471 isc_buffer_init(&rb, rcode, sizeof(rcode));
7472 (void)dns_rcode_totext(msg->rcode, &rb);
7474 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
7475 (msg->rcode == dns_rcode_servfail ||
7476 msg->rcode == dns_rcode_notimp ||
7477 msg->rcode == dns_rcode_formerr)) {
7478 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7479 "refresh: rcode (%.*s) retrying without "
7480 "EDNS master %s (source %s)",
7481 (int)rb.used, rcode, master, source);
7483 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7487 dns_zone_log(zone, ISC_LOG_INFO,
7488 "refresh: unexpected rcode (%.*s) from "
7489 "master %s (source %s)", (int)rb.used, rcode,
7492 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
7494 if (msg->rcode == dns_rcode_refused &&
7495 zone->type == dns_zone_slave)
7501 * If truncated punt to zone transfer which will query again.
7503 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
7504 if (zone->type == dns_zone_slave) {
7505 dns_zone_log(zone, ISC_LOG_INFO,
7506 "refresh: truncated UDP answer, "
7507 "initiating TCP zone xfer "
7508 "for master %s (source %s)",
7511 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
7515 INSIST(zone->type == dns_zone_stub);
7516 if (dns_request_usedtcp(revent->request)) {
7517 dns_zone_log(zone, ISC_LOG_INFO,
7518 "refresh: truncated TCP response "
7519 "from master %s (source %s)",
7524 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
7531 * if non-auth log and next master;
7533 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
7534 dns_zone_log(zone, ISC_LOG_INFO,
7535 "refresh: non-authoritative answer from "
7536 "master %s (source %s)", master, source);
7540 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
7541 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
7542 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
7543 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
7547 * There should not be a CNAME record at top of zone.
7549 if (cnamecnt != 0) {
7550 dns_zone_log(zone, ISC_LOG_INFO,
7551 "refresh: CNAME at top of zone "
7552 "in master %s (source %s)", master, source);
7557 * if referral log and next master;
7559 if (soacnt == 0 && soacount == 0 && nscount != 0) {
7560 dns_zone_log(zone, ISC_LOG_INFO,
7561 "refresh: referral response "
7562 "from master %s (source %s)", master, source);
7567 * if nodata log and next master;
7569 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
7570 dns_zone_log(zone, ISC_LOG_INFO,
7571 "refresh: NODATA response "
7572 "from master %s (source %s)", master, source);
7577 * Only one soa at top of zone.
7580 dns_zone_log(zone, ISC_LOG_INFO,
7581 "refresh: answer SOA count (%d) != 1 "
7582 "from master %s (source %s)",
7583 soacnt, master, source);
7590 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
7591 dns_rdatatype_soa, dns_rdatatype_none,
7593 if (result != ISC_R_SUCCESS) {
7594 dns_zone_log(zone, ISC_LOG_INFO,
7595 "refresh: unable to get SOA record "
7596 "from master %s (source %s)", master, source);
7600 result = dns_rdataset_first(rdataset);
7601 if (result != ISC_R_SUCCESS) {
7602 dns_zone_log(zone, ISC_LOG_INFO,
7603 "refresh: dns_rdataset_first() failed");
7607 dns_rdataset_current(rdataset, &rdata);
7608 result = dns_rdata_tostruct(&rdata, &soa, NULL);
7609 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7611 serial = soa.serial;
7613 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
7614 serial, zone->serial);
7615 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
7616 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
7617 isc_serial_gt(serial, zone->serial)) {
7618 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
7619 &zone->sourceaddr, &now)) {
7620 dns_zone_log(zone, ISC_LOG_INFO,
7621 "refresh: skipping %s as master %s "
7622 "(source %s) is unreachable (cached)",
7623 zone->type == dns_zone_slave ?
7624 "zone transfer" : "NS query",
7629 isc_event_free(&event);
7631 dns_request_destroy(&zone->request);
7633 if (zone->type == dns_zone_slave) {
7636 INSIST(zone->type == dns_zone_stub);
7637 ns_query(zone, rdataset, NULL);
7640 dns_message_destroy(&msg);
7641 } else if (isc_serial_eq(soa.serial, zone->serial)) {
7642 if (zone->masterfile != NULL) {
7643 result = ISC_R_FAILURE;
7644 if (zone->journal != NULL)
7645 result = isc_file_settime(zone->journal, &now);
7646 if (result == ISC_R_SUCCESS &&
7647 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
7648 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
7649 result = isc_file_settime(zone->masterfile,
7651 } else if (result != ISC_R_SUCCESS)
7652 result = isc_file_settime(zone->masterfile,
7654 /* Someone removed the file from underneath us! */
7655 if (result == ISC_R_FILENOTFOUND) {
7657 zone_needdump(zone, DNS_DUMP_DELAY);
7659 } else if (result != ISC_R_SUCCESS)
7660 dns_zone_log(zone, ISC_LOG_ERROR,
7661 "refresh: could not set file "
7662 "modification time of '%s': %s",
7664 dns_result_totext(result));
7666 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
7667 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
7668 zone->mastersok[zone->curmaster] = ISC_TRUE;
7671 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
7672 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
7673 "received from master %s < ours (%u)",
7674 soa.serial, master, zone->serial);
7676 zone_debuglog(zone, me, 1, "ahead");
7677 zone->mastersok[zone->curmaster] = ISC_TRUE;
7681 dns_message_destroy(&msg);
7686 dns_message_destroy(&msg);
7687 isc_event_free(&event);
7689 dns_request_destroy(&zone->request);
7691 * Skip to next failed / untried master.
7695 } while (zone->curmaster < zone->masterscnt &&
7696 zone->mastersok[zone->curmaster]);
7697 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
7698 if (zone->curmaster >= zone->masterscnt) {
7699 isc_boolean_t done = ISC_TRUE;
7700 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
7701 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7703 * Did we get a good answer from all the masters?
7705 for (j = 0; j < zone->masterscnt; j++)
7706 if (zone->mastersok[j] == ISC_FALSE) {
7713 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7714 zone->curmaster = 0;
7716 * Find the next failed master.
7718 while (zone->curmaster < zone->masterscnt &&
7719 zone->mastersok[zone->curmaster])
7723 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
7724 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
7725 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
7726 zone->refreshtime = now;
7728 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
7729 zone_settimer(zone, &now);
7735 queue_soa_query(zone);
7741 dns_message_destroy(&msg);
7742 isc_event_free(&event);
7744 dns_request_destroy(&zone->request);
7745 queue_soa_query(zone);
7749 dns_zone_idetach(&zone);
7754 queue_soa_query(dns_zone_t *zone) {
7755 const char me[] = "queue_soa_query";
7757 dns_zone_t *dummy = NULL;
7758 isc_result_t result;
7764 REQUIRE(LOCKED_ZONE(zone));
7766 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7767 cancel_refresh(zone);
7771 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
7772 soa_query, zone, sizeof(isc_event_t));
7774 cancel_refresh(zone);
7779 * Attach so that we won't clean up
7780 * until the event is delivered.
7782 zone_iattach(zone, &dummy);
7785 e->ev_sender = NULL;
7786 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
7787 if (result != ISC_R_SUCCESS) {
7788 zone_idetach(&dummy);
7790 cancel_refresh(zone);
7794 static inline isc_result_t
7795 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
7796 dns_message_t **messagep)
7798 dns_message_t *message = NULL;
7799 dns_name_t *qname = NULL;
7800 dns_rdataset_t *qrdataset = NULL;
7801 isc_result_t result;
7803 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
7805 if (result != ISC_R_SUCCESS)
7808 message->opcode = dns_opcode_query;
7809 message->rdclass = zone->rdclass;
7811 result = dns_message_gettempname(message, &qname);
7812 if (result != ISC_R_SUCCESS)
7815 result = dns_message_gettemprdataset(message, &qrdataset);
7816 if (result != ISC_R_SUCCESS)
7822 dns_name_init(qname, NULL);
7823 dns_name_clone(&zone->origin, qname);
7824 dns_rdataset_init(qrdataset);
7825 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
7826 ISC_LIST_APPEND(qname->list, qrdataset, link);
7827 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
7829 *messagep = message;
7830 return (ISC_R_SUCCESS);
7834 dns_message_puttempname(message, &qname);
7835 if (qrdataset != NULL)
7836 dns_message_puttemprdataset(message, &qrdataset);
7837 if (message != NULL)
7838 dns_message_destroy(&message);
7843 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
7844 dns_rdataset_t *rdataset = NULL;
7845 dns_rdatalist_t *rdatalist = NULL;
7846 dns_rdata_t *rdata = NULL;
7847 isc_result_t result;
7849 result = dns_message_gettemprdatalist(message, &rdatalist);
7850 if (result != ISC_R_SUCCESS)
7852 result = dns_message_gettemprdata(message, &rdata);
7853 if (result != ISC_R_SUCCESS)
7855 result = dns_message_gettemprdataset(message, &rdataset);
7856 if (result != ISC_R_SUCCESS)
7858 dns_rdataset_init(rdataset);
7860 rdatalist->type = dns_rdatatype_opt;
7861 rdatalist->covers = 0;
7864 * Set Maximum UDP buffer size.
7866 rdatalist->rdclass = udpsize;
7869 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
7873 /* Set EDNS options if applicable */
7875 unsigned char data[4];
7878 isc_buffer_init(&buf, data, sizeof(data));
7879 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
7880 isc_buffer_putuint16(&buf, 0);
7882 rdata->length = sizeof(data);
7888 rdata->rdclass = rdatalist->rdclass;
7889 rdata->type = rdatalist->type;
7892 ISC_LIST_INIT(rdatalist->rdata);
7893 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
7894 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
7897 return (dns_message_setopt(message, rdataset));
7900 if (rdatalist != NULL)
7901 dns_message_puttemprdatalist(message, &rdatalist);
7902 if (rdataset != NULL)
7903 dns_message_puttemprdataset(message, &rdataset);
7905 dns_message_puttemprdata(message, &rdata);
7911 soa_query(isc_task_t *task, isc_event_t *event) {
7912 const char me[] = "soa_query";
7913 isc_result_t result = ISC_R_FAILURE;
7914 dns_message_t *message = NULL;
7915 dns_zone_t *zone = event->ev_arg;
7916 dns_zone_t *dummy = NULL;
7917 isc_netaddr_t masterip;
7918 dns_tsigkey_t *key = NULL;
7919 isc_uint32_t options;
7920 isc_boolean_t cancel = ISC_TRUE;
7922 isc_boolean_t have_xfrsource, reqnsid;
7923 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
7925 REQUIRE(DNS_ZONE_VALID(zone));
7932 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
7933 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
7934 zone->view->requestmgr == NULL) {
7935 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
7941 * XXX Optimisation: Create message when zone is setup and reuse.
7943 result = create_query(zone, dns_rdatatype_soa, &message);
7944 if (result != ISC_R_SUCCESS)
7948 INSIST(zone->masterscnt > 0);
7949 INSIST(zone->curmaster < zone->masterscnt);
7951 zone->masteraddr = zone->masters[zone->curmaster];
7953 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
7955 * First, look for a tsig key in the master statement, then
7956 * try for a server key.
7958 if ((zone->masterkeynames != NULL) &&
7959 (zone->masterkeynames[zone->curmaster] != NULL)) {
7960 dns_view_t *view = dns_zone_getview(zone);
7961 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
7962 result = dns_view_gettsig(view, keyname, &key);
7963 if (result != ISC_R_SUCCESS) {
7964 char namebuf[DNS_NAME_FORMATSIZE];
7965 dns_name_format(keyname, namebuf, sizeof(namebuf));
7966 dns_zone_log(zone, ISC_LOG_ERROR,
7967 "unable to find key: %s", namebuf);
7971 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
7973 have_xfrsource = ISC_FALSE;
7974 reqnsid = zone->view->requestnsid;
7975 if (zone->view->peers != NULL) {
7976 dns_peer_t *peer = NULL;
7978 result = dns_peerlist_peerbyaddr(zone->view->peers,
7980 if (result == ISC_R_SUCCESS) {
7981 result = dns_peer_getsupportedns(peer, &edns);
7982 if (result == ISC_R_SUCCESS && !edns)
7983 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
7984 result = dns_peer_gettransfersource(peer,
7986 if (result == ISC_R_SUCCESS)
7987 have_xfrsource = ISC_TRUE;
7988 if (zone->view->resolver != NULL)
7990 dns_resolver_getudpsize(zone->view->resolver);
7991 (void)dns_peer_getudpsize(peer, &udpsize);
7992 (void)dns_peer_getrequestnsid(peer, &reqnsid);
7996 switch (isc_sockaddr_pf(&zone->masteraddr)) {
7998 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
7999 if (isc_sockaddr_equal(&zone->altxfrsource4,
8002 zone->sourceaddr = zone->altxfrsource4;
8003 } else if (!have_xfrsource)
8004 zone->sourceaddr = zone->xfrsource4;
8007 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
8008 if (isc_sockaddr_equal(&zone->altxfrsource6,
8011 zone->sourceaddr = zone->altxfrsource6;
8012 } else if (!have_xfrsource)
8013 zone->sourceaddr = zone->xfrsource6;
8016 result = ISC_R_NOTIMPLEMENTED;
8020 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
8021 DNS_REQUESTOPT_TCP : 0;
8023 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8024 result = add_opt(message, udpsize, reqnsid);
8025 if (result != ISC_R_SUCCESS)
8026 zone_debuglog(zone, me, 1,
8027 "unable to add opt record: %s",
8028 dns_result_totext(result));
8031 zone_iattach(zone, &dummy);
8033 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8035 result = dns_request_createvia2(zone->view->requestmgr, message,
8036 &zone->sourceaddr, &zone->masteraddr,
8037 options, key, timeout * 3, timeout,
8038 zone->task, refresh_callback, zone,
8040 if (result != ISC_R_SUCCESS) {
8041 zone_idetach(&dummy);
8042 zone_debuglog(zone, me, 1,
8043 "dns_request_createvia2() failed: %s",
8044 dns_result_totext(result));
8047 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
8048 inc_stats(zone, dns_zonestatscounter_soaoutv4);
8050 inc_stats(zone, dns_zonestatscounter_soaoutv6);
8056 dns_tsigkey_detach(&key);
8057 if (result != ISC_R_SUCCESS)
8058 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8059 if (message != NULL)
8060 dns_message_destroy(&message);
8062 cancel_refresh(zone);
8063 isc_event_free(&event);
8065 dns_zone_idetach(&zone);
8070 dns_tsigkey_detach(&key);
8072 * Skip to next failed / untried master.
8076 } while (zone->curmaster < zone->masterscnt &&
8077 zone->mastersok[zone->curmaster]);
8078 if (zone->curmaster < zone->masterscnt)
8080 zone->curmaster = 0;
8085 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
8086 const char me[] = "ns_query";
8087 isc_result_t result;
8088 dns_message_t *message = NULL;
8089 isc_netaddr_t masterip;
8090 dns_tsigkey_t *key = NULL;
8091 dns_dbnode_t *node = NULL;
8093 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
8094 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
8096 REQUIRE(DNS_ZONE_VALID(zone));
8097 REQUIRE((soardataset != NULL && stub == NULL) ||
8098 (soardataset == NULL && stub != NULL));
8099 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
8105 stub = isc_mem_get(zone->mctx, sizeof(*stub));
8108 stub->magic = STUB_MAGIC;
8109 stub->mctx = zone->mctx;
8112 stub->version = NULL;
8115 * Attach so that the zone won't disappear from under us.
8117 zone_iattach(zone, &stub->zone);
8120 * If a db exists we will update it, otherwise we create a
8121 * new one and attach it to the zone once we have the NS
8124 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8125 if (zone->db != NULL) {
8126 dns_db_attach(zone->db, &stub->db);
8127 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8129 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8131 INSIST(zone->db_argc >= 1);
8132 result = dns_db_create(zone->mctx, zone->db_argv[0],
8133 &zone->origin, dns_dbtype_stub,
8138 if (result != ISC_R_SUCCESS) {
8139 dns_zone_log(zone, ISC_LOG_ERROR,
8143 dns_result_totext(result));
8146 dns_db_settask(stub->db, zone->task);
8149 dns_db_newversion(stub->db, &stub->version);
8152 * Update SOA record.
8154 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
8156 if (result != ISC_R_SUCCESS) {
8157 dns_zone_log(zone, ISC_LOG_INFO,
8159 "dns_db_findnode() failed: %s",
8160 dns_result_totext(result));
8164 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
8165 soardataset, 0, NULL);
8166 dns_db_detachnode(stub->db, &node);
8167 if (result != ISC_R_SUCCESS) {
8168 dns_zone_log(zone, ISC_LOG_INFO,
8170 "dns_db_addrdataset() failed: %s",
8171 dns_result_totext(result));
8177 * XXX Optimisation: Create message when zone is setup and reuse.
8179 result = create_query(zone, dns_rdatatype_ns, &message);
8181 INSIST(zone->masterscnt > 0);
8182 INSIST(zone->curmaster < zone->masterscnt);
8183 zone->masteraddr = zone->masters[zone->curmaster];
8185 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
8187 * First, look for a tsig key in the master statement, then
8188 * try for a server key.
8190 if ((zone->masterkeynames != NULL) &&
8191 (zone->masterkeynames[zone->curmaster] != NULL)) {
8192 dns_view_t *view = dns_zone_getview(zone);
8193 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
8194 result = dns_view_gettsig(view, keyname, &key);
8195 if (result != ISC_R_SUCCESS) {
8196 char namebuf[DNS_NAME_FORMATSIZE];
8197 dns_name_format(keyname, namebuf, sizeof(namebuf));
8198 dns_zone_log(zone, ISC_LOG_ERROR,
8199 "unable to find key: %s", namebuf);
8203 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
8205 reqnsid = zone->view->requestnsid;
8206 if (zone->view->peers != NULL) {
8207 dns_peer_t *peer = NULL;
8209 result = dns_peerlist_peerbyaddr(zone->view->peers,
8211 if (result == ISC_R_SUCCESS) {
8212 result = dns_peer_getsupportedns(peer, &edns);
8213 if (result == ISC_R_SUCCESS && !edns)
8214 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
8215 result = dns_peer_gettransfersource(peer,
8217 if (result == ISC_R_SUCCESS)
8218 have_xfrsource = ISC_TRUE;
8219 if (zone->view->resolver != NULL)
8221 dns_resolver_getudpsize(zone->view->resolver);
8222 (void)dns_peer_getudpsize(peer, &udpsize);
8223 (void)dns_peer_getrequestnsid(peer, &reqnsid);
8227 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
8228 result = add_opt(message, udpsize, reqnsid);
8229 if (result != ISC_R_SUCCESS)
8230 zone_debuglog(zone, me, 1,
8231 "unable to add opt record: %s",
8232 dns_result_totext(result));
8236 * Always use TCP so that we shouldn't truncate in additional section.
8238 switch (isc_sockaddr_pf(&zone->masteraddr)) {
8240 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8241 zone->sourceaddr = zone->altxfrsource4;
8242 else if (!have_xfrsource)
8243 zone->sourceaddr = zone->xfrsource4;
8246 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
8247 zone->sourceaddr = zone->altxfrsource6;
8248 else if (!have_xfrsource)
8249 zone->sourceaddr = zone->xfrsource6;
8252 result = ISC_R_NOTIMPLEMENTED;
8256 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
8258 result = dns_request_createvia2(zone->view->requestmgr, message,
8259 &zone->sourceaddr, &zone->masteraddr,
8260 DNS_REQUESTOPT_TCP, key, timeout * 3,
8261 timeout, zone->task, stub_callback,
8262 stub, &zone->request);
8263 if (result != ISC_R_SUCCESS) {
8264 zone_debuglog(zone, me, 1,
8265 "dns_request_createvia() failed: %s",
8266 dns_result_totext(result));
8269 dns_message_destroy(&message);
8273 cancel_refresh(zone);
8276 if (stub->version != NULL)
8277 dns_db_closeversion(stub->db, &stub->version,
8279 if (stub->db != NULL)
8280 dns_db_detach(&stub->db);
8281 if (stub->zone != NULL)
8282 zone_idetach(&stub->zone);
8283 isc_mem_put(stub->mctx, stub, sizeof(*stub));
8285 if (message != NULL)
8286 dns_message_destroy(&message);
8289 dns_tsigkey_detach(&key);
8295 * Handle the control event. Note that although this event causes the zone
8296 * to shut down, it is not a shutdown event in the sense of the task library.
8299 zone_shutdown(isc_task_t *task, isc_event_t *event) {
8300 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
8301 isc_boolean_t free_needed, linked = ISC_FALSE;
8304 REQUIRE(DNS_ZONE_VALID(zone));
8305 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
8306 INSIST(isc_refcount_current(&zone->erefs) == 0);
8307 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
8310 * Stop things being restarted after we cancel them below.
8313 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
8317 * If we were waiting for xfrin quota, step out of
8319 * If there's no zone manager, we can't be waiting for the
8322 if (zone->zmgr != NULL) {
8323 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8324 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
8325 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
8328 zone->statelist = NULL;
8330 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
8334 * In task context, no locking required. See zone_xfrdone().
8336 if (zone->xfr != NULL)
8337 dns_xfrin_shutdown(zone->xfr);
8341 INSIST(zone->irefs > 0);
8344 if (zone->request != NULL) {
8345 dns_request_cancel(zone->request);
8348 if (zone->readio != NULL)
8349 zonemgr_cancelio(zone->readio);
8351 if (zone->lctx != NULL)
8352 dns_loadctx_cancel(zone->lctx);
8354 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8355 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8356 if (zone->writeio != NULL)
8357 zonemgr_cancelio(zone->writeio);
8359 if (zone->dctx != NULL)
8360 dns_dumpctx_cancel(zone->dctx);
8363 notify_cancel(zone);
8365 if (zone->timer != NULL) {
8366 isc_timer_detach(&zone->timer);
8367 INSIST(zone->irefs > 0);
8371 if (zone->view != NULL)
8372 dns_view_weakdetach(&zone->view);
8375 * We have now canceled everything set the flag to allow exit_check()
8376 * to succeed. We must not unlock between setting this flag and
8377 * calling exit_check().
8379 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
8380 free_needed = exit_check(zone);
8387 zone_timer(isc_task_t *task, isc_event_t *event) {
8388 const char me[] = "zone_timer";
8389 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
8392 REQUIRE(DNS_ZONE_VALID(zone));
8396 zone_maintenance(zone);
8398 isc_event_free(&event);
8402 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
8403 const char me[] = "zone_settimer";
8405 isc_result_t result;
8407 REQUIRE(DNS_ZONE_VALID(zone));
8408 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8411 isc_time_settoepoch(&next);
8413 switch (zone->type) {
8414 case dns_zone_master:
8415 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8416 next = zone->notifytime;
8417 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8418 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8419 INSIST(!isc_time_isepoch(&zone->dumptime));
8420 if (isc_time_isepoch(&next) ||
8421 isc_time_compare(&zone->dumptime, &next) < 0)
8422 next = zone->dumptime;
8424 if (!isc_time_isepoch(&zone->resigntime)) {
8425 if (isc_time_isepoch(&next) ||
8426 isc_time_compare(&zone->resigntime, &next) < 0)
8427 next = zone->resigntime;
8429 if (!isc_time_isepoch(&zone->keywarntime)) {
8430 if (isc_time_isepoch(&next) ||
8431 isc_time_compare(&zone->keywarntime, &next) < 0)
8432 next = zone->keywarntime;
8434 if (!isc_time_isepoch(&zone->signingtime)) {
8435 if (isc_time_isepoch(&next) ||
8436 isc_time_compare(&zone->signingtime, &next) < 0)
8437 next = zone->signingtime;
8439 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
8440 if (isc_time_isepoch(&next) ||
8441 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
8442 next = zone->nsec3chaintime;
8446 case dns_zone_slave:
8447 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
8448 next = zone->notifytime;
8452 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
8453 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
8454 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
8455 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
8456 INSIST(!isc_time_isepoch(&zone->refreshtime));
8457 if (isc_time_isepoch(&next) ||
8458 isc_time_compare(&zone->refreshtime, &next) < 0)
8459 next = zone->refreshtime;
8461 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8462 INSIST(!isc_time_isepoch(&zone->expiretime));
8463 if (isc_time_isepoch(&next) ||
8464 isc_time_compare(&zone->expiretime, &next) < 0)
8465 next = zone->expiretime;
8467 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8468 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8469 INSIST(!isc_time_isepoch(&zone->dumptime));
8470 if (isc_time_isepoch(&next) ||
8471 isc_time_compare(&zone->dumptime, &next) < 0)
8472 next = zone->dumptime;
8480 if (isc_time_isepoch(&next)) {
8481 zone_debuglog(zone, me, 10, "settimer inactive");
8482 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
8483 NULL, NULL, ISC_TRUE);
8484 if (result != ISC_R_SUCCESS)
8485 dns_zone_log(zone, ISC_LOG_ERROR,
8486 "could not deactivate zone timer: %s",
8487 isc_result_totext(result));
8489 if (isc_time_compare(&next, now) <= 0)
8491 result = isc_timer_reset(zone->timer, isc_timertype_once,
8492 &next, NULL, ISC_TRUE);
8493 if (result != ISC_R_SUCCESS)
8494 dns_zone_log(zone, ISC_LOG_ERROR,
8495 "could not reset zone timer: %s",
8496 isc_result_totext(result));
8501 cancel_refresh(dns_zone_t *zone) {
8502 const char me[] = "cancel_refresh";
8506 * 'zone' locked by caller.
8509 REQUIRE(DNS_ZONE_VALID(zone));
8510 REQUIRE(LOCKED_ZONE(zone));
8514 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
8516 zone_settimer(zone, &now);
8520 notify_createmessage(dns_zone_t *zone, unsigned int flags,
8521 dns_message_t **messagep)
8523 dns_db_t *zonedb = NULL;
8524 dns_dbnode_t *node = NULL;
8525 dns_dbversion_t *version = NULL;
8526 dns_message_t *message = NULL;
8527 dns_rdataset_t rdataset;
8528 dns_rdata_t rdata = DNS_RDATA_INIT;
8530 dns_name_t *tempname = NULL;
8531 dns_rdata_t *temprdata = NULL;
8532 dns_rdatalist_t *temprdatalist = NULL;
8533 dns_rdataset_t *temprdataset = NULL;
8535 isc_result_t result;
8537 isc_buffer_t *b = NULL;
8539 REQUIRE(DNS_ZONE_VALID(zone));
8540 REQUIRE(messagep != NULL && *messagep == NULL);
8542 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
8544 if (result != ISC_R_SUCCESS)
8547 message->opcode = dns_opcode_notify;
8548 message->flags |= DNS_MESSAGEFLAG_AA;
8549 message->rdclass = zone->rdclass;
8551 result = dns_message_gettempname(message, &tempname);
8552 if (result != ISC_R_SUCCESS)
8555 result = dns_message_gettemprdataset(message, &temprdataset);
8556 if (result != ISC_R_SUCCESS)
8562 dns_name_init(tempname, NULL);
8563 dns_name_clone(&zone->origin, tempname);
8564 dns_rdataset_init(temprdataset);
8565 dns_rdataset_makequestion(temprdataset, zone->rdclass,
8567 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8568 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
8570 temprdataset = NULL;
8572 if ((flags & DNS_NOTIFY_NOSOA) != 0)
8575 result = dns_message_gettempname(message, &tempname);
8576 if (result != ISC_R_SUCCESS)
8578 result = dns_message_gettemprdata(message, &temprdata);
8579 if (result != ISC_R_SUCCESS)
8581 result = dns_message_gettemprdataset(message, &temprdataset);
8582 if (result != ISC_R_SUCCESS)
8584 result = dns_message_gettemprdatalist(message, &temprdatalist);
8585 if (result != ISC_R_SUCCESS)
8588 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8589 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
8590 dns_db_attach(zone->db, &zonedb);
8591 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8593 dns_name_init(tempname, NULL);
8594 dns_name_clone(&zone->origin, tempname);
8595 dns_db_currentversion(zonedb, &version);
8596 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
8597 if (result != ISC_R_SUCCESS)
8600 dns_rdataset_init(&rdataset);
8601 result = dns_db_findrdataset(zonedb, node, version,
8603 dns_rdatatype_none, 0, &rdataset,
8605 if (result != ISC_R_SUCCESS)
8607 result = dns_rdataset_first(&rdataset);
8608 if (result != ISC_R_SUCCESS)
8610 dns_rdataset_current(&rdataset, &rdata);
8611 dns_rdata_toregion(&rdata, &r);
8612 result = isc_buffer_allocate(zone->mctx, &b, r.length);
8613 if (result != ISC_R_SUCCESS)
8615 isc_buffer_putmem(b, r.base, r.length);
8616 isc_buffer_usedregion(b, &r);
8617 dns_rdata_init(temprdata);
8618 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
8619 dns_message_takebuffer(message, &b);
8620 result = dns_rdataset_next(&rdataset);
8621 dns_rdataset_disassociate(&rdataset);
8622 if (result != ISC_R_NOMORE)
8624 temprdatalist->rdclass = rdata.rdclass;
8625 temprdatalist->type = rdata.type;
8626 temprdatalist->covers = 0;
8627 temprdatalist->ttl = rdataset.ttl;
8628 ISC_LIST_INIT(temprdatalist->rdata);
8629 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
8631 dns_rdataset_init(temprdataset);
8632 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
8633 if (result != ISC_R_SUCCESS)
8636 ISC_LIST_APPEND(tempname->list, temprdataset, link);
8637 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
8638 temprdatalist = NULL;
8639 temprdataset = NULL;
8645 dns_db_detachnode(zonedb, &node);
8646 if (version != NULL)
8647 dns_db_closeversion(zonedb, &version, ISC_FALSE);
8649 dns_db_detach(&zonedb);
8650 if (tempname != NULL)
8651 dns_message_puttempname(message, &tempname);
8652 if (temprdata != NULL)
8653 dns_message_puttemprdata(message, &temprdata);
8654 if (temprdataset != NULL)
8655 dns_message_puttemprdataset(message, &temprdataset);
8656 if (temprdatalist != NULL)
8657 dns_message_puttemprdatalist(message, &temprdatalist);
8660 *messagep = message;
8661 return (ISC_R_SUCCESS);
8664 if (tempname != NULL)
8665 dns_message_puttempname(message, &tempname);
8666 if (temprdataset != NULL)
8667 dns_message_puttemprdataset(message, &temprdataset);
8668 dns_message_destroy(&message);
8673 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
8677 dns_rdata_soa_t soa;
8678 dns_rdataset_t *rdataset = NULL;
8679 dns_rdata_t rdata = DNS_RDATA_INIT;
8680 isc_result_t result;
8681 char fromtext[ISC_SOCKADDR_FORMATSIZE];
8683 isc_netaddr_t netaddr;
8685 REQUIRE(DNS_ZONE_VALID(zone));
8688 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
8692 * Check that 'from' is a valid notify source, (zone->masters).
8693 * Return DNS_R_REFUSED if not.
8695 * If the notify message contains a serial number check it
8696 * against the zones serial and return if <= current serial
8698 * If a refresh check is progress, if so just record the
8699 * fact we received a NOTIFY and from where and return.
8700 * We will perform a new refresh check when the current one
8701 * completes. Return ISC_R_SUCCESS.
8703 * Otherwise initiate a refresh check using 'from' as the
8704 * first address to check. Return ISC_R_SUCCESS.
8707 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
8710 * We only handle NOTIFY (SOA) at the present.
8713 if (isc_sockaddr_pf(from) == PF_INET)
8714 inc_stats(zone, dns_zonestatscounter_notifyinv4);
8716 inc_stats(zone, dns_zonestatscounter_notifyinv6);
8717 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
8718 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
8719 dns_rdatatype_soa, dns_rdatatype_none,
8720 NULL, NULL) != ISC_R_SUCCESS) {
8722 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
8723 dns_zone_log(zone, ISC_LOG_NOTICE,
8725 "question section from: %s", fromtext);
8726 return (DNS_R_FORMERR);
8728 dns_zone_log(zone, ISC_LOG_NOTICE,
8729 "NOTIFY zone does not match");
8730 return (DNS_R_NOTIMP);
8734 * If we are a master zone just succeed.
8736 if (zone->type == dns_zone_master) {
8738 return (ISC_R_SUCCESS);
8741 isc_netaddr_fromsockaddr(&netaddr, from);
8742 for (i = 0; i < zone->masterscnt; i++) {
8743 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
8745 if (zone->view->aclenv.match_mapped &&
8746 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
8747 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
8748 isc_netaddr_t na1, na2;
8749 isc_netaddr_fromv4mapped(&na1, &netaddr);
8750 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
8751 if (isc_netaddr_equal(&na1, &na2))
8757 * Accept notify requests from non masters if they are on
8758 * 'zone->notify_acl'.
8760 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
8761 dns_acl_match(&netaddr, NULL, zone->notify_acl,
8762 &zone->view->aclenv,
8763 &match, NULL) == ISC_R_SUCCESS &&
8766 /* Accept notify. */
8767 } else if (i >= zone->masterscnt) {
8769 dns_zone_log(zone, ISC_LOG_INFO,
8770 "refused notify from non-master: %s", fromtext);
8771 inc_stats(zone, dns_zonestatscounter_notifyrej);
8772 return (DNS_R_REFUSED);
8776 * If the zone is loaded and there are answers check the serial
8777 * to see if we need to do a refresh. Do not worry about this
8778 * check if we are a dialup zone as we use the notify request
8779 * to trigger a refresh check.
8781 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
8782 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8783 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
8784 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
8787 dns_rdatatype_none, NULL,
8789 if (result == ISC_R_SUCCESS)
8790 result = dns_rdataset_first(rdataset);
8791 if (result == ISC_R_SUCCESS) {
8792 isc_uint32_t serial = 0;
8794 dns_rdataset_current(rdataset, &rdata);
8795 result = dns_rdata_tostruct(&rdata, &soa, NULL);
8796 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8797 serial = soa.serial;
8798 if (isc_serial_le(serial, zone->serial)) {
8799 dns_zone_log(zone, ISC_LOG_INFO,
8801 "zone is up to date",
8804 return (ISC_R_SUCCESS);
8810 * If we got this far and there was a refresh in progress just
8811 * let it complete. Record where we got the notify from so we
8812 * can perform a refresh check when the current one completes
8814 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
8815 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
8816 zone->notifyfrom = *from;
8818 dns_zone_log(zone, ISC_LOG_INFO,
8819 "notify from %s: refresh in progress, "
8820 "refresh check queued",
8822 return (ISC_R_SUCCESS);
8824 zone->notifyfrom = *from;
8826 dns_zone_refresh(zone);
8827 return (ISC_R_SUCCESS);
8831 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
8833 REQUIRE(DNS_ZONE_VALID(zone));
8836 if (zone->notify_acl != NULL)
8837 dns_acl_detach(&zone->notify_acl);
8838 dns_acl_attach(acl, &zone->notify_acl);
8843 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
8845 REQUIRE(DNS_ZONE_VALID(zone));
8848 if (zone->query_acl != NULL)
8849 dns_acl_detach(&zone->query_acl);
8850 dns_acl_attach(acl, &zone->query_acl);
8855 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
8857 REQUIRE(DNS_ZONE_VALID(zone));
8860 if (zone->queryon_acl != NULL)
8861 dns_acl_detach(&zone->queryon_acl);
8862 dns_acl_attach(acl, &zone->queryon_acl);
8867 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
8869 REQUIRE(DNS_ZONE_VALID(zone));
8872 if (zone->update_acl != NULL)
8873 dns_acl_detach(&zone->update_acl);
8874 dns_acl_attach(acl, &zone->update_acl);
8879 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
8881 REQUIRE(DNS_ZONE_VALID(zone));
8884 if (zone->forward_acl != NULL)
8885 dns_acl_detach(&zone->forward_acl);
8886 dns_acl_attach(acl, &zone->forward_acl);
8891 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
8893 REQUIRE(DNS_ZONE_VALID(zone));
8896 if (zone->xfr_acl != NULL)
8897 dns_acl_detach(&zone->xfr_acl);
8898 dns_acl_attach(acl, &zone->xfr_acl);
8903 dns_zone_getnotifyacl(dns_zone_t *zone) {
8905 REQUIRE(DNS_ZONE_VALID(zone));
8907 return (zone->notify_acl);
8911 dns_zone_getqueryacl(dns_zone_t *zone) {
8913 REQUIRE(DNS_ZONE_VALID(zone));
8915 return (zone->query_acl);
8919 dns_zone_getqueryonacl(dns_zone_t *zone) {
8921 REQUIRE(DNS_ZONE_VALID(zone));
8923 return (zone->queryon_acl);
8927 dns_zone_getupdateacl(dns_zone_t *zone) {
8929 REQUIRE(DNS_ZONE_VALID(zone));
8931 return (zone->update_acl);
8935 dns_zone_getforwardacl(dns_zone_t *zone) {
8937 REQUIRE(DNS_ZONE_VALID(zone));
8939 return (zone->forward_acl);
8943 dns_zone_getxfracl(dns_zone_t *zone) {
8945 REQUIRE(DNS_ZONE_VALID(zone));
8947 return (zone->xfr_acl);
8951 dns_zone_clearupdateacl(dns_zone_t *zone) {
8953 REQUIRE(DNS_ZONE_VALID(zone));
8956 if (zone->update_acl != NULL)
8957 dns_acl_detach(&zone->update_acl);
8962 dns_zone_clearforwardacl(dns_zone_t *zone) {
8964 REQUIRE(DNS_ZONE_VALID(zone));
8967 if (zone->forward_acl != NULL)
8968 dns_acl_detach(&zone->forward_acl);
8973 dns_zone_clearnotifyacl(dns_zone_t *zone) {
8975 REQUIRE(DNS_ZONE_VALID(zone));
8978 if (zone->notify_acl != NULL)
8979 dns_acl_detach(&zone->notify_acl);
8984 dns_zone_clearqueryacl(dns_zone_t *zone) {
8986 REQUIRE(DNS_ZONE_VALID(zone));
8989 if (zone->query_acl != NULL)
8990 dns_acl_detach(&zone->query_acl);
8995 dns_zone_clearqueryonacl(dns_zone_t *zone) {
8997 REQUIRE(DNS_ZONE_VALID(zone));
9000 if (zone->queryon_acl != NULL)
9001 dns_acl_detach(&zone->queryon_acl);
9006 dns_zone_clearxfracl(dns_zone_t *zone) {
9008 REQUIRE(DNS_ZONE_VALID(zone));
9011 if (zone->xfr_acl != NULL)
9012 dns_acl_detach(&zone->xfr_acl);
9017 dns_zone_getupdatedisabled(dns_zone_t *zone) {
9018 REQUIRE(DNS_ZONE_VALID(zone));
9019 return (zone->update_disabled);
9024 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
9025 REQUIRE(DNS_ZONE_VALID(zone));
9026 zone->update_disabled = state;
9030 dns_zone_getzeronosoattl(dns_zone_t *zone) {
9031 REQUIRE(DNS_ZONE_VALID(zone));
9032 return (zone->zero_no_soa_ttl);
9037 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
9038 REQUIRE(DNS_ZONE_VALID(zone));
9039 zone->zero_no_soa_ttl = state;
9043 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
9045 REQUIRE(DNS_ZONE_VALID(zone));
9047 zone->check_names = severity;
9051 dns_zone_getchecknames(dns_zone_t *zone) {
9053 REQUIRE(DNS_ZONE_VALID(zone));
9055 return (zone->check_names);
9059 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
9061 REQUIRE(DNS_ZONE_VALID(zone));
9063 zone->journalsize = size;
9067 dns_zone_getjournalsize(dns_zone_t *zone) {
9069 REQUIRE(DNS_ZONE_VALID(zone));
9071 return (zone->journalsize);
9075 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
9076 isc_result_t result = ISC_R_FAILURE;
9077 isc_buffer_t buffer;
9079 REQUIRE(buf != NULL);
9080 REQUIRE(length > 1U);
9083 * Leave space for terminating '\0'.
9085 isc_buffer_init(&buffer, buf, length - 1);
9086 if (dns_name_dynamic(&zone->origin))
9087 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9088 if (result != ISC_R_SUCCESS &&
9089 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9090 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9092 if (isc_buffer_availablelength(&buffer) > 0)
9093 isc_buffer_putstr(&buffer, "/");
9094 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9096 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
9097 strcmp(zone->view->name, "_default") != 0 &&
9098 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
9099 isc_buffer_putstr(&buffer, "/");
9100 isc_buffer_putstr(&buffer, zone->view->name);
9103 buf[isc_buffer_usedlength(&buffer)] = '\0';
9107 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
9108 isc_result_t result = ISC_R_FAILURE;
9109 isc_buffer_t buffer;
9111 REQUIRE(buf != NULL);
9112 REQUIRE(length > 1U);
9115 * Leave space for terminating '\0'.
9117 isc_buffer_init(&buffer, buf, length - 1);
9118 if (dns_name_dynamic(&zone->origin))
9119 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
9120 if (result != ISC_R_SUCCESS &&
9121 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
9122 isc_buffer_putstr(&buffer, "<UNKNOWN>");
9124 buf[isc_buffer_usedlength(&buffer)] = '\0';
9128 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
9129 isc_buffer_t buffer;
9131 REQUIRE(buf != NULL);
9132 REQUIRE(length > 1U);
9135 * Leave space for terminating '\0'.
9137 isc_buffer_init(&buffer, buf, length - 1);
9138 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
9140 buf[isc_buffer_usedlength(&buffer)] = '\0';
9144 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
9145 isc_buffer_t buffer;
9147 REQUIRE(buf != NULL);
9148 REQUIRE(length > 1U);
9152 * Leave space for terminating '\0'.
9154 isc_buffer_init(&buffer, buf, length - 1);
9156 if (zone->view == NULL) {
9157 isc_buffer_putstr(&buffer, "_none");
9158 } else if (strlen(zone->view->name)
9159 < isc_buffer_availablelength(&buffer)) {
9160 isc_buffer_putstr(&buffer, zone->view->name);
9162 isc_buffer_putstr(&buffer, "_toolong");
9165 buf[isc_buffer_usedlength(&buffer)] = '\0';
9169 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
9170 REQUIRE(DNS_ZONE_VALID(zone));
9171 REQUIRE(buf != NULL);
9172 zone_namerd_tostr(zone, buf, length);
9176 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9180 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9184 vsnprintf(message, sizeof(message), fmt, ap);
9186 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
9187 level, "zone %s: %s", zone->strnamerd, message);
9191 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
9192 int level, const char *fmt, ...) {
9196 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9200 vsnprintf(message, sizeof(message), fmt, ap);
9202 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
9203 level, "zone %s: %s", zone->strnamerd, message);
9207 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
9211 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9215 vsnprintf(message, sizeof(message), fmt, ap);
9217 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9218 level, "zone %s: %s", zone->strnamerd, message);
9222 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
9223 const char *fmt, ...)
9227 int level = ISC_LOG_DEBUG(debuglevel);
9229 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
9233 vsnprintf(message, sizeof(message), fmt, ap);
9235 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
9236 level, "%s: zone %s: %s", me, zone->strnamerd, message);
9240 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
9242 isc_result_t result;
9244 dns_rdataset_t *curr;
9247 result = dns_message_firstname(msg, section);
9248 while (result == ISC_R_SUCCESS) {
9250 dns_message_currentname(msg, section, &name);
9252 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
9253 curr = ISC_LIST_PREV(curr, link)) {
9254 if (curr->type == type)
9257 result = dns_message_nextname(msg, section);
9264 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
9265 REQUIRE(DNS_ZONE_VALID(zone));
9267 zone->maxxfrin = maxxfrin;
9271 dns_zone_getmaxxfrin(dns_zone_t *zone) {
9272 REQUIRE(DNS_ZONE_VALID(zone));
9274 return (zone->maxxfrin);
9278 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
9279 REQUIRE(DNS_ZONE_VALID(zone));
9280 zone->maxxfrout = maxxfrout;
9284 dns_zone_getmaxxfrout(dns_zone_t *zone) {
9285 REQUIRE(DNS_ZONE_VALID(zone));
9287 return (zone->maxxfrout);
9291 dns_zone_gettype(dns_zone_t *zone) {
9292 REQUIRE(DNS_ZONE_VALID(zone));
9294 return (zone->type);
9298 dns_zone_getorigin(dns_zone_t *zone) {
9299 REQUIRE(DNS_ZONE_VALID(zone));
9301 return (&zone->origin);
9305 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
9306 REQUIRE(DNS_ZONE_VALID(zone));
9309 if (zone->task != NULL)
9310 isc_task_detach(&zone->task);
9311 isc_task_attach(task, &zone->task);
9312 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9313 if (zone->db != NULL)
9314 dns_db_settask(zone->db, zone->task);
9315 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9320 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
9321 REQUIRE(DNS_ZONE_VALID(zone));
9322 isc_task_attach(zone->task, target);
9326 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
9327 REQUIRE(DNS_ZONE_VALID(zone));
9330 idlein = DNS_DEFAULT_IDLEIN;
9331 zone->idlein = idlein;
9335 dns_zone_getidlein(dns_zone_t *zone) {
9336 REQUIRE(DNS_ZONE_VALID(zone));
9338 return (zone->idlein);
9342 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
9343 REQUIRE(DNS_ZONE_VALID(zone));
9345 zone->idleout = idleout;
9349 dns_zone_getidleout(dns_zone_t *zone) {
9350 REQUIRE(DNS_ZONE_VALID(zone));
9352 return (zone->idleout);
9356 notify_done(isc_task_t *task, isc_event_t *event) {
9357 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9358 dns_notify_t *notify;
9359 isc_result_t result;
9360 dns_message_t *message = NULL;
9363 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9367 notify = event->ev_arg;
9368 REQUIRE(DNS_NOTIFY_VALID(notify));
9369 INSIST(task == notify->zone->task);
9371 isc_buffer_init(&buf, rcode, sizeof(rcode));
9372 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9374 result = revent->result;
9375 if (result == ISC_R_SUCCESS)
9376 result = dns_message_create(notify->zone->mctx,
9377 DNS_MESSAGE_INTENTPARSE, &message);
9378 if (result == ISC_R_SUCCESS)
9379 result = dns_request_getresponse(revent->request, message,
9380 DNS_MESSAGEPARSE_PRESERVEORDER);
9381 if (result == ISC_R_SUCCESS)
9382 result = dns_rcode_totext(message->rcode, &buf);
9383 if (result == ISC_R_SUCCESS)
9384 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9385 "notify response from %s: %.*s",
9386 addrbuf, (int)buf.used, rcode);
9388 notify_log(notify->zone, ISC_LOG_DEBUG(2),
9389 "notify to %s failed: %s", addrbuf,
9390 dns_result_totext(result));
9393 * Old bind's return formerr if they see a soa record. Retry w/o
9394 * the soa if we see a formerr and had sent a SOA.
9396 isc_event_free(&event);
9397 if (message != NULL && message->rcode == dns_rcode_formerr &&
9398 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
9399 notify->flags |= DNS_NOTIFY_NOSOA;
9400 dns_request_destroy(¬ify->request);
9401 result = notify_send_queue(notify);
9402 if (result != ISC_R_SUCCESS)
9403 notify_destroy(notify, ISC_FALSE);
9405 if (result == ISC_R_TIMEDOUT)
9406 notify_log(notify->zone, ISC_LOG_DEBUG(1),
9407 "notify to %s: retries exceeded", addrbuf);
9408 notify_destroy(notify, ISC_FALSE);
9410 if (message != NULL)
9411 dns_message_destroy(&message);
9415 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9416 isc_result_t result;
9418 REQUIRE(DNS_ZONE_VALID(zone));
9420 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9421 result = zone_replacedb(zone, db, dump);
9422 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9428 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
9429 dns_dbversion_t *ver;
9430 isc_result_t result;
9431 unsigned int soacount = 0;
9432 unsigned int nscount = 0;
9435 * 'zone' and 'zonedb' locked by caller.
9437 REQUIRE(DNS_ZONE_VALID(zone));
9438 REQUIRE(LOCKED_ZONE(zone));
9440 result = zone_get_from_db(zone, db, &nscount, &soacount,
9441 NULL, NULL, NULL, NULL, NULL, NULL);
9442 if (result == ISC_R_SUCCESS) {
9443 if (soacount != 1) {
9444 dns_zone_log(zone, ISC_LOG_ERROR,
9445 "has %d SOA records", soacount);
9446 result = DNS_R_BADZONE;
9449 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
9450 result = DNS_R_BADZONE;
9452 if (result != ISC_R_SUCCESS)
9455 dns_zone_log(zone, ISC_LOG_ERROR,
9456 "retrieving SOA and NS records failed: %s",
9457 dns_result_totext(result));
9461 result = check_nsec3param(zone, db);
9462 if (result != ISC_R_SUCCESS)
9466 dns_db_currentversion(db, &ver);
9469 * The initial version of a slave zone is always dumped;
9470 * subsequent versions may be journaled instead if this
9471 * is enabled in the configuration.
9473 if (zone->db != NULL && zone->journal != NULL &&
9474 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
9475 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
9476 isc_uint32_t serial;
9478 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
9480 result = dns_db_getsoaserial(db, ver, &serial);
9481 if (result != ISC_R_SUCCESS) {
9482 dns_zone_log(zone, ISC_LOG_ERROR,
9483 "ixfr-from-differences: unable to get "
9489 * This is checked in zone_postload() for master zones.
9491 if (zone->type == dns_zone_slave &&
9492 !isc_serial_gt(serial, zone->serial)) {
9493 isc_uint32_t serialmin, serialmax;
9494 serialmin = (zone->serial + 1) & 0xffffffffU;
9495 serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU;
9496 dns_zone_log(zone, ISC_LOG_ERROR,
9497 "ixfr-from-differences: failed: "
9498 "new serial (%u) out of range [%u - %u]",
9499 serial, serialmin, serialmax);
9500 result = ISC_R_RANGE;
9504 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
9506 if (result != ISC_R_SUCCESS)
9509 zone_needdump(zone, DNS_DUMP_DELAY);
9510 else if (zone->journalsize != -1) {
9511 result = dns_journal_compact(zone->mctx, zone->journal,
9512 serial, zone->journalsize);
9516 case ISC_R_NOTFOUND:
9517 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9518 "dns_journal_compact: %s",
9519 dns_result_totext(result));
9522 dns_zone_log(zone, ISC_LOG_ERROR,
9523 "dns_journal_compact failed: %s",
9524 dns_result_totext(result));
9529 if (dump && zone->masterfile != NULL) {
9530 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9531 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9532 "dumping new zone version");
9533 result = dns_db_dump2(db, ver, zone->masterfile,
9534 zone->masterformat);
9535 if (result != ISC_R_SUCCESS)
9539 * Update the time the zone was updated, so
9540 * dns_zone_load can avoid loading it when
9541 * the server is reloaded. If isc_time_now
9542 * fails for some reason, all that happens is
9543 * the timestamp is not updated.
9545 TIME_NOW(&zone->loadtime);
9548 if (dump && zone->journal != NULL) {
9550 * The in-memory database just changed, and
9551 * because 'dump' is set, it didn't change by
9552 * being loaded from disk. Also, we have not
9553 * journaled diffs for this change.
9554 * Therefore, the on-disk journal is missing
9555 * the deltas for this change. Since it can
9556 * no longer be used to bring the zone
9557 * up-to-date, it is useless and should be
9560 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9561 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9562 "removing journal file");
9563 if (remove(zone->journal) < 0 && errno != ENOENT) {
9564 char strbuf[ISC_STRERRORSIZE];
9565 isc__strerror(errno, strbuf, sizeof(strbuf));
9566 isc_log_write(dns_lctx,
9567 DNS_LOGCATEGORY_GENERAL,
9570 "unable to remove journal "
9572 zone->journal, strbuf);
9577 dns_db_closeversion(db, &ver, ISC_FALSE);
9579 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
9580 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
9581 "replacing zone database");
9583 if (zone->db != NULL)
9584 zone_detachdb(zone);
9585 zone_attachdb(zone, db);
9586 dns_db_settask(zone->db, zone->task);
9587 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
9588 return (ISC_R_SUCCESS);
9591 dns_db_closeversion(db, &ver, ISC_FALSE);
9595 /* The caller must hold the dblock as a writer. */
9597 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
9598 REQUIRE(zone->db == NULL && db != NULL);
9600 dns_db_attach(db, &zone->db);
9601 if (zone->acache != NULL) {
9602 isc_result_t result;
9603 result = dns_acache_setdb(zone->acache, db);
9604 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
9605 UNEXPECTED_ERROR(__FILE__, __LINE__,
9606 "dns_acache_setdb() failed: %s",
9607 isc_result_totext(result));
9612 /* The caller must hold the dblock as a writer. */
9614 zone_detachdb(dns_zone_t *zone) {
9615 REQUIRE(zone->db != NULL);
9617 if (zone->acache != NULL)
9618 (void)dns_acache_putdb(zone->acache, zone->db);
9619 dns_db_detach(&zone->db);
9623 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
9625 isc_boolean_t again = ISC_FALSE;
9626 unsigned int soacount;
9627 unsigned int nscount;
9628 isc_uint32_t serial, refresh, retry, expire, minimum;
9629 isc_result_t xfrresult = result;
9630 isc_boolean_t free_needed;
9632 REQUIRE(DNS_ZONE_VALID(zone));
9634 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9635 "zone transfer finished: %s", dns_result_totext(result));
9638 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
9639 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9640 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9645 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9647 case DNS_R_UPTODATE:
9648 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
9650 * Has the zone expired underneath us?
9652 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9653 if (zone->db == NULL) {
9654 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9659 * Update the zone structure's data from the actual
9664 INSIST(zone->db != NULL);
9665 result = zone_get_from_db(zone, zone->db, &nscount,
9666 &soacount, &serial, &refresh,
9667 &retry, &expire, &minimum, NULL);
9668 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9669 if (result == ISC_R_SUCCESS) {
9671 dns_zone_log(zone, ISC_LOG_ERROR,
9673 "has %d SOA record%s", soacount,
9674 (soacount != 0) ? "s" : "");
9676 dns_zone_log(zone, ISC_LOG_ERROR,
9678 "has no NS records");
9679 if (DNS_ZONE_FLAG(zone,
9680 DNS_ZONEFLG_HAVETIMERS)) {
9681 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9682 zone->retry = DNS_ZONE_DEFAULTRETRY;
9684 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9688 zone->serial = serial;
9689 zone->refresh = RANGE(refresh, zone->minrefresh,
9691 zone->retry = RANGE(retry, zone->minretry,
9693 zone->expire = RANGE(expire,
9694 zone->refresh + zone->retry,
9696 zone->minimum = minimum;
9697 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9701 * Set our next update/expire times.
9703 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
9704 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
9705 zone->refreshtime = now;
9706 DNS_ZONE_TIME_ADD(&now, zone->expire,
9709 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
9710 &zone->refreshtime);
9711 DNS_ZONE_TIME_ADD(&now, zone->expire,
9714 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
9715 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
9716 if (zone->tsigkey != NULL) {
9717 char namebuf[DNS_NAME_FORMATSIZE];
9718 dns_name_format(&zone->tsigkey->name, namebuf,
9720 snprintf(buf, sizeof(buf), ": TSIG '%s'",
9724 dns_zone_log(zone, ISC_LOG_INFO,
9725 "transferred serial %u%s",
9730 * This is not necessary if we just performed a AXFR
9731 * however it is necessary for an IXFR / UPTODATE and
9732 * won't hurt with an AXFR.
9734 if (zone->masterfile != NULL || zone->journal != NULL) {
9735 result = ISC_R_FAILURE;
9736 if (zone->journal != NULL)
9737 result = isc_file_settime(zone->journal, &now);
9738 if (result != ISC_R_SUCCESS &&
9739 zone->masterfile != NULL)
9740 result = isc_file_settime(zone->masterfile,
9742 /* Someone removed the file from underneath us! */
9743 if (result == ISC_R_FILENOTFOUND &&
9744 zone->masterfile != NULL)
9745 zone_needdump(zone, DNS_DUMP_DELAY);
9746 else if (result != ISC_R_SUCCESS)
9747 dns_zone_log(zone, ISC_LOG_ERROR,
9748 "transfer: could not set file "
9749 "modification time of '%s': %s",
9751 dns_result_totext(result));
9754 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
9758 /* Force retry with AXFR. */
9759 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
9765 * Skip to next failed / untried master.
9769 } while (zone->curmaster < zone->masterscnt &&
9770 zone->mastersok[zone->curmaster]);
9773 if (zone->curmaster >= zone->masterscnt) {
9774 zone->curmaster = 0;
9775 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9776 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9777 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9778 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9779 while (zone->curmaster < zone->masterscnt &&
9780 zone->mastersok[zone->curmaster])
9784 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9786 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9789 inc_stats(zone, dns_zonestatscounter_xfrfail);
9792 zone_settimer(zone, &now);
9795 * If creating the transfer object failed, zone->xfr is NULL.
9796 * Otherwise, we are called as the done callback of a zone
9797 * transfer object that just entered its shutting-down
9798 * state. Since we are no longer responsible for shutting
9799 * it down, we can detach our reference.
9801 if (zone->xfr != NULL)
9802 dns_xfrin_detach(&zone->xfr);
9804 if (zone->tsigkey != NULL)
9805 dns_tsigkey_detach(&zone->tsigkey);
9808 * Handle any deferred journal compaction.
9810 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
9811 result = dns_journal_compact(zone->mctx, zone->journal,
9812 zone->compact_serial,
9817 case ISC_R_NOTFOUND:
9818 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9819 "dns_journal_compact: %s",
9820 dns_result_totext(result));
9823 dns_zone_log(zone, ISC_LOG_ERROR,
9824 "dns_journal_compact failed: %s",
9825 dns_result_totext(result));
9828 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9832 * This transfer finishing freed up a transfer quota slot.
9833 * Let any other zones waiting for quota have it.
9835 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9836 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
9837 zone->statelist = NULL;
9838 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
9839 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
9842 * Retry with a different server if necessary.
9844 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9845 queue_soa_query(zone);
9847 INSIST(zone->irefs > 0);
9849 free_needed = exit_check(zone);
9856 zone_loaddone(void *arg, isc_result_t result) {
9857 static char me[] = "zone_loaddone";
9858 dns_load_t *load = arg;
9860 isc_result_t tresult;
9862 REQUIRE(DNS_LOAD_VALID(load));
9867 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
9868 if (tresult != ISC_R_SUCCESS &&
9869 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
9872 LOCK_ZONE(load->zone);
9873 (void)zone_postload(load->zone, load->db, load->loadtime, result);
9874 zonemgr_putio(&load->zone->readio);
9875 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
9876 UNLOCK_ZONE(load->zone);
9879 dns_db_detach(&load->db);
9880 if (load->zone->lctx != NULL)
9881 dns_loadctx_detach(&load->zone->lctx);
9882 dns_zone_idetach(&load->zone);
9883 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
9887 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
9888 REQUIRE(DNS_ZONE_VALID(zone));
9889 REQUIRE(table != NULL);
9890 REQUIRE(*table == NULL);
9893 if (zone->ssutable != NULL)
9894 dns_ssutable_attach(zone->ssutable, table);
9899 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
9900 REQUIRE(DNS_ZONE_VALID(zone));
9903 if (zone->ssutable != NULL)
9904 dns_ssutable_detach(&zone->ssutable);
9906 dns_ssutable_attach(table, &zone->ssutable);
9911 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
9912 REQUIRE(DNS_ZONE_VALID(zone));
9914 zone->sigvalidityinterval = interval;
9918 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
9919 REQUIRE(DNS_ZONE_VALID(zone));
9921 return (zone->sigvalidityinterval);
9925 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
9926 REQUIRE(DNS_ZONE_VALID(zone));
9928 zone->sigresigninginterval = interval;
9932 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
9933 REQUIRE(DNS_ZONE_VALID(zone));
9935 return (zone->sigresigninginterval);
9939 queue_xfrin(dns_zone_t *zone) {
9940 const char me[] = "queue_xfrin";
9941 isc_result_t result;
9942 dns_zonemgr_t *zmgr = zone->zmgr;
9946 INSIST(zone->statelist == NULL);
9948 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
9949 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
9953 zone->statelist = &zmgr->waiting_for_xfrin;
9954 result = zmgr_start_xfrin_ifquota(zmgr, zone);
9955 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
9957 if (result == ISC_R_QUOTA) {
9958 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
9959 "zone transfer deferred due to quota");
9960 } else if (result != ISC_R_SUCCESS) {
9961 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
9962 "starting zone transfer: %s",
9963 isc_result_totext(result));
9968 * This event callback is called when a zone has received
9969 * any necessary zone transfer quota. This is the time
9970 * to go ahead and start the transfer.
9973 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
9974 isc_result_t result;
9975 dns_peer_t *peer = NULL;
9976 char master[ISC_SOCKADDR_FORMATSIZE];
9977 char source[ISC_SOCKADDR_FORMATSIZE];
9978 dns_rdatatype_t xfrtype;
9979 dns_zone_t *zone = event->ev_arg;
9980 isc_netaddr_t masterip;
9981 isc_sockaddr_t sourceaddr;
9982 isc_sockaddr_t masteraddr;
9987 INSIST(task == zone->task);
9989 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9990 result = ISC_R_CANCELED;
9996 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9997 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
9998 &zone->sourceaddr, &now)) {
9999 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10000 dns_zone_log(zone, ISC_LOG_INFO,
10001 "got_transfer_quota: skipping zone transfer as "
10002 "master %s (source %s) is unreachable (cached)",
10004 result = ISC_R_CANCELED;
10008 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10009 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
10012 * Decide whether we should request IXFR or AXFR.
10014 if (zone->db == NULL) {
10015 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10016 "no database exists yet, requesting AXFR of "
10017 "initial version from %s", master);
10018 xfrtype = dns_rdatatype_axfr;
10019 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
10020 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
10021 "set, requesting AXFR from %s", master);
10022 xfrtype = dns_rdatatype_axfr;
10023 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
10024 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10025 "forced reload, requesting AXFR of "
10026 "initial version from %s", master);
10027 xfrtype = dns_rdatatype_axfr;
10028 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
10029 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10030 "retrying with AXFR from %s due to "
10031 "previous IXFR failure", master);
10032 xfrtype = dns_rdatatype_axfr;
10034 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
10037 isc_boolean_t use_ixfr = ISC_TRUE;
10038 if (peer != NULL &&
10039 dns_peer_getrequestixfr(peer, &use_ixfr) ==
10041 ; /* Using peer setting */
10043 use_ixfr = zone->view->requestixfr;
10045 if (use_ixfr == ISC_FALSE) {
10046 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10047 "IXFR disabled, requesting AXFR from %s",
10049 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
10050 xfrtype = dns_rdatatype_soa;
10052 xfrtype = dns_rdatatype_axfr;
10054 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10055 "requesting IXFR from %s", master);
10056 xfrtype = dns_rdatatype_ixfr;
10061 * Determine if we should attempt to sign the request with TSIG.
10063 result = ISC_R_NOTFOUND;
10065 * First, look for a tsig key in the master statement, then
10066 * try for a server key.
10068 if ((zone->masterkeynames != NULL) &&
10069 (zone->masterkeynames[zone->curmaster] != NULL)) {
10070 dns_view_t *view = dns_zone_getview(zone);
10071 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10072 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
10074 if (zone->tsigkey == NULL)
10075 result = dns_view_getpeertsig(zone->view, &masterip,
10078 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10079 dns_zone_log(zone, ISC_LOG_ERROR,
10080 "could not get TSIG key for zone transfer: %s",
10081 isc_result_totext(result));
10085 masteraddr = zone->masteraddr;
10086 sourceaddr = zone->sourceaddr;
10088 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
10089 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
10090 zone->tsigkey, zone->mctx,
10091 zone->zmgr->timermgr, zone->zmgr->socketmgr,
10092 zone->task, zone_xfrdone, &zone->xfr);
10093 if (result == ISC_R_SUCCESS) {
10095 if (xfrtype == dns_rdatatype_axfr) {
10096 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10097 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
10099 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
10100 } else if (xfrtype == dns_rdatatype_ixfr) {
10101 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
10102 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
10104 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
10110 * Any failure in this function is handled like a failed
10111 * zone transfer. This ensures that we get removed from
10112 * zmgr->xfrin_in_progress.
10114 if (result != ISC_R_SUCCESS)
10115 zone_xfrdone(zone, result);
10117 isc_event_free(&event);
10121 * Update forwarding support.
10125 forward_destroy(dns_forward_t *forward) {
10127 forward->magic = 0;
10128 if (forward->request != NULL)
10129 dns_request_destroy(&forward->request);
10130 if (forward->msgbuf != NULL)
10131 isc_buffer_free(&forward->msgbuf);
10132 if (forward->zone != NULL)
10133 dns_zone_idetach(&forward->zone);
10134 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
10137 static isc_result_t
10138 sendtomaster(dns_forward_t *forward) {
10139 isc_result_t result;
10140 isc_sockaddr_t src;
10142 LOCK_ZONE(forward->zone);
10143 if (forward->which >= forward->zone->masterscnt) {
10144 UNLOCK_ZONE(forward->zone);
10145 return (ISC_R_NOMORE);
10148 forward->addr = forward->zone->masters[forward->which];
10150 * Always use TCP regardless of whether the original update
10152 * XXX The timeout may but a bit small if we are far down a
10153 * transfer graph and the master has to try several masters.
10155 switch (isc_sockaddr_pf(&forward->addr)) {
10157 src = forward->zone->xfrsource4;
10160 src = forward->zone->xfrsource6;
10163 result = ISC_R_NOTIMPLEMENTED;
10166 result = dns_request_createraw(forward->zone->view->requestmgr,
10168 &src, &forward->addr,
10169 DNS_REQUESTOPT_TCP, 15 /* XXX */,
10170 forward->zone->task,
10171 forward_callback, forward,
10172 &forward->request);
10174 UNLOCK_ZONE(forward->zone);
10179 forward_callback(isc_task_t *task, isc_event_t *event) {
10180 const char me[] = "forward_callback";
10181 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10182 dns_message_t *msg = NULL;
10183 char master[ISC_SOCKADDR_FORMATSIZE];
10184 isc_result_t result;
10185 dns_forward_t *forward;
10190 forward = revent->ev_arg;
10191 INSIST(DNS_FORWARD_VALID(forward));
10192 zone = forward->zone;
10193 INSIST(DNS_ZONE_VALID(zone));
10197 isc_sockaddr_format(&forward->addr, master, sizeof(master));
10199 if (revent->result != ISC_R_SUCCESS) {
10200 dns_zone_log(zone, ISC_LOG_INFO,
10201 "could not forward dynamic update to %s: %s",
10202 master, dns_result_totext(revent->result));
10206 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10207 if (result != ISC_R_SUCCESS)
10210 result = dns_request_getresponse(revent->request, msg,
10211 DNS_MESSAGEPARSE_PRESERVEORDER |
10212 DNS_MESSAGEPARSE_CLONEBUFFER);
10213 if (result != ISC_R_SUCCESS)
10216 switch (msg->rcode) {
10218 * Pass these rcodes back to client.
10220 case dns_rcode_noerror:
10221 case dns_rcode_yxdomain:
10222 case dns_rcode_yxrrset:
10223 case dns_rcode_nxrrset:
10224 case dns_rcode_refused:
10225 case dns_rcode_nxdomain:
10228 /* These should not occur if the masters/zone are valid. */
10229 case dns_rcode_notzone:
10230 case dns_rcode_notauth: {
10234 isc_buffer_init(&rb, rcode, sizeof(rcode));
10235 (void)dns_rcode_totext(msg->rcode, &rb);
10236 dns_zone_log(zone, ISC_LOG_WARNING,
10237 "forwarding dynamic update: "
10238 "unexpected response: master %s returned: %.*s",
10239 master, (int)rb.used, rcode);
10243 /* Try another server for these rcodes. */
10244 case dns_rcode_formerr:
10245 case dns_rcode_servfail:
10246 case dns_rcode_notimp:
10247 case dns_rcode_badvers:
10252 /* call callback */
10253 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
10255 dns_request_destroy(&forward->request);
10256 forward_destroy(forward);
10257 isc_event_free(&event);
10262 dns_message_destroy(&msg);
10263 isc_event_free(&event);
10265 dns_request_destroy(&forward->request);
10266 result = sendtomaster(forward);
10267 if (result != ISC_R_SUCCESS) {
10268 /* call callback */
10269 dns_zone_log(zone, ISC_LOG_DEBUG(3),
10270 "exhausted dynamic update forwarder list");
10271 (forward->callback)(forward->callback_arg, result, NULL);
10272 forward_destroy(forward);
10277 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
10278 dns_updatecallback_t callback, void *callback_arg)
10280 dns_forward_t *forward;
10281 isc_result_t result;
10284 REQUIRE(DNS_ZONE_VALID(zone));
10285 REQUIRE(msg != NULL);
10286 REQUIRE(callback != NULL);
10288 forward = isc_mem_get(zone->mctx, sizeof(*forward));
10289 if (forward == NULL)
10290 return (ISC_R_NOMEMORY);
10292 forward->request = NULL;
10293 forward->zone = NULL;
10294 forward->msgbuf = NULL;
10295 forward->which = 0;
10297 forward->callback = callback;
10298 forward->callback_arg = callback_arg;
10299 forward->magic = FORWARD_MAGIC;
10301 mr = dns_message_getrawmessage(msg);
10303 result = ISC_R_UNEXPECTEDEND;
10307 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
10308 if (result != ISC_R_SUCCESS)
10310 result = isc_buffer_copyregion(forward->msgbuf, mr);
10311 if (result != ISC_R_SUCCESS)
10314 isc_mem_attach(zone->mctx, &forward->mctx);
10315 dns_zone_iattach(zone, &forward->zone);
10316 result = sendtomaster(forward);
10319 if (result != ISC_R_SUCCESS) {
10320 forward_destroy(forward);
10326 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
10327 REQUIRE(DNS_ZONE_VALID(zone));
10328 REQUIRE(next != NULL && *next == NULL);
10330 *next = ISC_LIST_NEXT(zone, link);
10332 return (ISC_R_NOMORE);
10334 return (ISC_R_SUCCESS);
10338 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
10339 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10340 REQUIRE(first != NULL && *first == NULL);
10342 *first = ISC_LIST_HEAD(zmgr->zones);
10343 if (*first == NULL)
10344 return (ISC_R_NOMORE);
10346 return (ISC_R_SUCCESS);
10354 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
10355 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
10356 dns_zonemgr_t **zmgrp)
10358 dns_zonemgr_t *zmgr;
10359 isc_result_t result;
10360 isc_interval_t interval;
10362 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
10364 return (ISC_R_NOMEMORY);
10367 isc_mem_attach(mctx, &zmgr->mctx);
10368 zmgr->taskmgr = taskmgr;
10369 zmgr->timermgr = timermgr;
10370 zmgr->socketmgr = socketmgr;
10371 zmgr->zonetasks = NULL;
10374 ISC_LIST_INIT(zmgr->zones);
10375 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
10376 ISC_LIST_INIT(zmgr->xfrin_in_progress);
10377 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
10378 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
10379 if (result != ISC_R_SUCCESS)
10382 zmgr->transfersin = 10;
10383 zmgr->transfersperns = 2;
10385 /* Create the zone task pool. */
10386 result = isc_taskpool_create(taskmgr, mctx,
10387 8 /* XXX */, 2, &zmgr->zonetasks);
10388 if (result != ISC_R_SUCCESS)
10391 /* Create a single task for queueing of SOA queries. */
10392 result = isc_task_create(taskmgr, 1, &zmgr->task);
10393 if (result != ISC_R_SUCCESS)
10394 goto free_taskpool;
10395 isc_task_setname(zmgr->task, "zmgr", zmgr);
10396 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
10398 if (result != ISC_R_SUCCESS)
10400 /* default to 20 refresh queries / notifies per second. */
10401 isc_interval_set(&interval, 0, 1000000000/2);
10402 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
10403 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10404 isc_ratelimiter_setpertic(zmgr->rl, 10);
10407 zmgr->ioactive = 0;
10408 ISC_LIST_INIT(zmgr->high);
10409 ISC_LIST_INIT(zmgr->low);
10411 result = isc_mutex_init(&zmgr->iolock);
10412 if (result != ISC_R_SUCCESS)
10415 zmgr->magic = ZONEMGR_MAGIC;
10418 return (ISC_R_SUCCESS);
10422 DESTROYLOCK(&zmgr->iolock);
10425 isc_ratelimiter_detach(&zmgr->rl);
10427 isc_task_detach(&zmgr->task);
10429 isc_taskpool_destroy(&zmgr->zonetasks);
10431 isc_rwlock_destroy(&zmgr->rwlock);
10433 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10434 isc_mem_detach(&mctx);
10439 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10440 isc_result_t result;
10442 REQUIRE(DNS_ZONE_VALID(zone));
10443 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10445 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10447 REQUIRE(zone->task == NULL);
10448 REQUIRE(zone->timer == NULL);
10449 REQUIRE(zone->zmgr == NULL);
10451 isc_taskpool_gettask(zmgr->zonetasks,
10452 dns_name_hash(dns_zone_getorigin(zone),
10457 * Set the task name. The tag will arbitrarily point to one
10458 * of the zones sharing the task (in practice, the one
10459 * to be managed last).
10461 isc_task_setname(zone->task, "zone", zone);
10463 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
10465 zone->task, zone_timer, zone,
10468 if (result != ISC_R_SUCCESS)
10472 * The timer "holds" a iref.
10475 INSIST(zone->irefs != 0);
10477 ISC_LIST_APPEND(zmgr->zones, zone, link);
10484 isc_task_detach(&zone->task);
10488 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10493 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10494 isc_boolean_t free_now = ISC_FALSE;
10496 REQUIRE(DNS_ZONE_VALID(zone));
10497 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10498 REQUIRE(zone->zmgr == zmgr);
10500 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10503 ISC_LIST_UNLINK(zmgr->zones, zone, link);
10506 if (zmgr->refs == 0)
10507 free_now = ISC_TRUE;
10510 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10513 zonemgr_free(zmgr);
10514 ENSURE(zone->zmgr == NULL);
10518 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
10519 REQUIRE(DNS_ZONEMGR_VALID(source));
10520 REQUIRE(target != NULL && *target == NULL);
10522 RWLOCK(&source->rwlock, isc_rwlocktype_write);
10523 REQUIRE(source->refs > 0);
10525 INSIST(source->refs > 0);
10526 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
10531 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
10532 dns_zonemgr_t *zmgr;
10533 isc_boolean_t free_now = ISC_FALSE;
10535 REQUIRE(zmgrp != NULL);
10537 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10539 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10541 if (zmgr->refs == 0)
10542 free_now = ISC_TRUE;
10543 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10546 zonemgr_free(zmgr);
10550 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
10553 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10555 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10556 for (p = ISC_LIST_HEAD(zmgr->zones);
10558 p = ISC_LIST_NEXT(p, link))
10560 dns_zone_maintenance(p);
10562 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
10565 * Recent configuration changes may have increased the
10566 * amount of available transfers quota. Make sure any
10567 * transfers currently blocked on quota get started if
10570 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10571 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10572 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10573 return (ISC_R_SUCCESS);
10577 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
10579 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10581 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10582 zmgr_resume_xfrs(zmgr, ISC_TRUE);
10583 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
10587 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
10588 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10590 isc_ratelimiter_shutdown(zmgr->rl);
10592 if (zmgr->task != NULL)
10593 isc_task_destroy(&zmgr->task);
10594 if (zmgr->zonetasks != NULL)
10595 isc_taskpool_destroy(&zmgr->zonetasks);
10599 zonemgr_free(dns_zonemgr_t *zmgr) {
10602 INSIST(zmgr->refs == 0);
10603 INSIST(ISC_LIST_EMPTY(zmgr->zones));
10607 DESTROYLOCK(&zmgr->iolock);
10608 isc_ratelimiter_detach(&zmgr->rl);
10610 isc_rwlock_destroy(&zmgr->rwlock);
10612 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
10613 isc_mem_detach(&mctx);
10617 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10618 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10620 zmgr->transfersin = value;
10624 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
10625 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10627 return (zmgr->transfersin);
10631 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
10632 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10634 zmgr->transfersperns = value;
10638 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
10639 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10641 return (zmgr->transfersperns);
10645 * Try to start a new incoming zone transfer to fill a quota
10646 * slot that was just vacated.
10649 * The zone manager is locked by the caller.
10652 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
10656 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
10660 isc_result_t result;
10661 next = ISC_LIST_NEXT(zone, statelink);
10662 result = zmgr_start_xfrin_ifquota(zmgr, zone);
10663 if (result == ISC_R_SUCCESS) {
10667 * We successfully filled the slot. We're done.
10670 } else if (result == ISC_R_QUOTA) {
10672 * Not enough quota. This is probably the per-server
10673 * quota, because we usually get called when a unit of
10674 * global quota has just been freed. Try the next
10675 * zone, it may succeed if it uses another master.
10679 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10680 "starting zone transfer: %s",
10681 isc_result_totext(result));
10688 * Try to start an incoming zone transfer for 'zone', quota permitting.
10691 * The zone manager is locked by the caller.
10694 * ISC_R_SUCCESS There was enough quota and we attempted to
10695 * start a transfer. zone_xfrdone() has been or will
10697 * ISC_R_QUOTA Not enough quota.
10700 static isc_result_t
10701 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
10702 dns_peer_t *peer = NULL;
10703 isc_netaddr_t masterip;
10704 isc_uint32_t nxfrsin, nxfrsperns;
10706 isc_uint32_t maxtransfersin, maxtransfersperns;
10710 * Find any configured information about the server we'd
10711 * like to transfer this zone from.
10713 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10714 (void)dns_peerlist_peerbyaddr(zone->view->peers,
10718 * Determine the total maximum number of simultaneous
10719 * transfers allowed, and the maximum for this specific
10722 maxtransfersin = zmgr->transfersin;
10723 maxtransfersperns = zmgr->transfersperns;
10725 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
10728 * Count the total number of transfers that are in progress,
10729 * and the number of transfers in progress from this master.
10730 * We linearly scan a list of all transfers; if this turns
10731 * out to be too slow, we could hash on the master address.
10733 nxfrsin = nxfrsperns = 0;
10734 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
10736 x = ISC_LIST_NEXT(x, statelink))
10739 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
10741 if (isc_netaddr_equal(&xip, &masterip))
10745 /* Enforce quota. */
10746 if (nxfrsin >= maxtransfersin)
10747 return (ISC_R_QUOTA);
10749 if (nxfrsperns >= maxtransfersperns)
10750 return (ISC_R_QUOTA);
10753 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
10754 * list and send it an event to let it start the actual transfer in the
10755 * context of its own task.
10757 e = isc_event_allocate(zmgr->mctx, zmgr,
10758 DNS_EVENT_ZONESTARTXFRIN,
10759 got_transfer_quota, zone,
10760 sizeof(isc_event_t));
10762 return (ISC_R_NOMEMORY);
10765 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
10766 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
10767 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
10768 zone->statelist = &zmgr->xfrin_in_progress;
10769 isc_task_send(zone->task, &e);
10770 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
10773 return (ISC_R_SUCCESS);
10777 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
10779 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10780 REQUIRE(iolimit > 0);
10782 zmgr->iolimit = iolimit;
10786 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
10788 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10790 return (zmgr->iolimit);
10794 * Get permission to request a file handle from the OS.
10795 * An event will be sent to action when one is available.
10796 * There are two queues available (high and low), the high
10797 * queue will be serviced before the low one.
10799 * zonemgr_putio() must be called after the event is delivered to
10803 static isc_result_t
10804 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
10805 isc_task_t *task, isc_taskaction_t action, void *arg,
10809 isc_boolean_t queue;
10811 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10812 REQUIRE(iop != NULL && *iop == NULL);
10814 io = isc_mem_get(zmgr->mctx, sizeof(*io));
10816 return (ISC_R_NOMEMORY);
10817 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
10818 action, arg, sizeof(*io->event));
10819 if (io->event == NULL) {
10820 isc_mem_put(zmgr->mctx, io, sizeof(*io));
10821 return (ISC_R_NOMEMORY);
10826 isc_task_attach(task, &io->task);
10827 ISC_LINK_INIT(io, link);
10828 io->magic = IO_MAGIC;
10830 LOCK(&zmgr->iolock);
10832 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
10835 ISC_LIST_APPEND(zmgr->high, io, link);
10837 ISC_LIST_APPEND(zmgr->low, io, link);
10839 UNLOCK(&zmgr->iolock);
10843 isc_task_send(io->task, &io->event);
10845 return (ISC_R_SUCCESS);
10849 zonemgr_putio(dns_io_t **iop) {
10852 dns_zonemgr_t *zmgr;
10854 REQUIRE(iop != NULL);
10856 REQUIRE(DNS_IO_VALID(io));
10860 INSIST(!ISC_LINK_LINKED(io, link));
10861 INSIST(io->event == NULL);
10864 isc_task_detach(&io->task);
10866 isc_mem_put(zmgr->mctx, io, sizeof(*io));
10868 LOCK(&zmgr->iolock);
10869 INSIST(zmgr->ioactive > 0);
10871 next = HEAD(zmgr->high);
10873 next = HEAD(zmgr->low);
10874 if (next != NULL) {
10876 ISC_LIST_UNLINK(zmgr->high, next, link);
10878 ISC_LIST_UNLINK(zmgr->low, next, link);
10879 INSIST(next->event != NULL);
10881 UNLOCK(&zmgr->iolock);
10883 isc_task_send(next->task, &next->event);
10887 zonemgr_cancelio(dns_io_t *io) {
10888 isc_boolean_t send_event = ISC_FALSE;
10890 REQUIRE(DNS_IO_VALID(io));
10893 * If we are queued to be run then dequeue.
10895 LOCK(&io->zmgr->iolock);
10896 if (ISC_LINK_LINKED(io, link)) {
10898 ISC_LIST_UNLINK(io->zmgr->high, io, link);
10900 ISC_LIST_UNLINK(io->zmgr->low, io, link);
10902 send_event = ISC_TRUE;
10903 INSIST(io->event != NULL);
10905 UNLOCK(&io->zmgr->iolock);
10907 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
10908 isc_task_send(io->task, &io->event);
10913 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
10916 isc_result_t result;
10918 buflen = strlen(path) + strlen(templat) + 2;
10920 buf = isc_mem_get(zone->mctx, buflen);
10924 result = isc_file_template(path, templat, buf, buflen);
10925 if (result != ISC_R_SUCCESS)
10928 result = isc_file_renameunique(path, buf);
10929 if (result != ISC_R_SUCCESS)
10932 dns_zone_log(zone, ISC_LOG_WARNING, "saved '%s' as '%s'",
10936 isc_mem_put(zone->mctx, buf, buflen);
10940 /* Hook for ondestroy notification from a database. */
10943 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
10944 dns_db_t *db = event->sender;
10947 isc_event_free(&event);
10949 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
10950 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
10951 "database (%p) destroyed", (void*) db);
10956 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
10957 isc_interval_t interval;
10958 isc_uint32_t s, ns;
10959 isc_uint32_t pertic;
10960 isc_result_t result;
10962 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10971 } else if (value <= 10) {
10973 ns = 1000000000 / value;
10977 ns = (1000000000 / value) * 10;
10981 isc_interval_set(&interval, s, ns);
10982 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
10983 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10984 isc_ratelimiter_setpertic(zmgr->rl, pertic);
10986 zmgr->serialqueryrate = value;
10990 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
10991 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
10993 return (zmgr->serialqueryrate);
10996 static isc_boolean_t
10997 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
10998 isc_sockaddr_t *local, isc_time_t *now)
11001 isc_rwlocktype_t locktype;
11002 isc_result_t result;
11003 isc_uint32_t seconds = isc_time_seconds(now);
11005 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11007 locktype = isc_rwlocktype_read;
11008 RWLOCK(&zmgr->rwlock, locktype);
11009 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11010 if (zmgr->unreachable[i].expire >= seconds &&
11011 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11012 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
11013 result = isc_rwlock_tryupgrade(&zmgr->rwlock);
11014 if (result == ISC_R_SUCCESS) {
11015 locktype = isc_rwlocktype_write;
11016 zmgr->unreachable[i].last = seconds;
11021 RWUNLOCK(&zmgr->rwlock, locktype);
11022 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
11026 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
11027 isc_sockaddr_t *local, isc_time_t *now)
11029 isc_uint32_t seconds = isc_time_seconds(now);
11030 isc_uint32_t last = seconds;
11031 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
11033 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11035 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
11036 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
11037 /* Existing entry? */
11038 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
11039 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
11042 if (zmgr->unreachable[i].expire < seconds)
11044 /* Least recently used slot? */
11045 if (zmgr->unreachable[i].last < last) {
11046 last = zmgr->unreachable[i].last;
11050 if (i < UNREACH_CHACHE_SIZE) {
11052 * Found a existing entry. Update the expire timer and
11053 * last usage timestamps.
11055 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
11056 zmgr->unreachable[i].last = seconds;
11057 } else if (slot != UNREACH_CHACHE_SIZE) {
11059 * Found a empty slot. Add a new entry to the cache.
11061 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
11062 zmgr->unreachable[slot].last = seconds;
11063 zmgr->unreachable[slot].remote = *remote;
11064 zmgr->unreachable[slot].local = *local;
11067 * Replace the least recently used entry in the cache.
11069 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
11070 zmgr->unreachable[oldest].last = seconds;
11071 zmgr->unreachable[oldest].remote = *remote;
11072 zmgr->unreachable[oldest].local = *local;
11074 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
11078 dns_zone_forcereload(dns_zone_t *zone) {
11079 REQUIRE(DNS_ZONE_VALID(zone));
11081 if (zone->type == dns_zone_master)
11085 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
11087 dns_zone_refresh(zone);
11091 dns_zone_isforced(dns_zone_t *zone) {
11092 REQUIRE(DNS_ZONE_VALID(zone));
11094 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
11098 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
11100 * This function is obsoleted.
11104 return (ISC_R_NOTIMPLEMENTED);
11108 dns_zone_getstatscounters(dns_zone_t *zone) {
11110 * This function is obsoleted.
11117 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
11118 REQUIRE(DNS_ZONE_VALID(zone));
11119 REQUIRE(zone->stats == NULL);
11122 zone->stats = NULL;
11123 isc_stats_attach(stats, &zone->stats);
11128 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
11129 REQUIRE(DNS_ZONE_VALID(zone));
11132 if (zone->requeststats_on && stats == NULL)
11133 zone->requeststats_on = ISC_FALSE;
11134 else if (!zone->requeststats_on && stats != NULL) {
11135 if (zone->requeststats == NULL) {
11136 isc_stats_attach(stats, &zone->requeststats);
11137 zone->requeststats_on = ISC_TRUE;
11146 dns_zone_getrequeststats(dns_zone_t *zone) {
11148 * We don't lock zone for efficiency reason. This is not catastrophic
11149 * because requeststats must always be valid when requeststats_on is
11151 * Some counters may be incremented while requeststats_on is becoming
11152 * false, or some cannot be incremented just after the statistics are
11153 * installed, but it shouldn't matter much in practice.
11155 if (zone->requeststats_on)
11156 return (zone->requeststats);
11162 dns_zone_dialup(dns_zone_t *zone) {
11164 REQUIRE(DNS_ZONE_VALID(zone));
11166 zone_debuglog(zone, "dns_zone_dialup", 3,
11167 "notify = %d, refresh = %d",
11168 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
11169 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
11171 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
11172 dns_zone_notify(zone);
11173 if (zone->type != dns_zone_master &&
11174 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11175 dns_zone_refresh(zone);
11179 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
11180 REQUIRE(DNS_ZONE_VALID(zone));
11183 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
11184 DNS_ZONEFLG_DIALREFRESH |
11185 DNS_ZONEFLG_NOREFRESH);
11187 case dns_dialuptype_no:
11189 case dns_dialuptype_yes:
11190 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
11191 DNS_ZONEFLG_DIALREFRESH |
11192 DNS_ZONEFLG_NOREFRESH));
11194 case dns_dialuptype_notify:
11195 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11197 case dns_dialuptype_notifypassive:
11198 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
11199 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11201 case dns_dialuptype_refresh:
11202 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
11203 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11205 case dns_dialuptype_passive:
11206 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
11215 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
11216 isc_result_t result = ISC_R_SUCCESS;
11218 REQUIRE(DNS_ZONE_VALID(zone));
11221 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
11228 dns_zone_getkeydirectory(dns_zone_t *zone) {
11229 REQUIRE(DNS_ZONE_VALID(zone));
11231 return (zone->keydirectory);
11235 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
11237 unsigned int count = 0;
11239 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
11241 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11243 case DNS_ZONESTATE_XFERRUNNING:
11244 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
11246 zone = ISC_LIST_NEXT(zone, statelink))
11249 case DNS_ZONESTATE_XFERDEFERRED:
11250 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
11252 zone = ISC_LIST_NEXT(zone, statelink))
11255 case DNS_ZONESTATE_SOAQUERY:
11256 for (zone = ISC_LIST_HEAD(zmgr->zones);
11258 zone = ISC_LIST_NEXT(zone, link))
11259 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
11262 case DNS_ZONESTATE_ANY:
11263 for (zone = ISC_LIST_HEAD(zmgr->zones);
11265 zone = ISC_LIST_NEXT(zone, link)) {
11266 dns_view_t *view = zone->view;
11267 if (view != NULL && strcmp(view->name, "_bind") == 0)
11276 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
11282 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
11283 isc_boolean_t ok = ISC_TRUE;
11284 isc_boolean_t fail = ISC_FALSE;
11285 char namebuf[DNS_NAME_FORMATSIZE];
11286 char namebuf2[DNS_NAME_FORMATSIZE];
11287 char typebuf[DNS_RDATATYPE_FORMATSIZE];
11288 int level = ISC_LOG_WARNING;
11291 REQUIRE(DNS_ZONE_VALID(zone));
11293 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
11294 return (ISC_R_SUCCESS);
11296 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
11297 level = ISC_LOG_ERROR;
11301 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
11303 dns_name_format(name, namebuf, sizeof(namebuf));
11304 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11305 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
11306 dns_result_totext(DNS_R_BADOWNERNAME));
11308 return (DNS_R_BADOWNERNAME);
11311 dns_name_init(&bad, NULL);
11312 ok = dns_rdata_checknames(rdata, name, &bad);
11314 dns_name_format(name, namebuf, sizeof(namebuf));
11315 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
11316 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
11317 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
11318 namebuf2, dns_result_totext(DNS_R_BADNAME));
11320 return (DNS_R_BADNAME);
11323 return (ISC_R_SUCCESS);
11327 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
11328 REQUIRE(DNS_ZONE_VALID(zone));
11329 zone->checkmx = checkmx;
11333 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
11334 REQUIRE(DNS_ZONE_VALID(zone));
11335 zone->checksrv = checksrv;
11339 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
11340 REQUIRE(DNS_ZONE_VALID(zone));
11341 zone->checkns = checkns;
11345 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
11346 REQUIRE(DNS_ZONE_VALID(zone));
11349 zone->isself = isself;
11350 zone->isselfarg = arg;
11355 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
11356 REQUIRE(DNS_ZONE_VALID(zone));
11359 zone->notifydelay = delay;
11364 dns_zone_getnotifydelay(dns_zone_t *zone) {
11365 REQUIRE(DNS_ZONE_VALID(zone));
11367 return (zone->notifydelay);
11371 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
11372 isc_uint16_t keyid, isc_boolean_t delete)
11374 isc_result_t result;
11375 REQUIRE(DNS_ZONE_VALID(zone));
11377 dns_zone_log(zone, ISC_LOG_NOTICE,
11378 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
11381 result = zone_signwithkey(zone, algorithm, keyid, delete);
11387 static const char *hex = "0123456789ABCDEF";
11390 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
11391 isc_result_t result;
11392 char salt[255*2+1];
11395 REQUIRE(DNS_ZONE_VALID(zone));
11397 if (nsec3param->salt_length != 0) {
11398 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
11399 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
11400 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
11401 salt[j++] = hex[nsec3param->salt[i] & 0xf];
11406 dns_zone_log(zone, ISC_LOG_NOTICE,
11407 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
11408 nsec3param->hash, nsec3param->iterations,
11411 result = zone_addnsec3chain(zone, nsec3param);
11418 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
11419 REQUIRE(DNS_ZONE_VALID(zone));
11423 zone->nodes = nodes;
11427 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
11428 REQUIRE(DNS_ZONE_VALID(zone));
11431 * We treat signatures as a signed value so explicitly
11432 * limit its range here.
11434 if (signatures > ISC_INT32_MAX)
11435 signatures = ISC_INT32_MAX;
11436 else if (signatures == 0)
11438 zone->signatures = signatures;
11442 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
11443 REQUIRE(DNS_ZONE_VALID(zone));
11444 zone->privatetype = type;
11448 dns_zone_getprivatetype(dns_zone_t *zone) {
11449 REQUIRE(DNS_ZONE_VALID(zone));
11450 return (zone->privatetype);
11453 static isc_result_t
11454 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
11455 isc_boolean_t delete)
11457 dns_signing_t *signing;
11458 dns_signing_t *current;
11459 isc_result_t result = ISC_R_SUCCESS;
11462 signing = isc_mem_get(zone->mctx, sizeof *signing);
11463 if (signing == NULL)
11464 return (ISC_R_NOMEMORY);
11466 signing->magic = 0;
11467 signing->db = NULL;
11468 signing->dbiterator = NULL;
11469 signing->algorithm = algorithm;
11470 signing->keyid = keyid;
11471 signing->delete = delete;
11472 signing->done = ISC_FALSE;
11476 for (current = ISC_LIST_HEAD(zone->signing);
11478 current = ISC_LIST_NEXT(current, link)) {
11479 if (current->db == zone->db &&
11480 current->algorithm == signing->algorithm &&
11481 current->keyid == signing->keyid) {
11482 if (current->delete != signing->delete)
11483 current->done = ISC_TRUE;
11489 if (zone->db != NULL) {
11490 dns_db_attach(zone->db, &signing->db);
11491 result = dns_db_createiterator(signing->db, 0,
11492 &signing->dbiterator);
11494 if (result == ISC_R_SUCCESS)
11495 result = dns_dbiterator_first(signing->dbiterator);
11496 if (result == ISC_R_SUCCESS) {
11497 dns_dbiterator_pause(signing->dbiterator);
11498 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
11500 if (isc_time_isepoch(&zone->signingtime)) {
11501 zone->signingtime = now;
11502 if (zone->task != NULL)
11503 zone_settimer(zone, &now);
11507 result = ISC_R_NOTFOUND;
11510 if (signing != NULL) {
11511 dns_db_detach(&signing->db);
11512 if (signing->dbiterator != NULL)
11513 dns_dbiterator_destroy(&signing->dbiterator);
11514 isc_mem_put(zone->mctx, signing, sizeof *signing);