4 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: zone.c,v 1.540 2009/12/07 20:51:12 each Exp */
28 #include <isc/mutex.h>
29 #include <isc/print.h>
30 #include <isc/random.h>
31 #include <isc/ratelimiter.h>
32 #include <isc/refcount.h>
33 #include <isc/rwlock.h>
34 #include <isc/serial.h>
35 #include <isc/strerror.h>
36 #include <isc/stats.h>
37 #include <isc/stdtime.h>
38 #include <isc/string.h>
39 #include <isc/taskpool.h>
40 #include <isc/timer.h>
43 #include <dns/acache.h>
46 #include <dns/callbacks.h>
48 #include <dns/dbiterator.h>
49 #include <dns/dnssec.h>
50 #include <dns/events.h>
51 #include <dns/journal.h>
52 #include <dns/keydata.h>
53 #include <dns/keytable.h>
54 #include <dns/keyvalues.h>
56 #include <dns/master.h>
57 #include <dns/masterdump.h>
58 #include <dns/message.h>
61 #include <dns/nsec3.h>
63 #include <dns/private.h>
65 #include <dns/rcode.h>
66 #include <dns/rdataclass.h>
67 #include <dns/rdatalist.h>
68 #include <dns/rdataset.h>
69 #include <dns/rdatasetiter.h>
70 #include <dns/rdatastruct.h>
71 #include <dns/rdatatype.h>
72 #include <dns/request.h>
73 #include <dns/resolver.h>
74 #include <dns/result.h>
75 #include <dns/rriterator.h>
78 #include <dns/stats.h>
80 #include <dns/xfrin.h>
85 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
86 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
88 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
89 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
91 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
92 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
94 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
95 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
97 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
98 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
100 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
101 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
103 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
104 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
107 * Ensure 'a' is at least 'min' but not more than 'max'.
109 #define RANGE(a, min, max) \
110 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
112 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
117 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
118 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
119 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
121 #ifndef DNS_MAX_EXPIRE
122 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
125 #ifndef DNS_DUMP_DELAY
126 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
129 typedef struct dns_notify dns_notify_t
;
130 typedef struct dns_stub dns_stub_t
;
131 typedef struct dns_load dns_load_t
;
132 typedef struct dns_forward dns_forward_t
;
133 typedef struct dns_io dns_io_t
;
134 typedef ISC_LIST(dns_io_t
) dns_iolist_t
;
135 typedef struct dns_signing dns_signing_t
;
136 typedef ISC_LIST(dns_signing_t
) dns_signinglist_t
;
137 typedef struct dns_nsec3chain dns_nsec3chain_t
;
138 typedef ISC_LIST(dns_nsec3chain_t
) dns_nsec3chainlist_t
;
139 typedef struct dns_keyfetch dns_keyfetch_t
;
141 #define DNS_ZONE_CHECKLOCK
142 #ifdef DNS_ZONE_CHECKLOCK
143 #define LOCK_ZONE(z) \
144 do { LOCK(&(z)->lock); \
145 INSIST((z)->locked == ISC_FALSE); \
146 (z)->locked = ISC_TRUE; \
148 #define UNLOCK_ZONE(z) \
149 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
150 #define LOCKED_ZONE(z) ((z)->locked)
152 #define LOCK_ZONE(z) LOCK(&(z)->lock)
153 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
154 #define LOCKED_ZONE(z) ISC_TRUE
157 #ifdef ISC_RWLOCK_USEATOMIC
158 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
159 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
160 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
161 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
163 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
164 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
165 #define ZONEDB_LOCK(l, t) LOCK(l)
166 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
173 #ifdef DNS_ZONE_CHECKLOCK
174 isc_boolean_t locked
;
177 isc_refcount_t erefs
;
179 #ifdef ISC_RWLOCK_USEATOMIC
184 dns_db_t
*db
; /* Locked by dblock */
188 ISC_LINK(dns_zone_t
) link
; /* Used by zmgr. */
193 dns_masterformat_t masterformat
;
195 isc_int32_t journalsize
;
196 dns_rdataclass_t rdclass
;
199 unsigned int options
;
200 unsigned int db_argc
;
202 isc_time_t expiretime
;
203 isc_time_t refreshtime
;
206 isc_time_t notifytime
;
207 isc_time_t resigntime
;
208 isc_time_t keywarntime
;
209 isc_time_t signingtime
;
210 isc_time_t nsec3chaintime
;
211 isc_time_t refreshkeytime
;
212 isc_uint32_t refreshkeycount
;
213 isc_uint32_t refresh
;
216 isc_uint32_t minimum
;
217 isc_stdtime_t key_expiry
;
220 isc_uint32_t maxrefresh
;
221 isc_uint32_t minrefresh
;
222 isc_uint32_t maxretry
;
223 isc_uint32_t minretry
;
225 isc_sockaddr_t
*masters
;
226 dns_name_t
**masterkeynames
;
227 isc_boolean_t
*mastersok
;
228 unsigned int masterscnt
;
229 unsigned int curmaster
;
230 isc_sockaddr_t masteraddr
;
231 dns_notifytype_t notifytype
;
232 isc_sockaddr_t
*notify
;
233 unsigned int notifycnt
;
234 isc_sockaddr_t notifyfrom
;
236 isc_sockaddr_t notifysrc4
;
237 isc_sockaddr_t notifysrc6
;
238 isc_sockaddr_t xfrsource4
;
239 isc_sockaddr_t xfrsource6
;
240 isc_sockaddr_t altxfrsource4
;
241 isc_sockaddr_t altxfrsource6
;
242 isc_sockaddr_t sourceaddr
;
243 dns_xfrin_ctx_t
*xfr
; /* task locked */
244 dns_tsigkey_t
*tsigkey
; /* key used for xfr */
245 /* Access Control Lists */
246 dns_acl_t
*update_acl
;
247 dns_acl_t
*forward_acl
;
248 dns_acl_t
*notify_acl
;
249 dns_acl_t
*query_acl
;
250 dns_acl_t
*queryon_acl
;
252 isc_boolean_t update_disabled
;
253 isc_boolean_t zero_no_soa_ttl
;
254 dns_severity_t check_names
;
255 ISC_LIST(dns_notify_t
) notifies
;
256 dns_request_t
*request
;
261 isc_uint32_t maxxfrin
;
262 isc_uint32_t maxxfrout
;
264 isc_uint32_t idleout
;
265 isc_event_t ctlevent
;
266 dns_ssutable_t
*ssutable
;
267 isc_uint32_t sigvalidityinterval
;
268 isc_uint32_t sigresigninginterval
;
270 dns_acache_t
*acache
;
271 dns_checkmxfunc_t checkmx
;
272 dns_checksrvfunc_t checksrv
;
273 dns_checknsfunc_t checkns
;
275 * Zones in certain states such as "waiting for zone transfer"
276 * or "zone transfer in progress" are kept on per-state linked lists
277 * in the zone manager using the 'statelink' field. The 'statelist'
278 * field points at the list the zone is currently on. It the zone
279 * is not on any such list, statelist is NULL.
281 ISC_LINK(dns_zone_t
) statelink
;
282 dns_zonelist_t
*statelist
;
284 * Statistics counters about zone management.
288 * Optional per-zone statistics counters. Counted outside of this
291 isc_boolean_t requeststats_on
;
292 isc_stats_t
*requeststats
;
293 isc_uint32_t notifydelay
;
294 dns_isselffunc_t isself
;
303 * Serial number for deferred journal compaction.
305 isc_uint32_t compact_serial
;
307 * Keys that are signing the zone for the first time.
309 dns_signinglist_t signing
;
310 dns_nsec3chainlist_t nsec3chain
;
312 * Signing / re-signing quantum stopping parameters.
314 isc_uint32_t signatures
;
316 dns_rdatatype_t privatetype
;
319 * Autosigning/key-maintenance options
321 isc_uint32_t keyopts
;
324 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
325 #define DNS_ZONE_SETFLAG(z,f) do { \
326 INSIST(LOCKED_ZONE(z)); \
329 #define DNS_ZONE_CLRFLAG(z,f) do { \
330 INSIST(LOCKED_ZONE(z)); \
331 (z)->flags &= ~(f); \
333 /* XXX MPA these may need to go back into zone.h */
334 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
335 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
336 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
337 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
338 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
339 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
340 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
341 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
342 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
343 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
345 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
347 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
349 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
350 * zone with no masters
352 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
353 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
354 * from SOA (if not set, we
356 * default timer values) */
357 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
358 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
359 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
360 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
361 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
362 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
363 #define DNS_ZONEFLG_FLUSH 0x00200000U
364 #define DNS_ZONEFLG_NOEDNS 0x00400000U
365 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
366 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
367 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
368 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
369 #define DNS_ZONEFLG_THAW 0x08000000U
370 #define DNS_ZONEFLG_NOTIFYRESIGN 0x10000000U
372 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
373 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
375 /* Flags for zone_load() */
376 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
377 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
380 #define UNREACH_CHACHE_SIZE 10U
381 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
384 do { result = (op); \
385 if (result != ISC_R_SUCCESS) goto failure; \
388 struct dns_unreachable
{
389 isc_sockaddr_t remote
;
390 isc_sockaddr_t local
;
398 int refs
; /* Locked by rwlock */
399 isc_taskmgr_t
* taskmgr
;
400 isc_timermgr_t
* timermgr
;
401 isc_socketmgr_t
* socketmgr
;
402 isc_taskpool_t
* zonetasks
;
404 isc_ratelimiter_t
* rl
;
408 /* Locked by rwlock. */
409 dns_zonelist_t zones
;
410 dns_zonelist_t waiting_for_xfrin
;
411 dns_zonelist_t xfrin_in_progress
;
413 /* Configuration data. */
414 isc_uint32_t transfersin
;
415 isc_uint32_t transfersperns
;
416 unsigned int serialqueryrate
;
418 /* Locked by iolock */
419 isc_uint32_t iolimit
;
420 isc_uint32_t ioactive
;
424 /* Locked by rwlock. */
426 struct dns_unreachable unreachable
[UNREACH_CHACHE_SIZE
];
438 dns_request_t
*request
;
441 ISC_LINK(dns_notify_t
) link
;
444 #define DNS_NOTIFY_NOSOA 0x0001U
447 * dns_stub holds state while performing a 'stub' transfer.
448 * 'db' is the zone's 'db' or a new one if this is the initial
457 dns_dbversion_t
*version
;
469 dns_rdatacallbacks_t callbacks
;
473 * Hold forward state.
479 isc_buffer_t
*msgbuf
;
480 dns_request_t
*request
;
483 dns_updatecallback_t callback
;
488 * Hold IO request state.
495 ISC_LINK(dns_io_t
) link
;
500 * Hold state for when we are signing a zone with a new
501 * DNSKEY as result of an update.
506 dns_dbiterator_t
*dbiterator
;
507 dns_secalg_t algorithm
;
509 isc_boolean_t
delete;
511 ISC_LINK(dns_signing_t
) link
;
514 struct dns_nsec3chain
{
517 dns_dbiterator_t
*dbiterator
;
518 dns_rdata_nsec3param_t nsec3param
;
519 unsigned char salt
[255];
521 isc_boolean_t seen_nsec
;
522 isc_boolean_t delete_nsec
;
523 isc_boolean_t save_delete_nsec
;
524 ISC_LINK(dns_nsec3chain_t
) link
;
527 * 'dbiterator' contains a iterator for the database. If we are creating
528 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
529 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
532 * 'nsec3param' contains the parameters of the NSEC3 chain being created
535 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
537 * 'seen_nsec' will be set to true if, while iterating the zone to create a
538 * NSEC3 chain, a NSEC record is seen.
540 * 'delete_nsec' will be set to true if, at the completion of the creation
541 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
542 * are in the process of deleting the NSEC chain.
544 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
545 * so it can be recovered in the event of a error.
548 struct dns_keyfetch
{
549 dns_fixedname_t name
;
550 dns_rdataset_t keydataset
;
551 dns_rdataset_t dnskeyset
;
552 dns_rdataset_t dnskeysigset
;
559 #define DAY (24*HOUR)
560 #define MONTH (30*DAY)
562 #define SEND_BUFFER_SIZE 2048
564 static void zone_settimer(dns_zone_t
*, isc_time_t
*);
565 static void cancel_refresh(dns_zone_t
*);
566 static void zone_debuglog(dns_zone_t
*zone
, const char *, int debuglevel
,
567 const char *msg
, ...) ISC_FORMAT_PRINTF(4, 5);
568 static void notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...)
569 ISC_FORMAT_PRINTF(3, 4);
570 static void queue_xfrin(dns_zone_t
*zone
);
571 static isc_result_t
update_one_rr(dns_db_t
*db
, dns_dbversion_t
*ver
,
572 dns_diff_t
*diff
, dns_diffop_t op
,
573 dns_name_t
*name
, dns_ttl_t ttl
,
575 static void zone_unload(dns_zone_t
*zone
);
576 static void zone_expire(dns_zone_t
*zone
);
577 static void zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
);
578 static void zone_idetach(dns_zone_t
**zonep
);
579 static isc_result_t
zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
,
581 static inline void zone_attachdb(dns_zone_t
*zone
, dns_db_t
*db
);
582 static inline void zone_detachdb(dns_zone_t
*zone
);
583 static isc_result_t
default_journal(dns_zone_t
*zone
);
584 static void zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
);
585 static isc_result_t
zone_postload(dns_zone_t
*zone
, dns_db_t
*db
,
586 isc_time_t loadtime
, isc_result_t result
);
587 static void zone_needdump(dns_zone_t
*zone
, unsigned int delay
);
588 static void zone_shutdown(isc_task_t
*, isc_event_t
*);
589 static void zone_loaddone(void *arg
, isc_result_t result
);
590 static isc_result_t
zone_startload(dns_db_t
*db
, dns_zone_t
*zone
,
591 isc_time_t loadtime
);
592 static void zone_namerd_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
593 static void zone_name_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
594 static void zone_rdclass_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
595 static void zone_viewname_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
598 /* ondestroy example */
599 static void dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
);
602 static void refresh_callback(isc_task_t
*, isc_event_t
*);
603 static void stub_callback(isc_task_t
*, isc_event_t
*);
604 static void queue_soa_query(dns_zone_t
*zone
);
605 static void soa_query(isc_task_t
*, isc_event_t
*);
606 static void ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
,
608 static int message_count(dns_message_t
*msg
, dns_section_t section
,
609 dns_rdatatype_t type
);
610 static void notify_cancel(dns_zone_t
*zone
);
611 static void notify_find_address(dns_notify_t
*notify
);
612 static void notify_send(dns_notify_t
*notify
);
613 static isc_result_t
notify_createmessage(dns_zone_t
*zone
,
615 dns_message_t
**messagep
);
616 static void notify_done(isc_task_t
*task
, isc_event_t
*event
);
617 static void notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
);
618 static isc_result_t
zone_dump(dns_zone_t
*, isc_boolean_t
);
619 static void got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
);
620 static isc_result_t
zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
,
622 static void zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
);
623 static void zonemgr_free(dns_zonemgr_t
*zmgr
);
624 static isc_result_t
zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
625 isc_task_t
*task
, isc_taskaction_t action
,
626 void *arg
, dns_io_t
**iop
);
627 static void zonemgr_putio(dns_io_t
**iop
);
628 static void zonemgr_cancelio(dns_io_t
*io
);
631 zone_get_from_db(dns_zone_t
*zone
, dns_db_t
*db
, unsigned int *nscount
,
632 unsigned int *soacount
, isc_uint32_t
*serial
,
633 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
634 isc_uint32_t
*expire
, isc_uint32_t
*minimum
,
635 unsigned int *errors
);
637 static void zone_freedbargs(dns_zone_t
*zone
);
638 static void forward_callback(isc_task_t
*task
, isc_event_t
*event
);
639 static void zone_saveunique(dns_zone_t
*zone
, const char *path
,
640 const char *templat
);
641 static void zone_maintenance(dns_zone_t
*zone
);
642 static void zone_notify(dns_zone_t
*zone
, isc_time_t
*now
);
643 static void dump_done(void *arg
, isc_result_t result
);
644 static isc_boolean_t
dns_zonemgr_unreachable(dns_zonemgr_t
*zmgr
,
645 isc_sockaddr_t
*remote
,
646 isc_sockaddr_t
*local
,
648 static isc_result_t
zone_signwithkey(dns_zone_t
*zone
, dns_secalg_t algorithm
,
649 isc_uint16_t keyid
, isc_boolean_t
delete);
650 static isc_result_t
delete_nsec(dns_db_t
*db
, dns_dbversion_t
*ver
,
651 dns_dbnode_t
*node
, dns_name_t
*name
,
653 static isc_result_t
zone_rekey(dns_zone_t
*zone
);
655 #define ENTER zone_debuglog(zone, me, 1, "enter")
657 static const unsigned int dbargc_default
= 1;
658 static const char *dbargv_default
[] = { "rbt" };
660 #define DNS_ZONE_JITTER_ADD(a, b, c) \
664 _j = isc_random_jitter((b), (b)/4); \
665 isc_interval_set(&_i, _j, 0); \
666 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
667 dns_zone_log(zone, ISC_LOG_WARNING, \
668 "epoch approaching: upgrade required: " \
669 "now + %s failed", #b); \
670 isc_interval_set(&_i, _j/2, 0); \
671 (void)isc_time_add((a), &_i, (c)); \
675 #define DNS_ZONE_TIME_ADD(a, b, c) \
678 isc_interval_set(&_i, (b), 0); \
679 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
680 dns_zone_log(zone, ISC_LOG_WARNING, \
681 "epoch approaching: upgrade required: " \
682 "now + %s failed", #b); \
683 isc_interval_set(&_i, (b)/2, 0); \
684 (void)isc_time_add((a), &_i, (c)); \
689 * Increment resolver-related statistics counters. Zone must be locked.
692 inc_stats(dns_zone_t
*zone
, isc_statscounter_t counter
) {
693 if (zone
->stats
!= NULL
)
694 isc_stats_increment(zone
->stats
, counter
);
698 *** Public functions.
702 dns_zone_create(dns_zone_t
**zonep
, isc_mem_t
*mctx
) {
707 REQUIRE(zonep
!= NULL
&& *zonep
== NULL
);
708 REQUIRE(mctx
!= NULL
);
711 zone
= isc_mem_get(mctx
, sizeof(*zone
));
713 return (ISC_R_NOMEMORY
);
716 isc_mem_attach(mctx
, &zone
->mctx
);
718 result
= isc_mutex_init(&zone
->lock
);
719 if (result
!= ISC_R_SUCCESS
)
722 result
= ZONEDB_INITLOCK(&zone
->dblock
);
723 if (result
!= ISC_R_SUCCESS
)
726 /* XXX MPA check that all elements are initialised */
727 #ifdef DNS_ZONE_CHECKLOCK
728 zone
->locked
= ISC_FALSE
;
732 ISC_LINK_INIT(zone
, link
);
733 result
= isc_refcount_init(&zone
->erefs
, 1); /* Implicit attach. */
734 if (result
!= ISC_R_SUCCESS
)
737 dns_name_init(&zone
->origin
, NULL
);
738 zone
->strnamerd
= NULL
;
739 zone
->strname
= NULL
;
740 zone
->strrdclass
= NULL
;
741 zone
->strviewname
= NULL
;
742 zone
->masterfile
= NULL
;
743 zone
->masterformat
= dns_masterformat_none
;
744 zone
->keydirectory
= NULL
;
745 zone
->journalsize
= -1;
746 zone
->journal
= NULL
;
747 zone
->rdclass
= dns_rdataclass_none
;
748 zone
->type
= dns_zone_none
;
753 zone
->db_argv
= NULL
;
754 isc_time_settoepoch(&zone
->expiretime
);
755 isc_time_settoepoch(&zone
->refreshtime
);
756 isc_time_settoepoch(&zone
->dumptime
);
757 isc_time_settoepoch(&zone
->loadtime
);
758 zone
->notifytime
= now
;
759 isc_time_settoepoch(&zone
->resigntime
);
760 isc_time_settoepoch(&zone
->keywarntime
);
761 isc_time_settoepoch(&zone
->signingtime
);
762 isc_time_settoepoch(&zone
->nsec3chaintime
);
763 isc_time_settoepoch(&zone
->refreshkeytime
);
764 zone
->refreshkeycount
= 0;
765 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
766 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
769 zone
->maxrefresh
= DNS_ZONE_MAXREFRESH
;
770 zone
->minrefresh
= DNS_ZONE_MINREFRESH
;
771 zone
->maxretry
= DNS_ZONE_MAXRETRY
;
772 zone
->minretry
= DNS_ZONE_MINRETRY
;
773 zone
->masters
= NULL
;
774 zone
->masterkeynames
= NULL
;
775 zone
->mastersok
= NULL
;
776 zone
->masterscnt
= 0;
779 zone
->notifytype
= dns_notifytype_yes
;
782 zone
->update_acl
= NULL
;
783 zone
->forward_acl
= NULL
;
784 zone
->notify_acl
= NULL
;
785 zone
->query_acl
= NULL
;
786 zone
->queryon_acl
= NULL
;
787 zone
->xfr_acl
= NULL
;
788 zone
->update_disabled
= ISC_FALSE
;
789 zone
->zero_no_soa_ttl
= ISC_TRUE
;
790 zone
->check_names
= dns_severity_ignore
;
791 zone
->request
= NULL
;
795 zone
->writeio
= NULL
;
797 zone
->idlein
= DNS_DEFAULT_IDLEIN
;
798 zone
->idleout
= DNS_DEFAULT_IDLEOUT
;
799 ISC_LIST_INIT(zone
->notifies
);
800 isc_sockaddr_any(&zone
->notifysrc4
);
801 isc_sockaddr_any6(&zone
->notifysrc6
);
802 isc_sockaddr_any(&zone
->xfrsource4
);
803 isc_sockaddr_any6(&zone
->xfrsource6
);
804 isc_sockaddr_any(&zone
->altxfrsource4
);
805 isc_sockaddr_any6(&zone
->altxfrsource6
);
807 zone
->tsigkey
= NULL
;
808 zone
->maxxfrin
= MAX_XFER_TIME
;
809 zone
->maxxfrout
= MAX_XFER_TIME
;
810 zone
->ssutable
= NULL
;
811 zone
->sigvalidityinterval
= 30 * 24 * 3600;
812 zone
->sigresigninginterval
= 7 * 24 * 3600;
815 zone
->checkmx
= NULL
;
816 zone
->checksrv
= NULL
;
817 zone
->checkns
= NULL
;
818 ISC_LINK_INIT(zone
, statelink
);
819 zone
->statelist
= NULL
;
821 zone
->requeststats_on
= ISC_FALSE
;
822 zone
->requeststats
= NULL
;
823 zone
->notifydelay
= 5;
825 zone
->isselfarg
= NULL
;
826 ISC_LIST_INIT(zone
->signing
);
827 ISC_LIST_INIT(zone
->nsec3chain
);
828 zone
->signatures
= 10;
830 zone
->privatetype
= (dns_rdatatype_t
)0xffffU
;
832 zone
->magic
= ZONE_MAGIC
;
834 /* Must be after magic is set. */
835 result
= dns_zone_setdbtype(zone
, dbargc_default
, dbargv_default
);
836 if (result
!= ISC_R_SUCCESS
)
839 ISC_EVENT_INIT(&zone
->ctlevent
, sizeof(zone
->ctlevent
), 0, NULL
,
840 DNS_EVENT_ZONECONTROL
, zone_shutdown
, zone
, zone
,
843 return (ISC_R_SUCCESS
);
846 isc_refcount_decrement(&zone
->erefs
, NULL
);
847 isc_refcount_destroy(&zone
->erefs
);
850 ZONEDB_DESTROYLOCK(&zone
->dblock
);
853 DESTROYLOCK(&zone
->lock
);
856 isc_mem_putanddetach(&zone
->mctx
, zone
, sizeof(*zone
));
861 * Free a zone. Because we require that there be no more
862 * outstanding events or references, no locking is necessary.
865 zone_free(dns_zone_t
*zone
) {
866 isc_mem_t
*mctx
= NULL
;
867 dns_signing_t
*signing
;
868 dns_nsec3chain_t
*nsec3chain
;
870 REQUIRE(DNS_ZONE_VALID(zone
));
871 REQUIRE(isc_refcount_current(&zone
->erefs
) == 0);
872 REQUIRE(zone
->irefs
== 0);
873 REQUIRE(!LOCKED_ZONE(zone
));
874 REQUIRE(zone
->timer
== NULL
);
877 * Managed objects. Order is important.
879 if (zone
->request
!= NULL
)
880 dns_request_destroy(&zone
->request
); /* XXXMPA */
881 INSIST(zone
->readio
== NULL
);
882 INSIST(zone
->statelist
== NULL
);
883 INSIST(zone
->writeio
== NULL
);
885 if (zone
->task
!= NULL
)
886 isc_task_detach(&zone
->task
);
887 if (zone
->zmgr
!= NULL
)
888 dns_zonemgr_releasezone(zone
->zmgr
, zone
);
890 /* Unmanaged objects */
891 for (signing
= ISC_LIST_HEAD(zone
->signing
);
893 signing
= ISC_LIST_HEAD(zone
->signing
)) {
894 ISC_LIST_UNLINK(zone
->signing
, signing
, link
);
895 dns_db_detach(&signing
->db
);
896 dns_dbiterator_destroy(&signing
->dbiterator
);
897 isc_mem_put(zone
->mctx
, signing
, sizeof *signing
);
899 for (nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
901 nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
)) {
902 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
, link
);
903 dns_db_detach(&nsec3chain
->db
);
904 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
905 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
907 if (zone
->masterfile
!= NULL
)
908 isc_mem_free(zone
->mctx
, zone
->masterfile
);
909 zone
->masterfile
= NULL
;
910 if (zone
->keydirectory
!= NULL
)
911 isc_mem_free(zone
->mctx
, zone
->keydirectory
);
912 zone
->keydirectory
= NULL
;
913 zone
->journalsize
= -1;
914 if (zone
->journal
!= NULL
)
915 isc_mem_free(zone
->mctx
, zone
->journal
);
916 zone
->journal
= NULL
;
917 if (zone
->stats
!= NULL
)
918 isc_stats_detach(&zone
->stats
);
919 if (zone
->requeststats
!= NULL
)
920 isc_stats_detach(&zone
->requeststats
);
921 if (zone
->db
!= NULL
)
923 if (zone
->acache
!= NULL
)
924 dns_acache_detach(&zone
->acache
);
925 zone_freedbargs(zone
);
926 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone
, NULL
, NULL
, 0)
928 RUNTIME_CHECK(dns_zone_setalsonotify(zone
, NULL
, 0)
930 zone
->check_names
= dns_severity_ignore
;
931 if (zone
->update_acl
!= NULL
)
932 dns_acl_detach(&zone
->update_acl
);
933 if (zone
->forward_acl
!= NULL
)
934 dns_acl_detach(&zone
->forward_acl
);
935 if (zone
->notify_acl
!= NULL
)
936 dns_acl_detach(&zone
->notify_acl
);
937 if (zone
->query_acl
!= NULL
)
938 dns_acl_detach(&zone
->query_acl
);
939 if (zone
->queryon_acl
!= NULL
)
940 dns_acl_detach(&zone
->queryon_acl
);
941 if (zone
->xfr_acl
!= NULL
)
942 dns_acl_detach(&zone
->xfr_acl
);
943 if (dns_name_dynamic(&zone
->origin
))
944 dns_name_free(&zone
->origin
, zone
->mctx
);
945 if (zone
->strnamerd
!= NULL
)
946 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
947 if (zone
->strname
!= NULL
)
948 isc_mem_free(zone
->mctx
, zone
->strname
);
949 if (zone
->strrdclass
!= NULL
)
950 isc_mem_free(zone
->mctx
, zone
->strrdclass
);
951 if (zone
->strviewname
!= NULL
)
952 isc_mem_free(zone
->mctx
, zone
->strviewname
);
953 if (zone
->ssutable
!= NULL
)
954 dns_ssutable_detach(&zone
->ssutable
);
957 ZONEDB_DESTROYLOCK(&zone
->dblock
);
958 DESTROYLOCK(&zone
->lock
);
959 isc_refcount_destroy(&zone
->erefs
);
962 isc_mem_put(mctx
, zone
, sizeof(*zone
));
963 isc_mem_detach(&mctx
);
970 dns_zone_setclass(dns_zone_t
*zone
, dns_rdataclass_t rdclass
) {
973 REQUIRE(DNS_ZONE_VALID(zone
));
974 REQUIRE(rdclass
!= dns_rdataclass_none
);
980 REQUIRE(zone
->rdclass
== dns_rdataclass_none
||
981 zone
->rdclass
== rdclass
);
982 zone
->rdclass
= rdclass
;
984 if (zone
->strnamerd
!= NULL
)
985 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
986 if (zone
->strrdclass
!= NULL
)
987 isc_mem_free(zone
->mctx
, zone
->strrdclass
);
989 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
990 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
991 zone_rdclass_tostr(zone
, namebuf
, sizeof namebuf
);
992 zone
->strrdclass
= isc_mem_strdup(zone
->mctx
, namebuf
);
998 dns_zone_getclass(dns_zone_t
*zone
) {
999 REQUIRE(DNS_ZONE_VALID(zone
));
1001 return (zone
->rdclass
);
1005 dns_zone_setnotifytype(dns_zone_t
*zone
, dns_notifytype_t notifytype
) {
1006 REQUIRE(DNS_ZONE_VALID(zone
));
1009 zone
->notifytype
= notifytype
;
1014 dns_zone_getserial2(dns_zone_t
*zone
, isc_uint32_t
*serialp
) {
1015 isc_result_t result
;
1017 REQUIRE(DNS_ZONE_VALID(zone
));
1018 REQUIRE(serialp
!= NULL
);
1021 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
1022 if (zone
->db
!= NULL
) {
1023 result
= zone_get_from_db(zone
, zone
->db
, NULL
, NULL
, serialp
,
1024 NULL
, NULL
, NULL
, NULL
, NULL
);
1026 result
= DNS_R_NOTLOADED
;
1027 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
1034 dns_zone_getserial(dns_zone_t
*zone
) {
1035 isc_result_t result
;
1036 isc_uint32_t serial
;
1038 result
= dns_zone_getserial2(zone
, &serial
);
1039 if (result
!= ISC_R_SUCCESS
)
1040 serial
= 0; /* XXX: not really correct, but no other choice */
1049 dns_zone_settype(dns_zone_t
*zone
, dns_zonetype_t type
) {
1051 REQUIRE(DNS_ZONE_VALID(zone
));
1052 REQUIRE(type
!= dns_zone_none
);
1058 REQUIRE(zone
->type
== dns_zone_none
|| zone
->type
== type
);
1064 zone_freedbargs(dns_zone_t
*zone
) {
1067 /* Free the old database argument list. */
1068 if (zone
->db_argv
!= NULL
) {
1069 for (i
= 0; i
< zone
->db_argc
; i
++)
1070 isc_mem_free(zone
->mctx
, zone
->db_argv
[i
]);
1071 isc_mem_put(zone
->mctx
, zone
->db_argv
,
1072 zone
->db_argc
* sizeof(*zone
->db_argv
));
1075 zone
->db_argv
= NULL
;
1079 dns_zone_getdbtype(dns_zone_t
*zone
, char ***argv
, isc_mem_t
*mctx
) {
1082 isc_result_t result
= ISC_R_SUCCESS
;
1086 REQUIRE(DNS_ZONE_VALID(zone
));
1087 REQUIRE(argv
!= NULL
&& *argv
== NULL
);
1090 size
= (zone
->db_argc
+ 1) * sizeof(char *);
1091 for (i
= 0; i
< zone
->db_argc
; i
++)
1092 size
+= strlen(zone
->db_argv
[i
]) + 1;
1093 mem
= isc_mem_allocate(mctx
, size
);
1097 tmp2
+= (zone
->db_argc
+ 1) * sizeof(char *);
1098 for (i
= 0; i
< zone
->db_argc
; i
++) {
1100 strcpy(tmp2
, zone
->db_argv
[i
]);
1101 tmp2
+= strlen(tmp2
) + 1;
1105 result
= ISC_R_NOMEMORY
;
1112 dns_zone_setdbtype(dns_zone_t
*zone
,
1113 unsigned int dbargc
, const char * const *dbargv
) {
1114 isc_result_t result
= ISC_R_SUCCESS
;
1118 REQUIRE(DNS_ZONE_VALID(zone
));
1119 REQUIRE(dbargc
>= 1);
1120 REQUIRE(dbargv
!= NULL
);
1124 /* Set up a new database argument list. */
1125 new = isc_mem_get(zone
->mctx
, dbargc
* sizeof(*new));
1128 for (i
= 0; i
< dbargc
; i
++)
1130 for (i
= 0; i
< dbargc
; i
++) {
1131 new[i
] = isc_mem_strdup(zone
->mctx
, dbargv
[i
]);
1136 /* Free the old list. */
1137 zone_freedbargs(zone
);
1139 zone
->db_argc
= dbargc
;
1140 zone
->db_argv
= new;
1141 result
= ISC_R_SUCCESS
;
1146 for (i
= 0; i
< dbargc
; i
++)
1148 isc_mem_free(zone
->mctx
, new[i
]);
1149 isc_mem_put(zone
->mctx
, new, dbargc
* sizeof(*new));
1151 result
= ISC_R_NOMEMORY
;
1159 dns_zone_setview(dns_zone_t
*zone
, dns_view_t
*view
) {
1161 REQUIRE(DNS_ZONE_VALID(zone
));
1164 if (zone
->view
!= NULL
)
1165 dns_view_weakdetach(&zone
->view
);
1166 dns_view_weakattach(view
, &zone
->view
);
1168 if (zone
->strviewname
!= NULL
)
1169 isc_mem_free(zone
->mctx
, zone
->strviewname
);
1170 if (zone
->strnamerd
!= NULL
)
1171 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
1173 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
1174 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
1175 zone_viewname_tostr(zone
, namebuf
, sizeof namebuf
);
1176 zone
->strviewname
= isc_mem_strdup(zone
->mctx
, namebuf
);
1183 dns_zone_getview(dns_zone_t
*zone
) {
1184 REQUIRE(DNS_ZONE_VALID(zone
));
1186 return (zone
->view
);
1191 dns_zone_setorigin(dns_zone_t
*zone
, const dns_name_t
*origin
) {
1192 isc_result_t result
;
1195 REQUIRE(DNS_ZONE_VALID(zone
));
1196 REQUIRE(origin
!= NULL
);
1199 if (dns_name_dynamic(&zone
->origin
)) {
1200 dns_name_free(&zone
->origin
, zone
->mctx
);
1201 dns_name_init(&zone
->origin
, NULL
);
1203 result
= dns_name_dup(origin
, zone
->mctx
, &zone
->origin
);
1205 if (zone
->strnamerd
!= NULL
)
1206 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
1207 if (zone
->strname
!= NULL
)
1208 isc_mem_free(zone
->mctx
, zone
->strname
);
1210 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
1211 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
1212 zone_name_tostr(zone
, namebuf
, sizeof namebuf
);
1213 zone
->strname
= isc_mem_strdup(zone
->mctx
, namebuf
);
1220 dns_zone_setacache(dns_zone_t
*zone
, dns_acache_t
*acache
) {
1221 REQUIRE(DNS_ZONE_VALID(zone
));
1222 REQUIRE(acache
!= NULL
);
1225 if (zone
->acache
!= NULL
)
1226 dns_acache_detach(&zone
->acache
);
1227 dns_acache_attach(acache
, &zone
->acache
);
1228 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
1229 if (zone
->db
!= NULL
) {
1230 isc_result_t result
;
1233 * If the zone reuses an existing DB, the DB needs to be
1234 * set in the acache explicitly. We can safely ignore the
1235 * case where the DB is already set. If other error happens,
1236 * the acache will not work effectively.
1238 result
= dns_acache_setdb(acache
, zone
->db
);
1239 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_EXISTS
) {
1240 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
1241 "dns_acache_setdb() failed: %s",
1242 isc_result_totext(result
));
1245 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
1250 dns_zone_setstring(dns_zone_t
*zone
, char **field
, const char *value
) {
1253 if (value
!= NULL
) {
1254 copy
= isc_mem_strdup(zone
->mctx
, value
);
1256 return (ISC_R_NOMEMORY
);
1262 isc_mem_free(zone
->mctx
, *field
);
1265 return (ISC_R_SUCCESS
);
1269 dns_zone_setfile(dns_zone_t
*zone
, const char *file
) {
1270 return (dns_zone_setfile2(zone
, file
, dns_masterformat_text
));
1274 dns_zone_setfile2(dns_zone_t
*zone
, const char *file
,
1275 dns_masterformat_t format
) {
1276 isc_result_t result
= ISC_R_SUCCESS
;
1278 REQUIRE(DNS_ZONE_VALID(zone
));
1281 result
= dns_zone_setstring(zone
, &zone
->masterfile
, file
);
1282 if (result
== ISC_R_SUCCESS
) {
1283 zone
->masterformat
= format
;
1284 result
= default_journal(zone
);
1292 dns_zone_getfile(dns_zone_t
*zone
) {
1293 REQUIRE(DNS_ZONE_VALID(zone
));
1295 return (zone
->masterfile
);
1299 default_journal(dns_zone_t
*zone
) {
1300 isc_result_t result
;
1303 REQUIRE(DNS_ZONE_VALID(zone
));
1304 REQUIRE(LOCKED_ZONE(zone
));
1306 if (zone
->masterfile
!= NULL
) {
1307 /* Calculate string length including '\0'. */
1308 int len
= strlen(zone
->masterfile
) + sizeof(".jnl");
1309 journal
= isc_mem_allocate(zone
->mctx
, len
);
1310 if (journal
== NULL
)
1311 return (ISC_R_NOMEMORY
);
1312 strcpy(journal
, zone
->masterfile
);
1313 strcat(journal
, ".jnl");
1317 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
1318 if (journal
!= NULL
)
1319 isc_mem_free(zone
->mctx
, journal
);
1324 dns_zone_setjournal(dns_zone_t
*zone
, const char *journal
) {
1325 isc_result_t result
= ISC_R_SUCCESS
;
1327 REQUIRE(DNS_ZONE_VALID(zone
));
1330 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
1337 dns_zone_getjournal(dns_zone_t
*zone
) {
1338 REQUIRE(DNS_ZONE_VALID(zone
));
1340 return (zone
->journal
);
1344 * Return true iff the zone is "dynamic", in the sense that the zone's
1345 * master file (if any) is written by the server, rather than being
1346 * updated manually and read by the server.
1348 * This is true for slave zones, stub zones, and zones that allow
1349 * dynamic updates either by having an update policy ("ssutable")
1350 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1352 static isc_boolean_t
1353 zone_isdynamic(dns_zone_t
*zone
) {
1354 REQUIRE(DNS_ZONE_VALID(zone
));
1356 return (ISC_TF(zone
->type
== dns_zone_slave
||
1357 zone
->type
== dns_zone_stub
||
1358 zone
->type
== dns_zone_key
||
1359 (!zone
->update_disabled
&& zone
->ssutable
!= NULL
) ||
1360 (!zone
->update_disabled
&& zone
->update_acl
!= NULL
&&
1361 !dns_acl_isnone(zone
->update_acl
))));
1366 zone_load(dns_zone_t
*zone
, unsigned int flags
) {
1367 isc_result_t result
;
1369 isc_time_t loadtime
, filetime
;
1370 dns_db_t
*db
= NULL
;
1372 REQUIRE(DNS_ZONE_VALID(zone
));
1377 INSIST(zone
->type
!= dns_zone_none
);
1379 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
1380 if ((flags
& DNS_ZONELOADFLAG_THAW
) != 0)
1381 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_THAW
);
1382 result
= DNS_R_CONTINUE
;
1386 if (zone
->db
!= NULL
&& zone
->masterfile
== NULL
) {
1388 * The zone has no master file configured, but it already
1389 * has a database. It could be the built-in
1390 * version.bind. CH zone, a zone with a persistent
1391 * database being reloaded, or maybe a zone that
1392 * used to have a master file but whose configuration
1393 * was changed so that it no longer has one. Do nothing.
1395 result
= ISC_R_SUCCESS
;
1399 if (zone
->db
!= NULL
&& zone_isdynamic(zone
)) {
1401 * This is a slave, stub, or dynamically updated
1402 * zone being reloaded. Do nothing - the database
1403 * we already have is guaranteed to be up-to-date.
1405 if (zone
->type
== dns_zone_master
)
1406 result
= DNS_R_DYNAMIC
;
1408 result
= ISC_R_SUCCESS
;
1414 * Store the current time before the zone is loaded, so that if the
1415 * file changes between the time of the load and the time that
1416 * zone->loadtime is set, then the file will still be reloaded
1417 * the next time dns_zone_load is called.
1419 TIME_NOW(&loadtime
);
1422 * Don't do the load if the file that stores the zone is older
1423 * than the last time the zone was loaded. If the zone has not
1424 * been loaded yet, zone->loadtime will be the epoch.
1426 if (zone
->masterfile
!= NULL
) {
1428 * The file is already loaded. If we are just doing a
1429 * "rndc reconfig", we are done.
1431 if (!isc_time_isepoch(&zone
->loadtime
) &&
1432 (flags
& DNS_ZONELOADFLAG_NOSTAT
) != 0) {
1433 result
= ISC_R_SUCCESS
;
1437 result
= isc_file_getmodtime(zone
->masterfile
, &filetime
);
1438 if (result
== ISC_R_SUCCESS
) {
1439 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
1440 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HASINCLUDE
) &&
1441 isc_time_compare(&filetime
, &zone
->loadtime
) <= 0) {
1442 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1443 "skipping load: master file "
1444 "older than last load");
1445 result
= DNS_R_UPTODATE
;
1448 loadtime
= filetime
;
1452 INSIST(zone
->db_argc
>= 1);
1455 * Built in zones don't need to be reloaded.
1457 if (zone
->type
== dns_zone_master
&&
1458 strcmp(zone
->db_argv
[0], "_builtin") == 0 &&
1459 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
1460 result
= ISC_R_SUCCESS
;
1464 if ((zone
->type
== dns_zone_slave
|| zone
->type
== dns_zone_stub
) &&
1465 (strcmp(zone
->db_argv
[0], "rbt") == 0 ||
1466 strcmp(zone
->db_argv
[0], "rbt64") == 0)) {
1467 if (zone
->masterfile
== NULL
||
1468 !isc_file_exists(zone
->masterfile
)) {
1469 if (zone
->masterfile
!= NULL
) {
1470 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1473 zone
->refreshtime
= now
;
1474 if (zone
->task
!= NULL
)
1475 zone_settimer(zone
, &now
);
1476 result
= ISC_R_SUCCESS
;
1481 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "starting load");
1483 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
1484 &zone
->origin
, (zone
->type
== dns_zone_stub
) ?
1485 dns_dbtype_stub
: dns_dbtype_zone
,
1487 zone
->db_argc
- 1, zone
->db_argv
+ 1,
1490 if (result
!= ISC_R_SUCCESS
) {
1491 dns_zone_log(zone
, ISC_LOG_ERROR
,
1492 "loading zone: creating database: %s",
1493 isc_result_totext(result
));
1496 dns_db_settask(db
, zone
->task
);
1498 if (! dns_db_ispersistent(db
)) {
1499 if (zone
->masterfile
!= NULL
) {
1500 result
= zone_startload(db
, zone
, loadtime
);
1502 result
= DNS_R_NOMASTERFILE
;
1503 if (zone
->type
== dns_zone_master
) {
1504 dns_zone_log(zone
, ISC_LOG_ERROR
,
1506 "no master file configured");
1509 dns_zone_log(zone
, ISC_LOG_INFO
, "loading zone: "
1510 "no master file configured: continuing");
1514 if (result
== DNS_R_CONTINUE
) {
1515 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADING
);
1516 if ((flags
& DNS_ZONELOADFLAG_THAW
) != 0)
1517 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_THAW
);
1521 result
= zone_postload(zone
, db
, loadtime
, result
);
1531 dns_zone_load(dns_zone_t
*zone
) {
1532 return (zone_load(zone
, 0));
1536 dns_zone_loadnew(dns_zone_t
*zone
) {
1537 return (zone_load(zone
, DNS_ZONELOADFLAG_NOSTAT
));
1541 dns_zone_loadandthaw(dns_zone_t
*zone
) {
1542 isc_result_t result
;
1544 result
= zone_load(zone
, DNS_ZONELOADFLAG_THAW
);
1546 case DNS_R_CONTINUE
:
1547 /* Deferred thaw. */
1550 case DNS_R_UPTODATE
:
1551 case DNS_R_SEENINCLUDE
:
1552 zone
->update_disabled
= ISC_FALSE
;
1554 case DNS_R_NOMASTERFILE
:
1555 zone
->update_disabled
= ISC_FALSE
;
1558 /* Error, remain in disabled state. */
1565 get_master_options(dns_zone_t
*zone
) {
1566 unsigned int options
;
1568 options
= DNS_MASTER_ZONE
;
1569 if (zone
->type
== dns_zone_slave
)
1570 options
|= DNS_MASTER_SLAVE
;
1571 if (zone
->type
== dns_zone_key
)
1572 options
|= DNS_MASTER_KEY
;
1573 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNS
))
1574 options
|= DNS_MASTER_CHECKNS
;
1575 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_FATALNS
))
1576 options
|= DNS_MASTER_FATALNS
;
1577 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMES
))
1578 options
|= DNS_MASTER_CHECKNAMES
;
1579 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
))
1580 options
|= DNS_MASTER_CHECKNAMESFAIL
;
1581 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKMX
))
1582 options
|= DNS_MASTER_CHECKMX
;
1583 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKMXFAIL
))
1584 options
|= DNS_MASTER_CHECKMXFAIL
;
1585 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKWILDCARD
))
1586 options
|= DNS_MASTER_CHECKWILDCARD
;
1587 if (zone
->type
== dns_zone_master
&&
1588 (zone
->update_acl
!= NULL
|| zone
->ssutable
!= NULL
))
1589 options
|= DNS_MASTER_RESIGN
;
1594 zone_gotreadhandle(isc_task_t
*task
, isc_event_t
*event
) {
1595 dns_load_t
*load
= event
->ev_arg
;
1596 isc_result_t result
= ISC_R_SUCCESS
;
1597 unsigned int options
;
1599 REQUIRE(DNS_LOAD_VALID(load
));
1601 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
1602 result
= ISC_R_CANCELED
;
1603 isc_event_free(&event
);
1604 if (result
== ISC_R_CANCELED
)
1607 options
= get_master_options(load
->zone
);
1609 result
= dns_master_loadfileinc3(load
->zone
->masterfile
,
1610 dns_db_origin(load
->db
),
1611 dns_db_origin(load
->db
),
1612 load
->zone
->rdclass
,
1614 load
->zone
->sigresigninginterval
,
1615 &load
->callbacks
, task
,
1616 zone_loaddone
, load
,
1617 &load
->zone
->lctx
, load
->zone
->mctx
,
1618 load
->zone
->masterformat
);
1619 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_CONTINUE
&&
1620 result
!= DNS_R_SEENINCLUDE
)
1625 zone_loaddone(load
, result
);
1629 zone_gotwritehandle(isc_task_t
*task
, isc_event_t
*event
) {
1630 const char me
[] = "zone_gotwritehandle";
1631 dns_zone_t
*zone
= event
->ev_arg
;
1632 isc_result_t result
= ISC_R_SUCCESS
;
1633 dns_dbversion_t
*version
= NULL
;
1635 REQUIRE(DNS_ZONE_VALID(zone
));
1636 INSIST(task
== zone
->task
);
1639 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
1640 result
= ISC_R_CANCELED
;
1641 isc_event_free(&event
);
1642 if (result
== ISC_R_CANCELED
)
1646 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
1647 dns_db_currentversion(zone
->db
, &version
);
1648 result
= dns_master_dumpinc2(zone
->mctx
, zone
->db
, version
,
1649 &dns_master_style_default
,
1650 zone
->masterfile
, zone
->task
, dump_done
,
1651 zone
, &zone
->dctx
, zone
->masterformat
);
1652 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
1653 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
1655 if (result
!= DNS_R_CONTINUE
)
1660 dump_done(zone
, result
);
1664 zone_startload(dns_db_t
*db
, dns_zone_t
*zone
, isc_time_t loadtime
) {
1666 isc_result_t result
;
1667 isc_result_t tresult
;
1668 unsigned int options
;
1670 options
= get_master_options(zone
);
1672 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MANYERRORS
))
1673 options
|= DNS_MASTER_MANYERRORS
;
1675 if (zone
->zmgr
!= NULL
&& zone
->db
!= NULL
&& zone
->task
!= NULL
) {
1676 load
= isc_mem_get(zone
->mctx
, sizeof(*load
));
1678 return (ISC_R_NOMEMORY
);
1683 load
->loadtime
= loadtime
;
1684 load
->magic
= LOAD_MAGIC
;
1686 isc_mem_attach(zone
->mctx
, &load
->mctx
);
1687 zone_iattach(zone
, &load
->zone
);
1688 dns_db_attach(db
, &load
->db
);
1689 dns_rdatacallbacks_init(&load
->callbacks
);
1690 result
= dns_db_beginload(db
, &load
->callbacks
.add
,
1691 &load
->callbacks
.add_private
);
1692 if (result
!= ISC_R_SUCCESS
)
1694 result
= zonemgr_getio(zone
->zmgr
, ISC_TRUE
, zone
->task
,
1695 zone_gotreadhandle
, load
,
1697 if (result
!= ISC_R_SUCCESS
) {
1699 * We can't report multiple errors so ignore
1700 * the result of dns_db_endload().
1702 (void)dns_db_endload(load
->db
,
1703 &load
->callbacks
.add_private
);
1706 result
= DNS_R_CONTINUE
;
1708 dns_rdatacallbacks_t callbacks
;
1710 dns_rdatacallbacks_init(&callbacks
);
1711 result
= dns_db_beginload(db
, &callbacks
.add
,
1712 &callbacks
.add_private
);
1713 if (result
!= ISC_R_SUCCESS
)
1715 result
= dns_master_loadfile3(zone
->masterfile
, &zone
->origin
,
1716 &zone
->origin
, zone
->rdclass
,
1717 options
, zone
->sigresigninginterval
,
1718 &callbacks
, zone
->mctx
,
1719 zone
->masterformat
);
1720 tresult
= dns_db_endload(db
, &callbacks
.add_private
);
1721 if (result
== ISC_R_SUCCESS
)
1729 dns_db_detach(&load
->db
);
1730 zone_idetach(&load
->zone
);
1731 isc_mem_detach(&load
->mctx
);
1732 isc_mem_put(zone
->mctx
, load
, sizeof(*load
));
1736 static isc_boolean_t
1737 zone_check_mx(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
1740 isc_result_t result
;
1741 char ownerbuf
[DNS_NAME_FORMATSIZE
];
1742 char namebuf
[DNS_NAME_FORMATSIZE
];
1743 char altbuf
[DNS_NAME_FORMATSIZE
];
1744 dns_fixedname_t fixed
;
1745 dns_name_t
*foundname
;
1751 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
1752 if (zone
->checkmx
!= NULL
)
1753 return ((zone
->checkmx
)(zone
, name
, owner
));
1757 if (zone
->type
== dns_zone_master
)
1758 level
= ISC_LOG_ERROR
;
1760 level
= ISC_LOG_WARNING
;
1762 dns_fixedname_init(&fixed
);
1763 foundname
= dns_fixedname_name(&fixed
);
1765 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
1766 0, 0, NULL
, foundname
, NULL
, NULL
);
1767 if (result
== ISC_R_SUCCESS
)
1770 if (result
== DNS_R_NXRRSET
) {
1771 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
1772 0, 0, NULL
, foundname
, NULL
, NULL
);
1773 if (result
== ISC_R_SUCCESS
)
1777 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
1778 dns_name_format(name
, namebuf
, sizeof namebuf
);
1779 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
1780 result
== DNS_R_EMPTYNAME
) {
1781 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKMXFAIL
))
1782 level
= ISC_LOG_WARNING
;
1783 dns_zone_log(zone
, level
,
1784 "%s/MX '%s' has no address records (A or AAAA)",
1786 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1789 if (result
== DNS_R_CNAME
) {
1790 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNMXCNAME
) ||
1791 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
1792 level
= ISC_LOG_WARNING
;
1793 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
1794 dns_zone_log(zone
, level
,
1795 "%s/MX '%s' is a CNAME (illegal)",
1797 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1800 if (result
== DNS_R_DNAME
) {
1801 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNMXCNAME
) ||
1802 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
1803 level
= ISC_LOG_WARNING
;
1804 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
)) {
1805 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
1806 dns_zone_log(zone
, level
, "%s/MX '%s' is below a DNAME"
1807 " '%s' (illegal)", ownerbuf
, namebuf
,
1810 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1813 if (zone
->checkmx
!= NULL
&& result
== DNS_R_DELEGATION
)
1814 return ((zone
->checkmx
)(zone
, name
, owner
));
1819 static isc_boolean_t
1820 zone_check_srv(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
1823 isc_result_t result
;
1824 char ownerbuf
[DNS_NAME_FORMATSIZE
];
1825 char namebuf
[DNS_NAME_FORMATSIZE
];
1826 char altbuf
[DNS_NAME_FORMATSIZE
];
1827 dns_fixedname_t fixed
;
1828 dns_name_t
*foundname
;
1832 * "." means the services does not exist.
1834 if (dns_name_equal(name
, dns_rootname
))
1840 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
1841 if (zone
->checksrv
!= NULL
)
1842 return ((zone
->checksrv
)(zone
, name
, owner
));
1846 if (zone
->type
== dns_zone_master
)
1847 level
= ISC_LOG_ERROR
;
1849 level
= ISC_LOG_WARNING
;
1851 dns_fixedname_init(&fixed
);
1852 foundname
= dns_fixedname_name(&fixed
);
1854 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
1855 0, 0, NULL
, foundname
, NULL
, NULL
);
1856 if (result
== ISC_R_SUCCESS
)
1859 if (result
== DNS_R_NXRRSET
) {
1860 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
1861 0, 0, NULL
, foundname
, NULL
, NULL
);
1862 if (result
== ISC_R_SUCCESS
)
1866 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
1867 dns_name_format(name
, namebuf
, sizeof namebuf
);
1868 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
1869 result
== DNS_R_EMPTYNAME
) {
1870 dns_zone_log(zone
, level
,
1871 "%s/SRV '%s' has no address records (A or AAAA)",
1873 /* XXX950 make fatal for 9.5.0. */
1877 if (result
== DNS_R_CNAME
) {
1878 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNSRVCNAME
) ||
1879 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
1880 level
= ISC_LOG_WARNING
;
1881 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
1882 dns_zone_log(zone
, level
,
1883 "%s/SRV '%s' is a CNAME (illegal)",
1885 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1888 if (result
== DNS_R_DNAME
) {
1889 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNSRVCNAME
) ||
1890 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
1891 level
= ISC_LOG_WARNING
;
1892 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
)) {
1893 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
1894 dns_zone_log(zone
, level
, "%s/SRV '%s' is below a "
1895 "DNAME '%s' (illegal)", ownerbuf
, namebuf
,
1898 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1901 if (zone
->checksrv
!= NULL
&& result
== DNS_R_DELEGATION
)
1902 return ((zone
->checksrv
)(zone
, name
, owner
));
1907 static isc_boolean_t
1908 zone_check_glue(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
1911 isc_boolean_t answer
= ISC_TRUE
;
1912 isc_result_t result
, tresult
;
1913 char ownerbuf
[DNS_NAME_FORMATSIZE
];
1914 char namebuf
[DNS_NAME_FORMATSIZE
];
1915 char altbuf
[DNS_NAME_FORMATSIZE
];
1916 dns_fixedname_t fixed
;
1917 dns_name_t
*foundname
;
1919 dns_rdataset_t aaaa
;
1925 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
1926 if (zone
->checkns
!= NULL
)
1927 return ((zone
->checkns
)(zone
, name
, owner
, NULL
, NULL
));
1931 if (zone
->type
== dns_zone_master
)
1932 level
= ISC_LOG_ERROR
;
1934 level
= ISC_LOG_WARNING
;
1936 dns_fixedname_init(&fixed
);
1937 foundname
= dns_fixedname_name(&fixed
);
1938 dns_rdataset_init(&a
);
1939 dns_rdataset_init(&aaaa
);
1941 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
1942 DNS_DBFIND_GLUEOK
, 0, NULL
,
1943 foundname
, &a
, NULL
);
1945 if (result
== ISC_R_SUCCESS
) {
1946 dns_rdataset_disassociate(&a
);
1948 } else if (result
== DNS_R_DELEGATION
)
1949 dns_rdataset_disassociate(&a
);
1951 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_DELEGATION
||
1952 result
== DNS_R_GLUE
) {
1953 tresult
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
1954 DNS_DBFIND_GLUEOK
, 0, NULL
,
1955 foundname
, &aaaa
, NULL
);
1956 if (tresult
== ISC_R_SUCCESS
) {
1957 dns_rdataset_disassociate(&aaaa
);
1960 if (tresult
== DNS_R_DELEGATION
)
1961 dns_rdataset_disassociate(&aaaa
);
1962 if (result
== DNS_R_GLUE
|| tresult
== DNS_R_GLUE
) {
1964 * Check glue against child zone.
1966 if (zone
->checkns
!= NULL
)
1967 answer
= (zone
->checkns
)(zone
, name
, owner
,
1969 if (dns_rdataset_isassociated(&a
))
1970 dns_rdataset_disassociate(&a
);
1971 if (dns_rdataset_isassociated(&aaaa
))
1972 dns_rdataset_disassociate(&aaaa
);
1978 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
1979 dns_name_format(name
, namebuf
, sizeof namebuf
);
1980 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
1981 result
== DNS_R_EMPTYNAME
|| result
== DNS_R_DELEGATION
) {
1983 isc_boolean_t required
= ISC_FALSE
;
1984 if (dns_name_issubdomain(name
, owner
)) {
1985 what
= "REQUIRED GLUE ";
1986 required
= ISC_TRUE
;
1987 } else if (result
== DNS_R_DELEGATION
)
1988 what
= "SIBLING GLUE ";
1992 if (result
!= DNS_R_DELEGATION
|| required
||
1993 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKSIBLING
)) {
1994 dns_zone_log(zone
, level
, "%s/NS '%s' has no %s"
1995 "address records (A or AAAA)",
1996 ownerbuf
, namebuf
, what
);
1998 * Log missing address record.
2000 if (result
== DNS_R_DELEGATION
&& zone
->checkns
!= NULL
)
2001 (void)(zone
->checkns
)(zone
, name
, owner
,
2003 /* XXX950 make fatal for 9.5.0. */
2004 /* answer = ISC_FALSE; */
2006 } else if (result
== DNS_R_CNAME
) {
2007 dns_zone_log(zone
, level
, "%s/NS '%s' is a CNAME (illegal)",
2009 /* XXX950 make fatal for 9.5.0. */
2010 /* answer = ISC_FALSE; */
2011 } else if (result
== DNS_R_DNAME
) {
2012 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
2013 dns_zone_log(zone
, level
,
2014 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2015 ownerbuf
, namebuf
, altbuf
);
2016 /* XXX950 make fatal for 9.5.0. */
2017 /* answer = ISC_FALSE; */
2020 if (dns_rdataset_isassociated(&a
))
2021 dns_rdataset_disassociate(&a
);
2022 if (dns_rdataset_isassociated(&aaaa
))
2023 dns_rdataset_disassociate(&aaaa
);
2027 static isc_boolean_t
2028 zone_rrset_check_dup(dns_zone_t
*zone
, dns_name_t
*owner
,
2029 dns_rdataset_t
*rdataset
)
2031 dns_rdataset_t tmprdataset
;
2032 isc_result_t result
;
2033 isc_boolean_t answer
= ISC_TRUE
;
2034 isc_boolean_t format
= ISC_TRUE
;
2035 int level
= ISC_LOG_WARNING
;
2036 char ownerbuf
[DNS_NAME_FORMATSIZE
];
2037 char typebuf
[DNS_RDATATYPE_FORMATSIZE
];
2038 unsigned int count1
= 0;
2040 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKDUPRRFAIL
))
2041 level
= ISC_LOG_ERROR
;
2043 dns_rdataset_init(&tmprdataset
);
2044 for (result
= dns_rdataset_first(rdataset
);
2045 result
== ISC_R_SUCCESS
;
2046 result
= dns_rdataset_next(rdataset
)) {
2047 dns_rdata_t rdata1
= DNS_RDATA_INIT
;
2048 unsigned int count2
= 0;
2051 dns_rdataset_current(rdataset
, &rdata1
);
2052 dns_rdataset_clone(rdataset
, &tmprdataset
);
2053 for (result
= dns_rdataset_first(&tmprdataset
);
2054 result
== ISC_R_SUCCESS
;
2055 result
= dns_rdataset_next(&tmprdataset
)) {
2056 dns_rdata_t rdata2
= DNS_RDATA_INIT
;
2058 if (count1
>= count2
)
2060 dns_rdataset_current(&tmprdataset
, &rdata2
);
2061 if (dns_rdata_casecompare(&rdata1
, &rdata2
) == 0) {
2063 dns_name_format(owner
, ownerbuf
,
2065 dns_rdatatype_format(rdata1
.type
,
2070 dns_zone_log(zone
, level
, "%s/%s has "
2071 "semantically identical records",
2073 if (level
== ISC_LOG_ERROR
)
2078 dns_rdataset_disassociate(&tmprdataset
);
2085 static isc_boolean_t
2086 zone_check_dup(dns_zone_t
*zone
, dns_db_t
*db
) {
2087 dns_dbiterator_t
*dbiterator
= NULL
;
2088 dns_dbnode_t
*node
= NULL
;
2089 dns_fixedname_t fixed
;
2091 dns_rdataset_t rdataset
;
2092 dns_rdatasetiter_t
*rdsit
= NULL
;
2093 isc_boolean_t ok
= ISC_TRUE
;
2094 isc_result_t result
;
2096 dns_fixedname_init(&fixed
);
2097 name
= dns_fixedname_name(&fixed
);
2098 dns_rdataset_init(&rdataset
);
2100 result
= dns_db_createiterator(db
, 0, &dbiterator
);
2101 if (result
!= ISC_R_SUCCESS
)
2104 for (result
= dns_dbiterator_first(dbiterator
);
2105 result
== ISC_R_SUCCESS
;
2106 result
= dns_dbiterator_next(dbiterator
)) {
2107 result
= dns_dbiterator_current(dbiterator
, &node
, name
);
2108 if (result
!= ISC_R_SUCCESS
)
2111 result
= dns_db_allrdatasets(db
, node
, NULL
, 0, &rdsit
);
2112 if (result
!= ISC_R_SUCCESS
)
2115 for (result
= dns_rdatasetiter_first(rdsit
);
2116 result
== ISC_R_SUCCESS
;
2117 result
= dns_rdatasetiter_next(rdsit
)) {
2118 dns_rdatasetiter_current(rdsit
, &rdataset
);
2119 if (!zone_rrset_check_dup(zone
, name
, &rdataset
))
2121 dns_rdataset_disassociate(&rdataset
);
2123 dns_rdatasetiter_destroy(&rdsit
);
2124 dns_db_detachnode(db
, &node
);
2128 dns_db_detachnode(db
, &node
);
2129 dns_dbiterator_destroy(&dbiterator
);
2134 static isc_boolean_t
2135 integrity_checks(dns_zone_t
*zone
, dns_db_t
*db
) {
2136 dns_dbiterator_t
*dbiterator
= NULL
;
2137 dns_dbnode_t
*node
= NULL
;
2138 dns_rdataset_t rdataset
;
2139 dns_fixedname_t fixed
;
2140 dns_fixedname_t fixedbottom
;
2143 dns_rdata_in_srv_t srv
;
2147 isc_result_t result
;
2148 isc_boolean_t ok
= ISC_TRUE
;
2150 dns_fixedname_init(&fixed
);
2151 name
= dns_fixedname_name(&fixed
);
2152 dns_fixedname_init(&fixedbottom
);
2153 bottom
= dns_fixedname_name(&fixedbottom
);
2154 dns_rdataset_init(&rdataset
);
2155 dns_rdata_init(&rdata
);
2157 result
= dns_db_createiterator(db
, 0, &dbiterator
);
2158 if (result
!= ISC_R_SUCCESS
)
2161 result
= dns_dbiterator_first(dbiterator
);
2162 while (result
== ISC_R_SUCCESS
) {
2163 result
= dns_dbiterator_current(dbiterator
, &node
, name
);
2164 if (result
!= ISC_R_SUCCESS
)
2168 * Is this name visible in the zone?
2170 if (!dns_name_issubdomain(name
, &zone
->origin
) ||
2171 (dns_name_countlabels(bottom
) > 0 &&
2172 dns_name_issubdomain(name
, bottom
)))
2176 * Don't check the NS records at the origin.
2178 if (dns_name_equal(name
, &zone
->origin
))
2181 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_ns
,
2182 0, 0, &rdataset
, NULL
);
2183 if (result
!= ISC_R_SUCCESS
)
2186 * Remember bottom of zone.
2188 dns_name_copy(name
, bottom
, NULL
);
2190 result
= dns_rdataset_first(&rdataset
);
2191 while (result
== ISC_R_SUCCESS
) {
2192 dns_rdataset_current(&rdataset
, &rdata
);
2193 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
2194 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2195 if (!zone_check_glue(zone
, db
, &ns
.name
, name
))
2197 dns_rdata_reset(&rdata
);
2198 result
= dns_rdataset_next(&rdataset
);
2200 dns_rdataset_disassociate(&rdataset
);
2204 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_mx
,
2205 0, 0, &rdataset
, NULL
);
2206 if (result
!= ISC_R_SUCCESS
)
2208 result
= dns_rdataset_first(&rdataset
);
2209 while (result
== ISC_R_SUCCESS
) {
2210 dns_rdataset_current(&rdataset
, &rdata
);
2211 result
= dns_rdata_tostruct(&rdata
, &mx
, NULL
);
2212 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2213 if (!zone_check_mx(zone
, db
, &mx
.mx
, name
))
2215 dns_rdata_reset(&rdata
);
2216 result
= dns_rdataset_next(&rdataset
);
2218 dns_rdataset_disassociate(&rdataset
);
2221 if (zone
->rdclass
!= dns_rdataclass_in
)
2223 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_srv
,
2224 0, 0, &rdataset
, NULL
);
2225 if (result
!= ISC_R_SUCCESS
)
2227 result
= dns_rdataset_first(&rdataset
);
2228 while (result
== ISC_R_SUCCESS
) {
2229 dns_rdataset_current(&rdataset
, &rdata
);
2230 result
= dns_rdata_tostruct(&rdata
, &srv
, NULL
);
2231 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2232 if (!zone_check_srv(zone
, db
, &srv
.target
, name
))
2234 dns_rdata_reset(&rdata
);
2235 result
= dns_rdataset_next(&rdataset
);
2237 dns_rdataset_disassociate(&rdataset
);
2240 dns_db_detachnode(db
, &node
);
2241 result
= dns_dbiterator_next(dbiterator
);
2246 dns_db_detachnode(db
, &node
);
2247 dns_dbiterator_destroy(&dbiterator
);
2253 * OpenSSL verification of RSA keys with exponent 3 is known to be
2254 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2255 * if they are in use.
2258 zone_check_dnskeys(dns_zone_t
*zone
, dns_db_t
*db
) {
2259 dns_dbnode_t
*node
= NULL
;
2260 dns_dbversion_t
*version
= NULL
;
2261 dns_rdata_dnskey_t dnskey
;
2262 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2263 dns_rdataset_t rdataset
;
2264 isc_result_t result
;
2265 isc_boolean_t logit
, foundrsa
= ISC_FALSE
, foundmd5
= ISC_FALSE
;
2266 const char *algorithm
;
2268 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
2269 if (result
!= ISC_R_SUCCESS
)
2272 dns_db_currentversion(db
, &version
);
2273 dns_rdataset_init(&rdataset
);
2274 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_dnskey
,
2275 dns_rdatatype_none
, 0, &rdataset
, NULL
);
2276 if (result
!= ISC_R_SUCCESS
)
2279 for (result
= dns_rdataset_first(&rdataset
);
2280 result
== ISC_R_SUCCESS
;
2281 result
= dns_rdataset_next(&rdataset
))
2283 dns_rdataset_current(&rdataset
, &rdata
);
2284 result
= dns_rdata_tostruct(&rdata
, &dnskey
, NULL
);
2285 INSIST(result
== ISC_R_SUCCESS
);
2287 if ((dnskey
.algorithm
== DST_ALG_RSASHA1
||
2288 dnskey
.algorithm
== DST_ALG_RSAMD5
) &&
2289 dnskey
.datalen
> 1 && dnskey
.data
[0] == 1 &&
2290 dnskey
.data
[1] == 3)
2292 if (dnskey
.algorithm
== DST_ALG_RSASHA1
) {
2294 foundrsa
= ISC_TRUE
;
2295 algorithm
= "RSASHA1";
2298 foundmd5
= ISC_TRUE
;
2299 algorithm
= "RSAMD5";
2302 dns_zone_log(zone
, ISC_LOG_WARNING
,
2303 "weak %s (%u) key found "
2304 "(exponent=3)", algorithm
,
2306 if (foundrsa
&& foundmd5
)
2309 dns_rdata_reset(&rdata
);
2311 dns_rdataset_disassociate(&rdataset
);
2315 dns_db_detachnode(db
, &node
);
2316 if (version
!= NULL
)
2317 dns_db_closeversion(db
, &version
, ISC_FALSE
);
2321 resume_signingwithkey(dns_zone_t
*zone
) {
2322 dns_dbnode_t
*node
= NULL
;
2323 dns_dbversion_t
*version
= NULL
;
2324 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2325 dns_rdataset_t rdataset
;
2326 isc_result_t result
;
2328 result
= dns_db_findnode(zone
->db
, &zone
->origin
, ISC_FALSE
, &node
);
2329 if (result
!= ISC_R_SUCCESS
)
2332 dns_db_currentversion(zone
->db
, &version
);
2333 dns_rdataset_init(&rdataset
);
2334 result
= dns_db_findrdataset(zone
->db
, node
, version
,
2336 dns_rdatatype_none
, 0,
2338 if (result
!= ISC_R_SUCCESS
) {
2339 INSIST(!dns_rdataset_isassociated(&rdataset
));
2343 for (result
= dns_rdataset_first(&rdataset
);
2344 result
== ISC_R_SUCCESS
;
2345 result
= dns_rdataset_next(&rdataset
))
2347 dns_rdataset_current(&rdataset
, &rdata
);
2348 if (rdata
.length
!= 5 ||
2349 rdata
.data
[0] == 0 || rdata
.data
[4] != 0) {
2350 dns_rdata_reset(&rdata
);
2354 result
= zone_signwithkey(zone
, rdata
.data
[0],
2355 (rdata
.data
[1] << 8) | rdata
.data
[2],
2356 ISC_TF(rdata
.data
[3]));
2357 if (result
!= ISC_R_SUCCESS
) {
2358 dns_zone_log(zone
, ISC_LOG_ERROR
,
2359 "zone_signwithkey failed: %s",
2360 dns_result_totext(result
));
2362 dns_rdata_reset(&rdata
);
2364 dns_rdataset_disassociate(&rdataset
);
2368 dns_db_detachnode(zone
->db
, &node
);
2369 if (version
!= NULL
)
2370 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
2374 zone_addnsec3chain(dns_zone_t
*zone
, dns_rdata_nsec3param_t
*nsec3param
) {
2375 dns_nsec3chain_t
*nsec3chain
, *current
;
2376 isc_result_t result
;
2378 unsigned int options
= 0;
2379 char saltbuf
[255*2+1];
2380 char flags
[sizeof("REMOVE|CREATE|NONSEC|OPTOUT")];
2383 nsec3chain
= isc_mem_get(zone
->mctx
, sizeof *nsec3chain
);
2384 if (nsec3chain
== NULL
)
2385 return (ISC_R_NOMEMORY
);
2387 nsec3chain
->magic
= 0;
2388 nsec3chain
->done
= ISC_FALSE
;
2389 nsec3chain
->db
= NULL
;
2390 nsec3chain
->dbiterator
= NULL
;
2391 nsec3chain
->nsec3param
.common
.rdclass
= nsec3param
->common
.rdclass
;
2392 nsec3chain
->nsec3param
.common
.rdtype
= nsec3param
->common
.rdtype
;
2393 nsec3chain
->nsec3param
.hash
= nsec3param
->hash
;
2394 nsec3chain
->nsec3param
.iterations
= nsec3param
->iterations
;
2395 nsec3chain
->nsec3param
.flags
= nsec3param
->flags
;
2396 nsec3chain
->nsec3param
.salt_length
= nsec3param
->salt_length
;
2397 memcpy(nsec3chain
->salt
, nsec3param
->salt
, nsec3param
->salt_length
);
2398 nsec3chain
->nsec3param
.salt
= nsec3chain
->salt
;
2399 nsec3chain
->seen_nsec
= ISC_FALSE
;
2400 nsec3chain
->delete_nsec
= ISC_FALSE
;
2401 nsec3chain
->save_delete_nsec
= ISC_FALSE
;
2403 if (nsec3param
->flags
== 0)
2404 strlcpy(flags
, "NONE", sizeof(flags
));
2407 if (nsec3param
->flags
& DNS_NSEC3FLAG_REMOVE
)
2408 strlcat(flags
, "REMOVE", sizeof(flags
));
2409 if (nsec3param
->flags
& DNS_NSEC3FLAG_CREATE
) {
2410 if (flags
[0] == '\0')
2411 strlcpy(flags
, "CREATE", sizeof(flags
));
2413 strlcat(flags
, "|CREATE", sizeof(flags
));
2415 if (nsec3param
->flags
& DNS_NSEC3FLAG_NONSEC
) {
2416 if (flags
[0] == '\0')
2417 strlcpy(flags
, "NONSEC", sizeof(flags
));
2419 strlcat(flags
, "|NONSEC", sizeof(flags
));
2421 if (nsec3param
->flags
& DNS_NSEC3FLAG_OPTOUT
) {
2422 if (flags
[0] == '\0')
2423 strlcpy(flags
, "OPTOUT", sizeof(flags
));
2425 strlcat(flags
, "|OPTOUT", sizeof(flags
));
2428 if (nsec3param
->salt_length
== 0)
2429 strlcpy(saltbuf
, "-", sizeof(saltbuf
));
2431 for (i
= 0; i
< nsec3param
->salt_length
; i
++)
2432 sprintf(&saltbuf
[i
*2], "%02X", nsec3chain
->salt
[i
]);
2433 dns_zone_log(zone
, ISC_LOG_INFO
,
2434 "zone_addnsec3chain(%u,%s,%u,%s)",
2435 nsec3param
->hash
, flags
, nsec3param
->iterations
,
2437 for (current
= ISC_LIST_HEAD(zone
->nsec3chain
);
2439 current
= ISC_LIST_NEXT(current
, link
)) {
2440 if (current
->db
== zone
->db
&&
2441 current
->nsec3param
.hash
== nsec3param
->hash
&&
2442 current
->nsec3param
.iterations
== nsec3param
->iterations
&&
2443 current
->nsec3param
.salt_length
== nsec3param
->salt_length
2444 && !memcmp(current
->nsec3param
.salt
, nsec3param
->salt
,
2445 nsec3param
->salt_length
))
2446 current
->done
= ISC_TRUE
;
2449 if (zone
->db
!= NULL
) {
2450 dns_db_attach(zone
->db
, &nsec3chain
->db
);
2451 if ((nsec3chain
->nsec3param
.flags
& DNS_NSEC3FLAG_CREATE
) != 0)
2452 options
= DNS_DB_NONSEC3
;
2453 result
= dns_db_createiterator(nsec3chain
->db
, options
,
2454 &nsec3chain
->dbiterator
);
2455 if (result
== ISC_R_SUCCESS
)
2456 dns_dbiterator_first(nsec3chain
->dbiterator
);
2457 if (result
== ISC_R_SUCCESS
) {
2458 dns_dbiterator_pause(nsec3chain
->dbiterator
);
2459 ISC_LIST_INITANDAPPEND(zone
->nsec3chain
,
2462 if (isc_time_isepoch(&zone
->nsec3chaintime
)) {
2464 zone
->nsec3chaintime
= now
;
2465 if (zone
->task
!= NULL
)
2466 zone_settimer(zone
, &now
);
2470 result
= ISC_R_NOTFOUND
;
2472 if (nsec3chain
!= NULL
) {
2473 if (nsec3chain
->db
!= NULL
)
2474 dns_db_detach(&nsec3chain
->db
);
2475 if (nsec3chain
->dbiterator
!= NULL
)
2476 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
2477 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
2483 resume_addnsec3chain(dns_zone_t
*zone
) {
2484 dns_dbnode_t
*node
= NULL
;
2485 dns_dbversion_t
*version
= NULL
;
2486 dns_rdataset_t rdataset
;
2487 isc_result_t result
;
2488 dns_rdata_nsec3param_t nsec3param
;
2490 if (zone
->privatetype
== 0)
2493 result
= dns_db_findnode(zone
->db
, &zone
->origin
, ISC_FALSE
, &node
);
2494 if (result
!= ISC_R_SUCCESS
)
2497 dns_db_currentversion(zone
->db
, &version
);
2498 dns_rdataset_init(&rdataset
);
2499 result
= dns_db_findrdataset(zone
->db
, node
, version
,
2500 zone
->privatetype
, dns_rdatatype_none
,
2501 0, &rdataset
, NULL
);
2502 if (result
!= ISC_R_SUCCESS
) {
2503 INSIST(!dns_rdataset_isassociated(&rdataset
));
2507 for (result
= dns_rdataset_first(&rdataset
);
2508 result
== ISC_R_SUCCESS
;
2509 result
= dns_rdataset_next(&rdataset
))
2511 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
2512 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2513 dns_rdata_t
private = DNS_RDATA_INIT
;
2515 dns_rdataset_current(&rdataset
, &private);
2516 if (!dns_nsec3param_fromprivate(&private, &rdata
, buf
,
2519 result
= dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
);
2520 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2521 if ((nsec3param
.flags
& DNS_NSEC3FLAG_CREATE
) != 0 ||
2522 (nsec3param
.flags
& DNS_NSEC3FLAG_REMOVE
) != 0) {
2523 result
= zone_addnsec3chain(zone
, &nsec3param
);
2524 if (result
!= ISC_R_SUCCESS
) {
2525 dns_zone_log(zone
, ISC_LOG_ERROR
,
2526 "zone_addnsec3chain failed: %s",
2527 dns_result_totext(result
));
2531 dns_rdataset_disassociate(&rdataset
);
2534 dns_db_detachnode(zone
->db
, &node
);
2535 if (version
!= NULL
)
2536 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
2540 set_resigntime(dns_zone_t
*zone
) {
2541 dns_rdataset_t rdataset
;
2542 dns_fixedname_t fixed
;
2543 unsigned int resign
;
2544 isc_result_t result
;
2545 isc_uint32_t nanosecs
;
2547 dns_rdataset_init(&rdataset
);
2548 dns_fixedname_init(&fixed
);
2549 result
= dns_db_getsigningtime(zone
->db
, &rdataset
,
2550 dns_fixedname_name(&fixed
));
2551 if (result
!= ISC_R_SUCCESS
) {
2552 isc_time_settoepoch(&zone
->resigntime
);
2555 resign
= rdataset
.resign
;
2556 dns_rdataset_disassociate(&rdataset
);
2557 isc_random_get(&nanosecs
);
2558 nanosecs
%= 1000000000;
2559 isc_time_set(&zone
->resigntime
, resign
, nanosecs
);
2563 check_nsec3param(dns_zone_t
*zone
, dns_db_t
*db
) {
2564 dns_dbnode_t
*node
= NULL
;
2565 dns_rdataset_t rdataset
;
2566 dns_dbversion_t
*version
= NULL
;
2567 dns_rdata_nsec3param_t nsec3param
;
2568 isc_boolean_t ok
= ISC_FALSE
;
2569 isc_result_t result
;
2570 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2571 isc_boolean_t dynamic
= (zone
->type
== dns_zone_master
) ?
2572 zone_isdynamic(zone
) : ISC_FALSE
;
2574 dns_rdataset_init(&rdataset
);
2575 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
2576 if (result
!= ISC_R_SUCCESS
) {
2577 dns_zone_log(zone
, ISC_LOG_ERROR
,
2578 "nsec3param lookup failure: %s",
2579 dns_result_totext(result
));
2582 dns_db_currentversion(db
, &version
);
2584 result
= dns_db_findrdataset(db
, node
, version
,
2585 dns_rdatatype_nsec3param
,
2586 dns_rdatatype_none
, 0, &rdataset
, NULL
);
2587 if (result
== ISC_R_NOTFOUND
) {
2588 INSIST(!dns_rdataset_isassociated(&rdataset
));
2589 result
= ISC_R_SUCCESS
;
2592 if (result
!= ISC_R_SUCCESS
) {
2593 INSIST(!dns_rdataset_isassociated(&rdataset
));
2594 dns_zone_log(zone
, ISC_LOG_ERROR
,
2595 "nsec3param lookup failure: %s",
2596 dns_result_totext(result
));
2601 * For dynamic zones we must support every algorithm so we can
2602 * regenerate all the NSEC3 chains.
2603 * For non-dynamic zones we only need to find a supported algorithm.
2605 for (result
= dns_rdataset_first(&rdataset
);
2606 result
== ISC_R_SUCCESS
;
2607 result
= dns_rdataset_next(&rdataset
))
2609 dns_rdataset_current(&rdataset
, &rdata
);
2610 result
= dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
);
2611 dns_rdata_reset(&rdata
);
2612 INSIST(result
== ISC_R_SUCCESS
);
2613 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NSEC3TESTZONE
) &&
2614 nsec3param
.hash
== DNS_NSEC3_UNKNOWNALG
&& !dynamic
)
2616 dns_zone_log(zone
, ISC_LOG_WARNING
,
2617 "nsec3 test \"unknown\" hash algorithm found: %u",
2620 } else if (!dns_nsec3_supportedhash(nsec3param
.hash
)) {
2622 dns_zone_log(zone
, ISC_LOG_ERROR
,
2623 "unsupported nsec3 hash algorithm"
2624 " in dynamic zone: %u",
2626 result
= DNS_R_BADZONE
;
2627 /* Stop second error message. */
2631 dns_zone_log(zone
, ISC_LOG_WARNING
,
2632 "unsupported nsec3 hash algorithm: %u",
2637 if (result
== ISC_R_NOMORE
)
2638 result
= ISC_R_SUCCESS
;
2641 result
= DNS_R_BADZONE
;
2642 dns_zone_log(zone
, ISC_LOG_ERROR
,
2643 "no supported nsec3 hash algorithm");
2647 if (dns_rdataset_isassociated(&rdataset
))
2648 dns_rdataset_disassociate(&rdataset
);
2649 dns_db_closeversion(db
, &version
, ISC_FALSE
);
2650 dns_db_detachnode(db
, &node
);
2655 * Set the timer for refreshing the key zone to the soonest future time
2656 * of the set (current timer, keydata->refresh, keydata->addhd,
2657 * keydata->removehd).
2660 set_refreshkeytimer(dns_zone_t
*zone
, dns_rdata_keydata_t
*key
,
2661 isc_stdtime_t now
) {
2662 const char me
[] = "set_refreshkeytimer";
2664 isc_time_t timenow
, timethen
;
2667 then
= key
->refresh
;
2668 if (key
->addhd
> now
&& key
->addhd
< then
)
2670 if (key
->removehd
> now
&& key
->removehd
< then
)
2671 then
= key
->removehd
;
2673 isc_time_set(&timenow
, now
, 0);
2674 isc_time_set(&timethen
, ISC_MAX(then
, now
), 0);
2675 if (isc_time_compare(&zone
->refreshkeytime
, &timenow
) < 0 ||
2676 isc_time_compare(&timethen
, &zone
->refreshkeytime
) < 0) {
2677 zone
->refreshkeytime
= timethen
;
2679 zone_settimer(zone
, &timenow
);
2683 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
2684 * If the key zone is changed, set '*changed' to ISC_TRUE.
2687 create_keydata(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
2688 dns_diff_t
*diff
, dns_keytable_t
*keytable
,
2689 dns_keynode_t
**keynodep
, isc_boolean_t
*changed
)
2691 const char me
[] = "create_keydata";
2692 isc_result_t result
= ISC_R_SUCCESS
;
2693 isc_buffer_t keyb
, dstb
;
2694 unsigned char key_buf
[4096], dst_buf
[DST_KEY_MAXSIZE
];
2695 dns_rdata_keydata_t keydata
;
2696 dns_rdata_dnskey_t dnskey
;
2697 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2698 dns_keynode_t
*keynode
;
2703 REQUIRE(keynodep
!= NULL
);
2704 keynode
= *keynodep
;
2707 isc_stdtime_get(&now
);
2709 /* Loop in case there's more than one key. */
2710 while (result
== ISC_R_SUCCESS
) {
2711 dns_keynode_t
*nextnode
= NULL
;
2713 key
= dns_keynode_key(keynode
);
2717 isc_buffer_init(&dstb
, dst_buf
, sizeof(dst_buf
));
2718 CHECK(dst_key_todns(key
, &dstb
));
2720 /* Convert DST key to DNSKEY. */
2721 dns_rdata_reset(&rdata
);
2722 isc_buffer_usedregion(&dstb
, &r
);
2723 dns_rdata_fromregion(&rdata
, dst_key_class(key
),
2724 dns_rdatatype_dnskey
, &r
);
2726 /* DSTKEY to KEYDATA. */
2727 CHECK(dns_rdata_tostruct(&rdata
, &dnskey
, NULL
));
2728 CHECK(dns_keydata_fromdnskey(&keydata
, &dnskey
, now
, 0, 0,
2731 /* KEYDATA to rdata. */
2732 dns_rdata_reset(&rdata
);
2733 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
2734 CHECK(dns_rdata_fromstruct(&rdata
,
2735 zone
->rdclass
, dns_rdatatype_keydata
,
2738 /* Add rdata to zone. */
2739 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_ADD
,
2740 dst_key_name(key
), 0, &rdata
));
2741 *changed
= ISC_TRUE
;
2744 result
= dns_keytable_nextkeynode(keytable
, keynode
, &nextnode
);
2745 if (result
!= ISC_R_NOTFOUND
) {
2746 dns_keytable_detachkeynode(keytable
, &keynode
);
2751 /* Refresh new keys from the zone apex as soon as possible. */
2753 set_refreshkeytimer(zone
, &keydata
, now
);
2755 if (keynode
!= NULL
)
2756 dns_keytable_detachkeynode(keytable
, &keynode
);
2759 return (ISC_R_SUCCESS
);
2766 * Remove from the key zone all the KEYDATA records found in rdataset.
2769 delete_keydata(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_diff_t
*diff
,
2770 dns_name_t
*name
, dns_rdataset_t
*rdataset
)
2772 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2773 isc_result_t result
, uresult
;
2775 for (result
= dns_rdataset_first(rdataset
);
2776 result
== ISC_R_SUCCESS
;
2777 result
= dns_rdataset_next(rdataset
)) {
2778 dns_rdata_reset(&rdata
);
2779 dns_rdataset_current(rdataset
, &rdata
);
2780 uresult
= update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
,
2782 if (uresult
!= ISC_R_SUCCESS
)
2785 if (result
== ISC_R_NOMORE
)
2786 result
= ISC_R_SUCCESS
;
2791 * Compute the DNSSEC key ID for a DNSKEY record.
2794 compute_tag(dns_name_t
*name
, dns_rdata_dnskey_t
*dnskey
, isc_mem_t
*mctx
,
2797 isc_result_t result
;
2798 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2799 unsigned char data
[4096];
2800 isc_buffer_t buffer
;
2801 dst_key_t
*dstkey
= NULL
;
2803 isc_buffer_init(&buffer
, data
, sizeof(data
));
2804 dns_rdata_fromstruct(&rdata
, dnskey
->common
.rdclass
,
2805 dns_rdatatype_dnskey
, dnskey
, &buffer
);
2807 result
= dns_dnssec_keyfromrdata(name
, &rdata
, mctx
, &dstkey
);
2808 if (result
== ISC_R_SUCCESS
)
2809 *tag
= dst_key_id(dstkey
);
2810 dst_key_free(&dstkey
);
2816 * Add key to the security roots for all views.
2819 trust_key(dns_viewlist_t
*viewlist
, dns_name_t
*keyname
,
2820 dns_rdata_dnskey_t
*dnskey
, isc_mem_t
*mctx
) {
2821 isc_result_t result
;
2822 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2823 unsigned char data
[4096];
2824 isc_buffer_t buffer
;
2826 dns_keytable_t
*sr
= NULL
;
2828 /* Convert dnskey to DST key. */
2829 isc_buffer_init(&buffer
, data
, sizeof(data
));
2830 dns_rdata_fromstruct(&rdata
, dnskey
->common
.rdclass
,
2831 dns_rdatatype_dnskey
, dnskey
, &buffer
);
2833 for (view
= ISC_LIST_HEAD(*viewlist
); view
!= NULL
;
2834 view
= ISC_LIST_NEXT(view
, link
)) {
2835 dst_key_t
*key
= NULL
;
2837 result
= dns_view_getsecroots(view
, &sr
);
2838 if (result
!= ISC_R_SUCCESS
)
2841 CHECK(dns_dnssec_keyfromrdata(keyname
, &rdata
, mctx
, &key
));
2842 CHECK(dns_keytable_add(sr
, ISC_TRUE
, &key
));
2843 dns_keytable_detach(&sr
);
2848 dns_keytable_detach(&sr
);
2853 * Remove key from the security roots for all views.
2856 untrust_key(dns_viewlist_t
*viewlist
, dns_name_t
*keyname
, isc_mem_t
*mctx
,
2857 dns_rdata_dnskey_t
*dnskey
)
2859 isc_result_t result
;
2860 unsigned char data
[4096];
2861 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2862 isc_buffer_t buffer
;
2864 dst_key_t
*key
= NULL
;
2867 * Clear the revoke bit, if set, so that the key will match what's
2870 dnskey
->flags
&= ~DNS_KEYFLAG_REVOKE
;
2872 /* Convert dnskey to DST key. */
2873 isc_buffer_init(&buffer
, data
, sizeof(data
));
2874 dns_rdata_fromstruct(&rdata
, dnskey
->common
.rdclass
,
2875 dns_rdatatype_dnskey
, dnskey
, &buffer
);
2876 result
= dns_dnssec_keyfromrdata(keyname
, &rdata
, mctx
, &key
);
2877 if (result
!= ISC_R_SUCCESS
)
2880 for (view
= ISC_LIST_HEAD(*viewlist
); view
!= NULL
;
2881 view
= ISC_LIST_NEXT(view
, link
)) {
2882 dns_keytable_t
*sr
= NULL
;
2883 result
= dns_view_getsecroots(view
, &sr
);
2884 if (result
!= ISC_R_SUCCESS
)
2887 dns_keytable_deletekeynode(sr
, key
);
2888 dns_keytable_detach(&sr
);
2895 * Add a null key to the security roots for all views, so that all queries
2896 * to the zone will fail.
2899 fail_secure(dns_viewlist_t
*viewlist
, dns_name_t
*keyname
) {
2900 isc_result_t result
;
2903 for (view
= ISC_LIST_HEAD(*viewlist
);
2905 view
= ISC_LIST_NEXT(view
, link
)) {
2906 dns_keytable_t
*sr
= NULL
;
2908 result
= dns_view_getsecroots(view
, &sr
);
2909 if (result
!= ISC_R_SUCCESS
)
2912 dns_keytable_marksecure(sr
, keyname
);
2913 dns_keytable_detach(&sr
);
2918 * Scan a set of KEYDATA records from the key zone. The ones that are
2919 * valid (i.e., the add holddown timer has expired) become trusted keys for
2923 load_secroots(dns_zone_t
*zone
, dns_name_t
*name
, dns_rdataset_t
*rdataset
) {
2924 isc_result_t result
;
2925 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2926 dns_rdata_keydata_t keydata
;
2927 dns_rdata_dnskey_t dnskey
;
2928 isc_mem_t
*mctx
= zone
->mctx
;
2929 dns_view_t
*view
= zone
->view
;
2930 dns_viewlist_t
*viewlist
= view
->viewlist
;
2931 int trusted
= 0, revoked
= 0, pending
= 0;
2934 isc_stdtime_get(&now
);
2936 /* For each view, delete references to this key from secroots. */
2937 for (view
= ISC_LIST_HEAD(*viewlist
); view
!= NULL
;
2938 view
= ISC_LIST_NEXT(view
, link
)) {
2939 dns_keytable_t
*sr
= NULL
;
2941 result
= dns_view_getsecroots(view
, &sr
);
2942 if (result
!= ISC_R_SUCCESS
)
2945 dns_keytable_delete(sr
, name
);
2946 dns_keytable_detach(&sr
);
2949 /* Now insert all the accepted trust anchors from this keydata set. */
2950 for (result
= dns_rdataset_first(rdataset
);
2951 result
== ISC_R_SUCCESS
;
2952 result
= dns_rdataset_next(rdataset
)) {
2953 dns_rdata_reset(&rdata
);
2954 dns_rdataset_current(rdataset
, &rdata
);
2956 /* Convert rdata to keydata. */
2957 dns_rdata_tostruct(&rdata
, &keydata
, NULL
);
2959 /* Set the key refresh timer. */
2960 set_refreshkeytimer(zone
, &keydata
, now
);
2962 /* If the removal timer is nonzero, this key was revoked. */
2963 if (keydata
.removehd
!= 0) {
2969 * If the add timer is still pending, this key is not
2972 if (now
< keydata
.addhd
) {
2977 /* Convert keydata to dnskey. */
2978 dns_keydata_todnskey(&keydata
, &dnskey
, NULL
);
2980 /* Add to keytables. */
2982 trust_key(viewlist
, name
, &dnskey
, mctx
);
2985 if (trusted
== 0 && pending
!= 0) {
2986 char namebuf
[DNS_NAME_FORMATSIZE
];
2987 dns_name_format(name
, namebuf
, sizeof namebuf
);
2988 dns_zone_log(zone
, ISC_LOG_ERROR
,
2989 "No valid trust anchors for '%s'!", namebuf
);
2990 dns_zone_log(zone
, ISC_LOG_ERROR
,
2991 "%d key(s) revoked, %d still pending",
2993 dns_zone_log(zone
, ISC_LOG_ERROR
,
2994 "All queries to '%s' will fail", namebuf
);
2995 fail_secure(viewlist
, name
);
3000 do_one_tuple(dns_difftuple_t
**tuple
, dns_db_t
*db
, dns_dbversion_t
*ver
,
3003 dns_diff_t temp_diff
;
3004 isc_result_t result
;
3007 * Create a singleton diff.
3009 dns_diff_init(diff
->mctx
, &temp_diff
);
3010 temp_diff
.resign
= diff
->resign
;
3011 ISC_LIST_APPEND(temp_diff
.tuples
, *tuple
, link
);
3014 * Apply it to the database.
3016 result
= dns_diff_apply(&temp_diff
, db
, ver
);
3017 ISC_LIST_UNLINK(temp_diff
.tuples
, *tuple
, link
);
3018 if (result
!= ISC_R_SUCCESS
) {
3019 dns_difftuple_free(tuple
);
3024 * Merge it into the current pending journal entry.
3026 dns_diff_appendminimal(diff
, tuple
);
3029 * Do not clear temp_diff.
3031 return (ISC_R_SUCCESS
);
3035 update_one_rr(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_diff_t
*diff
,
3036 dns_diffop_t op
, dns_name_t
*name
, dns_ttl_t ttl
,
3039 dns_difftuple_t
*tuple
= NULL
;
3040 isc_result_t result
;
3041 result
= dns_difftuple_create(diff
->mctx
, op
,
3042 name
, ttl
, rdata
, &tuple
);
3043 if (result
!= ISC_R_SUCCESS
)
3045 return (do_one_tuple(&tuple
, db
, ver
, diff
));
3049 increment_soa_serial(dns_db_t
*db
, dns_dbversion_t
*ver
,
3050 dns_diff_t
*diff
, isc_mem_t
*mctx
) {
3051 dns_difftuple_t
*deltuple
= NULL
;
3052 dns_difftuple_t
*addtuple
= NULL
;
3053 isc_uint32_t serial
;
3054 isc_result_t result
;
3056 CHECK(dns_db_createsoatuple(db
, ver
, mctx
, DNS_DIFFOP_DEL
, &deltuple
));
3057 CHECK(dns_difftuple_copy(deltuple
, &addtuple
));
3058 addtuple
->op
= DNS_DIFFOP_ADD
;
3060 serial
= dns_soa_getserial(&addtuple
->rdata
);
3063 serial
= (serial
+ 1) & 0xFFFFFFFF;
3067 dns_soa_setserial(serial
, &addtuple
->rdata
);
3068 CHECK(do_one_tuple(&deltuple
, db
, ver
, diff
));
3069 CHECK(do_one_tuple(&addtuple
, db
, ver
, diff
));
3070 result
= ISC_R_SUCCESS
;
3073 if (addtuple
!= NULL
)
3074 dns_difftuple_free(&addtuple
);
3075 if (deltuple
!= NULL
)
3076 dns_difftuple_free(&deltuple
);
3081 * Write all transactions in 'diff' to the zone journal file.
3084 zone_journal(dns_zone_t
*zone
, dns_diff_t
*diff
, const char *caller
) {
3085 const char me
[] = "zone_journal";
3086 const char *journalfile
;
3087 isc_result_t result
;
3088 dns_journal_t
*journal
= NULL
;
3091 journalfile
= dns_zone_getjournal(zone
);
3092 if (journalfile
!= NULL
) {
3093 result
= dns_journal_open(zone
->mctx
, journalfile
,
3094 ISC_TRUE
, &journal
);
3095 if (result
!= ISC_R_SUCCESS
) {
3096 dns_zone_log(zone
, ISC_LOG_ERROR
,
3097 "%s:dns_journal_open -> %s\n",
3098 caller
, dns_result_totext(result
));
3102 result
= dns_journal_write_transaction(journal
, diff
);
3103 dns_journal_destroy(&journal
);
3104 if (result
!= ISC_R_SUCCESS
) {
3105 dns_zone_log(zone
, ISC_LOG_ERROR
,
3106 "%s:dns_journal_write_transaction -> %s\n",
3107 caller
, dns_result_totext(result
));
3114 * Create an SOA record for a newly-created zone
3117 add_soa(dns_zone_t
*zone
, dns_db_t
*db
) {
3118 isc_result_t result
;
3119 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3120 unsigned char buf
[DNS_SOA_BUFFERSIZE
];
3121 dns_dbversion_t
*ver
= NULL
;
3124 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "creating SOA");
3126 dns_diff_init(zone
->mctx
, &diff
);
3127 result
= dns_db_newversion(db
, &ver
);
3128 if (result
!= ISC_R_SUCCESS
) {
3129 dns_zone_log(zone
, ISC_LOG_ERROR
,
3130 "add_soa:dns_db_newversion -> %s\n",
3131 dns_result_totext(result
));
3135 /* Build SOA record */
3136 result
= dns_soa_buildrdata(&zone
->origin
, dns_rootname
, zone
->rdclass
,
3137 0, 0, 0, 0, 0, buf
, &rdata
);
3138 if (result
!= ISC_R_SUCCESS
) {
3139 dns_zone_log(zone
, ISC_LOG_ERROR
,
3140 "add_soa:dns_soa_buildrdata -> %s\n",
3141 dns_result_totext(result
));
3145 result
= update_one_rr(db
, ver
, &diff
, DNS_DIFFOP_ADD
,
3146 &zone
->origin
, 0, &rdata
);
3149 dns_diff_clear(&diff
);
3151 dns_db_closeversion(db
, &ver
, ISC_TF(result
== ISC_R_SUCCESS
));
3157 * Synchronize the set of initializing keys found in managed-keys {}
3158 * statements with the set of trust anchors found in the managed-keys.bind
3159 * zone. If a domain is no longer named in managed-keys, delete all keys
3160 * from that domain from the key zone. If a domain is mentioned in in
3161 * managed-keys but there are no references to it in the key zone, load
3162 * the key zone with the initializing key(s) for that domain.
3165 sync_keyzone(dns_zone_t
*zone
, dns_db_t
*db
) {
3166 isc_result_t result
= ISC_R_SUCCESS
;
3167 isc_boolean_t changed
= ISC_FALSE
;
3168 dns_rbtnodechain_t chain
;
3170 dns_name_t foundname
, *origin
;
3171 dns_keynode_t
*keynode
= NULL
;
3172 dns_view_t
*view
= zone
->view
;
3173 dns_keytable_t
*sr
= NULL
;
3174 dns_dbversion_t
*ver
= NULL
;
3176 dns_rriterator_t rrit
;
3178 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3180 dns_name_init(&foundname
, NULL
);
3181 dns_fixedname_init(&fn
);
3182 origin
= dns_fixedname_name(&fn
);
3184 dns_diff_init(zone
->mctx
, &diff
);
3186 CHECK(dns_view_getsecroots(view
, &sr
));
3188 result
= dns_db_newversion(db
, &ver
);
3189 if (result
!= ISC_R_SUCCESS
) {
3190 dns_zone_log(zone
, ISC_LOG_ERROR
,
3191 "sync_keyzone:dns_db_newversion -> %s\n",
3192 dns_result_totext(result
));
3197 * Walk the zone DB. If we find any keys whose names are no longer
3198 * in managed-keys (or *are* in trusted-keys, meaning they are
3199 * permanent and not RFC5011-maintained), delete them from the
3200 * zone. Otherwise call load_secroots(), which loads keys into
3201 * secroots as appropriate.
3203 dns_rriterator_init(&rrit
, db
, ver
, 0);
3204 for (result
= dns_rriterator_first(&rrit
);
3205 result
== ISC_R_SUCCESS
;
3206 result
= dns_rriterator_nextrrset(&rrit
)) {
3207 dns_rdataset_t
*rdataset
;
3208 dns_name_t
*rrname
= NULL
;
3211 dns_rriterator_current(&rrit
, &rrname
, &ttl
,
3213 if (!dns_rdataset_isassociated(rdataset
)) {
3214 dns_rriterator_destroy(&rrit
);
3218 if (rdataset
->type
!= dns_rdatatype_keydata
)
3221 result
= dns_keytable_find(sr
, rrname
, &keynode
);
3222 if ((result
!= ISC_R_SUCCESS
&&
3223 result
!= DNS_R_PARTIALMATCH
) ||
3224 dns_keynode_managed(keynode
) == ISC_FALSE
) {
3225 CHECK(delete_keydata(db
, ver
, &diff
,
3229 load_secroots(zone
, rrname
, rdataset
);
3232 if (keynode
!= NULL
)
3233 dns_keytable_detachkeynode(sr
, &keynode
);
3235 dns_rriterator_destroy(&rrit
);
3238 * Now walk secroots to find any managed keys that aren't
3239 * in the zone. If we find any, we add them to the zone.
3241 RWLOCK(&sr
->rwlock
, isc_rwlocktype_write
);
3242 dns_rbtnodechain_init(&chain
, zone
->mctx
);
3243 result
= dns_rbtnodechain_first(&chain
, sr
->table
, &foundname
, origin
);
3244 if (result
== ISC_R_NOTFOUND
)
3245 result
= ISC_R_NOMORE
;
3246 while (result
== DNS_R_NEWORIGIN
|| result
== ISC_R_SUCCESS
) {
3247 dns_rbtnode_t
*rbtnode
= NULL
;
3249 dns_rbtnodechain_current(&chain
, &foundname
, origin
, &rbtnode
);
3250 if (rbtnode
->data
== NULL
)
3253 dns_keytable_attachkeynode(sr
, rbtnode
->data
, &keynode
);
3254 if (dns_keynode_managed(keynode
)) {
3255 dns_fixedname_t fname
;
3256 dns_name_t
*keyname
;
3258 key
= dns_keynode_key(keynode
);
3259 dns_fixedname_init(&fname
);
3261 if (key
== NULL
) /* fail_secure() was called. */
3264 keyname
= dst_key_name(key
);
3265 result
= dns_db_find(db
, keyname
, ver
,
3266 dns_rdatatype_keydata
,
3267 DNS_DBFIND_NOWILD
, 0, NULL
,
3268 dns_fixedname_name(&fname
),
3270 if (result
!= ISC_R_SUCCESS
)
3271 result
= create_keydata(zone
, db
, ver
, &diff
,
3272 sr
, &keynode
, &changed
);
3273 if (result
!= ISC_R_SUCCESS
)
3277 result
= dns_rbtnodechain_next(&chain
, &foundname
, origin
);
3278 if (keynode
!= NULL
)
3279 dns_keytable_detachkeynode(sr
, &keynode
);
3281 RWUNLOCK(&sr
->rwlock
, isc_rwlocktype_write
);
3283 if (result
== ISC_R_NOMORE
)
3284 result
= ISC_R_SUCCESS
;
3287 /* Write changes to journal file. */
3288 result
= increment_soa_serial(db
, ver
, &diff
, zone
->mctx
);
3289 if (result
== ISC_R_SUCCESS
)
3290 zone_journal(zone
, &diff
, "sync_keyzone");
3292 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
);
3293 zone_needdump(zone
, 30);
3297 if (keynode
!= NULL
)
3298 dns_keytable_detachkeynode(sr
, &keynode
);
3300 dns_keytable_detach(&sr
);
3302 dns_db_closeversion(db
, &ver
, changed
);
3303 dns_diff_clear(&diff
);
3309 zone_postload(dns_zone_t
*zone
, dns_db_t
*db
, isc_time_t loadtime
,
3310 isc_result_t result
)
3312 unsigned int soacount
= 0;
3313 unsigned int nscount
= 0;
3314 unsigned int errors
= 0;
3315 isc_uint32_t serial
, oldserial
, refresh
, retry
, expire
, minimum
;
3317 isc_boolean_t needdump
= ISC_FALSE
;
3318 isc_boolean_t hasinclude
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
3319 isc_boolean_t nomaster
= ISC_FALSE
;
3320 unsigned int options
;
3325 * Initiate zone transfer? We may need a error code that
3326 * indicates that the "permanent" form does not exist.
3327 * XXX better error feedback to log.
3329 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_SEENINCLUDE
) {
3330 if (zone
->type
== dns_zone_slave
||
3331 zone
->type
== dns_zone_stub
) {
3332 if (result
== ISC_R_FILENOTFOUND
)
3333 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
3335 else if (result
!= DNS_R_NOMASTERFILE
)
3336 dns_zone_log(zone
, ISC_LOG_ERROR
,
3337 "loading from master file %s "
3340 dns_result_totext(result
));
3342 dns_zone_log(zone
, ISC_LOG_ERROR
,
3343 "loading from master file %s failed: %s",
3345 dns_result_totext(result
));
3346 nomaster
= ISC_TRUE
;
3349 if (zone
->type
!= dns_zone_key
)
3353 dns_zone_log(zone
, ISC_LOG_DEBUG(2),
3354 "number of nodes in database: %u",
3355 dns_db_nodecount(db
));
3357 if (result
== DNS_R_SEENINCLUDE
)
3358 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
3360 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
3363 * If there's no master file for a key zone, then the zone is new:
3364 * create an SOA record. (We do this now, instead of later, so that
3365 * if there happens to be a journal file, we can roll forward from
3366 * a sane starting point.)
3368 if (nomaster
&& zone
->type
== dns_zone_key
) {
3369 result
= add_soa(zone
, db
);
3370 if (result
!= ISC_R_SUCCESS
)
3375 * Apply update log, if any, on initial load.
3377 if (zone
->journal
!= NULL
&&
3378 ! DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOMERGE
) &&
3379 ! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
3381 if (zone
->type
== dns_zone_master
&&
3382 (zone
->update_acl
!= NULL
|| zone
->ssutable
!= NULL
))
3383 options
= DNS_JOURNALOPT_RESIGN
;
3386 result
= dns_journal_rollforward2(zone
->mctx
, db
, options
,
3387 zone
->sigresigninginterval
,
3389 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
&&
3390 result
!= DNS_R_UPTODATE
&& result
!= DNS_R_NOJOURNAL
&&
3391 result
!= ISC_R_RANGE
) {
3392 dns_zone_log(zone
, ISC_LOG_ERROR
,
3393 "journal rollforward failed: %s",
3394 dns_result_totext(result
));
3397 if (result
== ISC_R_NOTFOUND
|| result
== ISC_R_RANGE
) {
3398 dns_zone_log(zone
, ISC_LOG_ERROR
,
3399 "journal rollforward failed: "
3400 "journal out of sync with zone");
3403 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
3404 "journal rollforward completed "
3406 dns_result_totext(result
));
3407 if (result
== ISC_R_SUCCESS
)
3408 needdump
= ISC_TRUE
;
3411 zone
->loadtime
= loadtime
;
3413 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "loaded");
3415 * Obtain ns, soa and cname counts for top of zone.
3418 result
= zone_get_from_db(zone
, db
, &nscount
, &soacount
, &serial
,
3419 &refresh
, &retry
, &expire
, &minimum
,
3421 if (result
!= ISC_R_SUCCESS
&& zone
->type
!= dns_zone_key
) {
3422 dns_zone_log(zone
, ISC_LOG_ERROR
,
3423 "could not find NS and/or SOA records");
3427 * Master / Slave / Stub zones require both NS and SOA records at
3428 * the top of the zone.
3431 switch (zone
->type
) {
3432 case dns_zone_master
:
3433 case dns_zone_slave
:
3435 if (soacount
!= 1) {
3436 dns_zone_log(zone
, ISC_LOG_ERROR
,
3437 "has %d SOA records", soacount
);
3438 result
= DNS_R_BADZONE
;
3441 dns_zone_log(zone
, ISC_LOG_ERROR
,
3442 "has no NS records");
3443 result
= DNS_R_BADZONE
;
3445 if (result
!= ISC_R_SUCCESS
)
3447 if (zone
->type
== dns_zone_master
&& errors
!= 0) {
3448 result
= DNS_R_BADZONE
;
3451 if (zone
->type
!= dns_zone_stub
) {
3452 result
= check_nsec3param(zone
, db
);
3453 if (result
!= ISC_R_SUCCESS
)
3456 if (zone
->type
== dns_zone_master
&&
3457 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKINTEGRITY
) &&
3458 !integrity_checks(zone
, db
)) {
3459 result
= DNS_R_BADZONE
;
3463 if (zone
->type
== dns_zone_master
&&
3464 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKDUPRR
) &&
3465 !zone_check_dup(zone
, db
)) {
3466 result
= DNS_R_BADZONE
;
3470 if (zone
->db
!= NULL
) {
3472 * This is checked in zone_replacedb() for slave zones
3473 * as they don't reload from disk.
3475 result
= zone_get_from_db(zone
, zone
->db
, NULL
, NULL
,
3476 &oldserial
, NULL
, NULL
, NULL
,
3478 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3479 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
) &&
3480 !isc_serial_gt(serial
, oldserial
)) {
3481 isc_uint32_t serialmin
, serialmax
;
3483 INSIST(zone
->type
== dns_zone_master
);
3485 serialmin
= (oldserial
+ 1) & 0xffffffffU
;
3486 serialmax
= (oldserial
+ 0x7fffffffU
) &
3488 dns_zone_log(zone
, ISC_LOG_ERROR
,
3489 "ixfr-from-differences: "
3490 "new serial (%u) out of range "
3491 "[%u - %u]", serial
, serialmin
,
3493 result
= DNS_R_BADZONE
;
3495 } else if (!isc_serial_ge(serial
, oldserial
))
3496 dns_zone_log(zone
, ISC_LOG_ERROR
,
3497 "zone serial (%u/%u) has gone "
3498 "backwards", serial
, oldserial
);
3499 else if (serial
== oldserial
&& !hasinclude
)
3500 dns_zone_log(zone
, ISC_LOG_ERROR
,
3501 "zone serial (%u) unchanged. "
3502 "zone may fail to transfer "
3503 "to slaves.", serial
);
3506 if (zone
->type
== dns_zone_master
&&
3507 (zone
->update_acl
!= NULL
|| zone
->ssutable
!= NULL
) &&
3508 zone
->sigresigninginterval
< (3 * refresh
) &&
3509 dns_db_issecure(db
))
3511 dns_zone_log(zone
, ISC_LOG_WARNING
,
3512 "sig-re-signing-interval less than "
3516 zone
->refresh
= RANGE(refresh
,
3517 zone
->minrefresh
, zone
->maxrefresh
);
3518 zone
->retry
= RANGE(retry
,
3519 zone
->minretry
, zone
->maxretry
);
3520 zone
->expire
= RANGE(expire
, zone
->refresh
+ zone
->retry
,
3522 zone
->minimum
= minimum
;
3523 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
3525 if (zone
->type
== dns_zone_slave
||
3526 zone
->type
== dns_zone_stub
) {
3530 result
= isc_file_getmodtime(zone
->journal
, &t
);
3531 if (result
!= ISC_R_SUCCESS
)
3532 result
= isc_file_getmodtime(zone
->masterfile
,
3534 if (result
== ISC_R_SUCCESS
)
3535 DNS_ZONE_TIME_ADD(&t
, zone
->expire
,
3538 DNS_ZONE_TIME_ADD(&now
, zone
->retry
,
3541 delay
= isc_random_jitter(zone
->retry
,
3542 (zone
->retry
* 3) / 4);
3543 DNS_ZONE_TIME_ADD(&now
, delay
, &zone
->refreshtime
);
3544 if (isc_time_compare(&zone
->refreshtime
,
3545 &zone
->expiretime
) >= 0)
3546 zone
->refreshtime
= now
;
3551 result
= sync_keyzone(zone
, db
);
3552 if (result
!= ISC_R_SUCCESS
)
3557 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
3558 "unexpected zone type %d", zone
->type
);
3559 result
= ISC_R_UNEXPECTED
;
3564 * Check for weak DNSKEY's.
3566 if (zone
->type
== dns_zone_master
)
3567 zone_check_dnskeys(zone
, db
);
3570 * Schedule DNSSEC key refresh.
3572 if (zone
->type
== dns_zone_master
&&
3573 DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_MAINTAIN
))
3574 zone
->refreshkeytime
= now
;
3577 /* destroy notification example. */
3579 isc_event_t
*e
= isc_event_allocate(zone
->mctx
, NULL
,
3580 DNS_EVENT_DBDESTROYED
,
3581 dns_zonemgr_dbdestroyed
,
3583 sizeof(isc_event_t
));
3584 dns_db_ondestroy(db
, zone
->task
, &e
);
3588 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
3589 if (zone
->db
!= NULL
) {
3590 result
= zone_replacedb(zone
, db
, ISC_FALSE
);
3591 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
3592 if (result
!= ISC_R_SUCCESS
)
3595 zone_attachdb(zone
, db
);
3596 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
3597 DNS_ZONE_SETFLAG(zone
,
3598 DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
3601 result
= ISC_R_SUCCESS
;
3604 if (zone
->type
== dns_zone_key
)
3605 zone_needdump(zone
, 30);
3607 zone_needdump(zone
, DNS_DUMP_DELAY
);
3610 if (zone
->task
!= NULL
) {
3611 if (zone
->type
== dns_zone_master
) {
3612 set_resigntime(zone
);
3613 resume_signingwithkey(zone
);
3614 resume_addnsec3chain(zone
);
3616 zone_settimer(zone
, &now
);
3619 if (! dns_db_ispersistent(db
))
3620 dns_zone_log(zone
, ISC_LOG_INFO
, "loaded serial %u%s", serial
,
3621 dns_db_issecure(db
) ? " (DNSSEC signed)" : "");
3626 if (zone
->type
== dns_zone_slave
||
3627 zone
->type
== dns_zone_stub
||
3628 zone
->type
== dns_zone_key
) {
3629 if (zone
->journal
!= NULL
)
3630 zone_saveunique(zone
, zone
->journal
, "jn-XXXXXXXX");
3631 if (zone
->masterfile
!= NULL
)
3632 zone_saveunique(zone
, zone
->masterfile
, "db-XXXXXXXX");
3634 /* Mark the zone for immediate refresh. */
3635 zone
->refreshtime
= now
;
3636 if (zone
->task
!= NULL
)
3637 zone_settimer(zone
, &now
);
3638 result
= ISC_R_SUCCESS
;
3643 static isc_boolean_t
3644 exit_check(dns_zone_t
*zone
) {
3646 REQUIRE(LOCKED_ZONE(zone
));
3648 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SHUTDOWN
) &&
3652 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
3654 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
3660 static isc_boolean_t
3661 zone_check_ns(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
3662 isc_boolean_t logit
)
3664 isc_result_t result
;
3665 char namebuf
[DNS_NAME_FORMATSIZE
];
3666 char altbuf
[DNS_NAME_FORMATSIZE
];
3667 dns_fixedname_t fixed
;
3668 dns_name_t
*foundname
;
3671 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOCHECKNS
))
3674 if (zone
->type
== dns_zone_master
)
3675 level
= ISC_LOG_ERROR
;
3677 level
= ISC_LOG_WARNING
;
3679 dns_fixedname_init(&fixed
);
3680 foundname
= dns_fixedname_name(&fixed
);
3682 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
3683 0, 0, NULL
, foundname
, NULL
, NULL
);
3684 if (result
== ISC_R_SUCCESS
)
3687 if (result
== DNS_R_NXRRSET
) {
3688 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
3689 0, 0, NULL
, foundname
, NULL
, NULL
);
3690 if (result
== ISC_R_SUCCESS
)
3694 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
3695 result
== DNS_R_EMPTYNAME
) {
3697 dns_name_format(name
, namebuf
, sizeof namebuf
);
3698 dns_zone_log(zone
, level
, "NS '%s' has no address "
3699 "records (A or AAAA)", namebuf
);
3704 if (result
== DNS_R_CNAME
) {
3706 dns_name_format(name
, namebuf
, sizeof namebuf
);
3707 dns_zone_log(zone
, level
, "NS '%s' is a CNAME "
3708 "(illegal)", namebuf
);
3713 if (result
== DNS_R_DNAME
) {
3715 dns_name_format(name
, namebuf
, sizeof namebuf
);
3716 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
3717 dns_zone_log(zone
, level
, "NS '%s' is below a DNAME "
3718 "'%s' (illegal)", namebuf
, altbuf
);
3727 zone_count_ns_rr(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbnode_t
*node
,
3728 dns_dbversion_t
*version
, unsigned int *nscount
,
3729 unsigned int *errors
, isc_boolean_t logit
)
3731 isc_result_t result
;
3732 unsigned int count
= 0;
3733 unsigned int ecount
= 0;
3734 dns_rdataset_t rdataset
;
3738 dns_rdataset_init(&rdataset
);
3739 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_ns
,
3740 dns_rdatatype_none
, 0, &rdataset
, NULL
);
3741 if (result
== ISC_R_NOTFOUND
) {
3742 INSIST(!dns_rdataset_isassociated(&rdataset
));
3745 if (result
!= ISC_R_SUCCESS
) {
3746 INSIST(!dns_rdataset_isassociated(&rdataset
));
3747 goto invalidate_rdataset
;
3750 result
= dns_rdataset_first(&rdataset
);
3751 while (result
== ISC_R_SUCCESS
) {
3752 if (errors
!= NULL
&& zone
->rdclass
== dns_rdataclass_in
&&
3753 (zone
->type
== dns_zone_master
||
3754 zone
->type
== dns_zone_slave
)) {
3755 dns_rdata_init(&rdata
);
3756 dns_rdataset_current(&rdataset
, &rdata
);
3757 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
3758 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3759 if (dns_name_issubdomain(&ns
.name
, &zone
->origin
) &&
3760 !zone_check_ns(zone
, db
, &ns
.name
, logit
))
3764 result
= dns_rdataset_next(&rdataset
);
3766 dns_rdataset_disassociate(&rdataset
);
3769 if (nscount
!= NULL
)
3774 result
= ISC_R_SUCCESS
;
3776 invalidate_rdataset
:
3777 dns_rdataset_invalidate(&rdataset
);
3783 zone_load_soa_rr(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
3784 unsigned int *soacount
,
3785 isc_uint32_t
*serial
, isc_uint32_t
*refresh
,
3786 isc_uint32_t
*retry
, isc_uint32_t
*expire
,
3787 isc_uint32_t
*minimum
)
3789 isc_result_t result
;
3791 dns_rdataset_t rdataset
;
3792 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3793 dns_rdata_soa_t soa
;
3795 dns_rdataset_init(&rdataset
);
3796 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_soa
,
3797 dns_rdatatype_none
, 0, &rdataset
, NULL
);
3798 if (result
== ISC_R_NOTFOUND
) {
3799 INSIST(!dns_rdataset_isassociated(&rdataset
));
3800 if (soacount
!= NULL
)
3804 if (refresh
!= NULL
)
3810 if (minimum
!= NULL
)
3812 result
= ISC_R_SUCCESS
;
3813 goto invalidate_rdataset
;
3815 if (result
!= ISC_R_SUCCESS
) {
3816 INSIST(!dns_rdataset_isassociated(&rdataset
));
3817 goto invalidate_rdataset
;
3821 result
= dns_rdataset_first(&rdataset
);
3822 while (result
== ISC_R_SUCCESS
) {
3823 dns_rdata_init(&rdata
);
3824 dns_rdataset_current(&rdataset
, &rdata
);
3827 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
3828 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3831 result
= dns_rdataset_next(&rdataset
);
3832 dns_rdata_reset(&rdata
);
3834 dns_rdataset_disassociate(&rdataset
);
3836 if (soacount
!= NULL
)
3841 *serial
= soa
.serial
;
3842 if (refresh
!= NULL
)
3843 *refresh
= soa
.refresh
;
3847 *expire
= soa
.expire
;
3848 if (minimum
!= NULL
)
3849 *minimum
= soa
.minimum
;
3852 result
= ISC_R_SUCCESS
;
3854 invalidate_rdataset
:
3855 dns_rdataset_invalidate(&rdataset
);
3861 * zone must be locked.
3864 zone_get_from_db(dns_zone_t
*zone
, dns_db_t
*db
, unsigned int *nscount
,
3865 unsigned int *soacount
, isc_uint32_t
*serial
,
3866 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
3867 isc_uint32_t
*expire
, isc_uint32_t
*minimum
,
3868 unsigned int *errors
)
3870 isc_result_t result
;
3871 isc_result_t answer
= ISC_R_SUCCESS
;
3872 dns_dbversion_t
*version
= NULL
;
3875 REQUIRE(db
!= NULL
);
3876 REQUIRE(zone
!= NULL
);
3878 dns_db_currentversion(db
, &version
);
3881 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
3882 if (result
!= ISC_R_SUCCESS
) {
3887 if (nscount
!= NULL
|| errors
!= NULL
) {
3888 result
= zone_count_ns_rr(zone
, db
, node
, version
,
3889 nscount
, errors
, ISC_TRUE
);
3890 if (result
!= ISC_R_SUCCESS
)
3894 if (soacount
!= NULL
|| serial
!= NULL
|| refresh
!= NULL
3895 || retry
!= NULL
|| expire
!= NULL
|| minimum
!= NULL
) {
3896 result
= zone_load_soa_rr(db
, node
, version
, soacount
,
3897 serial
, refresh
, retry
, expire
,
3899 if (result
!= ISC_R_SUCCESS
)
3903 dns_db_detachnode(db
, &node
);
3905 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3911 dns_zone_attach(dns_zone_t
*source
, dns_zone_t
**target
) {
3912 REQUIRE(DNS_ZONE_VALID(source
));
3913 REQUIRE(target
!= NULL
&& *target
== NULL
);
3914 isc_refcount_increment(&source
->erefs
, NULL
);
3919 dns_zone_detach(dns_zone_t
**zonep
) {
3922 isc_boolean_t free_now
= ISC_FALSE
;
3924 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
3928 isc_refcount_decrement(&zone
->erefs
, &refs
);
3933 * We just detached the last external reference.
3935 if (zone
->task
!= NULL
) {
3937 * This zone is being managed. Post
3938 * its control event and let it clean
3939 * up synchronously in the context of
3942 isc_event_t
*ev
= &zone
->ctlevent
;
3943 isc_task_send(zone
->task
, &ev
);
3946 * This zone is not being managed; it has
3947 * no task and can have no outstanding
3948 * events. Free it immediately.
3951 * Unmanaged zones should not have non-null views;
3952 * we have no way of detaching from the view here
3953 * without causing deadlock because this code is called
3954 * with the view already locked.
3956 INSIST(zone
->view
== NULL
);
3957 free_now
= ISC_TRUE
;
3967 dns_zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
3968 REQUIRE(DNS_ZONE_VALID(source
));
3969 REQUIRE(target
!= NULL
&& *target
== NULL
);
3971 zone_iattach(source
, target
);
3972 UNLOCK_ZONE(source
);
3976 zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
3979 * 'source' locked by caller.
3981 REQUIRE(LOCKED_ZONE(source
));
3982 REQUIRE(DNS_ZONE_VALID(source
));
3983 REQUIRE(target
!= NULL
&& *target
== NULL
);
3984 INSIST(source
->irefs
+ isc_refcount_current(&source
->erefs
) > 0);
3986 INSIST(source
->irefs
!= 0);
3991 zone_idetach(dns_zone_t
**zonep
) {
3995 * 'zone' locked by caller.
3997 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
3999 REQUIRE(LOCKED_ZONE(*zonep
));
4002 INSIST(zone
->irefs
> 0);
4004 INSIST(zone
->irefs
+ isc_refcount_current(&zone
->erefs
) > 0);
4008 dns_zone_idetach(dns_zone_t
**zonep
) {
4010 isc_boolean_t free_needed
;
4012 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
4017 INSIST(zone
->irefs
> 0);
4019 free_needed
= exit_check(zone
);
4026 dns_zone_getmctx(dns_zone_t
*zone
) {
4027 REQUIRE(DNS_ZONE_VALID(zone
));
4029 return (zone
->mctx
);
4033 dns_zone_getmgr(dns_zone_t
*zone
) {
4034 REQUIRE(DNS_ZONE_VALID(zone
));
4036 return (zone
->zmgr
);
4040 dns_zone_setflag(dns_zone_t
*zone
, unsigned int flags
, isc_boolean_t value
) {
4041 REQUIRE(DNS_ZONE_VALID(zone
));
4045 DNS_ZONE_SETFLAG(zone
, flags
);
4047 DNS_ZONE_CLRFLAG(zone
, flags
);
4052 dns_zone_setoption(dns_zone_t
*zone
, unsigned int option
, isc_boolean_t value
)
4054 REQUIRE(DNS_ZONE_VALID(zone
));
4058 zone
->options
|= option
;
4060 zone
->options
&= ~option
;
4065 dns_zone_getoptions(dns_zone_t
*zone
) {
4067 REQUIRE(DNS_ZONE_VALID(zone
));
4069 return (zone
->options
);
4073 dns_zone_setkeyopt(dns_zone_t
*zone
, unsigned int keyopt
, isc_boolean_t value
)
4075 REQUIRE(DNS_ZONE_VALID(zone
));
4079 zone
->keyopts
|= keyopt
;
4081 zone
->keyopts
&= ~keyopt
;
4086 dns_zone_getkeyopts(dns_zone_t
*zone
) {
4088 REQUIRE(DNS_ZONE_VALID(zone
));
4090 return (zone
->keyopts
);
4094 dns_zone_setxfrsource4(dns_zone_t
*zone
, const isc_sockaddr_t
*xfrsource
) {
4095 REQUIRE(DNS_ZONE_VALID(zone
));
4098 zone
->xfrsource4
= *xfrsource
;
4101 return (ISC_R_SUCCESS
);
4105 dns_zone_getxfrsource4(dns_zone_t
*zone
) {
4106 REQUIRE(DNS_ZONE_VALID(zone
));
4107 return (&zone
->xfrsource4
);
4111 dns_zone_setxfrsource6(dns_zone_t
*zone
, const isc_sockaddr_t
*xfrsource
) {
4112 REQUIRE(DNS_ZONE_VALID(zone
));
4115 zone
->xfrsource6
= *xfrsource
;
4118 return (ISC_R_SUCCESS
);
4122 dns_zone_getxfrsource6(dns_zone_t
*zone
) {
4123 REQUIRE(DNS_ZONE_VALID(zone
));
4124 return (&zone
->xfrsource6
);
4128 dns_zone_setaltxfrsource4(dns_zone_t
*zone
,
4129 const isc_sockaddr_t
*altxfrsource
)
4131 REQUIRE(DNS_ZONE_VALID(zone
));
4134 zone
->altxfrsource4
= *altxfrsource
;
4137 return (ISC_R_SUCCESS
);
4141 dns_zone_getaltxfrsource4(dns_zone_t
*zone
) {
4142 REQUIRE(DNS_ZONE_VALID(zone
));
4143 return (&zone
->altxfrsource4
);
4147 dns_zone_setaltxfrsource6(dns_zone_t
*zone
,
4148 const isc_sockaddr_t
*altxfrsource
)
4150 REQUIRE(DNS_ZONE_VALID(zone
));
4153 zone
->altxfrsource6
= *altxfrsource
;
4156 return (ISC_R_SUCCESS
);
4160 dns_zone_getaltxfrsource6(dns_zone_t
*zone
) {
4161 REQUIRE(DNS_ZONE_VALID(zone
));
4162 return (&zone
->altxfrsource6
);
4166 dns_zone_setnotifysrc4(dns_zone_t
*zone
, const isc_sockaddr_t
*notifysrc
) {
4167 REQUIRE(DNS_ZONE_VALID(zone
));
4170 zone
->notifysrc4
= *notifysrc
;
4173 return (ISC_R_SUCCESS
);
4177 dns_zone_getnotifysrc4(dns_zone_t
*zone
) {
4178 REQUIRE(DNS_ZONE_VALID(zone
));
4179 return (&zone
->notifysrc4
);
4183 dns_zone_setnotifysrc6(dns_zone_t
*zone
, const isc_sockaddr_t
*notifysrc
) {
4184 REQUIRE(DNS_ZONE_VALID(zone
));
4187 zone
->notifysrc6
= *notifysrc
;
4190 return (ISC_R_SUCCESS
);
4194 dns_zone_getnotifysrc6(dns_zone_t
*zone
) {
4195 REQUIRE(DNS_ZONE_VALID(zone
));
4196 return (&zone
->notifysrc6
);
4200 dns_zone_setalsonotify(dns_zone_t
*zone
, const isc_sockaddr_t
*notify
,
4203 isc_sockaddr_t
*new;
4205 REQUIRE(DNS_ZONE_VALID(zone
));
4206 REQUIRE(count
== 0 || notify
!= NULL
);
4209 if (zone
->notify
!= NULL
) {
4210 isc_mem_put(zone
->mctx
, zone
->notify
,
4211 zone
->notifycnt
* sizeof(*new));
4212 zone
->notify
= NULL
;
4213 zone
->notifycnt
= 0;
4216 new = isc_mem_get(zone
->mctx
, count
* sizeof(*new));
4219 return (ISC_R_NOMEMORY
);
4221 memcpy(new, notify
, count
* sizeof(*new));
4223 zone
->notifycnt
= count
;
4226 return (ISC_R_SUCCESS
);
4230 dns_zone_setmasters(dns_zone_t
*zone
, const isc_sockaddr_t
*masters
,
4233 isc_result_t result
;
4235 result
= dns_zone_setmasterswithkeys(zone
, masters
, NULL
, count
);
4239 static isc_boolean_t
4240 same_masters(const isc_sockaddr_t
*old
, const isc_sockaddr_t
*new,
4245 for (i
= 0; i
< count
; i
++)
4246 if (!isc_sockaddr_equal(&old
[i
], &new[i
]))
4251 static isc_boolean_t
4252 same_keynames(dns_name_t
**old
, dns_name_t
**new, isc_uint32_t count
) {
4255 if (old
== NULL
&& new == NULL
)
4257 if (old
== NULL
|| new == NULL
)
4260 for (i
= 0; i
< count
; i
++) {
4261 if (old
[i
] == NULL
&& new[i
] == NULL
)
4263 if (old
[i
] == NULL
|| new[i
] == NULL
||
4264 !dns_name_equal(old
[i
], new[i
]))
4271 dns_zone_setmasterswithkeys(dns_zone_t
*zone
,
4272 const isc_sockaddr_t
*masters
,
4273 dns_name_t
**keynames
,
4276 isc_sockaddr_t
*new;
4277 isc_result_t result
= ISC_R_SUCCESS
;
4278 dns_name_t
**newname
;
4279 isc_boolean_t
*newok
;
4282 REQUIRE(DNS_ZONE_VALID(zone
));
4283 REQUIRE(count
== 0 || masters
!= NULL
);
4284 if (keynames
!= NULL
) {
4285 REQUIRE(count
!= 0);
4290 * The refresh code assumes that 'masters' wouldn't change under it.
4291 * If it will change then kill off any current refresh in progress
4292 * and update the masters info. If it won't change then we can just
4295 if (count
!= zone
->masterscnt
||
4296 !same_masters(zone
->masters
, masters
, count
) ||
4297 !same_keynames(zone
->masterkeynames
, keynames
, count
)) {
4298 if (zone
->request
!= NULL
)
4299 dns_request_cancel(zone
->request
);
4302 if (zone
->masters
!= NULL
) {
4303 isc_mem_put(zone
->mctx
, zone
->masters
,
4304 zone
->masterscnt
* sizeof(*new));
4305 zone
->masters
= NULL
;
4307 if (zone
->masterkeynames
!= NULL
) {
4308 for (i
= 0; i
< zone
->masterscnt
; i
++) {
4309 if (zone
->masterkeynames
[i
] != NULL
) {
4310 dns_name_free(zone
->masterkeynames
[i
],
4312 isc_mem_put(zone
->mctx
,
4313 zone
->masterkeynames
[i
],
4314 sizeof(dns_name_t
));
4315 zone
->masterkeynames
[i
] = NULL
;
4318 isc_mem_put(zone
->mctx
, zone
->masterkeynames
,
4319 zone
->masterscnt
* sizeof(dns_name_t
*));
4320 zone
->masterkeynames
= NULL
;
4322 if (zone
->mastersok
!= NULL
) {
4323 isc_mem_put(zone
->mctx
, zone
->mastersok
,
4324 zone
->masterscnt
* sizeof(isc_boolean_t
));
4325 zone
->mastersok
= NULL
;
4327 zone
->masterscnt
= 0;
4329 * If count == 0, don't allocate any space for masters, mastersok or
4330 * keynames so internally, those pointers are NULL if count == 0
4336 * masters must contain count elements!
4338 new = isc_mem_get(zone
->mctx
, count
* sizeof(*new));
4340 result
= ISC_R_NOMEMORY
;
4343 memcpy(new, masters
, count
* sizeof(*new));
4346 * Similarly for mastersok.
4348 newok
= isc_mem_get(zone
->mctx
, count
* sizeof(*newok
));
4349 if (newok
== NULL
) {
4350 result
= ISC_R_NOMEMORY
;
4351 isc_mem_put(zone
->mctx
, new, count
* sizeof(*new));
4354 for (i
= 0; i
< count
; i
++)
4355 newok
[i
] = ISC_FALSE
;
4358 * if keynames is non-NULL, it must contain count elements!
4361 if (keynames
!= NULL
) {
4362 newname
= isc_mem_get(zone
->mctx
, count
* sizeof(*newname
));
4363 if (newname
== NULL
) {
4364 result
= ISC_R_NOMEMORY
;
4365 isc_mem_put(zone
->mctx
, new, count
* sizeof(*new));
4366 isc_mem_put(zone
->mctx
, newok
, count
* sizeof(*newok
));
4369 for (i
= 0; i
< count
; i
++)
4371 for (i
= 0; i
< count
; i
++) {
4372 if (keynames
[i
] != NULL
) {
4373 newname
[i
] = isc_mem_get(zone
->mctx
,
4374 sizeof(dns_name_t
));
4375 if (newname
[i
] == NULL
)
4377 dns_name_init(newname
[i
], NULL
);
4378 result
= dns_name_dup(keynames
[i
], zone
->mctx
,
4380 if (result
!= ISC_R_SUCCESS
) {
4382 for (i
= 0; i
< count
; i
++)
4383 if (newname
[i
] != NULL
)
4387 isc_mem_put(zone
->mctx
, new,
4388 count
* sizeof(*new));
4389 isc_mem_put(zone
->mctx
, newok
,
4390 count
* sizeof(*newok
));
4391 isc_mem_put(zone
->mctx
, newname
,
4392 count
* sizeof(*newname
));
4400 * Everything is ok so attach to the zone.
4402 zone
->masters
= new;
4403 zone
->mastersok
= newok
;
4404 zone
->masterkeynames
= newname
;
4405 zone
->masterscnt
= count
;
4406 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
4414 dns_zone_getdb(dns_zone_t
*zone
, dns_db_t
**dpb
) {
4415 isc_result_t result
= ISC_R_SUCCESS
;
4417 REQUIRE(DNS_ZONE_VALID(zone
));
4419 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
4420 if (zone
->db
== NULL
)
4421 result
= DNS_R_NOTLOADED
;
4423 dns_db_attach(zone
->db
, dpb
);
4424 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
4430 * Co-ordinates the starting of routine jobs.
4434 dns_zone_maintenance(dns_zone_t
*zone
) {
4435 const char me
[] = "dns_zone_maintenance";
4438 REQUIRE(DNS_ZONE_VALID(zone
));
4443 zone_settimer(zone
, &now
);
4447 static inline isc_boolean_t
4448 was_dumping(dns_zone_t
*zone
) {
4449 isc_boolean_t dumping
;
4451 REQUIRE(LOCKED_ZONE(zone
));
4453 dumping
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
);
4454 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
4456 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
4457 isc_time_settoepoch(&zone
->dumptime
);
4462 #define MAXZONEKEYS 10
4465 find_zone_keys(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
4466 isc_mem_t
*mctx
, unsigned int maxkeys
,
4467 dst_key_t
**keys
, unsigned int *nkeys
)
4469 isc_result_t result
;
4470 dns_dbnode_t
*node
= NULL
;
4471 const char *directory
= dns_zone_getkeydirectory(zone
);
4472 CHECK(dns_db_findnode(db
, dns_db_origin(db
), ISC_FALSE
, &node
));
4473 result
= dns_dnssec_findzonekeys2(db
, ver
, node
, dns_db_origin(db
),
4474 directory
, mctx
, maxkeys
, keys
,
4476 if (result
== ISC_R_NOTFOUND
)
4477 result
= ISC_R_SUCCESS
;
4480 dns_db_detachnode(db
, &node
);
4485 offline(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_diff_t
*diff
, dns_name_t
*name
,
4486 dns_ttl_t ttl
, dns_rdata_t
*rdata
)
4488 isc_result_t result
;
4490 if ((rdata
->flags
& DNS_RDATA_OFFLINE
) != 0)
4491 return (ISC_R_SUCCESS
);
4492 result
= update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DELRESIGN
,
4494 if (result
!= ISC_R_SUCCESS
)
4496 rdata
->flags
|= DNS_RDATA_OFFLINE
;
4497 result
= update_one_rr(db
, ver
, diff
, DNS_DIFFOP_ADDRESIGN
,
4503 set_key_expiry_warning(dns_zone_t
*zone
, isc_stdtime_t when
, isc_stdtime_t now
)
4507 zone
->key_expiry
= when
;
4509 dns_zone_log(zone
, ISC_LOG_ERROR
,
4510 "DNSKEY RRSIG(s) have expired");
4511 isc_time_settoepoch(&zone
->keywarntime
);
4512 } else if (when
< now
+ 7 * 24 * 3600) {
4513 dns_zone_log(zone
, ISC_LOG_WARNING
,
4514 "DNSKEY RRSIG(s) will expire at %u",
4515 when
); /* XXXMPA convert to date. */
4517 delta
--; /* loop prevention */
4518 delta
/= 24 * 3600; /* to whole days */
4519 delta
*= 24 * 3600; /* to seconds */
4520 isc_time_set(&zone
->keywarntime
, when
- delta
, 0);
4522 dns_zone_log(zone
, ISC_LOG_NOTICE
, /* XXMPA ISC_LOG_DEBUG(1) */
4523 "setting keywarntime to %u - 7 days",
4524 when
); /* XXXMPA convert to date. */
4525 isc_time_set(&zone
->keywarntime
, when
- 7 * 24 * 3600, 0);
4530 * Delete expired RRsigs and any RRsigs we are about to re-sign.
4531 * See also update.c:del_keysigs().
4534 del_sigs(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
, dns_name_t
*name
,
4535 dns_rdatatype_t type
, dns_diff_t
*diff
, dst_key_t
**keys
,
4536 unsigned int nkeys
, isc_stdtime_t now
)
4538 isc_result_t result
;
4539 dns_dbnode_t
*node
= NULL
;
4540 dns_rdataset_t rdataset
;
4541 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4543 dns_rdata_rrsig_t rrsig
;
4544 isc_boolean_t found
;
4545 isc_stdtime_t warn
= 0, maybe
= 0;
4547 dns_rdataset_init(&rdataset
);
4549 if (type
== dns_rdatatype_nsec3
)
4550 result
= dns_db_findnsec3node(db
, name
, ISC_FALSE
, &node
);
4552 result
= dns_db_findnode(db
, name
, ISC_FALSE
, &node
);
4553 if (result
== ISC_R_NOTFOUND
)
4554 return (ISC_R_SUCCESS
);
4555 if (result
!= ISC_R_SUCCESS
)
4557 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_rrsig
, type
,
4558 (isc_stdtime_t
) 0, &rdataset
, NULL
);
4559 dns_db_detachnode(db
, &node
);
4561 if (result
== ISC_R_NOTFOUND
) {
4562 INSIST(!dns_rdataset_isassociated(&rdataset
));
4563 return (ISC_R_SUCCESS
);
4565 if (result
!= ISC_R_SUCCESS
) {
4566 INSIST(!dns_rdataset_isassociated(&rdataset
));
4570 for (result
= dns_rdataset_first(&rdataset
);
4571 result
== ISC_R_SUCCESS
;
4572 result
= dns_rdataset_next(&rdataset
)) {
4573 dns_rdataset_current(&rdataset
, &rdata
);
4574 result
= dns_rdata_tostruct(&rdata
, &rrsig
, NULL
);
4575 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4577 if (type
!= dns_rdatatype_dnskey
) {
4578 result
= update_one_rr(db
, ver
, diff
,
4579 DNS_DIFFOP_DEL
, name
,
4580 rdataset
.ttl
, &rdata
);
4581 dns_rdata_reset(&rdata
);
4582 if (result
!= ISC_R_SUCCESS
)
4588 * RRSIG(DNSKEY) requires special processing.
4591 for (i
= 0; i
< nkeys
; i
++) {
4592 if (rrsig
.algorithm
== dst_key_alg(keys
[i
]) &&
4593 rrsig
.keyid
== dst_key_id(keys
[i
])) {
4596 * Mark offline RRSIG(DNSKEY).
4597 * We want the earliest offline expire time
4598 * iff there is a new offline signature.
4600 if (!dst_key_isprivate(keys
[i
])) {
4602 warn
> rrsig
.timeexpire
)
4603 warn
= rrsig
.timeexpire
;
4604 if (rdata
.flags
& DNS_RDATA_OFFLINE
) {
4606 maybe
> rrsig
.timeexpire
)
4614 warn
> rrsig
.timeexpire
)
4615 warn
= rrsig
.timeexpire
;
4616 result
= offline(db
, ver
, diff
, name
,
4617 rdataset
.ttl
, &rdata
);
4620 result
= update_one_rr(db
, ver
, diff
,
4628 * If there is not a matching DNSKEY then
4632 result
= update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
,
4633 name
, rdataset
.ttl
, &rdata
);
4634 dns_rdata_reset(&rdata
);
4635 if (result
!= ISC_R_SUCCESS
)
4638 dns_rdataset_disassociate(&rdataset
);
4639 if (result
== ISC_R_NOMORE
)
4640 result
= ISC_R_SUCCESS
;
4642 set_key_expiry_warning(zone
, warn
, now
);
4645 dns_db_detachnode(db
, &node
);
4650 add_sigs(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_name_t
*name
,
4651 dns_rdatatype_t type
, dns_diff_t
*diff
, dst_key_t
**keys
,
4652 unsigned int nkeys
, isc_mem_t
*mctx
, isc_stdtime_t inception
,
4653 isc_stdtime_t expire
, isc_boolean_t check_ksk
,
4654 isc_boolean_t keyset_kskonly
)
4656 isc_result_t result
;
4657 dns_dbnode_t
*node
= NULL
;
4658 dns_rdataset_t rdataset
;
4659 dns_rdata_t sig_rdata
= DNS_RDATA_INIT
;
4660 unsigned char data
[1024]; /* XXX */
4661 isc_buffer_t buffer
;
4664 dns_rdataset_init(&rdataset
);
4665 isc_buffer_init(&buffer
, data
, sizeof(data
));
4667 if (type
== dns_rdatatype_nsec3
)
4668 result
= dns_db_findnsec3node(db
, name
, ISC_FALSE
, &node
);
4670 result
= dns_db_findnode(db
, name
, ISC_FALSE
, &node
);
4671 if (result
== ISC_R_NOTFOUND
)
4672 return (ISC_R_SUCCESS
);
4673 if (result
!= ISC_R_SUCCESS
)
4675 result
= dns_db_findrdataset(db
, node
, ver
, type
, 0,
4676 (isc_stdtime_t
) 0, &rdataset
, NULL
);
4677 dns_db_detachnode(db
, &node
);
4678 if (result
== ISC_R_NOTFOUND
) {
4679 INSIST(!dns_rdataset_isassociated(&rdataset
));
4680 return (ISC_R_SUCCESS
);
4682 if (result
!= ISC_R_SUCCESS
) {
4683 INSIST(!dns_rdataset_isassociated(&rdataset
));
4687 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
4688 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
4689 #define ALG(x) dst_key_alg(x)
4691 for (i
= 0; i
< nkeys
; i
++) {
4692 isc_boolean_t both
= ISC_FALSE
;
4694 if (!dst_key_isprivate(keys
[i
]))
4697 if (check_ksk
&& !REVOKE(keys
[i
])) {
4698 isc_boolean_t have_ksk
, have_nonksk
;
4700 have_ksk
= ISC_TRUE
;
4701 have_nonksk
= ISC_FALSE
;
4703 have_ksk
= ISC_FALSE
;
4704 have_nonksk
= ISC_TRUE
;
4706 for (j
= 0; j
< nkeys
; j
++) {
4707 if (j
== i
|| ALG(keys
[i
]) != ALG(keys
[j
]))
4709 if (REVOKE(keys
[j
]))
4712 have_ksk
= ISC_TRUE
;
4714 have_nonksk
= ISC_TRUE
;
4715 both
= have_ksk
&& have_nonksk
;
4721 if (type
== dns_rdatatype_dnskey
) {
4722 if (!KSK(keys
[i
]) && keyset_kskonly
)
4724 } else if (KSK(keys
[i
]))
4726 } else if (REVOKE(keys
[i
]) && type
!= dns_rdatatype_dnskey
)
4729 /* Calculate the signature, creating a RRSIG RDATA. */
4730 isc_buffer_clear(&buffer
);
4731 CHECK(dns_dnssec_sign(name
, &rdataset
, keys
[i
],
4732 &inception
, &expire
,
4733 mctx
, &buffer
, &sig_rdata
));
4734 /* Update the database and journal with the RRSIG. */
4735 /* XXX inefficient - will cause dataset merging */
4736 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_ADDRESIGN
,
4737 name
, rdataset
.ttl
, &sig_rdata
));
4738 dns_rdata_reset(&sig_rdata
);
4742 if (dns_rdataset_isassociated(&rdataset
))
4743 dns_rdataset_disassociate(&rdataset
);
4745 dns_db_detachnode(db
, &node
);
4750 zone_resigninc(dns_zone_t
*zone
) {
4751 dns_db_t
*db
= NULL
;
4752 dns_dbversion_t
*version
= NULL
;
4753 dns_diff_t sig_diff
;
4754 dns_fixedname_t fixed
;
4756 dns_rdataset_t rdataset
;
4757 dns_rdatatype_t covers
;
4758 dst_key_t
*zone_keys
[MAXZONEKEYS
];
4759 isc_boolean_t check_ksk
, keyset_kskonly
= ISC_FALSE
;
4760 isc_result_t result
;
4761 isc_stdtime_t now
, inception
, soaexpire
, expire
, stop
;
4762 isc_uint32_t jitter
;
4764 unsigned int nkeys
= 0;
4765 unsigned int resign
;
4767 dns_rdataset_init(&rdataset
);
4768 dns_fixedname_init(&fixed
);
4769 dns_diff_init(zone
->mctx
, &sig_diff
);
4770 sig_diff
.resign
= zone
->sigresigninginterval
;
4773 * Updates are disabled. Pause for 5 minutes.
4775 if (zone
->update_disabled
) {
4776 result
= ISC_R_FAILURE
;
4780 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
4781 dns_db_attach(zone
->db
, &db
);
4782 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
4784 result
= dns_db_newversion(db
, &version
);
4785 if (result
!= ISC_R_SUCCESS
) {
4786 dns_zone_log(zone
, ISC_LOG_ERROR
,
4787 "zone_resigninc:dns_db_newversion -> %s\n",
4788 dns_result_totext(result
));
4792 result
= find_zone_keys(zone
, db
, version
, zone
->mctx
, MAXZONEKEYS
,
4794 if (result
!= ISC_R_SUCCESS
) {
4795 dns_zone_log(zone
, ISC_LOG_ERROR
,
4796 "zone_resigninc:find_zone_keys -> %s\n",
4797 dns_result_totext(result
));
4801 isc_stdtime_get(&now
);
4802 inception
= now
- 3600; /* Allow for clock skew. */
4803 soaexpire
= now
+ dns_zone_getsigvalidityinterval(zone
);
4805 * Spread out signatures over time if they happen to be
4806 * clumped. We don't do this for each add_sigs() call as
4807 * we still want some clustering to occur.
4809 isc_random_get(&jitter
);
4810 expire
= soaexpire
- jitter
% 3600;
4813 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
4814 keyset_kskonly
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
);
4816 name
= dns_fixedname_name(&fixed
);
4817 result
= dns_db_getsigningtime(db
, &rdataset
, name
);
4818 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
4819 dns_zone_log(zone
, ISC_LOG_ERROR
,
4820 "zone_resigninc:dns_db_getsigningtime -> %s\n",
4821 dns_result_totext(result
));
4825 while (result
== ISC_R_SUCCESS
) {
4826 resign
= rdataset
.resign
;
4827 covers
= rdataset
.covers
;
4829 * Stop if we hit the SOA as that means we have walked the
4830 * entire zone. The SOA record should always be the most
4833 /* XXXMPA increase number of RRsets signed pre call */
4834 if (covers
== dns_rdatatype_soa
|| i
++ > zone
->signatures
||
4837 * Ensure that we don't loop resigning the SOA.
4839 if (covers
== dns_rdatatype_soa
)
4840 dns_db_resigned(db
, &rdataset
, version
);
4841 dns_rdataset_disassociate(&rdataset
);
4845 dns_db_resigned(db
, &rdataset
, version
);
4846 dns_rdataset_disassociate(&rdataset
);
4848 result
= del_sigs(zone
, db
, version
, name
, covers
, &sig_diff
,
4849 zone_keys
, nkeys
, now
);
4850 if (result
!= ISC_R_SUCCESS
) {
4851 dns_zone_log(zone
, ISC_LOG_ERROR
,
4852 "zone_resigninc:del_sigs -> %s\n",
4853 dns_result_totext(result
));
4856 result
= add_sigs(db
, version
, name
, covers
, &sig_diff
,
4857 zone_keys
, nkeys
, zone
->mctx
, inception
,
4858 expire
, check_ksk
, keyset_kskonly
);
4859 if (result
!= ISC_R_SUCCESS
) {
4860 dns_zone_log(zone
, ISC_LOG_ERROR
,
4861 "zone_resigninc:add_sigs -> %s\n",
4862 dns_result_totext(result
));
4865 result
= dns_db_getsigningtime(db
, &rdataset
,
4866 dns_fixedname_name(&fixed
));
4867 if (nkeys
== 0 && result
== ISC_R_NOTFOUND
) {
4868 result
= ISC_R_SUCCESS
;
4871 if (result
!= ISC_R_SUCCESS
)
4872 dns_zone_log(zone
, ISC_LOG_ERROR
,
4873 "zone_resigninc:dns_db_getsigningtime -> %s\n",
4874 dns_result_totext(result
));
4877 if (result
!= ISC_R_NOMORE
&& result
!= ISC_R_SUCCESS
)
4880 result
= del_sigs(zone
, db
, version
, &zone
->origin
, dns_rdatatype_soa
,
4881 &sig_diff
, zone_keys
, nkeys
, now
);
4882 if (result
!= ISC_R_SUCCESS
) {
4883 dns_zone_log(zone
, ISC_LOG_ERROR
,
4884 "zone_resigninc:del_sigs -> %s\n",
4885 dns_result_totext(result
));
4889 result
= increment_soa_serial(db
, version
, &sig_diff
, zone
->mctx
);
4890 if (result
!= ISC_R_SUCCESS
) {
4891 dns_zone_log(zone
, ISC_LOG_ERROR
,
4892 "zone_resigninc:increment_soa_serial -> %s\n",
4893 dns_result_totext(result
));
4898 * Generate maximum life time signatures so that the above loop
4899 * termination is sensible.
4901 result
= add_sigs(db
, version
, &zone
->origin
, dns_rdatatype_soa
,
4902 &sig_diff
, zone_keys
, nkeys
, zone
->mctx
, inception
,
4903 soaexpire
, check_ksk
, keyset_kskonly
);
4904 if (result
!= ISC_R_SUCCESS
) {
4905 dns_zone_log(zone
, ISC_LOG_ERROR
,
4906 "zone_resigninc:add_sigs -> %s\n",
4907 dns_result_totext(result
));
4911 /* Write changes to journal file. */
4912 zone_journal(zone
, &sig_diff
, "zone_resigninc");
4914 /* Everything has succeeded. Commit the changes. */
4915 dns_db_closeversion(db
, &version
, ISC_TRUE
);
4918 dns_diff_clear(&sig_diff
);
4919 for (i
= 0; i
< nkeys
; i
++)
4920 dst_key_free(&zone_keys
[i
]);
4921 if (version
!= NULL
) {
4922 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
4924 } else if (db
!= NULL
)
4926 if (result
== ISC_R_SUCCESS
) {
4927 set_resigntime(zone
);
4929 zone_needdump(zone
, DNS_DUMP_DELAY
);
4930 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
4934 * Something failed. Retry in 5 minutes.
4936 isc_interval_t ival
;
4937 isc_interval_set(&ival
, 300, 0);
4938 isc_time_nowplusinterval(&zone
->resigntime
, &ival
);
4943 next_active(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*oldname
,
4944 dns_name_t
*newname
, isc_boolean_t bottom
)
4946 isc_result_t result
;
4947 dns_dbiterator_t
*dbit
= NULL
;
4948 dns_rdatasetiter_t
*rdsit
= NULL
;
4949 dns_dbnode_t
*node
= NULL
;
4951 CHECK(dns_db_createiterator(db
, DNS_DB_NONSEC3
, &dbit
));
4952 CHECK(dns_dbiterator_seek(dbit
, oldname
));
4954 result
= dns_dbiterator_next(dbit
);
4955 if (result
== ISC_R_NOMORE
)
4956 CHECK(dns_dbiterator_first(dbit
));
4957 CHECK(dns_dbiterator_current(dbit
, &node
, newname
));
4958 if (bottom
&& dns_name_issubdomain(newname
, oldname
) &&
4959 !dns_name_equal(newname
, oldname
)) {
4960 dns_db_detachnode(db
, &node
);
4964 * Is this node empty?
4966 CHECK(dns_db_allrdatasets(db
, node
, version
, 0, &rdsit
));
4967 result
= dns_rdatasetiter_first(rdsit
);
4968 dns_db_detachnode(db
, &node
);
4969 dns_rdatasetiter_destroy(&rdsit
);
4970 if (result
!= ISC_R_NOMORE
)
4975 dns_db_detachnode(db
, &node
);
4977 dns_dbiterator_destroy(&dbit
);
4981 static isc_boolean_t
4982 signed_with_key(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
4983 dns_rdatatype_t type
, dst_key_t
*key
)
4985 isc_result_t result
;
4986 dns_rdataset_t rdataset
;
4987 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4988 dns_rdata_rrsig_t rrsig
;
4990 dns_rdataset_init(&rdataset
);
4991 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_rrsig
,
4992 type
, 0, &rdataset
, NULL
);
4993 if (result
!= ISC_R_SUCCESS
) {
4994 INSIST(!dns_rdataset_isassociated(&rdataset
));
4997 for (result
= dns_rdataset_first(&rdataset
);
4998 result
== ISC_R_SUCCESS
;
4999 result
= dns_rdataset_next(&rdataset
)) {
5000 dns_rdataset_current(&rdataset
, &rdata
);
5001 result
= dns_rdata_tostruct(&rdata
, &rrsig
, NULL
);
5002 INSIST(result
== ISC_R_SUCCESS
);
5003 if (rrsig
.algorithm
== dst_key_alg(key
) &&
5004 rrsig
.keyid
== dst_key_id(key
)) {
5005 dns_rdataset_disassociate(&rdataset
);
5008 dns_rdata_reset(&rdata
);
5010 dns_rdataset_disassociate(&rdataset
);
5015 add_nsec(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
5016 dns_dbnode_t
*node
, dns_ttl_t ttl
, isc_boolean_t bottom
,
5019 dns_fixedname_t fixed
;
5021 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5022 isc_result_t result
;
5023 unsigned char nsecbuffer
[DNS_NSEC_BUFFERSIZE
];
5025 dns_fixedname_init(&fixed
);
5026 next
= dns_fixedname_name(&fixed
);
5028 CHECK(next_active(db
, version
, name
, next
, bottom
));
5029 CHECK(dns_nsec_buildrdata(db
, version
, node
, next
, nsecbuffer
,
5031 CHECK(update_one_rr(db
, version
, diff
, DNS_DIFFOP_ADD
, name
, ttl
,
5038 sign_a_node(dns_db_t
*db
, dns_name_t
*name
, dns_dbnode_t
*node
,
5039 dns_dbversion_t
*version
, isc_boolean_t build_nsec3
,
5040 isc_boolean_t build_nsec
, dst_key_t
*key
,
5041 isc_stdtime_t inception
, isc_stdtime_t expire
,
5042 unsigned int minimum
, isc_boolean_t is_ksk
,
5043 isc_boolean_t keyset_kskonly
, isc_boolean_t
*delegation
,
5044 dns_diff_t
*diff
, isc_int32_t
*signatures
, isc_mem_t
*mctx
)
5046 isc_result_t result
;
5047 dns_rdatasetiter_t
*iterator
= NULL
;
5048 dns_rdataset_t rdataset
;
5049 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5050 isc_buffer_t buffer
;
5051 unsigned char data
[1024];
5052 isc_boolean_t seen_soa
, seen_ns
, seen_rr
, seen_dname
, seen_nsec
,
5053 seen_nsec3
, seen_ds
;
5054 isc_boolean_t bottom
;
5056 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
5057 if (result
!= ISC_R_SUCCESS
) {
5058 if (result
== ISC_R_NOTFOUND
)
5059 result
= ISC_R_SUCCESS
;
5063 dns_rdataset_init(&rdataset
);
5064 isc_buffer_init(&buffer
, data
, sizeof(data
));
5065 seen_rr
= seen_soa
= seen_ns
= seen_dname
= seen_nsec
=
5066 seen_nsec3
= seen_ds
= ISC_FALSE
;
5067 for (result
= dns_rdatasetiter_first(iterator
);
5068 result
== ISC_R_SUCCESS
;
5069 result
= dns_rdatasetiter_next(iterator
)) {
5070 dns_rdatasetiter_current(iterator
, &rdataset
);
5071 if (rdataset
.type
== dns_rdatatype_soa
)
5072 seen_soa
= ISC_TRUE
;
5073 else if (rdataset
.type
== dns_rdatatype_ns
)
5075 else if (rdataset
.type
== dns_rdatatype_ds
)
5077 else if (rdataset
.type
== dns_rdatatype_dname
)
5078 seen_dname
= ISC_TRUE
;
5079 else if (rdataset
.type
== dns_rdatatype_nsec
)
5080 seen_nsec
= ISC_TRUE
;
5081 else if (rdataset
.type
== dns_rdatatype_nsec3
)
5082 seen_nsec3
= ISC_TRUE
;
5083 if (rdataset
.type
!= dns_rdatatype_rrsig
)
5085 dns_rdataset_disassociate(&rdataset
);
5087 if (result
!= ISC_R_NOMORE
)
5089 if (seen_ns
&& !seen_soa
)
5090 *delegation
= ISC_TRUE
;
5092 * Going from insecure to NSEC3.
5093 * Don't generate NSEC3 records for NSEC3 records.
5095 if (build_nsec3
&& !seen_nsec3
&& seen_rr
) {
5096 isc_boolean_t unsecure
= !seen_ds
&& seen_ns
&& !seen_soa
;
5097 CHECK(dns_nsec3_addnsec3s(db
, version
, name
, minimum
,
5102 * Going from insecure to NSEC.
5103 * Don't generate NSEC records for NSEC3 records.
5105 if (build_nsec
&& !seen_nsec3
&& !seen_nsec
&& seen_rr
) {
5106 /* Build and add NSEC. */
5107 bottom
= (seen_ns
&& !seen_soa
) || seen_dname
;
5109 * Build a NSEC record except at the origin.
5111 if (!dns_name_equal(name
, dns_db_origin(db
))) {
5112 CHECK(add_nsec(db
, version
, name
, node
, minimum
,
5114 /* Count a NSEC generation as a signature generation. */
5118 result
= dns_rdatasetiter_first(iterator
);
5119 while (result
== ISC_R_SUCCESS
) {
5120 dns_rdatasetiter_current(iterator
, &rdataset
);
5121 if (rdataset
.type
== dns_rdatatype_soa
||
5122 rdataset
.type
== dns_rdatatype_rrsig
)
5124 if (rdataset
.type
== dns_rdatatype_dnskey
) {
5125 if (!is_ksk
&& keyset_kskonly
)
5130 rdataset
.type
!= dns_rdatatype_ds
&&
5131 rdataset
.type
!= dns_rdatatype_nsec
)
5133 if (signed_with_key(db
, node
, version
, rdataset
.type
, key
))
5135 /* Calculate the signature, creating a RRSIG RDATA. */
5136 isc_buffer_clear(&buffer
);
5137 CHECK(dns_dnssec_sign(name
, &rdataset
, key
, &inception
,
5138 &expire
, mctx
, &buffer
, &rdata
));
5139 /* Update the database and journal with the RRSIG. */
5140 /* XXX inefficient - will cause dataset merging */
5141 CHECK(update_one_rr(db
, version
, diff
, DNS_DIFFOP_ADDRESIGN
,
5142 name
, rdataset
.ttl
, &rdata
));
5143 dns_rdata_reset(&rdata
);
5146 dns_rdataset_disassociate(&rdataset
);
5147 result
= dns_rdatasetiter_next(iterator
);
5149 if (result
== ISC_R_NOMORE
)
5150 result
= ISC_R_SUCCESS
;
5152 *delegation
= ISC_TRUE
;
5154 if (dns_rdataset_isassociated(&rdataset
))
5155 dns_rdataset_disassociate(&rdataset
);
5156 if (iterator
!= NULL
)
5157 dns_rdatasetiter_destroy(&iterator
);
5162 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
5165 updatesecure(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
5166 dns_ttl_t minimum
, isc_boolean_t update_only
, dns_diff_t
*diff
)
5168 isc_result_t result
;
5169 dns_rdataset_t rdataset
;
5170 dns_dbnode_t
*node
= NULL
;
5172 CHECK(dns_db_getoriginnode(db
, &node
));
5174 dns_rdataset_init(&rdataset
);
5175 result
= dns_db_findrdataset(db
, node
, version
,
5178 0, &rdataset
, NULL
);
5179 if (dns_rdataset_isassociated(&rdataset
))
5180 dns_rdataset_disassociate(&rdataset
);
5181 if (result
== ISC_R_NOTFOUND
)
5183 if (result
!= ISC_R_SUCCESS
)
5186 CHECK(delete_nsec(db
, version
, node
, name
, diff
));
5187 CHECK(add_nsec(db
, version
, name
, node
, minimum
, ISC_FALSE
, diff
));
5189 result
= ISC_R_SUCCESS
;
5192 dns_db_detachnode(db
, &node
);
5197 updatesignwithkey(dns_zone_t
*zone
, dns_signing_t
*signing
,
5198 dns_dbversion_t
*version
, isc_boolean_t build_nsec3
,
5199 dns_ttl_t minimum
, dns_diff_t
*diff
)
5201 isc_result_t result
;
5202 dns_dbnode_t
*node
= NULL
;
5203 dns_rdataset_t rdataset
;
5204 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5205 unsigned char data
[5];
5206 isc_boolean_t seen_done
= ISC_FALSE
;
5207 isc_boolean_t have_rr
= ISC_FALSE
;
5209 dns_rdataset_init(&rdataset
);
5210 result
= dns_db_getoriginnode(signing
->db
, &node
);
5211 if (result
!= ISC_R_SUCCESS
)
5214 result
= dns_db_findrdataset(signing
->db
, node
, version
,
5215 zone
->privatetype
, dns_rdatatype_none
,
5216 0, &rdataset
, NULL
);
5217 if (result
== ISC_R_NOTFOUND
) {
5218 INSIST(!dns_rdataset_isassociated(&rdataset
));
5219 result
= ISC_R_SUCCESS
;
5222 if (result
!= ISC_R_SUCCESS
) {
5223 INSIST(!dns_rdataset_isassociated(&rdataset
));
5226 for (result
= dns_rdataset_first(&rdataset
);
5227 result
== ISC_R_SUCCESS
;
5228 result
= dns_rdataset_next(&rdataset
)) {
5229 dns_rdataset_current(&rdataset
, &rdata
);
5231 * If we don't match the algorithm or keyid skip the record.
5233 if (rdata
.length
!= 5 ||
5234 rdata
.data
[0] != signing
->algorithm
||
5235 rdata
.data
[1] != ((signing
->keyid
>> 8) & 0xff) ||
5236 rdata
.data
[2] != (signing
->keyid
& 0xff)) {
5238 dns_rdata_reset(&rdata
);
5242 * We have a match. If we were signing (!signing->delete)
5243 * and we already have a record indicating that we have
5244 * finished signing (rdata.data[4] != 0) then keep it.
5245 * Otherwise it needs to be deleted as we have removed all
5246 * the signatures (signing->delete), so any record indicating
5247 * completion is now out of date, or we have finished signing
5248 * with the new record so we no longer need to remember that
5249 * we need to sign the zone with the matching key across a
5250 * nameserver re-start.
5252 if (!signing
->delete && rdata
.data
[4] != 0) {
5253 seen_done
= ISC_TRUE
;
5256 CHECK(update_one_rr(signing
->db
, version
, diff
,
5257 DNS_DIFFOP_DEL
, &zone
->origin
,
5258 rdataset
.ttl
, &rdata
));
5259 dns_rdata_reset(&rdata
);
5261 if (result
== ISC_R_NOMORE
)
5262 result
= ISC_R_SUCCESS
;
5263 if (!signing
->delete && !seen_done
) {
5265 * If we were signing then we need to indicate that we have
5266 * finished signing the zone with this key. If it is already
5267 * there we don't need to add it a second time.
5269 data
[0] = signing
->algorithm
;
5270 data
[1] = (signing
->keyid
>> 8) & 0xff;
5271 data
[2] = signing
->keyid
& 0xff;
5274 rdata
.length
= sizeof(data
);
5276 rdata
.type
= zone
->privatetype
;
5277 rdata
.rdclass
= dns_db_class(signing
->db
);
5278 CHECK(update_one_rr(signing
->db
, version
, diff
, DNS_DIFFOP_ADD
,
5279 &zone
->origin
, rdataset
.ttl
, &rdata
));
5280 } else if (!have_rr
) {
5281 dns_name_t
*origin
= dns_db_origin(signing
->db
);
5283 * Rebuild the NSEC/NSEC3 record for the origin as we no
5284 * longer have any private records.
5287 CHECK(dns_nsec3_addnsec3s(signing
->db
, version
, origin
,
5288 minimum
, ISC_FALSE
, diff
));
5289 CHECK(updatesecure(signing
->db
, version
, origin
, minimum
,
5294 if (dns_rdataset_isassociated(&rdataset
))
5295 dns_rdataset_disassociate(&rdataset
);
5297 dns_db_detachnode(signing
->db
, &node
);
5302 * If 'active' is set then we are not done with the chain yet so only
5303 * delete the nsec3param record which indicates a full chain exists
5307 fixup_nsec3param(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_nsec3chain_t
*chain
,
5308 isc_boolean_t active
, dns_rdatatype_t privatetype
,
5311 dns_dbnode_t
*node
= NULL
;
5312 dns_name_t
*name
= dns_db_origin(db
);
5313 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5314 dns_rdataset_t rdataset
;
5315 dns_rdata_nsec3param_t nsec3param
;
5316 isc_result_t result
;
5317 isc_buffer_t buffer
;
5318 unsigned char parambuf
[DNS_NSEC3PARAM_BUFFERSIZE
];
5321 dns_rdataset_init(&rdataset
);
5323 result
= dns_db_getoriginnode(db
, &node
);
5324 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
5325 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec3param
,
5326 0, 0, &rdataset
, NULL
);
5327 if (result
== ISC_R_NOTFOUND
)
5329 if (result
!= ISC_R_SUCCESS
)
5333 * Preserve the existing ttl.
5338 * Delete all NSEC3PARAM records which match that in nsec3chain.
5340 for (result
= dns_rdataset_first(&rdataset
);
5341 result
== ISC_R_SUCCESS
;
5342 result
= dns_rdataset_next(&rdataset
)) {
5344 dns_rdataset_current(&rdataset
, &rdata
);
5345 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
5347 if (nsec3param
.hash
!= chain
->nsec3param
.hash
||
5348 (active
&& nsec3param
.flags
!= 0) ||
5349 nsec3param
.iterations
!= chain
->nsec3param
.iterations
||
5350 nsec3param
.salt_length
!= chain
->nsec3param
.salt_length
||
5351 memcmp(nsec3param
.salt
, chain
->nsec3param
.salt
,
5352 nsec3param
.salt_length
)) {
5353 dns_rdata_reset(&rdata
);
5357 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
,
5358 name
, rdataset
.ttl
, &rdata
));
5359 dns_rdata_reset(&rdata
);
5361 if (result
!= ISC_R_NOMORE
)
5364 dns_rdataset_disassociate(&rdataset
);
5371 * Delete all private records which match that in nsec3chain.
5373 result
= dns_db_findrdataset(db
, node
, ver
, privatetype
,
5374 0, 0, &rdataset
, NULL
);
5375 if (result
== ISC_R_NOTFOUND
)
5377 if (result
!= ISC_R_SUCCESS
)
5380 for (result
= dns_rdataset_first(&rdataset
);
5381 result
== ISC_R_SUCCESS
;
5382 result
= dns_rdataset_next(&rdataset
)) {
5383 dns_rdata_t
private = DNS_RDATA_INIT
;
5384 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
5386 dns_rdataset_current(&rdataset
, &private);
5387 if (!dns_nsec3param_fromprivate(&private, &rdata
,
5390 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
5392 if (nsec3param
.hash
!= chain
->nsec3param
.hash
||
5393 nsec3param
.iterations
!= chain
->nsec3param
.iterations
||
5394 nsec3param
.salt_length
!= chain
->nsec3param
.salt_length
||
5395 memcmp(nsec3param
.salt
, chain
->nsec3param
.salt
,
5396 nsec3param
.salt_length
)) {
5397 dns_rdata_reset(&rdata
);
5401 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
,
5402 name
, rdataset
.ttl
, &private));
5403 dns_rdata_reset(&rdata
);
5405 if (result
!= ISC_R_NOMORE
)
5409 if ((chain
->nsec3param
.flags
& DNS_NSEC3FLAG_REMOVE
) != 0) {
5410 result
= ISC_R_SUCCESS
;
5415 * Add a NSEC3PARAM record which matches that in nsec3chain but
5416 * with all flags bits cleared.
5418 * Note: we do not clear chain->nsec3param.flags as this change
5421 isc_buffer_init(&buffer
, ¶mbuf
, sizeof(parambuf
));
5422 CHECK(dns_rdata_fromstruct(&rdata
, dns_db_class(db
),
5423 dns_rdatatype_nsec3param
,
5424 &chain
->nsec3param
, &buffer
));
5425 rdata
.data
[1] = 0; /* Clear flag bits. */
5426 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_ADD
, name
, ttl
, &rdata
));
5429 dns_db_detachnode(db
, &node
);
5430 if (dns_rdataset_isassociated(&rdataset
))
5431 dns_rdataset_disassociate(&rdataset
);
5436 delete_nsec(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_dbnode_t
*node
,
5437 dns_name_t
*name
, dns_diff_t
*diff
)
5439 dns_rdataset_t rdataset
;
5440 isc_result_t result
;
5442 dns_rdataset_init(&rdataset
);
5444 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec
,
5445 0, 0, &rdataset
, NULL
);
5446 if (result
== ISC_R_NOTFOUND
)
5447 return (ISC_R_SUCCESS
);
5448 if (result
!= ISC_R_SUCCESS
)
5450 for (result
= dns_rdataset_first(&rdataset
);
5451 result
== ISC_R_SUCCESS
;
5452 result
= dns_rdataset_next(&rdataset
)) {
5453 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5455 dns_rdataset_current(&rdataset
, &rdata
);
5456 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
, name
,
5457 rdataset
.ttl
, &rdata
));
5459 if (result
== ISC_R_NOMORE
)
5460 result
= ISC_R_SUCCESS
;
5462 dns_rdataset_disassociate(&rdataset
);
5467 deletematchingnsec3(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_dbnode_t
*node
,
5468 dns_name_t
*name
, const dns_rdata_nsec3param_t
*param
,
5471 dns_rdataset_t rdataset
;
5472 dns_rdata_nsec3_t nsec3
;
5473 isc_result_t result
;
5475 dns_rdataset_init(&rdataset
);
5476 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec3
,
5477 0, 0, &rdataset
, NULL
);
5478 if (result
== ISC_R_NOTFOUND
)
5479 return (ISC_R_SUCCESS
);
5480 if (result
!= ISC_R_SUCCESS
)
5483 for (result
= dns_rdataset_first(&rdataset
);
5484 result
== ISC_R_SUCCESS
;
5485 result
= dns_rdataset_next(&rdataset
)) {
5486 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5488 dns_rdataset_current(&rdataset
, &rdata
);
5489 CHECK(dns_rdata_tostruct(&rdata
, &nsec3
, NULL
));
5490 if (nsec3
.hash
!= param
->hash
||
5491 nsec3
.iterations
!= param
->iterations
||
5492 nsec3
.salt_length
!= param
->salt_length
||
5493 memcmp(nsec3
.salt
, param
->salt
, nsec3
.salt_length
))
5495 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
, name
,
5496 rdataset
.ttl
, &rdata
));
5498 if (result
== ISC_R_NOMORE
)
5499 result
= ISC_R_SUCCESS
;
5501 dns_rdataset_disassociate(&rdataset
);
5506 need_nsec_chain(dns_db_t
*db
, dns_dbversion_t
*ver
,
5507 const dns_rdata_nsec3param_t
*param
,
5508 isc_boolean_t
*answer
)
5510 dns_dbnode_t
*node
= NULL
;
5511 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5512 dns_rdata_nsec3param_t myparam
;
5513 dns_rdataset_t rdataset
;
5514 isc_result_t result
;
5516 *answer
= ISC_FALSE
;
5518 result
= dns_db_getoriginnode(db
, &node
);
5519 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
5521 dns_rdataset_init(&rdataset
);
5523 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec
,
5524 0, 0, &rdataset
, NULL
);
5525 if (result
== ISC_R_SUCCESS
) {
5526 dns_rdataset_disassociate(&rdataset
);
5527 dns_db_detachnode(db
, &node
);
5530 if (result
!= ISC_R_NOTFOUND
) {
5531 dns_db_detachnode(db
, &node
);
5535 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec3param
,
5536 0, 0, &rdataset
, NULL
);
5537 if (result
== ISC_R_NOTFOUND
) {
5539 dns_db_detachnode(db
, &node
);
5540 return (ISC_R_SUCCESS
);
5542 if (result
!= ISC_R_SUCCESS
) {
5543 dns_db_detachnode(db
, &node
);
5547 for (result
= dns_rdataset_first(&rdataset
);
5548 result
== ISC_R_SUCCESS
;
5549 result
= dns_rdataset_next(&rdataset
)) {
5550 dns_rdataset_current(&rdataset
, &rdata
);
5551 CHECK(dns_rdata_tostruct(&rdata
, &myparam
, NULL
));
5552 dns_rdata_reset(&rdata
);
5554 * Ignore any NSEC3PARAM removals.
5556 if (NSEC3REMOVE(myparam
.flags
))
5559 * Ignore the chain that we are in the process of deleting.
5561 if (myparam
.hash
== param
->hash
&&
5562 myparam
.iterations
== param
->iterations
&&
5563 myparam
.salt_length
== param
->salt_length
&&
5564 !memcmp(myparam
.salt
, param
->salt
, myparam
.salt_length
))
5567 * Found an active NSEC3 chain.
5571 if (result
== ISC_R_NOMORE
) {
5573 result
= ISC_R_SUCCESS
;
5577 if (dns_rdataset_isassociated(&rdataset
))
5578 dns_rdataset_disassociate(&rdataset
);
5579 dns_db_detachnode(db
, &node
);
5584 update_sigs(dns_diff_t
*diff
, dns_db_t
*db
, dns_dbversion_t
*version
,
5585 dst_key_t
*zone_keys
[], unsigned int nkeys
, dns_zone_t
*zone
,
5586 isc_stdtime_t inception
, isc_stdtime_t expire
, isc_stdtime_t now
,
5587 isc_boolean_t check_ksk
, isc_boolean_t keyset_kskonly
,
5588 dns_diff_t
*sig_diff
)
5590 dns_difftuple_t
*tuple
;
5591 isc_result_t result
;
5593 for (tuple
= ISC_LIST_HEAD(diff
->tuples
);
5595 tuple
= ISC_LIST_HEAD(diff
->tuples
)) {
5596 result
= del_sigs(zone
, db
, version
, &tuple
->name
,
5597 tuple
->rdata
.type
, sig_diff
,
5598 zone_keys
, nkeys
, now
);
5599 if (result
!= ISC_R_SUCCESS
) {
5600 dns_zone_log(zone
, ISC_LOG_ERROR
,
5601 "update_sigs:del_sigs -> %s\n",
5602 dns_result_totext(result
));
5605 result
= add_sigs(db
, version
, &tuple
->name
,
5606 tuple
->rdata
.type
, sig_diff
,
5607 zone_keys
, nkeys
, zone
->mctx
, inception
,
5608 expire
, check_ksk
, keyset_kskonly
);
5609 if (result
!= ISC_R_SUCCESS
) {
5610 dns_zone_log(zone
, ISC_LOG_ERROR
,
5611 "update_sigs:add_sigs -> %s\n",
5612 dns_result_totext(result
));
5617 dns_difftuple_t
*next
= ISC_LIST_NEXT(tuple
, link
);
5618 while (next
!= NULL
&&
5619 (tuple
->rdata
.type
!= next
->rdata
.type
||
5620 !dns_name_equal(&tuple
->name
, &next
->name
)))
5621 next
= ISC_LIST_NEXT(next
, link
);
5622 ISC_LIST_UNLINK(diff
->tuples
, tuple
, link
);
5623 dns_diff_appendminimal(sig_diff
, &tuple
);
5624 INSIST(tuple
== NULL
);
5626 } while (tuple
!= NULL
);
5628 return (ISC_R_SUCCESS
);
5632 * Incrementally build and sign a new NSEC3 chain using the parameters
5636 zone_nsec3chain(dns_zone_t
*zone
) {
5637 dns_db_t
*db
= NULL
;
5638 dns_dbnode_t
*node
= NULL
;
5639 dns_dbversion_t
*version
= NULL
;
5640 dns_diff_t sig_diff
;
5641 dns_diff_t nsec_diff
;
5642 dns_diff_t nsec3_diff
;
5643 dns_diff_t param_diff
;
5644 dns_fixedname_t fixed
;
5645 dns_fixedname_t nextfixed
;
5646 dns_name_t
*name
, *nextname
;
5647 dns_rdataset_t rdataset
;
5648 dns_nsec3chain_t
*nsec3chain
= NULL
, *nextnsec3chain
;
5649 dns_nsec3chainlist_t cleanup
;
5650 dst_key_t
*zone_keys
[MAXZONEKEYS
];
5651 isc_int32_t signatures
;
5652 isc_boolean_t check_ksk
, keyset_kskonly
, is_ksk
;
5653 isc_boolean_t delegation
;
5654 isc_boolean_t first
;
5655 isc_result_t result
;
5656 isc_stdtime_t now
, inception
, soaexpire
, expire
, stop
;
5657 isc_uint32_t jitter
;
5659 unsigned int nkeys
= 0;
5661 isc_boolean_t unsecure
= ISC_FALSE
;
5662 isc_boolean_t seen_soa
, seen_ns
, seen_dname
, seen_ds
;
5663 isc_boolean_t seen_nsec
, seen_nsec3
, seen_rr
;
5664 dns_rdatasetiter_t
*iterator
= NULL
;
5665 isc_boolean_t buildnsecchain
;
5666 isc_boolean_t updatensec
= ISC_FALSE
;
5667 dns_rdatatype_t privatetype
= zone
->privatetype
;
5669 dns_rdataset_init(&rdataset
);
5670 dns_fixedname_init(&fixed
);
5671 name
= dns_fixedname_name(&fixed
);
5672 dns_fixedname_init(&nextfixed
);
5673 nextname
= dns_fixedname_name(&nextfixed
);
5674 dns_diff_init(zone
->mctx
, ¶m_diff
);
5675 dns_diff_init(zone
->mctx
, &nsec3_diff
);
5676 dns_diff_init(zone
->mctx
, &nsec_diff
);
5677 dns_diff_init(zone
->mctx
, &sig_diff
);
5678 sig_diff
.resign
= zone
->sigresigninginterval
;
5679 ISC_LIST_INIT(cleanup
);
5682 * Updates are disabled. Pause for 5 minutes.
5684 if (zone
->update_disabled
) {
5685 result
= ISC_R_FAILURE
;
5689 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
5690 dns_db_attach(zone
->db
, &db
);
5691 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
5693 result
= dns_db_newversion(db
, &version
);
5694 if (result
!= ISC_R_SUCCESS
) {
5695 dns_zone_log(zone
, ISC_LOG_ERROR
,
5696 "zone_nsec3chain:dns_db_newversion -> %s\n",
5697 dns_result_totext(result
));
5701 result
= find_zone_keys(zone
, db
, version
, zone
->mctx
,
5702 MAXZONEKEYS
, zone_keys
, &nkeys
);
5703 if (result
!= ISC_R_SUCCESS
) {
5704 dns_zone_log(zone
, ISC_LOG_ERROR
,
5705 "zone_nsec3chain:find_zone_keys -> %s\n",
5706 dns_result_totext(result
));
5710 isc_stdtime_get(&now
);
5711 inception
= now
- 3600; /* Allow for clock skew. */
5712 soaexpire
= now
+ dns_zone_getsigvalidityinterval(zone
);
5715 * Spread out signatures over time if they happen to be
5716 * clumped. We don't do this for each add_sigs() call as
5717 * we still want some clustering to occur.
5719 isc_random_get(&jitter
);
5720 expire
= soaexpire
- jitter
% 3600;
5723 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
5724 keyset_kskonly
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
);
5727 * We keep pulling nodes off each iterator in turn until
5728 * we have no more nodes to pull off or we reach the limits
5731 nodes
= zone
->nodes
;
5732 signatures
= zone
->signatures
;
5734 nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
5738 if (nsec3chain
!= NULL
)
5739 nsec3chain
->save_delete_nsec
= nsec3chain
->delete_nsec
;
5741 * Generate new NSEC3 chains first.
5743 while (nsec3chain
!= NULL
&& nodes
-- > 0 && signatures
> 0) {
5745 nextnsec3chain
= ISC_LIST_NEXT(nsec3chain
, link
);
5747 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
5748 if (nsec3chain
->done
|| nsec3chain
->db
!= zone
->db
) {
5749 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
, link
);
5750 ISC_LIST_APPEND(cleanup
, nsec3chain
, link
);
5752 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
5754 if (ISC_LIST_TAIL(cleanup
) == nsec3chain
)
5758 * Possible future db.
5760 if (nsec3chain
->db
!= db
) {
5764 if (NSEC3REMOVE(nsec3chain
->nsec3param
.flags
))
5768 delegation
= ISC_FALSE
;
5769 dns_dbiterator_current(nsec3chain
->dbiterator
, &node
, name
);
5771 if (nsec3chain
->delete_nsec
) {
5772 delegation
= ISC_FALSE
;
5773 dns_dbiterator_pause(nsec3chain
->dbiterator
);
5774 CHECK(delete_nsec(db
, version
, node
, name
, &nsec_diff
));
5778 * On the first pass we need to check if the current node
5779 * has not been obscured.
5781 delegation
= ISC_FALSE
;
5782 unsecure
= ISC_FALSE
;
5784 dns_fixedname_t ffound
;
5786 dns_fixedname_init(&ffound
);
5787 found
= dns_fixedname_name(&ffound
);
5788 result
= dns_db_find(db
, name
, version
,
5790 DNS_DBFIND_NOWILD
, 0, NULL
, found
,
5792 if ((result
== DNS_R_DELEGATION
||
5793 result
== DNS_R_DNAME
) &&
5794 !dns_name_equal(name
, found
)) {
5796 * Remember the obscuring name so that
5797 * we skip all obscured names.
5799 dns_name_copy(found
, name
, NULL
);
5800 delegation
= ISC_TRUE
;
5806 * Check to see if this is a bottom of zone node.
5808 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
5809 if (result
== ISC_R_NOTFOUND
) /* Empty node? */
5811 if (result
!= ISC_R_SUCCESS
)
5814 seen_soa
= seen_ns
= seen_dname
= seen_ds
= seen_nsec
=
5816 for (result
= dns_rdatasetiter_first(iterator
);
5817 result
== ISC_R_SUCCESS
;
5818 result
= dns_rdatasetiter_next(iterator
)) {
5819 dns_rdatasetiter_current(iterator
, &rdataset
);
5820 INSIST(rdataset
.type
!= dns_rdatatype_nsec3
);
5821 if (rdataset
.type
== dns_rdatatype_soa
)
5822 seen_soa
= ISC_TRUE
;
5823 else if (rdataset
.type
== dns_rdatatype_ns
)
5825 else if (rdataset
.type
== dns_rdatatype_dname
)
5826 seen_dname
= ISC_TRUE
;
5827 else if (rdataset
.type
== dns_rdatatype_ds
)
5829 else if (rdataset
.type
== dns_rdatatype_nsec
)
5830 seen_nsec
= ISC_TRUE
;
5831 dns_rdataset_disassociate(&rdataset
);
5833 dns_rdatasetiter_destroy(&iterator
);
5835 * Is there a NSEC chain than needs to be cleaned up?
5838 nsec3chain
->seen_nsec
= ISC_TRUE
;
5839 if (seen_ns
&& !seen_soa
&& !seen_ds
)
5840 unsecure
= ISC_TRUE
;
5841 if ((seen_ns
&& !seen_soa
) || seen_dname
)
5842 delegation
= ISC_TRUE
;
5847 dns_dbiterator_pause(nsec3chain
->dbiterator
);
5848 result
= dns_nsec3_addnsec3(db
, version
, name
,
5849 &nsec3chain
->nsec3param
,
5850 zone
->minimum
, unsecure
,
5852 if (result
!= ISC_R_SUCCESS
) {
5853 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
5854 "dns_nsec3_addnsec3 -> %s\n",
5855 dns_result_totext(result
));
5860 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
5861 * two signatures. Additionally there will, in general, be
5862 * two signature generated below.
5864 * If we are only changing the optout flag the cost is half
5865 * that of the cost of generating a completely new chain.
5870 * Go onto next node.
5874 dns_db_detachnode(db
, &node
);
5876 result
= dns_dbiterator_next(nsec3chain
->dbiterator
);
5878 if (result
== ISC_R_NOMORE
&& nsec3chain
->delete_nsec
) {
5879 CHECK(fixup_nsec3param(db
, version
, nsec3chain
,
5880 ISC_FALSE
, privatetype
,
5883 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
,
5886 ISC_LIST_APPEND(cleanup
, nsec3chain
, link
);
5889 if (result
== ISC_R_NOMORE
) {
5890 dns_dbiterator_pause(nsec3chain
->dbiterator
);
5891 if (nsec3chain
->seen_nsec
) {
5892 CHECK(fixup_nsec3param(db
, version
,
5897 nsec3chain
->delete_nsec
= ISC_TRUE
;
5900 CHECK(fixup_nsec3param(db
, version
, nsec3chain
,
5901 ISC_FALSE
, privatetype
,
5904 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
,
5907 ISC_LIST_APPEND(cleanup
, nsec3chain
, link
);
5909 } else if (result
!= ISC_R_SUCCESS
) {
5910 dns_zone_log(zone
, ISC_LOG_ERROR
,
5912 "dns_dbiterator_next -> %s\n",
5913 dns_result_totext(result
));
5915 } else if (delegation
) {
5916 dns_dbiterator_current(nsec3chain
->dbiterator
,
5918 dns_db_detachnode(db
, &node
);
5919 if (!dns_name_issubdomain(nextname
, name
))
5927 CHECK(dns_dbiterator_first(nsec3chain
->dbiterator
));
5932 dns_dbiterator_pause(nsec3chain
->dbiterator
);
5933 nsec3chain
= nextnsec3chain
;
5935 if (nsec3chain
!= NULL
)
5936 nsec3chain
->save_delete_nsec
= nsec3chain
->delete_nsec
;
5943 nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
5946 buildnsecchain
= ISC_FALSE
;
5947 while (nsec3chain
!= NULL
&& nodes
-- > 0 && signatures
> 0) {
5949 nextnsec3chain
= ISC_LIST_NEXT(nsec3chain
, link
);
5952 if (nsec3chain
->db
!= db
)
5953 goto next_removechain
;
5955 if (!NSEC3REMOVE(nsec3chain
->nsec3param
.flags
))
5956 goto next_removechain
;
5959 * Work out if we need to build a NSEC chain as a consequence
5960 * of removing this NSEC3 chain.
5962 if (first
&& !updatensec
&&
5963 (nsec3chain
->nsec3param
.flags
& DNS_NSEC3FLAG_NONSEC
) == 0) {
5964 result
= need_nsec_chain(db
, version
,
5965 &nsec3chain
->nsec3param
,
5967 if (result
!= ISC_R_SUCCESS
) {
5968 dns_zone_log(zone
, ISC_LOG_ERROR
,
5970 "need_nsec_chain -> %s\n",
5971 dns_result_totext(result
));
5977 dns_zone_log(zone
, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
5978 "buildnsecchain = %u\n", buildnsecchain
);
5980 dns_dbiterator_current(nsec3chain
->dbiterator
, &node
, name
);
5981 delegation
= ISC_FALSE
;
5983 if (!buildnsecchain
) {
5985 * Delete the NSECPARAM record that matches this chain.
5988 result
= fixup_nsec3param(db
, version
,
5990 ISC_TRUE
, privatetype
,
5992 if (result
!= ISC_R_SUCCESS
) {
5993 dns_zone_log(zone
, ISC_LOG_ERROR
,
5995 "fixup_nsec3param -> %s\n",
5996 dns_result_totext(result
));
6002 * Delete the NSEC3 records.
6004 result
= deletematchingnsec3(db
, version
, node
, name
,
6005 &nsec3chain
->nsec3param
,
6007 if (result
!= ISC_R_SUCCESS
) {
6008 dns_zone_log(zone
, ISC_LOG_ERROR
,
6010 "deletematchingnsec3 -> %s\n",
6011 dns_result_totext(result
));
6014 goto next_removenode
;
6018 dns_fixedname_t ffound
;
6020 dns_fixedname_init(&ffound
);
6021 found
= dns_fixedname_name(&ffound
);
6022 result
= dns_db_find(db
, name
, version
,
6024 DNS_DBFIND_NOWILD
, 0, NULL
, found
,
6026 if ((result
== DNS_R_DELEGATION
||
6027 result
== DNS_R_DNAME
) &&
6028 !dns_name_equal(name
, found
)) {
6030 * Remember the obscuring name so that
6031 * we skip all obscured names.
6033 dns_name_copy(found
, name
, NULL
);
6034 delegation
= ISC_TRUE
;
6035 goto next_removenode
;
6040 * Check to see if this is a bottom of zone node.
6042 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
6043 if (result
== ISC_R_NOTFOUND
) /* Empty node? */
6044 goto next_removenode
;
6045 if (result
!= ISC_R_SUCCESS
)
6048 seen_soa
= seen_ns
= seen_dname
= seen_nsec3
= seen_nsec
=
6049 seen_rr
= ISC_FALSE
;
6050 for (result
= dns_rdatasetiter_first(iterator
);
6051 result
== ISC_R_SUCCESS
;
6052 result
= dns_rdatasetiter_next(iterator
)) {
6053 dns_rdatasetiter_current(iterator
, &rdataset
);
6054 if (rdataset
.type
== dns_rdatatype_soa
)
6055 seen_soa
= ISC_TRUE
;
6056 else if (rdataset
.type
== dns_rdatatype_ns
)
6058 else if (rdataset
.type
== dns_rdatatype_dname
)
6059 seen_dname
= ISC_TRUE
;
6060 else if (rdataset
.type
== dns_rdatatype_nsec
)
6061 seen_nsec
= ISC_TRUE
;
6062 else if (rdataset
.type
== dns_rdatatype_nsec3
)
6063 seen_nsec3
= ISC_TRUE
;
6064 if (rdataset
.type
!= dns_rdatatype_rrsig
)
6066 dns_rdataset_disassociate(&rdataset
);
6068 dns_rdatasetiter_destroy(&iterator
);
6070 if (!seen_rr
|| seen_nsec3
|| seen_nsec
)
6071 goto next_removenode
;
6072 if ((seen_ns
&& !seen_soa
) || seen_dname
)
6073 delegation
= ISC_TRUE
;
6076 * Add a NSEC record except at the origin.
6078 if (!dns_name_equal(name
, dns_db_origin(db
))) {
6079 dns_dbiterator_pause(nsec3chain
->dbiterator
);
6080 CHECK(add_nsec(db
, version
, name
, node
, zone
->minimum
,
6081 delegation
, &nsec_diff
));
6086 dns_db_detachnode(db
, &node
);
6088 result
= dns_dbiterator_next(nsec3chain
->dbiterator
);
6089 if (result
== ISC_R_NOMORE
&& buildnsecchain
) {
6091 * The NSEC chain should now be built.
6092 * We can now remove the NSEC3 chain.
6094 updatensec
= ISC_TRUE
;
6095 goto same_removechain
;
6097 if (result
== ISC_R_NOMORE
) {
6099 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
,
6102 ISC_LIST_APPEND(cleanup
, nsec3chain
, link
);
6103 dns_dbiterator_pause(nsec3chain
->dbiterator
);
6104 result
= fixup_nsec3param(db
, version
,
6105 nsec3chain
, ISC_FALSE
,
6108 if (result
!= ISC_R_SUCCESS
) {
6109 dns_zone_log(zone
, ISC_LOG_ERROR
,
6111 "fixup_nsec3param -> %s\n",
6112 dns_result_totext(result
));
6115 goto next_removechain
;
6116 } else if (result
!= ISC_R_SUCCESS
) {
6117 dns_zone_log(zone
, ISC_LOG_ERROR
,
6119 "dns_dbiterator_next -> %s\n",
6120 dns_result_totext(result
));
6122 } else if (delegation
) {
6123 dns_dbiterator_current(nsec3chain
->dbiterator
,
6125 dns_db_detachnode(db
, &node
);
6126 if (!dns_name_issubdomain(nextname
, name
))
6134 CHECK(dns_dbiterator_first(nsec3chain
->dbiterator
));
6135 buildnsecchain
= ISC_FALSE
;
6140 dns_dbiterator_pause(nsec3chain
->dbiterator
);
6141 nsec3chain
= nextnsec3chain
;
6146 * We may need to update the NSEC/NSEC3 records for the zone apex.
6148 if (!ISC_LIST_EMPTY(param_diff
.tuples
)) {
6149 isc_boolean_t rebuild_nsec
= ISC_FALSE
,
6150 rebuild_nsec3
= ISC_FALSE
;
6151 result
= dns_db_getoriginnode(db
, &node
);
6152 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
6153 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
6154 for (result
= dns_rdatasetiter_first(iterator
);
6155 result
== ISC_R_SUCCESS
;
6156 result
= dns_rdatasetiter_next(iterator
)) {
6157 dns_rdatasetiter_current(iterator
, &rdataset
);
6158 if (rdataset
.type
== dns_rdatatype_nsec
)
6159 rebuild_nsec
= ISC_TRUE
;
6160 if (rdataset
.type
== dns_rdatatype_nsec3param
)
6161 rebuild_nsec3
= ISC_TRUE
;
6162 dns_rdataset_disassociate(&rdataset
);
6164 dns_rdatasetiter_destroy(&iterator
);
6165 dns_db_detachnode(db
, &node
);
6168 result
= updatesecure(db
, version
, &zone
->origin
,
6169 zone
->minimum
, ISC_TRUE
,
6171 if (result
!= ISC_R_SUCCESS
) {
6172 dns_zone_log(zone
, ISC_LOG_ERROR
,
6174 "updatesecure -> %s\n",
6175 dns_result_totext(result
));
6179 if (rebuild_nsec3
) {
6180 result
= dns_nsec3_addnsec3s(db
, version
,
6182 zone
->minimum
, ISC_FALSE
,
6184 if (result
!= ISC_R_SUCCESS
) {
6185 dns_zone_log(zone
, ISC_LOG_ERROR
,
6187 "dns_nsec3_addnsec3s -> %s\n",
6188 dns_result_totext(result
));
6195 * Add / update signatures for the NSEC3 records.
6197 result
= update_sigs(&nsec3_diff
, db
, version
, zone_keys
,
6198 nkeys
, zone
, inception
, expire
, now
,
6199 check_ksk
, keyset_kskonly
, &sig_diff
);
6200 if (result
!= ISC_R_SUCCESS
) {
6201 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
6202 "update_sigs -> %s\n", dns_result_totext(result
));
6207 * We have changed the NSEC3PARAM or private RRsets
6208 * above so we need to update the signatures.
6210 result
= update_sigs(¶m_diff
, db
, version
, zone_keys
,
6211 nkeys
, zone
, inception
, expire
, now
,
6212 check_ksk
, keyset_kskonly
, &sig_diff
);
6213 if (result
!= ISC_R_SUCCESS
) {
6214 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
6215 "update_sigs -> %s\n", dns_result_totext(result
));
6220 result
= updatesecure(db
, version
, &zone
->origin
,
6221 zone
->minimum
, ISC_FALSE
, &nsec_diff
);
6222 if (result
!= ISC_R_SUCCESS
) {
6223 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
6224 "updatesecure -> %s\n",
6225 dns_result_totext(result
));
6230 result
= update_sigs(&nsec_diff
, db
, version
, zone_keys
,
6231 nkeys
, zone
, inception
, expire
, now
,
6232 check_ksk
, keyset_kskonly
, &sig_diff
);
6233 if (result
!= ISC_R_SUCCESS
) {
6234 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
6235 "update_sigs -> %s\n", dns_result_totext(result
));
6240 * If we made no effective changes to the zone then we can just
6241 * cleanup otherwise we need to increment the serial.
6243 if (ISC_LIST_HEAD(sig_diff
.tuples
) == NULL
)
6246 result
= del_sigs(zone
, db
, version
, &zone
->origin
, dns_rdatatype_soa
,
6247 &sig_diff
, zone_keys
, nkeys
, now
);
6248 if (result
!= ISC_R_SUCCESS
) {
6249 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
6250 "del_sigs -> %s\n", dns_result_totext(result
));
6254 result
= increment_soa_serial(db
, version
, &sig_diff
, zone
->mctx
);
6255 if (result
!= ISC_R_SUCCESS
) {
6256 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
6257 "increment_soa_serial -> %s\n",
6258 dns_result_totext(result
));
6262 result
= add_sigs(db
, version
, &zone
->origin
, dns_rdatatype_soa
,
6263 &sig_diff
, zone_keys
, nkeys
, zone
->mctx
, inception
,
6264 soaexpire
, check_ksk
, keyset_kskonly
);
6265 if (result
!= ISC_R_SUCCESS
) {
6266 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
6267 "add_sigs -> %s\n", dns_result_totext(result
));
6271 /* Write changes to journal file. */
6272 zone_journal(zone
, &sig_diff
, "zone_nsec3chain");
6275 zone_needdump(zone
, DNS_DUMP_DELAY
);
6280 * Pause all iterators so that dns_db_closeversion() can succeed.
6283 for (nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
6285 nsec3chain
= ISC_LIST_NEXT(nsec3chain
, link
))
6286 dns_dbiterator_pause(nsec3chain
->dbiterator
);
6290 * Everything has succeeded. Commit the changes.
6292 dns_db_closeversion(db
, &version
, ISC_TRUE
);
6295 * Everything succeeded so we can clean these up now.
6297 nsec3chain
= ISC_LIST_HEAD(cleanup
);
6298 while (nsec3chain
!= NULL
) {
6299 ISC_LIST_UNLINK(cleanup
, nsec3chain
, link
);
6300 dns_db_detach(&nsec3chain
->db
);
6301 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
6302 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
6303 nsec3chain
= ISC_LIST_HEAD(cleanup
);
6306 set_resigntime(zone
);
6309 if (result
!= ISC_R_SUCCESS
)
6310 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain: %s\n",
6311 dns_result_totext(result
));
6313 * On error roll back the current nsec3chain.
6315 if (result
!= ISC_R_SUCCESS
&& nsec3chain
!= NULL
) {
6316 if (nsec3chain
->done
) {
6317 dns_db_detach(&nsec3chain
->db
);
6318 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
6319 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
6321 result
= dns_dbiterator_first(nsec3chain
->dbiterator
);
6322 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
6323 dns_dbiterator_pause(nsec3chain
->dbiterator
);
6324 nsec3chain
->delete_nsec
= nsec3chain
->save_delete_nsec
;
6329 * Rollback the cleanup list.
6331 nsec3chain
= ISC_LIST_TAIL(cleanup
);
6332 while (nsec3chain
!= NULL
) {
6333 ISC_LIST_UNLINK(cleanup
, nsec3chain
, link
);
6334 if (nsec3chain
->done
) {
6335 dns_db_detach(&nsec3chain
->db
);
6336 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
6337 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
6340 ISC_LIST_PREPEND(zone
->nsec3chain
, nsec3chain
, link
);
6342 result
= dns_dbiterator_first(nsec3chain
->dbiterator
);
6343 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
6344 dns_dbiterator_pause(nsec3chain
->dbiterator
);
6345 nsec3chain
->delete_nsec
= nsec3chain
->save_delete_nsec
;
6347 nsec3chain
= ISC_LIST_TAIL(cleanup
);
6351 for (nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
6353 nsec3chain
= ISC_LIST_NEXT(nsec3chain
, link
))
6354 dns_dbiterator_pause(nsec3chain
->dbiterator
);
6357 dns_diff_clear(¶m_diff
);
6358 dns_diff_clear(&nsec3_diff
);
6359 dns_diff_clear(&nsec_diff
);
6360 dns_diff_clear(&sig_diff
);
6362 if (iterator
!= NULL
)
6363 dns_rdatasetiter_destroy(&iterator
);
6365 for (i
= 0; i
< nkeys
; i
++)
6366 dst_key_free(&zone_keys
[i
]);
6369 dns_db_detachnode(db
, &node
);
6370 if (version
!= NULL
) {
6371 dns_db_closeversion(db
, &version
, ISC_FALSE
);
6373 } else if (db
!= NULL
)
6377 if (ISC_LIST_HEAD(zone
->nsec3chain
) != NULL
) {
6379 if (zone
->update_disabled
|| result
!= ISC_R_SUCCESS
)
6380 isc_interval_set(&i
, 60, 0); /* 1 minute */
6382 isc_interval_set(&i
, 0, 10000000); /* 10 ms */
6383 isc_time_nowplusinterval(&zone
->nsec3chaintime
, &i
);
6385 isc_time_settoepoch(&zone
->nsec3chaintime
);
6390 del_sig(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
6391 dns_dbnode_t
*node
, unsigned int nkeys
, dns_secalg_t algorithm
,
6392 isc_uint16_t keyid
, dns_diff_t
*diff
)
6394 dns_rdata_rrsig_t rrsig
;
6395 dns_rdataset_t rdataset
;
6396 dns_rdatasetiter_t
*iterator
= NULL
;
6397 isc_result_t result
;
6399 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
6400 if (result
!= ISC_R_SUCCESS
) {
6401 if (result
== ISC_R_NOTFOUND
)
6402 result
= ISC_R_SUCCESS
;
6406 dns_rdataset_init(&rdataset
);
6407 for (result
= dns_rdatasetiter_first(iterator
);
6408 result
== ISC_R_SUCCESS
;
6409 result
= dns_rdatasetiter_next(iterator
)) {
6410 dns_rdatasetiter_current(iterator
, &rdataset
);
6411 if (nkeys
== 0 && rdataset
.type
== dns_rdatatype_nsec
) {
6412 for (result
= dns_rdataset_first(&rdataset
);
6413 result
== ISC_R_SUCCESS
;
6414 result
= dns_rdataset_next(&rdataset
)) {
6415 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6416 dns_rdataset_current(&rdataset
, &rdata
);
6417 CHECK(update_one_rr(db
, version
, diff
,
6418 DNS_DIFFOP_DEL
, name
,
6419 rdataset
.ttl
, &rdata
));
6421 if (result
!= ISC_R_NOMORE
)
6423 dns_rdataset_disassociate(&rdataset
);
6426 if (rdataset
.type
!= dns_rdatatype_rrsig
) {
6427 dns_rdataset_disassociate(&rdataset
);
6430 for (result
= dns_rdataset_first(&rdataset
);
6431 result
== ISC_R_SUCCESS
;
6432 result
= dns_rdataset_next(&rdataset
)) {
6433 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6434 dns_rdataset_current(&rdataset
, &rdata
);
6435 CHECK(dns_rdata_tostruct(&rdata
, &rrsig
, NULL
));
6436 if (rrsig
.algorithm
!= algorithm
||
6437 rrsig
.keyid
!= keyid
)
6439 CHECK(update_one_rr(db
, version
, diff
,
6440 DNS_DIFFOP_DEL
, name
,
6441 rdataset
.ttl
, &rdata
));
6443 dns_rdataset_disassociate(&rdataset
);
6444 if (result
!= ISC_R_NOMORE
)
6447 if (result
== ISC_R_NOMORE
)
6448 result
= ISC_R_SUCCESS
;
6450 if (dns_rdataset_isassociated(&rdataset
))
6451 dns_rdataset_disassociate(&rdataset
);
6452 dns_rdatasetiter_destroy(&iterator
);
6457 * Incrementally sign the zone using the keys requested.
6458 * Builds the NSEC chain if required.
6461 zone_sign(dns_zone_t
*zone
) {
6462 dns_db_t
*db
= NULL
;
6463 dns_dbnode_t
*node
= NULL
;
6464 dns_dbversion_t
*version
= NULL
;
6465 dns_diff_t sig_diff
;
6466 dns_diff_t post_diff
;
6467 dns_fixedname_t fixed
;
6468 dns_fixedname_t nextfixed
;
6469 dns_name_t
*name
, *nextname
;
6470 dns_rdataset_t rdataset
;
6471 dns_signing_t
*signing
, *nextsigning
;
6472 dns_signinglist_t cleanup
;
6473 dst_key_t
*zone_keys
[MAXZONEKEYS
];
6474 isc_int32_t signatures
;
6475 isc_boolean_t check_ksk
, keyset_kskonly
, is_ksk
;
6476 isc_boolean_t commit
= ISC_FALSE
;
6477 isc_boolean_t delegation
;
6478 isc_boolean_t build_nsec
= ISC_FALSE
;
6479 isc_boolean_t build_nsec3
= ISC_FALSE
;
6480 isc_boolean_t first
;
6481 isc_result_t result
;
6482 isc_stdtime_t now
, inception
, soaexpire
, expire
, stop
;
6483 isc_uint32_t jitter
;
6485 unsigned int nkeys
= 0;
6487 isc_boolean_t was_ksk
;
6490 dns_rdataset_init(&rdataset
);
6491 dns_fixedname_init(&fixed
);
6492 name
= dns_fixedname_name(&fixed
);
6493 dns_fixedname_init(&nextfixed
);
6494 nextname
= dns_fixedname_name(&nextfixed
);
6495 dns_diff_init(zone
->mctx
, &sig_diff
);
6496 sig_diff
.resign
= zone
->sigresigninginterval
;
6497 dns_diff_init(zone
->mctx
, &post_diff
);
6498 ISC_LIST_INIT(cleanup
);
6501 * Updates are disabled. Pause for 5 minutes.
6503 if (zone
->update_disabled
) {
6504 result
= ISC_R_FAILURE
;
6508 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
6509 dns_db_attach(zone
->db
, &db
);
6510 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
6512 result
= dns_db_newversion(db
, &version
);
6513 if (result
!= ISC_R_SUCCESS
) {
6514 dns_zone_log(zone
, ISC_LOG_ERROR
,
6515 "zone_sign:dns_db_newversion -> %s\n",
6516 dns_result_totext(result
));
6520 result
= find_zone_keys(zone
, db
, version
, zone
->mctx
,
6521 MAXZONEKEYS
, zone_keys
, &nkeys
);
6522 if (result
!= ISC_R_SUCCESS
) {
6523 dns_zone_log(zone
, ISC_LOG_ERROR
,
6524 "zone_sign:find_zone_keys -> %s\n",
6525 dns_result_totext(result
));
6529 isc_stdtime_get(&now
);
6530 inception
= now
- 3600; /* Allow for clock skew. */
6531 soaexpire
= now
+ dns_zone_getsigvalidityinterval(zone
);
6534 * Spread out signatures over time if they happen to be
6535 * clumped. We don't do this for each add_sigs() call as
6536 * we still want some clustering to occur.
6538 isc_random_get(&jitter
);
6539 expire
= soaexpire
- jitter
% 3600;
6543 * We keep pulling nodes off each iterator in turn until
6544 * we have no more nodes to pull off or we reach the limits
6547 nodes
= zone
->nodes
;
6548 signatures
= zone
->signatures
;
6549 signing
= ISC_LIST_HEAD(zone
->signing
);
6552 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
6553 keyset_kskonly
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
);
6555 /* Determine which type of chain to build */
6556 CHECK(dns_private_chains(db
, version
, zone
->privatetype
,
6557 &build_nsec
, &build_nsec3
));
6559 while (signing
!= NULL
&& nodes
-- > 0 && signatures
> 0) {
6560 nextsigning
= ISC_LIST_NEXT(signing
, link
);
6562 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
6563 if (signing
->done
|| signing
->db
!= zone
->db
) {
6565 * The zone has been reloaded. We will have
6566 * created new signings as part of the reload
6567 * process so we can destroy this one.
6569 ISC_LIST_UNLINK(zone
->signing
, signing
, link
);
6570 ISC_LIST_APPEND(cleanup
, signing
, link
);
6571 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
6574 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
6576 if (signing
->db
!= db
)
6579 delegation
= ISC_FALSE
;
6581 was_ksk
= ISC_FALSE
;
6583 if (first
&& signing
->delete) {
6585 * Remove the key we are deleting from consideration.
6587 for (i
= 0, j
= 0; i
< nkeys
; i
++) {
6589 * Find the key we want to remove.
6591 if (ALG(zone_keys
[i
]) == signing
->algorithm
&&
6592 dst_key_id(zone_keys
[i
]) == signing
->keyid
)
6594 if (KSK(zone_keys
[i
]))
6595 dst_key_free(&zone_keys
[i
]);
6598 zone_keys
[j
] = zone_keys
[i
];
6604 dns_dbiterator_current(signing
->dbiterator
, &node
, name
);
6606 if (signing
->delete) {
6607 dns_dbiterator_pause(signing
->dbiterator
);
6608 CHECK(del_sig(db
, version
, name
, node
, nkeys
,
6609 signing
->algorithm
, signing
->keyid
,
6614 * On the first pass we need to check if the current node
6615 * has not been obscured.
6618 dns_fixedname_t ffound
;
6620 dns_fixedname_init(&ffound
);
6621 found
= dns_fixedname_name(&ffound
);
6622 result
= dns_db_find(db
, name
, version
,
6624 DNS_DBFIND_NOWILD
, 0, NULL
, found
,
6626 if ((result
== DNS_R_DELEGATION
||
6627 result
== DNS_R_DNAME
) &&
6628 !dns_name_equal(name
, found
)) {
6630 * Remember the obscuring name so that
6631 * we skip all obscured names.
6633 dns_name_copy(found
, name
, NULL
);
6634 delegation
= ISC_TRUE
;
6642 dns_dbiterator_pause(signing
->dbiterator
);
6643 for (i
= 0; i
< nkeys
; i
++) {
6644 isc_boolean_t both
= ISC_FALSE
;
6647 * Find the keys we want to sign with.
6649 if (!dst_key_isprivate(zone_keys
[i
]))
6653 * When adding look for the specific key.
6655 if (!signing
->delete &&
6656 (dst_key_alg(zone_keys
[i
]) != signing
->algorithm
||
6657 dst_key_id(zone_keys
[i
]) != signing
->keyid
))
6661 * When deleting make sure we are properly signed
6662 * with the algorithm that was being removed.
6664 if (signing
->delete &&
6665 ALG(zone_keys
[i
]) != signing
->algorithm
)
6669 * Do we do KSK processing?
6671 if (check_ksk
&& !REVOKE(zone_keys
[i
])) {
6672 isc_boolean_t have_ksk
, have_nonksk
;
6673 if (KSK(zone_keys
[i
])) {
6674 have_ksk
= ISC_TRUE
;
6675 have_nonksk
= ISC_FALSE
;
6677 have_ksk
= ISC_FALSE
;
6678 have_nonksk
= ISC_TRUE
;
6680 for (j
= 0; j
< nkeys
; j
++) {
6682 ALG(zone_keys
[i
]) !=
6685 if (REVOKE(zone_keys
[j
]))
6687 if (KSK(zone_keys
[j
]))
6688 have_ksk
= ISC_TRUE
;
6690 have_nonksk
= ISC_TRUE
;
6691 both
= have_ksk
&& have_nonksk
;
6696 if (both
|| REVOKE(zone_keys
[i
]))
6697 is_ksk
= KSK(zone_keys
[i
]);
6701 CHECK(sign_a_node(db
, name
, node
, version
, build_nsec3
,
6702 build_nsec
, zone_keys
[i
], inception
,
6703 expire
, zone
->minimum
, is_ksk
,
6704 ISC_TF(both
&& keyset_kskonly
),
6705 &delegation
, &sig_diff
,
6706 &signatures
, zone
->mctx
));
6708 * If we are adding we are done. Look for other keys
6709 * of the same algorithm if deleting.
6711 if (!signing
->delete)
6716 * Go onto next node.
6720 dns_db_detachnode(db
, &node
);
6722 result
= dns_dbiterator_next(signing
->dbiterator
);
6723 if (result
== ISC_R_NOMORE
) {
6724 ISC_LIST_UNLINK(zone
->signing
, signing
, link
);
6725 ISC_LIST_APPEND(cleanup
, signing
, link
);
6726 dns_dbiterator_pause(signing
->dbiterator
);
6727 if (nkeys
!= 0 && build_nsec
) {
6729 * We have finished regenerating the
6730 * zone with a zone signing key.
6731 * The NSEC chain is now complete and
6732 * there is a full set of signatures
6733 * for the zone. We can now clear the
6734 * OPT bit from the NSEC record.
6736 result
= updatesecure(db
, version
,
6741 if (result
!= ISC_R_SUCCESS
) {
6744 "updatesecure -> %s\n",
6745 dns_result_totext(result
));
6749 result
= updatesignwithkey(zone
, signing
,
6754 if (result
!= ISC_R_SUCCESS
) {
6755 dns_zone_log(zone
, ISC_LOG_ERROR
,
6756 "updatesignwithkey "
6758 dns_result_totext(result
));
6761 build_nsec
= ISC_FALSE
;
6763 } else if (result
!= ISC_R_SUCCESS
) {
6764 dns_zone_log(zone
, ISC_LOG_ERROR
,
6765 "zone_sign:dns_dbiterator_next -> %s\n",
6766 dns_result_totext(result
));
6768 } else if (delegation
) {
6769 dns_dbiterator_current(signing
->dbiterator
,
6771 dns_db_detachnode(db
, &node
);
6772 if (!dns_name_issubdomain(nextname
, name
))
6780 dns_dbiterator_pause(signing
->dbiterator
);
6781 signing
= nextsigning
;
6785 if (ISC_LIST_HEAD(post_diff
.tuples
) != NULL
) {
6786 result
= update_sigs(&post_diff
, db
, version
, zone_keys
,
6787 nkeys
, zone
, inception
, expire
, now
,
6788 check_ksk
, keyset_kskonly
, &sig_diff
);
6789 if (result
!= ISC_R_SUCCESS
) {
6790 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_sign:"
6791 "update_sigs -> %s\n",
6792 dns_result_totext(result
));
6798 * Have we changed anything?
6800 if (ISC_LIST_HEAD(sig_diff
.tuples
) == NULL
) {
6801 result
= ISC_R_SUCCESS
;
6807 result
= del_sigs(zone
, db
, version
, &zone
->origin
, dns_rdatatype_soa
,
6808 &sig_diff
, zone_keys
, nkeys
, now
);
6809 if (result
!= ISC_R_SUCCESS
) {
6810 dns_zone_log(zone
, ISC_LOG_ERROR
,
6811 "zone_sign:del_sigs -> %s\n",
6812 dns_result_totext(result
));
6816 result
= increment_soa_serial(db
, version
, &sig_diff
, zone
->mctx
);
6817 if (result
!= ISC_R_SUCCESS
) {
6818 dns_zone_log(zone
, ISC_LOG_ERROR
,
6819 "zone_sign:increment_soa_serial -> %s\n",
6820 dns_result_totext(result
));
6825 * Generate maximum life time signatures so that the above loop
6826 * termination is sensible.
6828 result
= add_sigs(db
, version
, &zone
->origin
, dns_rdatatype_soa
,
6829 &sig_diff
, zone_keys
, nkeys
, zone
->mctx
, inception
,
6830 soaexpire
, check_ksk
, keyset_kskonly
);
6831 if (result
!= ISC_R_SUCCESS
) {
6832 dns_zone_log(zone
, ISC_LOG_ERROR
,
6833 "zone_sign:add_sigs -> %s\n",
6834 dns_result_totext(result
));
6839 * Write changes to journal file.
6841 zone_journal(zone
, &sig_diff
, "zone_sign");
6844 * Notify slaves, if appropriate.
6847 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOTIFYRESIGN
)) {
6849 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOTIFYRESIGN
);
6851 zone_notify(zone
, &when
);
6856 * Pause all iterators so that dns_db_closeversion() can succeed.
6858 for (signing
= ISC_LIST_HEAD(zone
->signing
);
6860 signing
= ISC_LIST_NEXT(signing
, link
))
6861 dns_dbiterator_pause(signing
->dbiterator
);
6863 for (signing
= ISC_LIST_HEAD(cleanup
);
6865 signing
= ISC_LIST_NEXT(signing
, link
))
6866 dns_dbiterator_pause(signing
->dbiterator
);
6869 * Everything has succeeded. Commit the changes.
6871 dns_db_closeversion(db
, &version
, commit
);
6874 * Everything succeeded so we can clean these up now.
6876 signing
= ISC_LIST_HEAD(cleanup
);
6877 while (signing
!= NULL
) {
6878 ISC_LIST_UNLINK(cleanup
, signing
, link
);
6879 dns_db_detach(&signing
->db
);
6880 dns_dbiterator_destroy(&signing
->dbiterator
);
6881 isc_mem_put(zone
->mctx
, signing
, sizeof *signing
);
6882 signing
= ISC_LIST_HEAD(cleanup
);
6885 set_resigntime(zone
);
6889 zone_needdump(zone
, DNS_DUMP_DELAY
);
6895 * Rollback the cleanup list.
6897 signing
= ISC_LIST_HEAD(cleanup
);
6898 while (signing
!= NULL
) {
6899 ISC_LIST_UNLINK(cleanup
, signing
, link
);
6900 ISC_LIST_PREPEND(zone
->signing
, signing
, link
);
6901 dns_dbiterator_first(signing
->dbiterator
);
6902 dns_dbiterator_pause(signing
->dbiterator
);
6903 signing
= ISC_LIST_HEAD(cleanup
);
6906 for (signing
= ISC_LIST_HEAD(zone
->signing
);
6908 signing
= ISC_LIST_NEXT(signing
, link
))
6909 dns_dbiterator_pause(signing
->dbiterator
);
6911 dns_diff_clear(&sig_diff
);
6913 for (i
= 0; i
< nkeys
; i
++)
6914 dst_key_free(&zone_keys
[i
]);
6917 dns_db_detachnode(db
, &node
);
6919 if (version
!= NULL
) {
6920 dns_db_closeversion(db
, &version
, ISC_FALSE
);
6922 } else if (db
!= NULL
)
6925 if (ISC_LIST_HEAD(zone
->signing
) != NULL
) {
6927 if (zone
->update_disabled
|| result
!= ISC_R_SUCCESS
)
6928 isc_interval_set(&i
, 60, 0); /* 1 minute */
6930 isc_interval_set(&i
, 0, 10000000); /* 10 ms */
6931 isc_time_nowplusinterval(&zone
->signingtime
, &i
);
6933 isc_time_settoepoch(&zone
->signingtime
);
6937 normalize_key(dns_rdata_t
*rr
, dns_rdata_t
*target
,
6938 unsigned char *data
, int size
) {
6939 dns_rdata_dnskey_t dnskey
;
6940 dns_rdata_keydata_t keydata
;
6943 dns_rdata_reset(target
);
6944 isc_buffer_init(&buf
, data
, size
);
6947 case dns_rdatatype_dnskey
:
6948 dns_rdata_tostruct(rr
, &dnskey
, NULL
);
6949 dnskey
.flags
&= ~DNS_KEYFLAG_REVOKE
;
6950 dns_rdata_fromstruct(target
, rr
->rdclass
, dns_rdatatype_dnskey
,
6953 case dns_rdatatype_keydata
:
6954 dns_rdata_tostruct(rr
, &keydata
, NULL
);
6955 dns_keydata_todnskey(&keydata
, &dnskey
, NULL
);
6956 dns_rdata_fromstruct(target
, rr
->rdclass
, dns_rdatatype_dnskey
,
6965 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
6966 * a KEYDATA rdataset from the key zone.
6968 * 'rr' contains either a DNSKEY record, or a KEYDATA record
6970 * After normalizing keys to the same format (DNSKEY, with revoke bit
6971 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
6972 * 'rdset', or ISC_FALSE if not.
6975 static isc_boolean_t
6976 matchkey(dns_rdataset_t
*rdset
, dns_rdata_t
*rr
) {
6977 unsigned char data1
[4096], data2
[4096];
6978 dns_rdata_t rdata
, rdata1
, rdata2
;
6979 isc_result_t result
;
6981 dns_rdata_init(&rdata
);
6982 dns_rdata_init(&rdata1
);
6983 dns_rdata_init(&rdata2
);
6985 normalize_key(rr
, &rdata1
, data1
, sizeof(data1
));
6987 for (result
= dns_rdataset_first(rdset
);
6988 result
== ISC_R_SUCCESS
;
6989 result
= dns_rdataset_next(rdset
)) {
6990 dns_rdata_reset(&rdata
);
6991 dns_rdataset_current(rdset
, &rdata
);
6992 normalize_key(&rdata
, &rdata2
, data2
, sizeof(data2
));
6993 if (dns_rdata_compare(&rdata1
, &rdata2
) == 0)
7001 * Calculate the refresh interval for a keydata zone, per
7002 * RFC5011: MAX(1 hr,
7005 * 1/2 * RRSigExpirationInterval))
7007 static inline isc_stdtime_t
7008 refresh_time(dns_keyfetch_t
*kfetch
) {
7009 isc_result_t result
;
7011 dns_rdataset_t
*rdset
;
7012 dns_rdata_t sigrr
= DNS_RDATA_INIT
;
7013 dns_rdata_sig_t sig
;
7016 isc_stdtime_get(&now
);
7018 if (dns_rdataset_isassociated(&kfetch
->dnskeysigset
))
7019 rdset
= &kfetch
->dnskeysigset
;
7021 return (now
+ HOUR
);
7023 result
= dns_rdataset_first(rdset
);
7024 if (result
!= ISC_R_SUCCESS
)
7025 return (now
+ HOUR
);
7027 dns_rdataset_current(rdset
, &sigrr
);
7028 result
= dns_rdata_tostruct(&sigrr
, &sig
, NULL
);
7030 t
= sig
.originalttl
/ 2;
7032 if (isc_serial_gt(sig
.timeexpire
, now
)) {
7033 isc_uint32_t exp
= (sig
.timeexpire
- now
) / 2;
7048 * This routine is called when no changes are needed in a KEYDATA
7049 * record except to simply update the refresh timer. Caller should
7053 minimal_update(dns_keyfetch_t
*kfetch
, dns_dbversion_t
*ver
, dns_diff_t
*diff
) {
7054 isc_result_t result
;
7056 unsigned char key_buf
[4096];
7057 dns_rdata_t rdata
= DNS_RDATA_INIT
;
7058 dns_rdata_keydata_t keydata
;
7060 dns_zone_t
*zone
= kfetch
->zone
;
7063 name
= dns_fixedname_name(&kfetch
->name
);
7064 isc_stdtime_get(&now
);
7066 for (result
= dns_rdataset_first(&kfetch
->keydataset
);
7067 result
== ISC_R_SUCCESS
;
7068 result
= dns_rdataset_next(&kfetch
->keydataset
)) {
7069 dns_rdata_reset(&rdata
);
7070 dns_rdataset_current(&kfetch
->keydataset
, &rdata
);
7072 /* Delete old version */
7073 CHECK(update_one_rr(kfetch
->db
, ver
, diff
, DNS_DIFFOP_DEL
,
7076 /* Update refresh timer */
7077 CHECK(dns_rdata_tostruct(&rdata
, &keydata
, NULL
));
7078 keydata
.refresh
= refresh_time(kfetch
);
7079 set_refreshkeytimer(zone
, &keydata
, now
);
7081 dns_rdata_reset(&rdata
);
7082 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
7083 CHECK(dns_rdata_fromstruct(&rdata
,
7084 zone
->rdclass
, dns_rdatatype_keydata
,
7087 /* Insert updated version */
7088 CHECK(update_one_rr(kfetch
->db
, ver
, diff
, DNS_DIFFOP_ADD
,
7091 result
= ISC_R_SUCCESS
;
7097 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
7099 static isc_boolean_t
7100 revocable(dns_keyfetch_t
*kfetch
, dns_rdata_keydata_t
*keydata
) {
7101 isc_result_t result
;
7102 dns_name_t
*keyname
;
7104 dns_rdata_t sigrr
= DNS_RDATA_INIT
;
7105 dns_rdata_t rr
= DNS_RDATA_INIT
;
7106 dns_rdata_rrsig_t sig
;
7107 dns_rdata_dnskey_t dnskey
;
7108 dst_key_t
*dstkey
= NULL
;
7109 unsigned char key_buf
[4096];
7111 isc_boolean_t answer
= ISC_FALSE
;
7113 REQUIRE(kfetch
!= NULL
&& keydata
!= NULL
);
7114 REQUIRE(dns_rdataset_isassociated(&kfetch
->dnskeysigset
));
7116 keyname
= dns_fixedname_name(&kfetch
->name
);
7117 mctx
= kfetch
->zone
->view
->mctx
;
7119 /* Generate a key from keydata */
7120 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
7121 dns_keydata_todnskey(keydata
, &dnskey
, NULL
);
7122 dns_rdata_fromstruct(&rr
, keydata
->common
.rdclass
, dns_rdatatype_dnskey
,
7124 result
= dns_dnssec_keyfromrdata(keyname
, &rr
, mctx
, &dstkey
);
7125 if (result
!= ISC_R_SUCCESS
)
7128 /* See if that key generated any of the signatures */
7129 for (result
= dns_rdataset_first(&kfetch
->dnskeysigset
);
7130 result
== ISC_R_SUCCESS
;
7131 result
= dns_rdataset_next(&kfetch
->dnskeysigset
)) {
7132 dns_fixedname_t fixed
;
7133 dns_fixedname_init(&fixed
);
7135 dns_rdata_reset(&sigrr
);
7136 dns_rdataset_current(&kfetch
->dnskeysigset
, &sigrr
);
7137 result
= dns_rdata_tostruct(&sigrr
, &sig
, NULL
);
7138 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
7140 if (dst_key_alg(dstkey
) == sig
.algorithm
&&
7141 (dst_key_id(dstkey
) == sig
.keyid
||
7142 (sig
.algorithm
!= 1 && sig
.keyid
==
7143 ((dst_key_id(dstkey
) + 128) & 0xffff)))) {
7144 result
= dns_dnssec_verify2(keyname
,
7146 dstkey
, ISC_FALSE
, mctx
, &sigrr
,
7147 dns_fixedname_name(&fixed
));
7149 dns_zone_log(kfetch
->zone
, ISC_LOG_DEBUG(3),
7150 "Confirm revoked DNSKEY is self-signed: "
7151 "%s", dns_result_totext(result
));
7153 if (result
== ISC_R_SUCCESS
) {
7160 dst_key_free(&dstkey
);
7165 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
7166 * anchors are being managed; scan the keyset, and update the key zone and the
7167 * local trust anchors according to RFC5011.
7170 keyfetch_done(isc_task_t
*task
, isc_event_t
*event
) {
7171 isc_result_t result
, eresult
;
7172 dns_fetchevent_t
*devent
;
7173 dns_keyfetch_t
*kfetch
;
7175 dns_keytable_t
*secroots
= NULL
;
7176 dns_dbversion_t
*ver
= NULL
;
7178 isc_boolean_t changed
= ISC_FALSE
;
7179 isc_boolean_t alldone
= ISC_FALSE
;
7180 dns_name_t
*keyname
;
7181 dns_rdata_t sigrr
= DNS_RDATA_INIT
;
7182 dns_rdata_t dnskeyrr
= DNS_RDATA_INIT
;
7183 dns_rdata_t keydatarr
= DNS_RDATA_INIT
;
7184 dns_rdata_rrsig_t sig
;
7185 dns_rdata_dnskey_t dnskey
;
7186 dns_rdata_keydata_t keydata
;
7187 isc_boolean_t initializing
;
7188 char namebuf
[DNS_NAME_FORMATSIZE
];
7189 unsigned char key_buf
[4096];
7196 INSIST(event
!= NULL
&& event
->ev_type
== DNS_EVENT_FETCHDONE
);
7197 INSIST(event
->ev_arg
!= NULL
);
7199 kfetch
= event
->ev_arg
;
7200 zone
= kfetch
->zone
;
7201 keyname
= dns_fixedname_name(&kfetch
->name
);
7203 devent
= (dns_fetchevent_t
*) event
;
7204 eresult
= devent
->result
;
7206 /* Free resources which are not of interest */
7207 if (devent
->node
!= NULL
)
7208 dns_db_detachnode(devent
->db
, &devent
->node
);
7209 if (devent
->db
!= NULL
)
7210 dns_db_detach(&devent
->db
);
7211 isc_event_free(&event
);
7212 dns_resolver_destroyfetch(&kfetch
->fetch
);
7214 isc_stdtime_get(&now
);
7215 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
7217 result
= dns_view_getsecroots(zone
->view
, &secroots
);
7218 INSIST(result
== ISC_R_SUCCESS
);
7221 dns_db_newversion(kfetch
->db
, &ver
);
7222 dns_diff_init(zone
->mctx
, &diff
);
7225 if (eresult
!= ISC_R_SUCCESS
||
7226 !dns_rdataset_isassociated(&kfetch
->dnskeyset
)) {
7227 dns_zone_log(zone
, ISC_LOG_WARNING
,
7228 "Unable to fetch DNSKEY set "
7229 "'%s': %s", namebuf
, dns_result_totext(eresult
));
7230 CHECK(minimal_update(kfetch
, ver
, &diff
));
7234 /* No RRSIGs found */
7235 if (!dns_rdataset_isassociated(&kfetch
->dnskeysigset
)) {
7236 dns_zone_log(zone
, ISC_LOG_WARNING
,
7237 "No DNSKEY RRSIGs found for "
7238 "'%s': %s", namebuf
, dns_result_totext(eresult
));
7239 CHECK(minimal_update(kfetch
, ver
, &diff
));
7244 * Validate the dnskeyset against the current trusted keys.
7245 * (Note, if a key has been revoked and isn't RSAMD5, then
7246 * its key ID will have changed.)
7248 for (result
= dns_rdataset_first(&kfetch
->dnskeysigset
);
7249 result
== ISC_R_SUCCESS
;
7250 result
= dns_rdataset_next(&kfetch
->dnskeysigset
)) {
7251 dns_keynode_t
*keynode
= NULL
;
7253 dns_rdata_reset(&sigrr
);
7254 dns_rdataset_current(&kfetch
->dnskeysigset
, &sigrr
);
7255 result
= dns_rdata_tostruct(&sigrr
, &sig
, NULL
);
7256 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
7258 result
= dns_keytable_find(secroots
, keyname
, &keynode
);
7259 while (result
== ISC_R_SUCCESS
) {
7260 dns_keynode_t
*nextnode
= NULL
;
7261 dns_fixedname_t fixed
;
7262 dns_fixedname_init(&fixed
);
7264 dstkey
= dns_keynode_key(keynode
);
7265 if (dstkey
== NULL
) /* fail_secure() was called */
7268 if (dst_key_alg(dstkey
) == sig
.algorithm
&&
7269 (dst_key_id(dstkey
) == sig
.keyid
||
7270 (sig
.algorithm
!= 1 && sig
.keyid
==
7271 ((dst_key_id(dstkey
) + 128) & 0xffff)))) {
7272 result
= dns_dnssec_verify2(keyname
,
7275 zone
->view
->mctx
, &sigrr
,
7276 dns_fixedname_name(&fixed
));
7278 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
7279 "Verifying DNSKEY set for zone "
7280 "'%s': %s", namebuf
,
7281 dns_result_totext(result
));
7283 if (result
== ISC_R_SUCCESS
) {
7284 kfetch
->dnskeyset
.trust
=
7286 kfetch
->dnskeysigset
.trust
=
7288 dns_keytable_detachkeynode(secroots
,
7294 result
= dns_keytable_nextkeynode(secroots
,
7295 keynode
, &nextnode
);
7296 dns_keytable_detachkeynode(secroots
, &keynode
);
7300 if (kfetch
->dnskeyset
.trust
== dns_trust_secure
)
7304 /* Failed to validate? Let's go home. */
7305 if (kfetch
->dnskeyset
.trust
!= dns_trust_secure
) {
7306 dns_zone_log(zone
, ISC_LOG_WARNING
,
7307 "DNSKEY set for zone '%s' failed to validate",
7309 CHECK(minimal_update(kfetch
, ver
, &diff
));
7315 * First scan keydataset to find keys that are not in dnskeyset
7316 * - Missing keys which are not scheduled for removal,
7318 * - Missing keys which are scheduled for removal and
7319 * the remove hold-down timer has completed should
7320 * be removed from the key zone
7321 * - Missing keys whose acceptance timers have not yet
7322 * completed, log a warning and reset the acceptance
7323 * timer to 30 days in the future
7324 * - All keys not being removed have their refresh timers
7327 initializing
= ISC_TRUE
;
7328 for (result
= dns_rdataset_first(&kfetch
->keydataset
);
7329 result
== ISC_R_SUCCESS
;
7330 result
= dns_rdataset_next(&kfetch
->keydataset
)) {
7331 dns_rdata_reset(&keydatarr
);
7332 dns_rdataset_current(&kfetch
->keydataset
, &keydatarr
);
7333 dns_rdata_tostruct(&keydatarr
, &keydata
, NULL
);
7336 * If any keydata record has a nonzero add holddown, then
7337 * there was a pre-existing trust anchor for this domain;
7338 * that means we are *not* initializing it and shouldn't
7339 * automatically trust all the keys we find at the zone apex.
7341 initializing
= initializing
&& ISC_TF(keydata
.addhd
== 0);
7343 if (! matchkey(&kfetch
->dnskeyset
, &keydatarr
)) {
7344 isc_boolean_t deletekey
= ISC_FALSE
;
7346 if (now
< keydata
.addhd
) {
7347 dns_zone_log(zone
, ISC_LOG_WARNING
,
7348 "Pending key unexpectedly missing "
7349 "from %s; restarting acceptance "
7351 keydata
.addhd
= now
+ MONTH
;
7352 keydata
.refresh
= refresh_time(kfetch
);
7353 } else if (keydata
.addhd
== 0) {
7354 keydata
.addhd
= now
;
7355 } else if (keydata
.removehd
== 0) {
7356 dns_zone_log(zone
, ISC_LOG_WARNING
,
7357 "Active key unexpectedly missing "
7358 "from %s", namebuf
);
7359 keydata
.refresh
= now
+ HOUR
;
7360 } else if (now
> keydata
.removehd
) {
7361 deletekey
= ISC_TRUE
;
7363 keydata
.refresh
= refresh_time(kfetch
);
7366 /* Delete old version */
7367 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
7368 DNS_DIFFOP_DEL
, keyname
, 0,
7375 dns_rdata_reset(&keydatarr
);
7376 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
7377 dns_rdata_fromstruct(&keydatarr
, zone
->rdclass
,
7378 dns_rdatatype_keydata
,
7381 /* Insert updated version */
7382 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
7383 DNS_DIFFOP_ADD
, keyname
, 0,
7387 set_refreshkeytimer(zone
, &keydata
, now
);
7392 * Next scan dnskeyset:
7393 * - If new keys are found (i.e., lacking a match in keydataset)
7394 * add them to the key zone and set the acceptance timer
7395 * to 30 days in the future (or to immediately if we've
7396 * determined that we're initializing the zone for the
7398 * - Previously-known keys that have been revoked
7399 * must be scheduled for removal from the key zone (or,
7400 * if they hadn't been accepted as trust anchors yet
7401 * anyway, removed at once)
7402 * - Previously-known unrevoked keys whose acceptance timers
7403 * have completed are promoted to trust anchors
7404 * - All keys not being removed have their refresh
7407 for (result
= dns_rdataset_first(&kfetch
->dnskeyset
);
7408 result
== ISC_R_SUCCESS
;
7409 result
= dns_rdataset_next(&kfetch
->dnskeyset
)) {
7410 isc_boolean_t revoked
= ISC_FALSE
;
7411 isc_boolean_t newkey
= ISC_FALSE
;
7412 isc_boolean_t updatekey
= ISC_FALSE
;
7413 isc_boolean_t deletekey
= ISC_FALSE
;
7414 isc_boolean_t trustkey
= ISC_FALSE
;
7416 dns_rdata_reset(&dnskeyrr
);
7417 dns_rdataset_current(&kfetch
->dnskeyset
, &dnskeyrr
);
7418 dns_rdata_tostruct(&dnskeyrr
, &dnskey
, NULL
);
7421 if (!ISC_TF(dnskey
.flags
& DNS_KEYFLAG_KSK
))
7424 revoked
= ISC_TF(dnskey
.flags
& DNS_KEYFLAG_REVOKE
);
7426 if (matchkey(&kfetch
->keydataset
, &dnskeyrr
)) {
7427 dns_rdata_reset(&keydatarr
);
7428 dns_rdataset_current(&kfetch
->keydataset
, &keydatarr
);
7429 dns_rdata_tostruct(&keydatarr
, &keydata
, NULL
);
7432 if (keydata
.addhd
> now
) {
7434 * Key wasn't trusted yet, and now
7435 * it's been revoked? Just remove it
7437 deletekey
= ISC_TRUE
;
7438 } else if (keydata
.removehd
== 0) {
7440 * Newly revoked key? Make sure
7443 if(! revocable(kfetch
, &keydata
)) {
7446 "Active key for zone "
7447 "'%s' is revoked but "
7448 "did not self-sign; "
7449 "ignoring.", namebuf
);
7453 /* Remove from secroots */
7454 untrust_key(zone
->view
->viewlist
,
7455 keyname
, zone
->mctx
,
7458 /* If initializing, delete now */
7459 if (keydata
.addhd
== 0)
7460 deletekey
= ISC_TRUE
;
7462 keydata
.removehd
= now
+ MONTH
;
7463 } else if (keydata
.removehd
< now
) {
7464 /* Scheduled for removal */
7465 deletekey
= ISC_TRUE
;
7468 if (keydata
.removehd
!= 0) {
7470 * Key isn't revoked--but it
7471 * seems it used to be.
7472 * Remove it now and add it
7473 * back as if it were a fresh key.
7475 deletekey
= ISC_TRUE
;
7477 } else if (keydata
.addhd
> now
)
7479 else if (keydata
.addhd
== 0)
7480 keydata
.addhd
= now
;
7482 if (keydata
.addhd
<= now
)
7483 trustkey
= ISC_TRUE
;
7486 if (!deletekey
&& !newkey
)
7487 updatekey
= ISC_TRUE
;
7490 * Key wasn't in the key zone but it's
7491 * revoked now anyway, so just skip it
7496 /* Key wasn't in the key zone: add it */
7500 dns_keytag_t tag
= 0;
7501 CHECK(compute_tag(keyname
, &dnskey
,
7503 dns_zone_log(zone
, ISC_LOG_WARNING
,
7504 "Initializing automatic trust "
7505 "anchor management for zone '%s'; "
7506 "DNSKEY ID %d is now trusted, "
7507 "waiving the normal 30-day "
7510 trustkey
= ISC_TRUE
;
7514 /* Delete old version */
7515 if (deletekey
|| !newkey
) {
7516 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
7517 DNS_DIFFOP_DEL
, keyname
, 0,
7523 /* Set refresh timer */
7524 keydata
.refresh
= refresh_time(kfetch
);
7525 dns_rdata_reset(&keydatarr
);
7526 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
7527 dns_rdata_fromstruct(&keydatarr
, zone
->rdclass
,
7528 dns_rdatatype_keydata
,
7531 /* Insert updated version */
7532 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
7533 DNS_DIFFOP_ADD
, keyname
, 0,
7536 } else if (newkey
) {
7537 /* Convert DNSKEY to KEYDATA */
7538 dns_rdata_tostruct(&dnskeyrr
, &dnskey
, NULL
);
7539 dns_keydata_fromdnskey(&keydata
, &dnskey
, 0, 0, 0,
7541 keydata
.addhd
= initializing
? now
: now
+ MONTH
;
7542 keydata
.refresh
= refresh_time(kfetch
);
7543 dns_rdata_reset(&keydatarr
);
7544 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
7545 dns_rdata_fromstruct(&keydatarr
, zone
->rdclass
,
7546 dns_rdatatype_keydata
,
7549 /* Insert into key zone */
7550 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
7551 DNS_DIFFOP_ADD
, keyname
, 0,
7557 /* Trust this key in all views */
7558 dns_rdata_tostruct(&dnskeyrr
, &dnskey
, NULL
);
7559 trust_key(zone
->view
->viewlist
, keyname
, &dnskey
,
7564 set_refreshkeytimer(zone
, &keydata
, now
);
7568 * RFC5011 says, "A trust point that has all of its trust anchors
7569 * revoked is considered deleted and is treated as if the trust
7570 * point was never configured." But if someone revoked their
7571 * active key before the standby was trusted, that would mean the
7572 * zone would suddenly be nonsecured. We avoid this by checking to
7573 * see if there's pending keydata. If so, we put a null key in
7574 * the security roots; then all queries to the zone will fail.
7577 fail_secure(zone
->view
->viewlist
, keyname
);
7580 zone
->refreshkeycount
--;
7581 alldone
= ISC_TF(zone
->refreshkeycount
== 0);
7584 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
);
7585 zone_needdump(zone
, 30);
7589 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESHING
);
7593 /* Write changes to journal file. */
7595 result
= increment_soa_serial(kfetch
->db
, ver
, &diff
,
7597 if (result
== ISC_R_SUCCESS
)
7598 zone_journal(zone
, &diff
, "keyfetch_done");
7601 dns_diff_clear(&diff
);
7602 dns_db_closeversion(kfetch
->db
, &ver
, changed
);
7603 dns_db_detach(&kfetch
->db
);
7605 if (dns_rdataset_isassociated(&kfetch
->keydataset
))
7606 dns_rdataset_disassociate(&kfetch
->keydataset
);
7607 if (dns_rdataset_isassociated(&kfetch
->dnskeyset
))
7608 dns_rdataset_disassociate(&kfetch
->dnskeyset
);
7609 if (dns_rdataset_isassociated(&kfetch
->dnskeysigset
))
7610 dns_rdataset_disassociate(&kfetch
->dnskeysigset
);
7612 dns_name_free(keyname
, zone
->mctx
);
7613 isc_mem_put(zone
->mctx
, kfetch
, sizeof(dns_keyfetch_t
));
7615 if (secroots
!= NULL
)
7616 dns_keytable_detach(&secroots
);
7620 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
7621 * records from the zone apex.
7624 zone_refreshkeys(dns_zone_t
*zone
) {
7625 const char me
[] = "zone_refreshkeys";
7626 isc_result_t result
;
7627 dns_rriterator_t rrit
;
7628 dns_db_t
*db
= NULL
;
7629 dns_dbversion_t
*ver
= NULL
;
7631 dns_rdata_t rdata
= DNS_RDATA_INIT
;
7632 dns_rdata_keydata_t kd
;
7636 REQUIRE(zone
->db
!= NULL
);
7638 isc_stdtime_get(&now
);
7640 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
7641 dns_db_attach(zone
->db
, &db
);
7642 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
7645 dns_db_newversion(db
, &ver
);
7646 dns_diff_init(zone
->mctx
, &diff
);
7648 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESHING
);
7650 dns_rriterator_init(&rrit
, db
, ver
, 0);
7651 for (result
= dns_rriterator_first(&rrit
);
7652 result
== ISC_R_SUCCESS
;
7653 result
= dns_rriterator_nextrrset(&rrit
)) {
7654 isc_stdtime_t timer
= 0xffffffff;
7655 dns_keyfetch_t
*kfetch
;
7656 dns_rdataset_t
*kdset
;
7657 dns_name_t
*name
= NULL
;
7660 dns_rriterator_current(&rrit
, &name
, &ttl
, &kdset
, NULL
);
7661 if (!dns_rdataset_isassociated(kdset
))
7664 if (kdset
->type
!= dns_rdatatype_keydata
)
7668 * Scan the stored keys looking for ones that need
7669 * removal or refreshing
7671 for (result
= dns_rdataset_first(kdset
);
7672 result
== ISC_R_SUCCESS
;
7673 result
= dns_rdataset_next(kdset
)) {
7674 dns_rdata_reset(&rdata
);
7675 dns_rdataset_current(kdset
, &rdata
);
7676 result
= dns_rdata_tostruct(&rdata
, &kd
, NULL
);
7677 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
7679 /* Removal timer expired? */
7680 if (kd
.removehd
!= 0 && kd
.removehd
< now
) {
7681 CHECK(update_one_rr(db
, ver
, &diff
,
7682 DNS_DIFFOP_DEL
, name
, ttl
,
7687 /* Acceptance timer expired? */
7688 if (kd
.addhd
!= 0 && kd
.addhd
< now
)
7691 /* Or do we just need to refresh the keyset? */
7692 if (timer
> kd
.refresh
)
7699 zone
->refreshkeycount
++;
7701 kfetch
= isc_mem_get(zone
->mctx
, sizeof(dns_keyfetch_t
));
7702 kfetch
->zone
= zone
;
7703 dns_fixedname_init(&kfetch
->name
);
7704 dns_name_dup(name
, zone
->mctx
,
7705 dns_fixedname_name(&kfetch
->name
));
7706 dns_rdataset_init(&kfetch
->dnskeyset
);
7707 dns_rdataset_init(&kfetch
->dnskeysigset
);
7708 dns_rdataset_init(&kfetch
->keydataset
);
7709 dns_rdataset_clone(kdset
, &kfetch
->keydataset
);
7711 dns_db_attach(db
, &kfetch
->db
);
7712 kfetch
->fetch
= NULL
;
7714 dns_resolver_createfetch(zone
->view
->resolver
,
7715 dns_fixedname_name(&kfetch
->name
),
7716 dns_rdatatype_dnskey
,
7718 DNS_FETCHOPT_NOVALIDATE
,
7719 zone
->task
, keyfetch_done
, kfetch
,
7721 &kfetch
->dnskeysigset
,
7727 dns_rriterator_destroy(&rrit
);
7728 dns_diff_clear(&diff
);
7729 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
7734 zone_maintenance(dns_zone_t
*zone
) {
7735 const char me
[] = "zone_maintenance";
7737 isc_result_t result
;
7738 isc_boolean_t dumping
;
7740 REQUIRE(DNS_ZONE_VALID(zone
));
7744 * Configuring the view of this zone may have
7745 * failed, for example because the config file
7746 * had a syntax error. In that case, the view
7747 * adb or resolver, and we had better not try
7748 * to do maintenance on it.
7750 if (zone
->view
== NULL
|| zone
->view
->adb
== NULL
)
7758 switch (zone
->type
) {
7759 case dns_zone_slave
:
7762 if (isc_time_compare(&now
, &zone
->expiretime
) >= 0 &&
7763 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
7765 zone
->refreshtime
= now
;
7776 switch (zone
->type
) {
7777 case dns_zone_slave
:
7779 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
) &&
7780 isc_time_compare(&now
, &zone
->refreshtime
) >= 0)
7781 dns_zone_refresh(zone
);
7788 * Do we need to consolidate the backing store?
7790 switch (zone
->type
) {
7791 case dns_zone_master
:
7792 case dns_zone_slave
:
7795 if (zone
->masterfile
!= NULL
&&
7796 isc_time_compare(&now
, &zone
->dumptime
) >= 0 &&
7797 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
7798 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
)) {
7799 dumping
= was_dumping(zone
);
7804 result
= zone_dump(zone
, ISC_TRUE
); /* task locked */
7805 if (result
!= ISC_R_SUCCESS
)
7806 dns_zone_log(zone
, ISC_LOG_WARNING
,
7808 dns_result_totext(result
));
7816 * Do we need to refresh keys?
7818 switch (zone
->type
) {
7820 if (isc_time_compare(&now
, &zone
->refreshkeytime
) >= 0 &&
7821 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
7822 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESHING
))
7823 zone_refreshkeys(zone
);
7825 case dns_zone_master
:
7826 if (DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_MAINTAIN
) &&
7827 !isc_time_isepoch(&zone
->refreshkeytime
) &&
7828 isc_time_compare(&now
, &zone
->refreshkeytime
) >= 0)
7829 dns_zone_rekey(zone
);
7834 switch (zone
->type
) {
7835 case dns_zone_master
:
7836 case dns_zone_slave
:
7838 * Do we need to send out notify messages?
7840 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
) &&
7841 isc_time_compare(&now
, &zone
->notifytime
) >= 0)
7842 zone_notify(zone
, &now
);
7844 * Do we need to sign/resign some RRsets?
7846 if (!isc_time_isepoch(&zone
->signingtime
) &&
7847 isc_time_compare(&now
, &zone
->signingtime
) >= 0)
7849 else if (!isc_time_isepoch(&zone
->resigntime
) &&
7850 isc_time_compare(&now
, &zone
->resigntime
) >= 0)
7851 zone_resigninc(zone
);
7852 else if (!isc_time_isepoch(&zone
->nsec3chaintime
) &&
7853 isc_time_compare(&now
, &zone
->nsec3chaintime
) >= 0)
7854 zone_nsec3chain(zone
);
7856 * Do we need to issue a key expiry warning.
7858 if (!isc_time_isepoch(&zone
->keywarntime
) &&
7859 isc_time_compare(&now
, &zone
->keywarntime
) >= 0)
7860 set_key_expiry_warning(zone
, zone
->key_expiry
,
7861 isc_time_seconds(&now
));
7866 zone_settimer(zone
, &now
);
7870 dns_zone_markdirty(dns_zone_t
*zone
) {
7873 set_resigntime(zone
); /* XXXMPA make separate call back */
7874 zone_needdump(zone
, DNS_DUMP_DELAY
);
7879 dns_zone_expire(dns_zone_t
*zone
) {
7880 REQUIRE(DNS_ZONE_VALID(zone
));
7888 zone_expire(dns_zone_t
*zone
) {
7890 * 'zone' locked by caller.
7893 REQUIRE(LOCKED_ZONE(zone
));
7895 dns_zone_log(zone
, ISC_LOG_WARNING
, "expired");
7897 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXPIRED
);
7898 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
7899 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
7900 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
7905 dns_zone_refresh(dns_zone_t
*zone
) {
7907 isc_uint32_t oldflags
;
7909 isc_result_t result
;
7911 REQUIRE(DNS_ZONE_VALID(zone
));
7913 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
7917 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
7918 * in progress at a time.
7922 oldflags
= zone
->flags
;
7923 if (zone
->masterscnt
== 0) {
7924 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
7925 if ((oldflags
& DNS_ZONEFLG_NOMASTERS
) == 0)
7926 dns_zone_log(zone
, ISC_LOG_ERROR
,
7927 "cannot refresh: no masters");
7930 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
7931 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
7932 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
7933 if ((oldflags
& (DNS_ZONEFLG_REFRESH
|DNS_ZONEFLG_LOADING
)) != 0)
7937 * Set the next refresh time as if refresh check has failed.
7938 * Setting this to the retry time will do that. XXXMLG
7939 * If we are successful it will be reset using zone->refresh.
7941 isc_interval_set(&i
, isc_random_jitter(zone
->retry
, zone
->retry
/ 4),
7943 result
= isc_time_nowplusinterval(&zone
->refreshtime
, &i
);
7944 if (result
|= ISC_R_SUCCESS
)
7945 dns_zone_log(zone
, ISC_LOG_WARNING
,
7946 "isc_time_nowplusinterval() failed: %s",
7947 dns_result_totext(result
));
7950 * When lacking user-specified timer values from the SOA,
7951 * do exponential backoff of the retry time up to a
7952 * maximum of six hours.
7954 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HAVETIMERS
))
7955 zone
->retry
= ISC_MIN(zone
->retry
* 2, 6 * 3600);
7957 zone
->curmaster
= 0;
7958 for (j
= 0; j
< zone
->masterscnt
; j
++)
7959 zone
->mastersok
[j
] = ISC_FALSE
;
7960 /* initiate soa query */
7961 queue_soa_query(zone
);
7967 dns_zone_flush(dns_zone_t
*zone
) {
7968 isc_result_t result
= ISC_R_SUCCESS
;
7969 isc_boolean_t dumping
;
7971 REQUIRE(DNS_ZONE_VALID(zone
));
7974 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FLUSH
);
7975 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
7976 zone
->masterfile
!= NULL
) {
7977 result
= ISC_R_ALREADYRUNNING
;
7978 dumping
= was_dumping(zone
);
7983 result
= zone_dump(zone
, ISC_FALSE
); /* Unknown task. */
7988 dns_zone_dump(dns_zone_t
*zone
) {
7989 isc_result_t result
= ISC_R_ALREADYRUNNING
;
7990 isc_boolean_t dumping
;
7992 REQUIRE(DNS_ZONE_VALID(zone
));
7995 dumping
= was_dumping(zone
);
7998 result
= zone_dump(zone
, ISC_FALSE
); /* Unknown task. */
8003 zone_needdump(dns_zone_t
*zone
, unsigned int delay
) {
8004 isc_time_t dumptime
;
8008 * 'zone' locked by caller
8011 REQUIRE(DNS_ZONE_VALID(zone
));
8012 REQUIRE(LOCKED_ZONE(zone
));
8015 * Do we have a place to dump to and are we loaded?
8017 if (zone
->masterfile
== NULL
||
8018 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) == 0)
8022 /* add some noise */
8023 DNS_ZONE_JITTER_ADD(&now
, delay
, &dumptime
);
8025 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
8026 if (isc_time_isepoch(&zone
->dumptime
) ||
8027 isc_time_compare(&zone
->dumptime
, &dumptime
) > 0)
8028 zone
->dumptime
= dumptime
;
8029 if (zone
->task
!= NULL
)
8030 zone_settimer(zone
, &now
);
8034 dump_done(void *arg
, isc_result_t result
) {
8035 const char me
[] = "dump_done";
8036 dns_zone_t
*zone
= arg
;
8038 dns_dbversion_t
*version
;
8039 isc_boolean_t again
= ISC_FALSE
;
8040 isc_boolean_t compact
= ISC_FALSE
;
8041 isc_uint32_t serial
;
8042 isc_result_t tresult
;
8044 REQUIRE(DNS_ZONE_VALID(zone
));
8048 if (result
== ISC_R_SUCCESS
&& zone
->journal
!= NULL
&&
8049 zone
->journalsize
!= -1) {
8052 * We don't own these, zone->dctx must stay valid.
8054 db
= dns_dumpctx_db(zone
->dctx
);
8055 version
= dns_dumpctx_version(zone
->dctx
);
8057 tresult
= dns_db_getsoaserial(db
, version
, &serial
);
8059 * Note: we are task locked here so we can test
8062 if (tresult
== ISC_R_SUCCESS
&& zone
->xfr
== NULL
) {
8063 tresult
= dns_journal_compact(zone
->mctx
,
8070 case ISC_R_NOTFOUND
:
8071 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
8072 "dns_journal_compact: %s",
8073 dns_result_totext(tresult
));
8076 dns_zone_log(zone
, ISC_LOG_ERROR
,
8077 "dns_journal_compact failed: %s",
8078 dns_result_totext(tresult
));
8081 } else if (tresult
== ISC_R_SUCCESS
) {
8083 zone
->compact_serial
= serial
;
8088 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
8090 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
);
8091 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_CANCELED
) {
8093 * Try again in a short while.
8095 zone_needdump(zone
, DNS_DUMP_DELAY
);
8096 } else if (result
== ISC_R_SUCCESS
&&
8097 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
8098 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
8099 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
8100 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
8101 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
8102 isc_time_settoepoch(&zone
->dumptime
);
8104 } else if (result
== ISC_R_SUCCESS
)
8105 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FLUSH
);
8107 if (zone
->dctx
!= NULL
)
8108 dns_dumpctx_detach(&zone
->dctx
);
8109 zonemgr_putio(&zone
->writeio
);
8112 (void)zone_dump(zone
, ISC_FALSE
);
8113 dns_zone_idetach(&zone
);
8117 zone_dump(dns_zone_t
*zone
, isc_boolean_t compact
) {
8118 const char me
[] = "zone_dump";
8119 isc_result_t result
;
8120 dns_dbversion_t
*version
= NULL
;
8121 isc_boolean_t again
;
8122 dns_db_t
*db
= NULL
;
8123 char *masterfile
= NULL
;
8124 dns_masterformat_t masterformat
= dns_masterformat_none
;
8127 * 'compact' MUST only be set if we are task locked.
8130 REQUIRE(DNS_ZONE_VALID(zone
));
8134 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
8135 if (zone
->db
!= NULL
)
8136 dns_db_attach(zone
->db
, &db
);
8137 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
8139 if (zone
->masterfile
!= NULL
) {
8140 masterfile
= isc_mem_strdup(zone
->mctx
, zone
->masterfile
);
8141 masterformat
= zone
->masterformat
;
8145 result
= DNS_R_NOTLOADED
;
8148 if (masterfile
== NULL
) {
8149 result
= DNS_R_NOMASTERFILE
;
8154 dns_zone_t
*dummy
= NULL
;
8156 zone_iattach(zone
, &dummy
);
8157 result
= zonemgr_getio(zone
->zmgr
, ISC_FALSE
, zone
->task
,
8158 zone_gotwritehandle
, zone
,
8160 if (result
!= ISC_R_SUCCESS
)
8161 zone_idetach(&dummy
);
8163 result
= DNS_R_CONTINUE
;
8166 dns_db_currentversion(db
, &version
);
8167 result
= dns_master_dump2(zone
->mctx
, db
, version
,
8168 &dns_master_style_default
,
8169 masterfile
, masterformat
);
8170 dns_db_closeversion(db
, &version
, ISC_FALSE
);
8175 if (masterfile
!= NULL
)
8176 isc_mem_free(zone
->mctx
, masterfile
);
8179 if (result
== DNS_R_CONTINUE
)
8180 return (ISC_R_SUCCESS
); /* XXXMPA */
8184 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
8185 if (result
!= ISC_R_SUCCESS
) {
8187 * Try again in a short while.
8189 zone_needdump(zone
, DNS_DUMP_DELAY
);
8190 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
8191 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
8192 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
8193 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
8194 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
8195 isc_time_settoepoch(&zone
->dumptime
);
8198 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FLUSH
);
8207 dumptostream(dns_zone_t
*zone
, FILE *fd
, const dns_master_style_t
*style
,
8208 dns_masterformat_t format
)
8210 isc_result_t result
;
8211 dns_dbversion_t
*version
= NULL
;
8212 dns_db_t
*db
= NULL
;
8214 REQUIRE(DNS_ZONE_VALID(zone
));
8216 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
8217 if (zone
->db
!= NULL
)
8218 dns_db_attach(zone
->db
, &db
);
8219 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
8221 return (DNS_R_NOTLOADED
);
8223 dns_db_currentversion(db
, &version
);
8224 result
= dns_master_dumptostream2(zone
->mctx
, db
, version
, style
,
8226 dns_db_closeversion(db
, &version
, ISC_FALSE
);
8232 dns_zone_dumptostream2(dns_zone_t
*zone
, FILE *fd
, dns_masterformat_t format
,
8233 const dns_master_style_t
*style
) {
8234 return dumptostream(zone
, fd
, style
, format
);
8238 dns_zone_dumptostream(dns_zone_t
*zone
, FILE *fd
) {
8239 return dumptostream(zone
, fd
, &dns_master_style_default
,
8240 dns_masterformat_text
);
8244 dns_zone_fulldumptostream(dns_zone_t
*zone
, FILE *fd
) {
8245 return dumptostream(zone
, fd
, &dns_master_style_full
,
8246 dns_masterformat_text
);
8250 dns_zone_unload(dns_zone_t
*zone
) {
8251 REQUIRE(DNS_ZONE_VALID(zone
));
8259 notify_cancel(dns_zone_t
*zone
) {
8260 dns_notify_t
*notify
;
8263 * 'zone' locked by caller.
8266 REQUIRE(LOCKED_ZONE(zone
));
8268 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
8270 notify
= ISC_LIST_NEXT(notify
, link
)) {
8271 if (notify
->find
!= NULL
)
8272 dns_adb_cancelfind(notify
->find
);
8273 if (notify
->request
!= NULL
)
8274 dns_request_cancel(notify
->request
);
8279 zone_unload(dns_zone_t
*zone
) {
8282 * 'zone' locked by caller.
8285 REQUIRE(LOCKED_ZONE(zone
));
8287 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
8288 zone_detachdb(zone
);
8289 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
8290 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_LOADED
);
8291 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
8295 dns_zone_setminrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
8296 REQUIRE(DNS_ZONE_VALID(zone
));
8299 zone
->minrefresh
= val
;
8303 dns_zone_setmaxrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
8304 REQUIRE(DNS_ZONE_VALID(zone
));
8307 zone
->maxrefresh
= val
;
8311 dns_zone_setminretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
8312 REQUIRE(DNS_ZONE_VALID(zone
));
8315 zone
->minretry
= val
;
8319 dns_zone_setmaxretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
8320 REQUIRE(DNS_ZONE_VALID(zone
));
8323 zone
->maxretry
= val
;
8326 static isc_boolean_t
8327 notify_isqueued(dns_zone_t
*zone
, dns_name_t
*name
, isc_sockaddr_t
*addr
) {
8328 dns_notify_t
*notify
;
8330 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
8332 notify
= ISC_LIST_NEXT(notify
, link
)) {
8333 if (notify
->request
!= NULL
)
8335 if (name
!= NULL
&& dns_name_dynamic(¬ify
->ns
) &&
8336 dns_name_equal(name
, ¬ify
->ns
))
8338 if (addr
!= NULL
&& isc_sockaddr_equal(addr
, ¬ify
->dst
))
8344 static isc_boolean_t
8345 notify_isself(dns_zone_t
*zone
, isc_sockaddr_t
*dst
) {
8346 dns_tsigkey_t
*key
= NULL
;
8349 isc_boolean_t isself
;
8350 isc_netaddr_t dstaddr
;
8351 isc_result_t result
;
8353 if (zone
->view
== NULL
|| zone
->isself
== NULL
)
8356 switch (isc_sockaddr_pf(dst
)) {
8358 src
= zone
->notifysrc4
;
8359 isc_sockaddr_any(&any
);
8362 src
= zone
->notifysrc6
;
8363 isc_sockaddr_any6(&any
);
8370 * When sending from any the kernel will assign a source address
8371 * that matches the destination address.
8373 if (isc_sockaddr_eqaddr(&any
, &src
))
8376 isc_netaddr_fromsockaddr(&dstaddr
, dst
);
8377 result
= dns_view_getpeertsig(zone
->view
, &dstaddr
, &key
);
8378 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
)
8380 isself
= (zone
->isself
)(zone
->view
, key
, &src
, dst
, zone
->rdclass
,
8383 dns_tsigkey_detach(&key
);
8388 notify_destroy(dns_notify_t
*notify
, isc_boolean_t locked
) {
8392 * Caller holds zone lock.
8394 REQUIRE(DNS_NOTIFY_VALID(notify
));
8396 if (notify
->zone
!= NULL
) {
8398 LOCK_ZONE(notify
->zone
);
8399 REQUIRE(LOCKED_ZONE(notify
->zone
));
8400 if (ISC_LINK_LINKED(notify
, link
))
8401 ISC_LIST_UNLINK(notify
->zone
->notifies
, notify
, link
);
8403 UNLOCK_ZONE(notify
->zone
);
8405 zone_idetach(¬ify
->zone
);
8407 dns_zone_idetach(¬ify
->zone
);
8409 if (notify
->find
!= NULL
)
8410 dns_adb_destroyfind(¬ify
->find
);
8411 if (notify
->request
!= NULL
)
8412 dns_request_destroy(¬ify
->request
);
8413 if (dns_name_dynamic(¬ify
->ns
))
8414 dns_name_free(¬ify
->ns
, notify
->mctx
);
8415 mctx
= notify
->mctx
;
8416 isc_mem_put(notify
->mctx
, notify
, sizeof(*notify
));
8417 isc_mem_detach(&mctx
);
8421 notify_create(isc_mem_t
*mctx
, unsigned int flags
, dns_notify_t
**notifyp
) {
8422 dns_notify_t
*notify
;
8424 REQUIRE(notifyp
!= NULL
&& *notifyp
== NULL
);
8426 notify
= isc_mem_get(mctx
, sizeof(*notify
));
8428 return (ISC_R_NOMEMORY
);
8430 notify
->mctx
= NULL
;
8431 isc_mem_attach(mctx
, ¬ify
->mctx
);
8432 notify
->flags
= flags
;
8433 notify
->zone
= NULL
;
8434 notify
->find
= NULL
;
8435 notify
->request
= NULL
;
8436 isc_sockaddr_any(¬ify
->dst
);
8437 dns_name_init(¬ify
->ns
, NULL
);
8438 ISC_LINK_INIT(notify
, link
);
8439 notify
->magic
= NOTIFY_MAGIC
;
8441 return (ISC_R_SUCCESS
);
8445 * XXXAG should check for DNS_ZONEFLG_EXITING
8448 process_adb_event(isc_task_t
*task
, isc_event_t
*ev
) {
8449 dns_notify_t
*notify
;
8450 isc_eventtype_t result
;
8454 notify
= ev
->ev_arg
;
8455 REQUIRE(DNS_NOTIFY_VALID(notify
));
8456 INSIST(task
== notify
->zone
->task
);
8457 result
= ev
->ev_type
;
8458 isc_event_free(&ev
);
8459 if (result
== DNS_EVENT_ADBMOREADDRESSES
) {
8460 dns_adb_destroyfind(¬ify
->find
);
8461 notify_find_address(notify
);
8464 if (result
== DNS_EVENT_ADBNOMOREADDRESSES
) {
8465 LOCK_ZONE(notify
->zone
);
8466 notify_send(notify
);
8467 UNLOCK_ZONE(notify
->zone
);
8469 notify_destroy(notify
, ISC_FALSE
);
8473 notify_find_address(dns_notify_t
*notify
) {
8474 isc_result_t result
;
8475 unsigned int options
;
8477 REQUIRE(DNS_NOTIFY_VALID(notify
));
8478 options
= DNS_ADBFIND_WANTEVENT
| DNS_ADBFIND_INET
|
8479 DNS_ADBFIND_INET6
| DNS_ADBFIND_RETURNLAME
;
8481 if (notify
->zone
->view
->adb
== NULL
)
8484 result
= dns_adb_createfind(notify
->zone
->view
->adb
,
8486 process_adb_event
, notify
,
8487 ¬ify
->ns
, dns_rootname
, 0,
8489 notify
->zone
->view
->dstport
,
8492 /* Something failed? */
8493 if (result
!= ISC_R_SUCCESS
)
8496 /* More addresses pending? */
8497 if ((notify
->find
->options
& DNS_ADBFIND_WANTEVENT
) != 0)
8500 /* We have as many addresses as we can get. */
8501 LOCK_ZONE(notify
->zone
);
8502 notify_send(notify
);
8503 UNLOCK_ZONE(notify
->zone
);
8506 notify_destroy(notify
, ISC_FALSE
);
8511 notify_send_queue(dns_notify_t
*notify
) {
8513 isc_result_t result
;
8515 e
= isc_event_allocate(notify
->mctx
, NULL
,
8516 DNS_EVENT_NOTIFYSENDTOADDR
,
8518 notify
, sizeof(isc_event_t
));
8520 return (ISC_R_NOMEMORY
);
8522 e
->ev_sender
= NULL
;
8523 result
= isc_ratelimiter_enqueue(notify
->zone
->zmgr
->rl
,
8524 notify
->zone
->task
, &e
);
8525 if (result
!= ISC_R_SUCCESS
)
8531 notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
) {
8532 dns_notify_t
*notify
;
8533 isc_result_t result
;
8534 dns_message_t
*message
= NULL
;
8535 isc_netaddr_t dstip
;
8536 dns_tsigkey_t
*key
= NULL
;
8537 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
8540 isc_boolean_t have_notifysource
= ISC_FALSE
;
8542 notify
= event
->ev_arg
;
8543 REQUIRE(DNS_NOTIFY_VALID(notify
));
8547 LOCK_ZONE(notify
->zone
);
8549 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_LOADED
) == 0) {
8550 result
= ISC_R_CANCELED
;
8554 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0 ||
8555 DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_EXITING
) ||
8556 notify
->zone
->view
->requestmgr
== NULL
||
8557 notify
->zone
->db
== NULL
) {
8558 result
= ISC_R_CANCELED
;
8563 * The raw IPv4 address should also exist. Don't send to the
8566 if (isc_sockaddr_pf(¬ify
->dst
) == PF_INET6
&&
8567 IN6_IS_ADDR_V4MAPPED(¬ify
->dst
.type
.sin6
.sin6_addr
)) {
8568 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
8569 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
8570 "notify: ignoring IPv6 mapped IPV4 address: %s",
8572 result
= ISC_R_CANCELED
;
8576 result
= notify_createmessage(notify
->zone
, notify
->flags
, &message
);
8577 if (result
!= ISC_R_SUCCESS
)
8580 isc_netaddr_fromsockaddr(&dstip
, ¬ify
->dst
);
8581 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
8582 result
= dns_view_getpeertsig(notify
->zone
->view
, &dstip
, &key
);
8583 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
8584 notify_log(notify
->zone
, ISC_LOG_ERROR
, "NOTIFY to %s not "
8585 "sent. Peer TSIG key lookup failure.", addrbuf
);
8586 goto cleanup_message
;
8589 notify_log(notify
->zone
, ISC_LOG_DEBUG(3), "sending notify to %s",
8591 if (notify
->zone
->view
->peers
!= NULL
) {
8592 dns_peer_t
*peer
= NULL
;
8593 result
= dns_peerlist_peerbyaddr(notify
->zone
->view
->peers
,
8595 if (result
== ISC_R_SUCCESS
) {
8596 result
= dns_peer_getnotifysource(peer
, &src
);
8597 if (result
== ISC_R_SUCCESS
)
8598 have_notifysource
= ISC_TRUE
;
8601 switch (isc_sockaddr_pf(¬ify
->dst
)) {
8603 if (!have_notifysource
)
8604 src
= notify
->zone
->notifysrc4
;
8607 if (!have_notifysource
)
8608 src
= notify
->zone
->notifysrc6
;
8611 result
= ISC_R_NOTIMPLEMENTED
;
8615 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_DIALNOTIFY
))
8617 result
= dns_request_createvia2(notify
->zone
->view
->requestmgr
,
8618 message
, &src
, ¬ify
->dst
, 0, key
,
8619 timeout
* 3, timeout
,
8620 notify
->zone
->task
, notify_done
,
8621 notify
, ¬ify
->request
);
8622 if (result
== ISC_R_SUCCESS
) {
8623 if (isc_sockaddr_pf(¬ify
->dst
) == AF_INET
) {
8624 inc_stats(notify
->zone
,
8625 dns_zonestatscounter_notifyoutv4
);
8627 inc_stats(notify
->zone
,
8628 dns_zonestatscounter_notifyoutv6
);
8634 dns_tsigkey_detach(&key
);
8636 dns_message_destroy(&message
);
8638 UNLOCK_ZONE(notify
->zone
);
8639 if (result
!= ISC_R_SUCCESS
)
8640 notify_destroy(notify
, ISC_FALSE
);
8641 isc_event_free(&event
);
8645 notify_send(dns_notify_t
*notify
) {
8646 dns_adbaddrinfo_t
*ai
;
8648 isc_result_t result
;
8649 dns_notify_t
*new = NULL
;
8652 * Zone lock held by caller.
8654 REQUIRE(DNS_NOTIFY_VALID(notify
));
8655 REQUIRE(LOCKED_ZONE(notify
->zone
));
8657 for (ai
= ISC_LIST_HEAD(notify
->find
->list
);
8659 ai
= ISC_LIST_NEXT(ai
, publink
)) {
8661 if (notify_isqueued(notify
->zone
, NULL
, &dst
))
8663 if (notify_isself(notify
->zone
, &dst
))
8666 result
= notify_create(notify
->mctx
,
8667 (notify
->flags
& DNS_NOTIFY_NOSOA
),
8669 if (result
!= ISC_R_SUCCESS
)
8671 zone_iattach(notify
->zone
, &new->zone
);
8672 ISC_LIST_APPEND(new->zone
->notifies
, new, link
);
8674 result
= notify_send_queue(new);
8675 if (result
!= ISC_R_SUCCESS
)
8682 notify_destroy(new, ISC_TRUE
);
8686 dns_zone_notify(dns_zone_t
*zone
) {
8689 REQUIRE(DNS_ZONE_VALID(zone
));
8692 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
8695 zone_settimer(zone
, &now
);
8700 zone_notify(dns_zone_t
*zone
, isc_time_t
*now
) {
8701 dns_dbnode_t
*node
= NULL
;
8702 dns_db_t
*zonedb
= NULL
;
8703 dns_dbversion_t
*version
= NULL
;
8704 dns_name_t
*origin
= NULL
;
8707 dns_rdata_soa_t soa
;
8708 isc_uint32_t serial
;
8709 dns_rdata_t rdata
= DNS_RDATA_INIT
;
8710 dns_rdataset_t nsrdset
;
8711 dns_rdataset_t soardset
;
8712 isc_result_t result
;
8713 dns_notify_t
*notify
= NULL
;
8716 isc_boolean_t isqueued
;
8717 dns_notifytype_t notifytype
;
8718 unsigned int flags
= 0;
8719 isc_boolean_t loggednotify
= ISC_FALSE
;
8721 REQUIRE(DNS_ZONE_VALID(zone
));
8724 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
8725 notifytype
= zone
->notifytype
;
8726 DNS_ZONE_TIME_ADD(now
, zone
->notifydelay
, &zone
->notifytime
);
8729 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
8732 if (notifytype
== dns_notifytype_no
)
8735 if (notifytype
== dns_notifytype_masteronly
&&
8736 zone
->type
!= dns_zone_master
)
8739 origin
= &zone
->origin
;
8742 * If the zone is dialup we are done as we don't want to send
8743 * the current soa so as to force a refresh query.
8745 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
8746 flags
|= DNS_NOTIFY_NOSOA
;
8751 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
8752 if (zone
->db
!= NULL
)
8753 dns_db_attach(zone
->db
, &zonedb
);
8754 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
8757 dns_db_currentversion(zonedb
, &version
);
8758 result
= dns_db_findnode(zonedb
, origin
, ISC_FALSE
, &node
);
8759 if (result
!= ISC_R_SUCCESS
)
8762 dns_rdataset_init(&soardset
);
8763 result
= dns_db_findrdataset(zonedb
, node
, version
, dns_rdatatype_soa
,
8764 dns_rdatatype_none
, 0, &soardset
, NULL
);
8765 if (result
!= ISC_R_SUCCESS
)
8769 * Find serial and master server's name.
8771 dns_name_init(&master
, NULL
);
8772 result
= dns_rdataset_first(&soardset
);
8773 if (result
!= ISC_R_SUCCESS
)
8775 dns_rdataset_current(&soardset
, &rdata
);
8776 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
8777 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8778 dns_rdata_reset(&rdata
);
8779 result
= dns_name_dup(&soa
.origin
, zone
->mctx
, &master
);
8780 serial
= soa
.serial
;
8781 dns_rdataset_disassociate(&soardset
);
8782 if (result
!= ISC_R_SUCCESS
)
8786 * Enqueue notify requests for 'also-notify' servers.
8789 for (i
= 0; i
< zone
->notifycnt
; i
++) {
8790 dst
= zone
->notify
[i
];
8791 if (notify_isqueued(zone
, NULL
, &dst
))
8793 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
8794 if (result
!= ISC_R_SUCCESS
)
8796 zone_iattach(zone
, ¬ify
->zone
);
8798 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
8799 result
= notify_send_queue(notify
);
8800 if (result
!= ISC_R_SUCCESS
)
8801 notify_destroy(notify
, ISC_TRUE
);
8802 if (!loggednotify
) {
8803 notify_log(zone
, ISC_LOG_INFO
,
8804 "sending notifies (serial %u)",
8806 loggednotify
= ISC_TRUE
;
8812 if (notifytype
== dns_notifytype_explicit
)
8816 * Process NS RRset to generate notifies.
8819 dns_rdataset_init(&nsrdset
);
8820 result
= dns_db_findrdataset(zonedb
, node
, version
, dns_rdatatype_ns
,
8821 dns_rdatatype_none
, 0, &nsrdset
, NULL
);
8822 if (result
!= ISC_R_SUCCESS
)
8825 result
= dns_rdataset_first(&nsrdset
);
8826 while (result
== ISC_R_SUCCESS
) {
8827 dns_rdataset_current(&nsrdset
, &rdata
);
8828 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
8829 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8830 dns_rdata_reset(&rdata
);
8832 * Don't notify the master server unless explicitly
8833 * configured to do so.
8835 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOTIFYTOSOA
) &&
8836 dns_name_compare(&master
, &ns
.name
) == 0) {
8837 result
= dns_rdataset_next(&nsrdset
);
8841 if (!loggednotify
) {
8842 notify_log(zone
, ISC_LOG_INFO
,
8843 "sending notifies (serial %u)",
8845 loggednotify
= ISC_TRUE
;
8849 isqueued
= notify_isqueued(zone
, &ns
.name
, NULL
);
8852 result
= dns_rdataset_next(&nsrdset
);
8855 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
8856 if (result
!= ISC_R_SUCCESS
)
8858 dns_zone_iattach(zone
, ¬ify
->zone
);
8859 result
= dns_name_dup(&ns
.name
, zone
->mctx
, ¬ify
->ns
);
8860 if (result
!= ISC_R_SUCCESS
) {
8862 notify_destroy(notify
, ISC_TRUE
);
8867 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
8869 notify_find_address(notify
);
8871 result
= dns_rdataset_next(&nsrdset
);
8873 dns_rdataset_disassociate(&nsrdset
);
8876 if (dns_name_dynamic(&master
))
8877 dns_name_free(&master
, zone
->mctx
);
8879 dns_db_detachnode(zonedb
, &node
);
8881 dns_db_closeversion(zonedb
, &version
, ISC_FALSE
);
8882 dns_db_detach(&zonedb
);
8889 static inline isc_result_t
8890 save_nsrrset(dns_message_t
*message
, dns_name_t
*name
,
8891 dns_db_t
*db
, dns_dbversion_t
*version
)
8893 dns_rdataset_t
*nsrdataset
= NULL
;
8894 dns_rdataset_t
*rdataset
= NULL
;
8895 dns_dbnode_t
*node
= NULL
;
8897 isc_result_t result
;
8898 dns_rdata_t rdata
= DNS_RDATA_INIT
;
8901 * Extract NS RRset from message.
8903 result
= dns_message_findname(message
, DNS_SECTION_ANSWER
, name
,
8904 dns_rdatatype_ns
, dns_rdatatype_none
,
8906 if (result
!= ISC_R_SUCCESS
)
8912 result
= dns_db_findnode(db
, name
, ISC_TRUE
, &node
);
8913 if (result
!= ISC_R_SUCCESS
)
8915 result
= dns_db_addrdataset(db
, node
, version
, 0,
8916 nsrdataset
, 0, NULL
);
8917 dns_db_detachnode(db
, &node
);
8918 if (result
!= ISC_R_SUCCESS
)
8921 * Add glue rdatasets.
8923 for (result
= dns_rdataset_first(nsrdataset
);
8924 result
== ISC_R_SUCCESS
;
8925 result
= dns_rdataset_next(nsrdataset
)) {
8926 dns_rdataset_current(nsrdataset
, &rdata
);
8927 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
8928 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8929 dns_rdata_reset(&rdata
);
8930 if (!dns_name_issubdomain(&ns
.name
, name
))
8933 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
8934 &ns
.name
, dns_rdatatype_aaaa
,
8935 dns_rdatatype_none
, NULL
,
8937 if (result
== ISC_R_SUCCESS
) {
8938 result
= dns_db_findnode(db
, &ns
.name
,
8940 if (result
!= ISC_R_SUCCESS
)
8942 result
= dns_db_addrdataset(db
, node
, version
, 0,
8944 dns_db_detachnode(db
, &node
);
8945 if (result
!= ISC_R_SUCCESS
)
8949 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
8950 &ns
.name
, dns_rdatatype_a
,
8951 dns_rdatatype_none
, NULL
,
8953 if (result
== ISC_R_SUCCESS
) {
8954 result
= dns_db_findnode(db
, &ns
.name
,
8956 if (result
!= ISC_R_SUCCESS
)
8958 result
= dns_db_addrdataset(db
, node
, version
, 0,
8960 dns_db_detachnode(db
, &node
);
8961 if (result
!= ISC_R_SUCCESS
)
8965 if (result
!= ISC_R_NOMORE
)
8968 return (ISC_R_SUCCESS
);
8975 stub_callback(isc_task_t
*task
, isc_event_t
*event
) {
8976 const char me
[] = "stub_callback";
8977 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
8978 dns_stub_t
*stub
= NULL
;
8979 dns_message_t
*msg
= NULL
;
8980 dns_zone_t
*zone
= NULL
;
8981 char master
[ISC_SOCKADDR_FORMATSIZE
];
8982 char source
[ISC_SOCKADDR_FORMATSIZE
];
8983 isc_uint32_t nscnt
, cnamecnt
;
8984 isc_result_t result
;
8986 isc_boolean_t exiting
= ISC_FALSE
;
8990 stub
= revent
->ev_arg
;
8991 INSIST(DNS_STUB_VALID(stub
));
9001 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
9002 zone_debuglog(zone
, me
, 1, "exiting");
9007 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
9008 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
9010 if (revent
->result
!= ISC_R_SUCCESS
) {
9011 if (revent
->result
== ISC_R_TIMEDOUT
&&
9012 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
9014 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
9016 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
9017 "refreshing stub: timeout retrying "
9018 " without EDNS master %s (source %s)",
9022 dns_zonemgr_unreachableadd(zone
->zmgr
, &zone
->masteraddr
,
9023 &zone
->sourceaddr
, &now
);
9024 dns_zone_log(zone
, ISC_LOG_INFO
,
9025 "could not refresh stub from master %s"
9026 " (source %s): %s", master
, source
,
9027 dns_result_totext(revent
->result
));
9031 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
9032 if (result
!= ISC_R_SUCCESS
)
9035 result
= dns_request_getresponse(revent
->request
, msg
, 0);
9036 if (result
!= ISC_R_SUCCESS
)
9042 if (msg
->rcode
!= dns_rcode_noerror
) {
9046 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
9047 (void)dns_rcode_totext(msg
->rcode
, &rb
);
9049 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
) &&
9050 (msg
->rcode
== dns_rcode_servfail
||
9051 msg
->rcode
== dns_rcode_notimp
||
9052 msg
->rcode
== dns_rcode_formerr
)) {
9053 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
9054 "refreshing stub: rcode (%.*s) retrying "
9055 "without EDNS master %s (source %s)",
9056 (int)rb
.used
, rcode
, master
, source
);
9058 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
9063 dns_zone_log(zone
, ISC_LOG_INFO
,
9065 "unexpected rcode (%.*s) from %s (source %s)",
9066 (int)rb
.used
, rcode
, master
, source
);
9071 * We need complete messages.
9073 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
9074 if (dns_request_usedtcp(revent
->request
)) {
9075 dns_zone_log(zone
, ISC_LOG_INFO
,
9076 "refreshing stub: truncated TCP "
9077 "response from master %s (source %s)",
9082 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
9088 * If non-auth log and next master.
9090 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
9091 dns_zone_log(zone
, ISC_LOG_INFO
, "refreshing stub: "
9092 "non-authoritative answer from "
9093 "master %s (source %s)", master
, source
);
9100 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
9101 nscnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_ns
);
9103 if (cnamecnt
!= 0) {
9104 dns_zone_log(zone
, ISC_LOG_INFO
,
9105 "refreshing stub: unexpected CNAME response "
9106 "from master %s (source %s)", master
, source
);
9111 dns_zone_log(zone
, ISC_LOG_INFO
,
9112 "refreshing stub: no NS records in response "
9113 "from master %s (source %s)", master
, source
);
9120 result
= save_nsrrset(msg
, &zone
->origin
, stub
->db
, stub
->version
);
9121 if (result
!= ISC_R_SUCCESS
) {
9122 dns_zone_log(zone
, ISC_LOG_INFO
,
9123 "refreshing stub: unable to save NS records "
9124 "from master %s (source %s)", master
, source
);
9131 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_TRUE
);
9132 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
9133 if (zone
->db
== NULL
)
9134 zone_attachdb(zone
, stub
->db
);
9135 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
9136 dns_db_detach(&stub
->db
);
9138 if (zone
->masterfile
!= NULL
) {
9139 dns_zone_dump(zone
);
9140 TIME_NOW(&zone
->loadtime
);
9143 dns_message_destroy(&msg
);
9144 isc_event_free(&event
);
9146 dns_request_destroy(&zone
->request
);
9147 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
9148 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
, &zone
->refreshtime
);
9149 isc_interval_set(&i
, zone
->expire
, 0);
9150 DNS_ZONE_TIME_ADD(&now
, zone
->expire
, &zone
->expiretime
);
9151 zone_settimer(zone
, &now
);
9156 if (stub
->version
!= NULL
)
9157 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_FALSE
);
9158 if (stub
->db
!= NULL
)
9159 dns_db_detach(&stub
->db
);
9161 dns_message_destroy(&msg
);
9162 isc_event_free(&event
);
9164 dns_request_destroy(&zone
->request
);
9166 * Skip to next failed / untried master.
9170 } while (zone
->curmaster
< zone
->masterscnt
&&
9171 zone
->mastersok
[zone
->curmaster
]);
9172 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
9173 if (exiting
|| zone
->curmaster
>= zone
->masterscnt
) {
9174 isc_boolean_t done
= ISC_TRUE
;
9176 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
9177 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
9179 * Did we get a good answer from all the masters?
9181 for (j
= 0; j
< zone
->masterscnt
; j
++)
9182 if (zone
->mastersok
[j
] == ISC_FALSE
) {
9189 zone
->curmaster
= 0;
9191 * Find the next failed master.
9193 while (zone
->curmaster
< zone
->masterscnt
&&
9194 zone
->mastersok
[zone
->curmaster
])
9196 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
9198 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
9200 zone_settimer(zone
, &now
);
9205 queue_soa_query(zone
);
9211 dns_message_destroy(&msg
);
9212 isc_event_free(&event
);
9214 dns_request_destroy(&zone
->request
);
9216 ns_query(zone
, NULL
, stub
);
9221 dns_zone_idetach(&stub
->zone
);
9222 INSIST(stub
->db
== NULL
);
9223 INSIST(stub
->version
== NULL
);
9224 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
9227 INSIST(event
== NULL
);
9232 * An SOA query has finished (successfully or not).
9235 refresh_callback(isc_task_t
*task
, isc_event_t
*event
) {
9236 const char me
[] = "refresh_callback";
9237 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
9239 dns_message_t
*msg
= NULL
;
9240 isc_uint32_t soacnt
, cnamecnt
, soacount
, nscount
;
9242 char master
[ISC_SOCKADDR_FORMATSIZE
];
9243 char source
[ISC_SOCKADDR_FORMATSIZE
];
9244 dns_rdataset_t
*rdataset
= NULL
;
9245 dns_rdata_t rdata
= DNS_RDATA_INIT
;
9246 dns_rdata_soa_t soa
;
9247 isc_result_t result
;
9248 isc_uint32_t serial
, oldserial
;
9251 zone
= revent
->ev_arg
;
9252 INSIST(DNS_ZONE_VALID(zone
));
9259 * if timeout log and next master;
9262 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
9263 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
9267 if (revent
->result
!= ISC_R_SUCCESS
) {
9268 if (revent
->result
== ISC_R_TIMEDOUT
&&
9269 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
9271 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
9273 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
9274 "refresh: timeout retrying without EDNS "
9275 "master %s (source %s)", master
, source
);
9278 if (revent
->result
== ISC_R_TIMEDOUT
&&
9279 !dns_request_usedtcp(revent
->request
)) {
9280 dns_zone_log(zone
, ISC_LOG_INFO
,
9281 "refresh: retry limit for "
9282 "master %s exceeded (source %s)",
9284 /* Try with slave with TCP. */
9285 if (zone
->type
== dns_zone_slave
&&
9286 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_TRYTCPREFRESH
)) {
9287 if (!dns_zonemgr_unreachable(zone
->zmgr
,
9292 DNS_ZONE_SETFLAG(zone
,
9293 DNS_ZONEFLG_SOABEFOREAXFR
);
9297 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
9298 "refresh: skipped tcp fallback"
9299 "as master %s (source %s) is "
9300 "unreachable (cached)",
9304 dns_zone_log(zone
, ISC_LOG_INFO
,
9305 "refresh: failure trying master "
9306 "%s (source %s): %s", master
, source
,
9307 dns_result_totext(revent
->result
));
9311 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
9312 if (result
!= ISC_R_SUCCESS
)
9314 result
= dns_request_getresponse(revent
->request
, msg
, 0);
9315 if (result
!= ISC_R_SUCCESS
) {
9316 dns_zone_log(zone
, ISC_LOG_INFO
,
9317 "refresh: failure trying master "
9318 "%s (source %s): %s", master
, source
,
9319 dns_result_totext(result
));
9326 if (msg
->rcode
!= dns_rcode_noerror
) {
9330 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
9331 (void)dns_rcode_totext(msg
->rcode
, &rb
);
9333 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
) &&
9334 (msg
->rcode
== dns_rcode_servfail
||
9335 msg
->rcode
== dns_rcode_notimp
||
9336 msg
->rcode
== dns_rcode_formerr
)) {
9337 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
9338 "refresh: rcode (%.*s) retrying without "
9339 "EDNS master %s (source %s)",
9340 (int)rb
.used
, rcode
, master
, source
);
9342 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
9346 dns_zone_log(zone
, ISC_LOG_INFO
,
9347 "refresh: unexpected rcode (%.*s) from "
9348 "master %s (source %s)", (int)rb
.used
, rcode
,
9351 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
9353 if (msg
->rcode
== dns_rcode_refused
&&
9354 zone
->type
== dns_zone_slave
)
9360 * If truncated punt to zone transfer which will query again.
9362 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
9363 if (zone
->type
== dns_zone_slave
) {
9364 dns_zone_log(zone
, ISC_LOG_INFO
,
9365 "refresh: truncated UDP answer, "
9366 "initiating TCP zone xfer "
9367 "for master %s (source %s)",
9370 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
);
9374 INSIST(zone
->type
== dns_zone_stub
);
9375 if (dns_request_usedtcp(revent
->request
)) {
9376 dns_zone_log(zone
, ISC_LOG_INFO
,
9377 "refresh: truncated TCP response "
9378 "from master %s (source %s)",
9383 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
9390 * if non-auth log and next master;
9392 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
9393 dns_zone_log(zone
, ISC_LOG_INFO
,
9394 "refresh: non-authoritative answer from "
9395 "master %s (source %s)", master
, source
);
9399 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
9400 soacnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_soa
);
9401 nscount
= message_count(msg
, DNS_SECTION_AUTHORITY
, dns_rdatatype_ns
);
9402 soacount
= message_count(msg
, DNS_SECTION_AUTHORITY
,
9406 * There should not be a CNAME record at top of zone.
9408 if (cnamecnt
!= 0) {
9409 dns_zone_log(zone
, ISC_LOG_INFO
,
9410 "refresh: CNAME at top of zone "
9411 "in master %s (source %s)", master
, source
);
9416 * if referral log and next master;
9418 if (soacnt
== 0 && soacount
== 0 && nscount
!= 0) {
9419 dns_zone_log(zone
, ISC_LOG_INFO
,
9420 "refresh: referral response "
9421 "from master %s (source %s)", master
, source
);
9426 * if nodata log and next master;
9428 if (soacnt
== 0 && (nscount
== 0 || soacount
!= 0)) {
9429 dns_zone_log(zone
, ISC_LOG_INFO
,
9430 "refresh: NODATA response "
9431 "from master %s (source %s)", master
, source
);
9436 * Only one soa at top of zone.
9439 dns_zone_log(zone
, ISC_LOG_INFO
,
9440 "refresh: answer SOA count (%d) != 1 "
9441 "from master %s (source %s)",
9442 soacnt
, master
, source
);
9449 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
, &zone
->origin
,
9450 dns_rdatatype_soa
, dns_rdatatype_none
,
9452 if (result
!= ISC_R_SUCCESS
) {
9453 dns_zone_log(zone
, ISC_LOG_INFO
,
9454 "refresh: unable to get SOA record "
9455 "from master %s (source %s)", master
, source
);
9459 result
= dns_rdataset_first(rdataset
);
9460 if (result
!= ISC_R_SUCCESS
) {
9461 dns_zone_log(zone
, ISC_LOG_INFO
,
9462 "refresh: dns_rdataset_first() failed");
9466 dns_rdataset_current(rdataset
, &rdata
);
9467 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
9468 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
9470 serial
= soa
.serial
;
9471 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
9472 result
= dns_zone_getserial2(zone
, &oldserial
);
9473 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
9474 zone_debuglog(zone
, me
, 1, "serial: new %u, old %u",
9477 zone_debuglog(zone
, me
, 1, "serial: new %u, old not loaded",
9479 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) ||
9480 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
) ||
9481 isc_serial_gt(serial
, oldserial
)) {
9482 if (dns_zonemgr_unreachable(zone
->zmgr
, &zone
->masteraddr
,
9483 &zone
->sourceaddr
, &now
)) {
9484 dns_zone_log(zone
, ISC_LOG_INFO
,
9485 "refresh: skipping %s as master %s "
9486 "(source %s) is unreachable (cached)",
9487 zone
->type
== dns_zone_slave
?
9488 "zone transfer" : "NS query",
9493 isc_event_free(&event
);
9495 dns_request_destroy(&zone
->request
);
9497 if (zone
->type
== dns_zone_slave
) {
9500 INSIST(zone
->type
== dns_zone_stub
);
9501 ns_query(zone
, rdataset
, NULL
);
9504 dns_message_destroy(&msg
);
9505 } else if (isc_serial_eq(soa
.serial
, oldserial
)) {
9506 if (zone
->masterfile
!= NULL
) {
9507 result
= ISC_R_FAILURE
;
9508 if (zone
->journal
!= NULL
)
9509 result
= isc_file_settime(zone
->journal
, &now
);
9510 if (result
== ISC_R_SUCCESS
&&
9511 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
9512 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
9513 result
= isc_file_settime(zone
->masterfile
,
9515 } else if (result
!= ISC_R_SUCCESS
)
9516 result
= isc_file_settime(zone
->masterfile
,
9518 /* Someone removed the file from underneath us! */
9519 if (result
== ISC_R_FILENOTFOUND
) {
9521 zone_needdump(zone
, DNS_DUMP_DELAY
);
9523 } else if (result
!= ISC_R_SUCCESS
)
9524 dns_zone_log(zone
, ISC_LOG_ERROR
,
9525 "refresh: could not set file "
9526 "modification time of '%s': %s",
9528 dns_result_totext(result
));
9530 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
, &zone
->refreshtime
);
9531 DNS_ZONE_TIME_ADD(&now
, zone
->expire
, &zone
->expiretime
);
9532 zone
->mastersok
[zone
->curmaster
] = ISC_TRUE
;
9535 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MULTIMASTER
))
9536 dns_zone_log(zone
, ISC_LOG_INFO
, "serial number (%u) "
9537 "received from master %s < ours (%u)",
9538 soa
.serial
, master
, oldserial
);
9540 zone_debuglog(zone
, me
, 1, "ahead");
9541 zone
->mastersok
[zone
->curmaster
] = ISC_TRUE
;
9545 dns_message_destroy(&msg
);
9550 dns_message_destroy(&msg
);
9551 isc_event_free(&event
);
9553 dns_request_destroy(&zone
->request
);
9555 * Skip to next failed / untried master.
9559 } while (zone
->curmaster
< zone
->masterscnt
&&
9560 zone
->mastersok
[zone
->curmaster
]);
9561 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
9562 if (zone
->curmaster
>= zone
->masterscnt
) {
9563 isc_boolean_t done
= ISC_TRUE
;
9564 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
9565 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
9567 * Did we get a good answer from all the masters?
9569 for (j
= 0; j
< zone
->masterscnt
; j
++)
9570 if (zone
->mastersok
[j
] == ISC_FALSE
) {
9577 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
9578 zone
->curmaster
= 0;
9580 * Find the next failed master.
9582 while (zone
->curmaster
< zone
->masterscnt
&&
9583 zone
->mastersok
[zone
->curmaster
])
9587 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
9588 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
9589 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
9590 zone
->refreshtime
= now
;
9592 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
9593 zone_settimer(zone
, &now
);
9599 queue_soa_query(zone
);
9605 dns_message_destroy(&msg
);
9606 isc_event_free(&event
);
9608 dns_request_destroy(&zone
->request
);
9609 queue_soa_query(zone
);
9613 dns_zone_idetach(&zone
);
9618 queue_soa_query(dns_zone_t
*zone
) {
9619 const char me
[] = "queue_soa_query";
9621 dns_zone_t
*dummy
= NULL
;
9622 isc_result_t result
;
9628 REQUIRE(LOCKED_ZONE(zone
));
9630 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
9631 cancel_refresh(zone
);
9635 e
= isc_event_allocate(zone
->mctx
, NULL
, DNS_EVENT_ZONE
,
9636 soa_query
, zone
, sizeof(isc_event_t
));
9638 cancel_refresh(zone
);
9643 * Attach so that we won't clean up
9644 * until the event is delivered.
9646 zone_iattach(zone
, &dummy
);
9649 e
->ev_sender
= NULL
;
9650 result
= isc_ratelimiter_enqueue(zone
->zmgr
->rl
, zone
->task
, &e
);
9651 if (result
!= ISC_R_SUCCESS
) {
9652 zone_idetach(&dummy
);
9654 cancel_refresh(zone
);
9658 static inline isc_result_t
9659 create_query(dns_zone_t
*zone
, dns_rdatatype_t rdtype
,
9660 dns_message_t
**messagep
)
9662 dns_message_t
*message
= NULL
;
9663 dns_name_t
*qname
= NULL
;
9664 dns_rdataset_t
*qrdataset
= NULL
;
9665 isc_result_t result
;
9667 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
9669 if (result
!= ISC_R_SUCCESS
)
9672 message
->opcode
= dns_opcode_query
;
9673 message
->rdclass
= zone
->rdclass
;
9675 result
= dns_message_gettempname(message
, &qname
);
9676 if (result
!= ISC_R_SUCCESS
)
9679 result
= dns_message_gettemprdataset(message
, &qrdataset
);
9680 if (result
!= ISC_R_SUCCESS
)
9686 dns_name_init(qname
, NULL
);
9687 dns_name_clone(&zone
->origin
, qname
);
9688 dns_rdataset_init(qrdataset
);
9689 dns_rdataset_makequestion(qrdataset
, zone
->rdclass
, rdtype
);
9690 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
9691 dns_message_addname(message
, qname
, DNS_SECTION_QUESTION
);
9693 *messagep
= message
;
9694 return (ISC_R_SUCCESS
);
9698 dns_message_puttempname(message
, &qname
);
9699 if (qrdataset
!= NULL
)
9700 dns_message_puttemprdataset(message
, &qrdataset
);
9701 if (message
!= NULL
)
9702 dns_message_destroy(&message
);
9707 add_opt(dns_message_t
*message
, isc_uint16_t udpsize
, isc_boolean_t reqnsid
) {
9708 dns_rdataset_t
*rdataset
= NULL
;
9709 dns_rdatalist_t
*rdatalist
= NULL
;
9710 dns_rdata_t
*rdata
= NULL
;
9711 isc_result_t result
;
9713 result
= dns_message_gettemprdatalist(message
, &rdatalist
);
9714 if (result
!= ISC_R_SUCCESS
)
9716 result
= dns_message_gettemprdata(message
, &rdata
);
9717 if (result
!= ISC_R_SUCCESS
)
9719 result
= dns_message_gettemprdataset(message
, &rdataset
);
9720 if (result
!= ISC_R_SUCCESS
)
9722 dns_rdataset_init(rdataset
);
9724 rdatalist
->type
= dns_rdatatype_opt
;
9725 rdatalist
->covers
= 0;
9728 * Set Maximum UDP buffer size.
9730 rdatalist
->rdclass
= udpsize
;
9733 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
9737 /* Set EDNS options if applicable */
9739 unsigned char data
[4];
9742 isc_buffer_init(&buf
, data
, sizeof(data
));
9743 isc_buffer_putuint16(&buf
, DNS_OPT_NSID
);
9744 isc_buffer_putuint16(&buf
, 0);
9746 rdata
->length
= sizeof(data
);
9752 rdata
->rdclass
= rdatalist
->rdclass
;
9753 rdata
->type
= rdatalist
->type
;
9756 ISC_LIST_INIT(rdatalist
->rdata
);
9757 ISC_LIST_APPEND(rdatalist
->rdata
, rdata
, link
);
9758 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist
, rdataset
)
9761 return (dns_message_setopt(message
, rdataset
));
9764 if (rdatalist
!= NULL
)
9765 dns_message_puttemprdatalist(message
, &rdatalist
);
9766 if (rdataset
!= NULL
)
9767 dns_message_puttemprdataset(message
, &rdataset
);
9769 dns_message_puttemprdata(message
, &rdata
);
9775 soa_query(isc_task_t
*task
, isc_event_t
*event
) {
9776 const char me
[] = "soa_query";
9777 isc_result_t result
= ISC_R_FAILURE
;
9778 dns_message_t
*message
= NULL
;
9779 dns_zone_t
*zone
= event
->ev_arg
;
9780 dns_zone_t
*dummy
= NULL
;
9781 isc_netaddr_t masterip
;
9782 dns_tsigkey_t
*key
= NULL
;
9783 isc_uint32_t options
;
9784 isc_boolean_t cancel
= ISC_TRUE
;
9786 isc_boolean_t have_xfrsource
, reqnsid
;
9787 isc_uint16_t udpsize
= SEND_BUFFER_SIZE
;
9789 REQUIRE(DNS_ZONE_VALID(zone
));
9796 if (((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0) ||
9797 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
) ||
9798 zone
->view
->requestmgr
== NULL
) {
9799 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
9805 * XXX Optimisation: Create message when zone is setup and reuse.
9807 result
= create_query(zone
, dns_rdatatype_soa
, &message
);
9808 if (result
!= ISC_R_SUCCESS
)
9812 INSIST(zone
->masterscnt
> 0);
9813 INSIST(zone
->curmaster
< zone
->masterscnt
);
9815 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
9817 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
9819 * First, look for a tsig key in the master statement, then
9820 * try for a server key.
9822 if ((zone
->masterkeynames
!= NULL
) &&
9823 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
9824 dns_view_t
*view
= dns_zone_getview(zone
);
9825 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
9826 result
= dns_view_gettsig(view
, keyname
, &key
);
9827 if (result
!= ISC_R_SUCCESS
) {
9828 char namebuf
[DNS_NAME_FORMATSIZE
];
9829 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
9830 dns_zone_log(zone
, ISC_LOG_ERROR
,
9831 "unable to find key: %s", namebuf
);
9836 result
= dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
9837 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
9838 char addrbuf
[ISC_NETADDR_FORMATSIZE
];
9839 isc_netaddr_format(&masterip
, addrbuf
, sizeof(addrbuf
));
9840 dns_zone_log(zone
, ISC_LOG_ERROR
,
9841 "unable to find TSIG key for %s", addrbuf
);
9846 have_xfrsource
= ISC_FALSE
;
9847 reqnsid
= zone
->view
->requestnsid
;
9848 if (zone
->view
->peers
!= NULL
) {
9849 dns_peer_t
*peer
= NULL
;
9851 result
= dns_peerlist_peerbyaddr(zone
->view
->peers
,
9853 if (result
== ISC_R_SUCCESS
) {
9854 result
= dns_peer_getsupportedns(peer
, &edns
);
9855 if (result
== ISC_R_SUCCESS
&& !edns
)
9856 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
9857 result
= dns_peer_gettransfersource(peer
,
9859 if (result
== ISC_R_SUCCESS
)
9860 have_xfrsource
= ISC_TRUE
;
9861 if (zone
->view
->resolver
!= NULL
)
9863 dns_resolver_getudpsize(zone
->view
->resolver
);
9864 (void)dns_peer_getudpsize(peer
, &udpsize
);
9865 (void)dns_peer_getrequestnsid(peer
, &reqnsid
);
9869 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
9871 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
9872 if (isc_sockaddr_equal(&zone
->altxfrsource4
,
9875 zone
->sourceaddr
= zone
->altxfrsource4
;
9876 } else if (!have_xfrsource
)
9877 zone
->sourceaddr
= zone
->xfrsource4
;
9880 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
9881 if (isc_sockaddr_equal(&zone
->altxfrsource6
,
9884 zone
->sourceaddr
= zone
->altxfrsource6
;
9885 } else if (!have_xfrsource
)
9886 zone
->sourceaddr
= zone
->xfrsource6
;
9889 result
= ISC_R_NOTIMPLEMENTED
;
9893 options
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEVC
) ?
9894 DNS_REQUESTOPT_TCP
: 0;
9896 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
9897 result
= add_opt(message
, udpsize
, reqnsid
);
9898 if (result
!= ISC_R_SUCCESS
)
9899 zone_debuglog(zone
, me
, 1,
9900 "unable to add opt record: %s",
9901 dns_result_totext(result
));
9904 zone_iattach(zone
, &dummy
);
9906 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
9908 result
= dns_request_createvia2(zone
->view
->requestmgr
, message
,
9909 &zone
->sourceaddr
, &zone
->masteraddr
,
9910 options
, key
, timeout
* 3, timeout
,
9911 zone
->task
, refresh_callback
, zone
,
9913 if (result
!= ISC_R_SUCCESS
) {
9914 zone_idetach(&dummy
);
9915 zone_debuglog(zone
, me
, 1,
9916 "dns_request_createvia2() failed: %s",
9917 dns_result_totext(result
));
9920 if (isc_sockaddr_pf(&zone
->masteraddr
) == PF_INET
)
9921 inc_stats(zone
, dns_zonestatscounter_soaoutv4
);
9923 inc_stats(zone
, dns_zonestatscounter_soaoutv6
);
9929 dns_tsigkey_detach(&key
);
9930 if (result
!= ISC_R_SUCCESS
)
9931 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
9932 if (message
!= NULL
)
9933 dns_message_destroy(&message
);
9935 cancel_refresh(zone
);
9936 isc_event_free(&event
);
9938 dns_zone_idetach(&zone
);
9943 dns_tsigkey_detach(&key
);
9945 * Skip to next failed / untried master.
9949 } while (zone
->curmaster
< zone
->masterscnt
&&
9950 zone
->mastersok
[zone
->curmaster
]);
9951 if (zone
->curmaster
< zone
->masterscnt
)
9953 zone
->curmaster
= 0;
9958 ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
, dns_stub_t
*stub
) {
9959 const char me
[] = "ns_query";
9960 isc_result_t result
;
9961 dns_message_t
*message
= NULL
;
9962 isc_netaddr_t masterip
;
9963 dns_tsigkey_t
*key
= NULL
;
9964 dns_dbnode_t
*node
= NULL
;
9966 isc_boolean_t have_xfrsource
= ISC_FALSE
, reqnsid
;
9967 isc_uint16_t udpsize
= SEND_BUFFER_SIZE
;
9969 REQUIRE(DNS_ZONE_VALID(zone
));
9970 REQUIRE((soardataset
!= NULL
&& stub
== NULL
) ||
9971 (soardataset
== NULL
&& stub
!= NULL
));
9972 REQUIRE(stub
== NULL
|| DNS_STUB_VALID(stub
));
9978 stub
= isc_mem_get(zone
->mctx
, sizeof(*stub
));
9981 stub
->magic
= STUB_MAGIC
;
9982 stub
->mctx
= zone
->mctx
;
9985 stub
->version
= NULL
;
9988 * Attach so that the zone won't disappear from under us.
9990 zone_iattach(zone
, &stub
->zone
);
9993 * If a db exists we will update it, otherwise we create a
9994 * new one and attach it to the zone once we have the NS
9997 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
9998 if (zone
->db
!= NULL
) {
9999 dns_db_attach(zone
->db
, &stub
->db
);
10000 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
10002 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
10004 INSIST(zone
->db_argc
>= 1);
10005 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
10006 &zone
->origin
, dns_dbtype_stub
,
10011 if (result
!= ISC_R_SUCCESS
) {
10012 dns_zone_log(zone
, ISC_LOG_ERROR
,
10013 "refreshing stub: "
10014 "could not create "
10016 dns_result_totext(result
));
10019 dns_db_settask(stub
->db
, zone
->task
);
10022 dns_db_newversion(stub
->db
, &stub
->version
);
10025 * Update SOA record.
10027 result
= dns_db_findnode(stub
->db
, &zone
->origin
, ISC_TRUE
,
10029 if (result
!= ISC_R_SUCCESS
) {
10030 dns_zone_log(zone
, ISC_LOG_INFO
,
10031 "refreshing stub: "
10032 "dns_db_findnode() failed: %s",
10033 dns_result_totext(result
));
10037 result
= dns_db_addrdataset(stub
->db
, node
, stub
->version
, 0,
10038 soardataset
, 0, NULL
);
10039 dns_db_detachnode(stub
->db
, &node
);
10040 if (result
!= ISC_R_SUCCESS
) {
10041 dns_zone_log(zone
, ISC_LOG_INFO
,
10042 "refreshing stub: "
10043 "dns_db_addrdataset() failed: %s",
10044 dns_result_totext(result
));
10050 * XXX Optimisation: Create message when zone is setup and reuse.
10052 result
= create_query(zone
, dns_rdatatype_ns
, &message
);
10054 INSIST(zone
->masterscnt
> 0);
10055 INSIST(zone
->curmaster
< zone
->masterscnt
);
10056 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
10058 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
10060 * First, look for a tsig key in the master statement, then
10061 * try for a server key.
10063 if ((zone
->masterkeynames
!= NULL
) &&
10064 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
10065 dns_view_t
*view
= dns_zone_getview(zone
);
10066 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
10067 result
= dns_view_gettsig(view
, keyname
, &key
);
10068 if (result
!= ISC_R_SUCCESS
) {
10069 char namebuf
[DNS_NAME_FORMATSIZE
];
10070 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
10071 dns_zone_log(zone
, ISC_LOG_ERROR
,
10072 "unable to find key: %s", namebuf
);
10076 (void)dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
10078 reqnsid
= zone
->view
->requestnsid
;
10079 if (zone
->view
->peers
!= NULL
) {
10080 dns_peer_t
*peer
= NULL
;
10081 isc_boolean_t edns
;
10082 result
= dns_peerlist_peerbyaddr(zone
->view
->peers
,
10084 if (result
== ISC_R_SUCCESS
) {
10085 result
= dns_peer_getsupportedns(peer
, &edns
);
10086 if (result
== ISC_R_SUCCESS
&& !edns
)
10087 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
10088 result
= dns_peer_gettransfersource(peer
,
10089 &zone
->sourceaddr
);
10090 if (result
== ISC_R_SUCCESS
)
10091 have_xfrsource
= ISC_TRUE
;
10092 if (zone
->view
->resolver
!= NULL
)
10094 dns_resolver_getudpsize(zone
->view
->resolver
);
10095 (void)dns_peer_getudpsize(peer
, &udpsize
);
10096 (void)dns_peer_getrequestnsid(peer
, &reqnsid
);
10100 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
10101 result
= add_opt(message
, udpsize
, reqnsid
);
10102 if (result
!= ISC_R_SUCCESS
)
10103 zone_debuglog(zone
, me
, 1,
10104 "unable to add opt record: %s",
10105 dns_result_totext(result
));
10109 * Always use TCP so that we shouldn't truncate in additional section.
10111 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
10113 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
))
10114 zone
->sourceaddr
= zone
->altxfrsource4
;
10115 else if (!have_xfrsource
)
10116 zone
->sourceaddr
= zone
->xfrsource4
;
10119 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
))
10120 zone
->sourceaddr
= zone
->altxfrsource6
;
10121 else if (!have_xfrsource
)
10122 zone
->sourceaddr
= zone
->xfrsource6
;
10125 result
= ISC_R_NOTIMPLEMENTED
;
10129 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
10131 result
= dns_request_createvia2(zone
->view
->requestmgr
, message
,
10132 &zone
->sourceaddr
, &zone
->masteraddr
,
10133 DNS_REQUESTOPT_TCP
, key
, timeout
* 3,
10134 timeout
, zone
->task
, stub_callback
,
10135 stub
, &zone
->request
);
10136 if (result
!= ISC_R_SUCCESS
) {
10137 zone_debuglog(zone
, me
, 1,
10138 "dns_request_createvia() failed: %s",
10139 dns_result_totext(result
));
10142 dns_message_destroy(&message
);
10146 cancel_refresh(zone
);
10147 if (stub
!= NULL
) {
10149 if (stub
->version
!= NULL
)
10150 dns_db_closeversion(stub
->db
, &stub
->version
,
10152 if (stub
->db
!= NULL
)
10153 dns_db_detach(&stub
->db
);
10154 if (stub
->zone
!= NULL
)
10155 zone_idetach(&stub
->zone
);
10156 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
10158 if (message
!= NULL
)
10159 dns_message_destroy(&message
);
10162 dns_tsigkey_detach(&key
);
10168 * Handle the control event. Note that although this event causes the zone
10169 * to shut down, it is not a shutdown event in the sense of the task library.
10172 zone_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
10173 dns_zone_t
*zone
= (dns_zone_t
*) event
->ev_arg
;
10174 isc_boolean_t free_needed
, linked
= ISC_FALSE
;
10177 REQUIRE(DNS_ZONE_VALID(zone
));
10178 INSIST(event
->ev_type
== DNS_EVENT_ZONECONTROL
);
10179 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
10180 zone_debuglog(zone
, "zone_shutdown", 3, "shutting down");
10183 * Stop things being restarted after we cancel them below.
10186 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXITING
);
10190 * If we were waiting for xfrin quota, step out of
10192 * If there's no zone manager, we can't be waiting for the
10195 if (zone
->zmgr
!= NULL
) {
10196 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
10197 if (zone
->statelist
== &zone
->zmgr
->waiting_for_xfrin
) {
10198 ISC_LIST_UNLINK(zone
->zmgr
->waiting_for_xfrin
, zone
,
10201 zone
->statelist
= NULL
;
10203 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
10207 * In task context, no locking required. See zone_xfrdone().
10209 if (zone
->xfr
!= NULL
)
10210 dns_xfrin_shutdown(zone
->xfr
);
10214 INSIST(zone
->irefs
> 0);
10217 if (zone
->request
!= NULL
) {
10218 dns_request_cancel(zone
->request
);
10221 if (zone
->readio
!= NULL
)
10222 zonemgr_cancelio(zone
->readio
);
10224 if (zone
->lctx
!= NULL
)
10225 dns_loadctx_cancel(zone
->lctx
);
10227 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) ||
10228 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
10229 if (zone
->writeio
!= NULL
)
10230 zonemgr_cancelio(zone
->writeio
);
10232 if (zone
->dctx
!= NULL
)
10233 dns_dumpctx_cancel(zone
->dctx
);
10236 notify_cancel(zone
);
10238 if (zone
->timer
!= NULL
) {
10239 isc_timer_detach(&zone
->timer
);
10240 INSIST(zone
->irefs
> 0);
10244 if (zone
->view
!= NULL
)
10245 dns_view_weakdetach(&zone
->view
);
10248 * We have now canceled everything set the flag to allow exit_check()
10249 * to succeed. We must not unlock between setting this flag and
10250 * calling exit_check().
10252 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SHUTDOWN
);
10253 free_needed
= exit_check(zone
);
10260 zone_timer(isc_task_t
*task
, isc_event_t
*event
) {
10261 const char me
[] = "zone_timer";
10262 dns_zone_t
*zone
= (dns_zone_t
*)event
->ev_arg
;
10265 REQUIRE(DNS_ZONE_VALID(zone
));
10269 zone_maintenance(zone
);
10271 isc_event_free(&event
);
10275 zone_settimer(dns_zone_t
*zone
, isc_time_t
*now
) {
10276 const char me
[] = "zone_settimer";
10278 isc_result_t result
;
10281 REQUIRE(DNS_ZONE_VALID(zone
));
10282 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
10285 isc_time_settoepoch(&next
);
10287 switch (zone
->type
) {
10288 case dns_zone_master
:
10289 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
10290 next
= zone
->notifytime
;
10291 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
10292 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
10293 INSIST(!isc_time_isepoch(&zone
->dumptime
));
10294 if (isc_time_isepoch(&next
) ||
10295 isc_time_compare(&zone
->dumptime
, &next
) < 0)
10296 next
= zone
->dumptime
;
10298 if (DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_MAINTAIN
) &&
10299 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESHING
)) {
10300 if (isc_time_isepoch(&next
) ||
10301 (!isc_time_isepoch(&zone
->refreshkeytime
) &&
10302 isc_time_compare(&zone
->refreshkeytime
, &next
) < 0))
10303 next
= zone
->refreshkeytime
;
10305 if (!isc_time_isepoch(&zone
->resigntime
)) {
10306 if (isc_time_isepoch(&next
) ||
10307 isc_time_compare(&zone
->resigntime
, &next
) < 0)
10308 next
= zone
->resigntime
;
10310 if (!isc_time_isepoch(&zone
->keywarntime
)) {
10311 if (isc_time_isepoch(&next
) ||
10312 isc_time_compare(&zone
->keywarntime
, &next
) < 0)
10313 next
= zone
->keywarntime
;
10315 if (!isc_time_isepoch(&zone
->signingtime
)) {
10316 if (isc_time_isepoch(&next
) ||
10317 isc_time_compare(&zone
->signingtime
, &next
) < 0)
10318 next
= zone
->signingtime
;
10320 if (!isc_time_isepoch(&zone
->nsec3chaintime
)) {
10321 if (isc_time_isepoch(&next
) ||
10322 isc_time_compare(&zone
->nsec3chaintime
, &next
) < 0)
10323 next
= zone
->nsec3chaintime
;
10327 case dns_zone_slave
:
10328 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
10329 next
= zone
->notifytime
;
10332 case dns_zone_stub
:
10333 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
) &&
10334 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOMASTERS
) &&
10335 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
) &&
10336 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
10337 INSIST(!isc_time_isepoch(&zone
->refreshtime
));
10338 if (isc_time_isepoch(&next
) ||
10339 isc_time_compare(&zone
->refreshtime
, &next
) < 0)
10340 next
= zone
->refreshtime
;
10342 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
10343 INSIST(!isc_time_isepoch(&zone
->expiretime
));
10344 if (isc_time_isepoch(&next
) ||
10345 isc_time_compare(&zone
->expiretime
, &next
) < 0)
10346 next
= zone
->expiretime
;
10348 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
10349 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
10350 INSIST(!isc_time_isepoch(&zone
->dumptime
));
10351 if (isc_time_isepoch(&next
) ||
10352 isc_time_compare(&zone
->dumptime
, &next
) < 0)
10353 next
= zone
->dumptime
;
10358 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
10359 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
10360 INSIST(!isc_time_isepoch(&zone
->dumptime
));
10361 if (isc_time_isepoch(&next
) ||
10362 isc_time_compare(&zone
->dumptime
, &next
) < 0)
10363 next
= zone
->dumptime
;
10365 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESHING
)) {
10366 if (isc_time_isepoch(&next
) ||
10367 (!isc_time_isepoch(&zone
->refreshkeytime
) &&
10368 isc_time_compare(&zone
->refreshkeytime
, &next
) < 0))
10369 next
= zone
->refreshkeytime
;
10377 if (isc_time_isepoch(&next
)) {
10378 zone_debuglog(zone
, me
, 10, "settimer inactive");
10379 result
= isc_timer_reset(zone
->timer
, isc_timertype_inactive
,
10380 NULL
, NULL
, ISC_TRUE
);
10381 if (result
!= ISC_R_SUCCESS
)
10382 dns_zone_log(zone
, ISC_LOG_ERROR
,
10383 "could not deactivate zone timer: %s",
10384 isc_result_totext(result
));
10386 if (isc_time_compare(&next
, now
) <= 0)
10388 result
= isc_timer_reset(zone
->timer
, isc_timertype_once
,
10389 &next
, NULL
, ISC_TRUE
);
10390 if (result
!= ISC_R_SUCCESS
)
10391 dns_zone_log(zone
, ISC_LOG_ERROR
,
10392 "could not reset zone timer: %s",
10393 isc_result_totext(result
));
10398 cancel_refresh(dns_zone_t
*zone
) {
10399 const char me
[] = "cancel_refresh";
10403 * 'zone' locked by caller.
10406 REQUIRE(DNS_ZONE_VALID(zone
));
10407 REQUIRE(LOCKED_ZONE(zone
));
10411 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
10413 zone_settimer(zone
, &now
);
10416 static isc_result_t
10417 notify_createmessage(dns_zone_t
*zone
, unsigned int flags
,
10418 dns_message_t
**messagep
)
10420 dns_db_t
*zonedb
= NULL
;
10421 dns_dbnode_t
*node
= NULL
;
10422 dns_dbversion_t
*version
= NULL
;
10423 dns_message_t
*message
= NULL
;
10424 dns_rdataset_t rdataset
;
10425 dns_rdata_t rdata
= DNS_RDATA_INIT
;
10427 dns_name_t
*tempname
= NULL
;
10428 dns_rdata_t
*temprdata
= NULL
;
10429 dns_rdatalist_t
*temprdatalist
= NULL
;
10430 dns_rdataset_t
*temprdataset
= NULL
;
10432 isc_result_t result
;
10434 isc_buffer_t
*b
= NULL
;
10436 REQUIRE(DNS_ZONE_VALID(zone
));
10437 REQUIRE(messagep
!= NULL
&& *messagep
== NULL
);
10439 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
10441 if (result
!= ISC_R_SUCCESS
)
10444 message
->opcode
= dns_opcode_notify
;
10445 message
->flags
|= DNS_MESSAGEFLAG_AA
;
10446 message
->rdclass
= zone
->rdclass
;
10448 result
= dns_message_gettempname(message
, &tempname
);
10449 if (result
!= ISC_R_SUCCESS
)
10452 result
= dns_message_gettemprdataset(message
, &temprdataset
);
10453 if (result
!= ISC_R_SUCCESS
)
10459 dns_name_init(tempname
, NULL
);
10460 dns_name_clone(&zone
->origin
, tempname
);
10461 dns_rdataset_init(temprdataset
);
10462 dns_rdataset_makequestion(temprdataset
, zone
->rdclass
,
10463 dns_rdatatype_soa
);
10464 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
10465 dns_message_addname(message
, tempname
, DNS_SECTION_QUESTION
);
10467 temprdataset
= NULL
;
10469 if ((flags
& DNS_NOTIFY_NOSOA
) != 0)
10472 result
= dns_message_gettempname(message
, &tempname
);
10473 if (result
!= ISC_R_SUCCESS
)
10475 result
= dns_message_gettemprdata(message
, &temprdata
);
10476 if (result
!= ISC_R_SUCCESS
)
10478 result
= dns_message_gettemprdataset(message
, &temprdataset
);
10479 if (result
!= ISC_R_SUCCESS
)
10481 result
= dns_message_gettemprdatalist(message
, &temprdatalist
);
10482 if (result
!= ISC_R_SUCCESS
)
10485 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
10486 INSIST(zone
->db
!= NULL
); /* XXXJT: is this assumption correct? */
10487 dns_db_attach(zone
->db
, &zonedb
);
10488 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
10490 dns_name_init(tempname
, NULL
);
10491 dns_name_clone(&zone
->origin
, tempname
);
10492 dns_db_currentversion(zonedb
, &version
);
10493 result
= dns_db_findnode(zonedb
, tempname
, ISC_FALSE
, &node
);
10494 if (result
!= ISC_R_SUCCESS
)
10497 dns_rdataset_init(&rdataset
);
10498 result
= dns_db_findrdataset(zonedb
, node
, version
,
10500 dns_rdatatype_none
, 0, &rdataset
,
10502 if (result
!= ISC_R_SUCCESS
)
10504 result
= dns_rdataset_first(&rdataset
);
10505 if (result
!= ISC_R_SUCCESS
)
10507 dns_rdataset_current(&rdataset
, &rdata
);
10508 dns_rdata_toregion(&rdata
, &r
);
10509 result
= isc_buffer_allocate(zone
->mctx
, &b
, r
.length
);
10510 if (result
!= ISC_R_SUCCESS
)
10512 isc_buffer_putmem(b
, r
.base
, r
.length
);
10513 isc_buffer_usedregion(b
, &r
);
10514 dns_rdata_init(temprdata
);
10515 dns_rdata_fromregion(temprdata
, rdata
.rdclass
, rdata
.type
, &r
);
10516 dns_message_takebuffer(message
, &b
);
10517 result
= dns_rdataset_next(&rdataset
);
10518 dns_rdataset_disassociate(&rdataset
);
10519 if (result
!= ISC_R_NOMORE
)
10521 temprdatalist
->rdclass
= rdata
.rdclass
;
10522 temprdatalist
->type
= rdata
.type
;
10523 temprdatalist
->covers
= 0;
10524 temprdatalist
->ttl
= rdataset
.ttl
;
10525 ISC_LIST_INIT(temprdatalist
->rdata
);
10526 ISC_LIST_APPEND(temprdatalist
->rdata
, temprdata
, link
);
10528 dns_rdataset_init(temprdataset
);
10529 result
= dns_rdatalist_tordataset(temprdatalist
, temprdataset
);
10530 if (result
!= ISC_R_SUCCESS
)
10533 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
10534 dns_message_addname(message
, tempname
, DNS_SECTION_ANSWER
);
10535 temprdatalist
= NULL
;
10536 temprdataset
= NULL
;
10542 dns_db_detachnode(zonedb
, &node
);
10543 if (version
!= NULL
)
10544 dns_db_closeversion(zonedb
, &version
, ISC_FALSE
);
10545 if (zonedb
!= NULL
)
10546 dns_db_detach(&zonedb
);
10547 if (tempname
!= NULL
)
10548 dns_message_puttempname(message
, &tempname
);
10549 if (temprdata
!= NULL
)
10550 dns_message_puttemprdata(message
, &temprdata
);
10551 if (temprdataset
!= NULL
)
10552 dns_message_puttemprdataset(message
, &temprdataset
);
10553 if (temprdatalist
!= NULL
)
10554 dns_message_puttemprdatalist(message
, &temprdatalist
);
10557 *messagep
= message
;
10558 return (ISC_R_SUCCESS
);
10561 if (tempname
!= NULL
)
10562 dns_message_puttempname(message
, &tempname
);
10563 if (temprdataset
!= NULL
)
10564 dns_message_puttemprdataset(message
, &temprdataset
);
10565 dns_message_destroy(&message
);
10570 dns_zone_notifyreceive(dns_zone_t
*zone
, isc_sockaddr_t
*from
,
10571 dns_message_t
*msg
)
10574 dns_rdata_soa_t soa
;
10575 dns_rdataset_t
*rdataset
= NULL
;
10576 dns_rdata_t rdata
= DNS_RDATA_INIT
;
10577 isc_result_t result
;
10578 char fromtext
[ISC_SOCKADDR_FORMATSIZE
];
10580 isc_netaddr_t netaddr
;
10582 REQUIRE(DNS_ZONE_VALID(zone
));
10585 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
10589 * Check that 'from' is a valid notify source, (zone->masters).
10590 * Return DNS_R_REFUSED if not.
10592 * If the notify message contains a serial number check it
10593 * against the zones serial and return if <= current serial
10595 * If a refresh check is progress, if so just record the
10596 * fact we received a NOTIFY and from where and return.
10597 * We will perform a new refresh check when the current one
10598 * completes. Return ISC_R_SUCCESS.
10600 * Otherwise initiate a refresh check using 'from' as the
10601 * first address to check. Return ISC_R_SUCCESS.
10604 isc_sockaddr_format(from
, fromtext
, sizeof(fromtext
));
10607 * We only handle NOTIFY (SOA) at the present.
10610 if (isc_sockaddr_pf(from
) == PF_INET
)
10611 inc_stats(zone
, dns_zonestatscounter_notifyinv4
);
10613 inc_stats(zone
, dns_zonestatscounter_notifyinv6
);
10614 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0 ||
10615 dns_message_findname(msg
, DNS_SECTION_QUESTION
, &zone
->origin
,
10616 dns_rdatatype_soa
, dns_rdatatype_none
,
10617 NULL
, NULL
) != ISC_R_SUCCESS
) {
10619 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0) {
10620 dns_zone_log(zone
, ISC_LOG_NOTICE
,
10622 "question section from: %s", fromtext
);
10623 return (DNS_R_FORMERR
);
10625 dns_zone_log(zone
, ISC_LOG_NOTICE
,
10626 "NOTIFY zone does not match");
10627 return (DNS_R_NOTIMP
);
10631 * If we are a master zone just succeed.
10633 if (zone
->type
== dns_zone_master
) {
10635 return (ISC_R_SUCCESS
);
10638 isc_netaddr_fromsockaddr(&netaddr
, from
);
10639 for (i
= 0; i
< zone
->masterscnt
; i
++) {
10640 if (isc_sockaddr_eqaddr(from
, &zone
->masters
[i
]))
10642 if (zone
->view
->aclenv
.match_mapped
&&
10643 IN6_IS_ADDR_V4MAPPED(&from
->type
.sin6
.sin6_addr
) &&
10644 isc_sockaddr_pf(&zone
->masters
[i
]) == AF_INET
) {
10645 isc_netaddr_t na1
, na2
;
10646 isc_netaddr_fromv4mapped(&na1
, &netaddr
);
10647 isc_netaddr_fromsockaddr(&na2
, &zone
->masters
[i
]);
10648 if (isc_netaddr_equal(&na1
, &na2
))
10654 * Accept notify requests from non masters if they are on
10655 * 'zone->notify_acl'.
10657 if (i
>= zone
->masterscnt
&& zone
->notify_acl
!= NULL
&&
10658 dns_acl_match(&netaddr
, NULL
, zone
->notify_acl
,
10659 &zone
->view
->aclenv
,
10660 &match
, NULL
) == ISC_R_SUCCESS
&&
10663 /* Accept notify. */
10664 } else if (i
>= zone
->masterscnt
) {
10666 dns_zone_log(zone
, ISC_LOG_INFO
,
10667 "refused notify from non-master: %s", fromtext
);
10668 inc_stats(zone
, dns_zonestatscounter_notifyrej
);
10669 return (DNS_R_REFUSED
);
10673 * If the zone is loaded and there are answers check the serial
10674 * to see if we need to do a refresh. Do not worry about this
10675 * check if we are a dialup zone as we use the notify request
10676 * to trigger a refresh check.
10678 if (msg
->counts
[DNS_SECTION_ANSWER
] > 0 &&
10679 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
10680 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
)) {
10681 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
,
10684 dns_rdatatype_none
, NULL
,
10686 if (result
== ISC_R_SUCCESS
)
10687 result
= dns_rdataset_first(rdataset
);
10688 if (result
== ISC_R_SUCCESS
) {
10689 isc_uint32_t serial
= 0, oldserial
;
10691 dns_rdataset_current(rdataset
, &rdata
);
10692 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
10693 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
10694 serial
= soa
.serial
;
10696 * The following should safely be performed without DB
10697 * lock and succeed in this context.
10699 result
= zone_get_from_db(zone
, zone
->db
, NULL
, NULL
,
10700 &oldserial
, NULL
, NULL
, NULL
,
10702 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
10703 if (isc_serial_le(serial
, oldserial
)) {
10704 dns_zone_log(zone
, ISC_LOG_INFO
,
10706 "zone is up to date",
10709 return (ISC_R_SUCCESS
);
10715 * If we got this far and there was a refresh in progress just
10716 * let it complete. Record where we got the notify from so we
10717 * can perform a refresh check when the current one completes
10719 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
)) {
10720 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
10721 zone
->notifyfrom
= *from
;
10723 dns_zone_log(zone
, ISC_LOG_INFO
,
10724 "notify from %s: refresh in progress, "
10725 "refresh check queued",
10727 return (ISC_R_SUCCESS
);
10729 zone
->notifyfrom
= *from
;
10731 dns_zone_refresh(zone
);
10732 return (ISC_R_SUCCESS
);
10736 dns_zone_setnotifyacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
10738 REQUIRE(DNS_ZONE_VALID(zone
));
10741 if (zone
->notify_acl
!= NULL
)
10742 dns_acl_detach(&zone
->notify_acl
);
10743 dns_acl_attach(acl
, &zone
->notify_acl
);
10748 dns_zone_setqueryacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
10750 REQUIRE(DNS_ZONE_VALID(zone
));
10753 if (zone
->query_acl
!= NULL
)
10754 dns_acl_detach(&zone
->query_acl
);
10755 dns_acl_attach(acl
, &zone
->query_acl
);
10760 dns_zone_setqueryonacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
10762 REQUIRE(DNS_ZONE_VALID(zone
));
10765 if (zone
->queryon_acl
!= NULL
)
10766 dns_acl_detach(&zone
->queryon_acl
);
10767 dns_acl_attach(acl
, &zone
->queryon_acl
);
10772 dns_zone_setupdateacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
10774 REQUIRE(DNS_ZONE_VALID(zone
));
10777 if (zone
->update_acl
!= NULL
)
10778 dns_acl_detach(&zone
->update_acl
);
10779 dns_acl_attach(acl
, &zone
->update_acl
);
10784 dns_zone_setforwardacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
10786 REQUIRE(DNS_ZONE_VALID(zone
));
10789 if (zone
->forward_acl
!= NULL
)
10790 dns_acl_detach(&zone
->forward_acl
);
10791 dns_acl_attach(acl
, &zone
->forward_acl
);
10796 dns_zone_setxfracl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
10798 REQUIRE(DNS_ZONE_VALID(zone
));
10801 if (zone
->xfr_acl
!= NULL
)
10802 dns_acl_detach(&zone
->xfr_acl
);
10803 dns_acl_attach(acl
, &zone
->xfr_acl
);
10808 dns_zone_getnotifyacl(dns_zone_t
*zone
) {
10810 REQUIRE(DNS_ZONE_VALID(zone
));
10812 return (zone
->notify_acl
);
10816 dns_zone_getqueryacl(dns_zone_t
*zone
) {
10818 REQUIRE(DNS_ZONE_VALID(zone
));
10820 return (zone
->query_acl
);
10824 dns_zone_getqueryonacl(dns_zone_t
*zone
) {
10826 REQUIRE(DNS_ZONE_VALID(zone
));
10828 return (zone
->queryon_acl
);
10832 dns_zone_getupdateacl(dns_zone_t
*zone
) {
10834 REQUIRE(DNS_ZONE_VALID(zone
));
10836 return (zone
->update_acl
);
10840 dns_zone_getforwardacl(dns_zone_t
*zone
) {
10842 REQUIRE(DNS_ZONE_VALID(zone
));
10844 return (zone
->forward_acl
);
10848 dns_zone_getxfracl(dns_zone_t
*zone
) {
10850 REQUIRE(DNS_ZONE_VALID(zone
));
10852 return (zone
->xfr_acl
);
10856 dns_zone_clearupdateacl(dns_zone_t
*zone
) {
10858 REQUIRE(DNS_ZONE_VALID(zone
));
10861 if (zone
->update_acl
!= NULL
)
10862 dns_acl_detach(&zone
->update_acl
);
10867 dns_zone_clearforwardacl(dns_zone_t
*zone
) {
10869 REQUIRE(DNS_ZONE_VALID(zone
));
10872 if (zone
->forward_acl
!= NULL
)
10873 dns_acl_detach(&zone
->forward_acl
);
10878 dns_zone_clearnotifyacl(dns_zone_t
*zone
) {
10880 REQUIRE(DNS_ZONE_VALID(zone
));
10883 if (zone
->notify_acl
!= NULL
)
10884 dns_acl_detach(&zone
->notify_acl
);
10889 dns_zone_clearqueryacl(dns_zone_t
*zone
) {
10891 REQUIRE(DNS_ZONE_VALID(zone
));
10894 if (zone
->query_acl
!= NULL
)
10895 dns_acl_detach(&zone
->query_acl
);
10900 dns_zone_clearqueryonacl(dns_zone_t
*zone
) {
10902 REQUIRE(DNS_ZONE_VALID(zone
));
10905 if (zone
->queryon_acl
!= NULL
)
10906 dns_acl_detach(&zone
->queryon_acl
);
10911 dns_zone_clearxfracl(dns_zone_t
*zone
) {
10913 REQUIRE(DNS_ZONE_VALID(zone
));
10916 if (zone
->xfr_acl
!= NULL
)
10917 dns_acl_detach(&zone
->xfr_acl
);
10922 dns_zone_getupdatedisabled(dns_zone_t
*zone
) {
10923 REQUIRE(DNS_ZONE_VALID(zone
));
10924 return (zone
->update_disabled
);
10929 dns_zone_setupdatedisabled(dns_zone_t
*zone
, isc_boolean_t state
) {
10930 REQUIRE(DNS_ZONE_VALID(zone
));
10931 zone
->update_disabled
= state
;
10935 dns_zone_getzeronosoattl(dns_zone_t
*zone
) {
10936 REQUIRE(DNS_ZONE_VALID(zone
));
10937 return (zone
->zero_no_soa_ttl
);
10942 dns_zone_setzeronosoattl(dns_zone_t
*zone
, isc_boolean_t state
) {
10943 REQUIRE(DNS_ZONE_VALID(zone
));
10944 zone
->zero_no_soa_ttl
= state
;
10948 dns_zone_setchecknames(dns_zone_t
*zone
, dns_severity_t severity
) {
10950 REQUIRE(DNS_ZONE_VALID(zone
));
10952 zone
->check_names
= severity
;
10956 dns_zone_getchecknames(dns_zone_t
*zone
) {
10958 REQUIRE(DNS_ZONE_VALID(zone
));
10960 return (zone
->check_names
);
10964 dns_zone_setjournalsize(dns_zone_t
*zone
, isc_int32_t size
) {
10966 REQUIRE(DNS_ZONE_VALID(zone
));
10968 zone
->journalsize
= size
;
10972 dns_zone_getjournalsize(dns_zone_t
*zone
) {
10974 REQUIRE(DNS_ZONE_VALID(zone
));
10976 return (zone
->journalsize
);
10980 zone_namerd_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
10981 isc_result_t result
= ISC_R_FAILURE
;
10982 isc_buffer_t buffer
;
10984 REQUIRE(buf
!= NULL
);
10985 REQUIRE(length
> 1U);
10988 * Leave space for terminating '\0'.
10990 isc_buffer_init(&buffer
, buf
, length
- 1);
10991 if (dns_name_dynamic(&zone
->origin
))
10992 result
= dns_name_totext(&zone
->origin
, ISC_TRUE
, &buffer
);
10993 if (result
!= ISC_R_SUCCESS
&&
10994 isc_buffer_availablelength(&buffer
) >= (sizeof("<UNKNOWN>") - 1))
10995 isc_buffer_putstr(&buffer
, "<UNKNOWN>");
10997 if (isc_buffer_availablelength(&buffer
) > 0)
10998 isc_buffer_putstr(&buffer
, "/");
10999 (void)dns_rdataclass_totext(zone
->rdclass
, &buffer
);
11001 if (zone
->view
!= NULL
&& strcmp(zone
->view
->name
, "_bind") != 0 &&
11002 strcmp(zone
->view
->name
, "_default") != 0 &&
11003 strlen(zone
->view
->name
) < isc_buffer_availablelength(&buffer
)) {
11004 isc_buffer_putstr(&buffer
, "/");
11005 isc_buffer_putstr(&buffer
, zone
->view
->name
);
11008 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
11012 zone_name_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
11013 isc_result_t result
= ISC_R_FAILURE
;
11014 isc_buffer_t buffer
;
11016 REQUIRE(buf
!= NULL
);
11017 REQUIRE(length
> 1U);
11020 * Leave space for terminating '\0'.
11022 isc_buffer_init(&buffer
, buf
, length
- 1);
11023 if (dns_name_dynamic(&zone
->origin
))
11024 result
= dns_name_totext(&zone
->origin
, ISC_TRUE
, &buffer
);
11025 if (result
!= ISC_R_SUCCESS
&&
11026 isc_buffer_availablelength(&buffer
) >= (sizeof("<UNKNOWN>") - 1))
11027 isc_buffer_putstr(&buffer
, "<UNKNOWN>");
11029 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
11033 zone_rdclass_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
11034 isc_buffer_t buffer
;
11036 REQUIRE(buf
!= NULL
);
11037 REQUIRE(length
> 1U);
11040 * Leave space for terminating '\0'.
11042 isc_buffer_init(&buffer
, buf
, length
- 1);
11043 (void)dns_rdataclass_totext(zone
->rdclass
, &buffer
);
11045 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
11049 zone_viewname_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
11050 isc_buffer_t buffer
;
11052 REQUIRE(buf
!= NULL
);
11053 REQUIRE(length
> 1U);
11057 * Leave space for terminating '\0'.
11059 isc_buffer_init(&buffer
, buf
, length
- 1);
11061 if (zone
->view
== NULL
) {
11062 isc_buffer_putstr(&buffer
, "_none");
11063 } else if (strlen(zone
->view
->name
)
11064 < isc_buffer_availablelength(&buffer
)) {
11065 isc_buffer_putstr(&buffer
, zone
->view
->name
);
11067 isc_buffer_putstr(&buffer
, "_toolong");
11070 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
11074 dns_zone_name(dns_zone_t
*zone
, char *buf
, size_t length
) {
11075 REQUIRE(DNS_ZONE_VALID(zone
));
11076 REQUIRE(buf
!= NULL
);
11077 zone_namerd_tostr(zone
, buf
, length
);
11081 notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
11083 char message
[4096];
11085 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
11089 vsnprintf(message
, sizeof(message
), fmt
, ap
);
11091 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_NOTIFY
, DNS_LOGMODULE_ZONE
,
11092 level
, "zone %s: %s", zone
->strnamerd
, message
);
11096 dns_zone_logc(dns_zone_t
*zone
, isc_logcategory_t
*category
,
11097 int level
, const char *fmt
, ...) {
11099 char message
[4096];
11101 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
11105 vsnprintf(message
, sizeof(message
), fmt
, ap
);
11107 isc_log_write(dns_lctx
, category
, DNS_LOGMODULE_ZONE
,
11108 level
, "zone %s: %s", zone
->strnamerd
, message
);
11112 dns_zone_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
11114 char message
[4096];
11116 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
11120 vsnprintf(message
, sizeof(message
), fmt
, ap
);
11122 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
11123 level
, "zone %s: %s", zone
->strnamerd
, message
);
11127 zone_debuglog(dns_zone_t
*zone
, const char *me
, int debuglevel
,
11128 const char *fmt
, ...)
11131 char message
[4096];
11132 int level
= ISC_LOG_DEBUG(debuglevel
);
11134 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
11138 vsnprintf(message
, sizeof(message
), fmt
, ap
);
11140 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
11141 level
, "%s: zone %s: %s", me
, zone
->strnamerd
, message
);
11145 message_count(dns_message_t
*msg
, dns_section_t section
, dns_rdatatype_t type
)
11147 isc_result_t result
;
11149 dns_rdataset_t
*curr
;
11152 result
= dns_message_firstname(msg
, section
);
11153 while (result
== ISC_R_SUCCESS
) {
11155 dns_message_currentname(msg
, section
, &name
);
11157 for (curr
= ISC_LIST_TAIL(name
->list
); curr
!= NULL
;
11158 curr
= ISC_LIST_PREV(curr
, link
)) {
11159 if (curr
->type
== type
)
11162 result
= dns_message_nextname(msg
, section
);
11169 dns_zone_setmaxxfrin(dns_zone_t
*zone
, isc_uint32_t maxxfrin
) {
11170 REQUIRE(DNS_ZONE_VALID(zone
));
11172 zone
->maxxfrin
= maxxfrin
;
11176 dns_zone_getmaxxfrin(dns_zone_t
*zone
) {
11177 REQUIRE(DNS_ZONE_VALID(zone
));
11179 return (zone
->maxxfrin
);
11183 dns_zone_setmaxxfrout(dns_zone_t
*zone
, isc_uint32_t maxxfrout
) {
11184 REQUIRE(DNS_ZONE_VALID(zone
));
11185 zone
->maxxfrout
= maxxfrout
;
11189 dns_zone_getmaxxfrout(dns_zone_t
*zone
) {
11190 REQUIRE(DNS_ZONE_VALID(zone
));
11192 return (zone
->maxxfrout
);
11196 dns_zone_gettype(dns_zone_t
*zone
) {
11197 REQUIRE(DNS_ZONE_VALID(zone
));
11199 return (zone
->type
);
11203 dns_zone_getorigin(dns_zone_t
*zone
) {
11204 REQUIRE(DNS_ZONE_VALID(zone
));
11206 return (&zone
->origin
);
11210 dns_zone_settask(dns_zone_t
*zone
, isc_task_t
*task
) {
11211 REQUIRE(DNS_ZONE_VALID(zone
));
11214 if (zone
->task
!= NULL
)
11215 isc_task_detach(&zone
->task
);
11216 isc_task_attach(task
, &zone
->task
);
11217 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
11218 if (zone
->db
!= NULL
)
11219 dns_db_settask(zone
->db
, zone
->task
);
11220 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
11225 dns_zone_gettask(dns_zone_t
*zone
, isc_task_t
**target
) {
11226 REQUIRE(DNS_ZONE_VALID(zone
));
11227 isc_task_attach(zone
->task
, target
);
11231 dns_zone_setidlein(dns_zone_t
*zone
, isc_uint32_t idlein
) {
11232 REQUIRE(DNS_ZONE_VALID(zone
));
11235 idlein
= DNS_DEFAULT_IDLEIN
;
11236 zone
->idlein
= idlein
;
11240 dns_zone_getidlein(dns_zone_t
*zone
) {
11241 REQUIRE(DNS_ZONE_VALID(zone
));
11243 return (zone
->idlein
);
11247 dns_zone_setidleout(dns_zone_t
*zone
, isc_uint32_t idleout
) {
11248 REQUIRE(DNS_ZONE_VALID(zone
));
11250 zone
->idleout
= idleout
;
11254 dns_zone_getidleout(dns_zone_t
*zone
) {
11255 REQUIRE(DNS_ZONE_VALID(zone
));
11257 return (zone
->idleout
);
11261 notify_done(isc_task_t
*task
, isc_event_t
*event
) {
11262 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
11263 dns_notify_t
*notify
;
11264 isc_result_t result
;
11265 dns_message_t
*message
= NULL
;
11268 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
11272 notify
= event
->ev_arg
;
11273 REQUIRE(DNS_NOTIFY_VALID(notify
));
11274 INSIST(task
== notify
->zone
->task
);
11276 isc_buffer_init(&buf
, rcode
, sizeof(rcode
));
11277 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
11279 result
= revent
->result
;
11280 if (result
== ISC_R_SUCCESS
)
11281 result
= dns_message_create(notify
->zone
->mctx
,
11282 DNS_MESSAGE_INTENTPARSE
, &message
);
11283 if (result
== ISC_R_SUCCESS
)
11284 result
= dns_request_getresponse(revent
->request
, message
,
11285 DNS_MESSAGEPARSE_PRESERVEORDER
);
11286 if (result
== ISC_R_SUCCESS
)
11287 result
= dns_rcode_totext(message
->rcode
, &buf
);
11288 if (result
== ISC_R_SUCCESS
)
11289 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
11290 "notify response from %s: %.*s",
11291 addrbuf
, (int)buf
.used
, rcode
);
11293 notify_log(notify
->zone
, ISC_LOG_DEBUG(2),
11294 "notify to %s failed: %s", addrbuf
,
11295 dns_result_totext(result
));
11298 * Old bind's return formerr if they see a soa record. Retry w/o
11299 * the soa if we see a formerr and had sent a SOA.
11301 isc_event_free(&event
);
11302 if (message
!= NULL
&& message
->rcode
== dns_rcode_formerr
&&
11303 (notify
->flags
& DNS_NOTIFY_NOSOA
) == 0) {
11304 notify
->flags
|= DNS_NOTIFY_NOSOA
;
11305 dns_request_destroy(¬ify
->request
);
11306 result
= notify_send_queue(notify
);
11307 if (result
!= ISC_R_SUCCESS
)
11308 notify_destroy(notify
, ISC_FALSE
);
11310 if (result
== ISC_R_TIMEDOUT
)
11311 notify_log(notify
->zone
, ISC_LOG_DEBUG(1),
11312 "notify to %s: retries exceeded", addrbuf
);
11313 notify_destroy(notify
, ISC_FALSE
);
11315 if (message
!= NULL
)
11316 dns_message_destroy(&message
);
11320 dns_zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
11321 isc_result_t result
;
11323 REQUIRE(DNS_ZONE_VALID(zone
));
11325 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
11326 result
= zone_replacedb(zone
, db
, dump
);
11327 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
11332 static isc_result_t
11333 zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
11334 dns_dbversion_t
*ver
;
11335 isc_result_t result
;
11336 unsigned int soacount
= 0;
11337 unsigned int nscount
= 0;
11340 * 'zone' and 'zonedb' locked by caller.
11342 REQUIRE(DNS_ZONE_VALID(zone
));
11343 REQUIRE(LOCKED_ZONE(zone
));
11345 result
= zone_get_from_db(zone
, db
, &nscount
, &soacount
,
11346 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
11347 if (result
== ISC_R_SUCCESS
) {
11348 if (soacount
!= 1) {
11349 dns_zone_log(zone
, ISC_LOG_ERROR
,
11350 "has %d SOA records", soacount
);
11351 result
= DNS_R_BADZONE
;
11353 if (nscount
== 0 && zone
->type
!= dns_zone_key
) {
11354 dns_zone_log(zone
, ISC_LOG_ERROR
, "has no NS records");
11355 result
= DNS_R_BADZONE
;
11357 if (result
!= ISC_R_SUCCESS
)
11360 dns_zone_log(zone
, ISC_LOG_ERROR
,
11361 "retrieving SOA and NS records failed: %s",
11362 dns_result_totext(result
));
11366 result
= check_nsec3param(zone
, db
);
11367 if (result
!= ISC_R_SUCCESS
)
11371 dns_db_currentversion(db
, &ver
);
11374 * The initial version of a slave zone is always dumped;
11375 * subsequent versions may be journaled instead if this
11376 * is enabled in the configuration.
11378 if (zone
->db
!= NULL
&& zone
->journal
!= NULL
&&
11379 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
) &&
11380 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
)) {
11381 isc_uint32_t serial
, oldserial
;
11383 dns_zone_log(zone
, ISC_LOG_DEBUG(3), "generating diffs");
11385 result
= dns_db_getsoaserial(db
, ver
, &serial
);
11386 if (result
!= ISC_R_SUCCESS
) {
11387 dns_zone_log(zone
, ISC_LOG_ERROR
,
11388 "ixfr-from-differences: unable to get "
11394 * This is checked in zone_postload() for master zones.
11396 result
= zone_get_from_db(zone
, zone
->db
, NULL
, NULL
,
11397 &oldserial
, NULL
, NULL
, NULL
, NULL
,
11399 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
11400 if (zone
->type
== dns_zone_slave
&&
11401 !isc_serial_gt(serial
, oldserial
)) {
11402 isc_uint32_t serialmin
, serialmax
;
11403 serialmin
= (oldserial
+ 1) & 0xffffffffU
;
11404 serialmax
= (oldserial
+ 0x7fffffffU
) & 0xffffffffU
;
11405 dns_zone_log(zone
, ISC_LOG_ERROR
,
11406 "ixfr-from-differences: failed: "
11407 "new serial (%u) out of range [%u - %u]",
11408 serial
, serialmin
, serialmax
);
11409 result
= ISC_R_RANGE
;
11413 result
= dns_db_diff(zone
->mctx
, db
, ver
, zone
->db
, NULL
,
11415 if (result
!= ISC_R_SUCCESS
)
11418 zone_needdump(zone
, DNS_DUMP_DELAY
);
11419 else if (zone
->journalsize
!= -1) {
11420 result
= dns_journal_compact(zone
->mctx
, zone
->journal
,
11421 serial
, zone
->journalsize
);
11423 case ISC_R_SUCCESS
:
11424 case ISC_R_NOSPACE
:
11425 case ISC_R_NOTFOUND
:
11426 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
11427 "dns_journal_compact: %s",
11428 dns_result_totext(result
));
11431 dns_zone_log(zone
, ISC_LOG_ERROR
,
11432 "dns_journal_compact failed: %s",
11433 dns_result_totext(result
));
11438 if (dump
&& zone
->masterfile
!= NULL
) {
11439 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
11440 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
11441 "dumping new zone version");
11442 result
= dns_db_dump2(db
, ver
, zone
->masterfile
,
11443 zone
->masterformat
);
11444 if (result
!= ISC_R_SUCCESS
)
11448 * Update the time the zone was updated, so
11449 * dns_zone_load can avoid loading it when
11450 * the server is reloaded. If isc_time_now
11451 * fails for some reason, all that happens is
11452 * the timestamp is not updated.
11454 TIME_NOW(&zone
->loadtime
);
11457 if (dump
&& zone
->journal
!= NULL
) {
11459 * The in-memory database just changed, and
11460 * because 'dump' is set, it didn't change by
11461 * being loaded from disk. Also, we have not
11462 * journaled diffs for this change.
11463 * Therefore, the on-disk journal is missing
11464 * the deltas for this change. Since it can
11465 * no longer be used to bring the zone
11466 * up-to-date, it is useless and should be
11469 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
11470 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
11471 "removing journal file");
11472 if (remove(zone
->journal
) < 0 && errno
!= ENOENT
) {
11473 char strbuf
[ISC_STRERRORSIZE
];
11474 isc__strerror(errno
, strbuf
, sizeof(strbuf
));
11475 isc_log_write(dns_lctx
,
11476 DNS_LOGCATEGORY_GENERAL
,
11477 DNS_LOGMODULE_ZONE
,
11479 "unable to remove journal "
11481 zone
->journal
, strbuf
);
11486 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
11488 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
11489 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
11490 "replacing zone database");
11492 if (zone
->db
!= NULL
)
11493 zone_detachdb(zone
);
11494 zone_attachdb(zone
, db
);
11495 dns_db_settask(zone
->db
, zone
->task
);
11496 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
11497 return (ISC_R_SUCCESS
);
11500 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
11504 /* The caller must hold the dblock as a writer. */
11506 zone_attachdb(dns_zone_t
*zone
, dns_db_t
*db
) {
11507 REQUIRE(zone
->db
== NULL
&& db
!= NULL
);
11509 dns_db_attach(db
, &zone
->db
);
11510 if (zone
->acache
!= NULL
) {
11511 isc_result_t result
;
11512 result
= dns_acache_setdb(zone
->acache
, db
);
11513 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_EXISTS
) {
11514 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
11515 "dns_acache_setdb() failed: %s",
11516 isc_result_totext(result
));
11521 /* The caller must hold the dblock as a writer. */
11523 zone_detachdb(dns_zone_t
*zone
) {
11524 REQUIRE(zone
->db
!= NULL
);
11526 if (zone
->acache
!= NULL
)
11527 (void)dns_acache_putdb(zone
->acache
, zone
->db
);
11528 dns_db_detach(&zone
->db
);
11532 zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
) {
11534 isc_boolean_t again
= ISC_FALSE
;
11535 unsigned int soacount
;
11536 unsigned int nscount
;
11537 isc_uint32_t serial
, refresh
, retry
, expire
, minimum
;
11538 isc_result_t xfrresult
= result
;
11539 isc_boolean_t free_needed
;
11541 REQUIRE(DNS_ZONE_VALID(zone
));
11543 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11544 "zone transfer finished: %s", dns_result_totext(result
));
11547 INSIST((zone
->flags
& DNS_ZONEFLG_REFRESH
) != 0);
11548 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
11549 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
);
11553 case ISC_R_SUCCESS
:
11554 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
11556 case DNS_R_UPTODATE
:
11557 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
11559 * Has the zone expired underneath us?
11561 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
11562 if (zone
->db
== NULL
) {
11563 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
11568 * Update the zone structure's data from the actual
11573 INSIST(zone
->db
!= NULL
);
11574 result
= zone_get_from_db(zone
, zone
->db
, &nscount
,
11575 &soacount
, &serial
, &refresh
,
11576 &retry
, &expire
, &minimum
, NULL
);
11577 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
11578 if (result
== ISC_R_SUCCESS
) {
11580 dns_zone_log(zone
, ISC_LOG_ERROR
,
11581 "transferred zone "
11582 "has %d SOA record%s", soacount
,
11583 (soacount
!= 0) ? "s" : "");
11584 if (nscount
== 0) {
11585 dns_zone_log(zone
, ISC_LOG_ERROR
,
11586 "transferred zone "
11587 "has no NS records");
11588 if (DNS_ZONE_FLAG(zone
,
11589 DNS_ZONEFLG_HAVETIMERS
)) {
11590 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
11591 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
11593 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
11597 zone
->refresh
= RANGE(refresh
, zone
->minrefresh
,
11599 zone
->retry
= RANGE(retry
, zone
->minretry
,
11601 zone
->expire
= RANGE(expire
,
11602 zone
->refresh
+ zone
->retry
,
11604 zone
->minimum
= minimum
;
11605 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
11609 * Set our next update/expire times.
11611 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
11612 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
11613 zone
->refreshtime
= now
;
11614 DNS_ZONE_TIME_ADD(&now
, zone
->expire
,
11615 &zone
->expiretime
);
11617 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
,
11618 &zone
->refreshtime
);
11619 DNS_ZONE_TIME_ADD(&now
, zone
->expire
,
11620 &zone
->expiretime
);
11622 if (result
== ISC_R_SUCCESS
&& xfrresult
== ISC_R_SUCCESS
) {
11623 char buf
[DNS_NAME_FORMATSIZE
+ sizeof(": TSIG ''")];
11624 if (zone
->tsigkey
!= NULL
) {
11625 char namebuf
[DNS_NAME_FORMATSIZE
];
11626 dns_name_format(&zone
->tsigkey
->name
, namebuf
,
11628 snprintf(buf
, sizeof(buf
), ": TSIG '%s'",
11632 dns_zone_log(zone
, ISC_LOG_INFO
,
11633 "transferred serial %u%s",
11638 * This is not necessary if we just performed a AXFR
11639 * however it is necessary for an IXFR / UPTODATE and
11640 * won't hurt with an AXFR.
11642 if (zone
->masterfile
!= NULL
|| zone
->journal
!= NULL
) {
11643 result
= ISC_R_FAILURE
;
11644 if (zone
->journal
!= NULL
)
11645 result
= isc_file_settime(zone
->journal
, &now
);
11646 if (result
!= ISC_R_SUCCESS
&&
11647 zone
->masterfile
!= NULL
)
11648 result
= isc_file_settime(zone
->masterfile
,
11650 /* Someone removed the file from underneath us! */
11651 if (result
== ISC_R_FILENOTFOUND
&&
11652 zone
->masterfile
!= NULL
)
11653 zone_needdump(zone
, DNS_DUMP_DELAY
);
11654 else if (result
!= ISC_R_SUCCESS
)
11655 dns_zone_log(zone
, ISC_LOG_ERROR
,
11656 "transfer: could not set file "
11657 "modification time of '%s': %s",
11659 dns_result_totext(result
));
11662 inc_stats(zone
, dns_zonestatscounter_xfrsuccess
);
11665 case DNS_R_BADIXFR
:
11666 /* Force retry with AXFR. */
11667 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
11673 * Skip to next failed / untried master.
11677 } while (zone
->curmaster
< zone
->masterscnt
&&
11678 zone
->mastersok
[zone
->curmaster
]);
11681 if (zone
->curmaster
>= zone
->masterscnt
) {
11682 zone
->curmaster
= 0;
11683 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
11684 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
11685 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
11686 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
11687 while (zone
->curmaster
< zone
->masterscnt
&&
11688 zone
->mastersok
[zone
->curmaster
])
11692 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
11694 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
11697 inc_stats(zone
, dns_zonestatscounter_xfrfail
);
11700 zone_settimer(zone
, &now
);
11703 * If creating the transfer object failed, zone->xfr is NULL.
11704 * Otherwise, we are called as the done callback of a zone
11705 * transfer object that just entered its shutting-down
11706 * state. Since we are no longer responsible for shutting
11707 * it down, we can detach our reference.
11709 if (zone
->xfr
!= NULL
)
11710 dns_xfrin_detach(&zone
->xfr
);
11712 if (zone
->tsigkey
!= NULL
)
11713 dns_tsigkey_detach(&zone
->tsigkey
);
11716 * Handle any deferred journal compaction.
11718 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
)) {
11719 result
= dns_journal_compact(zone
->mctx
, zone
->journal
,
11720 zone
->compact_serial
,
11721 zone
->journalsize
);
11723 case ISC_R_SUCCESS
:
11724 case ISC_R_NOSPACE
:
11725 case ISC_R_NOTFOUND
:
11726 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
11727 "dns_journal_compact: %s",
11728 dns_result_totext(result
));
11731 dns_zone_log(zone
, ISC_LOG_ERROR
,
11732 "dns_journal_compact failed: %s",
11733 dns_result_totext(result
));
11736 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
);
11740 * This transfer finishing freed up a transfer quota slot.
11741 * Let any other zones waiting for quota have it.
11743 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
11744 ISC_LIST_UNLINK(zone
->zmgr
->xfrin_in_progress
, zone
, statelink
);
11745 zone
->statelist
= NULL
;
11746 zmgr_resume_xfrs(zone
->zmgr
, ISC_FALSE
);
11747 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
11750 * Retry with a different server if necessary.
11752 if (again
&& !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
11753 queue_soa_query(zone
);
11755 INSIST(zone
->irefs
> 0);
11757 free_needed
= exit_check(zone
);
11764 zone_loaddone(void *arg
, isc_result_t result
) {
11765 static char me
[] = "zone_loaddone";
11766 dns_load_t
*load
= arg
;
11768 isc_result_t tresult
;
11770 REQUIRE(DNS_LOAD_VALID(load
));
11775 tresult
= dns_db_endload(load
->db
, &load
->callbacks
.add_private
);
11776 if (tresult
!= ISC_R_SUCCESS
&&
11777 (result
== ISC_R_SUCCESS
|| result
== DNS_R_SEENINCLUDE
))
11780 LOCK_ZONE(load
->zone
);
11781 (void)zone_postload(load
->zone
, load
->db
, load
->loadtime
, result
);
11782 zonemgr_putio(&load
->zone
->readio
);
11783 DNS_ZONE_CLRFLAG(load
->zone
, DNS_ZONEFLG_LOADING
);
11785 * Leave the zone frozen if the reload fails.
11787 if ((result
== ISC_R_SUCCESS
|| result
== DNS_R_SEENINCLUDE
) &&
11788 DNS_ZONE_FLAG(load
->zone
, DNS_ZONEFLG_THAW
))
11789 zone
->update_disabled
= ISC_FALSE
;
11790 DNS_ZONE_CLRFLAG(load
->zone
, DNS_ZONEFLG_THAW
);
11791 UNLOCK_ZONE(load
->zone
);
11794 dns_db_detach(&load
->db
);
11795 if (load
->zone
->lctx
!= NULL
)
11796 dns_loadctx_detach(&load
->zone
->lctx
);
11797 dns_zone_idetach(&load
->zone
);
11798 isc_mem_putanddetach(&load
->mctx
, load
, sizeof(*load
));
11802 dns_zone_getssutable(dns_zone_t
*zone
, dns_ssutable_t
**table
) {
11803 REQUIRE(DNS_ZONE_VALID(zone
));
11804 REQUIRE(table
!= NULL
);
11805 REQUIRE(*table
== NULL
);
11808 if (zone
->ssutable
!= NULL
)
11809 dns_ssutable_attach(zone
->ssutable
, table
);
11814 dns_zone_setssutable(dns_zone_t
*zone
, dns_ssutable_t
*table
) {
11815 REQUIRE(DNS_ZONE_VALID(zone
));
11818 if (zone
->ssutable
!= NULL
)
11819 dns_ssutable_detach(&zone
->ssutable
);
11821 dns_ssutable_attach(table
, &zone
->ssutable
);
11826 dns_zone_setsigvalidityinterval(dns_zone_t
*zone
, isc_uint32_t interval
) {
11827 REQUIRE(DNS_ZONE_VALID(zone
));
11829 zone
->sigvalidityinterval
= interval
;
11833 dns_zone_getsigvalidityinterval(dns_zone_t
*zone
) {
11834 REQUIRE(DNS_ZONE_VALID(zone
));
11836 return (zone
->sigvalidityinterval
);
11840 dns_zone_setsigresigninginterval(dns_zone_t
*zone
, isc_uint32_t interval
) {
11841 REQUIRE(DNS_ZONE_VALID(zone
));
11843 zone
->sigresigninginterval
= interval
;
11847 dns_zone_getsigresigninginterval(dns_zone_t
*zone
) {
11848 REQUIRE(DNS_ZONE_VALID(zone
));
11850 return (zone
->sigresigninginterval
);
11854 queue_xfrin(dns_zone_t
*zone
) {
11855 const char me
[] = "queue_xfrin";
11856 isc_result_t result
;
11857 dns_zonemgr_t
*zmgr
= zone
->zmgr
;
11861 INSIST(zone
->statelist
== NULL
);
11863 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
11864 ISC_LIST_APPEND(zmgr
->waiting_for_xfrin
, zone
, statelink
);
11868 zone
->statelist
= &zmgr
->waiting_for_xfrin
;
11869 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
11870 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
11872 if (result
== ISC_R_QUOTA
) {
11873 dns_zone_logc(zone
, DNS_LOGCATEGORY_XFER_IN
, ISC_LOG_INFO
,
11874 "zone transfer deferred due to quota");
11875 } else if (result
!= ISC_R_SUCCESS
) {
11876 dns_zone_logc(zone
, DNS_LOGCATEGORY_XFER_IN
, ISC_LOG_ERROR
,
11877 "starting zone transfer: %s",
11878 isc_result_totext(result
));
11883 * This event callback is called when a zone has received
11884 * any necessary zone transfer quota. This is the time
11885 * to go ahead and start the transfer.
11888 got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
) {
11889 isc_result_t result
;
11890 dns_peer_t
*peer
= NULL
;
11891 char master
[ISC_SOCKADDR_FORMATSIZE
];
11892 char source
[ISC_SOCKADDR_FORMATSIZE
];
11893 dns_rdatatype_t xfrtype
;
11894 dns_zone_t
*zone
= event
->ev_arg
;
11895 isc_netaddr_t masterip
;
11896 isc_sockaddr_t sourceaddr
;
11897 isc_sockaddr_t masteraddr
;
11902 INSIST(task
== zone
->task
);
11904 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
11905 result
= ISC_R_CANCELED
;
11911 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
11912 if (dns_zonemgr_unreachable(zone
->zmgr
, &zone
->masteraddr
,
11913 &zone
->sourceaddr
, &now
)) {
11914 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
11915 dns_zone_log(zone
, ISC_LOG_INFO
,
11916 "got_transfer_quota: skipping zone transfer as "
11917 "master %s (source %s) is unreachable (cached)",
11919 result
= ISC_R_CANCELED
;
11923 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
11924 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
, &masterip
, &peer
);
11927 * Decide whether we should request IXFR or AXFR.
11929 if (zone
->db
== NULL
) {
11930 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11931 "no database exists yet, requesting AXFR of "
11932 "initial version from %s", master
);
11933 xfrtype
= dns_rdatatype_axfr
;
11934 } else if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
)) {
11935 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "ixfr-from-differences "
11936 "set, requesting AXFR from %s", master
);
11937 xfrtype
= dns_rdatatype_axfr
;
11938 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
)) {
11939 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11940 "forced reload, requesting AXFR of "
11941 "initial version from %s", master
);
11942 xfrtype
= dns_rdatatype_axfr
;
11943 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLAG_NOIXFR
)) {
11944 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11945 "retrying with AXFR from %s due to "
11946 "previous IXFR failure", master
);
11947 xfrtype
= dns_rdatatype_axfr
;
11949 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
11952 isc_boolean_t use_ixfr
= ISC_TRUE
;
11953 if (peer
!= NULL
&&
11954 dns_peer_getrequestixfr(peer
, &use_ixfr
) ==
11956 ; /* Using peer setting */
11958 use_ixfr
= zone
->view
->requestixfr
;
11960 if (use_ixfr
== ISC_FALSE
) {
11961 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11962 "IXFR disabled, requesting AXFR from %s",
11964 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
))
11965 xfrtype
= dns_rdatatype_soa
;
11967 xfrtype
= dns_rdatatype_axfr
;
11969 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11970 "requesting IXFR from %s", master
);
11971 xfrtype
= dns_rdatatype_ixfr
;
11976 * Determine if we should attempt to sign the request with TSIG.
11978 result
= ISC_R_NOTFOUND
;
11980 * First, look for a tsig key in the master statement, then
11981 * try for a server key.
11983 if ((zone
->masterkeynames
!= NULL
) &&
11984 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
11985 dns_view_t
*view
= dns_zone_getview(zone
);
11986 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
11987 result
= dns_view_gettsig(view
, keyname
, &zone
->tsigkey
);
11989 if (zone
->tsigkey
== NULL
)
11990 result
= dns_view_getpeertsig(zone
->view
, &masterip
,
11993 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
11994 dns_zone_log(zone
, ISC_LOG_ERROR
,
11995 "could not get TSIG key for zone transfer: %s",
11996 isc_result_totext(result
));
12000 masteraddr
= zone
->masteraddr
;
12001 sourceaddr
= zone
->sourceaddr
;
12003 INSIST(isc_sockaddr_pf(&masteraddr
) == isc_sockaddr_pf(&sourceaddr
));
12004 result
= dns_xfrin_create2(zone
, xfrtype
, &masteraddr
, &sourceaddr
,
12005 zone
->tsigkey
, zone
->mctx
,
12006 zone
->zmgr
->timermgr
, zone
->zmgr
->socketmgr
,
12007 zone
->task
, zone_xfrdone
, &zone
->xfr
);
12008 if (result
== ISC_R_SUCCESS
) {
12010 if (xfrtype
== dns_rdatatype_axfr
) {
12011 if (isc_sockaddr_pf(&masteraddr
) == PF_INET
)
12012 inc_stats(zone
, dns_zonestatscounter_axfrreqv4
);
12014 inc_stats(zone
, dns_zonestatscounter_axfrreqv6
);
12015 } else if (xfrtype
== dns_rdatatype_ixfr
) {
12016 if (isc_sockaddr_pf(&masteraddr
) == PF_INET
)
12017 inc_stats(zone
, dns_zonestatscounter_ixfrreqv4
);
12019 inc_stats(zone
, dns_zonestatscounter_ixfrreqv6
);
12025 * Any failure in this function is handled like a failed
12026 * zone transfer. This ensures that we get removed from
12027 * zmgr->xfrin_in_progress.
12029 if (result
!= ISC_R_SUCCESS
)
12030 zone_xfrdone(zone
, result
);
12032 isc_event_free(&event
);
12036 * Update forwarding support.
12040 forward_destroy(dns_forward_t
*forward
) {
12042 forward
->magic
= 0;
12043 if (forward
->request
!= NULL
)
12044 dns_request_destroy(&forward
->request
);
12045 if (forward
->msgbuf
!= NULL
)
12046 isc_buffer_free(&forward
->msgbuf
);
12047 if (forward
->zone
!= NULL
)
12048 dns_zone_idetach(&forward
->zone
);
12049 isc_mem_putanddetach(&forward
->mctx
, forward
, sizeof(*forward
));
12052 static isc_result_t
12053 sendtomaster(dns_forward_t
*forward
) {
12054 isc_result_t result
;
12055 isc_sockaddr_t src
;
12057 LOCK_ZONE(forward
->zone
);
12058 if (forward
->which
>= forward
->zone
->masterscnt
) {
12059 UNLOCK_ZONE(forward
->zone
);
12060 return (ISC_R_NOMORE
);
12063 forward
->addr
= forward
->zone
->masters
[forward
->which
];
12065 * Always use TCP regardless of whether the original update
12067 * XXX The timeout may but a bit small if we are far down a
12068 * transfer graph and the master has to try several masters.
12070 switch (isc_sockaddr_pf(&forward
->addr
)) {
12072 src
= forward
->zone
->xfrsource4
;
12075 src
= forward
->zone
->xfrsource6
;
12078 result
= ISC_R_NOTIMPLEMENTED
;
12081 result
= dns_request_createraw(forward
->zone
->view
->requestmgr
,
12083 &src
, &forward
->addr
,
12084 DNS_REQUESTOPT_TCP
, 15 /* XXX */,
12085 forward
->zone
->task
,
12086 forward_callback
, forward
,
12087 &forward
->request
);
12089 UNLOCK_ZONE(forward
->zone
);
12094 forward_callback(isc_task_t
*task
, isc_event_t
*event
) {
12095 const char me
[] = "forward_callback";
12096 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
12097 dns_message_t
*msg
= NULL
;
12098 char master
[ISC_SOCKADDR_FORMATSIZE
];
12099 isc_result_t result
;
12100 dns_forward_t
*forward
;
12105 forward
= revent
->ev_arg
;
12106 INSIST(DNS_FORWARD_VALID(forward
));
12107 zone
= forward
->zone
;
12108 INSIST(DNS_ZONE_VALID(zone
));
12112 isc_sockaddr_format(&forward
->addr
, master
, sizeof(master
));
12114 if (revent
->result
!= ISC_R_SUCCESS
) {
12115 dns_zone_log(zone
, ISC_LOG_INFO
,
12116 "could not forward dynamic update to %s: %s",
12117 master
, dns_result_totext(revent
->result
));
12121 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
12122 if (result
!= ISC_R_SUCCESS
)
12125 result
= dns_request_getresponse(revent
->request
, msg
,
12126 DNS_MESSAGEPARSE_PRESERVEORDER
|
12127 DNS_MESSAGEPARSE_CLONEBUFFER
);
12128 if (result
!= ISC_R_SUCCESS
)
12131 switch (msg
->rcode
) {
12133 * Pass these rcodes back to client.
12135 case dns_rcode_noerror
:
12136 case dns_rcode_yxdomain
:
12137 case dns_rcode_yxrrset
:
12138 case dns_rcode_nxrrset
:
12139 case dns_rcode_refused
:
12140 case dns_rcode_nxdomain
:
12143 /* These should not occur if the masters/zone are valid. */
12144 case dns_rcode_notzone
:
12145 case dns_rcode_notauth
: {
12149 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
12150 (void)dns_rcode_totext(msg
->rcode
, &rb
);
12151 dns_zone_log(zone
, ISC_LOG_WARNING
,
12152 "forwarding dynamic update: "
12153 "unexpected response: master %s returned: %.*s",
12154 master
, (int)rb
.used
, rcode
);
12158 /* Try another server for these rcodes. */
12159 case dns_rcode_formerr
:
12160 case dns_rcode_servfail
:
12161 case dns_rcode_notimp
:
12162 case dns_rcode_badvers
:
12167 /* call callback */
12168 (forward
->callback
)(forward
->callback_arg
, ISC_R_SUCCESS
, msg
);
12170 dns_request_destroy(&forward
->request
);
12171 forward_destroy(forward
);
12172 isc_event_free(&event
);
12177 dns_message_destroy(&msg
);
12178 isc_event_free(&event
);
12180 dns_request_destroy(&forward
->request
);
12181 result
= sendtomaster(forward
);
12182 if (result
!= ISC_R_SUCCESS
) {
12183 /* call callback */
12184 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
12185 "exhausted dynamic update forwarder list");
12186 (forward
->callback
)(forward
->callback_arg
, result
, NULL
);
12187 forward_destroy(forward
);
12192 dns_zone_forwardupdate(dns_zone_t
*zone
, dns_message_t
*msg
,
12193 dns_updatecallback_t callback
, void *callback_arg
)
12195 dns_forward_t
*forward
;
12196 isc_result_t result
;
12199 REQUIRE(DNS_ZONE_VALID(zone
));
12200 REQUIRE(msg
!= NULL
);
12201 REQUIRE(callback
!= NULL
);
12203 forward
= isc_mem_get(zone
->mctx
, sizeof(*forward
));
12204 if (forward
== NULL
)
12205 return (ISC_R_NOMEMORY
);
12207 forward
->request
= NULL
;
12208 forward
->zone
= NULL
;
12209 forward
->msgbuf
= NULL
;
12210 forward
->which
= 0;
12212 forward
->callback
= callback
;
12213 forward
->callback_arg
= callback_arg
;
12214 forward
->magic
= FORWARD_MAGIC
;
12216 mr
= dns_message_getrawmessage(msg
);
12218 result
= ISC_R_UNEXPECTEDEND
;
12222 result
= isc_buffer_allocate(zone
->mctx
, &forward
->msgbuf
, mr
->length
);
12223 if (result
!= ISC_R_SUCCESS
)
12225 result
= isc_buffer_copyregion(forward
->msgbuf
, mr
);
12226 if (result
!= ISC_R_SUCCESS
)
12229 isc_mem_attach(zone
->mctx
, &forward
->mctx
);
12230 dns_zone_iattach(zone
, &forward
->zone
);
12231 result
= sendtomaster(forward
);
12234 if (result
!= ISC_R_SUCCESS
) {
12235 forward_destroy(forward
);
12241 dns_zone_next(dns_zone_t
*zone
, dns_zone_t
**next
) {
12242 REQUIRE(DNS_ZONE_VALID(zone
));
12243 REQUIRE(next
!= NULL
&& *next
== NULL
);
12245 *next
= ISC_LIST_NEXT(zone
, link
);
12247 return (ISC_R_NOMORE
);
12249 return (ISC_R_SUCCESS
);
12253 dns_zone_first(dns_zonemgr_t
*zmgr
, dns_zone_t
**first
) {
12254 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12255 REQUIRE(first
!= NULL
&& *first
== NULL
);
12257 *first
= ISC_LIST_HEAD(zmgr
->zones
);
12258 if (*first
== NULL
)
12259 return (ISC_R_NOMORE
);
12261 return (ISC_R_SUCCESS
);
12269 dns_zonemgr_create(isc_mem_t
*mctx
, isc_taskmgr_t
*taskmgr
,
12270 isc_timermgr_t
*timermgr
, isc_socketmgr_t
*socketmgr
,
12271 dns_zonemgr_t
**zmgrp
)
12273 dns_zonemgr_t
*zmgr
;
12274 isc_result_t result
;
12275 isc_interval_t interval
;
12277 zmgr
= isc_mem_get(mctx
, sizeof(*zmgr
));
12279 return (ISC_R_NOMEMORY
);
12282 isc_mem_attach(mctx
, &zmgr
->mctx
);
12283 zmgr
->taskmgr
= taskmgr
;
12284 zmgr
->timermgr
= timermgr
;
12285 zmgr
->socketmgr
= socketmgr
;
12286 zmgr
->zonetasks
= NULL
;
12289 ISC_LIST_INIT(zmgr
->zones
);
12290 ISC_LIST_INIT(zmgr
->waiting_for_xfrin
);
12291 ISC_LIST_INIT(zmgr
->xfrin_in_progress
);
12292 memset(zmgr
->unreachable
, 0, sizeof(zmgr
->unreachable
));
12293 result
= isc_rwlock_init(&zmgr
->rwlock
, 0, 0);
12294 if (result
!= ISC_R_SUCCESS
)
12297 zmgr
->transfersin
= 10;
12298 zmgr
->transfersperns
= 2;
12300 /* Create the zone task pool. */
12301 result
= isc_taskpool_create(taskmgr
, mctx
,
12302 8 /* XXX */, 2, &zmgr
->zonetasks
);
12303 if (result
!= ISC_R_SUCCESS
)
12306 /* Create a single task for queueing of SOA queries. */
12307 result
= isc_task_create(taskmgr
, 1, &zmgr
->task
);
12308 if (result
!= ISC_R_SUCCESS
)
12309 goto free_taskpool
;
12310 isc_task_setname(zmgr
->task
, "zmgr", zmgr
);
12311 result
= isc_ratelimiter_create(mctx
, timermgr
, zmgr
->task
,
12313 if (result
!= ISC_R_SUCCESS
)
12315 /* default to 20 refresh queries / notifies per second. */
12316 isc_interval_set(&interval
, 0, 1000000000/2);
12317 result
= isc_ratelimiter_setinterval(zmgr
->rl
, &interval
);
12318 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
12319 isc_ratelimiter_setpertic(zmgr
->rl
, 10);
12322 zmgr
->ioactive
= 0;
12323 ISC_LIST_INIT(zmgr
->high
);
12324 ISC_LIST_INIT(zmgr
->low
);
12326 result
= isc_mutex_init(&zmgr
->iolock
);
12327 if (result
!= ISC_R_SUCCESS
)
12330 zmgr
->magic
= ZONEMGR_MAGIC
;
12333 return (ISC_R_SUCCESS
);
12337 DESTROYLOCK(&zmgr
->iolock
);
12340 isc_ratelimiter_detach(&zmgr
->rl
);
12342 isc_task_detach(&zmgr
->task
);
12344 isc_taskpool_destroy(&zmgr
->zonetasks
);
12346 isc_rwlock_destroy(&zmgr
->rwlock
);
12348 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof(*zmgr
));
12349 isc_mem_detach(&mctx
);
12354 dns_zonemgr_managezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
12355 isc_result_t result
;
12357 REQUIRE(DNS_ZONE_VALID(zone
));
12358 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12360 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12362 REQUIRE(zone
->task
== NULL
);
12363 REQUIRE(zone
->timer
== NULL
);
12364 REQUIRE(zone
->zmgr
== NULL
);
12366 isc_taskpool_gettask(zmgr
->zonetasks
,
12367 dns_name_hash(dns_zone_getorigin(zone
),
12372 * Set the task name. The tag will arbitrarily point to one
12373 * of the zones sharing the task (in practice, the one
12374 * to be managed last).
12376 isc_task_setname(zone
->task
, "zone", zone
);
12378 result
= isc_timer_create(zmgr
->timermgr
, isc_timertype_inactive
,
12380 zone
->task
, zone_timer
, zone
,
12383 if (result
!= ISC_R_SUCCESS
)
12387 * The timer "holds" a iref.
12390 INSIST(zone
->irefs
!= 0);
12392 ISC_LIST_APPEND(zmgr
->zones
, zone
, link
);
12399 isc_task_detach(&zone
->task
);
12403 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12408 dns_zonemgr_releasezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
12409 isc_boolean_t free_now
= ISC_FALSE
;
12411 REQUIRE(DNS_ZONE_VALID(zone
));
12412 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12413 REQUIRE(zone
->zmgr
== zmgr
);
12415 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12418 ISC_LIST_UNLINK(zmgr
->zones
, zone
, link
);
12421 if (zmgr
->refs
== 0)
12422 free_now
= ISC_TRUE
;
12425 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12428 zonemgr_free(zmgr
);
12429 ENSURE(zone
->zmgr
== NULL
);
12433 dns_zonemgr_attach(dns_zonemgr_t
*source
, dns_zonemgr_t
**target
) {
12434 REQUIRE(DNS_ZONEMGR_VALID(source
));
12435 REQUIRE(target
!= NULL
&& *target
== NULL
);
12437 RWLOCK(&source
->rwlock
, isc_rwlocktype_write
);
12438 REQUIRE(source
->refs
> 0);
12440 INSIST(source
->refs
> 0);
12441 RWUNLOCK(&source
->rwlock
, isc_rwlocktype_write
);
12446 dns_zonemgr_detach(dns_zonemgr_t
**zmgrp
) {
12447 dns_zonemgr_t
*zmgr
;
12448 isc_boolean_t free_now
= ISC_FALSE
;
12450 REQUIRE(zmgrp
!= NULL
);
12452 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12454 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12456 if (zmgr
->refs
== 0)
12457 free_now
= ISC_TRUE
;
12458 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12461 zonemgr_free(zmgr
);
12465 dns_zonemgr_forcemaint(dns_zonemgr_t
*zmgr
) {
12468 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12470 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
12471 for (p
= ISC_LIST_HEAD(zmgr
->zones
);
12473 p
= ISC_LIST_NEXT(p
, link
))
12475 dns_zone_maintenance(p
);
12477 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
12480 * Recent configuration changes may have increased the
12481 * amount of available transfers quota. Make sure any
12482 * transfers currently blocked on quota get started if
12485 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12486 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
12487 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12488 return (ISC_R_SUCCESS
);
12492 dns_zonemgr_resumexfrs(dns_zonemgr_t
*zmgr
) {
12494 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12496 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12497 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
12498 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12502 dns_zonemgr_shutdown(dns_zonemgr_t
*zmgr
) {
12503 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12505 isc_ratelimiter_shutdown(zmgr
->rl
);
12507 if (zmgr
->task
!= NULL
)
12508 isc_task_destroy(&zmgr
->task
);
12509 if (zmgr
->zonetasks
!= NULL
)
12510 isc_taskpool_destroy(&zmgr
->zonetasks
);
12514 zonemgr_free(dns_zonemgr_t
*zmgr
) {
12517 INSIST(zmgr
->refs
== 0);
12518 INSIST(ISC_LIST_EMPTY(zmgr
->zones
));
12522 DESTROYLOCK(&zmgr
->iolock
);
12523 isc_ratelimiter_detach(&zmgr
->rl
);
12525 isc_rwlock_destroy(&zmgr
->rwlock
);
12527 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof(*zmgr
));
12528 isc_mem_detach(&mctx
);
12532 dns_zonemgr_settransfersin(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
12533 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12535 zmgr
->transfersin
= value
;
12539 dns_zonemgr_getttransfersin(dns_zonemgr_t
*zmgr
) {
12540 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12542 return (zmgr
->transfersin
);
12546 dns_zonemgr_settransfersperns(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
12547 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12549 zmgr
->transfersperns
= value
;
12553 dns_zonemgr_getttransfersperns(dns_zonemgr_t
*zmgr
) {
12554 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12556 return (zmgr
->transfersperns
);
12560 * Try to start a new incoming zone transfer to fill a quota
12561 * slot that was just vacated.
12564 * The zone manager is locked by the caller.
12567 zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
) {
12571 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
12575 isc_result_t result
;
12576 next
= ISC_LIST_NEXT(zone
, statelink
);
12577 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
12578 if (result
== ISC_R_SUCCESS
) {
12582 * We successfully filled the slot. We're done.
12585 } else if (result
== ISC_R_QUOTA
) {
12587 * Not enough quota. This is probably the per-server
12588 * quota, because we usually get called when a unit of
12589 * global quota has just been freed. Try the next
12590 * zone, it may succeed if it uses another master.
12594 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
12595 "starting zone transfer: %s",
12596 isc_result_totext(result
));
12603 * Try to start an incoming zone transfer for 'zone', quota permitting.
12606 * The zone manager is locked by the caller.
12609 * ISC_R_SUCCESS There was enough quota and we attempted to
12610 * start a transfer. zone_xfrdone() has been or will
12612 * ISC_R_QUOTA Not enough quota.
12615 static isc_result_t
12616 zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
12617 dns_peer_t
*peer
= NULL
;
12618 isc_netaddr_t masterip
;
12619 isc_uint32_t nxfrsin
, nxfrsperns
;
12621 isc_uint32_t maxtransfersin
, maxtransfersperns
;
12625 * Find any configured information about the server we'd
12626 * like to transfer this zone from.
12628 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
12629 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
,
12633 * Determine the total maximum number of simultaneous
12634 * transfers allowed, and the maximum for this specific
12637 maxtransfersin
= zmgr
->transfersin
;
12638 maxtransfersperns
= zmgr
->transfersperns
;
12640 (void)dns_peer_gettransfers(peer
, &maxtransfersperns
);
12643 * Count the total number of transfers that are in progress,
12644 * and the number of transfers in progress from this master.
12645 * We linearly scan a list of all transfers; if this turns
12646 * out to be too slow, we could hash on the master address.
12648 nxfrsin
= nxfrsperns
= 0;
12649 for (x
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
12651 x
= ISC_LIST_NEXT(x
, statelink
))
12654 isc_netaddr_fromsockaddr(&xip
, &x
->masteraddr
);
12656 if (isc_netaddr_equal(&xip
, &masterip
))
12660 /* Enforce quota. */
12661 if (nxfrsin
>= maxtransfersin
)
12662 return (ISC_R_QUOTA
);
12664 if (nxfrsperns
>= maxtransfersperns
)
12665 return (ISC_R_QUOTA
);
12668 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
12669 * list and send it an event to let it start the actual transfer in the
12670 * context of its own task.
12672 e
= isc_event_allocate(zmgr
->mctx
, zmgr
,
12673 DNS_EVENT_ZONESTARTXFRIN
,
12674 got_transfer_quota
, zone
,
12675 sizeof(isc_event_t
));
12677 return (ISC_R_NOMEMORY
);
12680 INSIST(zone
->statelist
== &zmgr
->waiting_for_xfrin
);
12681 ISC_LIST_UNLINK(zmgr
->waiting_for_xfrin
, zone
, statelink
);
12682 ISC_LIST_APPEND(zmgr
->xfrin_in_progress
, zone
, statelink
);
12683 zone
->statelist
= &zmgr
->xfrin_in_progress
;
12684 isc_task_send(zone
->task
, &e
);
12685 dns_zone_log(zone
, ISC_LOG_INFO
, "Transfer started.");
12688 return (ISC_R_SUCCESS
);
12692 dns_zonemgr_setiolimit(dns_zonemgr_t
*zmgr
, isc_uint32_t iolimit
) {
12694 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12695 REQUIRE(iolimit
> 0);
12697 zmgr
->iolimit
= iolimit
;
12701 dns_zonemgr_getiolimit(dns_zonemgr_t
*zmgr
) {
12703 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12705 return (zmgr
->iolimit
);
12709 * Get permission to request a file handle from the OS.
12710 * An event will be sent to action when one is available.
12711 * There are two queues available (high and low), the high
12712 * queue will be serviced before the low one.
12714 * zonemgr_putio() must be called after the event is delivered to
12718 static isc_result_t
12719 zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
12720 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
12724 isc_boolean_t queue
;
12726 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12727 REQUIRE(iop
!= NULL
&& *iop
== NULL
);
12729 io
= isc_mem_get(zmgr
->mctx
, sizeof(*io
));
12731 return (ISC_R_NOMEMORY
);
12732 io
->event
= isc_event_allocate(zmgr
->mctx
, task
, DNS_EVENT_IOREADY
,
12733 action
, arg
, sizeof(*io
->event
));
12734 if (io
->event
== NULL
) {
12735 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
12736 return (ISC_R_NOMEMORY
);
12741 isc_task_attach(task
, &io
->task
);
12742 ISC_LINK_INIT(io
, link
);
12743 io
->magic
= IO_MAGIC
;
12745 LOCK(&zmgr
->iolock
);
12747 queue
= ISC_TF(zmgr
->ioactive
> zmgr
->iolimit
);
12750 ISC_LIST_APPEND(zmgr
->high
, io
, link
);
12752 ISC_LIST_APPEND(zmgr
->low
, io
, link
);
12754 UNLOCK(&zmgr
->iolock
);
12758 isc_task_send(io
->task
, &io
->event
);
12760 return (ISC_R_SUCCESS
);
12764 zonemgr_putio(dns_io_t
**iop
) {
12767 dns_zonemgr_t
*zmgr
;
12769 REQUIRE(iop
!= NULL
);
12771 REQUIRE(DNS_IO_VALID(io
));
12775 INSIST(!ISC_LINK_LINKED(io
, link
));
12776 INSIST(io
->event
== NULL
);
12779 isc_task_detach(&io
->task
);
12781 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
12783 LOCK(&zmgr
->iolock
);
12784 INSIST(zmgr
->ioactive
> 0);
12786 next
= HEAD(zmgr
->high
);
12788 next
= HEAD(zmgr
->low
);
12789 if (next
!= NULL
) {
12791 ISC_LIST_UNLINK(zmgr
->high
, next
, link
);
12793 ISC_LIST_UNLINK(zmgr
->low
, next
, link
);
12794 INSIST(next
->event
!= NULL
);
12796 UNLOCK(&zmgr
->iolock
);
12798 isc_task_send(next
->task
, &next
->event
);
12802 zonemgr_cancelio(dns_io_t
*io
) {
12803 isc_boolean_t send_event
= ISC_FALSE
;
12805 REQUIRE(DNS_IO_VALID(io
));
12808 * If we are queued to be run then dequeue.
12810 LOCK(&io
->zmgr
->iolock
);
12811 if (ISC_LINK_LINKED(io
, link
)) {
12813 ISC_LIST_UNLINK(io
->zmgr
->high
, io
, link
);
12815 ISC_LIST_UNLINK(io
->zmgr
->low
, io
, link
);
12817 send_event
= ISC_TRUE
;
12818 INSIST(io
->event
!= NULL
);
12820 UNLOCK(&io
->zmgr
->iolock
);
12822 io
->event
->ev_attributes
|= ISC_EVENTATTR_CANCELED
;
12823 isc_task_send(io
->task
, &io
->event
);
12828 zone_saveunique(dns_zone_t
*zone
, const char *path
, const char *templat
) {
12831 isc_result_t result
;
12833 buflen
= strlen(path
) + strlen(templat
) + 2;
12835 buf
= isc_mem_get(zone
->mctx
, buflen
);
12839 result
= isc_file_template(path
, templat
, buf
, buflen
);
12840 if (result
!= ISC_R_SUCCESS
)
12843 result
= isc_file_renameunique(path
, buf
);
12844 if (result
!= ISC_R_SUCCESS
)
12847 dns_zone_log(zone
, ISC_LOG_WARNING
, "saved '%s' as '%s'",
12851 isc_mem_put(zone
->mctx
, buf
, buflen
);
12855 /* Hook for ondestroy notification from a database. */
12858 dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
) {
12859 dns_db_t
*db
= event
->sender
;
12862 isc_event_free(&event
);
12864 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
12865 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
12866 "database (%p) destroyed", (void*) db
);
12871 dns_zonemgr_setserialqueryrate(dns_zonemgr_t
*zmgr
, unsigned int value
) {
12872 isc_interval_t interval
;
12873 isc_uint32_t s
, ns
;
12874 isc_uint32_t pertic
;
12875 isc_result_t result
;
12877 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12886 } else if (value
<= 10) {
12888 ns
= 1000000000 / value
;
12892 ns
= (1000000000 / value
) * 10;
12896 isc_interval_set(&interval
, s
, ns
);
12897 result
= isc_ratelimiter_setinterval(zmgr
->rl
, &interval
);
12898 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
12899 isc_ratelimiter_setpertic(zmgr
->rl
, pertic
);
12901 zmgr
->serialqueryrate
= value
;
12905 dns_zonemgr_getserialqueryrate(dns_zonemgr_t
*zmgr
) {
12906 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12908 return (zmgr
->serialqueryrate
);
12911 static isc_boolean_t
12912 dns_zonemgr_unreachable(dns_zonemgr_t
*zmgr
, isc_sockaddr_t
*remote
,
12913 isc_sockaddr_t
*local
, isc_time_t
*now
)
12916 isc_rwlocktype_t locktype
;
12917 isc_result_t result
;
12918 isc_uint32_t seconds
= isc_time_seconds(now
);
12920 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12922 locktype
= isc_rwlocktype_read
;
12923 RWLOCK(&zmgr
->rwlock
, locktype
);
12924 for (i
= 0; i
< UNREACH_CHACHE_SIZE
; i
++) {
12925 if (zmgr
->unreachable
[i
].expire
>= seconds
&&
12926 isc_sockaddr_equal(&zmgr
->unreachable
[i
].remote
, remote
) &&
12927 isc_sockaddr_equal(&zmgr
->unreachable
[i
].local
, local
)) {
12928 result
= isc_rwlock_tryupgrade(&zmgr
->rwlock
);
12929 if (result
== ISC_R_SUCCESS
) {
12930 locktype
= isc_rwlocktype_write
;
12931 zmgr
->unreachable
[i
].last
= seconds
;
12936 RWUNLOCK(&zmgr
->rwlock
, locktype
);
12937 return (ISC_TF(i
< UNREACH_CHACHE_SIZE
));
12941 dns_zonemgr_unreachableadd(dns_zonemgr_t
*zmgr
, isc_sockaddr_t
*remote
,
12942 isc_sockaddr_t
*local
, isc_time_t
*now
)
12944 isc_uint32_t seconds
= isc_time_seconds(now
);
12945 isc_uint32_t last
= seconds
;
12946 unsigned int i
, slot
= UNREACH_CHACHE_SIZE
, oldest
= 0;
12948 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
12950 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12951 for (i
= 0; i
< UNREACH_CHACHE_SIZE
; i
++) {
12952 /* Existing entry? */
12953 if (isc_sockaddr_equal(&zmgr
->unreachable
[i
].remote
, remote
) &&
12954 isc_sockaddr_equal(&zmgr
->unreachable
[i
].local
, local
))
12957 if (zmgr
->unreachable
[i
].expire
< seconds
)
12959 /* Least recently used slot? */
12960 if (zmgr
->unreachable
[i
].last
< last
) {
12961 last
= zmgr
->unreachable
[i
].last
;
12965 if (i
< UNREACH_CHACHE_SIZE
) {
12967 * Found a existing entry. Update the expire timer and
12968 * last usage timestamps.
12970 zmgr
->unreachable
[i
].expire
= seconds
+ UNREACH_HOLD_TIME
;
12971 zmgr
->unreachable
[i
].last
= seconds
;
12972 } else if (slot
!= UNREACH_CHACHE_SIZE
) {
12974 * Found a empty slot. Add a new entry to the cache.
12976 zmgr
->unreachable
[slot
].expire
= seconds
+ UNREACH_HOLD_TIME
;
12977 zmgr
->unreachable
[slot
].last
= seconds
;
12978 zmgr
->unreachable
[slot
].remote
= *remote
;
12979 zmgr
->unreachable
[slot
].local
= *local
;
12982 * Replace the least recently used entry in the cache.
12984 zmgr
->unreachable
[oldest
].expire
= seconds
+ UNREACH_HOLD_TIME
;
12985 zmgr
->unreachable
[oldest
].last
= seconds
;
12986 zmgr
->unreachable
[oldest
].remote
= *remote
;
12987 zmgr
->unreachable
[oldest
].local
= *local
;
12989 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
12993 dns_zone_forcereload(dns_zone_t
*zone
) {
12994 REQUIRE(DNS_ZONE_VALID(zone
));
12996 if (zone
->type
== dns_zone_master
)
13000 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
13002 dns_zone_refresh(zone
);
13006 dns_zone_isforced(dns_zone_t
*zone
) {
13007 REQUIRE(DNS_ZONE_VALID(zone
));
13009 return (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
));
13013 dns_zone_setstatistics(dns_zone_t
*zone
, isc_boolean_t on
) {
13015 * This function is obsoleted.
13019 return (ISC_R_NOTIMPLEMENTED
);
13023 dns_zone_getstatscounters(dns_zone_t
*zone
) {
13025 * This function is obsoleted.
13032 dns_zone_setstats(dns_zone_t
*zone
, isc_stats_t
*stats
) {
13033 REQUIRE(DNS_ZONE_VALID(zone
));
13034 REQUIRE(zone
->stats
== NULL
);
13037 zone
->stats
= NULL
;
13038 isc_stats_attach(stats
, &zone
->stats
);
13043 dns_zone_setrequeststats(dns_zone_t
*zone
, isc_stats_t
*stats
) {
13044 REQUIRE(DNS_ZONE_VALID(zone
));
13047 if (zone
->requeststats_on
&& stats
== NULL
)
13048 zone
->requeststats_on
= ISC_FALSE
;
13049 else if (!zone
->requeststats_on
&& stats
!= NULL
) {
13050 if (zone
->requeststats
== NULL
) {
13051 isc_stats_attach(stats
, &zone
->requeststats
);
13052 zone
->requeststats_on
= ISC_TRUE
;
13061 dns_zone_getrequeststats(dns_zone_t
*zone
) {
13063 * We don't lock zone for efficiency reason. This is not catastrophic
13064 * because requeststats must always be valid when requeststats_on is
13066 * Some counters may be incremented while requeststats_on is becoming
13067 * false, or some cannot be incremented just after the statistics are
13068 * installed, but it shouldn't matter much in practice.
13070 if (zone
->requeststats_on
)
13071 return (zone
->requeststats
);
13077 dns_zone_dialup(dns_zone_t
*zone
) {
13079 REQUIRE(DNS_ZONE_VALID(zone
));
13081 zone_debuglog(zone
, "dns_zone_dialup", 3,
13082 "notify = %d, refresh = %d",
13083 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
),
13084 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
));
13086 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
13087 dns_zone_notify(zone
);
13088 if (zone
->type
!= dns_zone_master
&&
13089 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
13090 dns_zone_refresh(zone
);
13094 dns_zone_setdialup(dns_zone_t
*zone
, dns_dialuptype_t dialup
) {
13095 REQUIRE(DNS_ZONE_VALID(zone
));
13098 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
|
13099 DNS_ZONEFLG_DIALREFRESH
|
13100 DNS_ZONEFLG_NOREFRESH
);
13102 case dns_dialuptype_no
:
13104 case dns_dialuptype_yes
:
13105 DNS_ZONE_SETFLAG(zone
, (DNS_ZONEFLG_DIALNOTIFY
|
13106 DNS_ZONEFLG_DIALREFRESH
|
13107 DNS_ZONEFLG_NOREFRESH
));
13109 case dns_dialuptype_notify
:
13110 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
13112 case dns_dialuptype_notifypassive
:
13113 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
13114 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
13116 case dns_dialuptype_refresh
:
13117 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALREFRESH
);
13118 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
13120 case dns_dialuptype_passive
:
13121 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
13130 dns_zone_setkeydirectory(dns_zone_t
*zone
, const char *directory
) {
13131 isc_result_t result
= ISC_R_SUCCESS
;
13133 REQUIRE(DNS_ZONE_VALID(zone
));
13136 result
= dns_zone_setstring(zone
, &zone
->keydirectory
, directory
);
13143 dns_zone_getkeydirectory(dns_zone_t
*zone
) {
13144 REQUIRE(DNS_ZONE_VALID(zone
));
13146 return (zone
->keydirectory
);
13150 dns_zonemgr_getcount(dns_zonemgr_t
*zmgr
, int state
) {
13152 unsigned int count
= 0;
13154 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
13156 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
13158 case DNS_ZONESTATE_XFERRUNNING
:
13159 for (zone
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
13161 zone
= ISC_LIST_NEXT(zone
, statelink
))
13164 case DNS_ZONESTATE_XFERDEFERRED
:
13165 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
13167 zone
= ISC_LIST_NEXT(zone
, statelink
))
13170 case DNS_ZONESTATE_SOAQUERY
:
13171 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
13173 zone
= ISC_LIST_NEXT(zone
, link
))
13174 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
))
13177 case DNS_ZONESTATE_ANY
:
13178 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
13180 zone
= ISC_LIST_NEXT(zone
, link
)) {
13181 dns_view_t
*view
= zone
->view
;
13182 if (view
!= NULL
&& strcmp(view
->name
, "_bind") == 0)
13191 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
13197 dns_zone_checknames(dns_zone_t
*zone
, dns_name_t
*name
, dns_rdata_t
*rdata
) {
13198 isc_boolean_t ok
= ISC_TRUE
;
13199 isc_boolean_t fail
= ISC_FALSE
;
13200 char namebuf
[DNS_NAME_FORMATSIZE
];
13201 char namebuf2
[DNS_NAME_FORMATSIZE
];
13202 char typebuf
[DNS_RDATATYPE_FORMATSIZE
];
13203 int level
= ISC_LOG_WARNING
;
13206 REQUIRE(DNS_ZONE_VALID(zone
));
13208 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMES
))
13209 return (ISC_R_SUCCESS
);
13211 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
)) {
13212 level
= ISC_LOG_ERROR
;
13216 ok
= dns_rdata_checkowner(name
, rdata
->rdclass
, rdata
->type
, ISC_TRUE
);
13218 dns_name_format(name
, namebuf
, sizeof(namebuf
));
13219 dns_rdatatype_format(rdata
->type
, typebuf
, sizeof(typebuf
));
13220 dns_zone_log(zone
, level
, "%s/%s: %s", namebuf
, typebuf
,
13221 dns_result_totext(DNS_R_BADOWNERNAME
));
13223 return (DNS_R_BADOWNERNAME
);
13226 dns_name_init(&bad
, NULL
);
13227 ok
= dns_rdata_checknames(rdata
, name
, &bad
);
13229 dns_name_format(name
, namebuf
, sizeof(namebuf
));
13230 dns_name_format(&bad
, namebuf2
, sizeof(namebuf2
));
13231 dns_rdatatype_format(rdata
->type
, typebuf
, sizeof(typebuf
));
13232 dns_zone_log(zone
, level
, "%s/%s: %s: %s ", namebuf
, typebuf
,
13233 namebuf2
, dns_result_totext(DNS_R_BADNAME
));
13235 return (DNS_R_BADNAME
);
13238 return (ISC_R_SUCCESS
);
13242 dns_zone_setcheckmx(dns_zone_t
*zone
, dns_checkmxfunc_t checkmx
) {
13243 REQUIRE(DNS_ZONE_VALID(zone
));
13244 zone
->checkmx
= checkmx
;
13248 dns_zone_setchecksrv(dns_zone_t
*zone
, dns_checksrvfunc_t checksrv
) {
13249 REQUIRE(DNS_ZONE_VALID(zone
));
13250 zone
->checksrv
= checksrv
;
13254 dns_zone_setcheckns(dns_zone_t
*zone
, dns_checknsfunc_t checkns
) {
13255 REQUIRE(DNS_ZONE_VALID(zone
));
13256 zone
->checkns
= checkns
;
13260 dns_zone_setisself(dns_zone_t
*zone
, dns_isselffunc_t isself
, void *arg
) {
13261 REQUIRE(DNS_ZONE_VALID(zone
));
13264 zone
->isself
= isself
;
13265 zone
->isselfarg
= arg
;
13270 dns_zone_setnotifydelay(dns_zone_t
*zone
, isc_uint32_t delay
) {
13271 REQUIRE(DNS_ZONE_VALID(zone
));
13274 zone
->notifydelay
= delay
;
13279 dns_zone_getnotifydelay(dns_zone_t
*zone
) {
13280 REQUIRE(DNS_ZONE_VALID(zone
));
13282 return (zone
->notifydelay
);
13286 dns_zone_signwithkey(dns_zone_t
*zone
, dns_secalg_t algorithm
,
13287 isc_uint16_t keyid
, isc_boolean_t
delete)
13289 isc_result_t result
;
13290 REQUIRE(DNS_ZONE_VALID(zone
));
13292 dns_zone_log(zone
, ISC_LOG_NOTICE
,
13293 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
13296 result
= zone_signwithkey(zone
, algorithm
, keyid
, delete);
13302 static const char *hex
= "0123456789ABCDEF";
13305 dns_zone_addnsec3chain(dns_zone_t
*zone
, dns_rdata_nsec3param_t
*nsec3param
) {
13306 isc_result_t result
;
13307 char salt
[255*2+1];
13310 REQUIRE(DNS_ZONE_VALID(zone
));
13312 if (nsec3param
->salt_length
!= 0) {
13313 INSIST((nsec3param
->salt_length
* 2U) < sizeof(salt
));
13314 for (i
= 0, j
= 0; i
< nsec3param
->salt_length
; i
++) {
13315 salt
[j
++] = hex
[(nsec3param
->salt
[i
] >> 4) & 0xf];
13316 salt
[j
++] = hex
[nsec3param
->salt
[i
] & 0xf];
13321 dns_zone_log(zone
, ISC_LOG_NOTICE
,
13322 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
13323 nsec3param
->hash
, nsec3param
->iterations
,
13326 result
= zone_addnsec3chain(zone
, nsec3param
);
13333 dns_zone_setnodes(dns_zone_t
*zone
, isc_uint32_t nodes
) {
13334 REQUIRE(DNS_ZONE_VALID(zone
));
13338 zone
->nodes
= nodes
;
13342 dns_zone_setsignatures(dns_zone_t
*zone
, isc_uint32_t signatures
) {
13343 REQUIRE(DNS_ZONE_VALID(zone
));
13346 * We treat signatures as a signed value so explicitly
13347 * limit its range here.
13349 if (signatures
> ISC_INT32_MAX
)
13350 signatures
= ISC_INT32_MAX
;
13351 else if (signatures
== 0)
13353 zone
->signatures
= signatures
;
13357 dns_zone_setprivatetype(dns_zone_t
*zone
, dns_rdatatype_t type
) {
13358 REQUIRE(DNS_ZONE_VALID(zone
));
13359 zone
->privatetype
= type
;
13363 dns_zone_getprivatetype(dns_zone_t
*zone
) {
13364 REQUIRE(DNS_ZONE_VALID(zone
));
13365 return (zone
->privatetype
);
13368 static isc_result_t
13369 zone_signwithkey(dns_zone_t
*zone
, dns_secalg_t algorithm
, isc_uint16_t keyid
,
13370 isc_boolean_t
delete)
13372 dns_signing_t
*signing
;
13373 dns_signing_t
*current
;
13374 isc_result_t result
= ISC_R_SUCCESS
;
13377 signing
= isc_mem_get(zone
->mctx
, sizeof *signing
);
13378 if (signing
== NULL
)
13379 return (ISC_R_NOMEMORY
);
13381 signing
->magic
= 0;
13382 signing
->db
= NULL
;
13383 signing
->dbiterator
= NULL
;
13384 signing
->algorithm
= algorithm
;
13385 signing
->keyid
= keyid
;
13386 signing
->delete = delete;
13387 signing
->done
= ISC_FALSE
;
13391 for (current
= ISC_LIST_HEAD(zone
->signing
);
13393 current
= ISC_LIST_NEXT(current
, link
)) {
13394 if (current
->db
== zone
->db
&&
13395 current
->algorithm
== signing
->algorithm
&&
13396 current
->keyid
== signing
->keyid
) {
13397 if (current
->delete != signing
->delete)
13398 current
->done
= ISC_TRUE
;
13404 if (zone
->db
!= NULL
) {
13405 dns_db_attach(zone
->db
, &signing
->db
);
13406 result
= dns_db_createiterator(signing
->db
, 0,
13407 &signing
->dbiterator
);
13409 if (result
== ISC_R_SUCCESS
)
13410 result
= dns_dbiterator_first(signing
->dbiterator
);
13411 if (result
== ISC_R_SUCCESS
) {
13412 dns_dbiterator_pause(signing
->dbiterator
);
13413 ISC_LIST_INITANDAPPEND(zone
->signing
, signing
, link
);
13415 if (isc_time_isepoch(&zone
->signingtime
)) {
13416 zone
->signingtime
= now
;
13417 if (zone
->task
!= NULL
)
13418 zone_settimer(zone
, &now
);
13422 result
= ISC_R_NOTFOUND
;
13425 if (signing
!= NULL
) {
13426 if (signing
->db
!= NULL
)
13427 dns_db_detach(&signing
->db
);
13428 if (signing
->dbiterator
!= NULL
)
13429 dns_dbiterator_destroy(&signing
->dbiterator
);
13430 isc_mem_put(zone
->mctx
, signing
, sizeof *signing
);
13436 logmsg(const char *format
, ...) {
13438 va_start(args
, format
);
13439 isc_log_vwrite(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
13440 ISC_LOG_DEBUG(1), format
, args
);
13445 clear_keylist(dns_dnsseckeylist_t
*list
, isc_mem_t
*mctx
) {
13446 dns_dnsseckey_t
*key
;
13447 while (!ISC_LIST_EMPTY(*list
)) {
13448 key
= ISC_LIST_HEAD(*list
);
13449 ISC_LIST_UNLINK(*list
, key
, link
);
13450 dns_dnsseckey_destroy(mctx
, &key
);
13454 static isc_result_t
13455 next_keyevent(dst_key_t
*key
, isc_stdtime_t
*timep
) {
13456 isc_result_t result
;
13457 isc_stdtime_t now
, then
= 0, event
;
13460 isc_stdtime_get(&now
);
13462 for (i
= 0; i
<= DST_MAX_TIMES
; i
++) {
13463 result
= dst_key_gettime(key
, i
, &event
);
13464 if (result
== ISC_R_SUCCESS
&& event
> now
&&
13465 (then
== 0 || event
< then
))
13471 return (ISC_R_SUCCESS
);
13474 return (ISC_R_NOTFOUND
);
13477 static isc_result_t
13478 rr_exists(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_name_t
*name
,
13479 const dns_rdata_t
*rdata
, isc_boolean_t
*flag
)
13481 dns_rdataset_t rdataset
;
13482 dns_dbnode_t
*node
= NULL
;
13483 isc_result_t result
;
13485 dns_rdataset_init(&rdataset
);
13486 if (rdata
->type
== dns_rdatatype_nsec3
)
13487 CHECK(dns_db_findnsec3node(db
, name
, ISC_FALSE
, &node
));
13489 CHECK(dns_db_findnode(db
, name
, ISC_FALSE
, &node
));
13490 result
= dns_db_findrdataset(db
, node
, ver
, rdata
->type
, 0,
13491 (isc_stdtime_t
) 0, &rdataset
, NULL
);
13492 if (result
== ISC_R_NOTFOUND
) {
13494 result
= ISC_R_SUCCESS
;
13498 for (result
= dns_rdataset_first(&rdataset
);
13499 result
== ISC_R_SUCCESS
;
13500 result
= dns_rdataset_next(&rdataset
)) {
13501 dns_rdata_t myrdata
= DNS_RDATA_INIT
;
13502 dns_rdataset_current(&rdataset
, &myrdata
);
13503 if (!dns_rdata_compare(&myrdata
, rdata
))
13506 dns_rdataset_disassociate(&rdataset
);
13507 if (result
== ISC_R_SUCCESS
) {
13509 } else if (result
== ISC_R_NOMORE
) {
13511 result
= ISC_R_SUCCESS
;
13516 dns_db_detachnode(db
, &node
);
13521 * Add records to signal the state of signing or of key removal.
13523 static isc_result_t
13524 add_signing_records(dns_db_t
*db
, dns_rdatatype_t privatetype
,
13525 dns_dbversion_t
*ver
, dns_diff_t
*diff
)
13527 dns_difftuple_t
*tuple
, *newtuple
= NULL
;
13528 dns_rdata_dnskey_t dnskey
;
13529 dns_rdata_t rdata
= DNS_RDATA_INIT
;
13530 isc_boolean_t flag
;
13532 isc_result_t result
= ISC_R_SUCCESS
;
13533 isc_uint16_t keyid
;
13534 unsigned char buf
[5];
13535 dns_name_t
*name
= dns_db_origin(db
);
13537 for (tuple
= ISC_LIST_HEAD(diff
->tuples
);
13539 tuple
= ISC_LIST_NEXT(tuple
, link
)) {
13540 if (tuple
->rdata
.type
!= dns_rdatatype_dnskey
)
13543 dns_rdata_tostruct(&tuple
->rdata
, &dnskey
, NULL
);
13544 if ((dnskey
.flags
&
13545 (DNS_KEYFLAG_OWNERMASK
|DNS_KEYTYPE_NOAUTH
))
13546 != DNS_KEYOWNER_ZONE
)
13549 dns_rdata_toregion(&tuple
->rdata
, &r
);
13551 keyid
= dst_region_computeid(&r
, dnskey
.algorithm
);
13553 buf
[0] = dnskey
.algorithm
;
13554 buf
[1] = (keyid
& 0xff00) >> 8;
13555 buf
[2] = (keyid
& 0xff);
13556 buf
[3] = (tuple
->op
== DNS_DIFFOP_ADD
) ? 0 : 1;
13559 rdata
.length
= sizeof(buf
);
13560 rdata
.type
= privatetype
;
13561 rdata
.rdclass
= tuple
->rdata
.rdclass
;
13563 CHECK(rr_exists(db
, ver
, name
, &rdata
, &flag
));
13566 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
13567 name
, 0, &rdata
, &newtuple
));
13568 CHECK(do_one_tuple(&newtuple
, db
, ver
, diff
));
13569 INSIST(newtuple
== NULL
);
13571 * Remove any record which says this operation has already
13575 CHECK(rr_exists(db
, ver
, name
, &rdata
, &flag
));
13577 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_DEL
,
13578 name
, 0, &rdata
, &newtuple
));
13579 CHECK(do_one_tuple(&newtuple
, db
, ver
, diff
));
13580 INSIST(newtuple
== NULL
);
13588 sign_dnskey(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
13591 isc_result_t result
;
13592 isc_stdtime_t now
, inception
, soaexpire
;
13593 isc_boolean_t check_ksk
, keyset_kskonly
;
13594 dst_key_t
*zone_keys
[MAXZONEKEYS
];
13595 unsigned int nkeys
= 0, i
;
13597 result
= find_zone_keys(zone
, db
, ver
, zone
->mctx
, MAXZONEKEYS
,
13598 zone_keys
, &nkeys
);
13599 if (result
!= ISC_R_SUCCESS
) {
13600 dns_zone_log(zone
, ISC_LOG_ERROR
,
13601 "sign_dnskey:find_zone_keys -> %s\n",
13602 dns_result_totext(result
));
13606 isc_stdtime_get(&now
);
13607 inception
= now
- 3600; /* Allow for clock skew. */
13608 soaexpire
= now
+ dns_zone_getsigvalidityinterval(zone
);
13610 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
13611 keyset_kskonly
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
);
13613 result
= del_sigs(zone
, db
, ver
, &zone
->origin
, dns_rdatatype_dnskey
,
13614 diff
, zone_keys
, nkeys
, now
);
13615 if (result
!= ISC_R_SUCCESS
) {
13616 dns_zone_log(zone
, ISC_LOG_ERROR
,
13617 "sign_dnskey:del_sigs -> %s\n",
13618 dns_result_totext(result
));
13622 result
= add_sigs(db
, ver
, &zone
->origin
, dns_rdatatype_dnskey
, diff
,
13623 zone_keys
, nkeys
, zone
->mctx
, inception
, soaexpire
,
13624 check_ksk
, keyset_kskonly
);
13626 if (result
!= ISC_R_SUCCESS
)
13627 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_rekey:add_sigs -> %s\n",
13628 dns_result_totext(result
));
13630 for (i
= 0; i
< nkeys
; i
++)
13631 dst_key_free(&zone_keys
[i
]);
13634 static isc_result_t
13635 zone_rekey(dns_zone_t
*zone
) {
13636 isc_result_t result
;
13637 dns_db_t
*db
= NULL
;
13638 dns_dbnode_t
*node
= NULL
;
13639 dns_dbversion_t
*ver
= NULL
;
13640 dns_rdataset_t soaset
, soasigs
, keyset
, keysigs
;
13641 dns_dnsseckeylist_t dnskeys
, keys
, rmkeys
;
13642 dns_dnsseckey_t
*key
;
13644 isc_boolean_t commit
= ISC_FALSE
;
13645 dns_ttl_t ttl
= 3600;
13650 REQUIRE(DNS_ZONE_VALID(zone
));
13652 ISC_LIST_INIT(dnskeys
);
13653 ISC_LIST_INIT(keys
);
13654 ISC_LIST_INIT(rmkeys
);
13655 dns_rdataset_init(&soaset
);
13656 dns_rdataset_init(&soasigs
);
13657 dns_rdataset_init(&keyset
);
13658 dns_rdataset_init(&keysigs
);
13659 dir
= dns_zone_getkeydirectory(zone
);
13661 dns_diff_init(mctx
, &diff
);
13662 isc_stdtime_get(&now
);
13664 CHECK(dns_zone_getdb(zone
, &db
));
13665 CHECK(dns_db_newversion(db
, &ver
));
13666 CHECK(dns_db_getoriginnode(db
, &node
));
13668 dns_zone_log(zone
, ISC_LOG_INFO
, "reconfiguring zone keys");
13670 /* Get the SOA record's TTL */
13671 CHECK(dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_soa
,
13672 dns_rdatatype_none
, 0, &soaset
, &soasigs
));
13674 dns_rdataset_disassociate(&soaset
);
13676 /* Get the DNSKEY rdataset */
13677 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_dnskey
,
13678 dns_rdatatype_none
, 0, &keyset
, &keysigs
);
13679 if (result
== ISC_R_SUCCESS
) {
13681 CHECK(dns_dnssec_keylistfromrdataset(&zone
->origin
, dir
,
13683 &keysigs
, &soasigs
,
13684 ISC_FALSE
, ISC_FALSE
,
13686 } else if (result
!= ISC_R_NOTFOUND
)
13689 result
= dns_dnssec_findmatchingkeys(&zone
->origin
, dir
, mctx
, &keys
);
13690 if (result
== ISC_R_SUCCESS
) {
13691 isc_boolean_t check_ksk
;
13692 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
13694 CHECK(dns_dnssec_updatekeys(&dnskeys
, &keys
, &rmkeys
,
13695 &zone
->origin
, ttl
, &diff
,
13696 ISC_TF(!check_ksk
), mctx
, logmsg
));
13697 if (!ISC_LIST_EMPTY(diff
.tuples
)) {
13699 dns_diff_apply(&diff
, db
, ver
);
13700 sign_dnskey(zone
, db
, ver
, &diff
);
13701 add_signing_records(db
, zone
->privatetype
, ver
, &diff
);
13702 result
= increment_soa_serial(db
, ver
, &diff
, mctx
);
13703 if (result
== ISC_R_SUCCESS
)
13704 zone_journal(zone
, &diff
, "zone_rekey");
13708 dns_db_closeversion(db
, &ver
, commit
);
13711 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOTIFYRESIGN
);
13713 for (key
= ISC_LIST_HEAD(rmkeys
);
13715 key
= ISC_LIST_NEXT(key
, link
)) {
13716 zone_signwithkey(zone
, dst_key_alg(key
->key
),
13717 dst_key_id(key
->key
), ISC_TRUE
);
13720 for (key
= ISC_LIST_HEAD(dnskeys
);
13722 key
= ISC_LIST_NEXT(key
, link
)) {
13723 if (key
->first_sign
) {
13724 zone_signwithkey(zone
, dst_key_alg(key
->key
),
13725 dst_key_id(key
->key
),
13727 key
->is_active
= ISC_TRUE
;
13728 key
->first_sign
= ISC_FALSE
;
13733 isc_time_settoepoch(&zone
->refreshkeytime
);
13734 for (key
= ISC_LIST_HEAD(dnskeys
);
13736 key
= ISC_LIST_NEXT(key
, link
)) {
13737 isc_stdtime_t then
;
13738 isc_time_t timenow
, timethen
;
13741 * If we are doing automatic key maintenace and the
13742 * key metadata indicates there is a key change event
13743 * scheduled in the future, set the key refresh timer.
13745 if (!DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_MAINTAIN
))
13748 result
= next_keyevent(key
->key
, &then
);
13749 if (result
!= ISC_R_SUCCESS
)
13752 isc_time_set(&timethen
, then
, 0);
13753 if (isc_time_isepoch(&zone
->refreshkeytime
) ||
13754 isc_time_compare(&timethen
, &zone
->refreshkeytime
) < 0) {
13755 zone
->refreshkeytime
= timethen
;
13756 zone_settimer(zone
, &timenow
);
13760 result
= ISC_R_SUCCESS
;
13763 dns_diff_clear(&diff
);
13765 clear_keylist(&dnskeys
, mctx
);
13766 clear_keylist(&keys
, mctx
);
13767 clear_keylist(&rmkeys
, mctx
);
13770 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
13771 if (dns_rdataset_isassociated(&keyset
))
13772 dns_rdataset_disassociate(&keyset
);
13773 if (dns_rdataset_isassociated(&keysigs
))
13774 dns_rdataset_disassociate(&keysigs
);
13775 if (dns_rdataset_isassociated(&soasigs
))
13776 dns_rdataset_disassociate(&soasigs
);
13778 dns_db_detachnode(db
, &node
);
13780 dns_db_detach(&db
);
13785 dns_zone_rekey(dns_zone_t
*zone
) {
13786 isc_result_t result
;
13789 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESHING
);
13790 result
= zone_rekey(zone
);
13791 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESHING
);
13797 dns_zone_nscheck(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*version
,
13798 unsigned int *errors
)
13800 isc_result_t result
;
13801 dns_dbnode_t
*node
= NULL
;
13803 REQUIRE(DNS_ZONE_VALID(zone
));
13804 REQUIRE(errors
!= NULL
);
13806 result
= dns_db_getoriginnode(db
, &node
);
13807 if (result
!= ISC_R_SUCCESS
)
13809 result
= zone_count_ns_rr(zone
, db
, node
, version
, NULL
, errors
,
13811 dns_db_detachnode(db
, &node
);