1 /* $NetBSD: zone.c,v 1.14 2015/07/08 17:28:59 christos Exp $ */
4 * Copyright (C) 2004-2015 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.
27 #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/stats.h>
36 #include <isc/stdtime.h>
37 #include <isc/strerror.h>
38 #include <isc/string.h>
39 #include <isc/taskpool.h>
40 #include <isc/thread.h>
41 #include <isc/timer.h>
44 #include <dns/acache.h>
47 #include <dns/callbacks.h>
49 #include <dns/dbiterator.h>
51 #include <dns/dnssec.h>
52 #include <dns/events.h>
53 #include <dns/journal.h>
54 #include <dns/keydata.h>
55 #include <dns/keytable.h>
56 #include <dns/keyvalues.h>
58 #include <dns/master.h>
59 #include <dns/masterdump.h>
60 #include <dns/message.h>
63 #include <dns/nsec3.h>
65 #include <dns/private.h>
67 #include <dns/rcode.h>
68 #include <dns/rdata.h>
69 #include <dns/rdataclass.h>
70 #include <dns/rdatalist.h>
71 #include <dns/rdataset.h>
72 #include <dns/rdatasetiter.h>
73 #include <dns/rdatastruct.h>
74 #include <dns/rdatatype.h>
75 #include <dns/request.h>
76 #include <dns/resolver.h>
77 #include <dns/result.h>
78 #include <dns/rriterator.h>
81 #include <dns/stats.h>
84 #include <dns/update.h>
85 #include <dns/xfrin.h>
91 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
92 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
94 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
95 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
97 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
98 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
100 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
101 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
103 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
104 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
106 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
107 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
109 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
110 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
113 * Ensure 'a' is at least 'min' but not more than 'max'.
115 #define RANGE(a, min, max) \
116 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
118 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
123 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
124 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
125 #define ALG(x) dst_key_alg(x)
130 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
131 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
132 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
133 #define RESIGN_DELAY 3600 /*%< 1 hour */
135 #ifndef DNS_MAX_EXPIRE
136 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
139 #ifndef DNS_DUMP_DELAY
140 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
143 typedef struct dns_notify dns_notify_t
;
144 typedef struct dns_stub dns_stub_t
;
145 typedef struct dns_load dns_load_t
;
146 typedef struct dns_forward dns_forward_t
;
147 typedef ISC_LIST(dns_forward_t
) dns_forwardlist_t
;
148 typedef struct dns_io dns_io_t
;
149 typedef ISC_LIST(dns_io_t
) dns_iolist_t
;
150 typedef struct dns_signing dns_signing_t
;
151 typedef ISC_LIST(dns_signing_t
) dns_signinglist_t
;
152 typedef struct dns_nsec3chain dns_nsec3chain_t
;
153 typedef ISC_LIST(dns_nsec3chain_t
) dns_nsec3chainlist_t
;
154 typedef struct dns_keyfetch dns_keyfetch_t
;
155 typedef struct dns_asyncload dns_asyncload_t
;
156 typedef struct dns_include dns_include_t
;
158 #define DNS_ZONE_CHECKLOCK
159 #ifdef DNS_ZONE_CHECKLOCK
160 #define LOCK_ZONE(z) \
161 do { LOCK(&(z)->lock); \
162 INSIST((z)->locked == ISC_FALSE); \
163 (z)->locked = ISC_TRUE; \
164 } while (/*CONSTCOND*/0)
165 #define UNLOCK_ZONE(z) \
166 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (/*CONSTCOND*/0)
167 #define LOCKED_ZONE(z) ((z)->locked)
168 #define TRYLOCK_ZONE(result, z) \
170 result = isc_mutex_trylock(&(z)->lock); \
171 if (result == ISC_R_SUCCESS) { \
172 INSIST((z)->locked == ISC_FALSE); \
173 (z)->locked = ISC_TRUE; \
175 } while (/*CONSTCOND*/0)
177 #define LOCK_ZONE(z) LOCK(&(z)->lock)
178 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
179 #define LOCKED_ZONE(z) ISC_TRUE
180 #define TRYLOCK_ZONE(result, z) \
181 do { result = isc_mutex_trylock(&(z)->lock); } while (/*CONSTCOND*/0)
184 #ifdef ISC_RWLOCK_USEATOMIC
185 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
186 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
187 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
188 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
190 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
191 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
192 #define ZONEDB_LOCK(l, t) LOCK(l)
193 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
200 #ifdef DNS_ZONE_CHECKLOCK
201 isc_boolean_t locked
;
204 isc_refcount_t erefs
;
206 #ifdef ISC_RWLOCK_USEATOMIC
211 dns_db_t
*db
; /* Locked by dblock */
215 ISC_LINK(dns_zone_t
) link
; /* Used by zmgr. */
220 ISC_LIST(dns_include_t
) includes
; /* Include files */
221 ISC_LIST(dns_include_t
) newincludes
; /* Loading */
222 unsigned int nincludes
;
223 dns_masterformat_t masterformat
;
225 isc_int32_t journalsize
;
226 dns_rdataclass_t rdclass
;
229 unsigned int options
;
230 unsigned int options2
;
231 unsigned int db_argc
;
233 isc_time_t expiretime
;
234 isc_time_t refreshtime
;
237 isc_time_t notifytime
;
238 isc_time_t resigntime
;
239 isc_time_t keywarntime
;
240 isc_time_t signingtime
;
241 isc_time_t nsec3chaintime
;
242 isc_time_t refreshkeytime
;
243 isc_uint32_t refreshkeyinterval
;
244 isc_uint32_t refreshkeycount
;
245 isc_uint32_t refresh
;
248 isc_uint32_t minimum
;
249 isc_stdtime_t key_expiry
;
250 isc_stdtime_t log_key_expired_timer
;
253 isc_uint32_t maxrefresh
;
254 isc_uint32_t minrefresh
;
255 isc_uint32_t maxretry
;
256 isc_uint32_t minretry
;
258 isc_sockaddr_t
*masters
;
259 isc_dscp_t
*masterdscps
;
260 dns_name_t
**masterkeynames
;
261 isc_boolean_t
*mastersok
;
262 unsigned int masterscnt
;
263 unsigned int curmaster
;
264 isc_sockaddr_t masteraddr
;
265 dns_notifytype_t notifytype
;
266 isc_sockaddr_t
*notify
;
267 dns_name_t
**notifykeynames
;
268 isc_dscp_t
*notifydscp
;
269 unsigned int notifycnt
;
270 isc_sockaddr_t notifyfrom
;
272 isc_task_t
*loadtask
;
273 isc_sockaddr_t notifysrc4
;
274 isc_sockaddr_t notifysrc6
;
275 isc_sockaddr_t xfrsource4
;
276 isc_sockaddr_t xfrsource6
;
277 isc_sockaddr_t altxfrsource4
;
278 isc_sockaddr_t altxfrsource6
;
279 isc_sockaddr_t sourceaddr
;
280 isc_dscp_t notifysrc4dscp
;
281 isc_dscp_t notifysrc6dscp
;
282 isc_dscp_t xfrsource4dscp
;
283 isc_dscp_t xfrsource6dscp
;
284 isc_dscp_t altxfrsource4dscp
;
285 isc_dscp_t altxfrsource6dscp
;
286 dns_xfrin_ctx_t
*xfr
; /* task locked */
287 dns_tsigkey_t
*tsigkey
; /* key used for xfr */
288 /* Access Control Lists */
289 dns_acl_t
*update_acl
;
290 dns_acl_t
*forward_acl
;
291 dns_acl_t
*notify_acl
;
292 dns_acl_t
*query_acl
;
293 dns_acl_t
*queryon_acl
;
295 isc_boolean_t update_disabled
;
296 isc_boolean_t zero_no_soa_ttl
;
297 dns_severity_t check_names
;
298 ISC_LIST(dns_notify_t
) notifies
;
299 dns_request_t
*request
;
304 isc_uint32_t maxxfrin
;
305 isc_uint32_t maxxfrout
;
307 isc_uint32_t idleout
;
308 isc_event_t ctlevent
;
309 dns_ssutable_t
*ssutable
;
310 isc_uint32_t sigvalidityinterval
;
311 isc_uint32_t sigresigninginterval
;
313 dns_acache_t
*acache
;
314 dns_checkmxfunc_t checkmx
;
315 dns_checksrvfunc_t checksrv
;
316 dns_checknsfunc_t checkns
;
318 * Zones in certain states such as "waiting for zone transfer"
319 * or "zone transfer in progress" are kept on per-state linked lists
320 * in the zone manager using the 'statelink' field. The 'statelist'
321 * field points at the list the zone is currently on. It the zone
322 * is not on any such list, statelist is NULL.
324 ISC_LINK(dns_zone_t
) statelink
;
325 dns_zonelist_t
*statelist
;
327 * Statistics counters about zone management.
331 * Optional per-zone statistics counters. Counted outside of this
334 dns_zonestat_level_t statlevel
;
335 isc_boolean_t requeststats_on
;
336 isc_stats_t
*requeststats
;
337 dns_stats_t
*rcvquerystats
;
338 isc_uint32_t notifydelay
;
339 dns_isselffunc_t isself
;
348 * Serial number for deferred journal compaction.
350 isc_uint32_t compact_serial
;
352 * Keys that are signing the zone for the first time.
354 dns_signinglist_t signing
;
355 dns_nsec3chainlist_t nsec3chain
;
357 * Signing / re-signing quantum stopping parameters.
359 isc_uint32_t signatures
;
361 dns_rdatatype_t privatetype
;
364 * Autosigning/key-maintenance options
366 isc_uint32_t keyopts
;
369 * True if added by "rndc addzone"
374 * response policy data to be relayed to the database
376 dns_rpz_zones_t
*rpzs
;
377 dns_rpz_num_t rpz_num
;
380 * Serial number update method.
382 dns_updatemethod_t updatemethod
;
385 * whether ixfr is requested
387 isc_boolean_t requestixfr
;
390 * Outstanding forwarded UPDATE requests.
392 dns_forwardlist_t forwards
;
397 isc_boolean_t sourceserialset
;
398 isc_uint32_t sourceserial
;
409 isc_boolean_t offline
;
412 #define zonediff_init(z, d) \
414 zonediff_t *_z = (z); \
416 (_z)->offline = ISC_FALSE; \
417 } while (/*CONSTCOND*/0)
419 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
420 #define DNS_ZONE_SETFLAG(z,f) do { \
421 INSIST(LOCKED_ZONE(z)); \
423 } while (/*CONSTCOND*/0)
424 #define DNS_ZONE_CLRFLAG(z,f) do { \
425 INSIST(LOCKED_ZONE(z)); \
426 (z)->flags &= ~(f); \
427 } while (/*CONSTCOND*/0)
428 /* XXX MPA these may need to go back into zone.h */
429 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
430 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
431 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
432 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
433 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
434 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
435 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
436 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
437 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
438 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
440 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
442 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
444 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
445 * zone with no masters
447 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
448 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
449 * from SOA (if not set, we
451 * default timer values) */
452 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
453 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
454 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
455 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
456 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
457 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
458 #define DNS_ZONEFLG_FLUSH 0x00200000U
459 #define DNS_ZONEFLG_NOEDNS 0x00400000U
460 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
461 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
462 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
463 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
464 #define DNS_ZONEFLG_THAW 0x08000000U
465 #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
466 #define DNS_ZONEFLG_NODELAY 0x20000000U
467 #define DNS_ZONEFLG_SENDSECURE 0x40000000U
468 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
469 * due to the zone just
470 * being loaded for the
473 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
474 #define DNS_ZONE_OPTION2(z,o) (((z)->options2 & (o)) != 0)
475 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
477 /* Flags for zone_load() */
478 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
479 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
482 #define UNREACH_CHACHE_SIZE 10U
483 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
486 do { result = (op); \
487 if (result != ISC_R_SUCCESS) goto failure; \
488 } while (/*CONSTCOND*/0)
490 struct dns_unreachable
{
491 isc_sockaddr_t remote
;
492 isc_sockaddr_t local
;
501 int refs
; /* Locked by rwlock */
502 isc_taskmgr_t
* taskmgr
;
503 isc_timermgr_t
* timermgr
;
504 isc_socketmgr_t
* socketmgr
;
505 isc_taskpool_t
* zonetasks
;
506 isc_taskpool_t
* loadtasks
;
508 isc_pool_t
* mctxpool
;
509 isc_ratelimiter_t
* notifyrl
;
510 isc_ratelimiter_t
* refreshrl
;
511 isc_ratelimiter_t
* startupnotifyrl
;
512 isc_ratelimiter_t
* startuprefreshrl
;
517 /* Locked by rwlock. */
518 dns_zonelist_t zones
;
519 dns_zonelist_t waiting_for_xfrin
;
520 dns_zonelist_t xfrin_in_progress
;
522 /* Configuration data. */
523 isc_uint32_t transfersin
;
524 isc_uint32_t transfersperns
;
525 unsigned int notifyrate
;
526 unsigned int startupnotifyrate
;
527 unsigned int serialqueryrate
;
528 unsigned int startupserialqueryrate
;
530 /* Locked by iolock */
531 isc_uint32_t iolimit
;
532 isc_uint32_t ioactive
;
536 /* Locked by urlock. */
538 struct dns_unreachable unreachable
[UNREACH_CHACHE_SIZE
];
550 dns_request_t
*request
;
555 ISC_LINK(dns_notify_t
) link
;
559 #define DNS_NOTIFY_NOSOA 0x0001U
560 #define DNS_NOTIFY_STARTUP 0x0002U
563 * dns_stub holds state while performing a 'stub' transfer.
564 * 'db' is the zone's 'db' or a new one if this is the initial
573 dns_dbversion_t
*version
;
585 dns_rdatacallbacks_t callbacks
;
589 * Hold forward state.
595 isc_buffer_t
*msgbuf
;
596 dns_request_t
*request
;
599 dns_updatecallback_t callback
;
601 unsigned int options
;
602 ISC_LINK(dns_forward_t
) link
;
606 * Hold IO request state.
613 ISC_LINK(dns_io_t
) link
;
618 * Hold state for when we are signing a zone with a new
619 * DNSKEY as result of an update.
624 dns_dbiterator_t
*dbiterator
;
625 dns_secalg_t algorithm
;
627 isc_boolean_t
delete;
629 ISC_LINK(dns_signing_t
) link
;
632 struct dns_nsec3chain
{
635 dns_dbiterator_t
*dbiterator
;
636 dns_rdata_nsec3param_t nsec3param
;
637 unsigned char salt
[255];
639 isc_boolean_t seen_nsec
;
640 isc_boolean_t delete_nsec
;
641 isc_boolean_t save_delete_nsec
;
642 ISC_LINK(dns_nsec3chain_t
) link
;
645 * 'dbiterator' contains a iterator for the database. If we are creating
646 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
647 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
650 * 'nsec3param' contains the parameters of the NSEC3 chain being created
653 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
655 * 'seen_nsec' will be set to true if, while iterating the zone to create a
656 * NSEC3 chain, a NSEC record is seen.
658 * 'delete_nsec' will be set to true if, at the completion of the creation
659 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
660 * are in the process of deleting the NSEC chain.
662 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
663 * so it can be recovered in the event of a error.
666 struct dns_keyfetch
{
667 dns_fixedname_t name
;
668 dns_rdataset_t keydataset
;
669 dns_rdataset_t dnskeyset
;
670 dns_rdataset_t dnskeysigset
;
677 * Hold state for an asynchronous load
679 struct dns_asyncload
{
681 dns_zt_zoneloaded_t loaded
;
686 * Reference to an include file encountered during loading
691 ISC_LINK(dns_include_t
) link
;
695 #define DAY (24*HOUR)
696 #define MONTH (30*DAY)
699 * These can be overridden by the -T mkeytimers option on the command
700 * line, so that we can test with shorter periods than specified in
703 unsigned int dns_zone_mkey_hour
= HOUR
;
704 unsigned int dns_zone_mkey_day
= (24 * HOUR
);
705 unsigned int dns_zone_mkey_month
= (30 * DAY
);
708 #define SEND_BUFFER_SIZE 2048
710 static void zone_settimer(dns_zone_t
*, isc_time_t
*);
711 static void cancel_refresh(dns_zone_t
*);
712 static void zone_debuglog(dns_zone_t
*zone
, const char *, int debuglevel
,
713 const char *msg
, ...) ISC_FORMAT_PRINTF(4, 5);
714 static void notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...)
715 ISC_FORMAT_PRINTF(3, 4);
716 static void queue_xfrin(dns_zone_t
*zone
);
717 static isc_result_t
update_one_rr(dns_db_t
*db
, dns_dbversion_t
*ver
,
718 dns_diff_t
*diff
, dns_diffop_t op
,
719 dns_name_t
*name
, dns_ttl_t ttl
,
721 static void zone_unload(dns_zone_t
*zone
);
722 static void zone_expire(dns_zone_t
*zone
);
723 static void zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
);
724 static void zone_idetach(dns_zone_t
**zonep
);
725 static isc_result_t
zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
,
727 static inline void zone_attachdb(dns_zone_t
*zone
, dns_db_t
*db
);
728 static inline void zone_detachdb(dns_zone_t
*zone
);
729 static isc_result_t
default_journal(dns_zone_t
*zone
);
730 static void zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
);
731 static isc_result_t
zone_postload(dns_zone_t
*zone
, dns_db_t
*db
,
732 isc_time_t loadtime
, isc_result_t result
);
733 static void zone_needdump(dns_zone_t
*zone
, unsigned int delay
);
734 static void zone_shutdown(isc_task_t
*, isc_event_t
*);
735 static void zone_loaddone(void *arg
, isc_result_t result
);
736 static isc_result_t
zone_startload(dns_db_t
*db
, dns_zone_t
*zone
,
737 isc_time_t loadtime
);
738 static void zone_namerd_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
739 static void zone_name_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
740 static void zone_rdclass_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
741 static void zone_viewname_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
742 static isc_result_t
zone_send_secureserial(dns_zone_t
*zone
,
743 isc_uint32_t serial
);
746 /* ondestroy example */
747 static void dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
);
750 static void refresh_callback(isc_task_t
*, isc_event_t
*);
751 static void stub_callback(isc_task_t
*, isc_event_t
*);
752 static void queue_soa_query(dns_zone_t
*zone
);
753 static void soa_query(isc_task_t
*, isc_event_t
*);
754 static void ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
,
756 static int message_count(dns_message_t
*msg
, dns_section_t section
,
757 dns_rdatatype_t type
);
758 static void notify_cancel(dns_zone_t
*zone
);
759 static void notify_find_address(dns_notify_t
*notify
);
760 static void notify_send(dns_notify_t
*notify
);
761 static isc_result_t
notify_createmessage(dns_zone_t
*zone
,
763 dns_message_t
**messagep
);
764 static void notify_done(isc_task_t
*task
, isc_event_t
*event
);
765 static void notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
);
766 static isc_result_t
zone_dump(dns_zone_t
*, isc_boolean_t
);
767 static void got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
);
768 static isc_result_t
zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
,
770 static void zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
);
771 static void zonemgr_free(dns_zonemgr_t
*zmgr
);
772 static isc_result_t
zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
773 isc_task_t
*task
, isc_taskaction_t action
,
774 void *arg
, dns_io_t
**iop
);
775 static void zonemgr_putio(dns_io_t
**iop
);
776 static void zonemgr_cancelio(dns_io_t
*io
);
779 zone_get_from_db(dns_zone_t
*zone
, dns_db_t
*db
, unsigned int *nscount
,
780 unsigned int *soacount
, isc_uint32_t
*serial
,
781 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
782 isc_uint32_t
*expire
, isc_uint32_t
*minimum
,
783 unsigned int *errors
);
785 static void zone_freedbargs(dns_zone_t
*zone
);
786 static void forward_callback(isc_task_t
*task
, isc_event_t
*event
);
787 static void zone_saveunique(dns_zone_t
*zone
, const char *path
,
788 const char *templat
);
789 static void zone_maintenance(dns_zone_t
*zone
);
790 static void zone_notify(dns_zone_t
*zone
, isc_time_t
*now
);
791 static void dump_done(void *arg
, isc_result_t result
);
792 static isc_result_t
zone_signwithkey(dns_zone_t
*zone
, dns_secalg_t algorithm
,
793 isc_uint16_t keyid
, isc_boolean_t
delete);
794 static isc_result_t
delete_nsec(dns_db_t
*db
, dns_dbversion_t
*ver
,
795 dns_dbnode_t
*node
, dns_name_t
*name
,
797 static void zone_rekey(dns_zone_t
*zone
);
798 static isc_result_t
zone_send_securedb(dns_zone_t
*zone
, dns_db_t
*db
);
799 static void setrl(isc_ratelimiter_t
*rl
, unsigned int *rate
,
802 #define ENTER zone_debuglog(zone, me, 1, "enter")
804 static const unsigned int dbargc_default
= 1;
805 static const char *dbargv_default
[] = { "rbt" };
807 #define DNS_ZONE_JITTER_ADD(a, b, c) \
811 _j = isc_random_jitter((b), (b)/4); \
812 isc_interval_set(&_i, _j, 0); \
813 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
814 dns_zone_log(zone, ISC_LOG_WARNING, \
815 "epoch approaching: upgrade required: " \
816 "now + %s failed", #b); \
817 isc_interval_set(&_i, _j/2, 0); \
818 (void)isc_time_add((a), &_i, (c)); \
820 } while (/*CONSTCOND*/0)
822 #define DNS_ZONE_TIME_ADD(a, b, c) \
825 isc_interval_set(&_i, (b), 0); \
826 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
827 dns_zone_log(zone, ISC_LOG_WARNING, \
828 "epoch approaching: upgrade required: " \
829 "now + %s failed", #b); \
830 isc_interval_set(&_i, (b)/2, 0); \
831 (void)isc_time_add((a), &_i, (c)); \
833 } while (/*CONSTCOND*/0)
835 typedef struct nsec3param nsec3param_t
;
837 unsigned char data
[DNS_NSEC3PARAM_BUFFERSIZE
+ 1];
840 isc_boolean_t replace
;
841 ISC_LINK(nsec3param_t
) link
;
843 typedef ISC_LIST(nsec3param_t
) nsec3paramlist_t
;
850 * Increment resolver-related statistics counters. Zone must be locked.
853 inc_stats(dns_zone_t
*zone
, isc_statscounter_t counter
) {
854 if (zone
->stats
!= NULL
)
855 isc_stats_increment(zone
->stats
, counter
);
859 *** Public functions.
863 dns_zone_create(dns_zone_t
**zonep
, isc_mem_t
*mctx
) {
868 REQUIRE(zonep
!= NULL
&& *zonep
== NULL
);
869 REQUIRE(mctx
!= NULL
);
872 zone
= isc_mem_get(mctx
, sizeof(*zone
));
874 return (ISC_R_NOMEMORY
);
877 isc_mem_attach(mctx
, &zone
->mctx
);
879 result
= isc_mutex_init(&zone
->lock
);
880 if (result
!= ISC_R_SUCCESS
)
883 result
= ZONEDB_INITLOCK(&zone
->dblock
);
884 if (result
!= ISC_R_SUCCESS
)
887 /* XXX MPA check that all elements are initialised */
888 #ifdef DNS_ZONE_CHECKLOCK
889 zone
->locked
= ISC_FALSE
;
893 ISC_LINK_INIT(zone
, link
);
894 result
= isc_refcount_init(&zone
->erefs
, 1); /* Implicit attach. */
895 if (result
!= ISC_R_SUCCESS
)
898 dns_name_init(&zone
->origin
, NULL
);
899 zone
->strnamerd
= NULL
;
900 zone
->strname
= NULL
;
901 zone
->strrdclass
= NULL
;
902 zone
->strviewname
= NULL
;
903 zone
->masterfile
= NULL
;
904 ISC_LIST_INIT(zone
->includes
);
905 ISC_LIST_INIT(zone
->newincludes
);
907 zone
->masterformat
= dns_masterformat_none
;
908 zone
->keydirectory
= NULL
;
909 zone
->journalsize
= -1;
910 zone
->journal
= NULL
;
911 zone
->rdclass
= dns_rdataclass_none
;
912 zone
->type
= dns_zone_none
;
917 zone
->db_argv
= NULL
;
918 isc_time_settoepoch(&zone
->expiretime
);
919 isc_time_settoepoch(&zone
->refreshtime
);
920 isc_time_settoepoch(&zone
->dumptime
);
921 isc_time_settoepoch(&zone
->loadtime
);
922 zone
->notifytime
= now
;
923 isc_time_settoepoch(&zone
->resigntime
);
924 isc_time_settoepoch(&zone
->keywarntime
);
925 isc_time_settoepoch(&zone
->signingtime
);
926 isc_time_settoepoch(&zone
->nsec3chaintime
);
927 isc_time_settoepoch(&zone
->refreshkeytime
);
928 zone
->refreshkeyinterval
= 0;
929 zone
->refreshkeycount
= 0;
930 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
931 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
934 zone
->maxrefresh
= DNS_ZONE_MAXREFRESH
;
935 zone
->minrefresh
= DNS_ZONE_MINREFRESH
;
936 zone
->maxretry
= DNS_ZONE_MAXRETRY
;
937 zone
->minretry
= DNS_ZONE_MINRETRY
;
938 zone
->masters
= NULL
;
939 zone
->masterdscps
= NULL
;
940 zone
->masterkeynames
= NULL
;
941 zone
->mastersok
= NULL
;
942 zone
->masterscnt
= 0;
946 zone
->notifykeynames
= NULL
;
947 zone
->notifydscp
= NULL
;
948 zone
->notifytype
= dns_notifytype_yes
;
951 zone
->loadtask
= NULL
;
952 zone
->update_acl
= NULL
;
953 zone
->forward_acl
= NULL
;
954 zone
->notify_acl
= NULL
;
955 zone
->query_acl
= NULL
;
956 zone
->queryon_acl
= NULL
;
957 zone
->xfr_acl
= NULL
;
958 zone
->update_disabled
= ISC_FALSE
;
959 zone
->zero_no_soa_ttl
= ISC_TRUE
;
960 zone
->check_names
= dns_severity_ignore
;
961 zone
->request
= NULL
;
965 zone
->writeio
= NULL
;
967 zone
->idlein
= DNS_DEFAULT_IDLEIN
;
968 zone
->idleout
= DNS_DEFAULT_IDLEOUT
;
969 zone
->log_key_expired_timer
= 0;
970 ISC_LIST_INIT(zone
->notifies
);
971 isc_sockaddr_any(&zone
->notifysrc4
);
972 isc_sockaddr_any6(&zone
->notifysrc6
);
973 isc_sockaddr_any(&zone
->xfrsource4
);
974 isc_sockaddr_any6(&zone
->xfrsource6
);
975 isc_sockaddr_any(&zone
->altxfrsource4
);
976 isc_sockaddr_any6(&zone
->altxfrsource6
);
977 zone
->notifysrc4dscp
= -1;
978 zone
->notifysrc6dscp
= -1;
979 zone
->xfrsource4dscp
= -1;
980 zone
->xfrsource6dscp
= -1;
981 zone
->altxfrsource4dscp
= -1;
982 zone
->altxfrsource6dscp
= -1;
984 zone
->tsigkey
= NULL
;
985 zone
->maxxfrin
= MAX_XFER_TIME
;
986 zone
->maxxfrout
= MAX_XFER_TIME
;
987 zone
->ssutable
= NULL
;
988 zone
->sigvalidityinterval
= 30 * 24 * 3600;
989 zone
->sigresigninginterval
= 7 * 24 * 3600;
992 zone
->checkmx
= NULL
;
993 zone
->checksrv
= NULL
;
994 zone
->checkns
= NULL
;
995 ISC_LINK_INIT(zone
, statelink
);
996 zone
->statelist
= NULL
;
998 zone
->requeststats_on
= ISC_FALSE
;
999 zone
->statlevel
= dns_zonestat_none
;
1000 zone
->requeststats
= NULL
;
1001 zone
->rcvquerystats
= NULL
;
1002 zone
->notifydelay
= 5;
1003 zone
->isself
= NULL
;
1004 zone
->isselfarg
= NULL
;
1005 ISC_LIST_INIT(zone
->signing
);
1006 ISC_LIST_INIT(zone
->nsec3chain
);
1007 zone
->signatures
= 10;
1009 zone
->privatetype
= (dns_rdatatype_t
)0xffffU
;
1010 zone
->added
= ISC_FALSE
;
1012 zone
->rpz_num
= DNS_RPZ_INVALID_NUM
;
1013 ISC_LIST_INIT(zone
->forwards
);
1015 zone
->secure
= NULL
;
1016 zone
->sourceserial
= 0;
1017 zone
->sourceserialset
= ISC_FALSE
;
1019 zone
->magic
= ZONE_MAGIC
;
1021 /* Must be after magic is set. */
1022 result
= dns_zone_setdbtype(zone
, dbargc_default
, dbargv_default
);
1023 if (result
!= ISC_R_SUCCESS
)
1026 ISC_EVENT_INIT(&zone
->ctlevent
, sizeof(zone
->ctlevent
), 0, NULL
,
1027 DNS_EVENT_ZONECONTROL
, zone_shutdown
, zone
, zone
,
1030 return (ISC_R_SUCCESS
);
1033 isc_refcount_decrement(&zone
->erefs
, NULL
);
1034 isc_refcount_destroy(&zone
->erefs
);
1037 ZONEDB_DESTROYLOCK(&zone
->dblock
);
1040 DESTROYLOCK(&zone
->lock
);
1043 isc_mem_putanddetach(&zone
->mctx
, zone
, sizeof(*zone
));
1048 * Free a zone. Because we require that there be no more
1049 * outstanding events or references, no locking is necessary.
1052 zone_free(dns_zone_t
*zone
) {
1053 isc_mem_t
*mctx
= NULL
;
1054 dns_signing_t
*signing
;
1055 dns_nsec3chain_t
*nsec3chain
;
1056 dns_include_t
*include
;
1058 REQUIRE(DNS_ZONE_VALID(zone
));
1059 REQUIRE(isc_refcount_current(&zone
->erefs
) == 0);
1060 REQUIRE(zone
->irefs
== 0);
1061 REQUIRE(!LOCKED_ZONE(zone
));
1062 REQUIRE(zone
->timer
== NULL
);
1063 REQUIRE(zone
->zmgr
== NULL
);
1066 * Managed objects. Order is important.
1068 if (zone
->request
!= NULL
)
1069 dns_request_destroy(&zone
->request
); /* XXXMPA */
1070 INSIST(zone
->readio
== NULL
);
1071 INSIST(zone
->statelist
== NULL
);
1072 INSIST(zone
->writeio
== NULL
);
1074 if (zone
->task
!= NULL
)
1075 isc_task_detach(&zone
->task
);
1076 if (zone
->loadtask
!= NULL
)
1077 isc_task_detach(&zone
->loadtask
);
1079 /* Unmanaged objects */
1080 for (signing
= ISC_LIST_HEAD(zone
->signing
);
1082 signing
= ISC_LIST_HEAD(zone
->signing
)) {
1083 ISC_LIST_UNLINK(zone
->signing
, signing
, link
);
1084 dns_db_detach(&signing
->db
);
1085 dns_dbiterator_destroy(&signing
->dbiterator
);
1086 isc_mem_put(zone
->mctx
, signing
, sizeof *signing
);
1088 for (nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
1090 nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
)) {
1091 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
, link
);
1092 dns_db_detach(&nsec3chain
->db
);
1093 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
1094 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
1096 for (include
= ISC_LIST_HEAD(zone
->includes
);
1098 include
= ISC_LIST_HEAD(zone
->includes
)) {
1099 ISC_LIST_UNLINK(zone
->includes
, include
, link
);
1100 isc_mem_free(zone
->mctx
, include
->name
);
1101 isc_mem_put(zone
->mctx
, include
, sizeof *include
);
1103 for (include
= ISC_LIST_HEAD(zone
->newincludes
);
1105 include
= ISC_LIST_HEAD(zone
->newincludes
)) {
1106 ISC_LIST_UNLINK(zone
->newincludes
, include
, link
);
1107 isc_mem_free(zone
->mctx
, include
->name
);
1108 isc_mem_put(zone
->mctx
, include
, sizeof *include
);
1110 if (zone
->masterfile
!= NULL
)
1111 isc_mem_free(zone
->mctx
, zone
->masterfile
);
1112 zone
->masterfile
= NULL
;
1113 if (zone
->keydirectory
!= NULL
)
1114 isc_mem_free(zone
->mctx
, zone
->keydirectory
);
1115 zone
->keydirectory
= NULL
;
1116 zone
->journalsize
= -1;
1117 if (zone
->journal
!= NULL
)
1118 isc_mem_free(zone
->mctx
, zone
->journal
);
1119 zone
->journal
= NULL
;
1120 if (zone
->stats
!= NULL
)
1121 isc_stats_detach(&zone
->stats
);
1122 if (zone
->requeststats
!= NULL
)
1123 isc_stats_detach(&zone
->requeststats
);
1124 if (zone
->rcvquerystats
!= NULL
)
1125 dns_stats_detach(&zone
->rcvquerystats
);
1126 if (zone
->db
!= NULL
)
1127 zone_detachdb(zone
);
1128 if (zone
->acache
!= NULL
)
1129 dns_acache_detach(&zone
->acache
);
1130 if (zone
->rpzs
!= NULL
) {
1131 REQUIRE(zone
->rpz_num
< zone
->rpzs
->p
.num_zones
);
1132 dns_rpz_detach_rpzs(&zone
->rpzs
);
1133 zone
->rpz_num
= DNS_RPZ_INVALID_NUM
;
1135 zone_freedbargs(zone
);
1136 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone
, NULL
, NULL
, 0)
1138 RUNTIME_CHECK(dns_zone_setalsonotify(zone
, NULL
, 0)
1140 zone
->check_names
= dns_severity_ignore
;
1141 if (zone
->update_acl
!= NULL
)
1142 dns_acl_detach(&zone
->update_acl
);
1143 if (zone
->forward_acl
!= NULL
)
1144 dns_acl_detach(&zone
->forward_acl
);
1145 if (zone
->notify_acl
!= NULL
)
1146 dns_acl_detach(&zone
->notify_acl
);
1147 if (zone
->query_acl
!= NULL
)
1148 dns_acl_detach(&zone
->query_acl
);
1149 if (zone
->queryon_acl
!= NULL
)
1150 dns_acl_detach(&zone
->queryon_acl
);
1151 if (zone
->xfr_acl
!= NULL
)
1152 dns_acl_detach(&zone
->xfr_acl
);
1153 if (dns_name_dynamic(&zone
->origin
))
1154 dns_name_free(&zone
->origin
, zone
->mctx
);
1155 if (zone
->strnamerd
!= NULL
)
1156 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
1157 if (zone
->strname
!= NULL
)
1158 isc_mem_free(zone
->mctx
, zone
->strname
);
1159 if (zone
->strrdclass
!= NULL
)
1160 isc_mem_free(zone
->mctx
, zone
->strrdclass
);
1161 if (zone
->strviewname
!= NULL
)
1162 isc_mem_free(zone
->mctx
, zone
->strviewname
);
1163 if (zone
->ssutable
!= NULL
)
1164 dns_ssutable_detach(&zone
->ssutable
);
1167 ZONEDB_DESTROYLOCK(&zone
->dblock
);
1168 DESTROYLOCK(&zone
->lock
);
1169 isc_refcount_destroy(&zone
->erefs
);
1172 isc_mem_put(mctx
, zone
, sizeof(*zone
));
1173 isc_mem_detach(&mctx
);
1177 * Returns ISC_TRUE iff this the signed side of an inline-signing zone.
1178 * Caller should hold zone lock.
1180 static inline isc_boolean_t
1181 inline_secure(dns_zone_t
*zone
) {
1182 REQUIRE(DNS_ZONE_VALID(zone
));
1183 if (zone
->raw
!= NULL
)
1189 * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone
1190 * Caller should hold zone lock.
1192 static inline isc_boolean_t
1193 inline_raw(dns_zone_t
*zone
) {
1194 REQUIRE(DNS_ZONE_VALID(zone
));
1195 if (zone
->secure
!= NULL
)
1204 dns_zone_setclass(dns_zone_t
*zone
, dns_rdataclass_t rdclass
) {
1207 REQUIRE(DNS_ZONE_VALID(zone
));
1208 REQUIRE(rdclass
!= dns_rdataclass_none
);
1214 INSIST(zone
!= zone
->raw
);
1215 REQUIRE(zone
->rdclass
== dns_rdataclass_none
||
1216 zone
->rdclass
== rdclass
);
1217 zone
->rdclass
= rdclass
;
1219 if (zone
->strnamerd
!= NULL
)
1220 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
1221 if (zone
->strrdclass
!= NULL
)
1222 isc_mem_free(zone
->mctx
, zone
->strrdclass
);
1224 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
1225 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
1226 zone_rdclass_tostr(zone
, namebuf
, sizeof namebuf
);
1227 zone
->strrdclass
= isc_mem_strdup(zone
->mctx
, namebuf
);
1229 if (inline_secure(zone
))
1230 dns_zone_setclass(zone
->raw
, rdclass
);
1235 dns_zone_getclass(dns_zone_t
*zone
) {
1236 REQUIRE(DNS_ZONE_VALID(zone
));
1238 return (zone
->rdclass
);
1242 dns_zone_setnotifytype(dns_zone_t
*zone
, dns_notifytype_t notifytype
) {
1243 REQUIRE(DNS_ZONE_VALID(zone
));
1246 zone
->notifytype
= notifytype
;
1251 dns_zone_getserial2(dns_zone_t
*zone
, isc_uint32_t
*serialp
) {
1252 isc_result_t result
;
1253 unsigned int soacount
;
1255 REQUIRE(DNS_ZONE_VALID(zone
));
1256 REQUIRE(serialp
!= NULL
);
1259 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
1260 if (zone
->db
!= NULL
) {
1261 result
= zone_get_from_db(zone
, zone
->db
, NULL
, &soacount
,
1262 serialp
, NULL
, NULL
, NULL
, NULL
,
1264 if (result
== ISC_R_SUCCESS
&& soacount
== 0)
1265 result
= ISC_R_FAILURE
;
1267 result
= DNS_R_NOTLOADED
;
1268 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
1275 dns_zone_getserial(dns_zone_t
*zone
) {
1276 isc_result_t result
;
1277 isc_uint32_t serial
;
1279 result
= dns_zone_getserial2(zone
, &serial
);
1280 if (result
!= ISC_R_SUCCESS
)
1281 serial
= 0; /* XXX: not really correct, but no other choice */
1290 dns_zone_settype(dns_zone_t
*zone
, dns_zonetype_t type
) {
1293 REQUIRE(DNS_ZONE_VALID(zone
));
1294 REQUIRE(type
!= dns_zone_none
);
1300 REQUIRE(zone
->type
== dns_zone_none
|| zone
->type
== type
);
1303 if (zone
->strnamerd
!= NULL
)
1304 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
1306 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
1307 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
1312 zone_freedbargs(dns_zone_t
*zone
) {
1315 /* Free the old database argument list. */
1316 if (zone
->db_argv
!= NULL
) {
1317 for (i
= 0; i
< zone
->db_argc
; i
++)
1318 isc_mem_free(zone
->mctx
, zone
->db_argv
[i
]);
1319 isc_mem_put(zone
->mctx
, zone
->db_argv
,
1320 zone
->db_argc
* sizeof(*zone
->db_argv
));
1323 zone
->db_argv
= NULL
;
1327 dns_zone_getdbtype(dns_zone_t
*zone
, char ***argv
, isc_mem_t
*mctx
) {
1330 isc_result_t result
= ISC_R_SUCCESS
;
1334 REQUIRE(DNS_ZONE_VALID(zone
));
1335 REQUIRE(argv
!= NULL
&& *argv
== NULL
);
1338 size
= (zone
->db_argc
+ 1) * sizeof(char *);
1339 for (i
= 0; i
< zone
->db_argc
; i
++)
1340 size
+= strlen(zone
->db_argv
[i
]) + 1;
1341 mem
= isc_mem_allocate(mctx
, size
);
1345 tmp2
+= (zone
->db_argc
+ 1) * sizeof(char *);
1346 for (i
= 0; i
< zone
->db_argc
; i
++) {
1348 strcpy(tmp2
, zone
->db_argv
[i
]);
1349 tmp2
+= strlen(tmp2
) + 1;
1353 result
= ISC_R_NOMEMORY
;
1360 dns_zone_setdbtype(dns_zone_t
*zone
,
1361 unsigned int dbargc
, const char * const *dbargv
) {
1362 isc_result_t result
= ISC_R_SUCCESS
;
1366 REQUIRE(DNS_ZONE_VALID(zone
));
1367 REQUIRE(dbargc
>= 1);
1368 REQUIRE(dbargv
!= NULL
);
1372 /* Set up a new database argument list. */
1373 new = isc_mem_get(zone
->mctx
, dbargc
* sizeof(*new));
1376 for (i
= 0; i
< dbargc
; i
++)
1378 for (i
= 0; i
< dbargc
; i
++) {
1379 new[i
] = isc_mem_strdup(zone
->mctx
, dbargv
[i
]);
1384 /* Free the old list. */
1385 zone_freedbargs(zone
);
1387 zone
->db_argc
= dbargc
;
1388 zone
->db_argv
= new;
1389 result
= ISC_R_SUCCESS
;
1394 for (i
= 0; i
< dbargc
; i
++)
1396 isc_mem_free(zone
->mctx
, new[i
]);
1397 isc_mem_put(zone
->mctx
, new, dbargc
* sizeof(*new));
1399 result
= ISC_R_NOMEMORY
;
1407 dns_zone_setview(dns_zone_t
*zone
, dns_view_t
*view
) {
1409 REQUIRE(DNS_ZONE_VALID(zone
));
1412 INSIST(zone
!= zone
->raw
);
1413 if (zone
->view
!= NULL
)
1414 dns_view_weakdetach(&zone
->view
);
1415 dns_view_weakattach(view
, &zone
->view
);
1417 if (zone
->strviewname
!= NULL
)
1418 isc_mem_free(zone
->mctx
, zone
->strviewname
);
1419 if (zone
->strnamerd
!= NULL
)
1420 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
1422 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
1423 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
1424 zone_viewname_tostr(zone
, namebuf
, sizeof namebuf
);
1425 zone
->strviewname
= isc_mem_strdup(zone
->mctx
, namebuf
);
1427 if (inline_secure(zone
))
1428 dns_zone_setview(zone
->raw
, view
);
1434 dns_zone_getview(dns_zone_t
*zone
) {
1435 REQUIRE(DNS_ZONE_VALID(zone
));
1437 return (zone
->view
);
1442 dns_zone_setorigin(dns_zone_t
*zone
, const dns_name_t
*origin
) {
1443 isc_result_t result
;
1446 REQUIRE(DNS_ZONE_VALID(zone
));
1447 REQUIRE(origin
!= NULL
);
1450 INSIST(zone
!= zone
->raw
);
1451 if (dns_name_dynamic(&zone
->origin
)) {
1452 dns_name_free(&zone
->origin
, zone
->mctx
);
1453 dns_name_init(&zone
->origin
, NULL
);
1455 result
= dns_name_dup(origin
, zone
->mctx
, &zone
->origin
);
1457 if (zone
->strnamerd
!= NULL
)
1458 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
1459 if (zone
->strname
!= NULL
)
1460 isc_mem_free(zone
->mctx
, zone
->strname
);
1462 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
1463 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
1464 zone_name_tostr(zone
, namebuf
, sizeof namebuf
);
1465 zone
->strname
= isc_mem_strdup(zone
->mctx
, namebuf
);
1467 if (result
== ISC_R_SUCCESS
&& inline_secure(zone
))
1468 result
= dns_zone_setorigin(zone
->raw
, origin
);
1474 dns_zone_setacache(dns_zone_t
*zone
, dns_acache_t
*acache
) {
1475 REQUIRE(DNS_ZONE_VALID(zone
));
1476 REQUIRE(acache
!= NULL
);
1479 if (zone
->acache
!= NULL
)
1480 dns_acache_detach(&zone
->acache
);
1481 dns_acache_attach(acache
, &zone
->acache
);
1482 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
1483 if (zone
->db
!= NULL
) {
1484 isc_result_t result
;
1487 * If the zone reuses an existing DB, the DB needs to be
1488 * set in the acache explicitly. We can safely ignore the
1489 * case where the DB is already set. If other error happens,
1490 * the acache will not work effectively.
1492 result
= dns_acache_setdb(acache
, zone
->db
);
1493 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_EXISTS
) {
1494 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
1495 "dns_acache_setdb() failed: %s",
1496 isc_result_totext(result
));
1499 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
1504 dns_zone_setstring(dns_zone_t
*zone
, char **field
, const char *value
) {
1507 if (value
!= NULL
) {
1508 copy
= isc_mem_strdup(zone
->mctx
, value
);
1510 return (ISC_R_NOMEMORY
);
1516 isc_mem_free(zone
->mctx
, *field
);
1519 return (ISC_R_SUCCESS
);
1523 dns_zone_setfile(dns_zone_t
*zone
, const char *file
) {
1524 return (dns_zone_setfile2(zone
, file
, dns_masterformat_text
));
1528 dns_zone_setfile2(dns_zone_t
*zone
, const char *file
,
1529 dns_masterformat_t format
) {
1530 isc_result_t result
= ISC_R_SUCCESS
;
1532 REQUIRE(DNS_ZONE_VALID(zone
));
1535 result
= dns_zone_setstring(zone
, &zone
->masterfile
, file
);
1536 if (result
== ISC_R_SUCCESS
) {
1537 zone
->masterformat
= format
;
1538 result
= default_journal(zone
);
1546 dns_zone_getfile(dns_zone_t
*zone
) {
1547 REQUIRE(DNS_ZONE_VALID(zone
));
1549 return (zone
->masterfile
);
1553 dns_zone_getmaxttl(dns_zone_t
*zone
) {
1554 REQUIRE(DNS_ZONE_VALID(zone
));
1556 return (zone
->maxttl
);
1560 dns_zone_setmaxttl(dns_zone_t
*zone
, dns_ttl_t maxttl
) {
1561 REQUIRE(DNS_ZONE_VALID(zone
));
1565 zone
->options2
|= DNS_ZONEOPT2_CHECKTTL
;
1567 zone
->options2
&= ~DNS_ZONEOPT2_CHECKTTL
;
1568 zone
->maxttl
= maxttl
;
1575 default_journal(dns_zone_t
*zone
) {
1576 isc_result_t result
;
1579 REQUIRE(DNS_ZONE_VALID(zone
));
1580 REQUIRE(LOCKED_ZONE(zone
));
1582 if (zone
->masterfile
!= NULL
) {
1583 /* Calculate string length including '\0'. */
1584 int len
= strlen(zone
->masterfile
) + sizeof(".jnl");
1585 journal
= isc_mem_allocate(zone
->mctx
, len
);
1586 if (journal
== NULL
)
1587 return (ISC_R_NOMEMORY
);
1588 strcpy(journal
, zone
->masterfile
);
1589 strcat(journal
, ".jnl");
1593 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
1594 if (journal
!= NULL
)
1595 isc_mem_free(zone
->mctx
, journal
);
1600 dns_zone_setjournal(dns_zone_t
*zone
, const char *journal
) {
1601 isc_result_t result
= ISC_R_SUCCESS
;
1603 REQUIRE(DNS_ZONE_VALID(zone
));
1606 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
1613 dns_zone_getjournal(dns_zone_t
*zone
) {
1614 REQUIRE(DNS_ZONE_VALID(zone
));
1616 return (zone
->journal
);
1620 * Return true iff the zone is "dynamic", in the sense that the zone's
1621 * master file (if any) is written by the server, rather than being
1622 * updated manually and read by the server.
1624 * This is true for slave zones, stub zones, key zones, and zones that
1625 * allow dynamic updates either by having an update policy ("ssutable")
1626 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1629 dns_zone_isdynamic(dns_zone_t
*zone
, isc_boolean_t ignore_freeze
) {
1630 REQUIRE(DNS_ZONE_VALID(zone
));
1632 if (zone
->type
== dns_zone_slave
|| zone
->type
== dns_zone_stub
||
1633 zone
->type
== dns_zone_key
||
1634 (zone
->type
== dns_zone_redirect
&& zone
->masters
!= NULL
))
1637 /* If !ignore_freeze, we need check whether updates are disabled. */
1638 if (zone
->type
== dns_zone_master
&&
1639 (!zone
->update_disabled
|| ignore_freeze
) &&
1640 ((zone
->ssutable
!= NULL
) ||
1641 (zone
->update_acl
!= NULL
&& !dns_acl_isnone(zone
->update_acl
))))
1649 * Set the response policy index and information for a zone.
1652 dns_zone_rpz_enable(dns_zone_t
*zone
, dns_rpz_zones_t
*rpzs
,
1653 dns_rpz_num_t rpz_num
)
1656 * Only RBTDB zones can be used for response policy zones,
1657 * because only they have the code to load the create the summary data.
1658 * Only zones that are loaded instead of mmap()ed create the
1659 * summary data and so can be policy zones.
1661 if (strcmp(zone
->db_argv
[0], "rbt") != 0 &&
1662 strcmp(zone
->db_argv
[0], "rbt64") != 0)
1663 return (ISC_R_NOTIMPLEMENTED
);
1666 * This must happen only once or be redundant.
1669 if (zone
->rpzs
!= NULL
) {
1670 REQUIRE(zone
->rpzs
== rpzs
&& zone
->rpz_num
== rpz_num
);
1672 REQUIRE(zone
->rpz_num
== DNS_RPZ_INVALID_NUM
);
1673 dns_rpz_attach_rpzs(rpzs
, &zone
->rpzs
);
1674 zone
->rpz_num
= rpz_num
;
1676 rpzs
->defined
|= DNS_RPZ_ZBIT(rpz_num
);
1679 return (ISC_R_SUCCESS
);
1683 dns_zone_get_rpz_num(dns_zone_t
*zone
) {
1684 return (zone
->rpz_num
);
1688 * If a zone is a response policy zone, mark its new database.
1691 dns_zone_rpz_enable_db(dns_zone_t
*zone
, dns_db_t
*db
) {
1692 if (zone
->rpz_num
!= DNS_RPZ_INVALID_NUM
) {
1693 REQUIRE(zone
->rpzs
!= NULL
);
1694 dns_db_rpz_attach(db
, zone
->rpzs
, zone
->rpz_num
);
1698 static isc_boolean_t
1699 zone_touched(dns_zone_t
*zone
) {
1700 isc_result_t result
;
1702 dns_include_t
*include
;
1704 REQUIRE(DNS_ZONE_VALID(zone
));
1706 result
= isc_file_getmodtime(zone
->masterfile
, &modtime
);
1707 if (result
!= ISC_R_SUCCESS
||
1708 isc_time_compare(&modtime
, &zone
->loadtime
) > 0)
1710 zone
->loadtime
= modtime
;
1714 for (include
= ISC_LIST_HEAD(zone
->includes
);
1716 include
= ISC_LIST_NEXT(include
, link
))
1718 result
= isc_file_getmodtime(include
->name
, &modtime
);
1719 if (result
!= ISC_R_SUCCESS
||
1720 isc_time_compare(&modtime
, &include
->filetime
) > 0)
1729 zone_load(dns_zone_t
*zone
, unsigned int flags
, isc_boolean_t locked
) {
1730 isc_result_t result
;
1732 isc_time_t loadtime
;
1733 dns_db_t
*db
= NULL
;
1734 isc_boolean_t rbt
, hasraw
;
1736 REQUIRE(DNS_ZONE_VALID(zone
));
1741 INSIST(zone
!= zone
->raw
);
1742 hasraw
= inline_secure(zone
);
1744 result
= zone_load(zone
->raw
, flags
, ISC_FALSE
);
1745 if (result
!= ISC_R_SUCCESS
) {
1750 LOCK_ZONE(zone
->raw
);
1755 INSIST(zone
->type
!= dns_zone_none
);
1757 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
1758 if ((flags
& DNS_ZONELOADFLAG_THAW
) != 0)
1759 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_THAW
);
1760 result
= DNS_R_CONTINUE
;
1764 INSIST(zone
->db_argc
>= 1);
1766 rbt
= strcmp(zone
->db_argv
[0], "rbt") == 0 ||
1767 strcmp(zone
->db_argv
[0], "rbt64") == 0;
1769 if (zone
->db
!= NULL
&& zone
->masterfile
== NULL
&& rbt
) {
1771 * The zone has no master file configured.
1773 result
= ISC_R_SUCCESS
;
1777 if (zone
->db
!= NULL
&& dns_zone_isdynamic(zone
, ISC_FALSE
)) {
1779 * This is a slave, stub, or dynamically updated
1780 * zone being reloaded. Do nothing - the database
1781 * we already have is guaranteed to be up-to-date.
1783 if (zone
->type
== dns_zone_master
)
1784 result
= DNS_R_DYNAMIC
;
1786 result
= ISC_R_SUCCESS
;
1791 * Store the current time before the zone is loaded, so that if the
1792 * file changes between the time of the load and the time that
1793 * zone->loadtime is set, then the file will still be reloaded
1794 * the next time dns_zone_load is called.
1796 TIME_NOW(&loadtime
);
1799 * Don't do the load if the file that stores the zone is older
1800 * than the last time the zone was loaded. If the zone has not
1801 * been loaded yet, zone->loadtime will be the epoch.
1803 if (zone
->masterfile
!= NULL
) {
1805 * The file is already loaded. If we are just doing a
1806 * "rndc reconfig", we are done.
1808 if (!isc_time_isepoch(&zone
->loadtime
) &&
1809 (flags
& DNS_ZONELOADFLAG_NOSTAT
) != 0) {
1810 result
= ISC_R_SUCCESS
;
1814 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
1815 !zone_touched(zone
))
1817 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1818 "skipping load: master file "
1819 "older than last load");
1820 result
= DNS_R_UPTODATE
;
1826 * Built in zones (with the exception of empty zones) don't need
1829 if (zone
->type
== dns_zone_master
&&
1830 strcmp(zone
->db_argv
[0], "_builtin") == 0 &&
1831 (zone
->db_argc
< 2 || strcmp(zone
->db_argv
[1], "empty") != 0) &&
1832 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
1833 result
= ISC_R_SUCCESS
;
1838 * Zones associated with a DLZ don't need to be loaded either,
1839 * but we need to associate the database with the zone object.
1841 if (strcmp(zone
->db_argv
[0], "dlz") == 0) {
1843 dns_dlzfindzone_t findzone
;
1845 for (dlzdb
= ISC_LIST_HEAD(zone
->view
->dlz_unsearched
);
1847 dlzdb
= ISC_LIST_NEXT(dlzdb
, link
))
1849 INSIST(DNS_DLZ_VALID(dlzdb
));
1850 if (strcmp(zone
->db_argv
[1], dlzdb
->dlzname
) == 0)
1854 if (dlzdb
== NULL
) {
1855 dns_zone_log(zone
, ISC_LOG_ERROR
,
1856 "DLZ %s does not exist or is set "
1857 "to 'search yes;'", zone
->db_argv
[1]);
1858 result
= ISC_R_NOTFOUND
;
1862 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
1863 /* ask SDLZ driver if the zone is supported */
1864 findzone
= dlzdb
->implementation
->methods
->findzone
;
1865 result
= (*findzone
)(dlzdb
->implementation
->driverarg
,
1866 dlzdb
->dbdata
, dlzdb
->mctx
,
1867 zone
->view
->rdclass
, &zone
->origin
,
1869 if (result
!= ISC_R_NOTFOUND
) {
1870 if (zone
->db
!= NULL
)
1871 zone_detachdb(zone
);
1872 zone_attachdb(zone
, db
);
1874 result
= ISC_R_SUCCESS
;
1876 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
1878 if (result
== ISC_R_SUCCESS
) {
1879 if (dlzdb
->configure_callback
== NULL
)
1882 result
= (*dlzdb
->configure_callback
)(zone
->view
,
1884 if (result
!= ISC_R_SUCCESS
)
1885 dns_zone_log(zone
, ISC_LOG_ERROR
,
1886 "DLZ configuration callback: %s",
1887 isc_result_totext(result
));
1892 if ((zone
->type
== dns_zone_slave
|| zone
->type
== dns_zone_stub
||
1893 (zone
->type
== dns_zone_redirect
&& zone
->masters
!= NULL
)) &&
1895 if (zone
->masterfile
== NULL
||
1896 !isc_file_exists(zone
->masterfile
)) {
1897 if (zone
->masterfile
!= NULL
) {
1898 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1901 zone
->refreshtime
= now
;
1902 if (zone
->task
!= NULL
)
1903 zone_settimer(zone
, &now
);
1904 result
= ISC_R_SUCCESS
;
1909 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "starting load");
1911 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
1912 &zone
->origin
, (zone
->type
== dns_zone_stub
) ?
1913 dns_dbtype_stub
: dns_dbtype_zone
,
1915 zone
->db_argc
- 1, zone
->db_argv
+ 1,
1918 if (result
!= ISC_R_SUCCESS
) {
1919 dns_zone_log(zone
, ISC_LOG_ERROR
,
1920 "loading zone: creating database: %s",
1921 isc_result_totext(result
));
1924 dns_db_settask(db
, zone
->task
);
1926 if (! dns_db_ispersistent(db
)) {
1927 if (zone
->masterfile
!= NULL
) {
1928 result
= zone_startload(db
, zone
, loadtime
);
1930 result
= DNS_R_NOMASTERFILE
;
1931 if (zone
->type
== dns_zone_master
||
1932 (zone
->type
== dns_zone_redirect
&&
1933 zone
->masters
== NULL
)) {
1934 dns_zone_log(zone
, ISC_LOG_ERROR
,
1936 "no master file configured");
1939 dns_zone_log(zone
, ISC_LOG_INFO
, "loading zone: "
1940 "no master file configured: continuing");
1944 if (result
== DNS_R_CONTINUE
) {
1945 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADING
);
1946 if ((flags
& DNS_ZONELOADFLAG_THAW
) != 0)
1947 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_THAW
);
1951 result
= zone_postload(zone
, db
, loadtime
, result
);
1955 UNLOCK_ZONE(zone
->raw
);
1964 dns_zone_load(dns_zone_t
*zone
) {
1965 return (zone_load(zone
, 0, ISC_FALSE
));
1969 dns_zone_loadnew(dns_zone_t
*zone
) {
1970 return (zone_load(zone
, DNS_ZONELOADFLAG_NOSTAT
, ISC_FALSE
));
1974 zone_asyncload(isc_task_t
*task
, isc_event_t
*event
) {
1975 dns_asyncload_t
*asl
= event
->ev_arg
;
1976 dns_zone_t
*zone
= asl
->zone
;
1977 isc_result_t result
= ISC_R_SUCCESS
;
1978 isc_boolean_t load_pending
;
1982 REQUIRE(DNS_ZONE_VALID(zone
));
1984 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
1985 result
= ISC_R_CANCELED
;
1986 isc_event_free(&event
);
1988 if (result
== ISC_R_CANCELED
)
1991 /* Make sure load is still pending */
1993 load_pending
= ISC_TF(DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADPENDING
));
1995 if (!load_pending
) {
2000 zone_load(zone
, 0, ISC_TRUE
);
2002 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_LOADPENDING
);
2005 /* Inform the zone table we've finished loading */
2006 if (asl
->loaded
!= NULL
)
2007 (asl
->loaded
)(asl
->loaded_arg
, zone
, task
);
2010 isc_mem_put(zone
->mctx
, asl
, sizeof (*asl
));
2011 dns_zone_idetach(&zone
);
2015 dns_zone_asyncload(dns_zone_t
*zone
, dns_zt_zoneloaded_t done
, void *arg
) {
2017 dns_asyncload_t
*asl
= NULL
;
2018 isc_result_t result
= ISC_R_SUCCESS
;
2020 REQUIRE(DNS_ZONE_VALID(zone
));
2022 if (zone
->zmgr
== NULL
)
2023 return (ISC_R_FAILURE
);
2025 /* If we already have a load pending, stop now */
2026 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADPENDING
))
2027 return (ISC_R_ALREADYRUNNING
);
2029 asl
= isc_mem_get(zone
->mctx
, sizeof (*asl
));
2031 CHECK(ISC_R_NOMEMORY
);
2035 asl
->loaded_arg
= arg
;
2037 e
= isc_event_allocate(zone
->zmgr
->mctx
, zone
->zmgr
,
2039 zone_asyncload
, asl
,
2040 sizeof(isc_event_t
));
2042 CHECK(ISC_R_NOMEMORY
);
2045 zone_iattach(zone
, &asl
->zone
);
2046 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADPENDING
);
2047 isc_task_send(zone
->loadtask
, &e
);
2050 return (ISC_R_SUCCESS
);
2054 isc_mem_put(zone
->mctx
, asl
, sizeof (*asl
));
2059 dns__zone_loadpending(dns_zone_t
*zone
) {
2060 REQUIRE(DNS_ZONE_VALID(zone
));
2062 return (ISC_TF(DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADPENDING
)));
2066 dns_zone_loadandthaw(dns_zone_t
*zone
) {
2067 isc_result_t result
;
2069 if (inline_raw(zone
))
2070 result
= zone_load(zone
->secure
, DNS_ZONELOADFLAG_THAW
,
2073 result
= zone_load(zone
, DNS_ZONELOADFLAG_THAW
, ISC_FALSE
);
2076 case DNS_R_CONTINUE
:
2077 /* Deferred thaw. */
2079 case DNS_R_UPTODATE
:
2081 case DNS_R_SEENINCLUDE
:
2082 zone
->update_disabled
= ISC_FALSE
;
2084 case DNS_R_NOMASTERFILE
:
2085 zone
->update_disabled
= ISC_FALSE
;
2088 /* Error, remain in disabled state. */
2095 get_master_options(dns_zone_t
*zone
) {
2096 unsigned int options
;
2098 options
= DNS_MASTER_ZONE
| DNS_MASTER_RESIGN
;
2099 if (zone
->type
== dns_zone_slave
||
2100 (zone
->type
== dns_zone_redirect
&& zone
->masters
== NULL
))
2101 options
|= DNS_MASTER_SLAVE
;
2102 if (zone
->type
== dns_zone_key
)
2103 options
|= DNS_MASTER_KEY
;
2104 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNS
))
2105 options
|= DNS_MASTER_CHECKNS
;
2106 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_FATALNS
))
2107 options
|= DNS_MASTER_FATALNS
;
2108 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMES
))
2109 options
|= DNS_MASTER_CHECKNAMES
;
2110 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
))
2111 options
|= DNS_MASTER_CHECKNAMESFAIL
;
2112 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKMX
))
2113 options
|= DNS_MASTER_CHECKMX
;
2114 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKMXFAIL
))
2115 options
|= DNS_MASTER_CHECKMXFAIL
;
2116 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKWILDCARD
))
2117 options
|= DNS_MASTER_CHECKWILDCARD
;
2118 if (DNS_ZONE_OPTION2(zone
, DNS_ZONEOPT2_CHECKTTL
))
2119 options
|= DNS_MASTER_CHECKTTL
;
2124 zone_registerinclude(const char *filename
, void *arg
) {
2125 isc_result_t result
;
2126 dns_zone_t
*zone
= (dns_zone_t
*) arg
;
2127 dns_include_t
*inc
= NULL
;
2129 REQUIRE(DNS_ZONE_VALID(zone
));
2131 if (filename
== NULL
)
2135 * Suppress duplicates.
2137 for (inc
= ISC_LIST_HEAD(zone
->newincludes
);
2139 inc
= ISC_LIST_NEXT(inc
, link
))
2140 if (strcmp(filename
, inc
->name
) == 0)
2143 inc
= isc_mem_get(zone
->mctx
, sizeof(dns_include_t
));
2146 inc
->name
= isc_mem_strdup(zone
->mctx
, filename
);
2147 if (inc
->name
== NULL
) {
2148 isc_mem_put(zone
->mctx
, inc
, sizeof(dns_include_t
));
2151 ISC_LINK_INIT(inc
, link
);
2153 result
= isc_file_getmodtime(filename
, &inc
->filetime
);
2154 if (result
!= ISC_R_SUCCESS
)
2155 isc_time_settoepoch(&inc
->filetime
);
2157 ISC_LIST_APPEND(zone
->newincludes
, inc
, link
);
2161 zone_gotreadhandle(isc_task_t
*task
, isc_event_t
*event
) {
2162 dns_load_t
*load
= event
->ev_arg
;
2163 isc_result_t result
= ISC_R_SUCCESS
;
2164 unsigned int options
;
2166 REQUIRE(DNS_LOAD_VALID(load
));
2168 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
2169 result
= ISC_R_CANCELED
;
2170 isc_event_free(&event
);
2171 if (result
== ISC_R_CANCELED
)
2174 options
= get_master_options(load
->zone
);
2176 result
= dns_master_loadfileinc5(load
->zone
->masterfile
,
2177 dns_db_origin(load
->db
),
2178 dns_db_origin(load
->db
),
2179 load
->zone
->rdclass
, options
, 0,
2180 &load
->callbacks
, task
,
2181 zone_loaddone
, load
,
2183 zone_registerinclude
,
2184 load
->zone
, load
->zone
->mctx
,
2185 load
->zone
->masterformat
,
2186 load
->zone
->maxttl
);
2187 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_CONTINUE
&&
2188 result
!= DNS_R_SEENINCLUDE
)
2193 zone_loaddone(load
, result
);
2197 get_raw_serial(dns_zone_t
*raw
, dns_masterrawheader_t
*rawdata
) {
2198 isc_result_t result
;
2199 unsigned int soacount
;
2202 if (raw
->db
!= NULL
) {
2203 result
= zone_get_from_db(raw
, raw
->db
, NULL
, &soacount
,
2204 &rawdata
->sourceserial
,
2205 NULL
, NULL
, NULL
, NULL
,
2207 if (result
== ISC_R_SUCCESS
&& soacount
> 0U)
2208 rawdata
->flags
|= DNS_MASTERRAW_SOURCESERIALSET
;
2214 zone_gotwritehandle(isc_task_t
*task
, isc_event_t
*event
) {
2215 const char me
[] = "zone_gotwritehandle";
2216 dns_zone_t
*zone
= event
->ev_arg
;
2217 isc_result_t result
= ISC_R_SUCCESS
;
2218 dns_dbversion_t
*version
= NULL
;
2219 dns_masterrawheader_t rawdata
;
2221 REQUIRE(DNS_ZONE_VALID(zone
));
2222 INSIST(task
== zone
->task
);
2225 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
2226 result
= ISC_R_CANCELED
;
2227 isc_event_free(&event
);
2228 if (result
== ISC_R_CANCELED
)
2232 INSIST(zone
!= zone
->raw
);
2233 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
2234 if (zone
->db
!= NULL
) {
2235 const dns_master_style_t
*output_style
;
2237 dns_db_currentversion(zone
->db
, &version
);
2238 dns_master_initrawheader(&rawdata
);
2239 if (inline_secure(zone
))
2240 get_raw_serial(zone
->raw
, &rawdata
);
2241 if (zone
->type
== dns_zone_key
)
2242 output_style
= &dns_master_style_keyzone
;
2244 output_style
= &dns_master_style_default
;
2245 result
= dns_master_dumpinc3(zone
->mctx
, zone
->db
, version
,
2246 output_style
, zone
->masterfile
,
2247 zone
->task
, dump_done
, zone
, &zone
->dctx
, zone
->masterformat
,
2249 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
2251 result
= ISC_R_CANCELED
;
2252 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
2254 if (result
!= DNS_R_CONTINUE
)
2259 dump_done(zone
, result
);
2263 * Save the raw serial number for inline-signing zones.
2264 * (XXX: Other information from the header will be used
2265 * for other purposes in the future, but for now this is
2266 * all we're interested in.)
2269 zone_setrawdata(dns_zone_t
*zone
, dns_masterrawheader_t
*header
) {
2270 if ((header
->flags
& DNS_MASTERRAW_SOURCESERIALSET
) == 0)
2273 zone
->sourceserial
= header
->sourceserial
;
2274 zone
->sourceserialset
= ISC_TRUE
;
2278 dns_zone_setrawdata(dns_zone_t
*zone
, dns_masterrawheader_t
*header
) {
2283 zone_setrawdata(zone
, header
);
2288 zone_startload(dns_db_t
*db
, dns_zone_t
*zone
, isc_time_t loadtime
) {
2290 isc_result_t result
;
2291 isc_result_t tresult
;
2292 unsigned int options
;
2294 dns_zone_rpz_enable_db(zone
, db
);
2295 options
= get_master_options(zone
);
2296 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MANYERRORS
))
2297 options
|= DNS_MASTER_MANYERRORS
;
2299 if (zone
->zmgr
!= NULL
&& zone
->db
!= NULL
&& zone
->loadtask
!= NULL
) {
2300 load
= isc_mem_get(zone
->mctx
, sizeof(*load
));
2302 return (ISC_R_NOMEMORY
);
2307 load
->loadtime
= loadtime
;
2308 load
->magic
= LOAD_MAGIC
;
2310 isc_mem_attach(zone
->mctx
, &load
->mctx
);
2311 zone_iattach(zone
, &load
->zone
);
2312 dns_db_attach(db
, &load
->db
);
2313 dns_rdatacallbacks_init(&load
->callbacks
);
2314 load
->callbacks
.rawdata
= zone_setrawdata
;
2315 zone_iattach(zone
, &load
->callbacks
.zone
);
2316 result
= dns_db_beginload(db
, &load
->callbacks
);
2317 if (result
!= ISC_R_SUCCESS
)
2319 result
= zonemgr_getio(zone
->zmgr
, ISC_TRUE
, zone
->loadtask
,
2320 zone_gotreadhandle
, load
,
2322 if (result
!= ISC_R_SUCCESS
) {
2324 * We can't report multiple errors so ignore
2325 * the result of dns_db_endload().
2327 (void)dns_db_endload(load
->db
, &load
->callbacks
);
2330 result
= DNS_R_CONTINUE
;
2332 dns_rdatacallbacks_t callbacks
;
2334 dns_rdatacallbacks_init(&callbacks
);
2335 callbacks
.rawdata
= zone_setrawdata
;
2336 zone_iattach(zone
, &callbacks
.zone
);
2337 result
= dns_db_beginload(db
, &callbacks
);
2338 if (result
!= ISC_R_SUCCESS
) {
2339 zone_idetach(&callbacks
.zone
);
2342 result
= dns_master_loadfile5(zone
->masterfile
,
2343 &zone
->origin
, &zone
->origin
,
2344 zone
->rdclass
, options
, 0,
2346 zone_registerinclude
,
2350 tresult
= dns_db_endload(db
, &callbacks
);
2351 if (result
== ISC_R_SUCCESS
)
2353 zone_idetach(&callbacks
.zone
);
2360 dns_db_detach(&load
->db
);
2361 zone_idetach(&load
->zone
);
2362 zone_idetach(&load
->callbacks
.zone
);
2363 isc_mem_detach(&load
->mctx
);
2364 isc_mem_put(zone
->mctx
, load
, sizeof(*load
));
2368 static isc_boolean_t
2369 zone_check_mx(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
2372 isc_result_t result
;
2373 char ownerbuf
[DNS_NAME_FORMATSIZE
];
2374 char namebuf
[DNS_NAME_FORMATSIZE
];
2375 char altbuf
[DNS_NAME_FORMATSIZE
];
2376 dns_fixedname_t fixed
;
2377 dns_name_t
*foundname
;
2381 * "." means the services does not exist.
2383 if (dns_name_equal(name
, dns_rootname
))
2389 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
2390 if (zone
->checkmx
!= NULL
)
2391 return ((zone
->checkmx
)(zone
, name
, owner
));
2395 if (zone
->type
== dns_zone_master
)
2396 level
= ISC_LOG_ERROR
;
2398 level
= ISC_LOG_WARNING
;
2400 dns_fixedname_init(&fixed
);
2401 foundname
= dns_fixedname_name(&fixed
);
2403 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
2404 0, 0, NULL
, foundname
, NULL
, NULL
);
2405 if (result
== ISC_R_SUCCESS
)
2408 if (result
== DNS_R_NXRRSET
) {
2409 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
2410 0, 0, NULL
, foundname
, NULL
, NULL
);
2411 if (result
== ISC_R_SUCCESS
)
2415 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
2416 dns_name_format(name
, namebuf
, sizeof namebuf
);
2417 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
2418 result
== DNS_R_EMPTYNAME
) {
2419 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKMXFAIL
))
2420 level
= ISC_LOG_WARNING
;
2421 dns_zone_log(zone
, level
,
2422 "%s/MX '%s' has no address records (A or AAAA)",
2424 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
2427 if (result
== DNS_R_CNAME
) {
2428 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNMXCNAME
) ||
2429 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
2430 level
= ISC_LOG_WARNING
;
2431 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
2432 dns_zone_log(zone
, level
,
2433 "%s/MX '%s' is a CNAME (illegal)",
2435 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
2438 if (result
== DNS_R_DNAME
) {
2439 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNMXCNAME
) ||
2440 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
2441 level
= ISC_LOG_WARNING
;
2442 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
)) {
2443 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
2444 dns_zone_log(zone
, level
, "%s/MX '%s' is below a DNAME"
2445 " '%s' (illegal)", ownerbuf
, namebuf
,
2448 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
2451 if (zone
->checkmx
!= NULL
&& result
== DNS_R_DELEGATION
)
2452 return ((zone
->checkmx
)(zone
, name
, owner
));
2457 static isc_boolean_t
2458 zone_check_srv(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
2461 isc_result_t result
;
2462 char ownerbuf
[DNS_NAME_FORMATSIZE
];
2463 char namebuf
[DNS_NAME_FORMATSIZE
];
2464 char altbuf
[DNS_NAME_FORMATSIZE
];
2465 dns_fixedname_t fixed
;
2466 dns_name_t
*foundname
;
2470 * "." means the services does not exist.
2472 if (dns_name_equal(name
, dns_rootname
))
2478 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
2479 if (zone
->checksrv
!= NULL
)
2480 return ((zone
->checksrv
)(zone
, name
, owner
));
2484 if (zone
->type
== dns_zone_master
)
2485 level
= ISC_LOG_ERROR
;
2487 level
= ISC_LOG_WARNING
;
2489 dns_fixedname_init(&fixed
);
2490 foundname
= dns_fixedname_name(&fixed
);
2492 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
2493 0, 0, NULL
, foundname
, NULL
, NULL
);
2494 if (result
== ISC_R_SUCCESS
)
2497 if (result
== DNS_R_NXRRSET
) {
2498 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
2499 0, 0, NULL
, foundname
, NULL
, NULL
);
2500 if (result
== ISC_R_SUCCESS
)
2504 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
2505 dns_name_format(name
, namebuf
, sizeof namebuf
);
2506 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
2507 result
== DNS_R_EMPTYNAME
) {
2508 dns_zone_log(zone
, level
,
2509 "%s/SRV '%s' has no address records (A or AAAA)",
2511 /* XXX950 make fatal for 9.5.0. */
2515 if (result
== DNS_R_CNAME
) {
2516 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNSRVCNAME
) ||
2517 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
2518 level
= ISC_LOG_WARNING
;
2519 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
2520 dns_zone_log(zone
, level
,
2521 "%s/SRV '%s' is a CNAME (illegal)",
2523 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
2526 if (result
== DNS_R_DNAME
) {
2527 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNSRVCNAME
) ||
2528 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
2529 level
= ISC_LOG_WARNING
;
2530 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
)) {
2531 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
2532 dns_zone_log(zone
, level
, "%s/SRV '%s' is below a "
2533 "DNAME '%s' (illegal)", ownerbuf
, namebuf
,
2536 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
2539 if (zone
->checksrv
!= NULL
&& result
== DNS_R_DELEGATION
)
2540 return ((zone
->checksrv
)(zone
, name
, owner
));
2545 static isc_boolean_t
2546 zone_check_glue(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
2549 isc_boolean_t answer
= ISC_TRUE
;
2550 isc_result_t result
, tresult
;
2551 char ownerbuf
[DNS_NAME_FORMATSIZE
];
2552 char namebuf
[DNS_NAME_FORMATSIZE
];
2553 char altbuf
[DNS_NAME_FORMATSIZE
];
2554 dns_fixedname_t fixed
;
2555 dns_name_t
*foundname
;
2557 dns_rdataset_t aaaa
;
2563 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
2564 if (zone
->checkns
!= NULL
)
2565 return ((zone
->checkns
)(zone
, name
, owner
, NULL
, NULL
));
2569 if (zone
->type
== dns_zone_master
)
2570 level
= ISC_LOG_ERROR
;
2572 level
= ISC_LOG_WARNING
;
2574 dns_fixedname_init(&fixed
);
2575 foundname
= dns_fixedname_name(&fixed
);
2576 dns_rdataset_init(&a
);
2577 dns_rdataset_init(&aaaa
);
2579 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
2580 DNS_DBFIND_GLUEOK
, 0, NULL
,
2581 foundname
, &a
, NULL
);
2583 if (result
== ISC_R_SUCCESS
) {
2584 dns_rdataset_disassociate(&a
);
2586 } else if (result
== DNS_R_DELEGATION
)
2587 dns_rdataset_disassociate(&a
);
2589 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_DELEGATION
||
2590 result
== DNS_R_GLUE
) {
2591 tresult
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
2592 DNS_DBFIND_GLUEOK
, 0, NULL
,
2593 foundname
, &aaaa
, NULL
);
2594 if (tresult
== ISC_R_SUCCESS
) {
2595 if (dns_rdataset_isassociated(&a
))
2596 dns_rdataset_disassociate(&a
);
2597 dns_rdataset_disassociate(&aaaa
);
2600 if (tresult
== DNS_R_DELEGATION
)
2601 dns_rdataset_disassociate(&aaaa
);
2602 if (result
== DNS_R_GLUE
|| tresult
== DNS_R_GLUE
) {
2604 * Check glue against child zone.
2606 if (zone
->checkns
!= NULL
)
2607 answer
= (zone
->checkns
)(zone
, name
, owner
,
2609 if (dns_rdataset_isassociated(&a
))
2610 dns_rdataset_disassociate(&a
);
2611 if (dns_rdataset_isassociated(&aaaa
))
2612 dns_rdataset_disassociate(&aaaa
);
2617 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
2618 dns_name_format(name
, namebuf
, sizeof namebuf
);
2619 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
2620 result
== DNS_R_EMPTYNAME
|| result
== DNS_R_DELEGATION
) {
2622 isc_boolean_t required
= ISC_FALSE
;
2623 if (dns_name_issubdomain(name
, owner
)) {
2624 what
= "REQUIRED GLUE ";
2625 required
= ISC_TRUE
;
2626 } else if (result
== DNS_R_DELEGATION
)
2627 what
= "SIBLING GLUE ";
2631 if (result
!= DNS_R_DELEGATION
|| required
||
2632 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKSIBLING
)) {
2633 dns_zone_log(zone
, level
, "%s/NS '%s' has no %s"
2634 "address records (A or AAAA)",
2635 ownerbuf
, namebuf
, what
);
2637 * Log missing address record.
2639 if (result
== DNS_R_DELEGATION
&& zone
->checkns
!= NULL
)
2640 (void)(zone
->checkns
)(zone
, name
, owner
,
2642 /* XXX950 make fatal for 9.5.0. */
2643 /* answer = ISC_FALSE; */
2645 } else if (result
== DNS_R_CNAME
) {
2646 dns_zone_log(zone
, level
, "%s/NS '%s' is a CNAME (illegal)",
2648 /* XXX950 make fatal for 9.5.0. */
2649 /* answer = ISC_FALSE; */
2650 } else if (result
== DNS_R_DNAME
) {
2651 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
2652 dns_zone_log(zone
, level
,
2653 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2654 ownerbuf
, namebuf
, altbuf
);
2655 /* XXX950 make fatal for 9.5.0. */
2656 /* answer = ISC_FALSE; */
2659 if (dns_rdataset_isassociated(&a
))
2660 dns_rdataset_disassociate(&a
);
2661 if (dns_rdataset_isassociated(&aaaa
))
2662 dns_rdataset_disassociate(&aaaa
);
2666 static isc_boolean_t
2667 zone_rrset_check_dup(dns_zone_t
*zone
, dns_name_t
*owner
,
2668 dns_rdataset_t
*rdataset
)
2670 dns_rdataset_t tmprdataset
;
2671 isc_result_t result
;
2672 isc_boolean_t answer
= ISC_TRUE
;
2673 isc_boolean_t format
= ISC_TRUE
;
2674 int level
= ISC_LOG_WARNING
;
2675 char ownerbuf
[DNS_NAME_FORMATSIZE
];
2676 char typebuf
[DNS_RDATATYPE_FORMATSIZE
];
2677 unsigned int count1
= 0;
2679 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKDUPRRFAIL
))
2680 level
= ISC_LOG_ERROR
;
2682 dns_rdataset_init(&tmprdataset
);
2683 for (result
= dns_rdataset_first(rdataset
);
2684 result
== ISC_R_SUCCESS
;
2685 result
= dns_rdataset_next(rdataset
)) {
2686 dns_rdata_t rdata1
= DNS_RDATA_INIT
;
2687 unsigned int count2
= 0;
2690 dns_rdataset_current(rdataset
, &rdata1
);
2691 dns_rdataset_clone(rdataset
, &tmprdataset
);
2692 for (result
= dns_rdataset_first(&tmprdataset
);
2693 result
== ISC_R_SUCCESS
;
2694 result
= dns_rdataset_next(&tmprdataset
)) {
2695 dns_rdata_t rdata2
= DNS_RDATA_INIT
;
2697 if (count1
>= count2
)
2699 dns_rdataset_current(&tmprdataset
, &rdata2
);
2700 if (dns_rdata_casecompare(&rdata1
, &rdata2
) == 0) {
2702 dns_name_format(owner
, ownerbuf
,
2704 dns_rdatatype_format(rdata1
.type
,
2709 dns_zone_log(zone
, level
, "%s/%s has "
2710 "semantically identical records",
2712 if (level
== ISC_LOG_ERROR
)
2717 dns_rdataset_disassociate(&tmprdataset
);
2724 static isc_boolean_t
2725 zone_check_dup(dns_zone_t
*zone
, dns_db_t
*db
) {
2726 dns_dbiterator_t
*dbiterator
= NULL
;
2727 dns_dbnode_t
*node
= NULL
;
2728 dns_fixedname_t fixed
;
2730 dns_rdataset_t rdataset
;
2731 dns_rdatasetiter_t
*rdsit
= NULL
;
2732 isc_boolean_t ok
= ISC_TRUE
;
2733 isc_result_t result
;
2735 dns_fixedname_init(&fixed
);
2736 name
= dns_fixedname_name(&fixed
);
2737 dns_rdataset_init(&rdataset
);
2739 result
= dns_db_createiterator(db
, 0, &dbiterator
);
2740 if (result
!= ISC_R_SUCCESS
)
2743 for (result
= dns_dbiterator_first(dbiterator
);
2744 result
== ISC_R_SUCCESS
;
2745 result
= dns_dbiterator_next(dbiterator
)) {
2746 result
= dns_dbiterator_current(dbiterator
, &node
, name
);
2747 if (result
!= ISC_R_SUCCESS
)
2750 result
= dns_db_allrdatasets(db
, node
, NULL
, 0, &rdsit
);
2751 if (result
!= ISC_R_SUCCESS
)
2754 for (result
= dns_rdatasetiter_first(rdsit
);
2755 result
== ISC_R_SUCCESS
;
2756 result
= dns_rdatasetiter_next(rdsit
)) {
2757 dns_rdatasetiter_current(rdsit
, &rdataset
);
2758 if (!zone_rrset_check_dup(zone
, name
, &rdataset
))
2760 dns_rdataset_disassociate(&rdataset
);
2762 dns_rdatasetiter_destroy(&rdsit
);
2763 dns_db_detachnode(db
, &node
);
2767 dns_db_detachnode(db
, &node
);
2768 dns_dbiterator_destroy(&dbiterator
);
2773 static isc_boolean_t
2774 isspf(const dns_rdata_t
*rdata
) {
2776 const unsigned char *data
= rdata
->data
;
2777 unsigned int rdl
= rdata
->length
, i
= 0, tl
, len
;
2784 if (len
> sizeof(buf
) - i
- 1)
2785 len
= sizeof(buf
) - i
- 1;
2786 memmove(buf
+ i
, data
, len
);
2796 if (strncmp(buf
, "v=spf1", 6) == 0 && (buf
[6] == 0 || buf
[6] == ' '))
2801 static isc_boolean_t
2802 integrity_checks(dns_zone_t
*zone
, dns_db_t
*db
) {
2803 dns_dbiterator_t
*dbiterator
= NULL
;
2804 dns_dbnode_t
*node
= NULL
;
2805 dns_rdataset_t rdataset
;
2806 dns_fixedname_t fixed
;
2807 dns_fixedname_t fixedbottom
;
2810 dns_rdata_in_srv_t srv
;
2814 isc_result_t result
;
2815 isc_boolean_t ok
= ISC_TRUE
, have_spf
, have_txt
;
2817 dns_fixedname_init(&fixed
);
2818 name
= dns_fixedname_name(&fixed
);
2819 dns_fixedname_init(&fixedbottom
);
2820 bottom
= dns_fixedname_name(&fixedbottom
);
2821 dns_rdataset_init(&rdataset
);
2822 dns_rdata_init(&rdata
);
2824 result
= dns_db_createiterator(db
, 0, &dbiterator
);
2825 if (result
!= ISC_R_SUCCESS
)
2828 result
= dns_dbiterator_first(dbiterator
);
2829 while (result
== ISC_R_SUCCESS
) {
2830 result
= dns_dbiterator_current(dbiterator
, &node
, name
);
2831 if (result
!= ISC_R_SUCCESS
)
2835 * Is this name visible in the zone?
2837 if (!dns_name_issubdomain(name
, &zone
->origin
) ||
2838 (dns_name_countlabels(bottom
) > 0 &&
2839 dns_name_issubdomain(name
, bottom
)))
2843 * Don't check the NS records at the origin.
2845 if (dns_name_equal(name
, &zone
->origin
))
2848 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_ns
,
2849 0, 0, &rdataset
, NULL
);
2850 if (result
!= ISC_R_SUCCESS
)
2853 * Remember bottom of zone.
2855 dns_name_copy(name
, bottom
, NULL
);
2857 result
= dns_rdataset_first(&rdataset
);
2858 while (result
== ISC_R_SUCCESS
) {
2859 dns_rdataset_current(&rdataset
, &rdata
);
2860 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
2861 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2862 if (!zone_check_glue(zone
, db
, &ns
.name
, name
))
2864 dns_rdata_reset(&rdata
);
2865 result
= dns_rdataset_next(&rdataset
);
2867 dns_rdataset_disassociate(&rdataset
);
2871 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_mx
,
2872 0, 0, &rdataset
, NULL
);
2873 if (result
!= ISC_R_SUCCESS
)
2875 result
= dns_rdataset_first(&rdataset
);
2876 while (result
== ISC_R_SUCCESS
) {
2877 dns_rdataset_current(&rdataset
, &rdata
);
2878 result
= dns_rdata_tostruct(&rdata
, &mx
, NULL
);
2879 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2880 if (!zone_check_mx(zone
, db
, &mx
.mx
, name
))
2882 dns_rdata_reset(&rdata
);
2883 result
= dns_rdataset_next(&rdataset
);
2885 dns_rdataset_disassociate(&rdataset
);
2888 if (zone
->rdclass
!= dns_rdataclass_in
)
2890 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_srv
,
2891 0, 0, &rdataset
, NULL
);
2892 if (result
!= ISC_R_SUCCESS
)
2894 result
= dns_rdataset_first(&rdataset
);
2895 while (result
== ISC_R_SUCCESS
) {
2896 dns_rdataset_current(&rdataset
, &rdata
);
2897 result
= dns_rdata_tostruct(&rdata
, &srv
, NULL
);
2898 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2899 if (!zone_check_srv(zone
, db
, &srv
.target
, name
))
2901 dns_rdata_reset(&rdata
);
2902 result
= dns_rdataset_next(&rdataset
);
2904 dns_rdataset_disassociate(&rdataset
);
2908 * Check if there is a type SPF record without an
2909 * SPF-formatted type TXT record also being present.
2911 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKSPF
))
2913 if (zone
->rdclass
!= dns_rdataclass_in
)
2915 have_spf
= have_txt
= ISC_FALSE
;
2916 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_spf
,
2917 0, 0, &rdataset
, NULL
);
2918 if (result
== ISC_R_SUCCESS
) {
2919 dns_rdataset_disassociate(&rdataset
);
2920 have_spf
= ISC_TRUE
;
2922 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_txt
,
2923 0, 0, &rdataset
, NULL
);
2924 if (result
!= ISC_R_SUCCESS
)
2926 result
= dns_rdataset_first(&rdataset
);
2927 while (result
== ISC_R_SUCCESS
) {
2928 dns_rdataset_current(&rdataset
, &rdata
);
2929 have_txt
= isspf(&rdata
);
2930 dns_rdata_reset(&rdata
);
2933 result
= dns_rdataset_next(&rdataset
);
2935 dns_rdataset_disassociate(&rdataset
);
2938 if (have_spf
&& !have_txt
) {
2939 char namebuf
[DNS_NAME_FORMATSIZE
];
2941 dns_name_format(name
, namebuf
, sizeof(namebuf
));
2942 dns_zone_log(zone
, ISC_LOG_WARNING
, "'%s' found type "
2943 "SPF record but no SPF TXT record found, "
2944 "add matching type TXT record", namebuf
);
2948 dns_db_detachnode(db
, &node
);
2949 result
= dns_dbiterator_next(dbiterator
);
2954 dns_db_detachnode(db
, &node
);
2955 dns_dbiterator_destroy(&dbiterator
);
2961 * OpenSSL verification of RSA keys with exponent 3 is known to be
2962 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2963 * if they are in use.
2966 zone_check_dnskeys(dns_zone_t
*zone
, dns_db_t
*db
) {
2967 dns_dbnode_t
*node
= NULL
;
2968 dns_dbversion_t
*version
= NULL
;
2969 dns_rdata_dnskey_t dnskey
;
2970 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2971 dns_rdataset_t rdataset
;
2972 isc_result_t result
;
2973 isc_boolean_t logit
, foundrsa
= ISC_FALSE
, foundmd5
= ISC_FALSE
;
2974 const char *algorithm
;
2976 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
2977 if (result
!= ISC_R_SUCCESS
)
2980 dns_db_currentversion(db
, &version
);
2981 dns_rdataset_init(&rdataset
);
2982 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_dnskey
,
2983 dns_rdatatype_none
, 0, &rdataset
, NULL
);
2984 if (result
!= ISC_R_SUCCESS
)
2987 for (result
= dns_rdataset_first(&rdataset
);
2988 result
== ISC_R_SUCCESS
;
2989 result
= dns_rdataset_next(&rdataset
))
2991 dns_rdataset_current(&rdataset
, &rdata
);
2992 result
= dns_rdata_tostruct(&rdata
, &dnskey
, NULL
);
2993 INSIST(result
== ISC_R_SUCCESS
);
2995 if ((dnskey
.algorithm
== DST_ALG_RSASHA1
||
2996 dnskey
.algorithm
== DST_ALG_RSAMD5
) &&
2997 dnskey
.datalen
> 1 && dnskey
.data
[0] == 1 &&
2998 dnskey
.data
[1] == 3)
3000 if (dnskey
.algorithm
== DST_ALG_RSASHA1
) {
3002 foundrsa
= ISC_TRUE
;
3003 algorithm
= "RSASHA1";
3006 foundmd5
= ISC_TRUE
;
3007 algorithm
= "RSAMD5";
3010 dns_zone_log(zone
, ISC_LOG_WARNING
,
3011 "weak %s (%u) key found "
3012 "(exponent=3)", algorithm
,
3014 if (foundrsa
&& foundmd5
)
3017 dns_rdata_reset(&rdata
);
3019 dns_rdataset_disassociate(&rdataset
);
3023 dns_db_detachnode(db
, &node
);
3024 if (version
!= NULL
)
3025 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3029 resume_signingwithkey(dns_zone_t
*zone
) {
3030 dns_dbnode_t
*node
= NULL
;
3031 dns_dbversion_t
*version
= NULL
;
3032 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3033 dns_rdataset_t rdataset
;
3034 isc_result_t result
;
3035 dns_db_t
*db
= NULL
;
3037 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
3038 if (zone
->db
!= NULL
)
3039 dns_db_attach(zone
->db
, &db
);
3040 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
3044 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
3045 if (result
!= ISC_R_SUCCESS
)
3048 dns_db_currentversion(db
, &version
);
3049 dns_rdataset_init(&rdataset
);
3050 result
= dns_db_findrdataset(db
, node
, version
,
3052 dns_rdatatype_none
, 0,
3054 if (result
!= ISC_R_SUCCESS
) {
3055 INSIST(!dns_rdataset_isassociated(&rdataset
));
3059 for (result
= dns_rdataset_first(&rdataset
);
3060 result
== ISC_R_SUCCESS
;
3061 result
= dns_rdataset_next(&rdataset
))
3063 dns_rdataset_current(&rdataset
, &rdata
);
3064 if (rdata
.length
!= 5 ||
3065 rdata
.data
[0] == 0 || rdata
.data
[4] != 0) {
3066 dns_rdata_reset(&rdata
);
3070 result
= zone_signwithkey(zone
, rdata
.data
[0],
3071 (rdata
.data
[1] << 8) | rdata
.data
[2],
3072 ISC_TF(rdata
.data
[3]));
3073 if (result
!= ISC_R_SUCCESS
) {
3074 dns_zone_log(zone
, ISC_LOG_ERROR
,
3075 "zone_signwithkey failed: %s",
3076 dns_result_totext(result
));
3078 dns_rdata_reset(&rdata
);
3080 dns_rdataset_disassociate(&rdataset
);
3085 dns_db_detachnode(db
, &node
);
3086 if (version
!= NULL
)
3087 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3093 zone_addnsec3chain(dns_zone_t
*zone
, dns_rdata_nsec3param_t
*nsec3param
) {
3094 dns_nsec3chain_t
*nsec3chain
, *current
;
3095 dns_dbversion_t
*version
= NULL
;
3096 isc_boolean_t nseconly
= ISC_FALSE
, nsec3ok
= ISC_FALSE
;
3097 isc_result_t result
;
3099 unsigned int options
= 0;
3100 char saltbuf
[255*2+1];
3101 char flags
[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
3102 dns_db_t
*db
= NULL
;
3105 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
3106 if (zone
->db
!= NULL
)
3107 dns_db_attach(zone
->db
, &db
);
3108 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
3111 result
= ISC_R_SUCCESS
;
3115 dns_db_currentversion(db
, &version
);
3116 result
= dns_nsec_nseconly(db
, version
, &nseconly
);
3117 nsec3ok
= (result
== ISC_R_SUCCESS
&& !nseconly
);
3118 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3119 if (!nsec3ok
&& (nsec3param
->flags
& DNS_NSEC3FLAG_REMOVE
) == 0) {
3120 result
= ISC_R_SUCCESS
;
3124 nsec3chain
= isc_mem_get(zone
->mctx
, sizeof *nsec3chain
);
3125 if (nsec3chain
== NULL
) {
3126 result
= ISC_R_NOMEMORY
;
3130 nsec3chain
->magic
= 0;
3131 nsec3chain
->done
= ISC_FALSE
;
3132 nsec3chain
->db
= NULL
;
3133 nsec3chain
->dbiterator
= NULL
;
3134 nsec3chain
->nsec3param
.common
.rdclass
= nsec3param
->common
.rdclass
;
3135 nsec3chain
->nsec3param
.common
.rdtype
= nsec3param
->common
.rdtype
;
3136 nsec3chain
->nsec3param
.hash
= nsec3param
->hash
;
3137 nsec3chain
->nsec3param
.iterations
= nsec3param
->iterations
;
3138 nsec3chain
->nsec3param
.flags
= nsec3param
->flags
;
3139 nsec3chain
->nsec3param
.salt_length
= nsec3param
->salt_length
;
3140 memmove(nsec3chain
->salt
, nsec3param
->salt
, nsec3param
->salt_length
);
3141 nsec3chain
->nsec3param
.salt
= nsec3chain
->salt
;
3142 nsec3chain
->seen_nsec
= ISC_FALSE
;
3143 nsec3chain
->delete_nsec
= ISC_FALSE
;
3144 nsec3chain
->save_delete_nsec
= ISC_FALSE
;
3146 if (nsec3param
->flags
== 0)
3147 strlcpy(flags
, "NONE", sizeof(flags
));
3150 if (nsec3param
->flags
& DNS_NSEC3FLAG_REMOVE
)
3151 strlcat(flags
, "REMOVE", sizeof(flags
));
3152 if (nsec3param
->flags
& DNS_NSEC3FLAG_INITIAL
) {
3153 if (flags
[0] == '\0')
3154 strlcpy(flags
, "INITIAL", sizeof(flags
));
3156 strlcat(flags
, "|INITIAL", sizeof(flags
));
3158 if (nsec3param
->flags
& DNS_NSEC3FLAG_CREATE
) {
3159 if (flags
[0] == '\0')
3160 strlcpy(flags
, "CREATE", sizeof(flags
));
3162 strlcat(flags
, "|CREATE", sizeof(flags
));
3164 if (nsec3param
->flags
& DNS_NSEC3FLAG_NONSEC
) {
3165 if (flags
[0] == '\0')
3166 strlcpy(flags
, "NONSEC", sizeof(flags
));
3168 strlcat(flags
, "|NONSEC", sizeof(flags
));
3170 if (nsec3param
->flags
& DNS_NSEC3FLAG_OPTOUT
) {
3171 if (flags
[0] == '\0')
3172 strlcpy(flags
, "OPTOUT", sizeof(flags
));
3174 strlcat(flags
, "|OPTOUT", sizeof(flags
));
3177 if (nsec3param
->salt_length
== 0)
3178 strlcpy(saltbuf
, "-", sizeof(saltbuf
));
3180 for (i
= 0; i
< nsec3param
->salt_length
; i
++)
3181 sprintf(&saltbuf
[i
*2], "%02X", nsec3chain
->salt
[i
]);
3182 dns_zone_log(zone
, ISC_LOG_INFO
,
3183 "zone_addnsec3chain(%u,%s,%u,%s)",
3184 nsec3param
->hash
, flags
, nsec3param
->iterations
,
3187 for (current
= ISC_LIST_HEAD(zone
->nsec3chain
);
3189 current
= ISC_LIST_NEXT(current
, link
)) {
3190 if (current
->db
== db
&&
3191 current
->nsec3param
.hash
== nsec3param
->hash
&&
3192 current
->nsec3param
.iterations
== nsec3param
->iterations
&&
3193 current
->nsec3param
.salt_length
== nsec3param
->salt_length
3194 && !memcmp(current
->nsec3param
.salt
, nsec3param
->salt
,
3195 nsec3param
->salt_length
))
3196 current
->done
= ISC_TRUE
;
3199 dns_db_attach(db
, &nsec3chain
->db
);
3200 if ((nsec3chain
->nsec3param
.flags
& DNS_NSEC3FLAG_CREATE
) != 0)
3201 options
= DNS_DB_NONSEC3
;
3202 result
= dns_db_createiterator(nsec3chain
->db
, options
,
3203 &nsec3chain
->dbiterator
);
3204 if (result
== ISC_R_SUCCESS
)
3205 dns_dbiterator_first(nsec3chain
->dbiterator
);
3206 if (result
== ISC_R_SUCCESS
) {
3207 dns_dbiterator_pause(nsec3chain
->dbiterator
);
3208 ISC_LIST_INITANDAPPEND(zone
->nsec3chain
,
3211 if (isc_time_isepoch(&zone
->nsec3chaintime
)) {
3213 zone
->nsec3chaintime
= now
;
3214 if (zone
->task
!= NULL
)
3215 zone_settimer(zone
, &now
);
3219 if (nsec3chain
!= NULL
) {
3220 if (nsec3chain
->db
!= NULL
)
3221 dns_db_detach(&nsec3chain
->db
);
3222 if (nsec3chain
->dbiterator
!= NULL
)
3223 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
3224 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
3234 resume_addnsec3chain(dns_zone_t
*zone
) {
3235 dns_dbnode_t
*node
= NULL
;
3236 dns_dbversion_t
*version
= NULL
;
3237 dns_rdataset_t rdataset
;
3238 isc_result_t result
;
3239 dns_rdata_nsec3param_t nsec3param
;
3240 isc_boolean_t nseconly
= ISC_FALSE
, nsec3ok
= ISC_FALSE
;
3241 dns_db_t
*db
= NULL
;
3243 if (zone
->privatetype
== 0)
3246 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
3247 if (zone
->db
!= NULL
)
3248 dns_db_attach(zone
->db
, &db
);
3249 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
3253 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
3254 if (result
!= ISC_R_SUCCESS
)
3257 dns_db_currentversion(db
, &version
);
3259 result
= dns_nsec_nseconly(db
, version
, &nseconly
);
3260 nsec3ok
= (result
== ISC_R_SUCCESS
&& !nseconly
);
3262 dns_rdataset_init(&rdataset
);
3263 result
= dns_db_findrdataset(db
, node
, version
,
3264 zone
->privatetype
, dns_rdatatype_none
,
3265 0, &rdataset
, NULL
);
3266 if (result
!= ISC_R_SUCCESS
) {
3267 INSIST(!dns_rdataset_isassociated(&rdataset
));
3271 for (result
= dns_rdataset_first(&rdataset
);
3272 result
== ISC_R_SUCCESS
;
3273 result
= dns_rdataset_next(&rdataset
))
3275 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
3276 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3277 dns_rdata_t
private = DNS_RDATA_INIT
;
3279 dns_rdataset_current(&rdataset
, &private);
3280 if (!dns_nsec3param_fromprivate(&private, &rdata
, buf
,
3283 result
= dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
);
3284 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3285 if (((nsec3param
.flags
& DNS_NSEC3FLAG_REMOVE
) != 0) ||
3286 ((nsec3param
.flags
& DNS_NSEC3FLAG_CREATE
) != 0 && nsec3ok
))
3288 result
= zone_addnsec3chain(zone
, &nsec3param
);
3289 if (result
!= ISC_R_SUCCESS
) {
3290 dns_zone_log(zone
, ISC_LOG_ERROR
,
3291 "zone_addnsec3chain failed: %s",
3292 dns_result_totext(result
));
3296 dns_rdataset_disassociate(&rdataset
);
3300 dns_db_detachnode(db
, &node
);
3301 if (version
!= NULL
)
3302 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3308 set_resigntime(dns_zone_t
*zone
) {
3309 dns_rdataset_t rdataset
;
3310 dns_fixedname_t fixed
;
3311 unsigned int resign
;
3312 isc_result_t result
;
3313 isc_uint32_t nanosecs
;
3314 dns_db_t
*db
= NULL
;
3316 /* We only re-sign zones that can be dynamically updated */
3317 if (zone
->update_disabled
)
3320 if (!inline_secure(zone
) && (zone
->type
!= dns_zone_master
||
3321 (zone
->ssutable
== NULL
&&
3322 (zone
->update_acl
== NULL
|| dns_acl_isnone(zone
->update_acl
)))))
3325 dns_rdataset_init(&rdataset
);
3326 dns_fixedname_init(&fixed
);
3328 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
3329 if (zone
->db
!= NULL
)
3330 dns_db_attach(zone
->db
, &db
);
3331 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
3333 isc_time_settoepoch(&zone
->resigntime
);
3337 result
= dns_db_getsigningtime(db
, &rdataset
,
3338 dns_fixedname_name(&fixed
));
3339 if (result
!= ISC_R_SUCCESS
) {
3340 isc_time_settoepoch(&zone
->resigntime
);
3344 resign
= rdataset
.resign
- zone
->sigresigninginterval
;
3345 dns_rdataset_disassociate(&rdataset
);
3346 isc_random_get(&nanosecs
);
3347 nanosecs
%= 1000000000;
3348 isc_time_set(&zone
->resigntime
, resign
, nanosecs
);
3355 check_nsec3param(dns_zone_t
*zone
, dns_db_t
*db
) {
3356 dns_dbnode_t
*node
= NULL
;
3357 dns_rdataset_t rdataset
;
3358 dns_dbversion_t
*version
= NULL
;
3359 dns_rdata_nsec3param_t nsec3param
;
3360 isc_boolean_t ok
= ISC_FALSE
;
3361 isc_result_t result
;
3362 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3363 isc_boolean_t dynamic
= (zone
->type
== dns_zone_master
) ?
3364 dns_zone_isdynamic(zone
, ISC_FALSE
) : ISC_FALSE
;
3366 dns_rdataset_init(&rdataset
);
3367 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
3368 if (result
!= ISC_R_SUCCESS
) {
3369 dns_zone_log(zone
, ISC_LOG_ERROR
,
3370 "nsec3param lookup failure: %s",
3371 dns_result_totext(result
));
3374 dns_db_currentversion(db
, &version
);
3376 result
= dns_db_findrdataset(db
, node
, version
,
3377 dns_rdatatype_nsec3param
,
3378 dns_rdatatype_none
, 0, &rdataset
, NULL
);
3379 if (result
== ISC_R_NOTFOUND
) {
3380 INSIST(!dns_rdataset_isassociated(&rdataset
));
3381 result
= ISC_R_SUCCESS
;
3384 if (result
!= ISC_R_SUCCESS
) {
3385 INSIST(!dns_rdataset_isassociated(&rdataset
));
3386 dns_zone_log(zone
, ISC_LOG_ERROR
,
3387 "nsec3param lookup failure: %s",
3388 dns_result_totext(result
));
3393 * For dynamic zones we must support every algorithm so we can
3394 * regenerate all the NSEC3 chains.
3395 * For non-dynamic zones we only need to find a supported algorithm.
3397 for (result
= dns_rdataset_first(&rdataset
);
3398 result
== ISC_R_SUCCESS
;
3399 result
= dns_rdataset_next(&rdataset
))
3401 dns_rdataset_current(&rdataset
, &rdata
);
3402 result
= dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
);
3403 dns_rdata_reset(&rdata
);
3404 INSIST(result
== ISC_R_SUCCESS
);
3405 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NSEC3TESTZONE
) &&
3406 nsec3param
.hash
== DNS_NSEC3_UNKNOWNALG
&& !dynamic
)
3408 dns_zone_log(zone
, ISC_LOG_WARNING
,
3409 "nsec3 test \"unknown\" hash algorithm found: %u",
3412 } else if (!dns_nsec3_supportedhash(nsec3param
.hash
)) {
3414 dns_zone_log(zone
, ISC_LOG_ERROR
,
3415 "unsupported nsec3 hash algorithm"
3416 " in dynamic zone: %u",
3418 result
= DNS_R_BADZONE
;
3419 /* Stop second error message. */
3423 dns_zone_log(zone
, ISC_LOG_WARNING
,
3424 "unsupported nsec3 hash algorithm: %u",
3429 if (result
== ISC_R_NOMORE
)
3430 result
= ISC_R_SUCCESS
;
3433 result
= DNS_R_BADZONE
;
3434 dns_zone_log(zone
, ISC_LOG_ERROR
,
3435 "no supported nsec3 hash algorithm");
3439 if (dns_rdataset_isassociated(&rdataset
))
3440 dns_rdataset_disassociate(&rdataset
);
3441 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3442 dns_db_detachnode(db
, &node
);
3447 * Set the timer for refreshing the key zone to the soonest future time
3448 * of the set (current timer, keydata->refresh, keydata->addhd,
3449 * keydata->removehd).
3452 set_refreshkeytimer(dns_zone_t
*zone
, dns_rdata_keydata_t
*key
,
3453 isc_stdtime_t now
, isc_boolean_t force
)
3455 const char me
[] = "set_refreshkeytimer";
3457 isc_time_t timenow
, timethen
;
3461 then
= key
->refresh
;
3464 if (key
->addhd
> now
&& key
->addhd
< then
)
3466 if (key
->removehd
> now
&& key
->removehd
< then
)
3467 then
= key
->removehd
;
3471 DNS_ZONE_TIME_ADD(&timenow
, then
- now
, &timethen
);
3474 if (isc_time_compare(&zone
->refreshkeytime
, &timenow
) < 0 ||
3475 isc_time_compare(&timethen
, &zone
->refreshkeytime
) < 0)
3476 zone
->refreshkeytime
= timethen
;
3478 isc_time_formattimestamp(&zone
->refreshkeytime
, timebuf
, 80);
3479 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf
);
3480 zone_settimer(zone
, &timenow
);
3484 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
3485 * If the key zone is changed, set '*changed' to ISC_TRUE.
3488 create_keydata(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
3489 dns_diff_t
*diff
, dns_keytable_t
*keytable
,
3490 dns_keynode_t
**keynodep
, isc_boolean_t
*changed
)
3492 const char me
[] = "create_keydata";
3493 isc_result_t result
= ISC_R_SUCCESS
;
3494 isc_buffer_t keyb
, dstb
;
3495 unsigned char key_buf
[4096], dst_buf
[DST_KEY_MAXSIZE
];
3496 dns_rdata_keydata_t keydata
;
3497 dns_rdata_dnskey_t dnskey
;
3498 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3499 dns_keynode_t
*keynode
;
3504 REQUIRE(keynodep
!= NULL
);
3505 keynode
= *keynodep
;
3508 isc_stdtime_get(&now
);
3510 /* Loop in case there's more than one key. */
3511 while (result
== ISC_R_SUCCESS
) {
3512 dns_keynode_t
*nextnode
= NULL
;
3514 key
= dns_keynode_key(keynode
);
3518 isc_buffer_init(&dstb
, dst_buf
, sizeof(dst_buf
));
3519 CHECK(dst_key_todns(key
, &dstb
));
3521 /* Convert DST key to DNSKEY. */
3522 dns_rdata_reset(&rdata
);
3523 isc_buffer_usedregion(&dstb
, &r
);
3524 dns_rdata_fromregion(&rdata
, dst_key_class(key
),
3525 dns_rdatatype_dnskey
, &r
);
3527 /* DSTKEY to KEYDATA. */
3528 CHECK(dns_rdata_tostruct(&rdata
, &dnskey
, NULL
));
3529 CHECK(dns_keydata_fromdnskey(&keydata
, &dnskey
, now
, 0, 0,
3532 /* KEYDATA to rdata. */
3533 dns_rdata_reset(&rdata
);
3534 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
3535 CHECK(dns_rdata_fromstruct(&rdata
,
3536 zone
->rdclass
, dns_rdatatype_keydata
,
3539 /* Add rdata to zone. */
3540 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_ADD
,
3541 dst_key_name(key
), 0, &rdata
));
3542 *changed
= ISC_TRUE
;
3544 /* Refresh new keys from the zone apex as soon as possible. */
3545 set_refreshkeytimer(zone
, &keydata
, now
, ISC_TRUE
);
3548 result
= dns_keytable_nextkeynode(keytable
, keynode
, &nextnode
);
3549 if (result
!= ISC_R_NOTFOUND
) {
3550 dns_keytable_detachkeynode(keytable
, &keynode
);
3555 if (keynode
!= NULL
)
3556 dns_keytable_detachkeynode(keytable
, &keynode
);
3559 return (ISC_R_SUCCESS
);
3566 * Remove from the key zone all the KEYDATA records found in rdataset.
3569 delete_keydata(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_diff_t
*diff
,
3570 dns_name_t
*name
, dns_rdataset_t
*rdataset
)
3572 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3573 isc_result_t result
, uresult
;
3575 for (result
= dns_rdataset_first(rdataset
);
3576 result
== ISC_R_SUCCESS
;
3577 result
= dns_rdataset_next(rdataset
)) {
3578 dns_rdata_reset(&rdata
);
3579 dns_rdataset_current(rdataset
, &rdata
);
3580 uresult
= update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
,
3582 if (uresult
!= ISC_R_SUCCESS
)
3585 if (result
== ISC_R_NOMORE
)
3586 result
= ISC_R_SUCCESS
;
3591 * Compute the DNSSEC key ID for a DNSKEY record.
3594 compute_tag(dns_name_t
*name
, dns_rdata_dnskey_t
*dnskey
, isc_mem_t
*mctx
,
3597 isc_result_t result
;
3598 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3599 unsigned char data
[4096];
3600 isc_buffer_t buffer
;
3601 dst_key_t
*dstkey
= NULL
;
3603 isc_buffer_init(&buffer
, data
, sizeof(data
));
3604 dns_rdata_fromstruct(&rdata
, dnskey
->common
.rdclass
,
3605 dns_rdatatype_dnskey
, dnskey
, &buffer
);
3607 result
= dns_dnssec_keyfromrdata(name
, &rdata
, mctx
, &dstkey
);
3608 if (result
== ISC_R_SUCCESS
)
3609 *tag
= dst_key_id(dstkey
);
3610 dst_key_free(&dstkey
);
3616 * Add key to the security roots.
3619 trust_key(dns_zone_t
*zone
, dns_name_t
*keyname
,
3620 dns_rdata_dnskey_t
*dnskey
, isc_mem_t
*mctx
) {
3621 isc_result_t result
;
3622 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3623 unsigned char data
[4096];
3624 isc_buffer_t buffer
;
3625 dns_keytable_t
*sr
= NULL
;
3626 dst_key_t
*dstkey
= NULL
;
3628 /* Convert dnskey to DST key. */
3629 isc_buffer_init(&buffer
, data
, sizeof(data
));
3630 dns_rdata_fromstruct(&rdata
, dnskey
->common
.rdclass
,
3631 dns_rdatatype_dnskey
, dnskey
, &buffer
);
3633 result
= dns_view_getsecroots(zone
->view
, &sr
);
3634 if (result
!= ISC_R_SUCCESS
)
3637 CHECK(dns_dnssec_keyfromrdata(keyname
, &rdata
, mctx
, &dstkey
));
3638 CHECK(dns_keytable_add(sr
, ISC_TRUE
, &dstkey
));
3639 dns_keytable_detach(&sr
);
3643 dst_key_free(&dstkey
);
3645 dns_keytable_detach(&sr
);
3650 * Add a null key to the security roots for so that all queries
3651 * to the zone will fail.
3654 fail_secure(dns_zone_t
*zone
, dns_name_t
*keyname
) {
3655 isc_result_t result
;
3656 dns_keytable_t
*sr
= NULL
;
3658 result
= dns_view_getsecroots(zone
->view
, &sr
);
3659 if (result
== ISC_R_SUCCESS
) {
3660 dns_keytable_marksecure(sr
, keyname
);
3661 dns_keytable_detach(&sr
);
3666 * Scan a set of KEYDATA records from the key zone. The ones that are
3667 * valid (i.e., the add holddown timer has expired) become trusted keys.
3670 load_secroots(dns_zone_t
*zone
, dns_name_t
*name
, dns_rdataset_t
*rdataset
) {
3671 isc_result_t result
;
3672 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3673 dns_rdata_keydata_t keydata
;
3674 dns_rdata_dnskey_t dnskey
;
3675 isc_mem_t
*mctx
= zone
->mctx
;
3676 int trusted
= 0, revoked
= 0, pending
= 0;
3678 dns_keytable_t
*sr
= NULL
;
3680 isc_stdtime_get(&now
);
3682 result
= dns_view_getsecroots(zone
->view
, &sr
);
3683 if (result
== ISC_R_SUCCESS
) {
3684 dns_keytable_delete(sr
, name
);
3685 dns_keytable_detach(&sr
);
3688 /* Now insert all the accepted trust anchors from this keydata set. */
3689 for (result
= dns_rdataset_first(rdataset
);
3690 result
== ISC_R_SUCCESS
;
3691 result
= dns_rdataset_next(rdataset
)) {
3692 dns_rdata_reset(&rdata
);
3693 dns_rdataset_current(rdataset
, &rdata
);
3695 /* Convert rdata to keydata. */
3696 result
= dns_rdata_tostruct(&rdata
, &keydata
, NULL
);
3697 if (result
== ISC_R_UNEXPECTEDEND
)
3699 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3701 /* Set the key refresh timer to force a fast refresh. */
3702 set_refreshkeytimer(zone
, &keydata
, now
, ISC_TRUE
);
3704 /* If the removal timer is nonzero, this key was revoked. */
3705 if (keydata
.removehd
!= 0) {
3711 * If the add timer is still pending, this key is not
3714 if (now
< keydata
.addhd
) {
3719 /* Convert keydata to dnskey. */
3720 dns_keydata_todnskey(&keydata
, &dnskey
, NULL
);
3722 /* Add to keytables. */
3724 trust_key(zone
, name
, &dnskey
, mctx
);
3727 if (trusted
== 0 && pending
!= 0) {
3728 char namebuf
[DNS_NAME_FORMATSIZE
];
3729 dns_name_format(name
, namebuf
, sizeof namebuf
);
3730 dns_zone_log(zone
, ISC_LOG_ERROR
,
3731 "No valid trust anchors for '%s'!", namebuf
);
3732 dns_zone_log(zone
, ISC_LOG_ERROR
,
3733 "%d key(s) revoked, %d still pending",
3735 dns_zone_log(zone
, ISC_LOG_ERROR
,
3736 "All queries to '%s' will fail", namebuf
);
3737 fail_secure(zone
, name
);
3742 do_one_tuple(dns_difftuple_t
**tuple
, dns_db_t
*db
, dns_dbversion_t
*ver
,
3745 dns_diff_t temp_diff
;
3746 isc_result_t result
;
3749 * Create a singleton diff.
3751 dns_diff_init(diff
->mctx
, &temp_diff
);
3752 ISC_LIST_APPEND(temp_diff
.tuples
, *tuple
, link
);
3755 * Apply it to the database.
3757 result
= dns_diff_apply(&temp_diff
, db
, ver
);
3758 ISC_LIST_UNLINK(temp_diff
.tuples
, *tuple
, link
);
3759 if (result
!= ISC_R_SUCCESS
) {
3760 dns_difftuple_free(tuple
);
3765 * Merge it into the current pending journal entry.
3767 dns_diff_appendminimal(diff
, tuple
);
3770 * Do not clear temp_diff.
3772 return (ISC_R_SUCCESS
);
3776 update_one_rr(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_diff_t
*diff
,
3777 dns_diffop_t op
, dns_name_t
*name
, dns_ttl_t ttl
,
3780 dns_difftuple_t
*tuple
= NULL
;
3781 isc_result_t result
;
3782 result
= dns_difftuple_create(diff
->mctx
, op
,
3783 name
, ttl
, rdata
, &tuple
);
3784 if (result
!= ISC_R_SUCCESS
)
3786 return (do_one_tuple(&tuple
, db
, ver
, diff
));
3790 update_soa_serial(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_diff_t
*diff
,
3791 isc_mem_t
*mctx
, dns_updatemethod_t method
) {
3792 dns_difftuple_t
*deltuple
= NULL
;
3793 dns_difftuple_t
*addtuple
= NULL
;
3794 isc_uint32_t serial
;
3795 isc_result_t result
;
3797 CHECK(dns_db_createsoatuple(db
, ver
, mctx
, DNS_DIFFOP_DEL
, &deltuple
));
3798 CHECK(dns_difftuple_copy(deltuple
, &addtuple
));
3799 addtuple
->op
= DNS_DIFFOP_ADD
;
3801 serial
= dns_soa_getserial(&addtuple
->rdata
);
3802 serial
= dns_update_soaserial(serial
, method
);
3803 dns_soa_setserial(serial
, &addtuple
->rdata
);
3804 CHECK(do_one_tuple(&deltuple
, db
, ver
, diff
));
3805 CHECK(do_one_tuple(&addtuple
, db
, ver
, diff
));
3806 result
= ISC_R_SUCCESS
;
3809 if (addtuple
!= NULL
)
3810 dns_difftuple_free(&addtuple
);
3811 if (deltuple
!= NULL
)
3812 dns_difftuple_free(&deltuple
);
3817 * Write all transactions in 'diff' to the zone journal file.
3820 zone_journal(dns_zone_t
*zone
, dns_diff_t
*diff
, isc_uint32_t
*sourceserial
,
3823 const char me
[] = "zone_journal";
3824 const char *journalfile
;
3825 isc_result_t result
= ISC_R_SUCCESS
;
3826 dns_journal_t
*journal
= NULL
;
3827 unsigned int mode
= DNS_JOURNAL_CREATE
|DNS_JOURNAL_WRITE
;
3830 journalfile
= dns_zone_getjournal(zone
);
3831 if (journalfile
!= NULL
) {
3832 result
= dns_journal_open(zone
->mctx
, journalfile
, mode
,
3834 if (result
!= ISC_R_SUCCESS
) {
3835 dns_zone_log(zone
, ISC_LOG_ERROR
,
3836 "%s:dns_journal_open -> %s",
3837 caller
, dns_result_totext(result
));
3841 if (sourceserial
!= NULL
)
3842 dns_journal_set_sourceserial(journal
, *sourceserial
);
3844 result
= dns_journal_write_transaction(journal
, diff
);
3845 if (result
!= ISC_R_SUCCESS
) {
3846 dns_zone_log(zone
, ISC_LOG_ERROR
,
3847 "%s:dns_journal_write_transaction -> %s",
3848 caller
, dns_result_totext(result
));
3850 dns_journal_destroy(&journal
);
3857 * Create an SOA record for a newly-created zone
3860 add_soa(dns_zone_t
*zone
, dns_db_t
*db
) {
3861 isc_result_t result
;
3862 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3863 unsigned char buf
[DNS_SOA_BUFFERSIZE
];
3864 dns_dbversion_t
*ver
= NULL
;
3867 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "creating SOA");
3869 dns_diff_init(zone
->mctx
, &diff
);
3870 result
= dns_db_newversion(db
, &ver
);
3871 if (result
!= ISC_R_SUCCESS
) {
3872 dns_zone_log(zone
, ISC_LOG_ERROR
,
3873 "add_soa:dns_db_newversion -> %s",
3874 dns_result_totext(result
));
3878 /* Build SOA record */
3879 result
= dns_soa_buildrdata(&zone
->origin
, dns_rootname
, zone
->rdclass
,
3880 0, 0, 0, 0, 0, buf
, &rdata
);
3881 if (result
!= ISC_R_SUCCESS
) {
3882 dns_zone_log(zone
, ISC_LOG_ERROR
,
3883 "add_soa:dns_soa_buildrdata -> %s",
3884 dns_result_totext(result
));
3888 result
= update_one_rr(db
, ver
, &diff
, DNS_DIFFOP_ADD
,
3889 &zone
->origin
, 0, &rdata
);
3892 dns_diff_clear(&diff
);
3894 dns_db_closeversion(db
, &ver
, ISC_TF(result
== ISC_R_SUCCESS
));
3896 INSIST(ver
== NULL
);
3902 * Synchronize the set of initializing keys found in managed-keys {}
3903 * statements with the set of trust anchors found in the managed-keys.bind
3904 * zone. If a domain is no longer named in managed-keys, delete all keys
3905 * from that domain from the key zone. If a domain is mentioned in in
3906 * managed-keys but there are no references to it in the key zone, load
3907 * the key zone with the initializing key(s) for that domain.
3910 sync_keyzone(dns_zone_t
*zone
, dns_db_t
*db
) {
3911 isc_result_t result
= ISC_R_SUCCESS
;
3912 isc_boolean_t changed
= ISC_FALSE
;
3913 isc_boolean_t commit
= ISC_FALSE
;
3914 dns_rbtnodechain_t chain
;
3916 dns_name_t foundname
, *origin
;
3917 dns_keynode_t
*keynode
= NULL
;
3918 dns_view_t
*view
= zone
->view
;
3919 dns_keytable_t
*sr
= NULL
;
3920 dns_dbversion_t
*ver
= NULL
;
3922 dns_rriterator_t rrit
;
3924 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3926 dns_name_init(&foundname
, NULL
);
3927 dns_fixedname_init(&fn
);
3928 origin
= dns_fixedname_name(&fn
);
3930 dns_diff_init(zone
->mctx
, &diff
);
3932 CHECK(dns_view_getsecroots(view
, &sr
));
3934 result
= dns_db_newversion(db
, &ver
);
3935 if (result
!= ISC_R_SUCCESS
) {
3936 dns_zone_log(zone
, ISC_LOG_ERROR
,
3937 "sync_keyzone:dns_db_newversion -> %s",
3938 dns_result_totext(result
));
3943 * Walk the zone DB. If we find any keys whose names are no longer
3944 * in managed-keys (or *are* in trusted-keys, meaning they are
3945 * permanent and not RFC5011-maintained), delete them from the
3946 * zone. Otherwise call load_secroots(), which loads keys into
3947 * secroots as appropriate.
3949 dns_rriterator_init(&rrit
, db
, ver
, 0);
3950 for (result
= dns_rriterator_first(&rrit
);
3951 result
== ISC_R_SUCCESS
;
3952 result
= dns_rriterator_nextrrset(&rrit
)) {
3953 dns_rdataset_t
*rdataset
= NULL
;
3954 dns_name_t
*rrname
= NULL
;
3957 dns_rriterator_current(&rrit
, &rrname
, &ttl
,
3959 if (!dns_rdataset_isassociated(rdataset
)) {
3960 dns_rriterator_destroy(&rrit
);
3964 if (rdataset
->type
!= dns_rdatatype_keydata
)
3967 result
= dns_keytable_find(sr
, rrname
, &keynode
);
3968 if ((result
!= ISC_R_SUCCESS
&&
3969 result
!= DNS_R_PARTIALMATCH
) ||
3970 dns_keynode_managed(keynode
) == ISC_FALSE
)
3972 CHECK(delete_keydata(db
, ver
, &diff
,
3976 load_secroots(zone
, rrname
, rdataset
);
3979 if (keynode
!= NULL
)
3980 dns_keytable_detachkeynode(sr
, &keynode
);
3982 dns_rriterator_destroy(&rrit
);
3985 * Now walk secroots to find any managed keys that aren't
3986 * in the zone. If we find any, we add them to the zone.
3988 RWLOCK(&sr
->rwlock
, isc_rwlocktype_write
);
3989 dns_rbtnodechain_init(&chain
, zone
->mctx
);
3990 result
= dns_rbtnodechain_first(&chain
, sr
->table
, &foundname
, origin
);
3991 if (result
== ISC_R_NOTFOUND
)
3992 result
= ISC_R_NOMORE
;
3993 while (result
== DNS_R_NEWORIGIN
|| result
== ISC_R_SUCCESS
) {
3994 dns_rbtnode_t
*rbtnode
= NULL
;
3996 dns_rbtnodechain_current(&chain
, &foundname
, origin
, &rbtnode
);
3997 if (rbtnode
->data
== NULL
)
4000 dns_keytable_attachkeynode(sr
, rbtnode
->data
, &keynode
);
4001 if (dns_keynode_managed(keynode
)) {
4002 dns_fixedname_t fname
;
4003 dns_name_t
*keyname
;
4006 key
= dns_keynode_key(keynode
);
4007 dns_fixedname_init(&fname
);
4009 if (key
== NULL
) /* fail_secure() was called. */
4012 keyname
= dst_key_name(key
);
4013 result
= dns_db_find(db
, keyname
, ver
,
4014 dns_rdatatype_keydata
,
4015 DNS_DBFIND_NOWILD
, 0, NULL
,
4016 dns_fixedname_name(&fname
),
4018 if (result
!= ISC_R_SUCCESS
)
4019 result
= create_keydata(zone
, db
, ver
, &diff
,
4020 sr
, &keynode
, &changed
);
4021 if (result
!= ISC_R_SUCCESS
)
4025 result
= dns_rbtnodechain_next(&chain
, &foundname
, origin
);
4026 if (keynode
!= NULL
)
4027 dns_keytable_detachkeynode(sr
, &keynode
);
4029 RWUNLOCK(&sr
->rwlock
, isc_rwlocktype_write
);
4031 if (result
== ISC_R_NOMORE
)
4032 result
= ISC_R_SUCCESS
;
4035 /* Write changes to journal file. */
4036 CHECK(update_soa_serial(db
, ver
, &diff
, zone
->mctx
,
4037 zone
->updatemethod
));
4038 CHECK(zone_journal(zone
, &diff
, NULL
, "sync_keyzone"));
4040 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
);
4041 zone_needdump(zone
, 30);
4046 if (result
!= ISC_R_SUCCESS
&&
4047 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
4048 dns_zone_log(zone
, ISC_LOG_ERROR
,
4049 "unable to synchronize managed keys: %s",
4050 dns_result_totext(result
));
4051 isc_time_settoepoch(&zone
->refreshkeytime
);
4053 if (keynode
!= NULL
)
4054 dns_keytable_detachkeynode(sr
, &keynode
);
4056 dns_keytable_detach(&sr
);
4058 dns_db_closeversion(db
, &ver
, commit
);
4059 dns_diff_clear(&diff
);
4061 INSIST(ver
== NULL
);
4067 dns_zone_synckeyzone(dns_zone_t
*zone
) {
4068 isc_result_t result
;
4069 dns_db_t
*db
= NULL
;
4071 if (zone
->type
!= dns_zone_key
)
4072 return (DNS_R_BADZONE
);
4074 CHECK(dns_zone_getdb(zone
, &db
));
4077 result
= sync_keyzone(zone
, db
);
4087 maybe_send_secure(dns_zone_t
*zone
) {
4088 isc_result_t result
;
4091 * We've finished loading, or else failed to load, an inline-signing
4092 * 'secure' zone. We now need information about the status of the
4093 * 'raw' zone. If we failed to load, then we need it to send a
4094 * copy of its database; if we succeeded, we need it to send its
4095 * serial number so that we can sync with it. If it has not yet
4096 * loaded, we set a flag so that it will send the necessary
4097 * information when it has finished loading.
4099 if (zone
->raw
->db
!= NULL
) {
4100 if (zone
->db
!= NULL
) {
4101 isc_uint32_t serial
;
4102 unsigned int soacount
;
4104 result
= zone_get_from_db(zone
->raw
, zone
->raw
->db
,
4105 NULL
, &soacount
, &serial
, NULL
,
4106 NULL
, NULL
, NULL
, NULL
);
4107 if (result
== ISC_R_SUCCESS
&& soacount
> 0U)
4108 zone_send_secureserial(zone
->raw
, serial
);
4110 zone_send_securedb(zone
->raw
, zone
->raw
->db
);
4113 DNS_ZONE_SETFLAG(zone
->raw
, DNS_ZONEFLG_SENDSECURE
);
4116 static isc_boolean_t
4117 zone_unchanged(dns_db_t
*db1
, dns_db_t
*db2
, isc_mem_t
*mctx
) {
4118 isc_result_t result
;
4119 isc_boolean_t answer
= ISC_FALSE
;
4122 dns_diff_init(mctx
, &diff
);
4123 result
= dns_db_diffx(&diff
, db1
, NULL
, db2
, NULL
, NULL
);
4124 if (result
== ISC_R_SUCCESS
&& ISC_LIST_EMPTY(diff
.tuples
))
4126 dns_diff_clear(&diff
);
4131 * The zone is presumed to be locked.
4132 * If this is a inline_raw zone the secure version is also locked.
4135 zone_postload(dns_zone_t
*zone
, dns_db_t
*db
, isc_time_t loadtime
,
4136 isc_result_t result
)
4138 unsigned int soacount
= 0;
4139 unsigned int nscount
= 0;
4140 unsigned int errors
= 0;
4141 isc_uint32_t serial
, oldserial
, refresh
, retry
, expire
, minimum
;
4143 isc_boolean_t needdump
= ISC_FALSE
;
4144 isc_boolean_t hasinclude
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
4145 isc_boolean_t nomaster
= ISC_FALSE
;
4146 unsigned int options
;
4149 INSIST(LOCKED_ZONE(zone
));
4150 if (inline_raw(zone
))
4151 INSIST(LOCKED_ZONE(zone
->secure
));
4156 * Initiate zone transfer? We may need a error code that
4157 * indicates that the "permanent" form does not exist.
4158 * XXX better error feedback to log.
4160 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_SEENINCLUDE
) {
4161 if (zone
->type
== dns_zone_slave
||
4162 zone
->type
== dns_zone_stub
||
4163 (zone
->type
== dns_zone_redirect
&&
4164 zone
->masters
== NULL
)) {
4165 if (result
== ISC_R_FILENOTFOUND
)
4166 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4168 else if (result
!= DNS_R_NOMASTERFILE
)
4169 dns_zone_log(zone
, ISC_LOG_ERROR
,
4170 "loading from master file %s "
4173 dns_result_totext(result
));
4174 } else if (zone
->type
== dns_zone_master
&&
4175 inline_secure(zone
) && result
== ISC_R_FILENOTFOUND
)
4177 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4178 "no master file, requesting db");
4179 maybe_send_secure(zone
);
4181 int level
= ISC_LOG_ERROR
;
4182 if (zone
->type
== dns_zone_key
&&
4183 result
== ISC_R_FILENOTFOUND
)
4184 level
= ISC_LOG_DEBUG(1);
4185 dns_zone_log(zone
, level
,
4186 "loading from master file %s failed: %s",
4188 dns_result_totext(result
));
4189 nomaster
= ISC_TRUE
;
4192 if (zone
->type
!= dns_zone_key
)
4196 dns_zone_log(zone
, ISC_LOG_DEBUG(2),
4197 "number of nodes in database: %u",
4198 dns_db_nodecount(db
));
4200 if (result
== DNS_R_SEENINCLUDE
)
4201 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
4203 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
4206 * If there's no master file for a key zone, then the zone is new:
4207 * create an SOA record. (We do this now, instead of later, so that
4208 * if there happens to be a journal file, we can roll forward from
4209 * a sane starting point.)
4211 if (nomaster
&& zone
->type
== dns_zone_key
) {
4212 result
= add_soa(zone
, db
);
4213 if (result
!= ISC_R_SUCCESS
)
4218 * Apply update log, if any, on initial load.
4220 if (zone
->journal
!= NULL
&&
4221 ! DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOMERGE
) &&
4222 ! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
4224 if (zone
->type
== dns_zone_master
&&
4225 (zone
->update_acl
!= NULL
|| zone
->ssutable
!= NULL
))
4226 options
= DNS_JOURNALOPT_RESIGN
;
4229 result
= dns_journal_rollforward(zone
->mctx
, db
, options
,
4231 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
&&
4232 result
!= DNS_R_UPTODATE
&& result
!= DNS_R_NOJOURNAL
&&
4233 result
!= ISC_R_RANGE
) {
4234 dns_zone_log(zone
, ISC_LOG_ERROR
,
4235 "journal rollforward failed: %s",
4236 dns_result_totext(result
));
4241 if (result
== ISC_R_NOTFOUND
|| result
== ISC_R_RANGE
) {
4242 dns_zone_log(zone
, ISC_LOG_ERROR
,
4243 "journal rollforward failed: "
4244 "journal out of sync with zone");
4247 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4248 "journal rollforward completed "
4250 dns_result_totext(result
));
4251 if (result
== ISC_R_SUCCESS
)
4252 needdump
= ISC_TRUE
;
4256 * Obtain ns, soa and cname counts for top of zone.
4259 result
= zone_get_from_db(zone
, db
, &nscount
, &soacount
, &serial
,
4260 &refresh
, &retry
, &expire
, &minimum
,
4262 if (result
!= ISC_R_SUCCESS
&& zone
->type
!= dns_zone_key
) {
4263 dns_zone_log(zone
, ISC_LOG_ERROR
,
4264 "could not find NS and/or SOA records");
4268 * Check to make sure the journal is up to date, and remove the
4269 * journal file if it isn't, as we wouldn't be able to apply
4270 * updates otherwise.
4272 if (zone
->journal
!= NULL
&& dns_zone_isdynamic(zone
, ISC_TRUE
) &&
4273 ! DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
)) {
4274 isc_uint32_t jserial
;
4275 dns_journal_t
*journal
= NULL
;
4277 result
= dns_journal_open(zone
->mctx
, zone
->journal
,
4278 DNS_JOURNAL_READ
, &journal
);
4279 if (result
== ISC_R_SUCCESS
) {
4280 jserial
= dns_journal_last_serial(journal
);
4281 dns_journal_destroy(&journal
);
4284 result
= ISC_R_SUCCESS
;
4287 if (jserial
!= serial
) {
4288 dns_zone_log(zone
, ISC_LOG_INFO
,
4289 "journal file is out of date: "
4290 "removing journal file");
4291 if (remove(zone
->journal
) < 0 && errno
!= ENOENT
) {
4292 char strbuf
[ISC_STRERRORSIZE
];
4293 isc__strerror(errno
, strbuf
, sizeof(strbuf
));
4294 isc_log_write(dns_lctx
,
4295 DNS_LOGCATEGORY_GENERAL
,
4298 "unable to remove journal "
4300 zone
->journal
, strbuf
);
4305 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "loaded; checking validity");
4308 * Master / Slave / Stub zones require both NS and SOA records at
4309 * the top of the zone.
4312 switch (zone
->type
) {
4314 case dns_zone_master
:
4315 case dns_zone_slave
:
4317 case dns_zone_redirect
:
4318 if (soacount
!= 1) {
4319 dns_zone_log(zone
, ISC_LOG_ERROR
,
4320 "has %d SOA records", soacount
);
4321 result
= DNS_R_BADZONE
;
4324 dns_zone_log(zone
, ISC_LOG_ERROR
,
4325 "has no NS records");
4326 result
= DNS_R_BADZONE
;
4328 if (result
!= ISC_R_SUCCESS
)
4330 if (zone
->type
== dns_zone_master
&& errors
!= 0) {
4331 result
= DNS_R_BADZONE
;
4334 if (zone
->type
!= dns_zone_stub
&&
4335 zone
->type
!= dns_zone_redirect
) {
4336 result
= check_nsec3param(zone
, db
);
4337 if (result
!= ISC_R_SUCCESS
)
4340 if (zone
->type
== dns_zone_master
&&
4341 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKINTEGRITY
) &&
4342 !integrity_checks(zone
, db
)) {
4343 result
= DNS_R_BADZONE
;
4346 if (zone
->type
== dns_zone_master
&&
4347 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKDUPRR
) &&
4348 !zone_check_dup(zone
, db
)) {
4349 result
= DNS_R_BADZONE
;
4353 if (zone
->db
!= NULL
) {
4354 unsigned int oldsoacount
;
4357 * This is checked in zone_replacedb() for slave zones
4358 * as they don't reload from disk.
4360 result
= zone_get_from_db(zone
, zone
->db
, NULL
,
4361 &oldsoacount
, &oldserial
,
4362 NULL
, NULL
, NULL
, NULL
,
4364 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4365 RUNTIME_CHECK(soacount
> 0U);
4366 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
) &&
4367 !isc_serial_gt(serial
, oldserial
)) {
4368 isc_uint32_t serialmin
, serialmax
;
4370 INSIST(zone
->type
== dns_zone_master
);
4372 if (serial
== oldserial
&&
4373 zone_unchanged(zone
->db
, db
, zone
->mctx
)) {
4374 dns_zone_log(zone
, ISC_LOG_INFO
,
4375 "ixfr-from-differences: "
4377 return(ISC_R_SUCCESS
);
4380 serialmin
= (oldserial
+ 1) & 0xffffffffU
;
4381 serialmax
= (oldserial
+ 0x7fffffffU
) &
4383 dns_zone_log(zone
, ISC_LOG_ERROR
,
4384 "ixfr-from-differences: "
4385 "new serial (%u) out of range "
4386 "[%u - %u]", serial
, serialmin
,
4388 result
= DNS_R_BADZONE
;
4390 } else if (!isc_serial_ge(serial
, oldserial
))
4391 dns_zone_log(zone
, ISC_LOG_ERROR
,
4392 "zone serial (%u/%u) has gone "
4393 "backwards", serial
, oldserial
);
4394 else if (serial
== oldserial
&& !hasinclude
&&
4395 strcmp(zone
->db_argv
[0], "_builtin") != 0)
4396 dns_zone_log(zone
, ISC_LOG_ERROR
,
4397 "zone serial (%u) unchanged. "
4398 "zone may fail to transfer "
4399 "to slaves.", serial
);
4402 if (zone
->type
== dns_zone_master
&&
4403 (zone
->update_acl
!= NULL
|| zone
->ssutable
!= NULL
) &&
4404 zone
->sigresigninginterval
< (3 * refresh
) &&
4405 dns_db_issecure(db
))
4407 dns_zone_log(zone
, ISC_LOG_WARNING
,
4408 "sig-re-signing-interval less than "
4412 zone
->refresh
= RANGE(refresh
,
4413 zone
->minrefresh
, zone
->maxrefresh
);
4414 zone
->retry
= RANGE(retry
,
4415 zone
->minretry
, zone
->maxretry
);
4416 zone
->expire
= RANGE(expire
, zone
->refresh
+ zone
->retry
,
4418 zone
->minimum
= minimum
;
4419 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
4421 if (zone
->type
== dns_zone_slave
||
4422 zone
->type
== dns_zone_stub
||
4423 (zone
->type
== dns_zone_redirect
&&
4424 zone
->masters
!= NULL
)) {
4428 result
= isc_file_getmodtime(zone
->journal
, &t
);
4429 if (result
!= ISC_R_SUCCESS
)
4430 result
= isc_file_getmodtime(zone
->masterfile
,
4432 if (result
== ISC_R_SUCCESS
)
4433 DNS_ZONE_TIME_ADD(&t
, zone
->expire
,
4436 DNS_ZONE_TIME_ADD(&now
, zone
->retry
,
4439 delay
= isc_random_jitter(zone
->retry
,
4440 (zone
->retry
* 3) / 4);
4441 DNS_ZONE_TIME_ADD(&now
, delay
, &zone
->refreshtime
);
4442 if (isc_time_compare(&zone
->refreshtime
,
4443 &zone
->expiretime
) >= 0)
4444 zone
->refreshtime
= now
;
4450 result
= sync_keyzone(zone
, db
);
4451 if (result
!= ISC_R_SUCCESS
)
4456 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
4457 "unexpected zone type %d", zone
->type
);
4458 result
= ISC_R_UNEXPECTED
;
4463 * Check for weak DNSKEY's.
4465 if (zone
->type
== dns_zone_master
)
4466 zone_check_dnskeys(zone
, db
);
4469 * Schedule DNSSEC key refresh.
4471 if (zone
->type
== dns_zone_master
&&
4472 DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_MAINTAIN
))
4473 zone
->refreshkeytime
= now
;
4476 /* destroy notification example. */
4478 isc_event_t
*e
= isc_event_allocate(zone
->mctx
, NULL
,
4479 DNS_EVENT_DBDESTROYED
,
4480 dns_zonemgr_dbdestroyed
,
4482 sizeof(isc_event_t
));
4483 dns_db_ondestroy(db
, zone
->task
, &e
);
4487 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
4488 if (zone
->db
!= NULL
) {
4489 result
= zone_replacedb(zone
, db
, ISC_FALSE
);
4490 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
4491 if (result
!= ISC_R_SUCCESS
)
4494 result
= dns_db_rpz_ready(db
);
4495 if (result
!= ISC_R_SUCCESS
)
4497 zone_attachdb(zone
, db
);
4498 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
4499 DNS_ZONE_SETFLAG(zone
,
4501 DNS_ZONEFLG_NEEDSTARTUPNOTIFY
);
4502 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SENDSECURE
) &&
4505 if (zone
->secure
->db
== NULL
)
4506 zone_send_securedb(zone
, db
);
4508 zone_send_secureserial(zone
, serial
);
4513 * Finished loading inline-signing zone; need to get status
4514 * from the raw side now.
4516 if (zone
->type
== dns_zone_master
&& inline_secure(zone
))
4517 maybe_send_secure(zone
);
4520 result
= ISC_R_SUCCESS
;
4523 if (zone
->type
== dns_zone_key
)
4524 zone_needdump(zone
, 30);
4526 zone_needdump(zone
, DNS_DUMP_DELAY
);
4529 if (zone
->task
!= NULL
) {
4530 if (zone
->type
== dns_zone_master
) {
4531 set_resigntime(zone
);
4532 resume_signingwithkey(zone
);
4533 resume_addnsec3chain(zone
);
4536 if (zone
->type
== dns_zone_master
&&
4537 !DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_NORESIGN
) &&
4538 dns_zone_isdynamic(zone
, ISC_FALSE
) &&
4539 dns_db_issecure(db
)) {
4541 dns_fixedname_t fixed
;
4542 dns_rdataset_t next
;
4544 dns_rdataset_init(&next
);
4545 dns_fixedname_init(&fixed
);
4546 name
= dns_fixedname_name(&fixed
);
4548 result
= dns_db_getsigningtime(db
, &next
, name
);
4549 if (result
== ISC_R_SUCCESS
) {
4550 isc_stdtime_t timenow
;
4551 char namebuf
[DNS_NAME_FORMATSIZE
];
4552 char typebuf
[DNS_RDATATYPE_FORMATSIZE
];
4554 isc_stdtime_get(&timenow
);
4555 dns_name_format(name
, namebuf
, sizeof(namebuf
));
4556 dns_rdatatype_format(next
.covers
,
4557 typebuf
, sizeof(typebuf
));
4558 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
4559 "next resign: %s/%s in %d seconds",
4561 next
.resign
- timenow
-
4562 zone
->sigresigninginterval
);
4563 dns_rdataset_disassociate(&next
);
4565 dns_zone_log(zone
, ISC_LOG_WARNING
,
4566 "signed dynamic zone has no "
4567 "resign event scheduled");
4570 zone_settimer(zone
, &now
);
4574 * Clear old include list.
4576 for (inc
= ISC_LIST_HEAD(zone
->includes
);
4578 inc
= ISC_LIST_HEAD(zone
->includes
)) {
4579 ISC_LIST_UNLINK(zone
->includes
, inc
, link
);
4580 isc_mem_free(zone
->mctx
, inc
->name
);
4581 isc_mem_put(zone
->mctx
, inc
, sizeof(*inc
));
4583 zone
->nincludes
= 0;
4586 * Transfer new include list.
4588 for (inc
= ISC_LIST_HEAD(zone
->newincludes
);
4590 inc
= ISC_LIST_HEAD(zone
->newincludes
)) {
4591 ISC_LIST_UNLINK(zone
->newincludes
, inc
, link
);
4592 ISC_LIST_APPEND(zone
->includes
, inc
, link
);
4596 if (! dns_db_ispersistent(db
))
4597 dns_zone_log(zone
, ISC_LOG_INFO
, "loaded serial %u%s", serial
,
4598 dns_db_issecure(db
) ? " (DNSSEC signed)" : "");
4600 zone
->loadtime
= loadtime
;
4601 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_LOADPENDING
);
4605 for (inc
= ISC_LIST_HEAD(zone
->newincludes
);
4607 inc
= ISC_LIST_HEAD(zone
->newincludes
)) {
4608 ISC_LIST_UNLINK(zone
->newincludes
, inc
, link
);
4609 isc_mem_free(zone
->mctx
, inc
->name
);
4610 isc_mem_put(zone
->mctx
, inc
, sizeof(*inc
));
4612 if (zone
->type
== dns_zone_slave
||
4613 zone
->type
== dns_zone_stub
||
4614 zone
->type
== dns_zone_key
||
4615 (zone
->type
== dns_zone_redirect
&& zone
->masters
!= NULL
)) {
4616 if (zone
->journal
!= NULL
)
4617 zone_saveunique(zone
, zone
->journal
, "jn-XXXXXXXX");
4618 if (zone
->masterfile
!= NULL
)
4619 zone_saveunique(zone
, zone
->masterfile
, "db-XXXXXXXX");
4621 /* Mark the zone for immediate refresh. */
4622 zone
->refreshtime
= now
;
4623 if (zone
->task
!= NULL
)
4624 zone_settimer(zone
, &now
);
4625 result
= ISC_R_SUCCESS
;
4626 } else if (zone
->type
== dns_zone_master
||
4627 zone
->type
== dns_zone_redirect
) {
4628 if (!(inline_secure(zone
) && result
== ISC_R_FILENOTFOUND
))
4629 dns_zone_log(zone
, ISC_LOG_ERROR
,
4630 "not loaded due to errors.");
4631 else if (zone
->type
== dns_zone_master
)
4632 result
= ISC_R_SUCCESS
;
4638 static isc_boolean_t
4639 exit_check(dns_zone_t
*zone
) {
4640 REQUIRE(LOCKED_ZONE(zone
));
4642 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SHUTDOWN
) && zone
->irefs
== 0) {
4644 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
4646 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
4652 static isc_boolean_t
4653 zone_check_ns(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*version
,
4654 dns_name_t
*name
, isc_boolean_t logit
)
4656 isc_result_t result
;
4657 char namebuf
[DNS_NAME_FORMATSIZE
];
4658 char altbuf
[DNS_NAME_FORMATSIZE
];
4659 dns_fixedname_t fixed
;
4660 dns_name_t
*foundname
;
4663 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOCHECKNS
))
4666 if (zone
->type
== dns_zone_master
)
4667 level
= ISC_LOG_ERROR
;
4669 level
= ISC_LOG_WARNING
;
4671 dns_fixedname_init(&fixed
);
4672 foundname
= dns_fixedname_name(&fixed
);
4674 result
= dns_db_find(db
, name
, version
, dns_rdatatype_a
,
4675 0, 0, NULL
, foundname
, NULL
, NULL
);
4676 if (result
== ISC_R_SUCCESS
)
4679 if (result
== DNS_R_NXRRSET
) {
4680 result
= dns_db_find(db
, name
, version
, dns_rdatatype_aaaa
,
4681 0, 0, NULL
, foundname
, NULL
, NULL
);
4682 if (result
== ISC_R_SUCCESS
)
4686 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
4687 result
== DNS_R_EMPTYNAME
) {
4689 dns_name_format(name
, namebuf
, sizeof namebuf
);
4690 dns_zone_log(zone
, level
, "NS '%s' has no address "
4691 "records (A or AAAA)", namebuf
);
4696 if (result
== DNS_R_CNAME
) {
4698 dns_name_format(name
, namebuf
, sizeof namebuf
);
4699 dns_zone_log(zone
, level
, "NS '%s' is a CNAME "
4700 "(illegal)", namebuf
);
4705 if (result
== DNS_R_DNAME
) {
4707 dns_name_format(name
, namebuf
, sizeof namebuf
);
4708 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
4709 dns_zone_log(zone
, level
, "NS '%s' is below a DNAME "
4710 "'%s' (illegal)", namebuf
, altbuf
);
4719 zone_count_ns_rr(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbnode_t
*node
,
4720 dns_dbversion_t
*version
, unsigned int *nscount
,
4721 unsigned int *errors
, isc_boolean_t logit
)
4723 isc_result_t result
;
4724 unsigned int count
= 0;
4725 unsigned int ecount
= 0;
4726 dns_rdataset_t rdataset
;
4730 dns_rdataset_init(&rdataset
);
4731 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_ns
,
4732 dns_rdatatype_none
, 0, &rdataset
, NULL
);
4733 if (result
== ISC_R_NOTFOUND
) {
4734 INSIST(!dns_rdataset_isassociated(&rdataset
));
4737 if (result
!= ISC_R_SUCCESS
) {
4738 INSIST(!dns_rdataset_isassociated(&rdataset
));
4739 goto invalidate_rdataset
;
4742 result
= dns_rdataset_first(&rdataset
);
4743 while (result
== ISC_R_SUCCESS
) {
4744 if (errors
!= NULL
&& zone
->rdclass
== dns_rdataclass_in
&&
4745 (zone
->type
== dns_zone_master
||
4746 zone
->type
== dns_zone_slave
)) {
4747 dns_rdata_init(&rdata
);
4748 dns_rdataset_current(&rdataset
, &rdata
);
4749 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
4750 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4751 if (dns_name_issubdomain(&ns
.name
, &zone
->origin
) &&
4752 !zone_check_ns(zone
, db
, version
, &ns
.name
, logit
))
4756 result
= dns_rdataset_next(&rdataset
);
4758 dns_rdataset_disassociate(&rdataset
);
4761 if (nscount
!= NULL
)
4766 result
= ISC_R_SUCCESS
;
4768 invalidate_rdataset
:
4769 dns_rdataset_invalidate(&rdataset
);
4775 zone_load_soa_rr(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
4776 unsigned int *soacount
,
4777 isc_uint32_t
*serial
, isc_uint32_t
*refresh
,
4778 isc_uint32_t
*retry
, isc_uint32_t
*expire
,
4779 isc_uint32_t
*minimum
)
4781 isc_result_t result
;
4783 dns_rdataset_t rdataset
;
4784 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4785 dns_rdata_soa_t soa
;
4787 dns_rdataset_init(&rdataset
);
4788 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_soa
,
4789 dns_rdatatype_none
, 0, &rdataset
, NULL
);
4790 if (result
== ISC_R_NOTFOUND
) {
4791 INSIST(!dns_rdataset_isassociated(&rdataset
));
4792 if (soacount
!= NULL
)
4796 if (refresh
!= NULL
)
4802 if (minimum
!= NULL
)
4804 result
= ISC_R_SUCCESS
;
4805 goto invalidate_rdataset
;
4807 if (result
!= ISC_R_SUCCESS
) {
4808 INSIST(!dns_rdataset_isassociated(&rdataset
));
4809 goto invalidate_rdataset
;
4813 result
= dns_rdataset_first(&rdataset
);
4814 while (result
== ISC_R_SUCCESS
) {
4815 dns_rdata_init(&rdata
);
4816 dns_rdataset_current(&rdataset
, &rdata
);
4819 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
4820 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4823 result
= dns_rdataset_next(&rdataset
);
4824 dns_rdata_reset(&rdata
);
4826 dns_rdataset_disassociate(&rdataset
);
4828 if (soacount
!= NULL
)
4833 *serial
= soa
.serial
;
4834 if (refresh
!= NULL
)
4835 *refresh
= soa
.refresh
;
4839 *expire
= soa
.expire
;
4840 if (minimum
!= NULL
)
4841 *minimum
= soa
.minimum
;
4843 if (soacount
!= NULL
)
4847 if (refresh
!= NULL
)
4853 if (minimum
!= NULL
)
4857 result
= ISC_R_SUCCESS
;
4859 invalidate_rdataset
:
4860 dns_rdataset_invalidate(&rdataset
);
4866 * zone must be locked.
4869 zone_get_from_db(dns_zone_t
*zone
, dns_db_t
*db
, unsigned int *nscount
,
4870 unsigned int *soacount
, isc_uint32_t
*serial
,
4871 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
4872 isc_uint32_t
*expire
, isc_uint32_t
*minimum
,
4873 unsigned int *errors
)
4875 isc_result_t result
;
4876 isc_result_t answer
= ISC_R_SUCCESS
;
4877 dns_dbversion_t
*version
= NULL
;
4880 REQUIRE(db
!= NULL
);
4881 REQUIRE(zone
!= NULL
);
4883 dns_db_currentversion(db
, &version
);
4885 if (nscount
!= NULL
)
4887 if (soacount
!= NULL
)
4891 if (refresh
!= NULL
)
4901 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
4902 if (result
!= ISC_R_SUCCESS
) {
4907 if (nscount
!= NULL
|| errors
!= NULL
) {
4908 result
= zone_count_ns_rr(zone
, db
, node
, version
,
4909 nscount
, errors
, ISC_TRUE
);
4910 if (result
!= ISC_R_SUCCESS
)
4914 if (soacount
!= NULL
|| serial
!= NULL
|| refresh
!= NULL
4915 || retry
!= NULL
|| expire
!= NULL
|| minimum
!= NULL
) {
4916 result
= zone_load_soa_rr(db
, node
, version
, soacount
,
4917 serial
, refresh
, retry
, expire
,
4919 if (result
!= ISC_R_SUCCESS
)
4923 dns_db_detachnode(db
, &node
);
4925 dns_db_closeversion(db
, &version
, ISC_FALSE
);
4931 dns_zone_attach(dns_zone_t
*source
, dns_zone_t
**target
) {
4932 REQUIRE(DNS_ZONE_VALID(source
));
4933 REQUIRE(target
!= NULL
&& *target
== NULL
);
4934 isc_refcount_increment(&source
->erefs
, NULL
);
4939 dns_zone_detach(dns_zone_t
**zonep
) {
4941 dns_zone_t
*raw
= NULL
;
4942 dns_zone_t
*secure
= NULL
;
4944 isc_boolean_t free_now
= ISC_FALSE
;
4946 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
4950 isc_refcount_decrement(&zone
->erefs
, &refs
);
4954 INSIST(zone
!= zone
->raw
);
4956 * We just detached the last external reference.
4958 if (zone
->task
!= NULL
) {
4960 * This zone is being managed. Post
4961 * its control event and let it clean
4962 * up synchronously in the context of
4965 isc_event_t
*ev
= &zone
->ctlevent
;
4966 isc_task_send(zone
->task
, &ev
);
4969 * This zone is not being managed; it has
4970 * no task and can have no outstanding
4971 * events. Free it immediately.
4974 * Unmanaged zones should not have non-null views;
4975 * we have no way of detaching from the view here
4976 * without causing deadlock because this code is called
4977 * with the view already locked.
4979 INSIST(zone
->view
== NULL
);
4980 free_now
= ISC_TRUE
;
4983 secure
= zone
->secure
;
4984 zone
->secure
= NULL
;
4991 dns_zone_detach(&raw
);
4993 dns_zone_idetach(&secure
);
4999 dns_zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
5000 REQUIRE(DNS_ZONE_VALID(source
));
5001 REQUIRE(target
!= NULL
&& *target
== NULL
);
5003 zone_iattach(source
, target
);
5004 UNLOCK_ZONE(source
);
5008 zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
5011 * 'source' locked by caller.
5013 REQUIRE(LOCKED_ZONE(source
));
5014 REQUIRE(DNS_ZONE_VALID(source
));
5015 REQUIRE(target
!= NULL
&& *target
== NULL
);
5016 INSIST(source
->irefs
+ isc_refcount_current(&source
->erefs
) > 0);
5018 INSIST(source
->irefs
!= 0);
5023 zone_idetach(dns_zone_t
**zonep
) {
5027 * 'zone' locked by caller.
5029 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
5031 REQUIRE(LOCKED_ZONE(*zonep
));
5034 INSIST(zone
->irefs
> 0);
5036 INSIST(zone
->irefs
+ isc_refcount_current(&zone
->erefs
) > 0);
5040 dns_zone_idetach(dns_zone_t
**zonep
) {
5042 isc_boolean_t free_needed
;
5044 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
5049 INSIST(zone
->irefs
> 0);
5051 free_needed
= exit_check(zone
);
5058 dns_zone_getmctx(dns_zone_t
*zone
) {
5059 REQUIRE(DNS_ZONE_VALID(zone
));
5061 return (zone
->mctx
);
5065 dns_zone_getmgr(dns_zone_t
*zone
) {
5066 REQUIRE(DNS_ZONE_VALID(zone
));
5068 return (zone
->zmgr
);
5072 dns_zone_setflag(dns_zone_t
*zone
, unsigned int flags
, isc_boolean_t value
) {
5073 REQUIRE(DNS_ZONE_VALID(zone
));
5077 DNS_ZONE_SETFLAG(zone
, flags
);
5079 DNS_ZONE_CLRFLAG(zone
, flags
);
5084 dns_zone_setoption(dns_zone_t
*zone
, unsigned int option
,
5085 isc_boolean_t value
)
5087 REQUIRE(DNS_ZONE_VALID(zone
));
5091 zone
->options
|= option
;
5093 zone
->options
&= ~option
;
5098 dns_zone_setoption2(dns_zone_t
*zone
, unsigned int option
,
5099 isc_boolean_t value
)
5101 REQUIRE(DNS_ZONE_VALID(zone
));
5105 zone
->options2
|= option
;
5107 zone
->options2
&= ~option
;
5112 dns_zone_getoptions(dns_zone_t
*zone
) {
5113 REQUIRE(DNS_ZONE_VALID(zone
));
5115 return (zone
->options
);
5119 dns_zone_getoptions2(dns_zone_t
*zone
) {
5120 REQUIRE(DNS_ZONE_VALID(zone
));
5122 return (zone
->options2
);
5126 dns_zone_setkeyopt(dns_zone_t
*zone
, unsigned int keyopt
, isc_boolean_t value
)
5128 REQUIRE(DNS_ZONE_VALID(zone
));
5132 zone
->keyopts
|= keyopt
;
5134 zone
->keyopts
&= ~keyopt
;
5139 dns_zone_getkeyopts(dns_zone_t
*zone
) {
5141 REQUIRE(DNS_ZONE_VALID(zone
));
5143 return (zone
->keyopts
);
5147 dns_zone_setxfrsource4(dns_zone_t
*zone
, const isc_sockaddr_t
*xfrsource
) {
5148 REQUIRE(DNS_ZONE_VALID(zone
));
5151 zone
->xfrsource4
= *xfrsource
;
5154 return (ISC_R_SUCCESS
);
5158 dns_zone_getxfrsource4(dns_zone_t
*zone
) {
5159 REQUIRE(DNS_ZONE_VALID(zone
));
5160 return (&zone
->xfrsource4
);
5164 dns_zone_setxfrsource4dscp(dns_zone_t
*zone
, isc_dscp_t dscp
) {
5165 REQUIRE(DNS_ZONE_VALID(zone
));
5168 zone
->xfrsource4dscp
= dscp
;
5171 return (ISC_R_SUCCESS
);
5175 dns_zone_getxfrsource4dscp(dns_zone_t
*zone
) {
5176 REQUIRE(DNS_ZONE_VALID(zone
));
5177 return (zone
->xfrsource4dscp
);
5181 dns_zone_setxfrsource6(dns_zone_t
*zone
, const isc_sockaddr_t
*xfrsource
) {
5182 REQUIRE(DNS_ZONE_VALID(zone
));
5185 zone
->xfrsource6
= *xfrsource
;
5188 return (ISC_R_SUCCESS
);
5192 dns_zone_getxfrsource6(dns_zone_t
*zone
) {
5193 REQUIRE(DNS_ZONE_VALID(zone
));
5194 return (&zone
->xfrsource6
);
5198 dns_zone_getxfrsource6dscp(dns_zone_t
*zone
) {
5199 REQUIRE(DNS_ZONE_VALID(zone
));
5200 return (zone
->xfrsource6dscp
);
5204 dns_zone_setxfrsource6dscp(dns_zone_t
*zone
, isc_dscp_t dscp
) {
5205 REQUIRE(DNS_ZONE_VALID(zone
));
5208 zone
->xfrsource6dscp
= dscp
;
5211 return (ISC_R_SUCCESS
);
5215 dns_zone_setaltxfrsource4(dns_zone_t
*zone
,
5216 const isc_sockaddr_t
*altxfrsource
)
5218 REQUIRE(DNS_ZONE_VALID(zone
));
5221 zone
->altxfrsource4
= *altxfrsource
;
5224 return (ISC_R_SUCCESS
);
5228 dns_zone_getaltxfrsource4(dns_zone_t
*zone
) {
5229 REQUIRE(DNS_ZONE_VALID(zone
));
5230 return (&zone
->altxfrsource4
);
5234 dns_zone_setaltxfrsource4dscp(dns_zone_t
*zone
, isc_dscp_t dscp
) {
5235 REQUIRE(DNS_ZONE_VALID(zone
));
5238 zone
->altxfrsource4dscp
= dscp
;
5241 return (ISC_R_SUCCESS
);
5245 dns_zone_getaltxfrsource4dscp(dns_zone_t
*zone
) {
5246 REQUIRE(DNS_ZONE_VALID(zone
));
5247 return (zone
->altxfrsource4dscp
);
5251 dns_zone_setaltxfrsource6(dns_zone_t
*zone
,
5252 const isc_sockaddr_t
*altxfrsource
)
5254 REQUIRE(DNS_ZONE_VALID(zone
));
5257 zone
->altxfrsource6
= *altxfrsource
;
5260 return (ISC_R_SUCCESS
);
5264 dns_zone_getaltxfrsource6(dns_zone_t
*zone
) {
5265 REQUIRE(DNS_ZONE_VALID(zone
));
5266 return (&zone
->altxfrsource6
);
5270 dns_zone_setaltxfrsource6dscp(dns_zone_t
*zone
, isc_dscp_t dscp
) {
5271 REQUIRE(DNS_ZONE_VALID(zone
));
5274 zone
->altxfrsource6dscp
= dscp
;
5277 return (ISC_R_SUCCESS
);
5281 dns_zone_getaltxfrsource6dscp(dns_zone_t
*zone
) {
5282 REQUIRE(DNS_ZONE_VALID(zone
));
5283 return (zone
->altxfrsource6dscp
);
5287 dns_zone_setnotifysrc4(dns_zone_t
*zone
, const isc_sockaddr_t
*notifysrc
) {
5288 REQUIRE(DNS_ZONE_VALID(zone
));
5291 zone
->notifysrc4
= *notifysrc
;
5294 return (ISC_R_SUCCESS
);
5298 dns_zone_getnotifysrc4(dns_zone_t
*zone
) {
5299 REQUIRE(DNS_ZONE_VALID(zone
));
5300 return (&zone
->notifysrc4
);
5304 dns_zone_setnotifysrc4dscp(dns_zone_t
*zone
, isc_dscp_t dscp
) {
5305 REQUIRE(DNS_ZONE_VALID(zone
));
5308 zone
->notifysrc4dscp
= dscp
;
5311 return (ISC_R_SUCCESS
);
5315 dns_zone_getnotifysrc4dscp(dns_zone_t
*zone
) {
5316 REQUIRE(DNS_ZONE_VALID(zone
));
5317 return (zone
->notifysrc4dscp
);
5321 dns_zone_setnotifysrc6(dns_zone_t
*zone
, const isc_sockaddr_t
*notifysrc
) {
5322 REQUIRE(DNS_ZONE_VALID(zone
));
5325 zone
->notifysrc6
= *notifysrc
;
5328 return (ISC_R_SUCCESS
);
5332 dns_zone_getnotifysrc6(dns_zone_t
*zone
) {
5333 REQUIRE(DNS_ZONE_VALID(zone
));
5334 return (&zone
->notifysrc6
);
5337 static isc_boolean_t
5338 same_addrs(const isc_sockaddr_t
*old
, const isc_sockaddr_t
*new,
5343 for (i
= 0; i
< count
; i
++)
5344 if (!isc_sockaddr_equal(&old
[i
], &new[i
]))
5349 static isc_boolean_t
5350 same_keynames(dns_name_t
**old
, dns_name_t
**new, isc_uint32_t count
) {
5353 if (old
== NULL
&& new == NULL
)
5355 if (old
== NULL
|| new == NULL
)
5358 for (i
= 0; i
< count
; i
++) {
5359 if (old
[i
] == NULL
&& new[i
] == NULL
)
5361 if (old
[i
] == NULL
|| new[i
] == NULL
||
5362 !dns_name_equal(old
[i
], new[i
]))
5369 clear_addresskeylist(isc_sockaddr_t
**addrsp
, isc_dscp_t
**dscpsp
,
5370 dns_name_t
***keynamesp
, unsigned int *countp
,
5374 isc_sockaddr_t
*addrs
;
5376 dns_name_t
**keynames
;
5378 REQUIRE(countp
!= NULL
&& addrsp
!= NULL
&& dscpsp
!= NULL
&&
5387 keynames
= *keynamesp
;
5391 isc_mem_put(mctx
, addrs
, count
* sizeof(isc_sockaddr_t
));
5394 isc_mem_put(mctx
, dscps
, count
* sizeof(isc_dscp_t
));
5396 if (keynames
!= NULL
) {
5398 for (i
= 0; i
< count
; i
++) {
5399 if (keynames
[i
] != NULL
) {
5400 dns_name_free(keynames
[i
], mctx
);
5401 isc_mem_put(mctx
, keynames
[i
],
5402 sizeof(dns_name_t
));
5406 isc_mem_put(mctx
, keynames
, count
* sizeof(dns_name_t
*));
5411 set_addrkeylist(unsigned int count
,
5412 const isc_sockaddr_t
*addrs
, isc_sockaddr_t
**newaddrsp
,
5413 const isc_dscp_t
*dscp
, isc_dscp_t
**newdscpp
,
5414 dns_name_t
**names
, dns_name_t
***newnamesp
,
5417 isc_result_t result
;
5418 isc_sockaddr_t
*newaddrs
= NULL
;
5419 isc_dscp_t
*newdscp
= NULL
;
5420 dns_name_t
**newnames
= NULL
;
5423 REQUIRE(newaddrsp
!= NULL
&& *newaddrsp
== NULL
);
5424 REQUIRE(newdscpp
!= NULL
&& *newdscpp
== NULL
);
5425 REQUIRE(newnamesp
!= NULL
&& *newnamesp
== NULL
);
5427 newaddrs
= isc_mem_get(mctx
, count
* sizeof(*newaddrs
));
5428 if (newaddrs
== NULL
)
5429 return (ISC_R_NOMEMORY
);
5430 memmove(newaddrs
, addrs
, count
* sizeof(*newaddrs
));
5433 newdscp
= isc_mem_get(mctx
, count
* sizeof(*newdscp
));
5434 if (newdscp
== NULL
) {
5435 isc_mem_put(mctx
, newaddrs
, count
* sizeof(*newaddrs
));
5436 return (ISC_R_NOMEMORY
);
5438 memmove(newdscp
, dscp
, count
* sizeof(*newdscp
));
5442 if (names
!= NULL
) {
5443 newnames
= isc_mem_get(mctx
, count
* sizeof(*newnames
));
5444 if (newnames
== NULL
) {
5445 if (newdscp
!= NULL
)
5446 isc_mem_put(mctx
, newdscp
,
5447 count
* sizeof(*newdscp
));
5448 isc_mem_put(mctx
, newaddrs
, count
* sizeof(*newaddrs
));
5449 return (ISC_R_NOMEMORY
);
5451 for (i
= 0; i
< count
; i
++)
5453 for (i
= 0; i
< count
; i
++) {
5454 if (names
[i
] != NULL
) {
5455 newnames
[i
] = isc_mem_get(mctx
,
5456 sizeof(dns_name_t
));
5457 if (newnames
[i
] == NULL
)
5459 dns_name_init(newnames
[i
], NULL
);
5460 result
= dns_name_dup(names
[i
], mctx
,
5462 if (result
!= ISC_R_SUCCESS
) {
5464 for (i
= 0; i
< count
; i
++)
5465 if (newnames
[i
] != NULL
)
5469 isc_mem_put(mctx
, newaddrs
,
5470 count
* sizeof(*newaddrs
));
5471 isc_mem_put(mctx
, newdscp
,
5472 count
* sizeof(*newdscp
));
5473 isc_mem_put(mctx
, newnames
,
5474 count
* sizeof(*newnames
));
5475 return (ISC_R_NOMEMORY
);
5482 *newdscpp
= newdscp
;
5483 *newaddrsp
= newaddrs
;
5484 *newnamesp
= newnames
;
5485 return (ISC_R_SUCCESS
);
5489 dns_zone_setnotifysrc6dscp(dns_zone_t
*zone
, isc_dscp_t dscp
) {
5490 REQUIRE(DNS_ZONE_VALID(zone
));
5493 zone
->notifysrc6dscp
= dscp
;
5496 return (ISC_R_SUCCESS
);
5500 dns_zone_getnotifysrc6dscp(dns_zone_t
*zone
) {
5501 REQUIRE(DNS_ZONE_VALID(zone
));
5502 return (zone
->notifysrc6dscp
);
5506 dns_zone_setalsonotify(dns_zone_t
*zone
, const isc_sockaddr_t
*notify
,
5509 return (dns_zone_setalsonotifydscpkeys(zone
, notify
, NULL
, NULL
,
5514 dns_zone_setalsonotifywithkeys(dns_zone_t
*zone
, const isc_sockaddr_t
*notify
,
5515 dns_name_t
**keynames
, isc_uint32_t count
)
5517 return (dns_zone_setalsonotifydscpkeys(zone
, notify
, NULL
, keynames
,
5522 dns_zone_setalsonotifydscpkeys(dns_zone_t
*zone
, const isc_sockaddr_t
*notify
,
5523 const isc_dscp_t
*dscps
, dns_name_t
**keynames
,
5526 isc_result_t result
;
5527 isc_sockaddr_t
*newaddrs
= NULL
;
5528 isc_dscp_t
*newdscps
= NULL
;
5529 dns_name_t
**newnames
= NULL
;
5531 REQUIRE(DNS_ZONE_VALID(zone
));
5532 REQUIRE(count
== 0 || notify
!= NULL
);
5533 if (keynames
!= NULL
)
5534 REQUIRE(count
!= 0);
5538 if (count
== zone
->notifycnt
&&
5539 same_addrs(zone
->notify
, notify
, count
) &&
5540 same_keynames(zone
->notifykeynames
, keynames
, count
))
5543 clear_addresskeylist(&zone
->notify
, &zone
->notifydscp
,
5544 &zone
->notifykeynames
, &zone
->notifycnt
,
5551 * Set up the notify and notifykey lists
5553 result
= set_addrkeylist(count
, notify
, &newaddrs
, dscps
, &newdscps
,
5554 keynames
, &newnames
, zone
->mctx
);
5555 if (result
!= ISC_R_SUCCESS
)
5559 * Everything is ok so attach to the zone.
5561 zone
->notify
= newaddrs
;
5562 zone
->notifydscp
= newdscps
;
5563 zone
->notifykeynames
= newnames
;
5564 zone
->notifycnt
= count
;
5567 return (ISC_R_SUCCESS
);
5571 dns_zone_setmasters(dns_zone_t
*zone
, const isc_sockaddr_t
*masters
,
5574 isc_result_t result
;
5576 result
= dns_zone_setmasterswithkeys(zone
, masters
, NULL
, count
);
5581 dns_zone_setmasterswithkeys(dns_zone_t
*zone
,
5582 const isc_sockaddr_t
*masters
,
5583 dns_name_t
**keynames
,
5586 isc_result_t result
= ISC_R_SUCCESS
;
5587 isc_sockaddr_t
*newaddrs
= NULL
;
5588 isc_dscp_t
*newdscps
= NULL
;
5589 dns_name_t
**newnames
= NULL
;
5590 isc_boolean_t
*newok
;
5593 REQUIRE(DNS_ZONE_VALID(zone
));
5594 REQUIRE(count
== 0 || masters
!= NULL
);
5595 if (keynames
!= NULL
) {
5596 REQUIRE(count
!= 0);
5601 * The refresh code assumes that 'masters' wouldn't change under it.
5602 * If it will change then kill off any current refresh in progress
5603 * and update the masters info. If it won't change then we can just
5606 if (count
!= zone
->masterscnt
||
5607 !same_addrs(zone
->masters
, masters
, count
) ||
5608 !same_keynames(zone
->masterkeynames
, keynames
, count
)) {
5609 if (zone
->request
!= NULL
)
5610 dns_request_cancel(zone
->request
);
5615 * This needs to happen before clear_addresskeylist() sets
5616 * zone->masterscnt to 0:
5618 if (zone
->mastersok
!= NULL
) {
5619 isc_mem_put(zone
->mctx
, zone
->mastersok
,
5620 zone
->masterscnt
* sizeof(isc_boolean_t
));
5621 zone
->mastersok
= NULL
;
5623 clear_addresskeylist(&zone
->masters
, &zone
->masterdscps
,
5624 &zone
->masterkeynames
, &zone
->masterscnt
,
5627 * If count == 0, don't allocate any space for masters, mastersok or
5628 * keynames so internally, those pointers are NULL if count == 0
5634 * mastersok must contain count elements
5636 newok
= isc_mem_get(zone
->mctx
, count
* sizeof(*newok
));
5637 if (newok
== NULL
) {
5638 result
= ISC_R_NOMEMORY
;
5639 isc_mem_put(zone
->mctx
, newaddrs
, count
* sizeof(*newaddrs
));
5642 for (i
= 0; i
< count
; i
++)
5643 newok
[i
] = ISC_FALSE
;
5646 * Now set up the masters and masterkey lists
5648 result
= set_addrkeylist(count
, masters
, &newaddrs
, NULL
, &newdscps
,
5649 keynames
, &newnames
, zone
->mctx
);
5650 INSIST(newdscps
== NULL
);
5651 if (result
!= ISC_R_SUCCESS
) {
5652 isc_mem_put(zone
->mctx
, newok
, count
* sizeof(*newok
));
5657 * Everything is ok so attach to the zone.
5659 zone
->curmaster
= 0;
5660 zone
->mastersok
= newok
;
5661 zone
->masters
= newaddrs
;
5662 zone
->masterdscps
= newdscps
;
5663 zone
->masterkeynames
= newnames
;
5664 zone
->masterscnt
= count
;
5665 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
5673 dns_zone_getdb(dns_zone_t
*zone
, dns_db_t
**dpb
) {
5674 isc_result_t result
= ISC_R_SUCCESS
;
5676 REQUIRE(DNS_ZONE_VALID(zone
));
5678 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
5679 if (zone
->db
== NULL
)
5680 result
= DNS_R_NOTLOADED
;
5682 dns_db_attach(zone
->db
, dpb
);
5683 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
5689 dns_zone_setdb(dns_zone_t
*zone
, dns_db_t
*db
) {
5690 REQUIRE(DNS_ZONE_VALID(zone
));
5691 REQUIRE(zone
->type
== dns_zone_staticstub
);
5693 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
5694 REQUIRE(zone
->db
== NULL
);
5695 dns_db_attach(db
, &zone
->db
);
5696 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
5700 * Co-ordinates the starting of routine jobs.
5703 dns_zone_maintenance(dns_zone_t
*zone
) {
5704 const char me
[] = "dns_zone_maintenance";
5707 REQUIRE(DNS_ZONE_VALID(zone
));
5712 zone_settimer(zone
, &now
);
5716 static inline isc_boolean_t
5717 was_dumping(dns_zone_t
*zone
) {
5718 isc_boolean_t dumping
;
5720 REQUIRE(LOCKED_ZONE(zone
));
5722 dumping
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
);
5723 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
5725 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
5726 isc_time_settoepoch(&zone
->dumptime
);
5732 find_zone_keys(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
5733 isc_mem_t
*mctx
, unsigned int maxkeys
,
5734 dst_key_t
**keys
, unsigned int *nkeys
)
5736 isc_result_t result
;
5737 dns_dbnode_t
*node
= NULL
;
5738 const char *directory
= dns_zone_getkeydirectory(zone
);
5740 CHECK(dns_db_findnode(db
, dns_db_origin(db
), ISC_FALSE
, &node
));
5741 memset(keys
, 0, sizeof(*keys
) * maxkeys
);
5742 result
= dns_dnssec_findzonekeys2(db
, ver
, node
, dns_db_origin(db
),
5743 directory
, mctx
, maxkeys
, keys
,
5745 if (result
== ISC_R_NOTFOUND
)
5746 result
= ISC_R_SUCCESS
;
5749 dns_db_detachnode(db
, &node
);
5754 offline(dns_db_t
*db
, dns_dbversion_t
*ver
, zonediff_t
*zonediff
,
5755 dns_name_t
*name
, dns_ttl_t ttl
, dns_rdata_t
*rdata
)
5757 isc_result_t result
;
5759 if ((rdata
->flags
& DNS_RDATA_OFFLINE
) != 0)
5760 return (ISC_R_SUCCESS
);
5761 result
= update_one_rr(db
, ver
, zonediff
->diff
, DNS_DIFFOP_DELRESIGN
,
5763 if (result
!= ISC_R_SUCCESS
)
5765 rdata
->flags
|= DNS_RDATA_OFFLINE
;
5766 result
= update_one_rr(db
, ver
, zonediff
->diff
, DNS_DIFFOP_ADDRESIGN
,
5768 zonediff
->offline
= ISC_TRUE
;
5773 set_key_expiry_warning(dns_zone_t
*zone
, isc_stdtime_t when
, isc_stdtime_t now
)
5778 zone
->key_expiry
= when
;
5780 dns_zone_log(zone
, ISC_LOG_ERROR
,
5781 "DNSKEY RRSIG(s) have expired");
5782 isc_time_settoepoch(&zone
->keywarntime
);
5783 } else if (when
< now
+ 7 * 24 * 3600) {
5785 isc_time_set(&t
, when
, 0);
5786 isc_time_formattimestamp(&t
, timebuf
, 80);
5787 dns_zone_log(zone
, ISC_LOG_WARNING
,
5788 "DNSKEY RRSIG(s) will expire within 7 days: %s",
5791 delta
--; /* loop prevention */
5792 delta
/= 24 * 3600; /* to whole days */
5793 delta
*= 24 * 3600; /* to seconds */
5794 isc_time_set(&zone
->keywarntime
, when
- delta
, 0);
5796 isc_time_set(&zone
->keywarntime
, when
- 7 * 24 * 3600, 0);
5797 isc_time_formattimestamp(&zone
->refreshkeytime
, timebuf
, 80);
5798 dns_zone_log(zone
, ISC_LOG_NOTICE
,
5799 "setting keywarntime to %s", timebuf
);
5804 * Helper function to del_sigs(). We don't want to delete RRSIGs that
5807 static isc_boolean_t
5808 delsig_ok(dns_rdata_rrsig_t
*rrsig_ptr
, dst_key_t
**keys
, unsigned int nkeys
,
5809 isc_boolean_t
*warn
)
5812 isc_boolean_t have_ksk
= ISC_FALSE
, have_zsk
= ISC_FALSE
;
5813 isc_boolean_t have_pksk
= ISC_FALSE
, have_pzsk
= ISC_FALSE
;
5815 for (i
= 0; i
< nkeys
; i
++) {
5816 if (rrsig_ptr
->algorithm
!= dst_key_alg(keys
[i
]))
5818 if (dst_key_isprivate(keys
[i
])) {
5820 have_ksk
= have_pksk
= ISC_TRUE
;
5822 have_zsk
= have_pzsk
= ISC_TRUE
;
5825 have_ksk
= ISC_TRUE
;
5827 have_zsk
= ISC_TRUE
;
5831 if (have_zsk
&& have_ksk
&& !have_pzsk
)
5835 * It's okay to delete a signature if there is an active key
5836 * with the same algorithm to replace it.
5838 if (have_pksk
|| have_pzsk
)
5842 * Failing that, it is *not* okay to delete a signature
5843 * if the associated public key is still in the DNSKEY RRset
5845 for (i
= 0; i
< nkeys
; i
++) {
5846 if ((rrsig_ptr
->algorithm
== dst_key_alg(keys
[i
])) &&
5847 (rrsig_ptr
->keyid
== dst_key_id(keys
[i
])))
5852 * But if the key is gone, then go ahead.
5858 * Delete expired RRsigs and any RRsigs we are about to re-sign.
5859 * See also update.c:del_keysigs().
5862 del_sigs(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
, dns_name_t
*name
,
5863 dns_rdatatype_t type
, zonediff_t
*zonediff
, dst_key_t
**keys
,
5864 unsigned int nkeys
, isc_stdtime_t now
, isc_boolean_t incremental
)
5866 isc_result_t result
;
5867 dns_dbnode_t
*node
= NULL
;
5868 dns_rdataset_t rdataset
;
5870 dns_rdata_rrsig_t rrsig
;
5871 isc_boolean_t found
;
5872 isc_int64_t timewarn
= 0, timemaybe
= 0;
5874 dns_rdataset_init(&rdataset
);
5876 if (type
== dns_rdatatype_nsec3
)
5877 result
= dns_db_findnsec3node(db
, name
, ISC_FALSE
, &node
);
5879 result
= dns_db_findnode(db
, name
, ISC_FALSE
, &node
);
5880 if (result
== ISC_R_NOTFOUND
)
5881 return (ISC_R_SUCCESS
);
5882 if (result
!= ISC_R_SUCCESS
)
5884 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_rrsig
, type
,
5885 (isc_stdtime_t
) 0, &rdataset
, NULL
);
5886 dns_db_detachnode(db
, &node
);
5888 if (result
== ISC_R_NOTFOUND
) {
5889 INSIST(!dns_rdataset_isassociated(&rdataset
));
5890 return (ISC_R_SUCCESS
);
5892 if (result
!= ISC_R_SUCCESS
) {
5893 INSIST(!dns_rdataset_isassociated(&rdataset
));
5897 for (result
= dns_rdataset_first(&rdataset
);
5898 result
== ISC_R_SUCCESS
;
5899 result
= dns_rdataset_next(&rdataset
)) {
5900 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5902 dns_rdataset_current(&rdataset
, &rdata
);
5903 result
= dns_rdata_tostruct(&rdata
, &rrsig
, NULL
);
5904 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
5906 if (type
!= dns_rdatatype_dnskey
) {
5907 isc_boolean_t warn
= ISC_FALSE
, deleted
= ISC_FALSE
;
5908 if (delsig_ok(&rrsig
, keys
, nkeys
, &warn
)) {
5909 result
= update_one_rr(db
, ver
, zonediff
->diff
,
5910 DNS_DIFFOP_DELRESIGN
, name
,
5911 rdataset
.ttl
, &rdata
);
5912 if (result
!= ISC_R_SUCCESS
)
5918 * At this point, we've got an RRSIG,
5919 * which is signed by an inactive key.
5920 * An administrator needs to provide a new
5921 * key/alg, but until that time, we want to
5922 * keep the old RRSIG. Marking the key as
5923 * offline will prevent us spinning waiting
5924 * for the private part.
5926 if (incremental
&& !deleted
) {
5927 result
= offline(db
, ver
, zonediff
,
5930 if (result
!= ISC_R_SUCCESS
)
5935 * Log the key id and algorithm of
5936 * the inactive key with no replacement
5938 if (zone
->log_key_expired_timer
<= now
) {
5939 char origin
[DNS_NAME_FORMATSIZE
];
5940 char algbuf
[DNS_NAME_FORMATSIZE
];
5941 dns_name_format(&zone
->origin
, origin
,
5943 dns_secalg_format(rrsig
.algorithm
,
5946 dns_zone_log(zone
, ISC_LOG_WARNING
,
5948 "missing or inactive "
5949 "and has no replacement: "
5950 "retaining signatures.",
5953 zone
->log_key_expired_timer
= now
+
5961 * RRSIG(DNSKEY) requires special processing.
5964 for (i
= 0; i
< nkeys
; i
++) {
5965 if (rrsig
.algorithm
== dst_key_alg(keys
[i
]) &&
5966 rrsig
.keyid
== dst_key_id(keys
[i
])) {
5969 * Mark offline RRSIG(DNSKEY).
5970 * We want the earliest offline expire time
5971 * iff there is a new offline signature.
5973 if (!dst_key_inactive(keys
[i
]) &&
5974 !dst_key_isprivate(keys
[i
]))
5976 isc_int64_t timeexpire
=
5977 dns_time64_from32(rrsig
.timeexpire
);
5978 if (timewarn
!= 0 &&
5979 timewarn
> timeexpire
)
5980 timewarn
= timeexpire
;
5981 if (rdata
.flags
& DNS_RDATA_OFFLINE
) {
5982 if (timemaybe
== 0 ||
5983 timemaybe
> timeexpire
)
5984 timemaybe
= timeexpire
;
5988 timewarn
= timemaybe
;
5989 if (timewarn
== 0 ||
5990 timewarn
> timeexpire
)
5991 timewarn
= timeexpire
;
5992 result
= offline(db
, ver
, zonediff
,
5997 result
= update_one_rr(db
, ver
, zonediff
->diff
,
5998 DNS_DIFFOP_DELRESIGN
,
6006 * If there is not a matching DNSKEY then
6010 result
= update_one_rr(db
, ver
, zonediff
->diff
,
6011 DNS_DIFFOP_DELRESIGN
, name
,
6012 rdataset
.ttl
, &rdata
);
6013 if (result
!= ISC_R_SUCCESS
)
6017 dns_rdataset_disassociate(&rdataset
);
6018 if (result
== ISC_R_NOMORE
)
6019 result
= ISC_R_SUCCESS
;
6021 #if defined(STDTIME_ON_32BITS)
6022 isc_stdtime_t stdwarn
= (isc_stdtime_t
)timewarn
;
6023 if (timewarn
== stdwarn
)
6025 set_key_expiry_warning(zone
, (isc_stdtime_t
)timewarn
,
6027 #if defined(STDTIME_ON_32BITS)
6029 dns_zone_log(zone
, ISC_LOG_ERROR
,
6030 "key expiry warning time out of range");
6035 dns_db_detachnode(db
, &node
);
6040 add_sigs(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_name_t
*name
,
6041 dns_rdatatype_t type
, dns_diff_t
*diff
, dst_key_t
**keys
,
6042 unsigned int nkeys
, isc_mem_t
*mctx
, isc_stdtime_t inception
,
6043 isc_stdtime_t expire
, isc_boolean_t check_ksk
,
6044 isc_boolean_t keyset_kskonly
)
6046 isc_result_t result
;
6047 dns_dbnode_t
*node
= NULL
;
6048 dns_rdataset_t rdataset
;
6049 dns_rdata_t sig_rdata
= DNS_RDATA_INIT
;
6050 unsigned char data
[1024]; /* XXX */
6051 isc_buffer_t buffer
;
6054 dns_rdataset_init(&rdataset
);
6055 isc_buffer_init(&buffer
, data
, sizeof(data
));
6057 if (type
== dns_rdatatype_nsec3
)
6058 result
= dns_db_findnsec3node(db
, name
, ISC_FALSE
, &node
);
6060 result
= dns_db_findnode(db
, name
, ISC_FALSE
, &node
);
6061 if (result
== ISC_R_NOTFOUND
)
6062 return (ISC_R_SUCCESS
);
6063 if (result
!= ISC_R_SUCCESS
)
6065 result
= dns_db_findrdataset(db
, node
, ver
, type
, 0,
6066 (isc_stdtime_t
) 0, &rdataset
, NULL
);
6067 dns_db_detachnode(db
, &node
);
6068 if (result
== ISC_R_NOTFOUND
) {
6069 INSIST(!dns_rdataset_isassociated(&rdataset
));
6070 return (ISC_R_SUCCESS
);
6072 if (result
!= ISC_R_SUCCESS
) {
6073 INSIST(!dns_rdataset_isassociated(&rdataset
));
6077 for (i
= 0; i
< nkeys
; i
++) {
6078 isc_boolean_t both
= ISC_FALSE
;
6080 if (!dst_key_isprivate(keys
[i
]))
6083 if (check_ksk
&& !REVOKE(keys
[i
])) {
6084 isc_boolean_t have_ksk
, have_nonksk
;
6086 have_ksk
= ISC_TRUE
;
6087 have_nonksk
= ISC_FALSE
;
6089 have_ksk
= ISC_FALSE
;
6090 have_nonksk
= ISC_TRUE
;
6092 for (j
= 0; j
< nkeys
; j
++) {
6093 if (j
== i
|| ALG(keys
[i
]) != ALG(keys
[j
]))
6095 if (REVOKE(keys
[j
]))
6098 have_ksk
= ISC_TRUE
;
6100 have_nonksk
= ISC_TRUE
;
6101 both
= have_ksk
&& have_nonksk
;
6107 if (type
== dns_rdatatype_dnskey
) {
6108 if (!KSK(keys
[i
]) && keyset_kskonly
)
6110 } else if (KSK(keys
[i
]))
6112 } else if (REVOKE(keys
[i
]) && type
!= dns_rdatatype_dnskey
)
6115 /* Calculate the signature, creating a RRSIG RDATA. */
6116 isc_buffer_clear(&buffer
);
6117 CHECK(dns_dnssec_sign(name
, &rdataset
, keys
[i
],
6118 &inception
, &expire
,
6119 mctx
, &buffer
, &sig_rdata
));
6120 /* Update the database and journal with the RRSIG. */
6121 /* XXX inefficient - will cause dataset merging */
6122 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_ADDRESIGN
,
6123 name
, rdataset
.ttl
, &sig_rdata
));
6124 dns_rdata_reset(&sig_rdata
);
6125 isc_buffer_init(&buffer
, data
, sizeof(data
));
6129 if (dns_rdataset_isassociated(&rdataset
))
6130 dns_rdataset_disassociate(&rdataset
);
6132 dns_db_detachnode(db
, &node
);
6137 zone_resigninc(dns_zone_t
*zone
) {
6138 const char *me
= "zone_resigninc";
6139 dns_db_t
*db
= NULL
;
6140 dns_dbversion_t
*version
= NULL
;
6141 dns_diff_t _sig_diff
;
6142 zonediff_t zonediff
;
6143 dns_fixedname_t fixed
;
6145 dns_rdataset_t rdataset
;
6146 dns_rdatatype_t covers
;
6147 dst_key_t
*zone_keys
[DNS_MAXZONEKEYS
];
6148 isc_boolean_t check_ksk
, keyset_kskonly
= ISC_FALSE
;
6149 isc_result_t result
;
6150 isc_stdtime_t now
, inception
, soaexpire
, expire
, stop
;
6151 isc_uint32_t jitter
;
6153 unsigned int nkeys
= 0;
6154 unsigned int resign
;
6158 dns_rdataset_init(&rdataset
);
6159 dns_fixedname_init(&fixed
);
6160 dns_diff_init(zone
->mctx
, &_sig_diff
);
6161 zonediff_init(&zonediff
, &_sig_diff
);
6164 * Zone is frozen or automatic resigning is disabled.
6165 * Pause for 5 minutes.
6167 if (zone
->update_disabled
||
6168 DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_NORESIGN
))
6170 result
= ISC_R_FAILURE
;
6174 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
6175 dns_db_attach(zone
->db
, &db
);
6176 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
6178 result
= dns_db_newversion(db
, &version
);
6179 if (result
!= ISC_R_SUCCESS
) {
6180 dns_zone_log(zone
, ISC_LOG_ERROR
,
6181 "zone_resigninc:dns_db_newversion -> %s",
6182 dns_result_totext(result
));
6186 result
= find_zone_keys(zone
, db
, version
, zone
->mctx
, DNS_MAXZONEKEYS
,
6188 if (result
!= ISC_R_SUCCESS
) {
6189 dns_zone_log(zone
, ISC_LOG_ERROR
,
6190 "zone_resigninc:find_zone_keys -> %s",
6191 dns_result_totext(result
));
6195 isc_stdtime_get(&now
);
6196 inception
= now
- 3600; /* Allow for clock skew. */
6197 soaexpire
= now
+ dns_zone_getsigvalidityinterval(zone
);
6199 * Spread out signatures over time if they happen to be
6200 * clumped. We don't do this for each add_sigs() call as
6201 * we still want some clustering to occur.
6203 isc_random_get(&jitter
);
6204 expire
= soaexpire
- jitter
% 3600;
6207 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
6208 keyset_kskonly
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
);
6210 name
= dns_fixedname_name(&fixed
);
6211 result
= dns_db_getsigningtime(db
, &rdataset
, name
);
6212 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
6213 dns_zone_log(zone
, ISC_LOG_ERROR
,
6214 "zone_resigninc:dns_db_getsigningtime -> %s",
6215 dns_result_totext(result
));
6219 while (result
== ISC_R_SUCCESS
) {
6220 resign
= rdataset
.resign
- zone
->sigresigninginterval
;
6221 covers
= rdataset
.covers
;
6222 dns_rdataset_disassociate(&rdataset
);
6225 * Stop if we hit the SOA as that means we have walked the
6226 * entire zone. The SOA record should always be the most
6229 /* XXXMPA increase number of RRsets signed pre call */
6230 if (covers
== dns_rdatatype_soa
|| i
++ > zone
->signatures
||
6234 result
= del_sigs(zone
, db
, version
, name
, covers
, &zonediff
,
6235 zone_keys
, nkeys
, now
, ISC_TRUE
);
6236 if (result
!= ISC_R_SUCCESS
) {
6237 dns_zone_log(zone
, ISC_LOG_ERROR
,
6238 "zone_resigninc:del_sigs -> %s",
6239 dns_result_totext(result
));
6243 result
= add_sigs(db
, version
, name
, covers
, zonediff
.diff
,
6244 zone_keys
, nkeys
, zone
->mctx
, inception
,
6245 expire
, check_ksk
, keyset_kskonly
);
6246 if (result
!= ISC_R_SUCCESS
) {
6247 dns_zone_log(zone
, ISC_LOG_ERROR
,
6248 "zone_resigninc:add_sigs -> %s",
6249 dns_result_totext(result
));
6252 result
= dns_db_getsigningtime(db
, &rdataset
, name
);
6253 if (nkeys
== 0 && result
== ISC_R_NOTFOUND
) {
6254 result
= ISC_R_SUCCESS
;
6257 if (result
!= ISC_R_SUCCESS
)
6258 dns_zone_log(zone
, ISC_LOG_ERROR
,
6259 "zone_resigninc:dns_db_getsigningtime -> %s",
6260 dns_result_totext(result
));
6263 if (result
!= ISC_R_NOMORE
&& result
!= ISC_R_SUCCESS
)
6266 result
= del_sigs(zone
, db
, version
, &zone
->origin
, dns_rdatatype_soa
,
6267 &zonediff
, zone_keys
, nkeys
, now
, ISC_TRUE
);
6268 if (result
!= ISC_R_SUCCESS
) {
6269 dns_zone_log(zone
, ISC_LOG_ERROR
,
6270 "zone_resigninc:del_sigs -> %s",
6271 dns_result_totext(result
));
6276 * Did we change anything in the zone?
6278 if (ISC_LIST_EMPTY(zonediff
.diff
->tuples
)) {
6280 * Commit the changes if any key has been marked as offline. */
6281 if (zonediff
.offline
)
6282 dns_db_closeversion(db
, &version
, ISC_TRUE
);
6286 /* Increment SOA serial if we have made changes */
6287 result
= update_soa_serial(db
, version
, zonediff
.diff
, zone
->mctx
,
6288 zone
->updatemethod
);
6289 if (result
!= ISC_R_SUCCESS
) {
6290 dns_zone_log(zone
, ISC_LOG_ERROR
,
6291 "zone_resigninc:update_soa_serial -> %s",
6292 dns_result_totext(result
));
6297 * Generate maximum life time signatures so that the above loop
6298 * termination is sensible.
6300 result
= add_sigs(db
, version
, &zone
->origin
, dns_rdatatype_soa
,
6301 zonediff
.diff
, zone_keys
, nkeys
, zone
->mctx
,
6302 inception
, soaexpire
, check_ksk
, keyset_kskonly
);
6303 if (result
!= ISC_R_SUCCESS
) {
6304 dns_zone_log(zone
, ISC_LOG_ERROR
,
6305 "zone_resigninc:add_sigs -> %s",
6306 dns_result_totext(result
));
6310 /* Write changes to journal file. */
6311 CHECK(zone_journal(zone
, zonediff
.diff
, NULL
, "zone_resigninc"));
6313 /* Everything has succeeded. Commit the changes. */
6314 dns_db_closeversion(db
, &version
, ISC_TRUE
);
6317 dns_diff_clear(&_sig_diff
);
6318 for (i
= 0; i
< nkeys
; i
++)
6319 dst_key_free(&zone_keys
[i
]);
6320 if (version
!= NULL
) {
6321 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
6323 } else if (db
!= NULL
)
6325 if (result
== ISC_R_SUCCESS
) {
6326 set_resigntime(zone
);
6328 zone_needdump(zone
, DNS_DUMP_DELAY
);
6329 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
6333 * Something failed. Retry in 5 minutes.
6335 isc_interval_t ival
;
6336 isc_interval_set(&ival
, 300, 0);
6337 isc_time_nowplusinterval(&zone
->resigntime
, &ival
);
6340 INSIST(version
== NULL
);
6344 next_active(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*oldname
,
6345 dns_name_t
*newname
, isc_boolean_t bottom
)
6347 isc_result_t result
;
6348 dns_dbiterator_t
*dbit
= NULL
;
6349 dns_rdatasetiter_t
*rdsit
= NULL
;
6350 dns_dbnode_t
*node
= NULL
;
6352 CHECK(dns_db_createiterator(db
, DNS_DB_NONSEC3
, &dbit
));
6353 CHECK(dns_dbiterator_seek(dbit
, oldname
));
6355 result
= dns_dbiterator_next(dbit
);
6356 if (result
== ISC_R_NOMORE
)
6357 CHECK(dns_dbiterator_first(dbit
));
6358 CHECK(dns_dbiterator_current(dbit
, &node
, newname
));
6359 if (bottom
&& dns_name_issubdomain(newname
, oldname
) &&
6360 !dns_name_equal(newname
, oldname
)) {
6361 dns_db_detachnode(db
, &node
);
6365 * Is this node empty?
6367 CHECK(dns_db_allrdatasets(db
, node
, version
, 0, &rdsit
));
6368 result
= dns_rdatasetiter_first(rdsit
);
6369 dns_db_detachnode(db
, &node
);
6370 dns_rdatasetiter_destroy(&rdsit
);
6371 if (result
!= ISC_R_NOMORE
)
6376 dns_db_detachnode(db
, &node
);
6378 dns_dbiterator_destroy(&dbit
);
6382 static isc_boolean_t
6383 signed_with_key(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
6384 dns_rdatatype_t type
, dst_key_t
*key
)
6386 isc_result_t result
;
6387 dns_rdataset_t rdataset
;
6388 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6389 dns_rdata_rrsig_t rrsig
;
6391 dns_rdataset_init(&rdataset
);
6392 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_rrsig
,
6393 type
, 0, &rdataset
, NULL
);
6394 if (result
!= ISC_R_SUCCESS
) {
6395 INSIST(!dns_rdataset_isassociated(&rdataset
));
6398 for (result
= dns_rdataset_first(&rdataset
);
6399 result
== ISC_R_SUCCESS
;
6400 result
= dns_rdataset_next(&rdataset
)) {
6401 dns_rdataset_current(&rdataset
, &rdata
);
6402 result
= dns_rdata_tostruct(&rdata
, &rrsig
, NULL
);
6403 INSIST(result
== ISC_R_SUCCESS
);
6404 if (rrsig
.algorithm
== dst_key_alg(key
) &&
6405 rrsig
.keyid
== dst_key_id(key
)) {
6406 dns_rdataset_disassociate(&rdataset
);
6409 dns_rdata_reset(&rdata
);
6411 dns_rdataset_disassociate(&rdataset
);
6416 add_nsec(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
6417 dns_dbnode_t
*node
, dns_ttl_t ttl
, isc_boolean_t bottom
,
6420 dns_fixedname_t fixed
;
6422 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6423 isc_result_t result
;
6424 unsigned char nsecbuffer
[DNS_NSEC_BUFFERSIZE
];
6426 dns_fixedname_init(&fixed
);
6427 next
= dns_fixedname_name(&fixed
);
6429 CHECK(next_active(db
, version
, name
, next
, bottom
));
6430 CHECK(dns_nsec_buildrdata(db
, version
, node
, next
, nsecbuffer
,
6432 CHECK(update_one_rr(db
, version
, diff
, DNS_DIFFOP_ADD
, name
, ttl
,
6439 sign_a_node(dns_db_t
*db
, dns_name_t
*name
, dns_dbnode_t
*node
,
6440 dns_dbversion_t
*version
, isc_boolean_t build_nsec3
,
6441 isc_boolean_t build_nsec
, dst_key_t
*key
,
6442 isc_stdtime_t inception
, isc_stdtime_t expire
,
6443 unsigned int minimum
, isc_boolean_t is_ksk
,
6444 isc_boolean_t keyset_kskonly
, isc_boolean_t
*delegation
,
6445 dns_diff_t
*diff
, isc_int32_t
*signatures
, isc_mem_t
*mctx
)
6447 isc_result_t result
;
6448 dns_rdatasetiter_t
*iterator
= NULL
;
6449 dns_rdataset_t rdataset
;
6450 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6451 isc_buffer_t buffer
;
6452 unsigned char data
[1024];
6453 isc_boolean_t seen_soa
, seen_ns
, seen_rr
, seen_dname
, seen_nsec
,
6454 seen_nsec3
, seen_ds
;
6455 isc_boolean_t bottom
;
6457 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
6458 if (result
!= ISC_R_SUCCESS
) {
6459 if (result
== ISC_R_NOTFOUND
)
6460 result
= ISC_R_SUCCESS
;
6464 dns_rdataset_init(&rdataset
);
6465 isc_buffer_init(&buffer
, data
, sizeof(data
));
6466 seen_rr
= seen_soa
= seen_ns
= seen_dname
= seen_nsec
=
6467 seen_nsec3
= seen_ds
= ISC_FALSE
;
6468 for (result
= dns_rdatasetiter_first(iterator
);
6469 result
== ISC_R_SUCCESS
;
6470 result
= dns_rdatasetiter_next(iterator
)) {
6471 dns_rdatasetiter_current(iterator
, &rdataset
);
6472 if (rdataset
.type
== dns_rdatatype_soa
)
6473 seen_soa
= ISC_TRUE
;
6474 else if (rdataset
.type
== dns_rdatatype_ns
)
6476 else if (rdataset
.type
== dns_rdatatype_ds
)
6478 else if (rdataset
.type
== dns_rdatatype_dname
)
6479 seen_dname
= ISC_TRUE
;
6480 else if (rdataset
.type
== dns_rdatatype_nsec
)
6481 seen_nsec
= ISC_TRUE
;
6482 else if (rdataset
.type
== dns_rdatatype_nsec3
)
6483 seen_nsec3
= ISC_TRUE
;
6484 if (rdataset
.type
!= dns_rdatatype_rrsig
)
6486 dns_rdataset_disassociate(&rdataset
);
6488 if (result
!= ISC_R_NOMORE
)
6490 if (seen_ns
&& !seen_soa
)
6491 *delegation
= ISC_TRUE
;
6493 * Going from insecure to NSEC3.
6494 * Don't generate NSEC3 records for NSEC3 records.
6496 if (build_nsec3
&& !seen_nsec3
&& seen_rr
) {
6497 isc_boolean_t unsecure
= !seen_ds
&& seen_ns
&& !seen_soa
;
6498 CHECK(dns_nsec3_addnsec3s(db
, version
, name
, minimum
,
6503 * Going from insecure to NSEC.
6504 * Don't generate NSEC records for NSEC3 records.
6506 if (build_nsec
&& !seen_nsec3
&& !seen_nsec
&& seen_rr
) {
6507 /* Build and add NSEC. */
6508 bottom
= (seen_ns
&& !seen_soa
) || seen_dname
;
6510 * Build a NSEC record except at the origin.
6512 if (!dns_name_equal(name
, dns_db_origin(db
))) {
6513 CHECK(add_nsec(db
, version
, name
, node
, minimum
,
6515 /* Count a NSEC generation as a signature generation. */
6519 result
= dns_rdatasetiter_first(iterator
);
6520 while (result
== ISC_R_SUCCESS
) {
6521 dns_rdatasetiter_current(iterator
, &rdataset
);
6522 if (rdataset
.type
== dns_rdatatype_soa
||
6523 rdataset
.type
== dns_rdatatype_rrsig
)
6525 if (rdataset
.type
== dns_rdatatype_dnskey
) {
6526 if (!is_ksk
&& keyset_kskonly
)
6531 rdataset
.type
!= dns_rdatatype_ds
&&
6532 rdataset
.type
!= dns_rdatatype_nsec
)
6534 if (signed_with_key(db
, node
, version
, rdataset
.type
, key
))
6536 /* Calculate the signature, creating a RRSIG RDATA. */
6537 isc_buffer_clear(&buffer
);
6538 CHECK(dns_dnssec_sign(name
, &rdataset
, key
, &inception
,
6539 &expire
, mctx
, &buffer
, &rdata
));
6540 /* Update the database and journal with the RRSIG. */
6541 /* XXX inefficient - will cause dataset merging */
6542 CHECK(update_one_rr(db
, version
, diff
, DNS_DIFFOP_ADDRESIGN
,
6543 name
, rdataset
.ttl
, &rdata
));
6544 dns_rdata_reset(&rdata
);
6547 dns_rdataset_disassociate(&rdataset
);
6548 result
= dns_rdatasetiter_next(iterator
);
6550 if (result
== ISC_R_NOMORE
)
6551 result
= ISC_R_SUCCESS
;
6553 *delegation
= ISC_TRUE
;
6555 if (dns_rdataset_isassociated(&rdataset
))
6556 dns_rdataset_disassociate(&rdataset
);
6557 if (iterator
!= NULL
)
6558 dns_rdatasetiter_destroy(&iterator
);
6563 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
6566 updatesecure(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
6567 dns_ttl_t minimum
, isc_boolean_t update_only
, dns_diff_t
*diff
)
6569 isc_result_t result
;
6570 dns_rdataset_t rdataset
;
6571 dns_dbnode_t
*node
= NULL
;
6573 CHECK(dns_db_getoriginnode(db
, &node
));
6575 dns_rdataset_init(&rdataset
);
6576 result
= dns_db_findrdataset(db
, node
, version
,
6579 0, &rdataset
, NULL
);
6580 if (dns_rdataset_isassociated(&rdataset
))
6581 dns_rdataset_disassociate(&rdataset
);
6582 if (result
== ISC_R_NOTFOUND
)
6584 if (result
!= ISC_R_SUCCESS
)
6587 CHECK(delete_nsec(db
, version
, node
, name
, diff
));
6588 CHECK(add_nsec(db
, version
, name
, node
, minimum
, ISC_FALSE
, diff
));
6590 result
= ISC_R_SUCCESS
;
6593 dns_db_detachnode(db
, &node
);
6598 updatesignwithkey(dns_zone_t
*zone
, dns_signing_t
*signing
,
6599 dns_dbversion_t
*version
, isc_boolean_t build_nsec3
,
6600 dns_ttl_t minimum
, dns_diff_t
*diff
)
6602 isc_result_t result
;
6603 dns_dbnode_t
*node
= NULL
;
6604 dns_rdataset_t rdataset
;
6605 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6606 unsigned char data
[5];
6607 isc_boolean_t seen_done
= ISC_FALSE
;
6608 isc_boolean_t have_rr
= ISC_FALSE
;
6610 dns_rdataset_init(&rdataset
);
6611 result
= dns_db_getoriginnode(signing
->db
, &node
);
6612 if (result
!= ISC_R_SUCCESS
)
6615 result
= dns_db_findrdataset(signing
->db
, node
, version
,
6616 zone
->privatetype
, dns_rdatatype_none
,
6617 0, &rdataset
, NULL
);
6618 if (result
== ISC_R_NOTFOUND
) {
6619 INSIST(!dns_rdataset_isassociated(&rdataset
));
6620 result
= ISC_R_SUCCESS
;
6623 if (result
!= ISC_R_SUCCESS
) {
6624 INSIST(!dns_rdataset_isassociated(&rdataset
));
6627 for (result
= dns_rdataset_first(&rdataset
);
6628 result
== ISC_R_SUCCESS
;
6629 result
= dns_rdataset_next(&rdataset
)) {
6630 dns_rdataset_current(&rdataset
, &rdata
);
6632 * If we don't match the algorithm or keyid skip the record.
6634 if (rdata
.length
!= 5 ||
6635 rdata
.data
[0] != signing
->algorithm
||
6636 rdata
.data
[1] != ((signing
->keyid
>> 8) & 0xff) ||
6637 rdata
.data
[2] != (signing
->keyid
& 0xff)) {
6639 dns_rdata_reset(&rdata
);
6643 * We have a match. If we were signing (!signing->delete)
6644 * and we already have a record indicating that we have
6645 * finished signing (rdata.data[4] != 0) then keep it.
6646 * Otherwise it needs to be deleted as we have removed all
6647 * the signatures (signing->delete), so any record indicating
6648 * completion is now out of date, or we have finished signing
6649 * with the new record so we no longer need to remember that
6650 * we need to sign the zone with the matching key across a
6651 * nameserver re-start.
6653 if (!signing
->delete && rdata
.data
[4] != 0) {
6654 seen_done
= ISC_TRUE
;
6657 CHECK(update_one_rr(signing
->db
, version
, diff
,
6658 DNS_DIFFOP_DEL
, &zone
->origin
,
6659 rdataset
.ttl
, &rdata
));
6660 dns_rdata_reset(&rdata
);
6662 if (result
== ISC_R_NOMORE
)
6663 result
= ISC_R_SUCCESS
;
6664 if (!signing
->delete && !seen_done
) {
6666 * If we were signing then we need to indicate that we have
6667 * finished signing the zone with this key. If it is already
6668 * there we don't need to add it a second time.
6670 data
[0] = signing
->algorithm
;
6671 data
[1] = (signing
->keyid
>> 8) & 0xff;
6672 data
[2] = signing
->keyid
& 0xff;
6675 rdata
.length
= sizeof(data
);
6677 rdata
.type
= zone
->privatetype
;
6678 rdata
.rdclass
= dns_db_class(signing
->db
);
6679 CHECK(update_one_rr(signing
->db
, version
, diff
, DNS_DIFFOP_ADD
,
6680 &zone
->origin
, rdataset
.ttl
, &rdata
));
6681 } else if (!have_rr
) {
6682 dns_name_t
*origin
= dns_db_origin(signing
->db
);
6684 * Rebuild the NSEC/NSEC3 record for the origin as we no
6685 * longer have any private records.
6688 CHECK(dns_nsec3_addnsec3s(signing
->db
, version
, origin
,
6689 minimum
, ISC_FALSE
, diff
));
6690 CHECK(updatesecure(signing
->db
, version
, origin
, minimum
,
6695 if (dns_rdataset_isassociated(&rdataset
))
6696 dns_rdataset_disassociate(&rdataset
);
6698 dns_db_detachnode(signing
->db
, &node
);
6703 * If 'active' is set then we are not done with the chain yet so only
6704 * delete the nsec3param record which indicates a full chain exists
6708 fixup_nsec3param(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_nsec3chain_t
*chain
,
6709 isc_boolean_t active
, dns_rdatatype_t privatetype
,
6712 dns_dbnode_t
*node
= NULL
;
6713 dns_name_t
*name
= dns_db_origin(db
);
6714 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6715 dns_rdataset_t rdataset
;
6716 dns_rdata_nsec3param_t nsec3param
;
6717 isc_result_t result
;
6718 isc_buffer_t buffer
;
6719 unsigned char parambuf
[DNS_NSEC3PARAM_BUFFERSIZE
];
6721 isc_boolean_t nseconly
= ISC_FALSE
, nsec3ok
= ISC_FALSE
;
6723 dns_rdataset_init(&rdataset
);
6725 result
= dns_db_getoriginnode(db
, &node
);
6726 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
6727 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec3param
,
6728 0, 0, &rdataset
, NULL
);
6729 if (result
== ISC_R_NOTFOUND
)
6731 if (result
!= ISC_R_SUCCESS
)
6735 * Preserve the existing ttl.
6740 * Delete all NSEC3PARAM records which match that in nsec3chain.
6742 for (result
= dns_rdataset_first(&rdataset
);
6743 result
== ISC_R_SUCCESS
;
6744 result
= dns_rdataset_next(&rdataset
)) {
6746 dns_rdataset_current(&rdataset
, &rdata
);
6747 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
6749 if (nsec3param
.hash
!= chain
->nsec3param
.hash
||
6750 (active
&& nsec3param
.flags
!= 0) ||
6751 nsec3param
.iterations
!= chain
->nsec3param
.iterations
||
6752 nsec3param
.salt_length
!= chain
->nsec3param
.salt_length
||
6753 memcmp(nsec3param
.salt
, chain
->nsec3param
.salt
,
6754 nsec3param
.salt_length
)) {
6755 dns_rdata_reset(&rdata
);
6759 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
,
6760 name
, rdataset
.ttl
, &rdata
));
6761 dns_rdata_reset(&rdata
);
6763 if (result
!= ISC_R_NOMORE
)
6766 dns_rdataset_disassociate(&rdataset
);
6773 result
= dns_nsec_nseconly(db
, ver
, &nseconly
);
6774 nsec3ok
= (result
== ISC_R_SUCCESS
&& !nseconly
);
6777 * Delete all private records which match that in nsec3chain.
6779 result
= dns_db_findrdataset(db
, node
, ver
, privatetype
,
6780 0, 0, &rdataset
, NULL
);
6781 if (result
== ISC_R_NOTFOUND
)
6783 if (result
!= ISC_R_SUCCESS
)
6786 for (result
= dns_rdataset_first(&rdataset
);
6787 result
== ISC_R_SUCCESS
;
6788 result
= dns_rdataset_next(&rdataset
)) {
6789 dns_rdata_t
private = DNS_RDATA_INIT
;
6790 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
6792 dns_rdataset_current(&rdataset
, &private);
6793 if (!dns_nsec3param_fromprivate(&private, &rdata
,
6796 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
6799 (nsec3param
.flags
& DNS_NSEC3FLAG_INITIAL
) != 0) ||
6800 nsec3param
.hash
!= chain
->nsec3param
.hash
||
6801 nsec3param
.iterations
!= chain
->nsec3param
.iterations
||
6802 nsec3param
.salt_length
!= chain
->nsec3param
.salt_length
||
6803 memcmp(nsec3param
.salt
, chain
->nsec3param
.salt
,
6804 nsec3param
.salt_length
)) {
6805 dns_rdata_reset(&rdata
);
6809 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
,
6810 name
, rdataset
.ttl
, &private));
6811 dns_rdata_reset(&rdata
);
6813 if (result
!= ISC_R_NOMORE
)
6817 if ((chain
->nsec3param
.flags
& DNS_NSEC3FLAG_REMOVE
) != 0) {
6818 result
= ISC_R_SUCCESS
;
6823 * Add a NSEC3PARAM record which matches that in nsec3chain but
6824 * with all flags bits cleared.
6826 * Note: we do not clear chain->nsec3param.flags as this change
6829 isc_buffer_init(&buffer
, ¶mbuf
, sizeof(parambuf
));
6830 CHECK(dns_rdata_fromstruct(&rdata
, dns_db_class(db
),
6831 dns_rdatatype_nsec3param
,
6832 &chain
->nsec3param
, &buffer
));
6833 rdata
.data
[1] = 0; /* Clear flag bits. */
6834 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_ADD
, name
, ttl
, &rdata
));
6837 dns_db_detachnode(db
, &node
);
6838 if (dns_rdataset_isassociated(&rdataset
))
6839 dns_rdataset_disassociate(&rdataset
);
6844 delete_nsec(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_dbnode_t
*node
,
6845 dns_name_t
*name
, dns_diff_t
*diff
)
6847 dns_rdataset_t rdataset
;
6848 isc_result_t result
;
6850 dns_rdataset_init(&rdataset
);
6852 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec
,
6853 0, 0, &rdataset
, NULL
);
6854 if (result
== ISC_R_NOTFOUND
)
6855 return (ISC_R_SUCCESS
);
6856 if (result
!= ISC_R_SUCCESS
)
6858 for (result
= dns_rdataset_first(&rdataset
);
6859 result
== ISC_R_SUCCESS
;
6860 result
= dns_rdataset_next(&rdataset
)) {
6861 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6863 dns_rdataset_current(&rdataset
, &rdata
);
6864 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
, name
,
6865 rdataset
.ttl
, &rdata
));
6867 if (result
== ISC_R_NOMORE
)
6868 result
= ISC_R_SUCCESS
;
6870 dns_rdataset_disassociate(&rdataset
);
6875 deletematchingnsec3(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_dbnode_t
*node
,
6876 dns_name_t
*name
, const dns_rdata_nsec3param_t
*param
,
6879 dns_rdataset_t rdataset
;
6880 dns_rdata_nsec3_t nsec3
;
6881 isc_result_t result
;
6883 dns_rdataset_init(&rdataset
);
6884 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec3
,
6885 0, 0, &rdataset
, NULL
);
6886 if (result
== ISC_R_NOTFOUND
)
6887 return (ISC_R_SUCCESS
);
6888 if (result
!= ISC_R_SUCCESS
)
6891 for (result
= dns_rdataset_first(&rdataset
);
6892 result
== ISC_R_SUCCESS
;
6893 result
= dns_rdataset_next(&rdataset
)) {
6894 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6896 dns_rdataset_current(&rdataset
, &rdata
);
6897 CHECK(dns_rdata_tostruct(&rdata
, &nsec3
, NULL
));
6898 if (nsec3
.hash
!= param
->hash
||
6899 nsec3
.iterations
!= param
->iterations
||
6900 nsec3
.salt_length
!= param
->salt_length
||
6901 memcmp(nsec3
.salt
, param
->salt
, nsec3
.salt_length
))
6903 CHECK(update_one_rr(db
, ver
, diff
, DNS_DIFFOP_DEL
, name
,
6904 rdataset
.ttl
, &rdata
));
6906 if (result
== ISC_R_NOMORE
)
6907 result
= ISC_R_SUCCESS
;
6909 dns_rdataset_disassociate(&rdataset
);
6914 need_nsec_chain(dns_db_t
*db
, dns_dbversion_t
*ver
,
6915 const dns_rdata_nsec3param_t
*param
,
6916 isc_boolean_t
*answer
)
6918 dns_dbnode_t
*node
= NULL
;
6919 dns_rdata_t rdata
= DNS_RDATA_INIT
;
6920 dns_rdata_nsec3param_t myparam
;
6921 dns_rdataset_t rdataset
;
6922 isc_result_t result
;
6924 *answer
= ISC_FALSE
;
6926 result
= dns_db_getoriginnode(db
, &node
);
6927 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
6929 dns_rdataset_init(&rdataset
);
6931 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec
,
6932 0, 0, &rdataset
, NULL
);
6933 if (result
== ISC_R_SUCCESS
) {
6934 dns_rdataset_disassociate(&rdataset
);
6935 dns_db_detachnode(db
, &node
);
6938 if (result
!= ISC_R_NOTFOUND
) {
6939 dns_db_detachnode(db
, &node
);
6943 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec3param
,
6944 0, 0, &rdataset
, NULL
);
6945 if (result
== ISC_R_NOTFOUND
) {
6947 dns_db_detachnode(db
, &node
);
6948 return (ISC_R_SUCCESS
);
6950 if (result
!= ISC_R_SUCCESS
) {
6951 dns_db_detachnode(db
, &node
);
6955 for (result
= dns_rdataset_first(&rdataset
);
6956 result
== ISC_R_SUCCESS
;
6957 result
= dns_rdataset_next(&rdataset
)) {
6958 dns_rdataset_current(&rdataset
, &rdata
);
6959 CHECK(dns_rdata_tostruct(&rdata
, &myparam
, NULL
));
6960 dns_rdata_reset(&rdata
);
6962 * Ignore any NSEC3PARAM removals.
6964 if (NSEC3REMOVE(myparam
.flags
))
6967 * Ignore the chain that we are in the process of deleting.
6969 if (myparam
.hash
== param
->hash
&&
6970 myparam
.iterations
== param
->iterations
&&
6971 myparam
.salt_length
== param
->salt_length
&&
6972 !memcmp(myparam
.salt
, param
->salt
, myparam
.salt_length
))
6975 * Found an active NSEC3 chain.
6979 if (result
== ISC_R_NOMORE
) {
6981 result
= ISC_R_SUCCESS
;
6985 if (dns_rdataset_isassociated(&rdataset
))
6986 dns_rdataset_disassociate(&rdataset
);
6987 dns_db_detachnode(db
, &node
);
6992 update_sigs(dns_diff_t
*diff
, dns_db_t
*db
, dns_dbversion_t
*version
,
6993 dst_key_t
*zone_keys
[], unsigned int nkeys
, dns_zone_t
*zone
,
6994 isc_stdtime_t inception
, isc_stdtime_t expire
, isc_stdtime_t now
,
6995 isc_boolean_t check_ksk
, isc_boolean_t keyset_kskonly
,
6996 zonediff_t
*zonediff
)
6998 dns_difftuple_t
*tuple
;
6999 isc_result_t result
;
7001 for (tuple
= ISC_LIST_HEAD(diff
->tuples
);
7003 tuple
= ISC_LIST_HEAD(diff
->tuples
)) {
7004 result
= del_sigs(zone
, db
, version
, &tuple
->name
,
7005 tuple
->rdata
.type
, zonediff
,
7006 zone_keys
, nkeys
, now
, ISC_FALSE
);
7007 if (result
!= ISC_R_SUCCESS
) {
7008 dns_zone_log(zone
, ISC_LOG_ERROR
,
7009 "update_sigs:del_sigs -> %s",
7010 dns_result_totext(result
));
7013 result
= add_sigs(db
, version
, &tuple
->name
,
7014 tuple
->rdata
.type
, zonediff
->diff
,
7015 zone_keys
, nkeys
, zone
->mctx
, inception
,
7016 expire
, check_ksk
, keyset_kskonly
);
7017 if (result
!= ISC_R_SUCCESS
) {
7018 dns_zone_log(zone
, ISC_LOG_ERROR
,
7019 "update_sigs:add_sigs -> %s",
7020 dns_result_totext(result
));
7025 dns_difftuple_t
*next
= ISC_LIST_NEXT(tuple
, link
);
7026 while (next
!= NULL
&&
7027 (tuple
->rdata
.type
!= next
->rdata
.type
||
7028 !dns_name_equal(&tuple
->name
, &next
->name
)))
7029 next
= ISC_LIST_NEXT(next
, link
);
7030 ISC_LIST_UNLINK(diff
->tuples
, tuple
, link
);
7031 dns_diff_appendminimal(zonediff
->diff
, &tuple
);
7032 INSIST(tuple
== NULL
);
7034 } while (tuple
!= NULL
);
7036 return (ISC_R_SUCCESS
);
7040 * Incrementally build and sign a new NSEC3 chain using the parameters
7044 zone_nsec3chain(dns_zone_t
*zone
) {
7045 const char *me
= "zone_nsec3chain";
7046 dns_db_t
*db
= NULL
;
7047 dns_dbnode_t
*node
= NULL
;
7048 dns_dbversion_t
*version
= NULL
;
7049 dns_diff_t _sig_diff
;
7050 dns_diff_t nsec_diff
;
7051 dns_diff_t nsec3_diff
;
7052 dns_diff_t param_diff
;
7053 zonediff_t zonediff
;
7054 dns_fixedname_t fixed
;
7055 dns_fixedname_t nextfixed
;
7056 dns_name_t
*name
, *nextname
;
7057 dns_rdataset_t rdataset
;
7058 dns_nsec3chain_t
*nsec3chain
= NULL
, *nextnsec3chain
;
7059 dns_nsec3chainlist_t cleanup
;
7060 dst_key_t
*zone_keys
[DNS_MAXZONEKEYS
];
7061 isc_int32_t signatures
;
7062 isc_boolean_t check_ksk
, keyset_kskonly
;
7063 isc_boolean_t delegation
;
7064 isc_boolean_t first
;
7065 isc_result_t result
;
7066 isc_stdtime_t now
, inception
, soaexpire
, expire
;
7067 isc_uint32_t jitter
;
7069 unsigned int nkeys
= 0;
7071 isc_boolean_t unsecure
= ISC_FALSE
;
7072 isc_boolean_t seen_soa
, seen_ns
, seen_dname
, seen_ds
;
7073 isc_boolean_t seen_nsec
, seen_nsec3
, seen_rr
;
7074 dns_rdatasetiter_t
*iterator
= NULL
;
7075 isc_boolean_t buildnsecchain
;
7076 isc_boolean_t updatensec
= ISC_FALSE
;
7077 dns_rdatatype_t privatetype
= zone
->privatetype
;
7081 dns_rdataset_init(&rdataset
);
7082 dns_fixedname_init(&fixed
);
7083 name
= dns_fixedname_name(&fixed
);
7084 dns_fixedname_init(&nextfixed
);
7085 nextname
= dns_fixedname_name(&nextfixed
);
7086 dns_diff_init(zone
->mctx
, ¶m_diff
);
7087 dns_diff_init(zone
->mctx
, &nsec3_diff
);
7088 dns_diff_init(zone
->mctx
, &nsec_diff
);
7089 dns_diff_init(zone
->mctx
, &_sig_diff
);
7090 zonediff_init(&zonediff
, &_sig_diff
);
7091 ISC_LIST_INIT(cleanup
);
7094 * Updates are disabled. Pause for 5 minutes.
7096 if (zone
->update_disabled
) {
7097 result
= ISC_R_FAILURE
;
7101 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
7102 dns_db_attach(zone
->db
, &db
);
7103 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
7105 result
= dns_db_newversion(db
, &version
);
7106 if (result
!= ISC_R_SUCCESS
) {
7107 dns_zone_log(zone
, ISC_LOG_ERROR
,
7108 "zone_nsec3chain:dns_db_newversion -> %s",
7109 dns_result_totext(result
));
7113 result
= find_zone_keys(zone
, db
, version
, zone
->mctx
,
7114 DNS_MAXZONEKEYS
, zone_keys
, &nkeys
);
7115 if (result
!= ISC_R_SUCCESS
) {
7116 dns_zone_log(zone
, ISC_LOG_ERROR
,
7117 "zone_nsec3chain:find_zone_keys -> %s",
7118 dns_result_totext(result
));
7122 isc_stdtime_get(&now
);
7123 inception
= now
- 3600; /* Allow for clock skew. */
7124 soaexpire
= now
+ dns_zone_getsigvalidityinterval(zone
);
7127 * Spread out signatures over time if they happen to be
7128 * clumped. We don't do this for each add_sigs() call as
7129 * we still want some clustering to occur.
7131 isc_random_get(&jitter
);
7132 expire
= soaexpire
- jitter
% 3600;
7134 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
7135 keyset_kskonly
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
);
7138 * We keep pulling nodes off each iterator in turn until
7139 * we have no more nodes to pull off or we reach the limits
7142 nodes
= zone
->nodes
;
7143 signatures
= zone
->signatures
;
7145 nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
7149 if (nsec3chain
!= NULL
)
7150 nsec3chain
->save_delete_nsec
= nsec3chain
->delete_nsec
;
7152 * Generate new NSEC3 chains first.
7154 while (nsec3chain
!= NULL
&& nodes
-- > 0 && signatures
> 0) {
7156 nextnsec3chain
= ISC_LIST_NEXT(nsec3chain
, link
);
7158 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
7159 if (nsec3chain
->done
|| nsec3chain
->db
!= zone
->db
) {
7160 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
, link
);
7161 ISC_LIST_APPEND(cleanup
, nsec3chain
, link
);
7163 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
7165 if (ISC_LIST_TAIL(cleanup
) == nsec3chain
)
7169 * Possible future db.
7171 if (nsec3chain
->db
!= db
) {
7175 if (NSEC3REMOVE(nsec3chain
->nsec3param
.flags
))
7178 dns_dbiterator_current(nsec3chain
->dbiterator
, &node
, name
);
7180 if (nsec3chain
->delete_nsec
) {
7181 delegation
= ISC_FALSE
;
7182 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7183 CHECK(delete_nsec(db
, version
, node
, name
, &nsec_diff
));
7187 * On the first pass we need to check if the current node
7188 * has not been obscured.
7190 delegation
= ISC_FALSE
;
7191 unsecure
= ISC_FALSE
;
7193 dns_fixedname_t ffound
;
7195 dns_fixedname_init(&ffound
);
7196 found
= dns_fixedname_name(&ffound
);
7197 result
= dns_db_find(db
, name
, version
,
7199 DNS_DBFIND_NOWILD
, 0, NULL
, found
,
7201 if ((result
== DNS_R_DELEGATION
||
7202 result
== DNS_R_DNAME
) &&
7203 !dns_name_equal(name
, found
)) {
7205 * Remember the obscuring name so that
7206 * we skip all obscured names.
7208 dns_name_copy(found
, name
, NULL
);
7209 delegation
= ISC_TRUE
;
7215 * Check to see if this is a bottom of zone node.
7217 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
7218 if (result
== ISC_R_NOTFOUND
) /* Empty node? */
7220 if (result
!= ISC_R_SUCCESS
)
7223 seen_soa
= seen_ns
= seen_dname
= seen_ds
= seen_nsec
=
7225 for (result
= dns_rdatasetiter_first(iterator
);
7226 result
== ISC_R_SUCCESS
;
7227 result
= dns_rdatasetiter_next(iterator
)) {
7228 dns_rdatasetiter_current(iterator
, &rdataset
);
7229 INSIST(rdataset
.type
!= dns_rdatatype_nsec3
);
7230 if (rdataset
.type
== dns_rdatatype_soa
)
7231 seen_soa
= ISC_TRUE
;
7232 else if (rdataset
.type
== dns_rdatatype_ns
)
7234 else if (rdataset
.type
== dns_rdatatype_dname
)
7235 seen_dname
= ISC_TRUE
;
7236 else if (rdataset
.type
== dns_rdatatype_ds
)
7238 else if (rdataset
.type
== dns_rdatatype_nsec
)
7239 seen_nsec
= ISC_TRUE
;
7240 dns_rdataset_disassociate(&rdataset
);
7242 dns_rdatasetiter_destroy(&iterator
);
7244 * Is there a NSEC chain than needs to be cleaned up?
7247 nsec3chain
->seen_nsec
= ISC_TRUE
;
7248 if (seen_ns
&& !seen_soa
&& !seen_ds
)
7249 unsecure
= ISC_TRUE
;
7250 if ((seen_ns
&& !seen_soa
) || seen_dname
)
7251 delegation
= ISC_TRUE
;
7256 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7257 result
= dns_nsec3_addnsec3(db
, version
, name
,
7258 &nsec3chain
->nsec3param
,
7259 zone
->minimum
, unsecure
,
7261 if (result
!= ISC_R_SUCCESS
) {
7262 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7263 "dns_nsec3_addnsec3 -> %s",
7264 dns_result_totext(result
));
7269 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
7270 * two signatures. Additionally there will, in general, be
7271 * two signature generated below.
7273 * If we are only changing the optout flag the cost is half
7274 * that of the cost of generating a completely new chain.
7279 * Go onto next node.
7283 dns_db_detachnode(db
, &node
);
7285 result
= dns_dbiterator_next(nsec3chain
->dbiterator
);
7287 if (result
== ISC_R_NOMORE
&& nsec3chain
->delete_nsec
) {
7288 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7289 CHECK(fixup_nsec3param(db
, version
, nsec3chain
,
7290 ISC_FALSE
, privatetype
,
7293 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
,
7296 ISC_LIST_APPEND(cleanup
, nsec3chain
, link
);
7299 if (result
== ISC_R_NOMORE
) {
7300 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7301 if (nsec3chain
->seen_nsec
) {
7302 CHECK(fixup_nsec3param(db
, version
,
7307 nsec3chain
->delete_nsec
= ISC_TRUE
;
7310 CHECK(fixup_nsec3param(db
, version
, nsec3chain
,
7311 ISC_FALSE
, privatetype
,
7314 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
,
7317 ISC_LIST_APPEND(cleanup
, nsec3chain
, link
);
7319 } else if (result
!= ISC_R_SUCCESS
) {
7320 dns_zone_log(zone
, ISC_LOG_ERROR
,
7322 "dns_dbiterator_next -> %s",
7323 dns_result_totext(result
));
7325 } else if (delegation
) {
7326 dns_dbiterator_current(nsec3chain
->dbiterator
,
7328 dns_db_detachnode(db
, &node
);
7329 if (!dns_name_issubdomain(nextname
, name
))
7337 CHECK(dns_dbiterator_first(nsec3chain
->dbiterator
));
7342 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7343 nsec3chain
= nextnsec3chain
;
7345 if (nsec3chain
!= NULL
)
7346 nsec3chain
->save_delete_nsec
= nsec3chain
->delete_nsec
;
7353 nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
7356 buildnsecchain
= ISC_FALSE
;
7357 while (nsec3chain
!= NULL
&& nodes
-- > 0 && signatures
> 0) {
7359 nextnsec3chain
= ISC_LIST_NEXT(nsec3chain
, link
);
7362 if (nsec3chain
->db
!= db
)
7363 goto next_removechain
;
7365 if (!NSEC3REMOVE(nsec3chain
->nsec3param
.flags
))
7366 goto next_removechain
;
7369 * Work out if we need to build a NSEC chain as a consequence
7370 * of removing this NSEC3 chain.
7372 if (first
&& !updatensec
&&
7373 (nsec3chain
->nsec3param
.flags
& DNS_NSEC3FLAG_NONSEC
) == 0)
7375 result
= need_nsec_chain(db
, version
,
7376 &nsec3chain
->nsec3param
,
7378 if (result
!= ISC_R_SUCCESS
) {
7379 dns_zone_log(zone
, ISC_LOG_ERROR
,
7381 "need_nsec_chain -> %s",
7382 dns_result_totext(result
));
7388 dns_zone_log(zone
, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
7389 "buildnsecchain = %u\n", buildnsecchain
);
7391 dns_dbiterator_current(nsec3chain
->dbiterator
, &node
, name
);
7392 delegation
= ISC_FALSE
;
7394 if (!buildnsecchain
) {
7396 * Delete the NSECPARAM record that matches this chain.
7399 result
= fixup_nsec3param(db
, version
,
7401 ISC_TRUE
, privatetype
,
7403 if (result
!= ISC_R_SUCCESS
) {
7404 dns_zone_log(zone
, ISC_LOG_ERROR
,
7406 "fixup_nsec3param -> %s",
7407 dns_result_totext(result
));
7413 * Delete the NSEC3 records.
7415 result
= deletematchingnsec3(db
, version
, node
, name
,
7416 &nsec3chain
->nsec3param
,
7418 if (result
!= ISC_R_SUCCESS
) {
7419 dns_zone_log(zone
, ISC_LOG_ERROR
,
7421 "deletematchingnsec3 -> %s",
7422 dns_result_totext(result
));
7425 goto next_removenode
;
7429 dns_fixedname_t ffound
;
7431 dns_fixedname_init(&ffound
);
7432 found
= dns_fixedname_name(&ffound
);
7433 result
= dns_db_find(db
, name
, version
,
7435 DNS_DBFIND_NOWILD
, 0, NULL
, found
,
7437 if ((result
== DNS_R_DELEGATION
||
7438 result
== DNS_R_DNAME
) &&
7439 !dns_name_equal(name
, found
)) {
7441 * Remember the obscuring name so that
7442 * we skip all obscured names.
7444 dns_name_copy(found
, name
, NULL
);
7445 delegation
= ISC_TRUE
;
7446 goto next_removenode
;
7451 * Check to see if this is a bottom of zone node.
7453 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
7454 if (result
== ISC_R_NOTFOUND
) /* Empty node? */
7455 goto next_removenode
;
7456 if (result
!= ISC_R_SUCCESS
)
7459 seen_soa
= seen_ns
= seen_dname
= seen_nsec3
= seen_nsec
=
7460 seen_rr
= ISC_FALSE
;
7461 for (result
= dns_rdatasetiter_first(iterator
);
7462 result
== ISC_R_SUCCESS
;
7463 result
= dns_rdatasetiter_next(iterator
)) {
7464 dns_rdatasetiter_current(iterator
, &rdataset
);
7465 if (rdataset
.type
== dns_rdatatype_soa
)
7466 seen_soa
= ISC_TRUE
;
7467 else if (rdataset
.type
== dns_rdatatype_ns
)
7469 else if (rdataset
.type
== dns_rdatatype_dname
)
7470 seen_dname
= ISC_TRUE
;
7471 else if (rdataset
.type
== dns_rdatatype_nsec
)
7472 seen_nsec
= ISC_TRUE
;
7473 else if (rdataset
.type
== dns_rdatatype_nsec3
)
7474 seen_nsec3
= ISC_TRUE
;
7475 if (rdataset
.type
!= dns_rdatatype_rrsig
)
7477 dns_rdataset_disassociate(&rdataset
);
7479 dns_rdatasetiter_destroy(&iterator
);
7481 if (!seen_rr
|| seen_nsec3
|| seen_nsec
)
7482 goto next_removenode
;
7483 if ((seen_ns
&& !seen_soa
) || seen_dname
)
7484 delegation
= ISC_TRUE
;
7487 * Add a NSEC record except at the origin.
7489 if (!dns_name_equal(name
, dns_db_origin(db
))) {
7490 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7491 CHECK(add_nsec(db
, version
, name
, node
, zone
->minimum
,
7492 delegation
, &nsec_diff
));
7497 dns_db_detachnode(db
, &node
);
7499 result
= dns_dbiterator_next(nsec3chain
->dbiterator
);
7500 if (result
== ISC_R_NOMORE
&& buildnsecchain
) {
7502 * The NSEC chain should now be built.
7503 * We can now remove the NSEC3 chain.
7505 updatensec
= ISC_TRUE
;
7506 goto same_removechain
;
7508 if (result
== ISC_R_NOMORE
) {
7510 ISC_LIST_UNLINK(zone
->nsec3chain
, nsec3chain
,
7513 ISC_LIST_APPEND(cleanup
, nsec3chain
, link
);
7514 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7515 result
= fixup_nsec3param(db
, version
,
7516 nsec3chain
, ISC_FALSE
,
7519 if (result
!= ISC_R_SUCCESS
) {
7520 dns_zone_log(zone
, ISC_LOG_ERROR
,
7522 "fixup_nsec3param -> %s",
7523 dns_result_totext(result
));
7526 goto next_removechain
;
7527 } else if (result
!= ISC_R_SUCCESS
) {
7528 dns_zone_log(zone
, ISC_LOG_ERROR
,
7530 "dns_dbiterator_next -> %s",
7531 dns_result_totext(result
));
7533 } else if (delegation
) {
7534 dns_dbiterator_current(nsec3chain
->dbiterator
,
7536 dns_db_detachnode(db
, &node
);
7537 if (!dns_name_issubdomain(nextname
, name
))
7545 CHECK(dns_dbiterator_first(nsec3chain
->dbiterator
));
7546 buildnsecchain
= ISC_FALSE
;
7551 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7552 nsec3chain
= nextnsec3chain
;
7557 * We may need to update the NSEC/NSEC3 records for the zone apex.
7559 if (!ISC_LIST_EMPTY(param_diff
.tuples
)) {
7560 isc_boolean_t rebuild_nsec
= ISC_FALSE
,
7561 rebuild_nsec3
= ISC_FALSE
;
7562 result
= dns_db_getoriginnode(db
, &node
);
7563 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
7564 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
7565 if (result
!= ISC_R_SUCCESS
) {
7566 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7567 "dns_db_allrdatasets -> %s",
7568 dns_result_totext(result
));
7571 for (result
= dns_rdatasetiter_first(iterator
);
7572 result
== ISC_R_SUCCESS
;
7573 result
= dns_rdatasetiter_next(iterator
)) {
7574 dns_rdatasetiter_current(iterator
, &rdataset
);
7575 if (rdataset
.type
== dns_rdatatype_nsec
)
7576 rebuild_nsec
= ISC_TRUE
;
7577 if (rdataset
.type
== dns_rdatatype_nsec3param
)
7578 rebuild_nsec3
= ISC_TRUE
;
7579 dns_rdataset_disassociate(&rdataset
);
7581 dns_rdatasetiter_destroy(&iterator
);
7582 dns_db_detachnode(db
, &node
);
7585 if (nsec3chain
!= NULL
)
7586 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7588 result
= updatesecure(db
, version
, &zone
->origin
,
7589 zone
->minimum
, ISC_TRUE
,
7591 if (result
!= ISC_R_SUCCESS
) {
7592 dns_zone_log(zone
, ISC_LOG_ERROR
,
7594 "updatesecure -> %s",
7595 dns_result_totext(result
));
7600 if (rebuild_nsec3
) {
7601 if (nsec3chain
!= NULL
)
7602 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7604 result
= dns_nsec3_addnsec3s(db
, version
,
7606 zone
->minimum
, ISC_FALSE
,
7608 if (result
!= ISC_R_SUCCESS
) {
7609 dns_zone_log(zone
, ISC_LOG_ERROR
,
7611 "dns_nsec3_addnsec3s -> %s",
7612 dns_result_totext(result
));
7618 if (nsec3chain
!= NULL
)
7619 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7622 * Add / update signatures for the NSEC3 records.
7624 if (nsec3chain
!= NULL
)
7625 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7626 result
= update_sigs(&nsec3_diff
, db
, version
, zone_keys
,
7627 nkeys
, zone
, inception
, expire
, now
,
7628 check_ksk
, keyset_kskonly
, &zonediff
);
7629 if (result
!= ISC_R_SUCCESS
) {
7630 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7631 "update_sigs -> %s", dns_result_totext(result
));
7636 * We have changed the NSEC3PARAM or private RRsets
7637 * above so we need to update the signatures.
7639 result
= update_sigs(¶m_diff
, db
, version
, zone_keys
,
7640 nkeys
, zone
, inception
, expire
, now
,
7641 check_ksk
, keyset_kskonly
, &zonediff
);
7642 if (result
!= ISC_R_SUCCESS
) {
7643 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7644 "update_sigs -> %s", dns_result_totext(result
));
7649 result
= updatesecure(db
, version
, &zone
->origin
,
7650 zone
->minimum
, ISC_FALSE
, &nsec_diff
);
7651 if (result
!= ISC_R_SUCCESS
) {
7652 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7653 "updatesecure -> %s",
7654 dns_result_totext(result
));
7659 result
= update_sigs(&nsec_diff
, db
, version
, zone_keys
,
7660 nkeys
, zone
, inception
, expire
, now
,
7661 check_ksk
, keyset_kskonly
, &zonediff
);
7662 if (result
!= ISC_R_SUCCESS
) {
7663 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7664 "update_sigs -> %s", dns_result_totext(result
));
7669 * If we made no effective changes to the zone then we can just
7670 * cleanup otherwise we need to increment the serial.
7672 if (ISC_LIST_EMPTY(zonediff
.diff
->tuples
)) {
7674 * No need to call dns_db_closeversion() here as it is
7675 * called with commit = ISC_TRUE below.
7680 result
= del_sigs(zone
, db
, version
, &zone
->origin
, dns_rdatatype_soa
,
7681 &zonediff
, zone_keys
, nkeys
, now
, ISC_FALSE
);
7682 if (result
!= ISC_R_SUCCESS
) {
7683 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7684 "del_sigs -> %s", dns_result_totext(result
));
7688 result
= update_soa_serial(db
, version
, zonediff
.diff
, zone
->mctx
,
7689 zone
->updatemethod
);
7690 if (result
!= ISC_R_SUCCESS
) {
7691 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7692 "update_soa_serial -> %s",
7693 dns_result_totext(result
));
7697 result
= add_sigs(db
, version
, &zone
->origin
, dns_rdatatype_soa
,
7698 zonediff
.diff
, zone_keys
, nkeys
, zone
->mctx
,
7699 inception
, soaexpire
, check_ksk
, keyset_kskonly
);
7700 if (result
!= ISC_R_SUCCESS
) {
7701 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain:"
7702 "add_sigs -> %s", dns_result_totext(result
));
7706 /* Write changes to journal file. */
7707 CHECK(zone_journal(zone
, zonediff
.diff
, NULL
, "zone_nsec3chain"));
7710 zone_needdump(zone
, DNS_DUMP_DELAY
);
7711 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
7716 * Pause all iterators so that dns_db_closeversion() can succeed.
7719 for (nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
7721 nsec3chain
= ISC_LIST_NEXT(nsec3chain
, link
))
7722 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7726 * Everything has succeeded. Commit the changes.
7727 * Unconditionally commit as zonediff.offline not checked above.
7729 dns_db_closeversion(db
, &version
, ISC_TRUE
);
7732 * Everything succeeded so we can clean these up now.
7734 nsec3chain
= ISC_LIST_HEAD(cleanup
);
7735 while (nsec3chain
!= NULL
) {
7736 ISC_LIST_UNLINK(cleanup
, nsec3chain
, link
);
7737 dns_db_detach(&nsec3chain
->db
);
7738 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
7739 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
7740 nsec3chain
= ISC_LIST_HEAD(cleanup
);
7743 set_resigntime(zone
);
7746 if (result
!= ISC_R_SUCCESS
)
7747 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_nsec3chain: %s",
7748 dns_result_totext(result
));
7750 * On error roll back the current nsec3chain.
7752 if (result
!= ISC_R_SUCCESS
&& nsec3chain
!= NULL
) {
7753 if (nsec3chain
->done
) {
7754 dns_db_detach(&nsec3chain
->db
);
7755 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
7756 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
7758 result
= dns_dbiterator_first(nsec3chain
->dbiterator
);
7759 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
7760 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7761 nsec3chain
->delete_nsec
= nsec3chain
->save_delete_nsec
;
7766 * Rollback the cleanup list.
7768 nsec3chain
= ISC_LIST_TAIL(cleanup
);
7769 while (nsec3chain
!= NULL
) {
7770 ISC_LIST_UNLINK(cleanup
, nsec3chain
, link
);
7771 if (nsec3chain
->done
) {
7772 dns_db_detach(&nsec3chain
->db
);
7773 dns_dbiterator_destroy(&nsec3chain
->dbiterator
);
7774 isc_mem_put(zone
->mctx
, nsec3chain
, sizeof *nsec3chain
);
7777 ISC_LIST_PREPEND(zone
->nsec3chain
, nsec3chain
, link
);
7779 result
= dns_dbiterator_first(nsec3chain
->dbiterator
);
7780 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
7781 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7782 nsec3chain
->delete_nsec
= nsec3chain
->save_delete_nsec
;
7784 nsec3chain
= ISC_LIST_TAIL(cleanup
);
7788 for (nsec3chain
= ISC_LIST_HEAD(zone
->nsec3chain
);
7790 nsec3chain
= ISC_LIST_NEXT(nsec3chain
, link
))
7791 dns_dbiterator_pause(nsec3chain
->dbiterator
);
7794 dns_diff_clear(¶m_diff
);
7795 dns_diff_clear(&nsec3_diff
);
7796 dns_diff_clear(&nsec_diff
);
7797 dns_diff_clear(&_sig_diff
);
7799 if (iterator
!= NULL
)
7800 dns_rdatasetiter_destroy(&iterator
);
7802 for (i
= 0; i
< nkeys
; i
++)
7803 dst_key_free(&zone_keys
[i
]);
7806 dns_db_detachnode(db
, &node
);
7807 if (version
!= NULL
) {
7808 dns_db_closeversion(db
, &version
, ISC_FALSE
);
7810 } else if (db
!= NULL
)
7814 if (ISC_LIST_HEAD(zone
->nsec3chain
) != NULL
) {
7815 isc_interval_t interval
;
7816 if (zone
->update_disabled
|| result
!= ISC_R_SUCCESS
)
7817 isc_interval_set(&interval
, 60, 0); /* 1 minute */
7819 isc_interval_set(&interval
, 0, 10000000); /* 10 ms */
7820 isc_time_nowplusinterval(&zone
->nsec3chaintime
, &interval
);
7822 isc_time_settoepoch(&zone
->nsec3chaintime
);
7825 INSIST(version
== NULL
);
7829 del_sig(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
7830 dns_dbnode_t
*node
, unsigned int nkeys
, dns_secalg_t algorithm
,
7831 isc_uint16_t keyid
, dns_diff_t
*diff
)
7833 dns_rdata_rrsig_t rrsig
;
7834 dns_rdataset_t rdataset
;
7835 dns_rdatasetiter_t
*iterator
= NULL
;
7836 isc_result_t result
;
7838 result
= dns_db_allrdatasets(db
, node
, version
, 0, &iterator
);
7839 if (result
!= ISC_R_SUCCESS
) {
7840 if (result
== ISC_R_NOTFOUND
)
7841 result
= ISC_R_SUCCESS
;
7845 dns_rdataset_init(&rdataset
);
7846 for (result
= dns_rdatasetiter_first(iterator
);
7847 result
== ISC_R_SUCCESS
;
7848 result
= dns_rdatasetiter_next(iterator
)) {
7849 dns_rdatasetiter_current(iterator
, &rdataset
);
7850 if (nkeys
== 0 && rdataset
.type
== dns_rdatatype_nsec
) {
7851 for (result
= dns_rdataset_first(&rdataset
);
7852 result
== ISC_R_SUCCESS
;
7853 result
= dns_rdataset_next(&rdataset
)) {
7854 dns_rdata_t rdata
= DNS_RDATA_INIT
;
7855 dns_rdataset_current(&rdataset
, &rdata
);
7856 CHECK(update_one_rr(db
, version
, diff
,
7857 DNS_DIFFOP_DEL
, name
,
7858 rdataset
.ttl
, &rdata
));
7860 if (result
!= ISC_R_NOMORE
)
7862 dns_rdataset_disassociate(&rdataset
);
7865 if (rdataset
.type
!= dns_rdatatype_rrsig
) {
7866 dns_rdataset_disassociate(&rdataset
);
7869 for (result
= dns_rdataset_first(&rdataset
);
7870 result
== ISC_R_SUCCESS
;
7871 result
= dns_rdataset_next(&rdataset
)) {
7872 dns_rdata_t rdata
= DNS_RDATA_INIT
;
7873 dns_rdataset_current(&rdataset
, &rdata
);
7874 CHECK(dns_rdata_tostruct(&rdata
, &rrsig
, NULL
));
7875 if (rrsig
.algorithm
!= algorithm
||
7876 rrsig
.keyid
!= keyid
)
7878 CHECK(update_one_rr(db
, version
, diff
,
7879 DNS_DIFFOP_DELRESIGN
, name
,
7880 rdataset
.ttl
, &rdata
));
7882 dns_rdataset_disassociate(&rdataset
);
7883 if (result
!= ISC_R_NOMORE
)
7886 if (result
== ISC_R_NOMORE
)
7887 result
= ISC_R_SUCCESS
;
7889 if (dns_rdataset_isassociated(&rdataset
))
7890 dns_rdataset_disassociate(&rdataset
);
7891 dns_rdatasetiter_destroy(&iterator
);
7896 * Incrementally sign the zone using the keys requested.
7897 * Builds the NSEC chain if required.
7900 zone_sign(dns_zone_t
*zone
) {
7901 const char *me
= "zone_sign";
7902 dns_db_t
*db
= NULL
;
7903 dns_dbnode_t
*node
= NULL
;
7904 dns_dbversion_t
*version
= NULL
;
7905 dns_diff_t _sig_diff
;
7906 dns_diff_t post_diff
;
7907 zonediff_t zonediff
;
7908 dns_fixedname_t fixed
;
7909 dns_fixedname_t nextfixed
;
7910 dns_name_t
*name
, *nextname
;
7911 dns_rdataset_t rdataset
;
7912 dns_signing_t
*signing
, *nextsigning
;
7913 dns_signinglist_t cleanup
;
7914 dst_key_t
*zone_keys
[DNS_MAXZONEKEYS
];
7915 isc_int32_t signatures
;
7916 isc_boolean_t check_ksk
, keyset_kskonly
, is_ksk
;
7917 isc_boolean_t commit
= ISC_FALSE
;
7918 isc_boolean_t delegation
;
7919 isc_boolean_t build_nsec
= ISC_FALSE
;
7920 isc_boolean_t build_nsec3
= ISC_FALSE
;
7921 isc_boolean_t first
;
7922 isc_result_t result
;
7923 isc_stdtime_t now
, inception
, soaexpire
, expire
;
7924 isc_uint32_t jitter
;
7926 unsigned int nkeys
= 0;
7931 dns_rdataset_init(&rdataset
);
7932 dns_fixedname_init(&fixed
);
7933 name
= dns_fixedname_name(&fixed
);
7934 dns_fixedname_init(&nextfixed
);
7935 nextname
= dns_fixedname_name(&nextfixed
);
7936 dns_diff_init(zone
->mctx
, &_sig_diff
);
7937 dns_diff_init(zone
->mctx
, &post_diff
);
7938 zonediff_init(&zonediff
, &_sig_diff
);
7939 ISC_LIST_INIT(cleanup
);
7942 * Updates are disabled. Pause for 5 minutes.
7944 if (zone
->update_disabled
) {
7945 result
= ISC_R_FAILURE
;
7949 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
7950 if (zone
->db
!= NULL
)
7951 dns_db_attach(zone
->db
, &db
);
7952 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
7954 result
= ISC_R_FAILURE
;
7958 result
= dns_db_newversion(db
, &version
);
7959 if (result
!= ISC_R_SUCCESS
) {
7960 dns_zone_log(zone
, ISC_LOG_ERROR
,
7961 "zone_sign:dns_db_newversion -> %s",
7962 dns_result_totext(result
));
7966 result
= find_zone_keys(zone
, db
, version
, zone
->mctx
,
7967 DNS_MAXZONEKEYS
, zone_keys
, &nkeys
);
7968 if (result
!= ISC_R_SUCCESS
) {
7969 dns_zone_log(zone
, ISC_LOG_ERROR
,
7970 "zone_sign:find_zone_keys -> %s",
7971 dns_result_totext(result
));
7975 isc_stdtime_get(&now
);
7976 inception
= now
- 3600; /* Allow for clock skew. */
7977 soaexpire
= now
+ dns_zone_getsigvalidityinterval(zone
);
7980 * Spread out signatures over time if they happen to be
7981 * clumped. We don't do this for each add_sigs() call as
7982 * we still want some clustering to occur.
7984 isc_random_get(&jitter
);
7985 expire
= soaexpire
- jitter
% 3600;
7988 * We keep pulling nodes off each iterator in turn until
7989 * we have no more nodes to pull off or we reach the limits
7992 nodes
= zone
->nodes
;
7993 signatures
= zone
->signatures
;
7994 signing
= ISC_LIST_HEAD(zone
->signing
);
7997 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
7998 keyset_kskonly
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
);
8000 /* Determine which type of chain to build */
8001 CHECK(dns_private_chains(db
, version
, zone
->privatetype
,
8002 &build_nsec
, &build_nsec3
));
8004 /* If neither chain is found, default to NSEC */
8005 if (!build_nsec
&& !build_nsec3
)
8006 build_nsec
= ISC_TRUE
;
8008 while (signing
!= NULL
&& nodes
-- > 0 && signatures
> 0) {
8009 nextsigning
= ISC_LIST_NEXT(signing
, link
);
8011 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
8012 if (signing
->done
|| signing
->db
!= zone
->db
) {
8014 * The zone has been reloaded. We will have
8015 * created new signings as part of the reload
8016 * process so we can destroy this one.
8018 ISC_LIST_UNLINK(zone
->signing
, signing
, link
);
8019 ISC_LIST_APPEND(cleanup
, signing
, link
);
8020 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
8023 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
8025 if (signing
->db
!= db
)
8028 delegation
= ISC_FALSE
;
8030 if (first
&& signing
->delete) {
8032 * Remove the key we are deleting from consideration.
8034 for (i
= 0, j
= 0; i
< nkeys
; i
++) {
8036 * Find the key we want to remove.
8038 if (ALG(zone_keys
[i
]) == signing
->algorithm
&&
8039 dst_key_id(zone_keys
[i
]) == signing
->keyid
)
8041 if (KSK(zone_keys
[i
]))
8042 dst_key_free(&zone_keys
[i
]);
8045 zone_keys
[j
] = zone_keys
[i
];
8051 dns_dbiterator_current(signing
->dbiterator
, &node
, name
);
8053 if (signing
->delete) {
8054 dns_dbiterator_pause(signing
->dbiterator
);
8055 CHECK(del_sig(db
, version
, name
, node
, nkeys
,
8056 signing
->algorithm
, signing
->keyid
,
8061 * On the first pass we need to check if the current node
8062 * has not been obscured.
8065 dns_fixedname_t ffound
;
8067 dns_fixedname_init(&ffound
);
8068 found
= dns_fixedname_name(&ffound
);
8069 result
= dns_db_find(db
, name
, version
,
8071 DNS_DBFIND_NOWILD
, 0, NULL
, found
,
8073 if ((result
== DNS_R_DELEGATION
||
8074 result
== DNS_R_DNAME
) &&
8075 !dns_name_equal(name
, found
)) {
8077 * Remember the obscuring name so that
8078 * we skip all obscured names.
8080 dns_name_copy(found
, name
, NULL
);
8081 delegation
= ISC_TRUE
;
8089 dns_dbiterator_pause(signing
->dbiterator
);
8090 for (i
= 0; i
< nkeys
; i
++) {
8091 isc_boolean_t both
= ISC_FALSE
;
8094 * Find the keys we want to sign with.
8096 if (!dst_key_isprivate(zone_keys
[i
]))
8100 * When adding look for the specific key.
8102 if (!signing
->delete &&
8103 (dst_key_alg(zone_keys
[i
]) != signing
->algorithm
||
8104 dst_key_id(zone_keys
[i
]) != signing
->keyid
))
8108 * When deleting make sure we are properly signed
8109 * with the algorithm that was being removed.
8111 if (signing
->delete &&
8112 ALG(zone_keys
[i
]) != signing
->algorithm
)
8116 * Do we do KSK processing?
8118 if (check_ksk
&& !REVOKE(zone_keys
[i
])) {
8119 isc_boolean_t have_ksk
, have_nonksk
;
8120 if (KSK(zone_keys
[i
])) {
8121 have_ksk
= ISC_TRUE
;
8122 have_nonksk
= ISC_FALSE
;
8124 have_ksk
= ISC_FALSE
;
8125 have_nonksk
= ISC_TRUE
;
8127 for (j
= 0; j
< nkeys
; j
++) {
8129 ALG(zone_keys
[i
]) !=
8132 if (REVOKE(zone_keys
[j
]))
8134 if (KSK(zone_keys
[j
]))
8135 have_ksk
= ISC_TRUE
;
8137 have_nonksk
= ISC_TRUE
;
8138 both
= have_ksk
&& have_nonksk
;
8143 if (both
|| REVOKE(zone_keys
[i
]))
8144 is_ksk
= KSK(zone_keys
[i
]);
8148 CHECK(sign_a_node(db
, name
, node
, version
, build_nsec3
,
8149 build_nsec
, zone_keys
[i
], inception
,
8150 expire
, zone
->minimum
, is_ksk
,
8151 ISC_TF(both
&& keyset_kskonly
),
8152 &delegation
, zonediff
.diff
,
8153 &signatures
, zone
->mctx
));
8155 * If we are adding we are done. Look for other keys
8156 * of the same algorithm if deleting.
8158 if (!signing
->delete)
8163 * Go onto next node.
8167 dns_db_detachnode(db
, &node
);
8169 result
= dns_dbiterator_next(signing
->dbiterator
);
8170 if (result
== ISC_R_NOMORE
) {
8171 ISC_LIST_UNLINK(zone
->signing
, signing
, link
);
8172 ISC_LIST_APPEND(cleanup
, signing
, link
);
8173 dns_dbiterator_pause(signing
->dbiterator
);
8174 if (nkeys
!= 0 && build_nsec
) {
8176 * We have finished regenerating the
8177 * zone with a zone signing key.
8178 * The NSEC chain is now complete and
8179 * there is a full set of signatures
8180 * for the zone. We can now clear the
8181 * OPT bit from the NSEC record.
8183 result
= updatesecure(db
, version
,
8188 if (result
!= ISC_R_SUCCESS
) {
8191 "updatesecure -> %s",
8192 dns_result_totext(result
));
8196 result
= updatesignwithkey(zone
, signing
,
8201 if (result
!= ISC_R_SUCCESS
) {
8202 dns_zone_log(zone
, ISC_LOG_ERROR
,
8203 "updatesignwithkey -> %s",
8204 dns_result_totext(result
));
8207 build_nsec
= ISC_FALSE
;
8209 } else if (result
!= ISC_R_SUCCESS
) {
8210 dns_zone_log(zone
, ISC_LOG_ERROR
,
8211 "zone_sign:dns_dbiterator_next -> %s",
8212 dns_result_totext(result
));
8214 } else if (delegation
) {
8215 dns_dbiterator_current(signing
->dbiterator
,
8217 dns_db_detachnode(db
, &node
);
8218 if (!dns_name_issubdomain(nextname
, name
))
8226 dns_dbiterator_pause(signing
->dbiterator
);
8227 signing
= nextsigning
;
8231 if (ISC_LIST_HEAD(post_diff
.tuples
) != NULL
) {
8232 result
= update_sigs(&post_diff
, db
, version
, zone_keys
,
8233 nkeys
, zone
, inception
, expire
, now
,
8234 check_ksk
, keyset_kskonly
, &zonediff
);
8235 if (result
!= ISC_R_SUCCESS
) {
8236 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_sign:"
8237 "update_sigs -> %s",
8238 dns_result_totext(result
));
8244 * Have we changed anything?
8246 if (ISC_LIST_EMPTY(zonediff
.diff
->tuples
)) {
8247 if (zonediff
.offline
)
8249 result
= ISC_R_SUCCESS
;
8255 result
= del_sigs(zone
, db
, version
, &zone
->origin
, dns_rdatatype_soa
,
8256 &zonediff
, zone_keys
, nkeys
, now
, ISC_FALSE
);
8257 if (result
!= ISC_R_SUCCESS
) {
8258 dns_zone_log(zone
, ISC_LOG_ERROR
,
8259 "zone_sign:del_sigs -> %s",
8260 dns_result_totext(result
));
8264 result
= update_soa_serial(db
, version
, zonediff
.diff
, zone
->mctx
,
8265 zone
->updatemethod
);
8266 if (result
!= ISC_R_SUCCESS
) {
8267 dns_zone_log(zone
, ISC_LOG_ERROR
,
8268 "zone_sign:update_soa_serial -> %s",
8269 dns_result_totext(result
));
8274 * Generate maximum life time signatures so that the above loop
8275 * termination is sensible.
8277 result
= add_sigs(db
, version
, &zone
->origin
, dns_rdatatype_soa
,
8278 zonediff
.diff
, zone_keys
, nkeys
, zone
->mctx
,
8279 inception
, soaexpire
, check_ksk
, keyset_kskonly
);
8280 if (result
!= ISC_R_SUCCESS
) {
8281 dns_zone_log(zone
, ISC_LOG_ERROR
,
8282 "zone_sign:add_sigs -> %s",
8283 dns_result_totext(result
));
8288 * Write changes to journal file.
8290 CHECK(zone_journal(zone
, zonediff
.diff
, NULL
, "zone_sign"));
8294 * Pause all iterators so that dns_db_closeversion() can succeed.
8296 for (signing
= ISC_LIST_HEAD(zone
->signing
);
8298 signing
= ISC_LIST_NEXT(signing
, link
))
8299 dns_dbiterator_pause(signing
->dbiterator
);
8301 for (signing
= ISC_LIST_HEAD(cleanup
);
8303 signing
= ISC_LIST_NEXT(signing
, link
))
8304 dns_dbiterator_pause(signing
->dbiterator
);
8307 * Everything has succeeded. Commit the changes.
8309 dns_db_closeversion(db
, &version
, commit
);
8312 * Everything succeeded so we can clean these up now.
8314 signing
= ISC_LIST_HEAD(cleanup
);
8315 while (signing
!= NULL
) {
8316 ISC_LIST_UNLINK(cleanup
, signing
, link
);
8317 dns_db_detach(&signing
->db
);
8318 dns_dbiterator_destroy(&signing
->dbiterator
);
8319 isc_mem_put(zone
->mctx
, signing
, sizeof *signing
);
8320 signing
= ISC_LIST_HEAD(cleanup
);
8323 set_resigntime(zone
);
8327 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
8328 zone_needdump(zone
, DNS_DUMP_DELAY
);
8334 * Rollback the cleanup list.
8336 signing
= ISC_LIST_HEAD(cleanup
);
8337 while (signing
!= NULL
) {
8338 ISC_LIST_UNLINK(cleanup
, signing
, link
);
8339 ISC_LIST_PREPEND(zone
->signing
, signing
, link
);
8340 dns_dbiterator_first(signing
->dbiterator
);
8341 dns_dbiterator_pause(signing
->dbiterator
);
8342 signing
= ISC_LIST_HEAD(cleanup
);
8345 for (signing
= ISC_LIST_HEAD(zone
->signing
);
8347 signing
= ISC_LIST_NEXT(signing
, link
))
8348 dns_dbiterator_pause(signing
->dbiterator
);
8350 dns_diff_clear(&_sig_diff
);
8352 for (i
= 0; i
< nkeys
; i
++)
8353 dst_key_free(&zone_keys
[i
]);
8356 dns_db_detachnode(db
, &node
);
8358 if (version
!= NULL
) {
8359 dns_db_closeversion(db
, &version
, ISC_FALSE
);
8361 } else if (db
!= NULL
)
8364 if (ISC_LIST_HEAD(zone
->signing
) != NULL
) {
8365 isc_interval_t interval
;
8366 if (zone
->update_disabled
|| result
!= ISC_R_SUCCESS
)
8367 isc_interval_set(&interval
, 60, 0); /* 1 minute */
8369 isc_interval_set(&interval
, 0, 10000000); /* 10 ms */
8370 isc_time_nowplusinterval(&zone
->signingtime
, &interval
);
8372 isc_time_settoepoch(&zone
->signingtime
);
8374 INSIST(version
== NULL
);
8378 normalize_key(dns_rdata_t
*rr
, dns_rdata_t
*target
,
8379 unsigned char *data
, int size
)
8381 dns_rdata_dnskey_t dnskey
;
8382 dns_rdata_keydata_t keydata
;
8384 isc_result_t result
;
8386 dns_rdata_reset(target
);
8387 isc_buffer_init(&buf
, data
, size
);
8390 case dns_rdatatype_dnskey
:
8391 result
= dns_rdata_tostruct(rr
, &dnskey
, NULL
);
8392 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8393 dnskey
.flags
&= ~DNS_KEYFLAG_REVOKE
;
8394 dns_rdata_fromstruct(target
, rr
->rdclass
, dns_rdatatype_dnskey
,
8397 case dns_rdatatype_keydata
:
8398 result
= dns_rdata_tostruct(rr
, &keydata
, NULL
);
8399 if (result
== ISC_R_UNEXPECTEDEND
)
8401 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8402 dns_keydata_todnskey(&keydata
, &dnskey
, NULL
);
8403 dns_rdata_fromstruct(target
, rr
->rdclass
, dns_rdatatype_dnskey
,
8409 return (ISC_R_SUCCESS
);
8413 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
8414 * a KEYDATA rdataset from the key zone.
8416 * 'rr' contains either a DNSKEY record, or a KEYDATA record
8418 * After normalizing keys to the same format (DNSKEY, with revoke bit
8419 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
8420 * 'rdset', or ISC_FALSE if not.
8423 static isc_boolean_t
8424 matchkey(dns_rdataset_t
*rdset
, dns_rdata_t
*rr
) {
8425 unsigned char data1
[4096], data2
[4096];
8426 dns_rdata_t rdata
, rdata1
, rdata2
;
8427 isc_result_t result
;
8429 dns_rdata_init(&rdata
);
8430 dns_rdata_init(&rdata1
);
8431 dns_rdata_init(&rdata2
);
8433 result
= normalize_key(rr
, &rdata1
, data1
, sizeof(data1
));
8434 if (result
!= ISC_R_SUCCESS
)
8437 for (result
= dns_rdataset_first(rdset
);
8438 result
== ISC_R_SUCCESS
;
8439 result
= dns_rdataset_next(rdset
)) {
8440 dns_rdata_reset(&rdata
);
8441 dns_rdataset_current(rdset
, &rdata
);
8442 result
= normalize_key(&rdata
, &rdata2
, data2
, sizeof(data2
));
8443 if (result
!= ISC_R_SUCCESS
)
8445 if (dns_rdata_compare(&rdata1
, &rdata2
) == 0)
8453 * Calculate the refresh interval for a keydata zone, per
8454 * RFC5011: MAX(1 hr,
8457 * 1/2 * RRSigExpirationInterval))
8458 * or for retries: MAX(1 hr,
8461 * 1/10 * RRSigExpirationInterval))
8463 static inline isc_stdtime_t
8464 refresh_time(dns_keyfetch_t
*kfetch
, isc_boolean_t retry
) {
8465 isc_result_t result
;
8467 dns_rdataset_t
*rdset
;
8468 dns_rdata_t sigrr
= DNS_RDATA_INIT
;
8469 dns_rdata_sig_t sig
;
8472 isc_stdtime_get(&now
);
8474 if (dns_rdataset_isassociated(&kfetch
->dnskeysigset
))
8475 rdset
= &kfetch
->dnskeysigset
;
8477 return (now
+ dns_zone_mkey_hour
);
8479 result
= dns_rdataset_first(rdset
);
8480 if (result
!= ISC_R_SUCCESS
)
8481 return (now
+ dns_zone_mkey_hour
);
8483 dns_rdataset_current(rdset
, &sigrr
);
8484 result
= dns_rdata_tostruct(&sigrr
, &sig
, NULL
);
8485 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8488 t
= sig
.originalttl
/ 2;
8490 if (isc_serial_gt(sig
.timeexpire
, now
)) {
8491 isc_uint32_t exp
= (sig
.timeexpire
- now
) / 2;
8496 if (t
> (15 * dns_zone_mkey_day
))
8497 t
= (15 * dns_zone_mkey_day
);
8499 if (t
< dns_zone_mkey_hour
)
8500 t
= dns_zone_mkey_hour
;
8502 t
= sig
.originalttl
/ 10;
8504 if (isc_serial_gt(sig
.timeexpire
, now
)) {
8505 isc_uint32_t exp
= (sig
.timeexpire
- now
) / 10;
8510 if (t
> dns_zone_mkey_day
)
8511 t
= dns_zone_mkey_day
;
8513 if (t
< dns_zone_mkey_hour
)
8514 t
= dns_zone_mkey_hour
;
8521 * This routine is called when no changes are needed in a KEYDATA
8522 * record except to simply update the refresh timer. Caller should
8526 minimal_update(dns_keyfetch_t
*kfetch
, dns_dbversion_t
*ver
, dns_diff_t
*diff
)
8528 isc_result_t result
;
8530 unsigned char key_buf
[4096];
8531 dns_rdata_t rdata
= DNS_RDATA_INIT
;
8532 dns_rdata_keydata_t keydata
;
8534 dns_zone_t
*zone
= kfetch
->zone
;
8537 name
= dns_fixedname_name(&kfetch
->name
);
8538 isc_stdtime_get(&now
);
8540 for (result
= dns_rdataset_first(&kfetch
->keydataset
);
8541 result
== ISC_R_SUCCESS
;
8542 result
= dns_rdataset_next(&kfetch
->keydataset
)) {
8543 dns_rdata_reset(&rdata
);
8544 dns_rdataset_current(&kfetch
->keydataset
, &rdata
);
8546 /* Delete old version */
8547 CHECK(update_one_rr(kfetch
->db
, ver
, diff
, DNS_DIFFOP_DEL
,
8550 /* Update refresh timer */
8551 result
= dns_rdata_tostruct(&rdata
, &keydata
, NULL
);
8552 if (result
== ISC_R_UNEXPECTEDEND
)
8554 if (result
!= ISC_R_SUCCESS
)
8556 keydata
.refresh
= refresh_time(kfetch
, ISC_TRUE
);
8557 set_refreshkeytimer(zone
, &keydata
, now
, ISC_FALSE
);
8559 dns_rdata_reset(&rdata
);
8560 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
8561 CHECK(dns_rdata_fromstruct(&rdata
,
8562 zone
->rdclass
, dns_rdatatype_keydata
,
8565 /* Insert updated version */
8566 CHECK(update_one_rr(kfetch
->db
, ver
, diff
, DNS_DIFFOP_ADD
,
8569 result
= ISC_R_SUCCESS
;
8575 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
8577 static isc_boolean_t
8578 revocable(dns_keyfetch_t
*kfetch
, dns_rdata_keydata_t
*keydata
) {
8579 isc_result_t result
;
8580 dns_name_t
*keyname
;
8582 dns_rdata_t sigrr
= DNS_RDATA_INIT
;
8583 dns_rdata_t rr
= DNS_RDATA_INIT
;
8584 dns_rdata_rrsig_t sig
;
8585 dns_rdata_dnskey_t dnskey
;
8586 dst_key_t
*dstkey
= NULL
;
8587 unsigned char key_buf
[4096];
8589 isc_boolean_t answer
= ISC_FALSE
;
8591 REQUIRE(kfetch
!= NULL
&& keydata
!= NULL
);
8592 REQUIRE(dns_rdataset_isassociated(&kfetch
->dnskeysigset
));
8594 keyname
= dns_fixedname_name(&kfetch
->name
);
8595 mctx
= kfetch
->zone
->view
->mctx
;
8597 /* Generate a key from keydata */
8598 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
8599 dns_keydata_todnskey(keydata
, &dnskey
, NULL
);
8600 dns_rdata_fromstruct(&rr
, keydata
->common
.rdclass
,
8601 dns_rdatatype_dnskey
, &dnskey
, &keyb
);
8602 result
= dns_dnssec_keyfromrdata(keyname
, &rr
, mctx
, &dstkey
);
8603 if (result
!= ISC_R_SUCCESS
)
8606 /* See if that key generated any of the signatures */
8607 for (result
= dns_rdataset_first(&kfetch
->dnskeysigset
);
8608 result
== ISC_R_SUCCESS
;
8609 result
= dns_rdataset_next(&kfetch
->dnskeysigset
))
8611 dns_fixedname_t fixed
;
8612 dns_fixedname_init(&fixed
);
8614 dns_rdata_reset(&sigrr
);
8615 dns_rdataset_current(&kfetch
->dnskeysigset
, &sigrr
);
8616 result
= dns_rdata_tostruct(&sigrr
, &sig
, NULL
);
8617 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8619 if (dst_key_alg(dstkey
) == sig
.algorithm
&&
8620 dst_key_rid(dstkey
) == sig
.keyid
)
8622 result
= dns_dnssec_verify2(keyname
,
8624 dstkey
, ISC_FALSE
, mctx
, &sigrr
,
8625 dns_fixedname_name(&fixed
));
8627 dns_zone_log(kfetch
->zone
, ISC_LOG_DEBUG(3),
8628 "Confirm revoked DNSKEY is self-signed: "
8629 "%s", dns_result_totext(result
));
8631 if (result
== ISC_R_SUCCESS
) {
8638 dst_key_free(&dstkey
);
8643 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
8644 * anchors are being managed; scan the keyset, and update the key zone and the
8645 * local trust anchors according to RFC5011.
8648 keyfetch_done(isc_task_t
*task
, isc_event_t
*event
) {
8649 isc_result_t result
, eresult
;
8650 dns_fetchevent_t
*devent
;
8651 dns_keyfetch_t
*kfetch
;
8653 isc_mem_t
*mctx
= NULL
;
8654 dns_keytable_t
*secroots
= NULL
;
8655 dns_dbversion_t
*ver
= NULL
;
8657 isc_boolean_t alldone
= ISC_FALSE
;
8658 isc_boolean_t commit
= ISC_FALSE
;
8659 dns_name_t
*keyname
;
8660 dns_rdata_t sigrr
= DNS_RDATA_INIT
;
8661 dns_rdata_t dnskeyrr
= DNS_RDATA_INIT
;
8662 dns_rdata_t keydatarr
= DNS_RDATA_INIT
;
8663 dns_rdata_rrsig_t sig
;
8664 dns_rdata_dnskey_t dnskey
;
8665 dns_rdata_keydata_t keydata
;
8666 isc_boolean_t initializing
;
8667 char namebuf
[DNS_NAME_FORMATSIZE
];
8668 unsigned char key_buf
[4096];
8673 isc_boolean_t secure
;
8674 isc_boolean_t free_needed
;
8677 INSIST(event
!= NULL
&& event
->ev_type
== DNS_EVENT_FETCHDONE
);
8678 INSIST(event
->ev_arg
!= NULL
);
8680 kfetch
= event
->ev_arg
;
8681 zone
= kfetch
->zone
;
8682 isc_mem_attach(zone
->mctx
, &mctx
);
8683 keyname
= dns_fixedname_name(&kfetch
->name
);
8685 devent
= (dns_fetchevent_t
*) event
;
8686 eresult
= devent
->result
;
8688 /* Free resources which are not of interest */
8689 if (devent
->node
!= NULL
)
8690 dns_db_detachnode(devent
->db
, &devent
->node
);
8691 if (devent
->db
!= NULL
)
8692 dns_db_detach(&devent
->db
);
8693 isc_event_free(&event
);
8694 dns_resolver_destroyfetch(&kfetch
->fetch
);
8697 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
) || zone
->view
== NULL
)
8700 isc_stdtime_get(&now
);
8701 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
8703 result
= dns_view_getsecroots(zone
->view
, &secroots
);
8704 INSIST(result
== ISC_R_SUCCESS
);
8706 dns_diff_init(mctx
, &diff
);
8708 CHECK(dns_db_newversion(kfetch
->db
, &ver
));
8710 zone
->refreshkeycount
--;
8711 alldone
= ISC_TF(zone
->refreshkeycount
== 0);
8714 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESHING
);
8717 if (eresult
!= ISC_R_SUCCESS
||
8718 !dns_rdataset_isassociated(&kfetch
->dnskeyset
)) {
8719 dns_zone_log(zone
, ISC_LOG_WARNING
,
8720 "Unable to fetch DNSKEY set "
8721 "'%s': %s", namebuf
, dns_result_totext(eresult
));
8722 CHECK(minimal_update(kfetch
, ver
, &diff
));
8726 /* No RRSIGs found */
8727 if (!dns_rdataset_isassociated(&kfetch
->dnskeysigset
)) {
8728 dns_zone_log(zone
, ISC_LOG_WARNING
,
8729 "No DNSKEY RRSIGs found for "
8730 "'%s': %s", namebuf
, dns_result_totext(eresult
));
8731 CHECK(minimal_update(kfetch
, ver
, &diff
));
8736 * Clear any cached trust level, as we need to run validation
8737 * over again; trusted keys might have changed.
8739 kfetch
->dnskeyset
.trust
= kfetch
->dnskeysigset
.trust
= dns_trust_none
;
8742 * Validate the dnskeyset against the current trusted keys.
8744 for (result
= dns_rdataset_first(&kfetch
->dnskeysigset
);
8745 result
== ISC_R_SUCCESS
;
8746 result
= dns_rdataset_next(&kfetch
->dnskeysigset
)) {
8747 dns_keynode_t
*keynode
= NULL
;
8749 dns_rdata_reset(&sigrr
);
8750 dns_rdataset_current(&kfetch
->dnskeysigset
, &sigrr
);
8751 result
= dns_rdata_tostruct(&sigrr
, &sig
, NULL
);
8752 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8754 result
= dns_keytable_find(secroots
, keyname
, &keynode
);
8755 while (result
== ISC_R_SUCCESS
) {
8756 dns_keynode_t
*nextnode
= NULL
;
8757 dns_fixedname_t fixed
;
8758 dns_fixedname_init(&fixed
);
8760 dstkey
= dns_keynode_key(keynode
);
8761 if (dstkey
== NULL
) /* fail_secure() was called */
8764 if (dst_key_alg(dstkey
) == sig
.algorithm
&&
8765 dst_key_id(dstkey
) == sig
.keyid
) {
8766 result
= dns_dnssec_verify2(keyname
,
8769 zone
->view
->mctx
, &sigrr
,
8770 dns_fixedname_name(&fixed
));
8772 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
8773 "Verifying DNSKEY set for zone "
8774 "'%s' using key %d/%d: %s",
8775 namebuf
, sig
.keyid
, sig
.algorithm
,
8776 dns_result_totext(result
));
8778 if (result
== ISC_R_SUCCESS
) {
8779 kfetch
->dnskeyset
.trust
=
8781 kfetch
->dnskeysigset
.trust
=
8787 result
= dns_keytable_nextkeynode(secroots
,
8788 keynode
, &nextnode
);
8789 dns_keytable_detachkeynode(secroots
, &keynode
);
8793 if (keynode
!= NULL
)
8794 dns_keytable_detachkeynode(secroots
, &keynode
);
8796 if (kfetch
->dnskeyset
.trust
== dns_trust_secure
)
8801 * If we were not able to verify the answer using the current
8802 * trusted keys then all we can do is look at any revoked keys.
8804 secure
= ISC_TF(kfetch
->dnskeyset
.trust
== dns_trust_secure
);
8807 * First scan keydataset to find keys that are not in dnskeyset
8808 * - Missing keys which are not scheduled for removal,
8810 * - Missing keys which are scheduled for removal and
8811 * the remove hold-down timer has completed should
8812 * be removed from the key zone
8813 * - Missing keys whose acceptance timers have not yet
8814 * completed, log a warning and reset the acceptance
8815 * timer to 30 days in the future
8816 * - All keys not being removed have their refresh timers
8819 initializing
= ISC_TRUE
;
8820 for (result
= dns_rdataset_first(&kfetch
->keydataset
);
8821 result
== ISC_R_SUCCESS
;
8822 result
= dns_rdataset_next(&kfetch
->keydataset
)) {
8823 dns_rdata_reset(&keydatarr
);
8824 dns_rdataset_current(&kfetch
->keydataset
, &keydatarr
);
8825 result
= dns_rdata_tostruct(&keydatarr
, &keydata
, NULL
);
8826 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8829 * If any keydata record has a nonzero add holddown, then
8830 * there was a pre-existing trust anchor for this domain;
8831 * that means we are *not* initializing it and shouldn't
8832 * automatically trust all the keys we find at the zone apex.
8834 initializing
= initializing
&& ISC_TF(keydata
.addhd
== 0);
8836 if (! matchkey(&kfetch
->dnskeyset
, &keydatarr
)) {
8837 isc_boolean_t deletekey
= ISC_FALSE
;
8840 if (keydata
.removehd
!= 0 &&
8841 keydata
.removehd
<= now
)
8842 deletekey
= ISC_TRUE
;
8843 } else if (keydata
.addhd
== 0) {
8844 deletekey
= ISC_TRUE
;
8845 } else if (keydata
.addhd
> now
) {
8846 dns_zone_log(zone
, ISC_LOG_WARNING
,
8847 "Pending key unexpectedly missing "
8848 "from %s; restarting acceptance "
8850 if (keydata
.addhd
< now
+ dns_zone_mkey_month
)
8852 now
+ dns_zone_mkey_month
;
8853 keydata
.refresh
= refresh_time(kfetch
,
8855 } else if (keydata
.removehd
== 0) {
8856 dns_zone_log(zone
, ISC_LOG_WARNING
,
8857 "Active key unexpectedly missing "
8858 "from %s", namebuf
);
8859 keydata
.refresh
= now
+ dns_zone_mkey_hour
;
8860 } else if (keydata
.removehd
<= now
) {
8861 deletekey
= ISC_TRUE
;
8863 keydata
.refresh
= refresh_time(kfetch
,
8867 if (secure
|| deletekey
) {
8868 /* Delete old version */
8869 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
8870 DNS_DIFFOP_DEL
, keyname
, 0,
8874 if (!secure
|| deletekey
)
8877 dns_rdata_reset(&keydatarr
);
8878 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
8879 dns_rdata_fromstruct(&keydatarr
, zone
->rdclass
,
8880 dns_rdatatype_keydata
,
8883 /* Insert updated version */
8884 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
8885 DNS_DIFFOP_ADD
, keyname
, 0,
8888 set_refreshkeytimer(zone
, &keydata
, now
, ISC_FALSE
);
8893 * Next scan dnskeyset:
8894 * - If new keys are found (i.e., lacking a match in keydataset)
8895 * add them to the key zone and set the acceptance timer
8896 * to 30 days in the future (or to immediately if we've
8897 * determined that we're initializing the zone for the
8899 * - Previously-known keys that have been revoked
8900 * must be scheduled for removal from the key zone (or,
8901 * if they hadn't been accepted as trust anchors yet
8902 * anyway, removed at once)
8903 * - Previously-known unrevoked keys whose acceptance timers
8904 * have completed are promoted to trust anchors
8905 * - All keys not being removed have their refresh
8908 for (result
= dns_rdataset_first(&kfetch
->dnskeyset
);
8909 result
== ISC_R_SUCCESS
;
8910 result
= dns_rdataset_next(&kfetch
->dnskeyset
))
8912 isc_boolean_t revoked
= ISC_FALSE
;
8913 isc_boolean_t newkey
= ISC_FALSE
;
8914 isc_boolean_t updatekey
= ISC_FALSE
;
8915 isc_boolean_t deletekey
= ISC_FALSE
;
8916 isc_boolean_t trustkey
= ISC_FALSE
;
8918 dns_rdata_reset(&dnskeyrr
);
8919 dns_rdataset_current(&kfetch
->dnskeyset
, &dnskeyrr
);
8920 result
= dns_rdata_tostruct(&dnskeyrr
, &dnskey
, NULL
);
8921 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8924 if (!ISC_TF(dnskey
.flags
& DNS_KEYFLAG_KSK
))
8927 revoked
= ISC_TF(dnskey
.flags
& DNS_KEYFLAG_REVOKE
);
8929 if (matchkey(&kfetch
->keydataset
, &dnskeyrr
)) {
8930 dns_rdata_reset(&keydatarr
);
8931 dns_rdataset_current(&kfetch
->keydataset
, &keydatarr
);
8932 result
= dns_rdata_tostruct(&keydatarr
, &keydata
, NULL
);
8933 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8935 if (revoked
&& revocable(kfetch
, &keydata
)) {
8936 if (keydata
.addhd
> now
) {
8938 * Key wasn't trusted yet, and now
8939 * it's been revoked? Just remove it
8941 deletekey
= ISC_TRUE
;
8942 } else if (keydata
.removehd
== 0) {
8943 /* Remove from secroots */
8944 dns_view_untrust(zone
->view
, keyname
,
8947 /* But ensure there's a null key */
8948 fail_secure(zone
, keyname
);
8950 /* If initializing, delete now */
8951 if (keydata
.addhd
== 0)
8952 deletekey
= ISC_TRUE
;
8954 keydata
.removehd
= now
+
8955 dns_zone_mkey_month
;
8959 } else if (keydata
.removehd
< now
) {
8960 /* Scheduled for removal */
8961 deletekey
= ISC_TRUE
;
8963 } else if (revoked
&& keydata
.removehd
== 0) {
8964 dns_zone_log(zone
, ISC_LOG_WARNING
,
8965 "Active key for zone "
8966 "'%s' is revoked but "
8967 "did not self-sign; "
8968 "ignoring.", namebuf
);
8970 } else if (secure
) {
8971 if (keydata
.removehd
!= 0) {
8973 * Key isn't revoked--but it
8974 * seems it used to be.
8975 * Remove it now and add it
8976 * back as if it were a fresh key,
8977 * with a 30 day acceptance timer.
8979 deletekey
= ISC_TRUE
;
8981 keydata
.removehd
= 0;
8983 now
+ dns_zone_mkey_month
;
8984 } else if (keydata
.addhd
> now
)
8986 else if (keydata
.addhd
== 0)
8987 keydata
.addhd
= now
;
8989 if (keydata
.addhd
<= now
)
8990 trustkey
= ISC_TRUE
;
8991 } else if (keydata
.addhd
> now
) {
8993 * Not secure, and key is pending:
8994 * reset the acceptance timer
8997 keydata
.addhd
= now
+ dns_zone_mkey_month
;
9000 if (!deletekey
&& !newkey
)
9001 updatekey
= ISC_TRUE
;
9002 } else if (secure
) {
9004 * Key wasn't in the key zone but it's
9005 * revoked now anyway, so just skip it
9010 /* Key wasn't in the key zone: add it */
9014 dns_keytag_t tag
= 0;
9015 CHECK(compute_tag(keyname
, &dnskey
,
9017 dns_zone_log(zone
, ISC_LOG_WARNING
,
9018 "Initializing automatic trust "
9019 "anchor management for zone '%s'; "
9020 "DNSKEY ID %d is now trusted, "
9021 "waiving the normal 30-day "
9024 trustkey
= ISC_TRUE
;
9028 * No previously known key, and the key is not
9029 * secure, so skip it.
9034 /* Delete old version */
9035 if (deletekey
|| !newkey
)
9036 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
9037 DNS_DIFFOP_DEL
, keyname
, 0,
9041 /* Set refresh timer */
9042 keydata
.refresh
= refresh_time(kfetch
, ISC_FALSE
);
9043 dns_rdata_reset(&keydatarr
);
9044 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
9045 dns_rdata_fromstruct(&keydatarr
, zone
->rdclass
,
9046 dns_rdatatype_keydata
,
9049 /* Insert updated version */
9050 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
9051 DNS_DIFFOP_ADD
, keyname
, 0,
9053 } else if (newkey
) {
9054 /* Convert DNSKEY to KEYDATA */
9055 result
= dns_rdata_tostruct(&dnskeyrr
, &dnskey
, NULL
);
9056 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
9057 dns_keydata_fromdnskey(&keydata
, &dnskey
, 0, 0, 0,
9059 keydata
.addhd
= initializing
9060 ? now
: now
+ dns_zone_mkey_month
;
9061 keydata
.refresh
= refresh_time(kfetch
, ISC_FALSE
);
9062 dns_rdata_reset(&keydatarr
);
9063 isc_buffer_init(&keyb
, key_buf
, sizeof(key_buf
));
9064 dns_rdata_fromstruct(&keydatarr
, zone
->rdclass
,
9065 dns_rdatatype_keydata
,
9068 /* Insert into key zone */
9069 CHECK(update_one_rr(kfetch
->db
, ver
, &diff
,
9070 DNS_DIFFOP_ADD
, keyname
, 0,
9075 /* Trust this key. */
9076 result
= dns_rdata_tostruct(&dnskeyrr
, &dnskey
, NULL
);
9077 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
9078 trust_key(zone
, keyname
, &dnskey
, mctx
);
9081 if (secure
&& !deletekey
) {
9082 INSIST(newkey
|| updatekey
);
9083 set_refreshkeytimer(zone
, &keydata
, now
, ISC_FALSE
);
9088 * RFC5011 says, "A trust point that has all of its trust anchors
9089 * revoked is considered deleted and is treated as if the trust
9090 * point was never configured." But if someone revoked their
9091 * active key before the standby was trusted, that would mean the
9092 * zone would suddenly be nonsecured. We avoid this by checking to
9093 * see if there's pending keydata. If so, we put a null key in
9094 * the security roots; then all queries to the zone will fail.
9097 fail_secure(zone
, keyname
);
9101 if (!ISC_LIST_EMPTY(diff
.tuples
)) {
9102 /* Write changes to journal file. */
9103 CHECK(update_soa_serial(kfetch
->db
, ver
, &diff
, mctx
,
9104 zone
->updatemethod
));
9105 CHECK(zone_journal(zone
, &diff
, NULL
, "keyfetch_done"));
9108 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
);
9109 zone_needdump(zone
, 30);
9114 dns_diff_clear(&diff
);
9116 dns_db_closeversion(kfetch
->db
, &ver
, commit
);
9119 dns_db_detach(&kfetch
->db
);
9121 INSIST(zone
->irefs
> 0);
9123 kfetch
->zone
= NULL
;
9125 if (dns_rdataset_isassociated(&kfetch
->keydataset
))
9126 dns_rdataset_disassociate(&kfetch
->keydataset
);
9127 if (dns_rdataset_isassociated(&kfetch
->dnskeyset
))
9128 dns_rdataset_disassociate(&kfetch
->dnskeyset
);
9129 if (dns_rdataset_isassociated(&kfetch
->dnskeysigset
))
9130 dns_rdataset_disassociate(&kfetch
->dnskeysigset
);
9132 dns_name_free(keyname
, mctx
);
9133 isc_mem_put(mctx
, kfetch
, sizeof(dns_keyfetch_t
));
9134 isc_mem_detach(&mctx
);
9136 if (secroots
!= NULL
)
9137 dns_keytable_detach(&secroots
);
9139 free_needed
= exit_check(zone
);
9144 INSIST(ver
== NULL
);
9148 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
9149 * records from the zone apex.
9152 zone_refreshkeys(dns_zone_t
*zone
) {
9153 const char me
[] = "zone_refreshkeys";
9154 isc_result_t result
;
9155 dns_rriterator_t rrit
;
9156 dns_db_t
*db
= NULL
;
9157 dns_dbversion_t
*ver
= NULL
;
9159 dns_rdata_t rdata
= DNS_RDATA_INIT
;
9160 dns_rdata_keydata_t kd
;
9162 isc_boolean_t commit
= ISC_FALSE
;
9163 isc_boolean_t fetching
= ISC_FALSE
, fetch_err
= ISC_FALSE
;
9166 REQUIRE(zone
->db
!= NULL
);
9168 isc_stdtime_get(&now
);
9171 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
9172 isc_time_settoepoch(&zone
->refreshkeytime
);
9177 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
9178 dns_db_attach(zone
->db
, &db
);
9179 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
9181 dns_diff_init(zone
->mctx
, &diff
);
9183 CHECK(dns_db_newversion(db
, &ver
));
9185 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESHING
);
9187 dns_rriterator_init(&rrit
, db
, ver
, 0);
9188 for (result
= dns_rriterator_first(&rrit
);
9189 result
== ISC_R_SUCCESS
;
9190 result
= dns_rriterator_nextrrset(&rrit
)) {
9191 isc_stdtime_t timer
= 0xffffffff;
9192 dns_name_t
*name
= NULL
, *kname
= NULL
;
9193 dns_rdataset_t
*kdset
= NULL
;
9194 dns_keyfetch_t
*kfetch
;
9197 dns_rriterator_current(&rrit
, &name
, &ttl
, &kdset
, NULL
);
9198 if (kdset
== NULL
|| kdset
->type
!= dns_rdatatype_keydata
||
9199 !dns_rdataset_isassociated(kdset
))
9203 * Scan the stored keys looking for ones that need
9204 * removal or refreshing
9206 for (result
= dns_rdataset_first(kdset
);
9207 result
== ISC_R_SUCCESS
;
9208 result
= dns_rdataset_next(kdset
)) {
9209 dns_rdata_reset(&rdata
);
9210 dns_rdataset_current(kdset
, &rdata
);
9211 result
= dns_rdata_tostruct(&rdata
, &kd
, NULL
);
9212 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
9214 /* Removal timer expired? */
9215 if (kd
.removehd
!= 0 && kd
.removehd
< now
) {
9216 CHECK(update_one_rr(db
, ver
, &diff
,
9217 DNS_DIFFOP_DEL
, name
, ttl
,
9222 /* Acceptance timer expired? */
9223 if (kd
.addhd
!= 0 && kd
.addhd
< now
)
9226 /* Or do we just need to refresh the keyset? */
9227 if (timer
> kd
.refresh
)
9234 kfetch
= isc_mem_get(zone
->mctx
, sizeof(dns_keyfetch_t
));
9235 if (kfetch
== NULL
) {
9236 fetch_err
= ISC_TRUE
;
9240 zone
->refreshkeycount
++;
9241 kfetch
->zone
= zone
;
9243 INSIST(zone
->irefs
!= 0);
9244 dns_fixedname_init(&kfetch
->name
);
9245 kname
= dns_fixedname_name(&kfetch
->name
);
9246 dns_name_dup(name
, zone
->mctx
, kname
);
9247 dns_rdataset_init(&kfetch
->dnskeyset
);
9248 dns_rdataset_init(&kfetch
->dnskeysigset
);
9249 dns_rdataset_init(&kfetch
->keydataset
);
9250 dns_rdataset_clone(kdset
, &kfetch
->keydataset
);
9252 dns_db_attach(db
, &kfetch
->db
);
9253 kfetch
->fetch
= NULL
;
9255 result
= dns_resolver_createfetch(zone
->view
->resolver
,
9256 kname
, dns_rdatatype_dnskey
,
9258 DNS_FETCHOPT_NOVALIDATE
,
9260 keyfetch_done
, kfetch
,
9262 &kfetch
->dnskeysigset
,
9264 if (result
== ISC_R_SUCCESS
)
9265 fetching
= ISC_TRUE
;
9267 zone
->refreshkeycount
--;
9269 dns_db_detach(&kfetch
->db
);
9270 dns_rdataset_disassociate(&kfetch
->keydataset
);
9271 dns_name_free(kname
, zone
->mctx
);
9272 isc_mem_put(zone
->mctx
, kfetch
, sizeof(dns_keyfetch_t
));
9273 dns_zone_log(zone
, ISC_LOG_WARNING
,
9274 "Failed to create fetch for "
9276 fetch_err
= ISC_TRUE
;
9279 if (!ISC_LIST_EMPTY(diff
.tuples
)) {
9280 CHECK(update_soa_serial(db
, ver
, &diff
, zone
->mctx
,
9281 zone
->updatemethod
));
9282 CHECK(zone_journal(zone
, &diff
, NULL
, "zone_refreshkeys"));
9284 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
);
9285 zone_needdump(zone
, 30);
9291 * Error during a key fetch; retry in an hour.
9293 isc_time_t timenow
, timethen
;
9297 DNS_ZONE_TIME_ADD(&timenow
, dns_zone_mkey_hour
, &timethen
);
9298 zone
->refreshkeytime
= timethen
;
9299 zone_settimer(zone
, &timenow
);
9301 isc_time_formattimestamp(&zone
->refreshkeytime
, timebuf
, 80);
9302 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "retry key refresh: %s",
9306 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESHING
);
9311 dns_diff_clear(&diff
);
9313 dns_rriterator_destroy(&rrit
);
9314 dns_db_closeversion(db
, &ver
, commit
);
9318 INSIST(ver
== NULL
);
9322 zone_maintenance(dns_zone_t
*zone
) {
9323 const char me
[] = "zone_maintenance";
9325 isc_result_t result
;
9326 isc_boolean_t dumping
;
9328 REQUIRE(DNS_ZONE_VALID(zone
));
9332 * Are we pending load/reload?
9334 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADPENDING
))
9338 * Configuring the view of this zone may have
9339 * failed, for example because the config file
9340 * had a syntax error. In that case, the view
9341 * adb or resolver will be NULL, and we had better not try
9342 * to do further maintenance on it.
9344 if (zone
->view
== NULL
|| zone
->view
->adb
== NULL
)
9352 switch (zone
->type
) {
9353 case dns_zone_redirect
:
9354 if (zone
->masters
== NULL
)
9356 case dns_zone_slave
:
9359 if (isc_time_compare(&now
, &zone
->expiretime
) >= 0 &&
9360 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
9362 zone
->refreshtime
= now
;
9373 switch (zone
->type
) {
9374 case dns_zone_redirect
:
9375 if (zone
->masters
== NULL
)
9377 case dns_zone_slave
:
9379 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
) &&
9380 isc_time_compare(&now
, &zone
->refreshtime
) >= 0)
9381 dns_zone_refresh(zone
);
9388 * Slaves send notifies before backing up to disk, masters after.
9390 if (zone
->type
== dns_zone_slave
&&
9391 (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
) ||
9392 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDSTARTUPNOTIFY
)) &&
9393 isc_time_compare(&now
, &zone
->notifytime
) >= 0)
9394 zone_notify(zone
, &now
);
9397 * Do we need to consolidate the backing store?
9399 switch (zone
->type
) {
9400 case dns_zone_master
:
9401 case dns_zone_slave
:
9403 case dns_zone_redirect
:
9406 if (zone
->masterfile
!= NULL
&&
9407 isc_time_compare(&now
, &zone
->dumptime
) >= 0 &&
9408 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
9409 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
)) {
9410 dumping
= was_dumping(zone
);
9415 result
= zone_dump(zone
, ISC_TRUE
); /* task locked */
9416 if (result
!= ISC_R_SUCCESS
)
9417 dns_zone_log(zone
, ISC_LOG_WARNING
,
9419 dns_result_totext(result
));
9427 * Master/redirect zones send notifies now, if needed
9429 switch (zone
->type
) {
9430 case dns_zone_master
:
9431 case dns_zone_redirect
:
9432 if ((DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
) ||
9433 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDSTARTUPNOTIFY
))&&
9434 isc_time_compare(&now
, &zone
->notifytime
) >= 0)
9435 zone_notify(zone
, &now
);
9441 * Do we need to refresh keys?
9443 switch (zone
->type
) {
9445 if (isc_time_compare(&now
, &zone
->refreshkeytime
) >= 0) {
9446 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
9447 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESHING
)) {
9448 zone_refreshkeys(zone
);
9452 case dns_zone_master
:
9453 if (!isc_time_isepoch(&zone
->refreshkeytime
) &&
9454 isc_time_compare(&now
, &zone
->refreshkeytime
) >= 0)
9460 switch (zone
->type
) {
9461 case dns_zone_master
:
9462 case dns_zone_redirect
:
9463 case dns_zone_slave
:
9465 * Do we need to sign/resign some RRsets?
9467 if (!isc_time_isepoch(&zone
->signingtime
) &&
9468 isc_time_compare(&now
, &zone
->signingtime
) >= 0)
9470 else if (!isc_time_isepoch(&zone
->resigntime
) &&
9471 isc_time_compare(&now
, &zone
->resigntime
) >= 0)
9472 zone_resigninc(zone
);
9473 else if (!isc_time_isepoch(&zone
->nsec3chaintime
) &&
9474 isc_time_compare(&now
, &zone
->nsec3chaintime
) >= 0)
9475 zone_nsec3chain(zone
);
9477 * Do we need to issue a key expiry warning?
9479 if (!isc_time_isepoch(&zone
->keywarntime
) &&
9480 isc_time_compare(&now
, &zone
->keywarntime
) >= 0)
9481 set_key_expiry_warning(zone
, zone
->key_expiry
,
9482 isc_time_seconds(&now
));
9488 zone_settimer(zone
, &now
);
9492 dns_zone_markdirty(dns_zone_t
*zone
) {
9493 isc_uint32_t serial
;
9494 isc_result_t result
= ISC_R_SUCCESS
;
9495 dns_zone_t
*secure
= NULL
;
9498 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
9499 * could result in a deadlock due to a LOR so we will spin if we
9500 * can't obtain the both locks.
9504 if (zone
->type
== dns_zone_master
) {
9505 if (inline_raw(zone
)) {
9506 unsigned int soacount
;
9507 secure
= zone
->secure
;
9508 INSIST(secure
!= zone
);
9509 TRYLOCK_ZONE(result
, secure
);
9510 if (result
!= ISC_R_SUCCESS
) {
9513 #ifdef ISC_PLATFORM_USETHREADS
9519 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
9520 if (zone
->db
!= NULL
) {
9521 result
= zone_get_from_db(zone
, zone
->db
, NULL
,
9526 result
= DNS_R_NOTLOADED
;
9527 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
9528 if (result
== ISC_R_SUCCESS
&& soacount
> 0U)
9529 zone_send_secureserial(zone
, serial
);
9532 /* XXXMPA make separate call back */
9533 if (result
== ISC_R_SUCCESS
)
9534 set_resigntime(zone
);
9537 UNLOCK_ZONE(secure
);
9538 zone_needdump(zone
, DNS_DUMP_DELAY
);
9543 dns_zone_expire(dns_zone_t
*zone
) {
9544 REQUIRE(DNS_ZONE_VALID(zone
));
9552 zone_expire(dns_zone_t
*zone
) {
9554 * 'zone' locked by caller.
9557 REQUIRE(LOCKED_ZONE(zone
));
9559 dns_zone_log(zone
, ISC_LOG_WARNING
, "expired");
9561 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXPIRED
);
9562 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
9563 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
9564 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
9569 dns_zone_refresh(dns_zone_t
*zone
) {
9571 isc_uint32_t oldflags
;
9573 isc_result_t result
;
9575 REQUIRE(DNS_ZONE_VALID(zone
));
9577 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
9581 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
9582 * in progress at a time.
9586 oldflags
= zone
->flags
;
9587 if (zone
->masterscnt
== 0) {
9588 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
9589 if ((oldflags
& DNS_ZONEFLG_NOMASTERS
) == 0)
9590 dns_zone_log(zone
, ISC_LOG_ERROR
,
9591 "cannot refresh: no masters");
9594 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
9595 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
9596 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
9597 if ((oldflags
& (DNS_ZONEFLG_REFRESH
|DNS_ZONEFLG_LOADING
)) != 0)
9601 * Set the next refresh time as if refresh check has failed.
9602 * Setting this to the retry time will do that. XXXMLG
9603 * If we are successful it will be reset using zone->refresh.
9605 isc_interval_set(&i
, isc_random_jitter(zone
->retry
, zone
->retry
/ 4),
9607 result
= isc_time_nowplusinterval(&zone
->refreshtime
, &i
);
9608 if (result
!= ISC_R_SUCCESS
)
9609 dns_zone_log(zone
, ISC_LOG_WARNING
,
9610 "isc_time_nowplusinterval() failed: %s",
9611 dns_result_totext(result
));
9614 * When lacking user-specified timer values from the SOA,
9615 * do exponential backoff of the retry time up to a
9616 * maximum of six hours.
9618 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HAVETIMERS
))
9619 zone
->retry
= ISC_MIN(zone
->retry
* 2, 6 * 3600);
9621 zone
->curmaster
= 0;
9622 for (j
= 0; j
< zone
->masterscnt
; j
++)
9623 zone
->mastersok
[j
] = ISC_FALSE
;
9624 /* initiate soa query */
9625 queue_soa_query(zone
);
9631 dns_zone_flush(dns_zone_t
*zone
) {
9632 isc_result_t result
= ISC_R_SUCCESS
;
9633 isc_boolean_t dumping
;
9635 REQUIRE(DNS_ZONE_VALID(zone
));
9638 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FLUSH
);
9639 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
9640 zone
->masterfile
!= NULL
) {
9641 result
= ISC_R_ALREADYRUNNING
;
9642 dumping
= was_dumping(zone
);
9647 result
= zone_dump(zone
, ISC_FALSE
); /* Unknown task. */
9652 dns_zone_dump(dns_zone_t
*zone
) {
9653 isc_result_t result
= ISC_R_ALREADYRUNNING
;
9654 isc_boolean_t dumping
;
9656 REQUIRE(DNS_ZONE_VALID(zone
));
9659 dumping
= was_dumping(zone
);
9662 result
= zone_dump(zone
, ISC_FALSE
); /* Unknown task. */
9667 zone_needdump(dns_zone_t
*zone
, unsigned int delay
) {
9668 const char me
[] = "zone_needdump";
9669 isc_time_t dumptime
;
9673 * 'zone' locked by caller
9676 REQUIRE(DNS_ZONE_VALID(zone
));
9677 REQUIRE(LOCKED_ZONE(zone
));
9681 * Do we have a place to dump to and are we loaded?
9683 if (zone
->masterfile
== NULL
||
9684 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) == 0)
9688 /* add some noise */
9689 DNS_ZONE_JITTER_ADD(&now
, delay
, &dumptime
);
9691 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
9692 if (isc_time_isepoch(&zone
->dumptime
) ||
9693 isc_time_compare(&zone
->dumptime
, &dumptime
) > 0)
9694 zone
->dumptime
= dumptime
;
9695 if (zone
->task
!= NULL
)
9696 zone_settimer(zone
, &now
);
9700 dump_done(void *arg
, isc_result_t result
) {
9701 const char me
[] = "dump_done";
9702 dns_zone_t
*zone
= arg
;
9704 dns_dbversion_t
*version
;
9705 isc_boolean_t again
= ISC_FALSE
;
9706 isc_boolean_t compact
= ISC_FALSE
;
9707 isc_uint32_t serial
;
9708 isc_result_t tresult
;
9710 REQUIRE(DNS_ZONE_VALID(zone
));
9714 if (result
== ISC_R_SUCCESS
&& zone
->journal
!= NULL
&&
9715 zone
->journalsize
!= -1) {
9718 * We don't own these, zone->dctx must stay valid.
9720 db
= dns_dumpctx_db(zone
->dctx
);
9721 version
= dns_dumpctx_version(zone
->dctx
);
9723 tresult
= dns_db_getsoaserial(db
, version
, &serial
);
9725 * If there is a secure version of this zone
9726 * use its serial if it is less than ours.
9728 if (tresult
== ISC_R_SUCCESS
&& inline_raw(zone
) &&
9729 zone
->secure
->db
!= NULL
)
9731 isc_uint32_t sserial
;
9732 isc_result_t mresult
;
9734 mresult
= dns_db_getsoaserial(zone
->secure
->db
,
9736 if (mresult
== ISC_R_SUCCESS
&&
9737 isc_serial_lt(sserial
, serial
))
9741 * Note: we are task locked here so we can test
9744 if (tresult
== ISC_R_SUCCESS
&& zone
->xfr
== NULL
) {
9745 tresult
= dns_journal_compact(zone
->mctx
,
9752 case ISC_R_NOTFOUND
:
9753 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
9754 "dns_journal_compact: %s",
9755 dns_result_totext(tresult
));
9758 dns_zone_log(zone
, ISC_LOG_ERROR
,
9759 "dns_journal_compact failed: %s",
9760 dns_result_totext(tresult
));
9763 } else if (tresult
== ISC_R_SUCCESS
) {
9765 zone
->compact_serial
= serial
;
9770 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
9772 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
);
9773 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_CANCELED
) {
9775 * Try again in a short while.
9777 zone_needdump(zone
, DNS_DUMP_DELAY
);
9778 } else if (result
== ISC_R_SUCCESS
&&
9779 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
9780 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
9781 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
9782 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
9783 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
9784 isc_time_settoepoch(&zone
->dumptime
);
9786 } else if (result
== ISC_R_SUCCESS
)
9787 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FLUSH
);
9789 if (zone
->dctx
!= NULL
)
9790 dns_dumpctx_detach(&zone
->dctx
);
9791 zonemgr_putio(&zone
->writeio
);
9794 (void)zone_dump(zone
, ISC_FALSE
);
9795 dns_zone_idetach(&zone
);
9799 zone_dump(dns_zone_t
*zone
, isc_boolean_t compact
) {
9800 const char me
[] = "zone_dump";
9801 isc_result_t result
;
9802 dns_dbversion_t
*version
= NULL
;
9803 isc_boolean_t again
;
9804 dns_db_t
*db
= NULL
;
9805 char *masterfile
= NULL
;
9806 dns_masterformat_t masterformat
= dns_masterformat_none
;
9809 * 'compact' MUST only be set if we are task locked.
9812 REQUIRE(DNS_ZONE_VALID(zone
));
9816 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
9817 if (zone
->db
!= NULL
)
9818 dns_db_attach(zone
->db
, &db
);
9819 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
9821 if (zone
->masterfile
!= NULL
) {
9822 masterfile
= isc_mem_strdup(zone
->mctx
, zone
->masterfile
);
9823 masterformat
= zone
->masterformat
;
9827 result
= DNS_R_NOTLOADED
;
9830 if (masterfile
== NULL
) {
9831 result
= DNS_R_NOMASTERFILE
;
9835 if (compact
&& zone
->type
!= dns_zone_stub
) {
9836 dns_zone_t
*dummy
= NULL
;
9838 zone_iattach(zone
, &dummy
);
9839 result
= zonemgr_getio(zone
->zmgr
, ISC_FALSE
, zone
->task
,
9840 zone_gotwritehandle
, zone
,
9842 if (result
!= ISC_R_SUCCESS
)
9843 zone_idetach(&dummy
);
9845 result
= DNS_R_CONTINUE
;
9848 const dns_master_style_t
*output_style
;
9850 dns_masterrawheader_t rawdata
;
9851 dns_db_currentversion(db
, &version
);
9852 dns_master_initrawheader(&rawdata
);
9853 if (inline_secure(zone
))
9854 get_raw_serial(zone
->raw
, &rawdata
);
9855 if (zone
->type
== dns_zone_key
)
9856 output_style
= &dns_master_style_keyzone
;
9858 output_style
= &dns_master_style_default
;
9859 result
= dns_master_dump3(zone
->mctx
, db
, version
,
9860 output_style
, masterfile
,
9861 masterformat
, &rawdata
);
9862 dns_db_closeversion(db
, &version
, ISC_FALSE
);
9867 if (masterfile
!= NULL
)
9868 isc_mem_free(zone
->mctx
, masterfile
);
9871 if (result
== DNS_R_CONTINUE
)
9872 return (ISC_R_SUCCESS
); /* XXXMPA */
9876 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
9877 if (result
!= ISC_R_SUCCESS
) {
9879 * Try again in a short while.
9881 zone_needdump(zone
, DNS_DUMP_DELAY
);
9882 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
9883 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
9884 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
9885 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
9886 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
9887 isc_time_settoepoch(&zone
->dumptime
);
9890 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FLUSH
);
9899 dumptostream(dns_zone_t
*zone
, FILE *fd
, const dns_master_style_t
*style
,
9900 dns_masterformat_t format
, const isc_uint32_t rawversion
)
9902 isc_result_t result
;
9903 dns_dbversion_t
*version
= NULL
;
9904 dns_db_t
*db
= NULL
;
9905 dns_masterrawheader_t rawdata
;
9907 REQUIRE(DNS_ZONE_VALID(zone
));
9909 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
9910 if (zone
->db
!= NULL
)
9911 dns_db_attach(zone
->db
, &db
);
9912 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
9914 return (DNS_R_NOTLOADED
);
9916 dns_db_currentversion(db
, &version
);
9917 dns_master_initrawheader(&rawdata
);
9918 if (rawversion
== 0)
9919 rawdata
.flags
|= DNS_MASTERRAW_COMPAT
;
9920 else if (inline_secure(zone
))
9921 get_raw_serial(zone
->raw
, &rawdata
);
9922 else if (zone
->sourceserialset
) {
9923 rawdata
.flags
= DNS_MASTERRAW_SOURCESERIALSET
;
9924 rawdata
.sourceserial
= zone
->sourceserial
;
9926 result
= dns_master_dumptostream3(zone
->mctx
, db
, version
, style
,
9927 format
, &rawdata
, fd
);
9928 dns_db_closeversion(db
, &version
, ISC_FALSE
);
9934 dns_zone_dumptostream3(dns_zone_t
*zone
, FILE *fd
, dns_masterformat_t format
,
9935 const dns_master_style_t
*style
,
9936 const isc_uint32_t rawversion
)
9938 return (dumptostream(zone
, fd
, style
, format
, rawversion
));
9942 dns_zone_dumptostream2(dns_zone_t
*zone
, FILE *fd
, dns_masterformat_t format
,
9943 const dns_master_style_t
*style
) {
9944 return (dumptostream(zone
, fd
, style
, format
, DNS_RAWFORMAT_VERSION
));
9948 dns_zone_dumptostream(dns_zone_t
*zone
, FILE *fd
) {
9949 return (dumptostream(zone
, fd
, &dns_master_style_default
,
9950 dns_masterformat_text
, 0));
9954 dns_zone_fulldumptostream(dns_zone_t
*zone
, FILE *fd
) {
9955 return (dumptostream(zone
, fd
, &dns_master_style_full
,
9956 dns_masterformat_text
, 0));
9960 dns_zone_unload(dns_zone_t
*zone
) {
9961 REQUIRE(DNS_ZONE_VALID(zone
));
9969 notify_cancel(dns_zone_t
*zone
) {
9970 dns_notify_t
*notify
;
9973 * 'zone' locked by caller.
9976 REQUIRE(LOCKED_ZONE(zone
));
9978 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
9980 notify
= ISC_LIST_NEXT(notify
, link
)) {
9981 if (notify
->find
!= NULL
)
9982 dns_adb_cancelfind(notify
->find
);
9983 if (notify
->request
!= NULL
)
9984 dns_request_cancel(notify
->request
);
9989 forward_cancel(dns_zone_t
*zone
) {
9990 dns_forward_t
*forward
;
9993 * 'zone' locked by caller.
9996 REQUIRE(LOCKED_ZONE(zone
));
9998 for (forward
= ISC_LIST_HEAD(zone
->forwards
);
10000 forward
= ISC_LIST_NEXT(forward
, link
)) {
10001 if (forward
->request
!= NULL
)
10002 dns_request_cancel(forward
->request
);
10007 zone_unload(dns_zone_t
*zone
) {
10009 * 'zone' locked by caller.
10012 REQUIRE(LOCKED_ZONE(zone
));
10014 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) ||
10015 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
10016 if (zone
->writeio
!= NULL
)
10017 zonemgr_cancelio(zone
->writeio
);
10019 if (zone
->dctx
!= NULL
)
10020 dns_dumpctx_cancel(zone
->dctx
);
10022 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
10023 zone_detachdb(zone
);
10024 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
10025 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_LOADED
);
10026 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
10030 dns_zone_setminrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
10031 REQUIRE(DNS_ZONE_VALID(zone
));
10034 zone
->minrefresh
= val
;
10038 dns_zone_setmaxrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
10039 REQUIRE(DNS_ZONE_VALID(zone
));
10042 zone
->maxrefresh
= val
;
10046 dns_zone_setminretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
10047 REQUIRE(DNS_ZONE_VALID(zone
));
10050 zone
->minretry
= val
;
10054 dns_zone_setmaxretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
10055 REQUIRE(DNS_ZONE_VALID(zone
));
10058 zone
->maxretry
= val
;
10061 static isc_boolean_t
10062 notify_isqueued(dns_zone_t
*zone
, unsigned int flags
, dns_name_t
*name
,
10063 isc_sockaddr_t
*addr
, dns_tsigkey_t
*key
)
10065 dns_notify_t
*notify
;
10066 dns_zonemgr_t
*zmgr
;
10067 isc_result_t result
;
10069 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
10071 notify
= ISC_LIST_NEXT(notify
, link
)) {
10072 if (notify
->request
!= NULL
)
10074 if ((flags
& DNS_NOTIFY_STARTUP
) == 0)
10075 notify
->flags
&= ~DNS_NOTIFY_STARTUP
;
10076 if (name
!= NULL
&& dns_name_dynamic(¬ify
->ns
) &&
10077 dns_name_equal(name
, ¬ify
->ns
))
10079 if (addr
!= NULL
&& isc_sockaddr_equal(addr
, ¬ify
->dst
) &&
10080 notify
->key
== key
)
10083 return (ISC_FALSE
);
10087 * If we are enqueued on the startup ratelimiter and this is
10088 * not a startup notify, re-enqueue on the normal notify
10091 if (notify
->event
!= NULL
&& (flags
& DNS_NOTIFY_STARTUP
) == 0) {
10092 zmgr
= notify
->zone
->zmgr
;
10093 result
= isc_ratelimiter_dequeue(zmgr
->startupnotifyrl
,
10095 if (result
!= ISC_R_SUCCESS
)
10097 result
= isc_ratelimiter_enqueue(notify
->zone
->zmgr
->notifyrl
,
10098 notify
->zone
->task
,
10100 if (result
!= ISC_R_SUCCESS
) {
10101 isc_event_free(¬ify
->event
);
10102 return (ISC_FALSE
);
10109 static isc_boolean_t
10110 notify_isself(dns_zone_t
*zone
, isc_sockaddr_t
*dst
) {
10111 dns_tsigkey_t
*key
= NULL
;
10112 isc_sockaddr_t src
;
10113 isc_sockaddr_t any
;
10114 isc_boolean_t isself
;
10115 isc_netaddr_t dstaddr
;
10116 isc_result_t result
;
10118 if (zone
->view
== NULL
|| zone
->isself
== NULL
)
10119 return (ISC_FALSE
);
10121 switch (isc_sockaddr_pf(dst
)) {
10123 src
= zone
->notifysrc4
;
10124 isc_sockaddr_any(&any
);
10127 src
= zone
->notifysrc6
;
10128 isc_sockaddr_any6(&any
);
10131 return (ISC_FALSE
);
10135 * When sending from any the kernel will assign a source address
10136 * that matches the destination address.
10138 if (isc_sockaddr_eqaddr(&any
, &src
))
10141 isc_netaddr_fromsockaddr(&dstaddr
, dst
);
10142 result
= dns_view_getpeertsig(zone
->view
, &dstaddr
, &key
);
10143 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
)
10144 return (ISC_FALSE
);
10145 isself
= (zone
->isself
)(zone
->view
, key
, &src
, dst
, zone
->rdclass
,
10148 dns_tsigkey_detach(&key
);
10153 notify_destroy(dns_notify_t
*notify
, isc_boolean_t locked
) {
10157 * Caller holds zone lock.
10159 REQUIRE(DNS_NOTIFY_VALID(notify
));
10161 if (notify
->zone
!= NULL
) {
10163 LOCK_ZONE(notify
->zone
);
10164 REQUIRE(LOCKED_ZONE(notify
->zone
));
10165 if (ISC_LINK_LINKED(notify
, link
))
10166 ISC_LIST_UNLINK(notify
->zone
->notifies
, notify
, link
);
10168 UNLOCK_ZONE(notify
->zone
);
10170 zone_idetach(¬ify
->zone
);
10172 dns_zone_idetach(¬ify
->zone
);
10174 if (notify
->find
!= NULL
)
10175 dns_adb_destroyfind(¬ify
->find
);
10176 if (notify
->request
!= NULL
)
10177 dns_request_destroy(¬ify
->request
);
10178 if (dns_name_dynamic(¬ify
->ns
))
10179 dns_name_free(¬ify
->ns
, notify
->mctx
);
10180 if (notify
->key
!= NULL
)
10181 dns_tsigkey_detach(¬ify
->key
);
10182 mctx
= notify
->mctx
;
10183 isc_mem_put(notify
->mctx
, notify
, sizeof(*notify
));
10184 isc_mem_detach(&mctx
);
10187 static isc_result_t
10188 notify_create(isc_mem_t
*mctx
, unsigned int flags
, dns_notify_t
**notifyp
) {
10189 dns_notify_t
*notify
;
10191 REQUIRE(notifyp
!= NULL
&& *notifyp
== NULL
);
10193 notify
= isc_mem_get(mctx
, sizeof(*notify
));
10194 if (notify
== NULL
)
10195 return (ISC_R_NOMEMORY
);
10197 notify
->mctx
= NULL
;
10198 isc_mem_attach(mctx
, ¬ify
->mctx
);
10199 notify
->flags
= flags
;
10200 notify
->zone
= NULL
;
10201 notify
->find
= NULL
;
10202 notify
->request
= NULL
;
10203 notify
->key
= NULL
;
10204 notify
->event
= NULL
;
10205 isc_sockaddr_any(¬ify
->dst
);
10206 dns_name_init(¬ify
->ns
, NULL
);
10207 ISC_LINK_INIT(notify
, link
);
10208 notify
->magic
= NOTIFY_MAGIC
;
10210 return (ISC_R_SUCCESS
);
10214 * XXXAG should check for DNS_ZONEFLG_EXITING
10217 process_adb_event(isc_task_t
*task
, isc_event_t
*ev
) {
10218 dns_notify_t
*notify
;
10219 isc_eventtype_t result
;
10223 notify
= ev
->ev_arg
;
10224 REQUIRE(DNS_NOTIFY_VALID(notify
));
10225 INSIST(task
== notify
->zone
->task
);
10226 result
= ev
->ev_type
;
10227 isc_event_free(&ev
);
10228 if (result
== DNS_EVENT_ADBMOREADDRESSES
) {
10229 dns_adb_destroyfind(¬ify
->find
);
10230 notify_find_address(notify
);
10233 if (result
== DNS_EVENT_ADBNOMOREADDRESSES
) {
10234 LOCK_ZONE(notify
->zone
);
10235 notify_send(notify
);
10236 UNLOCK_ZONE(notify
->zone
);
10238 notify_destroy(notify
, ISC_FALSE
);
10242 notify_find_address(dns_notify_t
*notify
) {
10243 isc_result_t result
;
10244 unsigned int options
;
10246 REQUIRE(DNS_NOTIFY_VALID(notify
));
10247 options
= DNS_ADBFIND_WANTEVENT
| DNS_ADBFIND_INET
|
10248 DNS_ADBFIND_INET6
| DNS_ADBFIND_RETURNLAME
;
10250 if (notify
->zone
->view
->adb
== NULL
)
10253 result
= dns_adb_createfind(notify
->zone
->view
->adb
,
10254 notify
->zone
->task
,
10255 process_adb_event
, notify
,
10256 ¬ify
->ns
, dns_rootname
, 0,
10258 notify
->zone
->view
->dstport
,
10261 /* Something failed? */
10262 if (result
!= ISC_R_SUCCESS
)
10265 /* More addresses pending? */
10266 if ((notify
->find
->options
& DNS_ADBFIND_WANTEVENT
) != 0)
10269 /* We have as many addresses as we can get. */
10270 LOCK_ZONE(notify
->zone
);
10271 notify_send(notify
);
10272 UNLOCK_ZONE(notify
->zone
);
10275 notify_destroy(notify
, ISC_FALSE
);
10279 static isc_result_t
10280 notify_send_queue(dns_notify_t
*notify
, isc_boolean_t startup
) {
10282 isc_result_t result
;
10284 INSIST(notify
->event
== NULL
);
10285 e
= isc_event_allocate(notify
->mctx
, NULL
, DNS_EVENT_NOTIFYSENDTOADDR
,
10286 notify_send_toaddr
, notify
, sizeof(isc_event_t
));
10288 return (ISC_R_NOMEMORY
);
10291 e
->ev_arg
= notify
;
10292 e
->ev_sender
= NULL
;
10293 result
= isc_ratelimiter_enqueue(startup
10294 ? notify
->zone
->zmgr
->startupnotifyrl
10295 : notify
->zone
->zmgr
->notifyrl
,
10296 notify
->zone
->task
, &e
);
10297 if (result
!= ISC_R_SUCCESS
) {
10298 isc_event_free(&e
);
10299 notify
->event
= NULL
;
10305 notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
) {
10306 dns_notify_t
*notify
;
10307 isc_result_t result
;
10308 dns_message_t
*message
= NULL
;
10309 isc_netaddr_t dstip
;
10310 dns_tsigkey_t
*key
= NULL
;
10311 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
10312 isc_sockaddr_t src
;
10314 isc_boolean_t have_notifysource
= ISC_FALSE
;
10315 isc_boolean_t have_notifydscp
= ISC_FALSE
;
10316 isc_dscp_t dscp
= -1;
10318 notify
= event
->ev_arg
;
10319 REQUIRE(DNS_NOTIFY_VALID(notify
));
10323 LOCK_ZONE(notify
->zone
);
10325 notify
->event
= NULL
;
10327 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_LOADED
) == 0) {
10328 result
= ISC_R_CANCELED
;
10332 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0 ||
10333 DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_EXITING
) ||
10334 notify
->zone
->view
->requestmgr
== NULL
||
10335 notify
->zone
->db
== NULL
) {
10336 result
= ISC_R_CANCELED
;
10341 * The raw IPv4 address should also exist. Don't send to the
10344 if (isc_sockaddr_pf(¬ify
->dst
) == PF_INET6
&&
10345 IN6_IS_ADDR_V4MAPPED(¬ify
->dst
.type
.sin6
.sin6_addr
)) {
10346 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
10347 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
10348 "notify: ignoring IPv6 mapped IPV4 address: %s",
10350 result
= ISC_R_CANCELED
;
10354 result
= notify_createmessage(notify
->zone
, notify
->flags
, &message
);
10355 if (result
!= ISC_R_SUCCESS
)
10358 if (notify
->key
!= NULL
) {
10359 /* Transfer ownership of key */
10361 notify
->key
= NULL
;
10363 isc_netaddr_fromsockaddr(&dstip
, ¬ify
->dst
);
10364 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
10365 result
= dns_view_getpeertsig(notify
->zone
->view
, &dstip
, &key
);
10366 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
10367 notify_log(notify
->zone
, ISC_LOG_ERROR
,
10368 "NOTIFY to %s not sent. "
10369 "Peer TSIG key lookup failure.", addrbuf
);
10370 goto cleanup_message
;
10374 /* XXX: should we log the tsig key too? */
10375 notify_log(notify
->zone
, ISC_LOG_DEBUG(3), "sending notify to %s",
10377 if (notify
->zone
->view
->peers
!= NULL
) {
10378 dns_peer_t
*peer
= NULL
;
10379 result
= dns_peerlist_peerbyaddr(notify
->zone
->view
->peers
,
10381 if (result
== ISC_R_SUCCESS
) {
10382 result
= dns_peer_getnotifysource(peer
, &src
);
10383 if (result
== ISC_R_SUCCESS
)
10384 have_notifysource
= ISC_TRUE
;
10385 dns_peer_getnotifydscp(peer
, &dscp
);
10387 have_notifydscp
= ISC_TRUE
;
10390 switch (isc_sockaddr_pf(¬ify
->dst
)) {
10392 if (!have_notifysource
)
10393 src
= notify
->zone
->notifysrc4
;
10394 if (!have_notifydscp
)
10395 dscp
= notify
->zone
->notifysrc4dscp
;
10398 if (!have_notifysource
)
10399 src
= notify
->zone
->notifysrc6
;
10400 if (!have_notifydscp
)
10401 dscp
= notify
->zone
->notifysrc6dscp
;
10404 result
= ISC_R_NOTIMPLEMENTED
;
10408 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_DIALNOTIFY
))
10410 result
= dns_request_createvia4(notify
->zone
->view
->requestmgr
,
10411 message
, &src
, ¬ify
->dst
, dscp
,
10412 0, key
, timeout
* 3, timeout
, 0,
10413 notify
->zone
->task
, notify_done
,
10414 notify
, ¬ify
->request
);
10415 if (result
== ISC_R_SUCCESS
) {
10416 if (isc_sockaddr_pf(¬ify
->dst
) == AF_INET
) {
10417 inc_stats(notify
->zone
,
10418 dns_zonestatscounter_notifyoutv4
);
10420 inc_stats(notify
->zone
,
10421 dns_zonestatscounter_notifyoutv6
);
10427 dns_tsigkey_detach(&key
);
10429 dns_message_destroy(&message
);
10431 UNLOCK_ZONE(notify
->zone
);
10432 isc_event_free(&event
);
10433 if (result
!= ISC_R_SUCCESS
)
10434 notify_destroy(notify
, ISC_FALSE
);
10438 notify_send(dns_notify_t
*notify
) {
10439 dns_adbaddrinfo_t
*ai
;
10440 isc_sockaddr_t dst
;
10441 isc_result_t result
;
10442 dns_notify_t
*new = NULL
;
10443 unsigned int flags
;
10444 isc_boolean_t startup
;
10447 * Zone lock held by caller.
10449 REQUIRE(DNS_NOTIFY_VALID(notify
));
10450 REQUIRE(LOCKED_ZONE(notify
->zone
));
10452 for (ai
= ISC_LIST_HEAD(notify
->find
->list
);
10454 ai
= ISC_LIST_NEXT(ai
, publink
)) {
10455 dst
= ai
->sockaddr
;
10456 if (notify_isqueued(notify
->zone
, notify
->flags
, NULL
, &dst
,
10459 if (notify_isself(notify
->zone
, &dst
))
10462 flags
= notify
->flags
& DNS_NOTIFY_NOSOA
;
10463 result
= notify_create(notify
->mctx
, flags
, &new);
10464 if (result
!= ISC_R_SUCCESS
)
10466 zone_iattach(notify
->zone
, &new->zone
);
10467 ISC_LIST_APPEND(new->zone
->notifies
, new, link
);
10469 startup
= ISC_TF((notify
->flags
& DNS_NOTIFY_STARTUP
) != 0);
10470 result
= notify_send_queue(new, startup
);
10471 if (result
!= ISC_R_SUCCESS
)
10478 notify_destroy(new, ISC_TRUE
);
10482 dns_zone_notify(dns_zone_t
*zone
) {
10485 REQUIRE(DNS_ZONE_VALID(zone
));
10488 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
10491 zone_settimer(zone
, &now
);
10496 zone_notify(dns_zone_t
*zone
, isc_time_t
*now
) {
10497 dns_dbnode_t
*node
= NULL
;
10498 dns_db_t
*zonedb
= NULL
;
10499 dns_dbversion_t
*version
= NULL
;
10500 dns_name_t
*origin
= NULL
;
10503 dns_rdata_soa_t soa
;
10504 isc_uint32_t serial
;
10505 dns_rdata_t rdata
= DNS_RDATA_INIT
;
10506 dns_rdataset_t nsrdset
;
10507 dns_rdataset_t soardset
;
10508 isc_result_t result
;
10510 isc_sockaddr_t dst
;
10511 isc_boolean_t isqueued
;
10512 dns_notifytype_t notifytype
;
10513 unsigned int flags
= 0;
10514 isc_boolean_t loggednotify
= ISC_FALSE
;
10515 isc_boolean_t startup
;
10517 REQUIRE(DNS_ZONE_VALID(zone
));
10520 startup
= !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
10521 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
10522 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDSTARTUPNOTIFY
);
10523 notifytype
= zone
->notifytype
;
10524 DNS_ZONE_TIME_ADD(now
, zone
->notifydelay
, &zone
->notifytime
);
10527 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
10530 if (notifytype
== dns_notifytype_no
)
10533 if (notifytype
== dns_notifytype_masteronly
&&
10534 zone
->type
!= dns_zone_master
)
10537 origin
= &zone
->origin
;
10540 * If the zone is dialup we are done as we don't want to send
10541 * the current soa so as to force a refresh query.
10543 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
10544 flags
|= DNS_NOTIFY_NOSOA
;
10547 * Record that this was a notify due to starting up.
10550 flags
|= DNS_NOTIFY_STARTUP
;
10555 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
10556 if (zone
->db
!= NULL
)
10557 dns_db_attach(zone
->db
, &zonedb
);
10558 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
10559 if (zonedb
== NULL
)
10561 dns_db_currentversion(zonedb
, &version
);
10562 result
= dns_db_findnode(zonedb
, origin
, ISC_FALSE
, &node
);
10563 if (result
!= ISC_R_SUCCESS
)
10566 dns_rdataset_init(&soardset
);
10567 result
= dns_db_findrdataset(zonedb
, node
, version
, dns_rdatatype_soa
,
10568 dns_rdatatype_none
, 0, &soardset
, NULL
);
10569 if (result
!= ISC_R_SUCCESS
)
10573 * Find serial and master server's name.
10575 dns_name_init(&master
, NULL
);
10576 result
= dns_rdataset_first(&soardset
);
10577 if (result
!= ISC_R_SUCCESS
)
10579 dns_rdataset_current(&soardset
, &rdata
);
10580 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
10581 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
10582 dns_rdata_reset(&rdata
);
10583 result
= dns_name_dup(&soa
.origin
, zone
->mctx
, &master
);
10584 serial
= soa
.serial
;
10585 dns_rdataset_disassociate(&soardset
);
10586 if (result
!= ISC_R_SUCCESS
)
10590 * Enqueue notify requests for 'also-notify' servers.
10593 for (i
= 0; i
< zone
->notifycnt
; i
++) {
10594 dns_tsigkey_t
*key
= NULL
;
10595 dns_notify_t
*notify
= NULL
;
10597 if ((zone
->notifykeynames
!= NULL
) &&
10598 (zone
->notifykeynames
[i
] != NULL
)) {
10599 dns_view_t
*view
= dns_zone_getview(zone
);
10600 dns_name_t
*keyname
= zone
->notifykeynames
[i
];
10601 (void)dns_view_gettsig(view
, keyname
, &key
);
10604 dst
= zone
->notify
[i
];
10605 if (notify_isqueued(zone
, flags
, NULL
, &dst
, key
)) {
10607 dns_tsigkey_detach(&key
);
10611 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
10612 if (result
!= ISC_R_SUCCESS
) {
10614 dns_tsigkey_detach(&key
);
10618 zone_iattach(zone
, ¬ify
->zone
);
10621 INSIST(notify
->key
== NULL
);
10628 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
10629 result
= notify_send_queue(notify
, startup
);
10630 if (result
!= ISC_R_SUCCESS
)
10631 notify_destroy(notify
, ISC_TRUE
);
10632 if (!loggednotify
) {
10633 notify_log(zone
, ISC_LOG_INFO
,
10634 "sending notifies (serial %u)",
10636 loggednotify
= ISC_TRUE
;
10641 if (notifytype
== dns_notifytype_explicit
)
10645 * Process NS RRset to generate notifies.
10648 dns_rdataset_init(&nsrdset
);
10649 result
= dns_db_findrdataset(zonedb
, node
, version
, dns_rdatatype_ns
,
10650 dns_rdatatype_none
, 0, &nsrdset
, NULL
);
10651 if (result
!= ISC_R_SUCCESS
)
10654 result
= dns_rdataset_first(&nsrdset
);
10655 while (result
== ISC_R_SUCCESS
) {
10656 dns_notify_t
*notify
= NULL
;
10658 dns_rdataset_current(&nsrdset
, &rdata
);
10659 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
10660 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
10661 dns_rdata_reset(&rdata
);
10663 * Don't notify the master server unless explicitly
10664 * configured to do so.
10666 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOTIFYTOSOA
) &&
10667 dns_name_compare(&master
, &ns
.name
) == 0) {
10668 result
= dns_rdataset_next(&nsrdset
);
10672 if (!loggednotify
) {
10673 notify_log(zone
, ISC_LOG_INFO
,
10674 "sending notifies (serial %u)",
10676 loggednotify
= ISC_TRUE
;
10680 isqueued
= notify_isqueued(zone
, flags
, &ns
.name
, NULL
, NULL
);
10683 result
= dns_rdataset_next(&nsrdset
);
10686 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
10687 if (result
!= ISC_R_SUCCESS
)
10689 dns_zone_iattach(zone
, ¬ify
->zone
);
10690 result
= dns_name_dup(&ns
.name
, zone
->mctx
, ¬ify
->ns
);
10691 if (result
!= ISC_R_SUCCESS
) {
10693 notify_destroy(notify
, ISC_TRUE
);
10698 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
10700 notify_find_address(notify
);
10701 result
= dns_rdataset_next(&nsrdset
);
10703 dns_rdataset_disassociate(&nsrdset
);
10706 if (dns_name_dynamic(&master
))
10707 dns_name_free(&master
, zone
->mctx
);
10709 dns_db_detachnode(zonedb
, &node
);
10711 dns_db_closeversion(zonedb
, &version
, ISC_FALSE
);
10712 dns_db_detach(&zonedb
);
10719 static inline isc_result_t
10720 save_nsrrset(dns_message_t
*message
, dns_name_t
*name
,
10721 dns_db_t
*db
, dns_dbversion_t
*version
)
10723 dns_rdataset_t
*nsrdataset
= NULL
;
10724 dns_rdataset_t
*rdataset
= NULL
;
10725 dns_dbnode_t
*node
= NULL
;
10727 isc_result_t result
;
10728 dns_rdata_t rdata
= DNS_RDATA_INIT
;
10731 * Extract NS RRset from message.
10733 result
= dns_message_findname(message
, DNS_SECTION_ANSWER
, name
,
10734 dns_rdatatype_ns
, dns_rdatatype_none
,
10735 NULL
, &nsrdataset
);
10736 if (result
!= ISC_R_SUCCESS
)
10742 result
= dns_db_findnode(db
, name
, ISC_TRUE
, &node
);
10743 if (result
!= ISC_R_SUCCESS
)
10745 result
= dns_db_addrdataset(db
, node
, version
, 0,
10746 nsrdataset
, 0, NULL
);
10747 dns_db_detachnode(db
, &node
);
10748 if (result
!= ISC_R_SUCCESS
)
10751 * Add glue rdatasets.
10753 for (result
= dns_rdataset_first(nsrdataset
);
10754 result
== ISC_R_SUCCESS
;
10755 result
= dns_rdataset_next(nsrdataset
)) {
10756 dns_rdataset_current(nsrdataset
, &rdata
);
10757 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
10758 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
10759 dns_rdata_reset(&rdata
);
10760 if (!dns_name_issubdomain(&ns
.name
, name
))
10763 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
10764 &ns
.name
, dns_rdatatype_aaaa
,
10765 dns_rdatatype_none
, NULL
,
10767 if (result
== ISC_R_SUCCESS
) {
10768 result
= dns_db_findnode(db
, &ns
.name
,
10770 if (result
!= ISC_R_SUCCESS
)
10772 result
= dns_db_addrdataset(db
, node
, version
, 0,
10773 rdataset
, 0, NULL
);
10774 dns_db_detachnode(db
, &node
);
10775 if (result
!= ISC_R_SUCCESS
)
10779 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
10780 &ns
.name
, dns_rdatatype_a
,
10781 dns_rdatatype_none
, NULL
,
10783 if (result
== ISC_R_SUCCESS
) {
10784 result
= dns_db_findnode(db
, &ns
.name
,
10786 if (result
!= ISC_R_SUCCESS
)
10788 result
= dns_db_addrdataset(db
, node
, version
, 0,
10789 rdataset
, 0, NULL
);
10790 dns_db_detachnode(db
, &node
);
10791 if (result
!= ISC_R_SUCCESS
)
10795 if (result
!= ISC_R_NOMORE
)
10798 return (ISC_R_SUCCESS
);
10805 stub_callback(isc_task_t
*task
, isc_event_t
*event
) {
10806 const char me
[] = "stub_callback";
10807 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
10808 dns_stub_t
*stub
= NULL
;
10809 dns_message_t
*msg
= NULL
;
10810 dns_zone_t
*zone
= NULL
;
10811 char master
[ISC_SOCKADDR_FORMATSIZE
];
10812 char source
[ISC_SOCKADDR_FORMATSIZE
];
10813 isc_uint32_t nscnt
, cnamecnt
, refresh
, retry
, expire
;
10814 isc_result_t result
;
10816 isc_boolean_t exiting
= ISC_FALSE
;
10818 unsigned int j
, soacount
;
10820 stub
= revent
->ev_arg
;
10821 INSIST(DNS_STUB_VALID(stub
));
10833 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
10834 zone_debuglog(zone
, me
, 1, "exiting");
10835 exiting
= ISC_TRUE
;
10839 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
10840 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
10842 if (revent
->result
!= ISC_R_SUCCESS
) {
10843 if (revent
->result
== ISC_R_TIMEDOUT
&&
10844 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
10845 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
10846 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
10847 "refreshing stub: timeout retrying "
10848 " without EDNS master %s (source %s)",
10852 dns_zonemgr_unreachableadd(zone
->zmgr
, &zone
->masteraddr
,
10853 &zone
->sourceaddr
, &now
);
10854 dns_zone_log(zone
, ISC_LOG_INFO
,
10855 "could not refresh stub from master %s"
10856 " (source %s): %s", master
, source
,
10857 dns_result_totext(revent
->result
));
10861 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
10862 if (result
!= ISC_R_SUCCESS
)
10865 result
= dns_request_getresponse(revent
->request
, msg
, 0);
10866 if (result
!= ISC_R_SUCCESS
)
10870 * Unexpected rcode.
10872 if (msg
->rcode
!= dns_rcode_noerror
) {
10876 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
10877 (void)dns_rcode_totext(msg
->rcode
, &rb
);
10879 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
) &&
10880 (msg
->rcode
== dns_rcode_servfail
||
10881 msg
->rcode
== dns_rcode_notimp
||
10882 msg
->rcode
== dns_rcode_formerr
)) {
10883 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
10884 "refreshing stub: rcode (%.*s) retrying "
10885 "without EDNS master %s (source %s)",
10886 (int)rb
.used
, rcode
, master
, source
);
10887 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
10891 dns_zone_log(zone
, ISC_LOG_INFO
,
10892 "refreshing stub: "
10893 "unexpected rcode (%.*s) from %s (source %s)",
10894 (int)rb
.used
, rcode
, master
, source
);
10899 * We need complete messages.
10901 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
10902 if (dns_request_usedtcp(revent
->request
)) {
10903 dns_zone_log(zone
, ISC_LOG_INFO
,
10904 "refreshing stub: truncated TCP "
10905 "response from master %s (source %s)",
10909 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
10914 * If non-auth log and next master.
10916 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
10917 dns_zone_log(zone
, ISC_LOG_INFO
, "refreshing stub: "
10918 "non-authoritative answer from "
10919 "master %s (source %s)", master
, source
);
10926 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
10927 nscnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_ns
);
10929 if (cnamecnt
!= 0) {
10930 dns_zone_log(zone
, ISC_LOG_INFO
,
10931 "refreshing stub: unexpected CNAME response "
10932 "from master %s (source %s)", master
, source
);
10937 dns_zone_log(zone
, ISC_LOG_INFO
,
10938 "refreshing stub: no NS records in response "
10939 "from master %s (source %s)", master
, source
);
10946 result
= save_nsrrset(msg
, &zone
->origin
, stub
->db
, stub
->version
);
10947 if (result
!= ISC_R_SUCCESS
) {
10948 dns_zone_log(zone
, ISC_LOG_INFO
,
10949 "refreshing stub: unable to save NS records "
10950 "from master %s (source %s)", master
, source
);
10957 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_TRUE
);
10958 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
10959 if (zone
->db
== NULL
)
10960 zone_attachdb(zone
, stub
->db
);
10961 result
= zone_get_from_db(zone
, zone
->db
, NULL
, &soacount
, NULL
,
10962 &refresh
, &retry
, &expire
, NULL
, NULL
);
10963 if (result
== ISC_R_SUCCESS
&& soacount
> 0U) {
10964 zone
->refresh
= RANGE(refresh
, zone
->minrefresh
,
10966 zone
->retry
= RANGE(retry
, zone
->minretry
, zone
->maxretry
);
10967 zone
->expire
= RANGE(expire
, zone
->refresh
+ zone
->retry
,
10969 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
10971 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
10972 dns_db_detach(&stub
->db
);
10974 dns_message_destroy(&msg
);
10975 isc_event_free(&event
);
10976 dns_request_destroy(&zone
->request
);
10978 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
10979 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
);
10980 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
, &zone
->refreshtime
);
10981 isc_interval_set(&i
, zone
->expire
, 0);
10982 DNS_ZONE_TIME_ADD(&now
, zone
->expire
, &zone
->expiretime
);
10984 if (zone
->masterfile
!= NULL
)
10985 zone_needdump(zone
, 0);
10987 zone_settimer(zone
, &now
);
10991 if (stub
->version
!= NULL
)
10992 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_FALSE
);
10993 if (stub
->db
!= NULL
)
10994 dns_db_detach(&stub
->db
);
10996 dns_message_destroy(&msg
);
10997 isc_event_free(&event
);
10998 dns_request_destroy(&zone
->request
);
11000 * Skip to next failed / untried master.
11004 } while (zone
->curmaster
< zone
->masterscnt
&&
11005 zone
->mastersok
[zone
->curmaster
]);
11006 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
11007 if (exiting
|| zone
->curmaster
>= zone
->masterscnt
) {
11008 isc_boolean_t done
= ISC_TRUE
;
11010 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
11011 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
11013 * Did we get a good answer from all the masters?
11015 for (j
= 0; j
< zone
->masterscnt
; j
++)
11016 if (zone
->mastersok
[j
] == ISC_FALSE
) {
11023 zone
->curmaster
= 0;
11025 * Find the next failed master.
11027 while (zone
->curmaster
< zone
->masterscnt
&&
11028 zone
->mastersok
[zone
->curmaster
])
11030 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
11032 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
11034 zone_settimer(zone
, &now
);
11038 queue_soa_query(zone
);
11043 dns_message_destroy(&msg
);
11044 isc_event_free(&event
);
11045 dns_request_destroy(&zone
->request
);
11046 ns_query(zone
, NULL
, stub
);
11053 dns_zone_idetach(&stub
->zone
);
11054 INSIST(stub
->db
== NULL
);
11055 INSIST(stub
->version
== NULL
);
11056 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
11059 INSIST(event
== NULL
);
11064 * An SOA query has finished (successfully or not).
11067 refresh_callback(isc_task_t
*task
, isc_event_t
*event
) {
11068 const char me
[] = "refresh_callback";
11069 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
11071 dns_message_t
*msg
= NULL
;
11072 isc_uint32_t soacnt
, cnamecnt
, soacount
, nscount
;
11074 char master
[ISC_SOCKADDR_FORMATSIZE
];
11075 char source
[ISC_SOCKADDR_FORMATSIZE
];
11076 dns_rdataset_t
*rdataset
= NULL
;
11077 dns_rdata_t rdata
= DNS_RDATA_INIT
;
11078 dns_rdata_soa_t soa
;
11079 isc_result_t result
;
11080 isc_uint32_t serial
, oldserial
= 0;
11082 isc_boolean_t do_queue_xfrin
= ISC_FALSE
;
11084 zone
= revent
->ev_arg
;
11085 INSIST(DNS_ZONE_VALID(zone
));
11095 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
11096 isc_event_free(&event
);
11097 dns_request_destroy(&zone
->request
);
11102 * if timeout log and next master;
11105 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
11106 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
11108 if (revent
->result
!= ISC_R_SUCCESS
) {
11109 if (revent
->result
== ISC_R_TIMEDOUT
&&
11110 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
11111 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
11112 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11113 "refresh: timeout retrying without EDNS "
11114 "master %s (source %s)", master
, source
);
11117 if (revent
->result
== ISC_R_TIMEDOUT
&&
11118 !dns_request_usedtcp(revent
->request
)) {
11119 dns_zone_log(zone
, ISC_LOG_INFO
,
11120 "refresh: retry limit for "
11121 "master %s exceeded (source %s)",
11123 /* Try with slave with TCP. */
11124 if ((zone
->type
== dns_zone_slave
||
11125 zone
->type
== dns_zone_redirect
) &&
11126 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_TRYTCPREFRESH
)) {
11127 if (!dns_zonemgr_unreachable(zone
->zmgr
,
11132 DNS_ZONE_SETFLAG(zone
,
11133 DNS_ZONEFLG_SOABEFOREAXFR
);
11136 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11137 "refresh: skipped tcp fallback "
11138 "as master %s (source %s) is "
11139 "unreachable (cached)",
11143 dns_zone_log(zone
, ISC_LOG_INFO
,
11144 "refresh: failure trying master "
11145 "%s (source %s): %s", master
, source
,
11146 dns_result_totext(revent
->result
));
11150 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
11151 if (result
!= ISC_R_SUCCESS
)
11153 result
= dns_request_getresponse(revent
->request
, msg
, 0);
11154 if (result
!= ISC_R_SUCCESS
) {
11155 dns_zone_log(zone
, ISC_LOG_INFO
,
11156 "refresh: failure trying master "
11157 "%s (source %s): %s", master
, source
,
11158 dns_result_totext(result
));
11163 * Unexpected rcode.
11165 if (msg
->rcode
!= dns_rcode_noerror
) {
11169 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
11170 (void)dns_rcode_totext(msg
->rcode
, &rb
);
11172 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
) &&
11173 (msg
->rcode
== dns_rcode_servfail
||
11174 msg
->rcode
== dns_rcode_notimp
||
11175 msg
->rcode
== dns_rcode_formerr
)) {
11176 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
11177 "refresh: rcode (%.*s) retrying without "
11178 "EDNS master %s (source %s)",
11179 (int)rb
.used
, rcode
, master
, source
);
11180 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
11183 dns_zone_log(zone
, ISC_LOG_INFO
,
11184 "refresh: unexpected rcode (%.*s) from "
11185 "master %s (source %s)", (int)rb
.used
, rcode
,
11188 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
11190 if (msg
->rcode
== dns_rcode_refused
&&
11191 (zone
->type
== dns_zone_slave
||
11192 zone
->type
== dns_zone_redirect
))
11198 * If truncated punt to zone transfer which will query again.
11200 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
11201 if (zone
->type
== dns_zone_slave
||
11202 zone
->type
== dns_zone_redirect
) {
11203 dns_zone_log(zone
, ISC_LOG_INFO
,
11204 "refresh: truncated UDP answer, "
11205 "initiating TCP zone xfer "
11206 "for master %s (source %s)",
11208 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
);
11211 INSIST(zone
->type
== dns_zone_stub
);
11212 if (dns_request_usedtcp(revent
->request
)) {
11213 dns_zone_log(zone
, ISC_LOG_INFO
,
11214 "refresh: truncated TCP response "
11215 "from master %s (source %s)",
11219 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
11225 * if non-auth log and next master;
11227 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
11228 dns_zone_log(zone
, ISC_LOG_INFO
,
11229 "refresh: non-authoritative answer from "
11230 "master %s (source %s)", master
, source
);
11234 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
11235 soacnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_soa
);
11236 nscount
= message_count(msg
, DNS_SECTION_AUTHORITY
, dns_rdatatype_ns
);
11237 soacount
= message_count(msg
, DNS_SECTION_AUTHORITY
,
11238 dns_rdatatype_soa
);
11241 * There should not be a CNAME record at top of zone.
11243 if (cnamecnt
!= 0) {
11244 dns_zone_log(zone
, ISC_LOG_INFO
,
11245 "refresh: CNAME at top of zone "
11246 "in master %s (source %s)", master
, source
);
11251 * if referral log and next master;
11253 if (soacnt
== 0 && soacount
== 0 && nscount
!= 0) {
11254 dns_zone_log(zone
, ISC_LOG_INFO
,
11255 "refresh: referral response "
11256 "from master %s (source %s)", master
, source
);
11261 * if nodata log and next master;
11263 if (soacnt
== 0 && (nscount
== 0 || soacount
!= 0)) {
11264 dns_zone_log(zone
, ISC_LOG_INFO
,
11265 "refresh: NODATA response "
11266 "from master %s (source %s)", master
, source
);
11271 * Only one soa at top of zone.
11274 dns_zone_log(zone
, ISC_LOG_INFO
,
11275 "refresh: answer SOA count (%d) != 1 "
11276 "from master %s (source %s)",
11277 soacnt
, master
, source
);
11285 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
, &zone
->origin
,
11286 dns_rdatatype_soa
, dns_rdatatype_none
,
11288 if (result
!= ISC_R_SUCCESS
) {
11289 dns_zone_log(zone
, ISC_LOG_INFO
,
11290 "refresh: unable to get SOA record "
11291 "from master %s (source %s)", master
, source
);
11295 result
= dns_rdataset_first(rdataset
);
11296 if (result
!= ISC_R_SUCCESS
) {
11297 dns_zone_log(zone
, ISC_LOG_INFO
,
11298 "refresh: dns_rdataset_first() failed");
11302 dns_rdataset_current(rdataset
, &rdata
);
11303 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
11304 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
11306 serial
= soa
.serial
;
11307 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
11308 unsigned int dbsoacount
;
11309 result
= zone_get_from_db(zone
, zone
->db
, NULL
, &dbsoacount
,
11310 &oldserial
, NULL
, NULL
, NULL
, NULL
,
11312 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
11313 RUNTIME_CHECK(dbsoacount
> 0U);
11314 zone_debuglog(zone
, me
, 1, "serial: new %u, old %u",
11315 serial
, oldserial
);
11317 zone_debuglog(zone
, me
, 1, "serial: new %u, old not loaded",
11320 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) ||
11321 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
) ||
11322 isc_serial_gt(serial
, oldserial
)) {
11323 if (dns_zonemgr_unreachable(zone
->zmgr
, &zone
->masteraddr
,
11324 &zone
->sourceaddr
, &now
))
11326 dns_zone_log(zone
, ISC_LOG_INFO
,
11327 "refresh: skipping %s as master %s "
11328 "(source %s) is unreachable (cached)",
11329 (zone
->type
== dns_zone_slave
||
11330 zone
->type
== dns_zone_redirect
) ?
11331 "zone transfer" : "NS query",
11336 isc_event_free(&event
);
11337 dns_request_destroy(&zone
->request
);
11338 if (zone
->type
== dns_zone_slave
||
11339 zone
->type
== dns_zone_redirect
) {
11340 do_queue_xfrin
= ISC_TRUE
;
11342 INSIST(zone
->type
== dns_zone_stub
);
11343 ns_query(zone
, rdataset
, NULL
);
11346 dns_message_destroy(&msg
);
11347 } else if (isc_serial_eq(soa
.serial
, oldserial
)) {
11348 if (zone
->masterfile
!= NULL
) {
11349 result
= ISC_R_FAILURE
;
11350 if (zone
->journal
!= NULL
)
11351 result
= isc_file_settime(zone
->journal
, &now
);
11352 if (result
== ISC_R_SUCCESS
&&
11353 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
11354 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
11355 result
= isc_file_settime(zone
->masterfile
,
11357 } else if (result
!= ISC_R_SUCCESS
)
11358 result
= isc_file_settime(zone
->masterfile
,
11360 /* Someone removed the file from underneath us! */
11361 if (result
== ISC_R_FILENOTFOUND
) {
11362 zone_needdump(zone
, DNS_DUMP_DELAY
);
11363 } else if (result
!= ISC_R_SUCCESS
)
11364 dns_zone_log(zone
, ISC_LOG_ERROR
,
11365 "refresh: could not set file "
11366 "modification time of '%s': %s",
11368 dns_result_totext(result
));
11370 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
, &zone
->refreshtime
);
11371 DNS_ZONE_TIME_ADD(&now
, zone
->expire
, &zone
->expiretime
);
11372 zone
->mastersok
[zone
->curmaster
] = ISC_TRUE
;
11375 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MULTIMASTER
))
11376 dns_zone_log(zone
, ISC_LOG_INFO
, "serial number (%u) "
11377 "received from master %s < ours (%u)",
11378 soa
.serial
, master
, oldserial
);
11380 zone_debuglog(zone
, me
, 1, "ahead");
11381 zone
->mastersok
[zone
->curmaster
] = ISC_TRUE
;
11385 dns_message_destroy(&msg
);
11390 dns_message_destroy(&msg
);
11391 isc_event_free(&event
);
11392 dns_request_destroy(&zone
->request
);
11394 * Skip to next failed / untried master.
11398 } while (zone
->curmaster
< zone
->masterscnt
&&
11399 zone
->mastersok
[zone
->curmaster
]);
11400 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
11401 if (zone
->curmaster
>= zone
->masterscnt
) {
11402 isc_boolean_t done
= ISC_TRUE
;
11403 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
11404 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
11406 * Did we get a good answer from all the masters?
11408 for (j
= 0; j
< zone
->masterscnt
; j
++)
11409 if (zone
->mastersok
[j
] == ISC_FALSE
) {
11416 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
11417 zone
->curmaster
= 0;
11419 * Find the next failed master.
11421 while (zone
->curmaster
< zone
->masterscnt
&&
11422 zone
->mastersok
[zone
->curmaster
])
11426 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
11427 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
11428 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
11429 zone
->refreshtime
= now
;
11431 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
11432 zone_settimer(zone
, &now
);
11437 queue_soa_query(zone
);
11442 dns_message_destroy(&msg
);
11443 isc_event_free(&event
);
11444 dns_request_destroy(&zone
->request
);
11445 queue_soa_query(zone
);
11449 if (do_queue_xfrin
)
11451 dns_zone_idetach(&zone
);
11456 queue_soa_query(dns_zone_t
*zone
) {
11457 const char me
[] = "queue_soa_query";
11459 dns_zone_t
*dummy
= NULL
;
11460 isc_result_t result
;
11466 REQUIRE(LOCKED_ZONE(zone
));
11468 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
11469 cancel_refresh(zone
);
11473 e
= isc_event_allocate(zone
->mctx
, NULL
, DNS_EVENT_ZONE
,
11474 soa_query
, zone
, sizeof(isc_event_t
));
11476 cancel_refresh(zone
);
11481 * Attach so that we won't clean up
11482 * until the event is delivered.
11484 zone_iattach(zone
, &dummy
);
11487 e
->ev_sender
= NULL
;
11488 result
= isc_ratelimiter_enqueue(zone
->zmgr
->refreshrl
, zone
->task
, &e
);
11489 if (result
!= ISC_R_SUCCESS
) {
11490 zone_idetach(&dummy
);
11491 isc_event_free(&e
);
11492 cancel_refresh(zone
);
11496 static inline isc_result_t
11497 create_query(dns_zone_t
*zone
, dns_rdatatype_t rdtype
,
11498 dns_message_t
**messagep
)
11500 dns_message_t
*message
= NULL
;
11501 dns_name_t
*qname
= NULL
;
11502 dns_rdataset_t
*qrdataset
= NULL
;
11503 isc_result_t result
;
11505 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
11507 if (result
!= ISC_R_SUCCESS
)
11510 message
->opcode
= dns_opcode_query
;
11511 message
->rdclass
= zone
->rdclass
;
11513 result
= dns_message_gettempname(message
, &qname
);
11514 if (result
!= ISC_R_SUCCESS
)
11517 result
= dns_message_gettemprdataset(message
, &qrdataset
);
11518 if (result
!= ISC_R_SUCCESS
)
11524 dns_name_init(qname
, NULL
);
11525 dns_name_clone(&zone
->origin
, qname
);
11526 dns_rdataset_makequestion(qrdataset
, zone
->rdclass
, rdtype
);
11527 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
11528 dns_message_addname(message
, qname
, DNS_SECTION_QUESTION
);
11530 *messagep
= message
;
11531 return (ISC_R_SUCCESS
);
11535 dns_message_puttempname(message
, &qname
);
11536 if (qrdataset
!= NULL
)
11537 dns_message_puttemprdataset(message
, &qrdataset
);
11538 if (message
!= NULL
)
11539 dns_message_destroy(&message
);
11543 static isc_result_t
11544 add_opt(dns_message_t
*message
, isc_uint16_t udpsize
, isc_boolean_t reqnsid
) {
11545 isc_result_t result
;
11546 dns_rdataset_t
*rdataset
= NULL
;
11547 dns_ednsopt_t ednsopts
[DNS_EDNSOPTIONS
];
11550 /* Set EDNS options if applicable */
11552 INSIST(count
< DNS_EDNSOPTIONS
);
11553 ednsopts
[count
].code
= DNS_OPT_NSID
;
11554 ednsopts
[count
].length
= 0;
11555 ednsopts
[count
].value
= NULL
;
11558 result
= dns_message_buildopt(message
, &rdataset
, 0, udpsize
, 0,
11560 if (result
!= ISC_R_SUCCESS
)
11563 return (dns_message_setopt(message
, rdataset
));
11567 soa_query(isc_task_t
*task
, isc_event_t
*event
) {
11568 const char me
[] = "soa_query";
11569 isc_result_t result
= ISC_R_FAILURE
;
11570 dns_message_t
*message
= NULL
;
11571 dns_zone_t
*zone
= event
->ev_arg
;
11572 dns_zone_t
*dummy
= NULL
;
11573 isc_netaddr_t masterip
;
11574 dns_tsigkey_t
*key
= NULL
;
11575 isc_uint32_t options
;
11576 isc_boolean_t cancel
= ISC_TRUE
;
11578 isc_boolean_t have_xfrsource
, have_xfrdscp
, reqnsid
;
11579 isc_uint16_t udpsize
= SEND_BUFFER_SIZE
;
11580 isc_dscp_t dscp
= -1;
11582 REQUIRE(DNS_ZONE_VALID(zone
));
11589 if (((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0) ||
11590 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
) ||
11591 zone
->view
->requestmgr
== NULL
) {
11592 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
11593 cancel
= ISC_FALSE
;
11598 result
= create_query(zone
, dns_rdatatype_soa
, &message
);
11599 if (result
!= ISC_R_SUCCESS
)
11602 INSIST(zone
->masterscnt
> 0);
11603 INSIST(zone
->curmaster
< zone
->masterscnt
);
11605 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
11607 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
11609 * First, look for a tsig key in the master statement, then
11610 * try for a server key.
11612 if ((zone
->masterkeynames
!= NULL
) &&
11613 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
11614 dns_view_t
*view
= dns_zone_getview(zone
);
11615 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
11616 result
= dns_view_gettsig(view
, keyname
, &key
);
11617 if (result
!= ISC_R_SUCCESS
) {
11618 char namebuf
[DNS_NAME_FORMATSIZE
];
11619 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
11620 dns_zone_log(zone
, ISC_LOG_ERROR
,
11621 "unable to find key: %s", namebuf
);
11626 result
= dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
11627 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
11628 char addrbuf
[ISC_NETADDR_FORMATSIZE
];
11629 isc_netaddr_format(&masterip
, addrbuf
, sizeof(addrbuf
));
11630 dns_zone_log(zone
, ISC_LOG_ERROR
,
11631 "unable to find TSIG key for %s", addrbuf
);
11636 have_xfrsource
= have_xfrdscp
= ISC_FALSE
;
11637 reqnsid
= zone
->view
->requestnsid
;
11638 if (zone
->view
->peers
!= NULL
) {
11639 dns_peer_t
*peer
= NULL
;
11640 isc_boolean_t edns
;
11641 result
= dns_peerlist_peerbyaddr(zone
->view
->peers
,
11643 if (result
== ISC_R_SUCCESS
) {
11644 result
= dns_peer_getsupportedns(peer
, &edns
);
11645 if (result
== ISC_R_SUCCESS
&& !edns
)
11646 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
11647 result
= dns_peer_gettransfersource(peer
,
11648 &zone
->sourceaddr
);
11649 if (result
== ISC_R_SUCCESS
)
11650 have_xfrsource
= ISC_TRUE
;
11651 (void)dns_peer_gettransferdscp(peer
, &dscp
);
11653 have_xfrdscp
= ISC_TRUE
;
11654 if (zone
->view
->resolver
!= NULL
)
11656 dns_resolver_getudpsize(zone
->view
->resolver
);
11657 (void)dns_peer_getudpsize(peer
, &udpsize
);
11658 (void)dns_peer_getrequestnsid(peer
, &reqnsid
);
11662 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
11664 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
11665 if (isc_sockaddr_equal(&zone
->altxfrsource4
,
11666 &zone
->xfrsource4
))
11668 zone
->sourceaddr
= zone
->altxfrsource4
;
11670 dscp
= zone
->altxfrsource4dscp
;
11671 } else if (!have_xfrsource
) {
11672 zone
->sourceaddr
= zone
->xfrsource4
;
11674 dscp
= zone
->xfrsource4dscp
;
11678 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
11679 if (isc_sockaddr_equal(&zone
->altxfrsource6
,
11680 &zone
->xfrsource6
))
11682 zone
->sourceaddr
= zone
->altxfrsource6
;
11684 dscp
= zone
->altxfrsource6dscp
;
11685 } else if (!have_xfrsource
) {
11686 zone
->sourceaddr
= zone
->xfrsource6
;
11688 dscp
= zone
->xfrsource6dscp
;
11692 result
= ISC_R_NOTIMPLEMENTED
;
11696 options
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEVC
) ?
11697 DNS_REQUESTOPT_TCP
: 0;
11699 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
11700 result
= add_opt(message
, udpsize
, reqnsid
);
11701 if (result
!= ISC_R_SUCCESS
)
11702 zone_debuglog(zone
, me
, 1,
11703 "unable to add opt record: %s",
11704 dns_result_totext(result
));
11707 zone_iattach(zone
, &dummy
);
11709 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
11711 result
= dns_request_createvia4(zone
->view
->requestmgr
, message
,
11712 &zone
->sourceaddr
, &zone
->masteraddr
,
11713 dscp
, options
, key
, timeout
* 3,
11714 timeout
, 0, zone
->task
,
11715 refresh_callback
, zone
, &zone
->request
);
11716 if (result
!= ISC_R_SUCCESS
) {
11717 zone_idetach(&dummy
);
11718 zone_debuglog(zone
, me
, 1,
11719 "dns_request_createvia4() failed: %s",
11720 dns_result_totext(result
));
11723 if (isc_sockaddr_pf(&zone
->masteraddr
) == PF_INET
)
11724 inc_stats(zone
, dns_zonestatscounter_soaoutv4
);
11726 inc_stats(zone
, dns_zonestatscounter_soaoutv6
);
11728 cancel
= ISC_FALSE
;
11732 dns_tsigkey_detach(&key
);
11733 if (result
!= ISC_R_SUCCESS
)
11734 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
11735 if (message
!= NULL
)
11736 dns_message_destroy(&message
);
11738 cancel_refresh(zone
);
11739 isc_event_free(&event
);
11741 dns_zone_idetach(&zone
);
11746 dns_tsigkey_detach(&key
);
11747 dns_message_destroy(&message
);
11749 * Skip to next failed / untried master.
11753 } while (zone
->curmaster
< zone
->masterscnt
&&
11754 zone
->mastersok
[zone
->curmaster
]);
11755 if (zone
->curmaster
< zone
->masterscnt
)
11757 zone
->curmaster
= 0;
11762 ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
, dns_stub_t
*stub
) {
11763 const char me
[] = "ns_query";
11764 isc_result_t result
;
11765 dns_message_t
*message
= NULL
;
11766 isc_netaddr_t masterip
;
11767 dns_tsigkey_t
*key
= NULL
;
11768 dns_dbnode_t
*node
= NULL
;
11770 isc_boolean_t have_xfrsource
= ISC_FALSE
, have_xfrdscp
= ISC_FALSE
;
11771 isc_boolean_t reqnsid
;
11772 isc_uint16_t udpsize
= SEND_BUFFER_SIZE
;
11773 isc_dscp_t dscp
= -1;
11775 REQUIRE(DNS_ZONE_VALID(zone
));
11776 REQUIRE(LOCKED_ZONE(zone
));
11777 REQUIRE((soardataset
!= NULL
&& stub
== NULL
) ||
11778 (soardataset
== NULL
&& stub
!= NULL
));
11779 REQUIRE(stub
== NULL
|| DNS_STUB_VALID(stub
));
11783 if (stub
== NULL
) {
11784 stub
= isc_mem_get(zone
->mctx
, sizeof(*stub
));
11787 stub
->magic
= STUB_MAGIC
;
11788 stub
->mctx
= zone
->mctx
;
11791 stub
->version
= NULL
;
11794 * Attach so that the zone won't disappear from under us.
11796 zone_iattach(zone
, &stub
->zone
);
11799 * If a db exists we will update it, otherwise we create a
11800 * new one and attach it to the zone once we have the NS
11803 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
11804 if (zone
->db
!= NULL
) {
11805 dns_db_attach(zone
->db
, &stub
->db
);
11806 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
11808 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
11810 INSIST(zone
->db_argc
>= 1);
11811 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
11812 &zone
->origin
, dns_dbtype_stub
,
11817 if (result
!= ISC_R_SUCCESS
) {
11818 dns_zone_log(zone
, ISC_LOG_ERROR
,
11819 "refreshing stub: "
11820 "could not create "
11822 dns_result_totext(result
));
11825 dns_db_settask(stub
->db
, zone
->task
);
11828 result
= dns_db_newversion(stub
->db
, &stub
->version
);
11829 if (result
!= ISC_R_SUCCESS
) {
11830 dns_zone_log(zone
, ISC_LOG_INFO
, "refreshing stub: "
11831 "dns_db_newversion() failed: %s",
11832 dns_result_totext(result
));
11837 * Update SOA record.
11839 result
= dns_db_findnode(stub
->db
, &zone
->origin
, ISC_TRUE
,
11841 if (result
!= ISC_R_SUCCESS
) {
11842 dns_zone_log(zone
, ISC_LOG_INFO
, "refreshing stub: "
11843 "dns_db_findnode() failed: %s",
11844 dns_result_totext(result
));
11848 result
= dns_db_addrdataset(stub
->db
, node
, stub
->version
, 0,
11849 soardataset
, 0, NULL
);
11850 dns_db_detachnode(stub
->db
, &node
);
11851 if (result
!= ISC_R_SUCCESS
) {
11852 dns_zone_log(zone
, ISC_LOG_INFO
,
11853 "refreshing stub: "
11854 "dns_db_addrdataset() failed: %s",
11855 dns_result_totext(result
));
11861 * XXX Optimisation: Create message when zone is setup and reuse.
11863 result
= create_query(zone
, dns_rdatatype_ns
, &message
);
11864 INSIST(result
== ISC_R_SUCCESS
);
11866 INSIST(zone
->masterscnt
> 0);
11867 INSIST(zone
->curmaster
< zone
->masterscnt
);
11868 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
11870 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
11872 * First, look for a tsig key in the master statement, then
11873 * try for a server key.
11875 if ((zone
->masterkeynames
!= NULL
) &&
11876 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
11877 dns_view_t
*view
= dns_zone_getview(zone
);
11878 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
11879 result
= dns_view_gettsig(view
, keyname
, &key
);
11880 if (result
!= ISC_R_SUCCESS
) {
11881 char namebuf
[DNS_NAME_FORMATSIZE
];
11882 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
11883 dns_zone_log(zone
, ISC_LOG_ERROR
,
11884 "unable to find key: %s", namebuf
);
11888 (void)dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
11890 reqnsid
= zone
->view
->requestnsid
;
11891 if (zone
->view
->peers
!= NULL
) {
11892 dns_peer_t
*peer
= NULL
;
11893 isc_boolean_t edns
;
11894 result
= dns_peerlist_peerbyaddr(zone
->view
->peers
,
11896 if (result
== ISC_R_SUCCESS
) {
11897 result
= dns_peer_getsupportedns(peer
, &edns
);
11898 if (result
== ISC_R_SUCCESS
&& !edns
)
11899 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
11900 result
= dns_peer_gettransfersource(peer
,
11901 &zone
->sourceaddr
);
11902 if (result
== ISC_R_SUCCESS
)
11903 have_xfrsource
= ISC_TRUE
;
11904 result
= dns_peer_gettransferdscp(peer
, &dscp
);
11905 if (result
== ISC_R_SUCCESS
&& dscp
!= -1)
11906 have_xfrdscp
= ISC_TRUE
;
11907 if (zone
->view
->resolver
!= NULL
)
11909 dns_resolver_getudpsize(zone
->view
->resolver
);
11910 (void)dns_peer_getudpsize(peer
, &udpsize
);
11911 (void)dns_peer_getrequestnsid(peer
, &reqnsid
);
11915 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
11916 result
= add_opt(message
, udpsize
, reqnsid
);
11917 if (result
!= ISC_R_SUCCESS
)
11918 zone_debuglog(zone
, me
, 1,
11919 "unable to add opt record: %s",
11920 dns_result_totext(result
));
11924 * Always use TCP so that we shouldn't truncate in additional section.
11926 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
11928 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
11929 zone
->sourceaddr
= zone
->altxfrsource4
;
11931 dscp
= zone
->altxfrsource4dscp
;
11932 } else if (!have_xfrsource
) {
11933 zone
->sourceaddr
= zone
->xfrsource4
;
11935 dscp
= zone
->xfrsource4dscp
;
11939 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
11940 zone
->sourceaddr
= zone
->altxfrsource6
;
11942 dscp
= zone
->altxfrsource6dscp
;
11943 } else if (!have_xfrsource
) {
11944 zone
->sourceaddr
= zone
->xfrsource6
;
11946 dscp
= zone
->xfrsource6dscp
;
11950 result
= ISC_R_NOTIMPLEMENTED
;
11955 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
11957 result
= dns_request_createvia4(zone
->view
->requestmgr
, message
,
11958 &zone
->sourceaddr
, &zone
->masteraddr
,
11959 dscp
, DNS_REQUESTOPT_TCP
, key
,
11960 timeout
* 3, timeout
, 0, zone
->task
,
11961 stub_callback
, stub
, &zone
->request
);
11962 if (result
!= ISC_R_SUCCESS
) {
11963 zone_debuglog(zone
, me
, 1,
11964 "dns_request_createvia() failed: %s",
11965 dns_result_totext(result
));
11968 dns_message_destroy(&message
);
11972 cancel_refresh(zone
);
11973 if (stub
!= NULL
) {
11975 if (stub
->version
!= NULL
)
11976 dns_db_closeversion(stub
->db
, &stub
->version
,
11978 if (stub
->db
!= NULL
)
11979 dns_db_detach(&stub
->db
);
11980 if (stub
->zone
!= NULL
)
11981 zone_idetach(&stub
->zone
);
11982 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
11984 if (message
!= NULL
)
11985 dns_message_destroy(&message
);
11988 dns_tsigkey_detach(&key
);
11993 * Handle the control event. Note that although this event causes the zone
11994 * to shut down, it is not a shutdown event in the sense of the task library.
11997 zone_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
11998 dns_zone_t
*zone
= (dns_zone_t
*) event
->ev_arg
;
11999 isc_boolean_t free_needed
, linked
= ISC_FALSE
;
12000 dns_zone_t
*raw
= NULL
, *secure
= NULL
;
12003 REQUIRE(DNS_ZONE_VALID(zone
));
12004 INSIST(event
->ev_type
== DNS_EVENT_ZONECONTROL
);
12005 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
12007 zone_debuglog(zone
, "zone_shutdown", 3, "shutting down");
12010 * Stop things being restarted after we cancel them below.
12013 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXITING
);
12017 * If we were waiting for xfrin quota, step out of
12019 * If there's no zone manager, we can't be waiting for the
12022 if (zone
->zmgr
!= NULL
) {
12023 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
12024 if (zone
->statelist
== &zone
->zmgr
->waiting_for_xfrin
) {
12025 ISC_LIST_UNLINK(zone
->zmgr
->waiting_for_xfrin
, zone
,
12028 zone
->statelist
= NULL
;
12030 if (zone
->statelist
== &zone
->zmgr
->xfrin_in_progress
) {
12031 ISC_LIST_UNLINK(zone
->zmgr
->xfrin_in_progress
, zone
,
12033 zone
->statelist
= NULL
;
12034 zmgr_resume_xfrs(zone
->zmgr
, ISC_FALSE
);
12036 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
12040 * In task context, no locking required. See zone_xfrdone().
12042 if (zone
->xfr
!= NULL
)
12043 dns_xfrin_shutdown(zone
->xfr
);
12045 /* Safe to release the zone now */
12046 if (zone
->zmgr
!= NULL
)
12047 dns_zonemgr_releasezone(zone
->zmgr
, zone
);
12050 INSIST(zone
!= zone
->raw
);
12052 INSIST(zone
->irefs
> 0);
12055 if (zone
->request
!= NULL
) {
12056 dns_request_cancel(zone
->request
);
12059 if (zone
->readio
!= NULL
)
12060 zonemgr_cancelio(zone
->readio
);
12062 if (zone
->lctx
!= NULL
)
12063 dns_loadctx_cancel(zone
->lctx
);
12065 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) ||
12066 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
12067 if (zone
->writeio
!= NULL
)
12068 zonemgr_cancelio(zone
->writeio
);
12070 if (zone
->dctx
!= NULL
)
12071 dns_dumpctx_cancel(zone
->dctx
);
12074 notify_cancel(zone
);
12076 forward_cancel(zone
);
12078 if (zone
->timer
!= NULL
) {
12079 isc_timer_detach(&zone
->timer
);
12080 INSIST(zone
->irefs
> 0);
12084 if (zone
->view
!= NULL
)
12085 dns_view_weakdetach(&zone
->view
);
12088 * We have now canceled everything set the flag to allow exit_check()
12089 * to succeed. We must not unlock between setting this flag and
12090 * calling exit_check().
12092 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SHUTDOWN
);
12093 free_needed
= exit_check(zone
);
12094 if (inline_secure(zone
)) {
12098 if (inline_raw(zone
)) {
12099 secure
= zone
->secure
;
12100 zone
->secure
= NULL
;
12104 dns_zone_detach(&raw
);
12105 if (secure
!= NULL
)
12106 dns_zone_idetach(&secure
);
12112 zone_timer(isc_task_t
*task
, isc_event_t
*event
) {
12113 const char me
[] = "zone_timer";
12114 dns_zone_t
*zone
= (dns_zone_t
*)event
->ev_arg
;
12117 REQUIRE(DNS_ZONE_VALID(zone
));
12121 zone_maintenance(zone
);
12123 isc_event_free(&event
);
12127 zone_settimer(dns_zone_t
*zone
, isc_time_t
*now
) {
12128 const char me
[] = "zone_settimer";
12130 isc_result_t result
;
12132 REQUIRE(DNS_ZONE_VALID(zone
));
12135 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
12138 isc_time_settoepoch(&next
);
12140 switch (zone
->type
) {
12141 case dns_zone_redirect
:
12142 if (zone
->masters
!= NULL
)
12143 goto treat_as_slave
;
12146 case dns_zone_master
:
12147 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
) ||
12148 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDSTARTUPNOTIFY
))
12149 next
= zone
->notifytime
;
12150 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
12151 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
12152 INSIST(!isc_time_isepoch(&zone
->dumptime
));
12153 if (isc_time_isepoch(&next
) ||
12154 isc_time_compare(&zone
->dumptime
, &next
) < 0)
12155 next
= zone
->dumptime
;
12157 if (zone
->type
== dns_zone_redirect
)
12159 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESHING
) &&
12160 !isc_time_isepoch(&zone
->refreshkeytime
)) {
12161 if (isc_time_isepoch(&next
) ||
12162 isc_time_compare(&zone
->refreshkeytime
, &next
) < 0)
12163 next
= zone
->refreshkeytime
;
12165 if (!isc_time_isepoch(&zone
->resigntime
)) {
12166 if (isc_time_isepoch(&next
) ||
12167 isc_time_compare(&zone
->resigntime
, &next
) < 0)
12168 next
= zone
->resigntime
;
12170 if (!isc_time_isepoch(&zone
->keywarntime
)) {
12171 if (isc_time_isepoch(&next
) ||
12172 isc_time_compare(&zone
->keywarntime
, &next
) < 0)
12173 next
= zone
->keywarntime
;
12175 if (!isc_time_isepoch(&zone
->signingtime
)) {
12176 if (isc_time_isepoch(&next
) ||
12177 isc_time_compare(&zone
->signingtime
, &next
) < 0)
12178 next
= zone
->signingtime
;
12180 if (!isc_time_isepoch(&zone
->nsec3chaintime
)) {
12181 if (isc_time_isepoch(&next
) ||
12182 isc_time_compare(&zone
->nsec3chaintime
, &next
) < 0)
12183 next
= zone
->nsec3chaintime
;
12187 case dns_zone_slave
:
12189 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
12190 next
= zone
->notifytime
;
12193 case dns_zone_stub
:
12194 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
) &&
12195 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOMASTERS
) &&
12196 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
) &&
12197 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
) &&
12198 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADPENDING
) &&
12199 !isc_time_isepoch(&zone
->refreshtime
) &&
12200 (isc_time_isepoch(&next
) ||
12201 isc_time_compare(&zone
->refreshtime
, &next
) < 0))
12202 next
= zone
->refreshtime
;
12203 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
12204 !isc_time_isepoch(&zone
->expiretime
)) {
12205 if (isc_time_isepoch(&next
) ||
12206 isc_time_compare(&zone
->expiretime
, &next
) < 0)
12207 next
= zone
->expiretime
;
12209 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
12210 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
12211 INSIST(!isc_time_isepoch(&zone
->dumptime
));
12212 if (isc_time_isepoch(&next
) ||
12213 isc_time_compare(&zone
->dumptime
, &next
) < 0)
12214 next
= zone
->dumptime
;
12219 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
12220 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
12221 INSIST(!isc_time_isepoch(&zone
->dumptime
));
12222 if (isc_time_isepoch(&next
) ||
12223 isc_time_compare(&zone
->dumptime
, &next
) < 0)
12224 next
= zone
->dumptime
;
12226 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESHING
)) {
12227 if (isc_time_isepoch(&next
) ||
12228 (!isc_time_isepoch(&zone
->refreshkeytime
) &&
12229 isc_time_compare(&zone
->refreshkeytime
, &next
) < 0))
12230 next
= zone
->refreshkeytime
;
12238 if (isc_time_isepoch(&next
)) {
12239 zone_debuglog(zone
, me
, 10, "settimer inactive");
12240 result
= isc_timer_reset(zone
->timer
, isc_timertype_inactive
,
12241 NULL
, NULL
, ISC_TRUE
);
12242 if (result
!= ISC_R_SUCCESS
)
12243 dns_zone_log(zone
, ISC_LOG_ERROR
,
12244 "could not deactivate zone timer: %s",
12245 isc_result_totext(result
));
12247 if (isc_time_compare(&next
, now
) <= 0)
12249 result
= isc_timer_reset(zone
->timer
, isc_timertype_once
,
12250 &next
, NULL
, ISC_TRUE
);
12251 if (result
!= ISC_R_SUCCESS
)
12252 dns_zone_log(zone
, ISC_LOG_ERROR
,
12253 "could not reset zone timer: %s",
12254 isc_result_totext(result
));
12259 cancel_refresh(dns_zone_t
*zone
) {
12260 const char me
[] = "cancel_refresh";
12264 * 'zone' locked by caller.
12267 REQUIRE(DNS_ZONE_VALID(zone
));
12268 REQUIRE(LOCKED_ZONE(zone
));
12272 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
12274 zone_settimer(zone
, &now
);
12277 static isc_result_t
12278 notify_createmessage(dns_zone_t
*zone
, unsigned int flags
,
12279 dns_message_t
**messagep
)
12281 dns_db_t
*zonedb
= NULL
;
12282 dns_dbnode_t
*node
= NULL
;
12283 dns_dbversion_t
*version
= NULL
;
12284 dns_message_t
*message
= NULL
;
12285 dns_rdataset_t rdataset
;
12286 dns_rdata_t rdata
= DNS_RDATA_INIT
;
12288 dns_name_t
*tempname
= NULL
;
12289 dns_rdata_t
*temprdata
= NULL
;
12290 dns_rdatalist_t
*temprdatalist
= NULL
;
12291 dns_rdataset_t
*temprdataset
= NULL
;
12293 isc_result_t result
;
12295 isc_buffer_t
*b
= NULL
;
12297 REQUIRE(DNS_ZONE_VALID(zone
));
12298 REQUIRE(messagep
!= NULL
&& *messagep
== NULL
);
12300 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
12302 if (result
!= ISC_R_SUCCESS
)
12305 message
->opcode
= dns_opcode_notify
;
12306 message
->flags
|= DNS_MESSAGEFLAG_AA
;
12307 message
->rdclass
= zone
->rdclass
;
12309 result
= dns_message_gettempname(message
, &tempname
);
12310 if (result
!= ISC_R_SUCCESS
)
12313 result
= dns_message_gettemprdataset(message
, &temprdataset
);
12314 if (result
!= ISC_R_SUCCESS
)
12320 dns_name_init(tempname
, NULL
);
12321 dns_name_clone(&zone
->origin
, tempname
);
12322 dns_rdataset_makequestion(temprdataset
, zone
->rdclass
,
12323 dns_rdatatype_soa
);
12324 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
12325 dns_message_addname(message
, tempname
, DNS_SECTION_QUESTION
);
12327 temprdataset
= NULL
;
12329 if ((flags
& DNS_NOTIFY_NOSOA
) != 0)
12332 result
= dns_message_gettempname(message
, &tempname
);
12333 if (result
!= ISC_R_SUCCESS
)
12335 result
= dns_message_gettemprdata(message
, &temprdata
);
12336 if (result
!= ISC_R_SUCCESS
)
12338 result
= dns_message_gettemprdataset(message
, &temprdataset
);
12339 if (result
!= ISC_R_SUCCESS
)
12341 result
= dns_message_gettemprdatalist(message
, &temprdatalist
);
12342 if (result
!= ISC_R_SUCCESS
)
12345 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
12346 INSIST(zone
->db
!= NULL
); /* XXXJT: is this assumption correct? */
12347 dns_db_attach(zone
->db
, &zonedb
);
12348 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
12350 dns_name_init(tempname
, NULL
);
12351 dns_name_clone(&zone
->origin
, tempname
);
12352 dns_db_currentversion(zonedb
, &version
);
12353 result
= dns_db_findnode(zonedb
, tempname
, ISC_FALSE
, &node
);
12354 if (result
!= ISC_R_SUCCESS
)
12357 dns_rdataset_init(&rdataset
);
12358 result
= dns_db_findrdataset(zonedb
, node
, version
,
12360 dns_rdatatype_none
, 0, &rdataset
,
12362 if (result
!= ISC_R_SUCCESS
)
12364 result
= dns_rdataset_first(&rdataset
);
12365 if (result
!= ISC_R_SUCCESS
)
12367 dns_rdataset_current(&rdataset
, &rdata
);
12368 dns_rdata_toregion(&rdata
, &r
);
12369 result
= isc_buffer_allocate(zone
->mctx
, &b
, r
.length
);
12370 if (result
!= ISC_R_SUCCESS
)
12372 isc_buffer_putmem(b
, r
.base
, r
.length
);
12373 isc_buffer_usedregion(b
, &r
);
12374 dns_rdata_init(temprdata
);
12375 dns_rdata_fromregion(temprdata
, rdata
.rdclass
, rdata
.type
, &r
);
12376 dns_message_takebuffer(message
, &b
);
12377 result
= dns_rdataset_next(&rdataset
);
12378 dns_rdataset_disassociate(&rdataset
);
12379 if (result
!= ISC_R_NOMORE
)
12381 temprdatalist
->rdclass
= rdata
.rdclass
;
12382 temprdatalist
->type
= rdata
.type
;
12383 temprdatalist
->covers
= 0;
12384 temprdatalist
->ttl
= rdataset
.ttl
;
12385 ISC_LIST_INIT(temprdatalist
->rdata
);
12386 ISC_LIST_APPEND(temprdatalist
->rdata
, temprdata
, link
);
12388 result
= dns_rdatalist_tordataset(temprdatalist
, temprdataset
);
12389 if (result
!= ISC_R_SUCCESS
)
12392 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
12393 dns_message_addname(message
, tempname
, DNS_SECTION_ANSWER
);
12394 temprdatalist
= NULL
;
12395 temprdataset
= NULL
;
12401 dns_db_detachnode(zonedb
, &node
);
12402 if (version
!= NULL
)
12403 dns_db_closeversion(zonedb
, &version
, ISC_FALSE
);
12404 if (zonedb
!= NULL
)
12405 dns_db_detach(&zonedb
);
12406 if (tempname
!= NULL
)
12407 dns_message_puttempname(message
, &tempname
);
12408 if (temprdata
!= NULL
)
12409 dns_message_puttemprdata(message
, &temprdata
);
12410 if (temprdataset
!= NULL
)
12411 dns_message_puttemprdataset(message
, &temprdataset
);
12412 if (temprdatalist
!= NULL
)
12413 dns_message_puttemprdatalist(message
, &temprdatalist
);
12416 *messagep
= message
;
12417 return (ISC_R_SUCCESS
);
12420 if (tempname
!= NULL
)
12421 dns_message_puttempname(message
, &tempname
);
12422 if (temprdataset
!= NULL
)
12423 dns_message_puttemprdataset(message
, &temprdataset
);
12424 dns_message_destroy(&message
);
12429 dns_zone_notifyreceive(dns_zone_t
*zone
, isc_sockaddr_t
*from
,
12430 dns_message_t
*msg
)
12433 dns_rdata_soa_t soa
;
12434 dns_rdataset_t
*rdataset
= NULL
;
12435 dns_rdata_t rdata
= DNS_RDATA_INIT
;
12436 isc_result_t result
;
12437 char fromtext
[ISC_SOCKADDR_FORMATSIZE
];
12439 isc_netaddr_t netaddr
;
12440 isc_sockaddr_t local
, remote
;
12441 isc_uint32_t serial
= 0;
12442 isc_boolean_t have_serial
= ISC_FALSE
;
12443 dns_tsigkey_t
*tsigkey
;
12446 REQUIRE(DNS_ZONE_VALID(zone
));
12449 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
12453 * Check that 'from' is a valid notify source, (zone->masters).
12454 * Return DNS_R_REFUSED if not.
12456 * If the notify message contains a serial number check it
12457 * against the zones serial and return if <= current serial
12459 * If a refresh check is progress, if so just record the
12460 * fact we received a NOTIFY and from where and return.
12461 * We will perform a new refresh check when the current one
12462 * completes. Return ISC_R_SUCCESS.
12464 * Otherwise initiate a refresh check using 'from' as the
12465 * first address to check. Return ISC_R_SUCCESS.
12468 isc_sockaddr_format(from
, fromtext
, sizeof(fromtext
));
12471 * Notify messages are processed by the raw zone.
12474 INSIST(zone
!= zone
->raw
);
12475 if (inline_secure(zone
)) {
12476 result
= dns_zone_notifyreceive(zone
->raw
, from
, msg
);
12481 * We only handle NOTIFY (SOA) at the present.
12483 if (isc_sockaddr_pf(from
) == PF_INET
)
12484 inc_stats(zone
, dns_zonestatscounter_notifyinv4
);
12486 inc_stats(zone
, dns_zonestatscounter_notifyinv6
);
12487 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0 ||
12488 dns_message_findname(msg
, DNS_SECTION_QUESTION
, &zone
->origin
,
12489 dns_rdatatype_soa
, dns_rdatatype_none
,
12490 NULL
, NULL
) != ISC_R_SUCCESS
) {
12492 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0) {
12493 dns_zone_log(zone
, ISC_LOG_NOTICE
,
12495 "question section from: %s", fromtext
);
12496 return (DNS_R_FORMERR
);
12498 dns_zone_log(zone
, ISC_LOG_NOTICE
,
12499 "NOTIFY zone does not match");
12500 return (DNS_R_NOTIMP
);
12504 * If we are a master zone just succeed.
12506 if (zone
->type
== dns_zone_master
) {
12508 return (ISC_R_SUCCESS
);
12511 isc_netaddr_fromsockaddr(&netaddr
, from
);
12512 for (i
= 0; i
< zone
->masterscnt
; i
++) {
12513 if (isc_sockaddr_eqaddr(from
, &zone
->masters
[i
]))
12515 if (zone
->view
->aclenv
.match_mapped
&&
12516 IN6_IS_ADDR_V4MAPPED(&from
->type
.sin6
.sin6_addr
) &&
12517 isc_sockaddr_pf(&zone
->masters
[i
]) == AF_INET
) {
12518 isc_netaddr_t na1
, na2
;
12519 isc_netaddr_fromv4mapped(&na1
, &netaddr
);
12520 isc_netaddr_fromsockaddr(&na2
, &zone
->masters
[i
]);
12521 if (isc_netaddr_equal(&na1
, &na2
))
12527 * Accept notify requests from non masters if they are on
12528 * 'zone->notify_acl'.
12530 tsigkey
= dns_message_gettsigkey(msg
);
12531 tsig
= dns_tsigkey_identity(tsigkey
);
12532 if (i
>= zone
->masterscnt
&& zone
->notify_acl
!= NULL
&&
12533 dns_acl_match(&netaddr
, tsig
, zone
->notify_acl
,
12534 &zone
->view
->aclenv
,
12535 &match
, NULL
) == ISC_R_SUCCESS
&&
12538 /* Accept notify. */
12539 } else if (i
>= zone
->masterscnt
) {
12541 dns_zone_log(zone
, ISC_LOG_INFO
,
12542 "refused notify from non-master: %s", fromtext
);
12543 inc_stats(zone
, dns_zonestatscounter_notifyrej
);
12544 return (DNS_R_REFUSED
);
12548 * If the zone is loaded and there are answers check the serial
12549 * to see if we need to do a refresh. Do not worry about this
12550 * check if we are a dialup zone as we use the notify request
12551 * to trigger a refresh check.
12553 if (msg
->counts
[DNS_SECTION_ANSWER
] > 0 &&
12554 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
12555 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
)) {
12556 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
,
12559 dns_rdatatype_none
, NULL
,
12561 if (result
== ISC_R_SUCCESS
)
12562 result
= dns_rdataset_first(rdataset
);
12563 if (result
== ISC_R_SUCCESS
) {
12564 isc_uint32_t oldserial
;
12565 unsigned int soacount
;
12567 dns_rdataset_current(rdataset
, &rdata
);
12568 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
12569 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
12570 serial
= soa
.serial
;
12571 have_serial
= ISC_TRUE
;
12573 * The following should safely be performed without DB
12574 * lock and succeed in this context.
12576 result
= zone_get_from_db(zone
, zone
->db
, NULL
,
12577 &soacount
, &oldserial
, NULL
,
12578 NULL
, NULL
, NULL
, NULL
);
12579 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
12580 RUNTIME_CHECK(soacount
> 0U);
12581 if (isc_serial_le(serial
, oldserial
)) {
12585 "zone is up to date",
12588 return (ISC_R_SUCCESS
);
12594 * If we got this far and there was a refresh in progress just
12595 * let it complete. Record where we got the notify from so we
12596 * can perform a refresh check when the current one completes
12598 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
)) {
12599 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
12600 zone
->notifyfrom
= *from
;
12603 dns_zone_log(zone
, ISC_LOG_INFO
,
12604 "notify from %s: serial %u: refresh in "
12605 "progress, refresh check queued",
12608 dns_zone_log(zone
, ISC_LOG_INFO
,
12609 "notify from %s: refresh in progress, "
12610 "refresh check queued", fromtext
);
12611 return (ISC_R_SUCCESS
);
12614 dns_zone_log(zone
, ISC_LOG_INFO
, "notify from %s: serial %u",
12617 dns_zone_log(zone
, ISC_LOG_INFO
, "notify from %s: no serial",
12619 zone
->notifyfrom
= *from
;
12620 local
= zone
->masteraddr
;
12621 remote
= zone
->sourceaddr
;
12623 dns_zonemgr_unreachabledel(zone
->zmgr
, &local
, &remote
);
12624 dns_zone_refresh(zone
);
12625 return (ISC_R_SUCCESS
);
12629 dns_zone_setnotifyacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
12631 REQUIRE(DNS_ZONE_VALID(zone
));
12634 if (zone
->notify_acl
!= NULL
)
12635 dns_acl_detach(&zone
->notify_acl
);
12636 dns_acl_attach(acl
, &zone
->notify_acl
);
12641 dns_zone_setqueryacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
12643 REQUIRE(DNS_ZONE_VALID(zone
));
12646 if (zone
->query_acl
!= NULL
)
12647 dns_acl_detach(&zone
->query_acl
);
12648 dns_acl_attach(acl
, &zone
->query_acl
);
12653 dns_zone_setqueryonacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
12655 REQUIRE(DNS_ZONE_VALID(zone
));
12658 if (zone
->queryon_acl
!= NULL
)
12659 dns_acl_detach(&zone
->queryon_acl
);
12660 dns_acl_attach(acl
, &zone
->queryon_acl
);
12665 dns_zone_setupdateacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
12667 REQUIRE(DNS_ZONE_VALID(zone
));
12670 if (zone
->update_acl
!= NULL
)
12671 dns_acl_detach(&zone
->update_acl
);
12672 dns_acl_attach(acl
, &zone
->update_acl
);
12677 dns_zone_setforwardacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
12679 REQUIRE(DNS_ZONE_VALID(zone
));
12682 if (zone
->forward_acl
!= NULL
)
12683 dns_acl_detach(&zone
->forward_acl
);
12684 dns_acl_attach(acl
, &zone
->forward_acl
);
12689 dns_zone_setxfracl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
12691 REQUIRE(DNS_ZONE_VALID(zone
));
12694 if (zone
->xfr_acl
!= NULL
)
12695 dns_acl_detach(&zone
->xfr_acl
);
12696 dns_acl_attach(acl
, &zone
->xfr_acl
);
12701 dns_zone_getnotifyacl(dns_zone_t
*zone
) {
12703 REQUIRE(DNS_ZONE_VALID(zone
));
12705 return (zone
->notify_acl
);
12709 dns_zone_getqueryacl(dns_zone_t
*zone
) {
12711 REQUIRE(DNS_ZONE_VALID(zone
));
12713 return (zone
->query_acl
);
12717 dns_zone_getqueryonacl(dns_zone_t
*zone
) {
12719 REQUIRE(DNS_ZONE_VALID(zone
));
12721 return (zone
->queryon_acl
);
12725 dns_zone_getupdateacl(dns_zone_t
*zone
) {
12727 REQUIRE(DNS_ZONE_VALID(zone
));
12729 return (zone
->update_acl
);
12733 dns_zone_getforwardacl(dns_zone_t
*zone
) {
12735 REQUIRE(DNS_ZONE_VALID(zone
));
12737 return (zone
->forward_acl
);
12741 dns_zone_getxfracl(dns_zone_t
*zone
) {
12743 REQUIRE(DNS_ZONE_VALID(zone
));
12745 return (zone
->xfr_acl
);
12749 dns_zone_clearupdateacl(dns_zone_t
*zone
) {
12751 REQUIRE(DNS_ZONE_VALID(zone
));
12754 if (zone
->update_acl
!= NULL
)
12755 dns_acl_detach(&zone
->update_acl
);
12760 dns_zone_clearforwardacl(dns_zone_t
*zone
) {
12762 REQUIRE(DNS_ZONE_VALID(zone
));
12765 if (zone
->forward_acl
!= NULL
)
12766 dns_acl_detach(&zone
->forward_acl
);
12771 dns_zone_clearnotifyacl(dns_zone_t
*zone
) {
12773 REQUIRE(DNS_ZONE_VALID(zone
));
12776 if (zone
->notify_acl
!= NULL
)
12777 dns_acl_detach(&zone
->notify_acl
);
12782 dns_zone_clearqueryacl(dns_zone_t
*zone
) {
12784 REQUIRE(DNS_ZONE_VALID(zone
));
12787 if (zone
->query_acl
!= NULL
)
12788 dns_acl_detach(&zone
->query_acl
);
12793 dns_zone_clearqueryonacl(dns_zone_t
*zone
) {
12795 REQUIRE(DNS_ZONE_VALID(zone
));
12798 if (zone
->queryon_acl
!= NULL
)
12799 dns_acl_detach(&zone
->queryon_acl
);
12804 dns_zone_clearxfracl(dns_zone_t
*zone
) {
12806 REQUIRE(DNS_ZONE_VALID(zone
));
12809 if (zone
->xfr_acl
!= NULL
)
12810 dns_acl_detach(&zone
->xfr_acl
);
12815 dns_zone_getupdatedisabled(dns_zone_t
*zone
) {
12816 REQUIRE(DNS_ZONE_VALID(zone
));
12817 return (zone
->update_disabled
);
12822 dns_zone_setupdatedisabled(dns_zone_t
*zone
, isc_boolean_t state
) {
12823 REQUIRE(DNS_ZONE_VALID(zone
));
12824 zone
->update_disabled
= state
;
12828 dns_zone_getzeronosoattl(dns_zone_t
*zone
) {
12829 REQUIRE(DNS_ZONE_VALID(zone
));
12830 return (zone
->zero_no_soa_ttl
);
12835 dns_zone_setzeronosoattl(dns_zone_t
*zone
, isc_boolean_t state
) {
12836 REQUIRE(DNS_ZONE_VALID(zone
));
12837 zone
->zero_no_soa_ttl
= state
;
12841 dns_zone_setchecknames(dns_zone_t
*zone
, dns_severity_t severity
) {
12843 REQUIRE(DNS_ZONE_VALID(zone
));
12845 zone
->check_names
= severity
;
12849 dns_zone_getchecknames(dns_zone_t
*zone
) {
12851 REQUIRE(DNS_ZONE_VALID(zone
));
12853 return (zone
->check_names
);
12857 dns_zone_setjournalsize(dns_zone_t
*zone
, isc_int32_t size
) {
12859 REQUIRE(DNS_ZONE_VALID(zone
));
12861 zone
->journalsize
= size
;
12865 dns_zone_getjournalsize(dns_zone_t
*zone
) {
12867 REQUIRE(DNS_ZONE_VALID(zone
));
12869 return (zone
->journalsize
);
12873 zone_namerd_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
12874 isc_result_t result
= ISC_R_FAILURE
;
12875 isc_buffer_t buffer
;
12877 REQUIRE(buf
!= NULL
);
12878 REQUIRE(length
> 1U);
12881 * Leave space for terminating '\0'.
12883 isc_buffer_init(&buffer
, buf
, (unsigned int)length
- 1);
12884 if (zone
->type
!= dns_zone_redirect
&& zone
->type
!= dns_zone_key
) {
12885 if (dns_name_dynamic(&zone
->origin
))
12886 result
= dns_name_totext(&zone
->origin
, ISC_TRUE
, &buffer
);
12887 if (result
!= ISC_R_SUCCESS
&&
12888 isc_buffer_availablelength(&buffer
) >= (sizeof("<UNKNOWN>") - 1))
12889 isc_buffer_putstr(&buffer
, "<UNKNOWN>");
12891 if (isc_buffer_availablelength(&buffer
) > 0)
12892 isc_buffer_putstr(&buffer
, "/");
12893 (void)dns_rdataclass_totext(zone
->rdclass
, &buffer
);
12896 if (zone
->view
!= NULL
&& strcmp(zone
->view
->name
, "_bind") != 0 &&
12897 strcmp(zone
->view
->name
, "_default") != 0 &&
12898 strlen(zone
->view
->name
) < isc_buffer_availablelength(&buffer
)) {
12899 isc_buffer_putstr(&buffer
, "/");
12900 isc_buffer_putstr(&buffer
, zone
->view
->name
);
12902 if (inline_secure(zone
) && 9U < isc_buffer_availablelength(&buffer
))
12903 isc_buffer_putstr(&buffer
, " (signed)");
12904 if (inline_raw(zone
) && 11U < isc_buffer_availablelength(&buffer
))
12905 isc_buffer_putstr(&buffer
, " (unsigned)");
12907 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
12911 zone_name_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
12912 isc_result_t result
= ISC_R_FAILURE
;
12913 isc_buffer_t buffer
;
12915 REQUIRE(buf
!= NULL
);
12916 REQUIRE(length
> 1U);
12919 * Leave space for terminating '\0'.
12921 isc_buffer_init(&buffer
, buf
, (unsigned int)length
- 1);
12922 if (dns_name_dynamic(&zone
->origin
))
12923 result
= dns_name_totext(&zone
->origin
, ISC_TRUE
, &buffer
);
12924 if (result
!= ISC_R_SUCCESS
&&
12925 isc_buffer_availablelength(&buffer
) >= (sizeof("<UNKNOWN>") - 1))
12926 isc_buffer_putstr(&buffer
, "<UNKNOWN>");
12928 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
12932 zone_rdclass_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
12933 isc_buffer_t buffer
;
12935 REQUIRE(buf
!= NULL
);
12936 REQUIRE(length
> 1U);
12939 * Leave space for terminating '\0'.
12941 isc_buffer_init(&buffer
, buf
, (unsigned int)length
- 1);
12942 (void)dns_rdataclass_totext(zone
->rdclass
, &buffer
);
12944 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
12948 zone_viewname_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
12949 isc_buffer_t buffer
;
12951 REQUIRE(buf
!= NULL
);
12952 REQUIRE(length
> 1U);
12956 * Leave space for terminating '\0'.
12958 isc_buffer_init(&buffer
, buf
, (unsigned int)length
- 1);
12960 if (zone
->view
== NULL
) {
12961 isc_buffer_putstr(&buffer
, "_none");
12962 } else if (strlen(zone
->view
->name
)
12963 < isc_buffer_availablelength(&buffer
)) {
12964 isc_buffer_putstr(&buffer
, zone
->view
->name
);
12966 isc_buffer_putstr(&buffer
, "_toolong");
12969 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
12973 dns_zone_name(dns_zone_t
*zone
, char *buf
, size_t length
) {
12974 REQUIRE(DNS_ZONE_VALID(zone
));
12975 REQUIRE(buf
!= NULL
);
12976 zone_namerd_tostr(zone
, buf
, length
);
12980 notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
12982 char message
[4096];
12984 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
12988 vsnprintf(message
, sizeof(message
), fmt
, ap
);
12990 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_NOTIFY
, DNS_LOGMODULE_ZONE
,
12991 level
, "zone %s: %s", zone
->strnamerd
, message
);
12995 dns_zone_logc(dns_zone_t
*zone
, isc_logcategory_t
*category
,
12996 int level
, const char *fmt
, ...) {
12998 char message
[4096];
13000 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
13004 vsnprintf(message
, sizeof(message
), fmt
, ap
);
13006 isc_log_write(dns_lctx
, category
, DNS_LOGMODULE_ZONE
,
13007 level
, "%s%s: %s", (zone
->type
== dns_zone_key
) ?
13008 "managed-keys-zone" : (zone
->type
== dns_zone_redirect
) ?
13009 "redirect-zone" : "zone ", zone
->strnamerd
, message
);
13013 dns_zone_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
13015 char message
[4096];
13017 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
13021 vsnprintf(message
, sizeof(message
), fmt
, ap
);
13023 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
13024 level
, "%s%s: %s", (zone
->type
== dns_zone_key
) ?
13025 "managed-keys-zone" : (zone
->type
== dns_zone_redirect
) ?
13026 "redirect-zone" : "zone ", zone
->strnamerd
, message
);
13030 zone_debuglog(dns_zone_t
*zone
, const char *me
, int debuglevel
,
13031 const char *fmt
, ...)
13034 char message
[4096];
13035 int level
= ISC_LOG_DEBUG(debuglevel
);
13038 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
13042 vsnprintf(message
, sizeof(message
), fmt
, ap
);
13045 switch (zone
->type
) {
13047 zstr
= "managed-keys-zone";
13049 case dns_zone_redirect
:
13050 zstr
= "redirect-zone";
13056 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
13057 level
, "%s: %s %s: %s", me
, zstr
, zone
->strnamerd
,
13062 message_count(dns_message_t
*msg
, dns_section_t section
, dns_rdatatype_t type
)
13064 isc_result_t result
;
13066 dns_rdataset_t
*curr
;
13069 result
= dns_message_firstname(msg
, section
);
13070 while (result
== ISC_R_SUCCESS
) {
13072 dns_message_currentname(msg
, section
, &name
);
13074 for (curr
= ISC_LIST_TAIL(name
->list
); curr
!= NULL
;
13075 curr
= ISC_LIST_PREV(curr
, link
)) {
13076 if (curr
->type
== type
)
13079 result
= dns_message_nextname(msg
, section
);
13086 dns_zone_setmaxxfrin(dns_zone_t
*zone
, isc_uint32_t maxxfrin
) {
13087 REQUIRE(DNS_ZONE_VALID(zone
));
13089 zone
->maxxfrin
= maxxfrin
;
13093 dns_zone_getmaxxfrin(dns_zone_t
*zone
) {
13094 REQUIRE(DNS_ZONE_VALID(zone
));
13096 return (zone
->maxxfrin
);
13100 dns_zone_setmaxxfrout(dns_zone_t
*zone
, isc_uint32_t maxxfrout
) {
13101 REQUIRE(DNS_ZONE_VALID(zone
));
13102 zone
->maxxfrout
= maxxfrout
;
13106 dns_zone_getmaxxfrout(dns_zone_t
*zone
) {
13107 REQUIRE(DNS_ZONE_VALID(zone
));
13109 return (zone
->maxxfrout
);
13113 dns_zone_gettype(dns_zone_t
*zone
) {
13114 REQUIRE(DNS_ZONE_VALID(zone
));
13116 return (zone
->type
);
13120 dns_zone_getorigin(dns_zone_t
*zone
) {
13121 REQUIRE(DNS_ZONE_VALID(zone
));
13123 return (&zone
->origin
);
13127 dns_zone_settask(dns_zone_t
*zone
, isc_task_t
*task
) {
13128 REQUIRE(DNS_ZONE_VALID(zone
));
13131 if (zone
->task
!= NULL
)
13132 isc_task_detach(&zone
->task
);
13133 isc_task_attach(task
, &zone
->task
);
13134 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
13135 if (zone
->db
!= NULL
)
13136 dns_db_settask(zone
->db
, zone
->task
);
13137 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
13142 dns_zone_gettask(dns_zone_t
*zone
, isc_task_t
**target
) {
13143 REQUIRE(DNS_ZONE_VALID(zone
));
13144 isc_task_attach(zone
->task
, target
);
13148 dns_zone_setidlein(dns_zone_t
*zone
, isc_uint32_t idlein
) {
13149 REQUIRE(DNS_ZONE_VALID(zone
));
13152 idlein
= DNS_DEFAULT_IDLEIN
;
13153 zone
->idlein
= idlein
;
13157 dns_zone_getidlein(dns_zone_t
*zone
) {
13158 REQUIRE(DNS_ZONE_VALID(zone
));
13160 return (zone
->idlein
);
13164 dns_zone_setidleout(dns_zone_t
*zone
, isc_uint32_t idleout
) {
13165 REQUIRE(DNS_ZONE_VALID(zone
));
13167 zone
->idleout
= idleout
;
13171 dns_zone_getidleout(dns_zone_t
*zone
) {
13172 REQUIRE(DNS_ZONE_VALID(zone
));
13174 return (zone
->idleout
);
13178 notify_done(isc_task_t
*task
, isc_event_t
*event
) {
13179 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
13180 dns_notify_t
*notify
;
13181 isc_result_t result
;
13182 dns_message_t
*message
= NULL
;
13185 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
13189 notify
= event
->ev_arg
;
13190 REQUIRE(DNS_NOTIFY_VALID(notify
));
13191 INSIST(task
== notify
->zone
->task
);
13193 isc_buffer_init(&buf
, rcode
, sizeof(rcode
));
13194 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
13196 result
= revent
->result
;
13197 if (result
== ISC_R_SUCCESS
)
13198 result
= dns_message_create(notify
->zone
->mctx
,
13199 DNS_MESSAGE_INTENTPARSE
, &message
);
13200 if (result
== ISC_R_SUCCESS
)
13201 result
= dns_request_getresponse(revent
->request
, message
,
13202 DNS_MESSAGEPARSE_PRESERVEORDER
);
13203 if (result
== ISC_R_SUCCESS
)
13204 result
= dns_rcode_totext(message
->rcode
, &buf
);
13205 if (result
== ISC_R_SUCCESS
)
13206 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
13207 "notify response from %s: %.*s",
13208 addrbuf
, (int)buf
.used
, rcode
);
13210 notify_log(notify
->zone
, ISC_LOG_DEBUG(2),
13211 "notify to %s failed: %s", addrbuf
,
13212 dns_result_totext(result
));
13215 * Old bind's return formerr if they see a soa record. Retry w/o
13216 * the soa if we see a formerr and had sent a SOA.
13218 isc_event_free(&event
);
13219 if (message
!= NULL
&& message
->rcode
== dns_rcode_formerr
&&
13220 (notify
->flags
& DNS_NOTIFY_NOSOA
) == 0) {
13221 isc_boolean_t startup
;
13223 notify
->flags
|= DNS_NOTIFY_NOSOA
;
13224 dns_request_destroy(¬ify
->request
);
13225 startup
= ISC_TF((notify
->flags
& DNS_NOTIFY_STARTUP
) != 0);
13226 result
= notify_send_queue(notify
, startup
);
13227 if (result
!= ISC_R_SUCCESS
)
13228 notify_destroy(notify
, ISC_FALSE
);
13230 if (result
== ISC_R_TIMEDOUT
)
13231 notify_log(notify
->zone
, ISC_LOG_DEBUG(1),
13232 "notify to %s: retries exceeded", addrbuf
);
13233 notify_destroy(notify
, ISC_FALSE
);
13235 if (message
!= NULL
)
13236 dns_message_destroy(&message
);
13239 struct secure_event
{
13242 isc_uint32_t serial
;
13246 update_log_cb(void *arg
, dns_zone_t
*zone
, int level
, const char *message
) {
13248 dns_zone_log(zone
, level
, "%s", message
);
13251 static isc_result_t
13252 sync_secure_journal(dns_zone_t
*zone
, dns_zone_t
*raw
, dns_journal_t
*journal
,
13253 isc_uint32_t start
, isc_uint32_t end
,
13254 dns_difftuple_t
**soatuplep
, dns_diff_t
*diff
)
13256 isc_result_t result
;
13257 dns_difftuple_t
*tuple
= NULL
;
13258 dns_diffop_t op
= DNS_DIFFOP_ADD
;
13261 REQUIRE(soatuplep
!= NULL
);
13264 return (DNS_R_UNCHANGED
);
13266 CHECK(dns_journal_iter_init(journal
, start
, end
));
13267 for (result
= dns_journal_first_rr(journal
);
13268 result
== ISC_R_SUCCESS
;
13269 result
= dns_journal_next_rr(journal
))
13271 dns_name_t
*name
= NULL
;
13273 dns_rdata_t
*rdata
= NULL
;
13274 dns_journal_current_rr(journal
, &name
, &ttl
, &rdata
);
13276 if (rdata
->type
== dns_rdatatype_soa
) {
13280 * Save the latest raw SOA record.
13282 if (*soatuplep
!= NULL
)
13283 dns_difftuple_free(soatuplep
);
13284 CHECK(dns_difftuple_create(diff
->mctx
,
13296 dns_zone_log(raw
, ISC_LOG_ERROR
,
13297 "corrupt journal file: '%s'\n",
13299 return (ISC_R_FAILURE
);
13302 if (zone
->privatetype
!= 0 &&
13303 rdata
->type
== zone
->privatetype
)
13306 if (rdata
->type
== dns_rdatatype_nsec
||
13307 rdata
->type
== dns_rdatatype_rrsig
||
13308 rdata
->type
== dns_rdatatype_nsec3
||
13309 rdata
->type
== dns_rdatatype_dnskey
||
13310 rdata
->type
== dns_rdatatype_nsec3param
)
13313 op
= (n_soa
== 1) ? DNS_DIFFOP_DEL
: DNS_DIFFOP_ADD
;
13315 CHECK(dns_difftuple_create(diff
->mctx
, op
, name
, ttl
, rdata
,
13317 dns_diff_appendminimal(diff
, &tuple
);
13319 if (result
== ISC_R_NOMORE
)
13320 result
= ISC_R_SUCCESS
;
13326 static isc_result_t
13327 sync_secure_db(dns_zone_t
*seczone
, dns_zone_t
*raw
, dns_db_t
*secdb
,
13328 dns_dbversion_t
*secver
, dns_difftuple_t
**soatuple
,
13331 isc_result_t result
;
13332 dns_db_t
*rawdb
= NULL
;
13333 dns_dbversion_t
*rawver
= NULL
;
13334 dns_difftuple_t
*tuple
= NULL
, *next
;
13335 dns_difftuple_t
*oldtuple
= NULL
, *newtuple
= NULL
;
13336 dns_rdata_soa_t oldsoa
, newsoa
;
13338 REQUIRE(DNS_ZONE_VALID(seczone
));
13339 REQUIRE(soatuple
!= NULL
&& *soatuple
== NULL
);
13341 if (!seczone
->sourceserialset
)
13342 return (DNS_R_UNCHANGED
);
13344 dns_db_attach(raw
->db
, &rawdb
);
13345 dns_db_currentversion(rawdb
, &rawver
);
13346 result
= dns_db_diffx(diff
, rawdb
, rawver
, secdb
, secver
, NULL
);
13347 dns_db_closeversion(rawdb
, &rawver
, ISC_FALSE
);
13348 dns_db_detach(&rawdb
);
13350 if (result
!= ISC_R_SUCCESS
)
13353 for (tuple
= ISC_LIST_HEAD(diff
->tuples
);
13357 next
= ISC_LIST_NEXT(tuple
, link
);
13358 if (tuple
->rdata
.type
== dns_rdatatype_nsec
||
13359 tuple
->rdata
.type
== dns_rdatatype_rrsig
||
13360 tuple
->rdata
.type
== dns_rdatatype_dnskey
||
13361 tuple
->rdata
.type
== dns_rdatatype_nsec3
||
13362 tuple
->rdata
.type
== dns_rdatatype_nsec3param
)
13364 ISC_LIST_UNLINK(diff
->tuples
, tuple
, link
);
13365 dns_difftuple_free(&tuple
);
13368 if (tuple
->rdata
.type
== dns_rdatatype_soa
) {
13369 if (tuple
->op
== DNS_DIFFOP_DEL
) {
13370 INSIST(oldtuple
== NULL
);
13373 if (tuple
->op
== DNS_DIFFOP_ADD
) {
13374 INSIST(newtuple
== NULL
);
13380 if (oldtuple
!= NULL
&& newtuple
!= NULL
) {
13382 result
= dns_rdata_tostruct(&oldtuple
->rdata
, &oldsoa
, NULL
);
13383 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
13385 result
= dns_rdata_tostruct(&newtuple
->rdata
, &newsoa
, NULL
);
13386 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
13389 * If the SOA records are the same except for the serial
13390 * remove them from the diff.
13392 if (oldsoa
.refresh
== newsoa
.refresh
&&
13393 oldsoa
.retry
== newsoa
.retry
&&
13394 oldsoa
.minimum
== newsoa
.minimum
&&
13395 oldsoa
.expire
== newsoa
.expire
&&
13396 dns_name_equal(&oldsoa
.origin
, &newsoa
.origin
) &&
13397 dns_name_equal(&oldsoa
.contact
, &newsoa
.contact
)) {
13398 ISC_LIST_UNLINK(diff
->tuples
, oldtuple
, link
);
13399 dns_difftuple_free(&oldtuple
);
13400 ISC_LIST_UNLINK(diff
->tuples
, newtuple
, link
);
13401 dns_difftuple_free(&newtuple
);
13405 if (ISC_LIST_EMPTY(diff
->tuples
))
13406 return (DNS_R_UNCHANGED
);
13409 * If there are still SOA records in the diff they can now be removed
13410 * saving the new SOA record.
13412 if (oldtuple
!= NULL
) {
13413 ISC_LIST_UNLINK(diff
->tuples
, oldtuple
, link
);
13414 dns_difftuple_free(&oldtuple
);
13417 if (newtuple
!= NULL
) {
13418 ISC_LIST_UNLINK(diff
->tuples
, newtuple
, link
);
13419 *soatuple
= newtuple
;
13422 return (ISC_R_SUCCESS
);
13426 receive_secure_serial(isc_task_t
*task
, isc_event_t
*event
) {
13427 static char me
[] = "receive_secure_serial";
13428 isc_result_t result
;
13429 dns_journal_t
*rjournal
= NULL
;
13430 isc_uint32_t start
, end
;
13431 dns_zone_t
*zone
, *raw
= NULL
;
13432 dns_db_t
*db
= NULL
;
13433 dns_dbversion_t
*newver
= NULL
, *oldver
= NULL
;
13435 dns_difftuple_t
*tuple
= NULL
, *soatuple
= NULL
;
13436 dns_update_log_t log
= { update_log_cb
, NULL
};
13437 isc_time_t timenow
;
13439 zone
= event
->ev_arg
;
13440 end
= ((struct secure_event
*)event
)->serial
;
13441 isc_event_free(&event
);
13447 dns_diff_init(zone
->mctx
, &diff
);
13451 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
13452 if (zone
->db
!= NULL
)
13453 dns_db_attach(zone
->db
, &db
);
13454 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
13456 if (zone
->raw
!= NULL
)
13457 dns_zone_attach(zone
->raw
, &raw
);
13461 * zone->db may be NULL if the load from disk failed.
13463 if (db
== NULL
|| raw
== NULL
) {
13464 result
= ISC_R_FAILURE
;
13469 * We first attempt to sync the raw zone to the secure zone
13470 * by using the raw zone's journal, applying all the deltas
13471 * from the latest source-serial of the secure zone up to
13472 * the current serial number of the raw zone.
13474 * If that fails, then we'll fall back to a direct comparison
13475 * between raw and secure zones.
13477 result
= dns_journal_open(raw
->mctx
, raw
->journal
,
13478 DNS_JOURNAL_WRITE
, &rjournal
);
13479 if (result
!= ISC_R_SUCCESS
)
13482 dns_journal_t
*sjournal
= NULL
;
13484 result
= dns_journal_open(zone
->mctx
, zone
->journal
,
13485 DNS_JOURNAL_READ
, &sjournal
);
13486 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
)
13489 if (!dns_journal_get_sourceserial(rjournal
, &start
)) {
13490 start
= dns_journal_first_serial(rjournal
);
13491 dns_journal_set_sourceserial(rjournal
, start
);
13493 if (sjournal
!= NULL
) {
13494 isc_uint32_t serial
;
13496 * We read the secure journal first, if that exists
13497 * use its value provided it is greater that from the
13500 if (dns_journal_get_sourceserial(sjournal
, &serial
)) {
13501 if (isc_serial_gt(serial
, start
))
13504 dns_journal_destroy(&sjournal
);
13508 dns_db_currentversion(db
, &oldver
);
13509 CHECK(dns_db_newversion(db
, &newver
));
13512 * Try to apply diffs from the raw zone's journal to the secure
13513 * zone. If that fails, we recover by syncing up the databases
13516 result
= sync_secure_journal(zone
, raw
, rjournal
, start
, end
,
13518 if (result
== DNS_R_UNCHANGED
)
13520 else if (result
!= ISC_R_SUCCESS
)
13521 CHECK(sync_secure_db(zone
, raw
, db
, oldver
, &soatuple
, &diff
));
13523 CHECK(dns_diff_apply(&diff
, db
, newver
));
13525 if (soatuple
!= NULL
) {
13526 isc_uint32_t oldserial
, newserial
, desired
;
13528 CHECK(dns_db_createsoatuple(db
, oldver
, diff
.mctx
,
13529 DNS_DIFFOP_DEL
, &tuple
));
13530 oldserial
= dns_soa_getserial(&tuple
->rdata
);
13531 newserial
= desired
= dns_soa_getserial(&soatuple
->rdata
);
13532 if (!isc_serial_gt(newserial
, oldserial
)) {
13533 newserial
= oldserial
+ 1;
13534 if (newserial
== 0)
13536 dns_soa_setserial(newserial
, &soatuple
->rdata
);
13538 CHECK(do_one_tuple(&tuple
, db
, newver
, &diff
));
13539 CHECK(do_one_tuple(&soatuple
, db
, newver
, &diff
));
13540 dns_zone_log(zone
, ISC_LOG_INFO
, "serial %u (unsigned %u)",
13541 newserial
, desired
);
13543 CHECK(update_soa_serial(db
, newver
, &diff
, zone
->mctx
,
13544 zone
->updatemethod
));
13546 CHECK(dns_update_signatures(&log
, zone
, db
, oldver
, newver
,
13547 &diff
, zone
->sigvalidityinterval
));
13549 CHECK(zone_journal(zone
, &diff
, &end
, "receive_secure_serial"));
13551 dns_journal_set_sourceserial(rjournal
, end
);
13552 dns_journal_commit(rjournal
);
13555 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
13557 zone
->sourceserial
= end
;
13558 zone
->sourceserialset
= ISC_TRUE
;
13559 zone_needdump(zone
, DNS_DUMP_DELAY
);
13561 TIME_NOW(&timenow
);
13562 zone_settimer(zone
, &timenow
);
13565 dns_db_closeversion(db
, &oldver
, ISC_FALSE
);
13566 dns_db_closeversion(db
, &newver
, ISC_TRUE
);
13570 dns_zone_detach(&raw
);
13571 if (result
!= ISC_R_SUCCESS
)
13572 dns_zone_log(zone
, ISC_LOG_ERROR
, "receive_secure_serial: %s",
13573 dns_result_totext(result
));
13575 dns_difftuple_free(&tuple
);
13576 if (soatuple
!= NULL
)
13577 dns_difftuple_free(&soatuple
);
13579 if (oldver
!= NULL
)
13580 dns_db_closeversion(db
, &oldver
, ISC_FALSE
);
13581 if (newver
!= NULL
)
13582 dns_db_closeversion(db
, &newver
, ISC_FALSE
);
13583 dns_db_detach(&db
);
13585 if (rjournal
!= NULL
)
13586 dns_journal_destroy(&rjournal
);
13587 dns_diff_clear(&diff
);
13588 dns_zone_idetach(&zone
);
13590 INSIST(oldver
== NULL
);
13591 INSIST(newver
== NULL
);
13594 static isc_result_t
13595 zone_send_secureserial(dns_zone_t
*zone
, isc_uint32_t serial
) {
13597 dns_zone_t
*dummy
= NULL
;
13599 e
= isc_event_allocate(zone
->secure
->mctx
, zone
,
13600 DNS_EVENT_ZONESECURESERIAL
,
13601 receive_secure_serial
, zone
->secure
,
13602 sizeof(struct secure_event
));
13604 return (ISC_R_NOMEMORY
);
13605 ((struct secure_event
*)e
)->serial
= serial
;
13606 INSIST(LOCKED_ZONE(zone
->secure
));
13607 zone_iattach(zone
->secure
, &dummy
);
13608 isc_task_send(zone
->secure
->task
, &e
);
13610 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_SENDSECURE
);
13611 return (ISC_R_SUCCESS
);
13614 static isc_result_t
13615 checkandaddsoa(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
13616 dns_rdataset_t
*rdataset
, isc_uint32_t oldserial
)
13618 dns_rdata_soa_t soa
;
13619 dns_rdata_t rdata
= DNS_RDATA_INIT
;
13620 dns_rdatalist_t temprdatalist
;
13621 dns_rdataset_t temprdataset
;
13623 isc_result_t result
;
13624 unsigned char buf
[DNS_SOA_BUFFERSIZE
];
13626 result
= dns_rdataset_first(rdataset
);
13627 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
13628 dns_rdataset_current(rdataset
, &rdata
);
13629 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
13630 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
13632 if (isc_serial_gt(soa
.serial
, oldserial
))
13633 return (dns_db_addrdataset(db
, node
, version
, 0, rdataset
, 0,
13636 * Always bump the serial.
13639 if (oldserial
== 0)
13641 soa
.serial
= oldserial
;
13644 * Construct a replacement rdataset.
13646 dns_rdata_reset(&rdata
);
13647 isc_buffer_init(&b
, buf
, sizeof(buf
));
13648 result
= dns_rdata_fromstruct(&rdata
, rdataset
->rdclass
,
13649 dns_rdatatype_soa
, &soa
, &b
);
13650 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
13651 temprdatalist
.rdclass
= rdata
.rdclass
;
13652 temprdatalist
.type
= rdata
.type
;
13653 temprdatalist
.covers
= 0;
13654 temprdatalist
.ttl
= rdataset
->ttl
;
13655 ISC_LIST_INIT(temprdatalist
.rdata
);
13656 ISC_LIST_APPEND(temprdatalist
.rdata
, &rdata
, link
);
13658 dns_rdataset_init(&temprdataset
);
13659 result
= dns_rdatalist_tordataset(&temprdatalist
, &temprdataset
);
13660 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
13661 return (dns_db_addrdataset(db
, node
, version
, 0, &temprdataset
,
13666 * This function should populate an nsec3paramlist_t with the
13667 * nsecparam_t data from a zone.
13669 static isc_result_t
13670 save_nsec3param(dns_zone_t
*zone
, nsec3paramlist_t
*nsec3list
) {
13671 isc_result_t result
;
13672 dns_dbnode_t
*node
= NULL
;
13673 dns_rdataset_t rdataset
, prdataset
;
13674 dns_dbversion_t
*version
= NULL
;
13675 nsec3param_t
*nsec3param
= NULL
;
13676 nsec3param_t
*nsec3p
= NULL
;
13677 nsec3param_t
*next
;
13678 dns_db_t
*db
= NULL
;
13679 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
13681 REQUIRE(DNS_ZONE_VALID(zone
));
13682 REQUIRE(nsec3list
!= NULL
);
13683 REQUIRE(ISC_LIST_EMPTY(*nsec3list
));
13685 dns_rdataset_init(&rdataset
);
13686 dns_rdataset_init(&prdataset
);
13688 dns_db_attach(zone
->db
, &db
);
13689 CHECK(dns_db_getoriginnode(db
, &node
));
13691 dns_db_currentversion(db
, &version
);
13692 result
= dns_db_findrdataset(db
, node
, version
,
13693 dns_rdatatype_nsec3param
,
13694 dns_rdatatype_none
, 0, &rdataset
, NULL
);
13696 if (result
!= ISC_R_SUCCESS
)
13700 * walk nsec3param rdataset making a list of parameters (note that
13701 * multiple simultaneous nsec3 chains are annoyingly legal -- this
13702 * is why we use an nsec3list, even tho we will usually only have
13705 for (result
= dns_rdataset_first(&rdataset
);
13706 result
== ISC_R_SUCCESS
;
13707 result
= dns_rdataset_next(&rdataset
))
13709 dns_rdata_t rdata
= DNS_RDATA_INIT
;
13710 dns_rdata_t
private = DNS_RDATA_INIT
;
13712 dns_rdataset_current(&rdataset
, &rdata
);
13713 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
13714 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
13715 "looping through nsec3param data");
13716 nsec3param
= isc_mem_get(zone
->mctx
, sizeof(nsec3param_t
));
13717 if (nsec3param
== NULL
)
13718 CHECK(ISC_R_NOMEMORY
);
13719 ISC_LINK_INIT(nsec3param
, link
);
13722 * now transfer the data from the rdata to
13725 dns_nsec3param_toprivate(&rdata
, &private,
13726 zone
->privatetype
, nsec3param
->data
,
13727 sizeof(nsec3param
->data
));
13728 nsec3param
->length
= private.length
;
13729 ISC_LIST_APPEND(*nsec3list
, nsec3param
, link
);
13733 result
= dns_db_findrdataset(db
, node
, version
, zone
->privatetype
,
13734 dns_rdatatype_none
, 0, &prdataset
, NULL
);
13735 if (result
!= ISC_R_SUCCESS
)
13739 * walk private type records, converting them to nsec3 parameters
13740 * using dns_nsec3param_fromprivate(), do the right thing based on
13741 * CREATE and REMOVE flags
13743 for (result
= dns_rdataset_first(&prdataset
);
13744 result
== ISC_R_SUCCESS
;
13745 result
= dns_rdataset_next(&prdataset
))
13747 dns_rdata_t rdata
= DNS_RDATA_INIT
;
13748 dns_rdata_t
private = DNS_RDATA_INIT
;
13750 dns_rdataset_current(&prdataset
, &private);
13751 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
13752 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
13753 "looping through nsec3param private data");
13756 * Do we have a valid private record?
13758 if (!dns_nsec3param_fromprivate(&private, &rdata
,
13763 * Remove any NSEC3PARAM records scheduled to be removed.
13765 if (NSEC3REMOVE(rdata
.data
[1])) {
13767 * Zero out the flags.
13771 for (nsec3p
= ISC_LIST_HEAD(*nsec3list
);
13775 next
= ISC_LIST_NEXT(nsec3p
, link
);
13777 if (nsec3p
->length
== rdata
.length
+ 1 &&
13778 memcmp(rdata
.data
, nsec3p
->data
+ 1,
13779 nsec3p
->length
- 1) == 0) {
13780 ISC_LIST_UNLINK(*nsec3list
,
13782 isc_mem_put(zone
->mctx
, nsec3p
,
13783 sizeof(nsec3param_t
));
13789 nsec3param
= isc_mem_get(zone
->mctx
, sizeof(nsec3param_t
));
13790 if (nsec3param
== NULL
)
13791 CHECK(ISC_R_NOMEMORY
);
13792 ISC_LINK_INIT(nsec3param
, link
);
13795 * Copy the remaining private records so the nsec/nsec3
13796 * chain gets created.
13798 INSIST(private.length
<= sizeof(nsec3param
->data
));
13799 memmove(nsec3param
->data
, private.data
, private.length
);
13800 nsec3param
->length
= private.length
;
13801 ISC_LIST_APPEND(*nsec3list
, nsec3param
, link
);
13805 if (result
== ISC_R_NOMORE
|| result
== ISC_R_NOTFOUND
)
13806 result
= ISC_R_SUCCESS
;
13810 dns_db_detachnode(db
, &node
);
13811 if (version
!= NULL
)
13812 dns_db_closeversion(db
, &version
, ISC_FALSE
);
13814 dns_db_detach(&db
);
13815 if (dns_rdataset_isassociated(&rdataset
))
13816 dns_rdataset_disassociate(&rdataset
);
13817 if (dns_rdataset_isassociated(&prdataset
))
13818 dns_rdataset_disassociate(&prdataset
);
13823 * Walk the list of the nsec3 chains desired for the zone, converting
13824 * parameters to private type records using dns_nsec3param_toprivate(),
13825 * and insert them into the new zone db.
13827 static isc_result_t
13828 restore_nsec3param(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*version
,
13829 nsec3paramlist_t
*nsec3list
)
13831 isc_result_t result
;
13834 nsec3param_t
*nsec3p
= NULL
;
13835 nsec3param_t
*next
;
13837 REQUIRE(DNS_ZONE_VALID(zone
));
13838 REQUIRE(!ISC_LIST_EMPTY(*nsec3list
));
13840 dns_diff_init(zone
->mctx
, &diff
);
13843 * Loop through the list of private-type records, set the INITIAL
13844 * and CREATE flags, and the add the record to the apex of the tree
13847 for (nsec3p
= ISC_LIST_HEAD(*nsec3list
);
13851 next
= ISC_LIST_NEXT(nsec3p
, link
);
13852 dns_rdata_init(&rdata
);
13853 nsec3p
->data
[2] = DNS_NSEC3FLAG_CREATE
| DNS_NSEC3FLAG_INITIAL
;
13854 rdata
.length
= nsec3p
->length
;
13855 rdata
.data
= nsec3p
->data
;
13856 rdata
.type
= zone
->privatetype
;
13857 rdata
.rdclass
= zone
->rdclass
;
13858 CHECK(update_one_rr(db
, version
, &diff
, DNS_DIFFOP_ADD
,
13859 &zone
->origin
, 0, &rdata
));
13862 result
= ISC_R_SUCCESS
;
13865 for (nsec3p
= ISC_LIST_HEAD(*nsec3list
);
13869 next
= ISC_LIST_NEXT(nsec3p
, link
);
13870 ISC_LIST_UNLINK(*nsec3list
, nsec3p
, link
);
13871 isc_mem_put(zone
->mctx
, nsec3p
, sizeof(nsec3param_t
));
13874 dns_diff_clear(&diff
);
13879 receive_secure_db(isc_task_t
*task
, isc_event_t
*event
) {
13880 isc_result_t result
;
13882 dns_db_t
*rawdb
, *db
= NULL
;
13883 dns_dbnode_t
*rawnode
= NULL
, *node
= NULL
;
13884 dns_fixedname_t fname
;
13886 dns_dbiterator_t
*dbiterator
= NULL
;
13887 dns_rdatasetiter_t
*rdsit
= NULL
;
13888 dns_rdataset_t rdataset
;
13889 dns_dbversion_t
*version
= NULL
;
13890 isc_time_t loadtime
;
13891 unsigned int oldserial
= 0;
13892 isc_boolean_t have_oldserial
= ISC_FALSE
;
13893 nsec3paramlist_t nsec3list
;
13897 ISC_LIST_INIT(nsec3list
);
13899 zone
= event
->ev_arg
;
13900 rawdb
= ((struct secure_event
*)event
)->db
;
13901 isc_event_free(&event
);
13903 dns_fixedname_init(&fname
);
13904 name
= dns_fixedname_name(&fname
);
13905 dns_rdataset_init(&rdataset
);
13908 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
) || !inline_secure(zone
)) {
13909 result
= ISC_R_SHUTTINGDOWN
;
13913 TIME_NOW(&loadtime
);
13914 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
13915 if (zone
->db
!= NULL
) {
13916 result
= dns_db_getsoaserial(zone
->db
, NULL
, &oldserial
);
13917 if (result
== ISC_R_SUCCESS
)
13918 have_oldserial
= ISC_TRUE
;
13921 * assemble nsec3parameters from the old zone, and set a flag
13924 result
= save_nsec3param(zone
, &nsec3list
);
13925 if (result
!= ISC_R_SUCCESS
) {
13926 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
13930 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
13932 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
13933 &zone
->origin
, dns_dbtype_zone
, zone
->rdclass
,
13934 zone
->db_argc
- 1, zone
->db_argv
+ 1, &db
);
13935 if (result
!= ISC_R_SUCCESS
)
13938 result
= dns_db_newversion(db
, &version
);
13939 if (result
!= ISC_R_SUCCESS
)
13942 result
= dns_db_createiterator(rawdb
, 0, &dbiterator
);
13943 if (result
!= ISC_R_SUCCESS
)
13946 for (result
= dns_dbiterator_first(dbiterator
);
13947 result
== ISC_R_SUCCESS
;
13948 result
= dns_dbiterator_next(dbiterator
)) {
13949 result
= dns_dbiterator_current(dbiterator
, &rawnode
, name
);
13950 if (result
!= ISC_R_SUCCESS
)
13953 result
= dns_db_findnode(db
, name
, ISC_TRUE
, &node
);
13954 if (result
!= ISC_R_SUCCESS
)
13957 result
= dns_db_allrdatasets(rawdb
, rawnode
, NULL
, 0, &rdsit
);
13958 if (result
!= ISC_R_SUCCESS
)
13961 for (result
= dns_rdatasetiter_first(rdsit
);
13962 result
== ISC_R_SUCCESS
;
13963 result
= dns_rdatasetiter_next(rdsit
)) {
13964 dns_rdatasetiter_current(rdsit
, &rdataset
);
13965 if (rdataset
.type
== dns_rdatatype_nsec
||
13966 rdataset
.type
== dns_rdatatype_rrsig
||
13967 rdataset
.type
== dns_rdatatype_nsec3
||
13968 rdataset
.type
== dns_rdatatype_dnskey
||
13969 rdataset
.type
== dns_rdatatype_nsec3param
) {
13970 dns_rdataset_disassociate(&rdataset
);
13973 if (rdataset
.type
== dns_rdatatype_soa
&&
13975 result
= checkandaddsoa(db
, node
, version
,
13976 &rdataset
, oldserial
);
13978 result
= dns_db_addrdataset(db
, node
, version
,
13981 if (result
!= ISC_R_SUCCESS
)
13984 dns_rdataset_disassociate(&rdataset
);
13986 dns_rdatasetiter_destroy(&rdsit
);
13987 dns_db_detachnode(rawdb
, &rawnode
);
13988 dns_db_detachnode(db
, &node
);
13992 * Call restore_nsec3param() to create private-type records from
13993 * the old nsec3 parameters and insert them into db
13995 if (!ISC_LIST_EMPTY(nsec3list
))
13996 restore_nsec3param(zone
, db
, version
, &nsec3list
);
13998 dns_db_closeversion(db
, &version
, ISC_TRUE
);
14001 * Lock hierarchy: zmgr, zone, raw.
14003 INSIST(zone
!= zone
->raw
);
14004 LOCK_ZONE(zone
->raw
);
14005 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
14006 result
= zone_postload(zone
, db
, loadtime
, ISC_R_SUCCESS
);
14007 zone_needdump(zone
, 0); /* XXXMPA */
14008 UNLOCK_ZONE(zone
->raw
);
14012 if (result
!= ISC_R_SUCCESS
)
14013 dns_zone_log(zone
, ISC_LOG_ERROR
, "receive_secure_db: %s",
14014 dns_result_totext(result
));
14016 while (!ISC_LIST_EMPTY(nsec3list
)) {
14017 nsec3param_t
*nsec3p
;
14018 nsec3p
= ISC_LIST_HEAD(nsec3list
);
14019 ISC_LIST_UNLINK(nsec3list
, nsec3p
, link
);
14020 isc_mem_put(zone
->mctx
, nsec3p
, sizeof(nsec3param_t
));
14022 if (dns_rdataset_isassociated(&rdataset
))
14023 dns_rdataset_disassociate(&rdataset
);
14026 dns_db_detachnode(db
, &node
);
14027 if (version
!= NULL
)
14028 dns_db_closeversion(db
, &version
, ISC_FALSE
);
14029 dns_db_detach(&db
);
14031 if (rawnode
!= NULL
)
14032 dns_db_detachnode(rawdb
, &rawnode
);
14033 dns_db_detach(&rawdb
);
14034 if (dbiterator
!= NULL
)
14035 dns_dbiterator_destroy(&dbiterator
);
14036 dns_zone_idetach(&zone
);
14038 INSIST(version
== NULL
);
14041 static isc_result_t
14042 zone_send_securedb(dns_zone_t
*zone
, dns_db_t
*db
) {
14044 dns_db_t
*dummy
= NULL
;
14045 dns_zone_t
*secure
= NULL
;
14047 e
= isc_event_allocate(zone
->secure
->mctx
, zone
,
14048 DNS_EVENT_ZONESECUREDB
,
14049 receive_secure_db
, zone
->secure
,
14050 sizeof(struct secure_event
));
14052 return (ISC_R_NOMEMORY
);
14053 dns_db_attach(db
, &dummy
);
14054 ((struct secure_event
*)e
)->db
= dummy
;
14055 INSIST(LOCKED_ZONE(zone
->secure
));
14056 zone_iattach(zone
->secure
, &secure
);
14057 isc_task_send(zone
->secure
->task
, &e
);
14058 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_SENDSECURE
);
14059 return (ISC_R_SUCCESS
);
14063 dns_zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
14064 isc_result_t result
;
14065 dns_zone_t
*secure
= NULL
;
14067 REQUIRE(DNS_ZONE_VALID(zone
));
14070 if (inline_raw(zone
)) {
14071 secure
= zone
->secure
;
14072 INSIST(secure
!= zone
);
14073 TRYLOCK_ZONE(result
, secure
);
14074 if (result
!= ISC_R_SUCCESS
) {
14077 #if ISC_PLATFORM_USETHREADS
14078 isc_thread_yield();
14083 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
14084 result
= zone_replacedb(zone
, db
, dump
);
14085 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
14086 if (secure
!= NULL
)
14087 UNLOCK_ZONE(secure
);
14092 static isc_result_t
14093 zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
14094 dns_dbversion_t
*ver
;
14095 isc_result_t result
;
14096 unsigned int soacount
= 0;
14097 unsigned int nscount
= 0;
14100 * 'zone' and 'zonedb' locked by caller.
14102 REQUIRE(DNS_ZONE_VALID(zone
));
14103 REQUIRE(LOCKED_ZONE(zone
));
14104 if (inline_raw(zone
))
14105 REQUIRE(LOCKED_ZONE(zone
->secure
));
14107 result
= dns_db_rpz_ready(db
);
14108 if (result
!= ISC_R_SUCCESS
)
14111 result
= zone_get_from_db(zone
, db
, &nscount
, &soacount
,
14112 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
14113 if (result
== ISC_R_SUCCESS
) {
14114 if (soacount
!= 1) {
14115 dns_zone_log(zone
, ISC_LOG_ERROR
,
14116 "has %d SOA records", soacount
);
14117 result
= DNS_R_BADZONE
;
14119 if (nscount
== 0 && zone
->type
!= dns_zone_key
) {
14120 dns_zone_log(zone
, ISC_LOG_ERROR
, "has no NS records");
14121 result
= DNS_R_BADZONE
;
14123 if (result
!= ISC_R_SUCCESS
)
14126 dns_zone_log(zone
, ISC_LOG_ERROR
,
14127 "retrieving SOA and NS records failed: %s",
14128 dns_result_totext(result
));
14132 result
= check_nsec3param(zone
, db
);
14133 if (result
!= ISC_R_SUCCESS
)
14137 dns_db_currentversion(db
, &ver
);
14140 * The initial version of a slave zone is always dumped;
14141 * subsequent versions may be journaled instead if this
14142 * is enabled in the configuration.
14144 if (zone
->db
!= NULL
&& zone
->journal
!= NULL
&&
14145 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
) &&
14146 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
))
14148 isc_uint32_t serial
, oldserial
;
14150 dns_zone_log(zone
, ISC_LOG_DEBUG(3), "generating diffs");
14152 result
= dns_db_getsoaserial(db
, ver
, &serial
);
14153 if (result
!= ISC_R_SUCCESS
) {
14154 dns_zone_log(zone
, ISC_LOG_ERROR
,
14155 "ixfr-from-differences: unable to get "
14161 * This is checked in zone_postload() for master zones.
14163 result
= zone_get_from_db(zone
, zone
->db
, NULL
, &soacount
,
14164 &oldserial
, NULL
, NULL
, NULL
, NULL
,
14166 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
14167 RUNTIME_CHECK(soacount
> 0U);
14168 if ((zone
->type
== dns_zone_slave
||
14169 (zone
->type
== dns_zone_redirect
&&
14170 zone
->masters
!= NULL
))
14171 && !isc_serial_gt(serial
, oldserial
)) {
14172 isc_uint32_t serialmin
, serialmax
;
14173 serialmin
= (oldserial
+ 1) & 0xffffffffU
;
14174 serialmax
= (oldserial
+ 0x7fffffffU
) & 0xffffffffU
;
14175 dns_zone_log(zone
, ISC_LOG_ERROR
,
14176 "ixfr-from-differences: failed: "
14177 "new serial (%u) out of range [%u - %u]",
14178 serial
, serialmin
, serialmax
);
14179 result
= ISC_R_RANGE
;
14183 result
= dns_db_diff(zone
->mctx
, db
, ver
, zone
->db
, NULL
,
14185 if (result
!= ISC_R_SUCCESS
)
14188 zone_needdump(zone
, DNS_DUMP_DELAY
);
14189 else if (zone
->journalsize
!= -1) {
14190 result
= dns_journal_compact(zone
->mctx
, zone
->journal
,
14191 serial
, zone
->journalsize
);
14193 case ISC_R_SUCCESS
:
14194 case ISC_R_NOSPACE
:
14195 case ISC_R_NOTFOUND
:
14196 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
14197 "dns_journal_compact: %s",
14198 dns_result_totext(result
));
14201 dns_zone_log(zone
, ISC_LOG_ERROR
,
14202 "dns_journal_compact failed: %s",
14203 dns_result_totext(result
));
14207 if (zone
->type
== dns_zone_master
&& inline_raw(zone
))
14208 zone_send_secureserial(zone
, serial
);
14210 if (dump
&& zone
->masterfile
!= NULL
) {
14212 * If DNS_ZONEFLG_FORCEXFER was set we don't want
14213 * to keep the old masterfile.
14215 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
) &&
14216 remove(zone
->masterfile
) < 0 && errno
!= ENOENT
) {
14217 char strbuf
[ISC_STRERRORSIZE
];
14218 isc__strerror(errno
, strbuf
, sizeof(strbuf
));
14219 isc_log_write(dns_lctx
,
14220 DNS_LOGCATEGORY_GENERAL
,
14221 DNS_LOGMODULE_ZONE
,
14223 "unable to remove masterfile "
14225 zone
->masterfile
, strbuf
);
14227 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) == 0)
14228 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NODELAY
);
14230 zone_needdump(zone
, 0);
14232 if (dump
&& zone
->journal
!= NULL
) {
14234 * The in-memory database just changed, and
14235 * because 'dump' is set, it didn't change by
14236 * being loaded from disk. Also, we have not
14237 * journaled diffs for this change.
14238 * Therefore, the on-disk journal is missing
14239 * the deltas for this change. Since it can
14240 * no longer be used to bring the zone
14241 * up-to-date, it is useless and should be
14244 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
14245 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
14246 "removing journal file");
14247 if (remove(zone
->journal
) < 0 && errno
!= ENOENT
) {
14248 char strbuf
[ISC_STRERRORSIZE
];
14249 isc__strerror(errno
, strbuf
, sizeof(strbuf
));
14250 isc_log_write(dns_lctx
,
14251 DNS_LOGCATEGORY_GENERAL
,
14252 DNS_LOGMODULE_ZONE
,
14254 "unable to remove journal "
14256 zone
->journal
, strbuf
);
14260 if (inline_raw(zone
))
14261 zone_send_securedb(zone
, db
);
14264 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
14266 dns_zone_log(zone
, ISC_LOG_DEBUG(3), "replacing zone database");
14268 if (zone
->db
!= NULL
)
14269 zone_detachdb(zone
);
14270 zone_attachdb(zone
, db
);
14271 dns_db_settask(zone
->db
, zone
->task
);
14272 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
14273 return (ISC_R_SUCCESS
);
14276 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
14280 /* The caller must hold the dblock as a writer. */
14282 zone_attachdb(dns_zone_t
*zone
, dns_db_t
*db
) {
14283 REQUIRE(zone
->db
== NULL
&& db
!= NULL
);
14285 dns_db_attach(db
, &zone
->db
);
14286 if (zone
->acache
!= NULL
) {
14287 isc_result_t result
;
14288 result
= dns_acache_setdb(zone
->acache
, db
);
14289 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_EXISTS
) {
14290 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
14291 "dns_acache_setdb() failed: %s",
14292 isc_result_totext(result
));
14297 /* The caller must hold the dblock as a writer. */
14299 zone_detachdb(dns_zone_t
*zone
) {
14300 REQUIRE(zone
->db
!= NULL
);
14302 if (zone
->acache
!= NULL
)
14303 (void)dns_acache_putdb(zone
->acache
, zone
->db
);
14304 dns_db_detach(&zone
->db
);
14308 zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
) {
14310 isc_boolean_t again
= ISC_FALSE
;
14311 unsigned int soacount
;
14312 unsigned int nscount
;
14313 isc_uint32_t serial
, refresh
, retry
, expire
, minimum
;
14314 isc_result_t xfrresult
= result
;
14315 isc_boolean_t free_needed
;
14316 dns_zone_t
*secure
= NULL
;
14318 REQUIRE(DNS_ZONE_VALID(zone
));
14320 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
14321 "zone transfer finished: %s", dns_result_totext(result
));
14324 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
14325 * could result in a deadlock due to a LOR so we will spin if we
14326 * can't obtain the both locks.
14330 if (inline_raw(zone
)) {
14331 secure
= zone
->secure
;
14332 INSIST(secure
!= zone
);
14333 TRYLOCK_ZONE(result
, secure
);
14334 if (result
!= ISC_R_SUCCESS
) {
14337 #if ISC_PLATFORM_USETHREADS
14338 isc_thread_yield();
14344 INSIST((zone
->flags
& DNS_ZONEFLG_REFRESH
) != 0);
14345 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
14346 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
);
14350 case ISC_R_SUCCESS
:
14351 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
14353 case DNS_R_UPTODATE
:
14354 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
14356 * Has the zone expired underneath us?
14358 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
14359 if (zone
->db
== NULL
) {
14360 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
14365 * Update the zone structure's data from the actual
14370 INSIST(zone
->db
!= NULL
);
14371 result
= zone_get_from_db(zone
, zone
->db
, &nscount
,
14372 &soacount
, &serial
, &refresh
,
14373 &retry
, &expire
, &minimum
, NULL
);
14374 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
14375 if (result
== ISC_R_SUCCESS
) {
14377 dns_zone_log(zone
, ISC_LOG_ERROR
,
14378 "transferred zone "
14379 "has %d SOA record%s", soacount
,
14380 (soacount
!= 0) ? "s" : "");
14381 if (nscount
== 0) {
14382 dns_zone_log(zone
, ISC_LOG_ERROR
,
14383 "transferred zone "
14384 "has no NS records");
14385 if (DNS_ZONE_FLAG(zone
,
14386 DNS_ZONEFLG_HAVETIMERS
)) {
14387 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
14388 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
14390 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
14394 zone
->refresh
= RANGE(refresh
, zone
->minrefresh
,
14396 zone
->retry
= RANGE(retry
, zone
->minretry
,
14398 zone
->expire
= RANGE(expire
,
14399 zone
->refresh
+ zone
->retry
,
14401 zone
->minimum
= minimum
;
14402 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
14406 * Set our next update/expire times.
14408 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
14409 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
14410 zone
->refreshtime
= now
;
14411 DNS_ZONE_TIME_ADD(&now
, zone
->expire
,
14412 &zone
->expiretime
);
14414 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
,
14415 &zone
->refreshtime
);
14416 DNS_ZONE_TIME_ADD(&now
, zone
->expire
,
14417 &zone
->expiretime
);
14419 if (result
== ISC_R_SUCCESS
&& xfrresult
== ISC_R_SUCCESS
) {
14420 char buf
[DNS_NAME_FORMATSIZE
+ sizeof(": TSIG ''")];
14421 if (zone
->tsigkey
!= NULL
) {
14422 char namebuf
[DNS_NAME_FORMATSIZE
];
14423 dns_name_format(&zone
->tsigkey
->name
, namebuf
,
14425 snprintf(buf
, sizeof(buf
), ": TSIG '%s'",
14429 dns_zone_log(zone
, ISC_LOG_INFO
,
14430 "transferred serial %u%s",
14432 if (inline_raw(zone
))
14433 zone_send_secureserial(zone
, serial
);
14437 * This is not necessary if we just performed a AXFR
14438 * however it is necessary for an IXFR / UPTODATE and
14439 * won't hurt with an AXFR.
14441 if (zone
->masterfile
!= NULL
|| zone
->journal
!= NULL
) {
14442 unsigned int delay
= DNS_DUMP_DELAY
;
14444 result
= ISC_R_FAILURE
;
14445 if (zone
->journal
!= NULL
)
14446 result
= isc_file_settime(zone
->journal
, &now
);
14447 if (result
!= ISC_R_SUCCESS
&&
14448 zone
->masterfile
!= NULL
)
14449 result
= isc_file_settime(zone
->masterfile
,
14452 if ((DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NODELAY
) != 0) ||
14453 result
== ISC_R_FILENOTFOUND
)
14456 if ((result
== ISC_R_SUCCESS
||
14457 result
== ISC_R_FILENOTFOUND
) &&
14458 zone
->masterfile
!= NULL
)
14459 zone_needdump(zone
, delay
);
14460 else if (result
!= ISC_R_SUCCESS
)
14461 dns_zone_log(zone
, ISC_LOG_ERROR
,
14462 "transfer: could not set file "
14463 "modification time of '%s': %s",
14465 dns_result_totext(result
));
14467 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NODELAY
);
14468 inc_stats(zone
, dns_zonestatscounter_xfrsuccess
);
14471 case DNS_R_BADIXFR
:
14472 /* Force retry with AXFR. */
14473 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
14479 * Skip to next failed / untried master.
14483 } while (zone
->curmaster
< zone
->masterscnt
&&
14484 zone
->mastersok
[zone
->curmaster
]);
14487 if (zone
->curmaster
>= zone
->masterscnt
) {
14488 zone
->curmaster
= 0;
14489 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
14490 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
14491 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
14492 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
14493 while (zone
->curmaster
< zone
->masterscnt
&&
14494 zone
->mastersok
[zone
->curmaster
])
14498 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
14500 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
14503 inc_stats(zone
, dns_zonestatscounter_xfrfail
);
14506 zone_settimer(zone
, &now
);
14509 * If creating the transfer object failed, zone->xfr is NULL.
14510 * Otherwise, we are called as the done callback of a zone
14511 * transfer object that just entered its shutting-down
14512 * state. Since we are no longer responsible for shutting
14513 * it down, we can detach our reference.
14515 if (zone
->xfr
!= NULL
)
14516 dns_xfrin_detach(&zone
->xfr
);
14518 if (zone
->tsigkey
!= NULL
)
14519 dns_tsigkey_detach(&zone
->tsigkey
);
14522 * Handle any deferred journal compaction.
14524 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
)) {
14525 result
= dns_journal_compact(zone
->mctx
, zone
->journal
,
14526 zone
->compact_serial
,
14527 zone
->journalsize
);
14529 case ISC_R_SUCCESS
:
14530 case ISC_R_NOSPACE
:
14531 case ISC_R_NOTFOUND
:
14532 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
14533 "dns_journal_compact: %s",
14534 dns_result_totext(result
));
14537 dns_zone_log(zone
, ISC_LOG_ERROR
,
14538 "dns_journal_compact failed: %s",
14539 dns_result_totext(result
));
14542 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
);
14545 if (secure
!= NULL
)
14546 UNLOCK_ZONE(secure
);
14548 * This transfer finishing freed up a transfer quota slot.
14549 * Let any other zones waiting for quota have it.
14551 if (zone
->zmgr
!= NULL
&&
14552 zone
->statelist
== &zone
->zmgr
->xfrin_in_progress
) {
14554 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
14555 ISC_LIST_UNLINK(zone
->zmgr
->xfrin_in_progress
, zone
, statelink
);
14556 zone
->statelist
= NULL
;
14557 zmgr_resume_xfrs(zone
->zmgr
, ISC_FALSE
);
14558 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
14563 * Retry with a different server if necessary.
14565 if (again
&& !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
14566 queue_soa_query(zone
);
14568 INSIST(zone
->irefs
> 0);
14570 free_needed
= exit_check(zone
);
14577 zone_loaddone(void *arg
, isc_result_t result
) {
14578 static char me
[] = "zone_loaddone";
14579 dns_load_t
*load
= arg
;
14581 isc_result_t tresult
;
14582 dns_zone_t
*secure
= NULL
;
14584 REQUIRE(DNS_LOAD_VALID(load
));
14589 tresult
= dns_db_endload(load
->db
, &load
->callbacks
);
14590 if (tresult
!= ISC_R_SUCCESS
&&
14591 (result
== ISC_R_SUCCESS
|| result
== DNS_R_SEENINCLUDE
))
14595 * Lock hierarchy: zmgr, zone, raw.
14599 INSIST(zone
!= zone
->raw
);
14600 if (inline_secure(zone
))
14601 LOCK_ZONE(zone
->raw
);
14602 else if (inline_raw(zone
)) {
14603 secure
= zone
->secure
;
14604 TRYLOCK_ZONE(result
, secure
);
14605 if (result
!= ISC_R_SUCCESS
) {
14608 #if ISC_PLATFORM_USETHREADS
14609 isc_thread_yield();
14614 (void)zone_postload(zone
, load
->db
, load
->loadtime
, result
);
14615 zonemgr_putio(&zone
->readio
);
14616 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_LOADING
);
14617 zone_idetach(&load
->callbacks
.zone
);
14619 * Leave the zone frozen if the reload fails.
14621 if ((result
== ISC_R_SUCCESS
|| result
== DNS_R_SEENINCLUDE
) &&
14622 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_THAW
))
14623 zone
->update_disabled
= ISC_FALSE
;
14624 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_THAW
);
14625 if (inline_secure(zone
))
14626 UNLOCK_ZONE(zone
->raw
);
14627 else if (secure
!= NULL
)
14628 UNLOCK_ZONE(secure
);
14632 dns_db_detach(&load
->db
);
14633 if (load
->zone
->lctx
!= NULL
)
14634 dns_loadctx_detach(&load
->zone
->lctx
);
14635 dns_zone_idetach(&load
->zone
);
14636 isc_mem_putanddetach(&load
->mctx
, load
, sizeof(*load
));
14640 dns_zone_getssutable(dns_zone_t
*zone
, dns_ssutable_t
**table
) {
14641 REQUIRE(DNS_ZONE_VALID(zone
));
14642 REQUIRE(table
!= NULL
);
14643 REQUIRE(*table
== NULL
);
14646 if (zone
->ssutable
!= NULL
)
14647 dns_ssutable_attach(zone
->ssutable
, table
);
14652 dns_zone_setssutable(dns_zone_t
*zone
, dns_ssutable_t
*table
) {
14653 REQUIRE(DNS_ZONE_VALID(zone
));
14656 if (zone
->ssutable
!= NULL
)
14657 dns_ssutable_detach(&zone
->ssutable
);
14659 dns_ssutable_attach(table
, &zone
->ssutable
);
14664 dns_zone_setsigvalidityinterval(dns_zone_t
*zone
, isc_uint32_t interval
) {
14665 REQUIRE(DNS_ZONE_VALID(zone
));
14667 zone
->sigvalidityinterval
= interval
;
14671 dns_zone_getsigvalidityinterval(dns_zone_t
*zone
) {
14672 REQUIRE(DNS_ZONE_VALID(zone
));
14674 return (zone
->sigvalidityinterval
);
14678 dns_zone_setsigresigninginterval(dns_zone_t
*zone
, isc_uint32_t interval
) {
14681 REQUIRE(DNS_ZONE_VALID(zone
));
14684 zone
->sigresigninginterval
= interval
;
14685 set_resigntime(zone
);
14686 if (zone
->task
!= NULL
) {
14688 zone_settimer(zone
, &now
);
14694 dns_zone_getsigresigninginterval(dns_zone_t
*zone
) {
14695 REQUIRE(DNS_ZONE_VALID(zone
));
14697 return (zone
->sigresigninginterval
);
14701 queue_xfrin(dns_zone_t
*zone
) {
14702 const char me
[] = "queue_xfrin";
14703 isc_result_t result
;
14704 dns_zonemgr_t
*zmgr
= zone
->zmgr
;
14708 INSIST(zone
->statelist
== NULL
);
14710 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
14711 ISC_LIST_APPEND(zmgr
->waiting_for_xfrin
, zone
, statelink
);
14715 zone
->statelist
= &zmgr
->waiting_for_xfrin
;
14716 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
14717 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
14719 if (result
== ISC_R_QUOTA
) {
14720 dns_zone_logc(zone
, DNS_LOGCATEGORY_XFER_IN
, ISC_LOG_INFO
,
14721 "zone transfer deferred due to quota");
14722 } else if (result
!= ISC_R_SUCCESS
) {
14723 dns_zone_logc(zone
, DNS_LOGCATEGORY_XFER_IN
, ISC_LOG_ERROR
,
14724 "starting zone transfer: %s",
14725 isc_result_totext(result
));
14730 * This event callback is called when a zone has received
14731 * any necessary zone transfer quota. This is the time
14732 * to go ahead and start the transfer.
14735 got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
) {
14736 isc_result_t result
= ISC_R_SUCCESS
;
14737 dns_peer_t
*peer
= NULL
;
14738 char master
[ISC_SOCKADDR_FORMATSIZE
];
14739 char source
[ISC_SOCKADDR_FORMATSIZE
];
14740 dns_rdatatype_t xfrtype
;
14741 dns_zone_t
*zone
= event
->ev_arg
;
14742 isc_netaddr_t masterip
;
14743 isc_sockaddr_t sourceaddr
;
14744 isc_sockaddr_t masteraddr
;
14746 const char *soa_before
= "";
14747 isc_dscp_t dscp
= -1;
14748 isc_boolean_t loaded
;
14752 INSIST(task
== zone
->task
);
14754 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
14755 result
= ISC_R_CANCELED
;
14761 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
14762 if (dns_zonemgr_unreachable(zone
->zmgr
, &zone
->masteraddr
,
14763 &zone
->sourceaddr
, &now
))
14765 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
14766 dns_zone_log(zone
, ISC_LOG_INFO
,
14767 "got_transfer_quota: skipping zone transfer as "
14768 "master %s (source %s) is unreachable (cached)",
14770 result
= ISC_R_CANCELED
;
14774 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
14775 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
, &masterip
, &peer
);
14777 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
))
14778 soa_before
= "SOA before ";
14780 * Decide whether we should request IXFR or AXFR.
14782 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
14783 loaded
= ISC_TF(zone
->db
!= NULL
);
14784 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
14787 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
14788 "no database exists yet, requesting AXFR of "
14789 "initial version from %s", master
);
14790 xfrtype
= dns_rdatatype_axfr
;
14791 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
)) {
14792 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
14793 "forced reload, requesting AXFR of "
14794 "initial version from %s", master
);
14795 xfrtype
= dns_rdatatype_axfr
;
14796 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLAG_NOIXFR
)) {
14797 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
14798 "retrying with AXFR from %s due to "
14799 "previous IXFR failure", master
);
14800 xfrtype
= dns_rdatatype_axfr
;
14802 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
14805 isc_boolean_t use_ixfr
= ISC_TRUE
;
14807 result
= dns_peer_getrequestixfr(peer
, &use_ixfr
);
14808 if (peer
== NULL
|| result
!= ISC_R_SUCCESS
)
14809 use_ixfr
= zone
->requestixfr
;
14810 if (use_ixfr
== ISC_FALSE
) {
14811 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
14812 "IXFR disabled, requesting %sAXFR from %s",
14813 soa_before
, master
);
14814 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
))
14815 xfrtype
= dns_rdatatype_soa
;
14817 xfrtype
= dns_rdatatype_axfr
;
14819 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
14820 "requesting IXFR from %s", master
);
14821 xfrtype
= dns_rdatatype_ixfr
;
14826 * Determine if we should attempt to sign the request with TSIG.
14828 result
= ISC_R_NOTFOUND
;
14831 * First, look for a tsig key in the master statement, then
14832 * try for a server key.
14834 if ((zone
->masterkeynames
!= NULL
) &&
14835 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
14836 dns_view_t
*view
= dns_zone_getview(zone
);
14837 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
14838 result
= dns_view_gettsig(view
, keyname
, &zone
->tsigkey
);
14840 if (zone
->tsigkey
== NULL
)
14841 result
= dns_view_getpeertsig(zone
->view
, &masterip
,
14844 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
14845 dns_zone_log(zone
, ISC_LOG_ERROR
,
14846 "could not get TSIG key for zone transfer: %s",
14847 isc_result_totext(result
));
14850 if (zone
->masterdscps
!= NULL
)
14851 dscp
= zone
->masterdscps
[zone
->curmaster
];
14854 masteraddr
= zone
->masteraddr
;
14855 sourceaddr
= zone
->sourceaddr
;
14856 switch (isc_sockaddr_pf(&masteraddr
)) {
14859 dscp
= zone
->xfrsource4dscp
;
14863 dscp
= zone
->xfrsource6dscp
;
14869 INSIST(isc_sockaddr_pf(&masteraddr
) == isc_sockaddr_pf(&sourceaddr
));
14870 result
= dns_xfrin_create3(zone
, xfrtype
, &masteraddr
, &sourceaddr
,
14871 dscp
, zone
->tsigkey
, zone
->mctx
,
14872 zone
->zmgr
->timermgr
, zone
->zmgr
->socketmgr
,
14873 zone
->task
, zone_xfrdone
, &zone
->xfr
);
14874 if (result
== ISC_R_SUCCESS
) {
14876 if (xfrtype
== dns_rdatatype_axfr
) {
14877 if (isc_sockaddr_pf(&masteraddr
) == PF_INET
)
14878 inc_stats(zone
, dns_zonestatscounter_axfrreqv4
);
14880 inc_stats(zone
, dns_zonestatscounter_axfrreqv6
);
14881 } else if (xfrtype
== dns_rdatatype_ixfr
) {
14882 if (isc_sockaddr_pf(&masteraddr
) == PF_INET
)
14883 inc_stats(zone
, dns_zonestatscounter_ixfrreqv4
);
14885 inc_stats(zone
, dns_zonestatscounter_ixfrreqv6
);
14891 * Any failure in this function is handled like a failed
14892 * zone transfer. This ensures that we get removed from
14893 * zmgr->xfrin_in_progress.
14895 if (result
!= ISC_R_SUCCESS
)
14896 zone_xfrdone(zone
, result
);
14898 isc_event_free(&event
);
14902 * Update forwarding support.
14906 forward_destroy(dns_forward_t
*forward
) {
14908 forward
->magic
= 0;
14909 if (forward
->request
!= NULL
)
14910 dns_request_destroy(&forward
->request
);
14911 if (forward
->msgbuf
!= NULL
)
14912 isc_buffer_free(&forward
->msgbuf
);
14913 if (forward
->zone
!= NULL
) {
14914 LOCK(&forward
->zone
->lock
);
14915 if (ISC_LINK_LINKED(forward
, link
))
14916 ISC_LIST_UNLINK(forward
->zone
->forwards
, forward
, link
);
14917 UNLOCK(&forward
->zone
->lock
);
14918 dns_zone_idetach(&forward
->zone
);
14920 isc_mem_putanddetach(&forward
->mctx
, forward
, sizeof(*forward
));
14923 static isc_result_t
14924 sendtomaster(dns_forward_t
*forward
) {
14925 isc_result_t result
;
14926 isc_sockaddr_t src
;
14927 isc_dscp_t dscp
= -1;
14929 LOCK_ZONE(forward
->zone
);
14931 if (DNS_ZONE_FLAG(forward
->zone
, DNS_ZONEFLG_EXITING
)) {
14932 UNLOCK_ZONE(forward
->zone
);
14933 return (ISC_R_CANCELED
);
14936 if (forward
->which
>= forward
->zone
->masterscnt
) {
14937 UNLOCK_ZONE(forward
->zone
);
14938 return (ISC_R_NOMORE
);
14941 forward
->addr
= forward
->zone
->masters
[forward
->which
];
14943 * Always use TCP regardless of whether the original update
14945 * XXX The timeout may but a bit small if we are far down a
14946 * transfer graph and the master has to try several masters.
14948 switch (isc_sockaddr_pf(&forward
->addr
)) {
14950 src
= forward
->zone
->xfrsource4
;
14951 dscp
= forward
->zone
->xfrsource4dscp
;
14954 src
= forward
->zone
->xfrsource6
;
14955 dscp
= forward
->zone
->xfrsource6dscp
;
14958 result
= ISC_R_NOTIMPLEMENTED
;
14961 result
= dns_request_createraw4(forward
->zone
->view
->requestmgr
,
14963 &src
, &forward
->addr
, dscp
,
14964 forward
->options
, 15 /* XXX */,
14965 0, 0, forward
->zone
->task
,
14966 forward_callback
, forward
,
14967 &forward
->request
);
14968 if (result
== ISC_R_SUCCESS
) {
14969 if (!ISC_LINK_LINKED(forward
, link
))
14970 ISC_LIST_APPEND(forward
->zone
->forwards
, forward
, link
);
14974 UNLOCK_ZONE(forward
->zone
);
14979 forward_callback(isc_task_t
*task
, isc_event_t
*event
) {
14980 const char me
[] = "forward_callback";
14981 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
14982 dns_message_t
*msg
= NULL
;
14983 char master
[ISC_SOCKADDR_FORMATSIZE
];
14984 isc_result_t result
;
14985 dns_forward_t
*forward
;
14990 forward
= revent
->ev_arg
;
14991 INSIST(DNS_FORWARD_VALID(forward
));
14992 zone
= forward
->zone
;
14993 INSIST(DNS_ZONE_VALID(zone
));
14997 isc_sockaddr_format(&forward
->addr
, master
, sizeof(master
));
14999 if (revent
->result
!= ISC_R_SUCCESS
) {
15000 dns_zone_log(zone
, ISC_LOG_INFO
,
15001 "could not forward dynamic update to %s: %s",
15002 master
, dns_result_totext(revent
->result
));
15006 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
15007 if (result
!= ISC_R_SUCCESS
)
15010 result
= dns_request_getresponse(revent
->request
, msg
,
15011 DNS_MESSAGEPARSE_PRESERVEORDER
|
15012 DNS_MESSAGEPARSE_CLONEBUFFER
);
15013 if (result
!= ISC_R_SUCCESS
)
15016 switch (msg
->rcode
) {
15018 * Pass these rcodes back to client.
15020 case dns_rcode_noerror
:
15021 case dns_rcode_yxdomain
:
15022 case dns_rcode_yxrrset
:
15023 case dns_rcode_nxrrset
:
15024 case dns_rcode_refused
:
15025 case dns_rcode_nxdomain
: {
15029 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
15030 (void)dns_rcode_totext(msg
->rcode
, &rb
);
15031 dns_zone_log(zone
, ISC_LOG_INFO
,
15032 "forwarded dynamic update: "
15033 "master %s returned: %.*s",
15034 master
, (int)rb
.used
, rcode
);
15038 /* These should not occur if the masters/zone are valid. */
15039 case dns_rcode_notzone
:
15040 case dns_rcode_notauth
: {
15044 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
15045 (void)dns_rcode_totext(msg
->rcode
, &rb
);
15046 dns_zone_log(zone
, ISC_LOG_WARNING
,
15047 "forwarding dynamic update: "
15048 "unexpected response: master %s returned: %.*s",
15049 master
, (int)rb
.used
, rcode
);
15053 /* Try another server for these rcodes. */
15054 case dns_rcode_formerr
:
15055 case dns_rcode_servfail
:
15056 case dns_rcode_notimp
:
15057 case dns_rcode_badvers
:
15062 /* call callback */
15063 (forward
->callback
)(forward
->callback_arg
, ISC_R_SUCCESS
, msg
);
15065 dns_request_destroy(&forward
->request
);
15066 forward_destroy(forward
);
15067 isc_event_free(&event
);
15072 dns_message_destroy(&msg
);
15073 isc_event_free(&event
);
15075 dns_request_destroy(&forward
->request
);
15076 result
= sendtomaster(forward
);
15077 if (result
!= ISC_R_SUCCESS
) {
15078 /* call callback */
15079 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
15080 "exhausted dynamic update forwarder list");
15081 (forward
->callback
)(forward
->callback_arg
, result
, NULL
);
15082 forward_destroy(forward
);
15087 dns_zone_forwardupdate(dns_zone_t
*zone
, dns_message_t
*msg
,
15088 dns_updatecallback_t callback
, void *callback_arg
)
15090 dns_forward_t
*forward
;
15091 isc_result_t result
;
15094 REQUIRE(DNS_ZONE_VALID(zone
));
15095 REQUIRE(msg
!= NULL
);
15096 REQUIRE(callback
!= NULL
);
15098 forward
= isc_mem_get(zone
->mctx
, sizeof(*forward
));
15099 if (forward
== NULL
)
15100 return (ISC_R_NOMEMORY
);
15102 forward
->request
= NULL
;
15103 forward
->zone
= NULL
;
15104 forward
->msgbuf
= NULL
;
15105 forward
->which
= 0;
15107 forward
->callback
= callback
;
15108 forward
->callback_arg
= callback_arg
;
15109 ISC_LINK_INIT(forward
, link
);
15110 forward
->magic
= FORWARD_MAGIC
;
15111 forward
->options
= DNS_REQUESTOPT_TCP
;
15113 * If we have a SIG(0) signed message we need to preserve the
15114 * query id as that is included in the SIG(0) computation.
15116 if (msg
->sig0
!= NULL
)
15117 forward
->options
|= DNS_REQUESTOPT_FIXEDID
;
15119 mr
= dns_message_getrawmessage(msg
);
15121 result
= ISC_R_UNEXPECTEDEND
;
15125 result
= isc_buffer_allocate(zone
->mctx
, &forward
->msgbuf
, mr
->length
);
15126 if (result
!= ISC_R_SUCCESS
)
15128 result
= isc_buffer_copyregion(forward
->msgbuf
, mr
);
15129 if (result
!= ISC_R_SUCCESS
)
15132 isc_mem_attach(zone
->mctx
, &forward
->mctx
);
15133 dns_zone_iattach(zone
, &forward
->zone
);
15134 result
= sendtomaster(forward
);
15137 if (result
!= ISC_R_SUCCESS
) {
15138 forward_destroy(forward
);
15144 dns_zone_next(dns_zone_t
*zone
, dns_zone_t
**next
) {
15145 REQUIRE(DNS_ZONE_VALID(zone
));
15146 REQUIRE(next
!= NULL
&& *next
== NULL
);
15148 *next
= ISC_LIST_NEXT(zone
, link
);
15150 return (ISC_R_NOMORE
);
15152 return (ISC_R_SUCCESS
);
15156 dns_zone_first(dns_zonemgr_t
*zmgr
, dns_zone_t
**first
) {
15157 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15158 REQUIRE(first
!= NULL
&& *first
== NULL
);
15160 *first
= ISC_LIST_HEAD(zmgr
->zones
);
15161 if (*first
== NULL
)
15162 return (ISC_R_NOMORE
);
15164 return (ISC_R_SUCCESS
);
15172 dns_zonemgr_create(isc_mem_t
*mctx
, isc_taskmgr_t
*taskmgr
,
15173 isc_timermgr_t
*timermgr
, isc_socketmgr_t
*socketmgr
,
15174 dns_zonemgr_t
**zmgrp
)
15176 dns_zonemgr_t
*zmgr
;
15177 isc_result_t result
;
15179 zmgr
= isc_mem_get(mctx
, sizeof(*zmgr
));
15181 return (ISC_R_NOMEMORY
);
15184 isc_mem_attach(mctx
, &zmgr
->mctx
);
15185 zmgr
->taskmgr
= taskmgr
;
15186 zmgr
->timermgr
= timermgr
;
15187 zmgr
->socketmgr
= socketmgr
;
15188 zmgr
->zonetasks
= NULL
;
15189 zmgr
->loadtasks
= NULL
;
15190 zmgr
->mctxpool
= NULL
;
15192 zmgr
->notifyrl
= NULL
;
15193 zmgr
->refreshrl
= NULL
;
15194 zmgr
->startupnotifyrl
= NULL
;
15195 zmgr
->startuprefreshrl
= NULL
;
15196 ISC_LIST_INIT(zmgr
->zones
);
15197 ISC_LIST_INIT(zmgr
->waiting_for_xfrin
);
15198 ISC_LIST_INIT(zmgr
->xfrin_in_progress
);
15199 memset(zmgr
->unreachable
, 0, sizeof(zmgr
->unreachable
));
15200 result
= isc_rwlock_init(&zmgr
->rwlock
, 0, 0);
15201 if (result
!= ISC_R_SUCCESS
)
15204 zmgr
->transfersin
= 10;
15205 zmgr
->transfersperns
= 2;
15207 /* Unreachable lock. */
15208 result
= isc_rwlock_init(&zmgr
->urlock
, 0, 0);
15209 if (result
!= ISC_R_SUCCESS
)
15212 /* Create a single task for queueing of SOA queries. */
15213 result
= isc_task_create(taskmgr
, 1, &zmgr
->task
);
15214 if (result
!= ISC_R_SUCCESS
)
15217 isc_task_setname(zmgr
->task
, "zmgr", zmgr
);
15218 result
= isc_ratelimiter_create(mctx
, timermgr
, zmgr
->task
,
15220 if (result
!= ISC_R_SUCCESS
)
15223 result
= isc_ratelimiter_create(mctx
, timermgr
, zmgr
->task
,
15225 if (result
!= ISC_R_SUCCESS
)
15226 goto free_notifyrl
;
15228 result
= isc_ratelimiter_create(mctx
, timermgr
, zmgr
->task
,
15229 &zmgr
->startupnotifyrl
);
15230 if (result
!= ISC_R_SUCCESS
)
15231 goto free_refreshrl
;
15233 result
= isc_ratelimiter_create(mctx
, timermgr
, zmgr
->task
,
15234 &zmgr
->startuprefreshrl
);
15235 if (result
!= ISC_R_SUCCESS
)
15236 goto free_startupnotifyrl
;
15238 /* default to 20 refresh queries / notifies per second. */
15239 setrl(zmgr
->notifyrl
, &zmgr
->notifyrate
, 20);
15240 setrl(zmgr
->startupnotifyrl
, &zmgr
->startupnotifyrate
, 20);
15241 setrl(zmgr
->refreshrl
, &zmgr
->serialqueryrate
, 20);
15242 setrl(zmgr
->startuprefreshrl
, &zmgr
->startupserialqueryrate
, 20);
15245 zmgr
->ioactive
= 0;
15246 ISC_LIST_INIT(zmgr
->high
);
15247 ISC_LIST_INIT(zmgr
->low
);
15249 result
= isc_mutex_init(&zmgr
->iolock
);
15250 if (result
!= ISC_R_SUCCESS
)
15251 goto free_startuprefreshrl
;
15253 zmgr
->magic
= ZONEMGR_MAGIC
;
15256 return (ISC_R_SUCCESS
);
15260 DESTROYLOCK(&zmgr
->iolock
);
15262 free_startuprefreshrl
:
15263 isc_ratelimiter_detach(&zmgr
->startuprefreshrl
);
15264 free_startupnotifyrl
:
15265 isc_ratelimiter_detach(&zmgr
->startupnotifyrl
);
15267 isc_ratelimiter_detach(&zmgr
->refreshrl
);
15269 isc_ratelimiter_detach(&zmgr
->notifyrl
);
15271 isc_task_detach(&zmgr
->task
);
15273 isc_rwlock_destroy(&zmgr
->urlock
);
15275 isc_rwlock_destroy(&zmgr
->rwlock
);
15277 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof(*zmgr
));
15278 isc_mem_detach(&mctx
);
15283 dns_zonemgr_createzone(dns_zonemgr_t
*zmgr
, dns_zone_t
**zonep
) {
15284 isc_result_t result
;
15285 isc_mem_t
*mctx
= NULL
;
15286 dns_zone_t
*zone
= NULL
;
15289 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15290 REQUIRE(zonep
!= NULL
&& *zonep
== NULL
);
15292 if (zmgr
->mctxpool
== NULL
)
15293 return (ISC_R_FAILURE
);
15295 item
= isc_pool_get(zmgr
->mctxpool
);
15297 return (ISC_R_FAILURE
);
15299 isc_mem_attach((isc_mem_t
*) item
, &mctx
);
15300 result
= dns_zone_create(&zone
, mctx
);
15301 isc_mem_detach(&mctx
);
15303 if (result
== ISC_R_SUCCESS
)
15310 dns_zonemgr_managezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
15311 isc_result_t result
;
15313 REQUIRE(DNS_ZONE_VALID(zone
));
15314 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15316 if (zmgr
->zonetasks
== NULL
)
15317 return (ISC_R_FAILURE
);
15319 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15321 REQUIRE(zone
->task
== NULL
);
15322 REQUIRE(zone
->timer
== NULL
);
15323 REQUIRE(zone
->zmgr
== NULL
);
15325 isc_taskpool_gettask(zmgr
->zonetasks
, &zone
->task
);
15326 isc_taskpool_gettask(zmgr
->loadtasks
, &zone
->loadtask
);
15329 * Set the task name. The tag will arbitrarily point to one
15330 * of the zones sharing the task (in practice, the one
15331 * to be managed last).
15333 isc_task_setname(zone
->task
, "zone", zone
);
15334 isc_task_setname(zone
->loadtask
, "loadzone", zone
);
15336 result
= isc_timer_create(zmgr
->timermgr
, isc_timertype_inactive
,
15338 zone
->task
, zone_timer
, zone
,
15341 if (result
!= ISC_R_SUCCESS
)
15342 goto cleanup_tasks
;
15345 * The timer "holds" a iref.
15348 INSIST(zone
->irefs
!= 0);
15350 ISC_LIST_APPEND(zmgr
->zones
, zone
, link
);
15357 isc_task_detach(&zone
->loadtask
);
15358 isc_task_detach(&zone
->task
);
15362 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15367 dns_zonemgr_releasezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
15368 isc_boolean_t free_now
= ISC_FALSE
;
15370 REQUIRE(DNS_ZONE_VALID(zone
));
15371 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15372 REQUIRE(zone
->zmgr
== zmgr
);
15374 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15377 ISC_LIST_UNLINK(zmgr
->zones
, zone
, link
);
15380 if (zmgr
->refs
== 0)
15381 free_now
= ISC_TRUE
;
15384 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15387 zonemgr_free(zmgr
);
15388 ENSURE(zone
->zmgr
== NULL
);
15392 dns_zonemgr_attach(dns_zonemgr_t
*source
, dns_zonemgr_t
**target
) {
15393 REQUIRE(DNS_ZONEMGR_VALID(source
));
15394 REQUIRE(target
!= NULL
&& *target
== NULL
);
15396 RWLOCK(&source
->rwlock
, isc_rwlocktype_write
);
15397 REQUIRE(source
->refs
> 0);
15399 INSIST(source
->refs
> 0);
15400 RWUNLOCK(&source
->rwlock
, isc_rwlocktype_write
);
15405 dns_zonemgr_detach(dns_zonemgr_t
**zmgrp
) {
15406 dns_zonemgr_t
*zmgr
;
15407 isc_boolean_t free_now
= ISC_FALSE
;
15409 REQUIRE(zmgrp
!= NULL
);
15411 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15413 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15415 if (zmgr
->refs
== 0)
15416 free_now
= ISC_TRUE
;
15417 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15420 zonemgr_free(zmgr
);
15425 dns_zonemgr_forcemaint(dns_zonemgr_t
*zmgr
) {
15428 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15430 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
15431 for (p
= ISC_LIST_HEAD(zmgr
->zones
);
15433 p
= ISC_LIST_NEXT(p
, link
))
15435 dns_zone_maintenance(p
);
15437 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
15440 * Recent configuration changes may have increased the
15441 * amount of available transfers quota. Make sure any
15442 * transfers currently blocked on quota get started if
15445 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15446 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
15447 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15448 return (ISC_R_SUCCESS
);
15452 dns_zonemgr_resumexfrs(dns_zonemgr_t
*zmgr
) {
15454 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15456 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15457 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
15458 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
15462 dns_zonemgr_shutdown(dns_zonemgr_t
*zmgr
) {
15465 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15467 isc_ratelimiter_shutdown(zmgr
->notifyrl
);
15468 isc_ratelimiter_shutdown(zmgr
->refreshrl
);
15469 isc_ratelimiter_shutdown(zmgr
->startupnotifyrl
);
15470 isc_ratelimiter_shutdown(zmgr
->startuprefreshrl
);
15472 if (zmgr
->task
!= NULL
)
15473 isc_task_destroy(&zmgr
->task
);
15474 if (zmgr
->zonetasks
!= NULL
)
15475 isc_taskpool_destroy(&zmgr
->zonetasks
);
15476 if (zmgr
->loadtasks
!= NULL
)
15477 isc_taskpool_destroy(&zmgr
->loadtasks
);
15478 if (zmgr
->mctxpool
!= NULL
)
15479 isc_pool_destroy(&zmgr
->mctxpool
);
15481 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
15482 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
15484 zone
= ISC_LIST_NEXT(zone
, link
))
15487 forward_cancel(zone
);
15490 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
15493 static isc_result_t
15494 mctxinit(void **target
, void *arg
) {
15495 isc_result_t result
;
15496 isc_mem_t
*mctx
= NULL
;
15500 REQUIRE(target
!= NULL
&& *target
== NULL
);
15502 result
= isc_mem_create(0, 0, &mctx
);
15503 if (result
!= ISC_R_SUCCESS
)
15505 isc_mem_setname(mctx
, "zonemgr-pool", NULL
);
15508 return (ISC_R_SUCCESS
);
15512 mctxfree(void **target
) {
15513 isc_mem_t
*mctx
= *(isc_mem_t
**) target
;
15514 isc_mem_detach(&mctx
);
15518 #define ZONES_PER_TASK 100
15519 #define ZONES_PER_MCTX 1000
15522 dns_zonemgr_setsize(dns_zonemgr_t
*zmgr
, int num_zones
) {
15523 isc_result_t result
;
15524 int ntasks
= num_zones
/ ZONES_PER_TASK
;
15525 int nmctx
= num_zones
/ ZONES_PER_MCTX
;
15526 isc_taskpool_t
*pool
= NULL
;
15527 isc_pool_t
*mctxpool
= NULL
;
15529 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15532 * For anything fewer than 1000 zones we use 10 tasks in
15533 * the task pools. More than that, and we'll scale at one
15534 * task per 100 zones. Similarly, for anything smaller than
15535 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
15542 /* Create or resize the zone task pools. */
15543 if (zmgr
->zonetasks
== NULL
)
15544 result
= isc_taskpool_create(zmgr
->taskmgr
, zmgr
->mctx
,
15547 result
= isc_taskpool_expand(&zmgr
->zonetasks
, ntasks
, &pool
);
15549 if (result
== ISC_R_SUCCESS
)
15550 zmgr
->zonetasks
= pool
;
15553 if (zmgr
->loadtasks
== NULL
)
15554 result
= isc_taskpool_create(zmgr
->taskmgr
, zmgr
->mctx
,
15557 result
= isc_taskpool_expand(&zmgr
->loadtasks
, ntasks
, &pool
);
15559 if (result
== ISC_R_SUCCESS
)
15560 zmgr
->loadtasks
= pool
;
15563 * We always set all tasks in the zone-load task pool to
15564 * privileged. This prevents other tasks in the system from
15565 * running while the server task manager is in privileged
15568 * NOTE: If we start using task privileges for any other
15569 * part of the system than zone tasks, then this will need to be
15570 * revisted. In that case we'd want to turn on privileges for
15571 * zone tasks only when we were loading, and turn them off the
15572 * rest of the time. For now, however, it's okay to just
15573 * set it and forget it.
15575 isc_taskpool_setprivilege(zmgr
->loadtasks
, ISC_TRUE
);
15577 /* Create or resize the zone memory context pool. */
15578 if (zmgr
->mctxpool
== NULL
)
15579 result
= isc_pool_create(zmgr
->mctx
, nmctx
, mctxfree
,
15580 mctxinit
, NULL
, &mctxpool
);
15582 result
= isc_pool_expand(&zmgr
->mctxpool
, nmctx
, &mctxpool
);
15584 if (result
== ISC_R_SUCCESS
)
15585 zmgr
->mctxpool
= mctxpool
;
15591 zonemgr_free(dns_zonemgr_t
*zmgr
) {
15594 INSIST(zmgr
->refs
== 0);
15595 INSIST(ISC_LIST_EMPTY(zmgr
->zones
));
15599 DESTROYLOCK(&zmgr
->iolock
);
15600 isc_ratelimiter_detach(&zmgr
->notifyrl
);
15601 isc_ratelimiter_detach(&zmgr
->refreshrl
);
15602 isc_ratelimiter_detach(&zmgr
->startupnotifyrl
);
15603 isc_ratelimiter_detach(&zmgr
->startuprefreshrl
);
15605 isc_rwlock_destroy(&zmgr
->urlock
);
15606 isc_rwlock_destroy(&zmgr
->rwlock
);
15608 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof(*zmgr
));
15609 isc_mem_detach(&mctx
);
15613 dns_zonemgr_settransfersin(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
15614 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15616 zmgr
->transfersin
= value
;
15620 dns_zonemgr_getttransfersin(dns_zonemgr_t
*zmgr
) {
15621 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15623 return (zmgr
->transfersin
);
15627 dns_zonemgr_settransfersperns(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
15628 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15630 zmgr
->transfersperns
= value
;
15634 dns_zonemgr_getttransfersperns(dns_zonemgr_t
*zmgr
) {
15635 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15637 return (zmgr
->transfersperns
);
15641 * Try to start a new incoming zone transfer to fill a quota
15642 * slot that was just vacated.
15645 * The zone manager is locked by the caller.
15648 zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
) {
15652 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
15656 isc_result_t result
;
15657 next
= ISC_LIST_NEXT(zone
, statelink
);
15658 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
15659 if (result
== ISC_R_SUCCESS
) {
15663 * We successfully filled the slot. We're done.
15666 } else if (result
== ISC_R_QUOTA
) {
15668 * Not enough quota. This is probably the per-server
15669 * quota, because we usually get called when a unit of
15670 * global quota has just been freed. Try the next
15671 * zone, it may succeed if it uses another master.
15675 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
15676 "starting zone transfer: %s",
15677 isc_result_totext(result
));
15684 * Try to start an incoming zone transfer for 'zone', quota permitting.
15687 * The zone manager is locked by the caller.
15690 * ISC_R_SUCCESS There was enough quota and we attempted to
15691 * start a transfer. zone_xfrdone() has been or will
15693 * ISC_R_QUOTA Not enough quota.
15696 static isc_result_t
15697 zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
15698 dns_peer_t
*peer
= NULL
;
15699 isc_netaddr_t masterip
;
15700 isc_uint32_t nxfrsin
, nxfrsperns
;
15702 isc_uint32_t maxtransfersin
, maxtransfersperns
;
15706 * If we are exiting just pretend we got quota so the zone will
15707 * be cleaned up in the zone's task context.
15710 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
15716 * Find any configured information about the server we'd
15717 * like to transfer this zone from.
15719 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
15720 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
, &masterip
, &peer
);
15724 * Determine the total maximum number of simultaneous
15725 * transfers allowed, and the maximum for this specific
15728 maxtransfersin
= zmgr
->transfersin
;
15729 maxtransfersperns
= zmgr
->transfersperns
;
15731 (void)dns_peer_gettransfers(peer
, &maxtransfersperns
);
15734 * Count the total number of transfers that are in progress,
15735 * and the number of transfers in progress from this master.
15736 * We linearly scan a list of all transfers; if this turns
15737 * out to be too slow, we could hash on the master address.
15739 nxfrsin
= nxfrsperns
= 0;
15740 for (x
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
15742 x
= ISC_LIST_NEXT(x
, statelink
))
15747 isc_netaddr_fromsockaddr(&xip
, &x
->masteraddr
);
15751 if (isc_netaddr_equal(&xip
, &masterip
))
15755 /* Enforce quota. */
15756 if (nxfrsin
>= maxtransfersin
)
15757 return (ISC_R_QUOTA
);
15759 if (nxfrsperns
>= maxtransfersperns
)
15760 return (ISC_R_QUOTA
);
15764 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
15765 * list and send it an event to let it start the actual transfer in the
15766 * context of its own task.
15768 e
= isc_event_allocate(zmgr
->mctx
, zmgr
, DNS_EVENT_ZONESTARTXFRIN
,
15769 got_transfer_quota
, zone
, sizeof(isc_event_t
));
15771 return (ISC_R_NOMEMORY
);
15774 INSIST(zone
->statelist
== &zmgr
->waiting_for_xfrin
);
15775 ISC_LIST_UNLINK(zmgr
->waiting_for_xfrin
, zone
, statelink
);
15776 ISC_LIST_APPEND(zmgr
->xfrin_in_progress
, zone
, statelink
);
15777 zone
->statelist
= &zmgr
->xfrin_in_progress
;
15778 isc_task_send(zone
->task
, &e
);
15779 dns_zone_log(zone
, ISC_LOG_INFO
, "Transfer started.");
15782 return (ISC_R_SUCCESS
);
15786 dns_zonemgr_setiolimit(dns_zonemgr_t
*zmgr
, isc_uint32_t iolimit
) {
15788 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15789 REQUIRE(iolimit
> 0);
15791 zmgr
->iolimit
= iolimit
;
15795 dns_zonemgr_getiolimit(dns_zonemgr_t
*zmgr
) {
15797 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15799 return (zmgr
->iolimit
);
15803 * Get permission to request a file handle from the OS.
15804 * An event will be sent to action when one is available.
15805 * There are two queues available (high and low), the high
15806 * queue will be serviced before the low one.
15808 * zonemgr_putio() must be called after the event is delivered to
15812 static isc_result_t
15813 zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
15814 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
15818 isc_boolean_t queue
;
15820 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
15821 REQUIRE(iop
!= NULL
&& *iop
== NULL
);
15823 io
= isc_mem_get(zmgr
->mctx
, sizeof(*io
));
15825 return (ISC_R_NOMEMORY
);
15827 io
->event
= isc_event_allocate(zmgr
->mctx
, task
, DNS_EVENT_IOREADY
,
15828 action
, arg
, sizeof(*io
->event
));
15829 if (io
->event
== NULL
) {
15830 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
15831 return (ISC_R_NOMEMORY
);
15837 isc_task_attach(task
, &io
->task
);
15838 ISC_LINK_INIT(io
, link
);
15839 io
->magic
= IO_MAGIC
;
15841 LOCK(&zmgr
->iolock
);
15843 queue
= ISC_TF(zmgr
->ioactive
> zmgr
->iolimit
);
15846 ISC_LIST_APPEND(zmgr
->high
, io
, link
);
15848 ISC_LIST_APPEND(zmgr
->low
, io
, link
);
15850 UNLOCK(&zmgr
->iolock
);
15854 isc_task_send(io
->task
, &io
->event
);
15855 return (ISC_R_SUCCESS
);
15859 zonemgr_putio(dns_io_t
**iop
) {
15862 dns_zonemgr_t
*zmgr
;
15864 REQUIRE(iop
!= NULL
);
15866 REQUIRE(DNS_IO_VALID(io
));
15870 INSIST(!ISC_LINK_LINKED(io
, link
));
15871 INSIST(io
->event
== NULL
);
15874 isc_task_detach(&io
->task
);
15876 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
15878 LOCK(&zmgr
->iolock
);
15879 INSIST(zmgr
->ioactive
> 0);
15881 next
= HEAD(zmgr
->high
);
15883 next
= HEAD(zmgr
->low
);
15884 if (next
!= NULL
) {
15886 ISC_LIST_UNLINK(zmgr
->high
, next
, link
);
15888 ISC_LIST_UNLINK(zmgr
->low
, next
, link
);
15889 INSIST(next
->event
!= NULL
);
15891 UNLOCK(&zmgr
->iolock
);
15893 isc_task_send(next
->task
, &next
->event
);
15897 zonemgr_cancelio(dns_io_t
*io
) {
15898 isc_boolean_t send_event
= ISC_FALSE
;
15900 REQUIRE(DNS_IO_VALID(io
));
15903 * If we are queued to be run then dequeue.
15905 LOCK(&io
->zmgr
->iolock
);
15906 if (ISC_LINK_LINKED(io
, link
)) {
15908 ISC_LIST_UNLINK(io
->zmgr
->high
, io
, link
);
15910 ISC_LIST_UNLINK(io
->zmgr
->low
, io
, link
);
15912 send_event
= ISC_TRUE
;
15913 INSIST(io
->event
!= NULL
);
15915 UNLOCK(&io
->zmgr
->iolock
);
15917 io
->event
->ev_attributes
|= ISC_EVENTATTR_CANCELED
;
15918 isc_task_send(io
->task
, &io
->event
);
15923 zone_saveunique(dns_zone_t
*zone
, const char *path
, const char *templat
) {
15926 isc_result_t result
;
15928 buflen
= strlen(path
) + strlen(templat
) + 2;
15930 buf
= isc_mem_get(zone
->mctx
, buflen
);
15934 result
= isc_file_template(path
, templat
, buf
, buflen
);
15935 if (result
!= ISC_R_SUCCESS
)
15938 result
= isc_file_renameunique(path
, buf
);
15939 if (result
!= ISC_R_SUCCESS
)
15942 dns_zone_log(zone
, ISC_LOG_WARNING
, "unable to load from '%s'; "
15943 "renaming file to '%s' for failure analysis and "
15944 "retransferring.", path
, buf
);
15947 isc_mem_put(zone
->mctx
, buf
, buflen
);
15951 /* Hook for ondestroy notification from a database. */
15954 dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
) {
15955 dns_db_t
*db
= event
->sender
;
15958 isc_event_free(&event
);
15960 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
15961 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
15962 "database (%p) destroyed", (void*) db
);
15967 setrl(isc_ratelimiter_t
*rl
, unsigned int *rate
, unsigned int value
) {
15968 isc_interval_t interval
;
15969 isc_uint32_t s
, ns
;
15970 isc_uint32_t pertic
;
15971 isc_result_t result
;
15980 } else if (value
<= 10) {
15982 ns
= 1000000000 / value
;
15986 ns
= (1000000000 / value
) * 10;
15990 isc_interval_set(&interval
, s
, ns
);
15992 result
= isc_ratelimiter_setinterval(rl
, &interval
);
15993 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
15994 isc_ratelimiter_setpertic(rl
, pertic
);
16000 dns_zonemgr_setserialqueryrate(dns_zonemgr_t
*zmgr
, unsigned int value
) {
16002 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
16004 setrl(zmgr
->refreshrl
, &zmgr
->serialqueryrate
, value
);
16006 /* Seperately controlled in BIND 9.11.x */
16007 setrl(zmgr
->notifyrl
, &zmgr
->notifyrate
, 20);
16008 setrl(zmgr
->startupnotifyrl
, &zmgr
->startupnotifyrate
, 20);
16010 /* XXXMPA seperate out once we have the code to support this. */
16011 setrl(zmgr
->startuprefreshrl
, &zmgr
->startupserialqueryrate
, value
);
16015 dns_zonemgr_getserialqueryrate(dns_zonemgr_t
*zmgr
) {
16016 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
16018 return (zmgr
->serialqueryrate
);
16022 dns_zonemgr_unreachable(dns_zonemgr_t
*zmgr
, isc_sockaddr_t
*remote
,
16023 isc_sockaddr_t
*local
, isc_time_t
*now
)
16026 isc_rwlocktype_t locktype
;
16027 isc_result_t result
;
16028 isc_uint32_t seconds
= isc_time_seconds(now
);
16029 isc_uint32_t count
= 0;
16031 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
16033 locktype
= isc_rwlocktype_read
;
16034 RWLOCK(&zmgr
->urlock
, locktype
);
16035 for (i
= 0; i
< UNREACH_CHACHE_SIZE
; i
++) {
16036 if (zmgr
->unreachable
[i
].expire
>= seconds
&&
16037 isc_sockaddr_equal(&zmgr
->unreachable
[i
].remote
, remote
) &&
16038 isc_sockaddr_equal(&zmgr
->unreachable
[i
].local
, local
)) {
16039 result
= isc_rwlock_tryupgrade(&zmgr
->urlock
);
16040 if (result
== ISC_R_SUCCESS
) {
16041 locktype
= isc_rwlocktype_write
;
16042 zmgr
->unreachable
[i
].last
= seconds
;
16043 count
= zmgr
->unreachable
[i
].count
;
16048 RWUNLOCK(&zmgr
->urlock
, locktype
);
16049 return (ISC_TF(i
< UNREACH_CHACHE_SIZE
&& count
> 1U));
16053 dns_zonemgr_unreachabledel(dns_zonemgr_t
*zmgr
, isc_sockaddr_t
*remote
,
16054 isc_sockaddr_t
*local
)
16057 isc_rwlocktype_t locktype
;
16058 isc_result_t result
;
16060 char master
[ISC_SOCKADDR_FORMATSIZE
];
16061 char source
[ISC_SOCKADDR_FORMATSIZE
];
16063 isc_sockaddr_format(remote
, master
, sizeof(master
));
16064 isc_sockaddr_format(local
, source
, sizeof(source
));
16066 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
16068 locktype
= isc_rwlocktype_read
;
16069 RWLOCK(&zmgr
->urlock
, locktype
);
16070 for (i
= 0; i
< UNREACH_CHACHE_SIZE
; i
++) {
16071 if (isc_sockaddr_equal(&zmgr
->unreachable
[i
].remote
, remote
) &&
16072 isc_sockaddr_equal(&zmgr
->unreachable
[i
].local
, local
)) {
16073 if (zmgr
->unreachable
[i
].expire
== 0)
16075 result
= isc_rwlock_tryupgrade(&zmgr
->urlock
);
16076 if (result
== ISC_R_SUCCESS
) {
16077 locktype
= isc_rwlocktype_write
;
16078 zmgr
->unreachable
[i
].expire
= 0;
16079 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
16080 DNS_LOGMODULE_ZONE
, ISC_LOG_INFO
,
16081 "master %s (source %s) deleted "
16082 "from unreachable cache",
16088 RWUNLOCK(&zmgr
->urlock
, locktype
);
16092 dns_zonemgr_unreachableadd(dns_zonemgr_t
*zmgr
, isc_sockaddr_t
*remote
,
16093 isc_sockaddr_t
*local
, isc_time_t
*now
)
16095 isc_uint32_t seconds
= isc_time_seconds(now
);
16096 isc_uint32_t last
= seconds
;
16097 unsigned int i
, slot
= UNREACH_CHACHE_SIZE
, oldest
= 0;
16099 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
16101 RWLOCK(&zmgr
->urlock
, isc_rwlocktype_write
);
16102 for (i
= 0; i
< UNREACH_CHACHE_SIZE
; i
++) {
16103 /* Existing entry? */
16104 if (isc_sockaddr_equal(&zmgr
->unreachable
[i
].remote
, remote
) &&
16105 isc_sockaddr_equal(&zmgr
->unreachable
[i
].local
, local
))
16108 if (zmgr
->unreachable
[i
].expire
< seconds
)
16110 /* Least recently used slot? */
16111 if (zmgr
->unreachable
[i
].last
< last
) {
16112 last
= zmgr
->unreachable
[i
].last
;
16116 if (i
< UNREACH_CHACHE_SIZE
) {
16118 * Found a existing entry. Update the expire timer and
16119 * last usage timestamps.
16121 zmgr
->unreachable
[i
].expire
= seconds
+ UNREACH_HOLD_TIME
;
16122 zmgr
->unreachable
[i
].last
= seconds
;
16123 if (zmgr
->unreachable
[i
].expire
< seconds
)
16124 zmgr
->unreachable
[i
].count
= 1;
16126 zmgr
->unreachable
[i
].count
++;
16127 } else if (slot
!= UNREACH_CHACHE_SIZE
) {
16129 * Found a empty slot. Add a new entry to the cache.
16131 zmgr
->unreachable
[slot
].expire
= seconds
+ UNREACH_HOLD_TIME
;
16132 zmgr
->unreachable
[slot
].last
= seconds
;
16133 zmgr
->unreachable
[slot
].remote
= *remote
;
16134 zmgr
->unreachable
[slot
].local
= *local
;
16135 zmgr
->unreachable
[slot
].count
= 1;
16138 * Replace the least recently used entry in the cache.
16140 zmgr
->unreachable
[oldest
].expire
= seconds
+ UNREACH_HOLD_TIME
;
16141 zmgr
->unreachable
[oldest
].last
= seconds
;
16142 zmgr
->unreachable
[oldest
].remote
= *remote
;
16143 zmgr
->unreachable
[oldest
].local
= *local
;
16144 zmgr
->unreachable
[oldest
].count
= 1;
16146 RWUNLOCK(&zmgr
->urlock
, isc_rwlocktype_write
);
16150 dns_zone_forcereload(dns_zone_t
*zone
) {
16151 REQUIRE(DNS_ZONE_VALID(zone
));
16153 if (zone
->type
== dns_zone_master
||
16154 (zone
->type
== dns_zone_redirect
&& zone
->masters
== NULL
))
16158 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
16160 dns_zone_refresh(zone
);
16164 dns_zone_isforced(dns_zone_t
*zone
) {
16165 REQUIRE(DNS_ZONE_VALID(zone
));
16167 return (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
));
16171 dns_zone_setstatistics(dns_zone_t
*zone
, isc_boolean_t on
) {
16173 * This function is obsoleted.
16177 return (ISC_R_NOTIMPLEMENTED
);
16181 dns_zone_getstatscounters(dns_zone_t
*zone
) {
16183 * This function is obsoleted.
16190 dns_zone_setstats(dns_zone_t
*zone
, isc_stats_t
*stats
) {
16191 REQUIRE(DNS_ZONE_VALID(zone
));
16192 REQUIRE(zone
->stats
== NULL
);
16195 zone
->stats
= NULL
;
16196 isc_stats_attach(stats
, &zone
->stats
);
16201 dns_zone_setrequeststats(dns_zone_t
*zone
, isc_stats_t
*stats
) {
16203 REQUIRE(DNS_ZONE_VALID(zone
));
16206 if (zone
->requeststats_on
&& stats
== NULL
)
16207 zone
->requeststats_on
= ISC_FALSE
;
16208 else if (!zone
->requeststats_on
&& stats
!= NULL
) {
16209 if (zone
->requeststats
== NULL
) {
16210 isc_stats_attach(stats
, &zone
->requeststats
);
16211 zone
->requeststats_on
= ISC_TRUE
;
16218 dns_zone_setrcvquerystats(dns_zone_t
*zone
, dns_stats_t
*stats
) {
16220 REQUIRE(DNS_ZONE_VALID(zone
));
16223 if (zone
->requeststats_on
&& stats
!= NULL
) {
16224 if (zone
->rcvquerystats
== NULL
) {
16225 dns_stats_attach(stats
, &zone
->rcvquerystats
);
16226 zone
->requeststats_on
= ISC_TRUE
;
16233 dns_zone_getrequeststats(dns_zone_t
*zone
) {
16235 * We don't lock zone for efficiency reason. This is not catastrophic
16236 * because requeststats must always be valid when requeststats_on is
16238 * Some counters may be incremented while requeststats_on is becoming
16239 * false, or some cannot be incremented just after the statistics are
16240 * installed, but it shouldn't matter much in practice.
16242 if (zone
->requeststats_on
)
16243 return (zone
->requeststats
);
16249 * Return the received query stats bucket
16250 * see note from dns_zone_getrequeststats()
16253 dns_zone_getrcvquerystats(dns_zone_t
*zone
) {
16254 if (zone
->requeststats_on
)
16255 return (zone
->rcvquerystats
);
16261 dns_zone_dialup(dns_zone_t
*zone
) {
16263 REQUIRE(DNS_ZONE_VALID(zone
));
16265 zone_debuglog(zone
, "dns_zone_dialup", 3,
16266 "notify = %d, refresh = %d",
16267 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
),
16268 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
));
16270 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
16271 dns_zone_notify(zone
);
16272 if (zone
->type
!= dns_zone_master
&& zone
->masters
!= NULL
&&
16273 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
16274 dns_zone_refresh(zone
);
16278 dns_zone_setdialup(dns_zone_t
*zone
, dns_dialuptype_t dialup
) {
16279 REQUIRE(DNS_ZONE_VALID(zone
));
16282 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
|
16283 DNS_ZONEFLG_DIALREFRESH
|
16284 DNS_ZONEFLG_NOREFRESH
);
16286 case dns_dialuptype_no
:
16288 case dns_dialuptype_yes
:
16289 DNS_ZONE_SETFLAG(zone
, (DNS_ZONEFLG_DIALNOTIFY
|
16290 DNS_ZONEFLG_DIALREFRESH
|
16291 DNS_ZONEFLG_NOREFRESH
));
16293 case dns_dialuptype_notify
:
16294 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
16296 case dns_dialuptype_notifypassive
:
16297 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
16298 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
16300 case dns_dialuptype_refresh
:
16301 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALREFRESH
);
16302 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
16304 case dns_dialuptype_passive
:
16305 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
16314 dns_zone_setkeydirectory(dns_zone_t
*zone
, const char *directory
) {
16315 isc_result_t result
= ISC_R_SUCCESS
;
16317 REQUIRE(DNS_ZONE_VALID(zone
));
16320 result
= dns_zone_setstring(zone
, &zone
->keydirectory
, directory
);
16327 dns_zone_getkeydirectory(dns_zone_t
*zone
) {
16328 REQUIRE(DNS_ZONE_VALID(zone
));
16330 return (zone
->keydirectory
);
16334 dns_zonemgr_getcount(dns_zonemgr_t
*zmgr
, int state
) {
16336 unsigned int count
= 0;
16338 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
16340 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
16342 case DNS_ZONESTATE_XFERRUNNING
:
16343 for (zone
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
16345 zone
= ISC_LIST_NEXT(zone
, statelink
))
16348 case DNS_ZONESTATE_XFERDEFERRED
:
16349 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
16351 zone
= ISC_LIST_NEXT(zone
, statelink
))
16354 case DNS_ZONESTATE_SOAQUERY
:
16355 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
16357 zone
= ISC_LIST_NEXT(zone
, link
))
16358 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
))
16361 case DNS_ZONESTATE_ANY
:
16362 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
16364 zone
= ISC_LIST_NEXT(zone
, link
)) {
16365 dns_view_t
*view
= zone
->view
;
16366 if (view
!= NULL
&& strcmp(view
->name
, "_bind") == 0)
16375 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
16381 dns_zone_checknames(dns_zone_t
*zone
, dns_name_t
*name
, dns_rdata_t
*rdata
) {
16382 isc_boolean_t ok
= ISC_TRUE
;
16383 isc_boolean_t fail
= ISC_FALSE
;
16384 char namebuf
[DNS_NAME_FORMATSIZE
];
16385 char namebuf2
[DNS_NAME_FORMATSIZE
];
16386 char typebuf
[DNS_RDATATYPE_FORMATSIZE
];
16387 int level
= ISC_LOG_WARNING
;
16390 REQUIRE(DNS_ZONE_VALID(zone
));
16392 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMES
) &&
16393 rdata
->type
!= dns_rdatatype_nsec3
)
16394 return (ISC_R_SUCCESS
);
16396 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
) ||
16397 rdata
->type
== dns_rdatatype_nsec3
) {
16398 level
= ISC_LOG_ERROR
;
16402 ok
= dns_rdata_checkowner(name
, rdata
->rdclass
, rdata
->type
, ISC_TRUE
);
16404 dns_name_format(name
, namebuf
, sizeof(namebuf
));
16405 dns_rdatatype_format(rdata
->type
, typebuf
, sizeof(typebuf
));
16406 dns_zone_log(zone
, level
, "%s/%s: %s", namebuf
, typebuf
,
16407 dns_result_totext(DNS_R_BADOWNERNAME
));
16409 return (DNS_R_BADOWNERNAME
);
16412 dns_name_init(&bad
, NULL
);
16413 ok
= dns_rdata_checknames(rdata
, name
, &bad
);
16415 dns_name_format(name
, namebuf
, sizeof(namebuf
));
16416 dns_name_format(&bad
, namebuf2
, sizeof(namebuf2
));
16417 dns_rdatatype_format(rdata
->type
, typebuf
, sizeof(typebuf
));
16418 dns_zone_log(zone
, level
, "%s/%s: %s: %s ", namebuf
, typebuf
,
16419 namebuf2
, dns_result_totext(DNS_R_BADNAME
));
16421 return (DNS_R_BADNAME
);
16424 return (ISC_R_SUCCESS
);
16428 dns_zone_setcheckmx(dns_zone_t
*zone
, dns_checkmxfunc_t checkmx
) {
16429 REQUIRE(DNS_ZONE_VALID(zone
));
16430 zone
->checkmx
= checkmx
;
16434 dns_zone_setchecksrv(dns_zone_t
*zone
, dns_checksrvfunc_t checksrv
) {
16435 REQUIRE(DNS_ZONE_VALID(zone
));
16436 zone
->checksrv
= checksrv
;
16440 dns_zone_setcheckns(dns_zone_t
*zone
, dns_checknsfunc_t checkns
) {
16441 REQUIRE(DNS_ZONE_VALID(zone
));
16442 zone
->checkns
= checkns
;
16446 dns_zone_setisself(dns_zone_t
*zone
, dns_isselffunc_t isself
, void *arg
) {
16447 REQUIRE(DNS_ZONE_VALID(zone
));
16450 zone
->isself
= isself
;
16451 zone
->isselfarg
= arg
;
16456 dns_zone_setnotifydelay(dns_zone_t
*zone
, isc_uint32_t delay
) {
16457 REQUIRE(DNS_ZONE_VALID(zone
));
16460 zone
->notifydelay
= delay
;
16465 dns_zone_getnotifydelay(dns_zone_t
*zone
) {
16466 REQUIRE(DNS_ZONE_VALID(zone
));
16468 return (zone
->notifydelay
);
16472 dns_zone_signwithkey(dns_zone_t
*zone
, dns_secalg_t algorithm
,
16473 isc_uint16_t keyid
, isc_boolean_t
delete)
16475 isc_result_t result
;
16476 REQUIRE(DNS_ZONE_VALID(zone
));
16478 dns_zone_log(zone
, ISC_LOG_NOTICE
,
16479 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
16482 result
= zone_signwithkey(zone
, algorithm
, keyid
, delete);
16488 static const char *hex
= "0123456789ABCDEF";
16491 dns_zone_addnsec3chain(dns_zone_t
*zone
, dns_rdata_nsec3param_t
*nsec3param
) {
16492 isc_result_t result
;
16493 char salt
[255*2+1];
16496 REQUIRE(DNS_ZONE_VALID(zone
));
16498 if (nsec3param
->salt_length
!= 0) {
16499 INSIST((nsec3param
->salt_length
* 2U) < sizeof(salt
));
16500 for (i
= 0, j
= 0; i
< nsec3param
->salt_length
; i
++) {
16501 salt
[j
++] = hex
[(nsec3param
->salt
[i
] >> 4) & 0xf];
16502 salt
[j
++] = hex
[nsec3param
->salt
[i
] & 0xf];
16507 dns_zone_log(zone
, ISC_LOG_NOTICE
,
16508 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
16509 nsec3param
->hash
, nsec3param
->iterations
,
16512 result
= zone_addnsec3chain(zone
, nsec3param
);
16519 dns_zone_setnodes(dns_zone_t
*zone
, isc_uint32_t nodes
) {
16520 REQUIRE(DNS_ZONE_VALID(zone
));
16524 zone
->nodes
= nodes
;
16528 dns_zone_setsignatures(dns_zone_t
*zone
, isc_uint32_t signatures
) {
16529 REQUIRE(DNS_ZONE_VALID(zone
));
16532 * We treat signatures as a signed value so explicitly
16533 * limit its range here.
16535 if (signatures
> ISC_INT32_MAX
)
16536 signatures
= ISC_INT32_MAX
;
16537 else if (signatures
== 0)
16539 zone
->signatures
= signatures
;
16543 dns_zone_setprivatetype(dns_zone_t
*zone
, dns_rdatatype_t type
) {
16544 REQUIRE(DNS_ZONE_VALID(zone
));
16545 zone
->privatetype
= type
;
16549 dns_zone_getprivatetype(dns_zone_t
*zone
) {
16550 REQUIRE(DNS_ZONE_VALID(zone
));
16551 return (zone
->privatetype
);
16554 static isc_result_t
16555 zone_signwithkey(dns_zone_t
*zone
, dns_secalg_t algorithm
, isc_uint16_t keyid
,
16556 isc_boolean_t
delete)
16558 dns_signing_t
*signing
;
16559 dns_signing_t
*current
;
16560 isc_result_t result
= ISC_R_SUCCESS
;
16562 dns_db_t
*db
= NULL
;
16564 signing
= isc_mem_get(zone
->mctx
, sizeof *signing
);
16565 if (signing
== NULL
)
16566 return (ISC_R_NOMEMORY
);
16568 signing
->magic
= 0;
16569 signing
->db
= NULL
;
16570 signing
->dbiterator
= NULL
;
16571 signing
->algorithm
= algorithm
;
16572 signing
->keyid
= keyid
;
16573 signing
->delete = delete;
16574 signing
->done
= ISC_FALSE
;
16578 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
16579 if (zone
->db
!= NULL
)
16580 dns_db_attach(zone
->db
, &db
);
16581 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
16584 result
= ISC_R_NOTFOUND
;
16588 dns_db_attach(db
, &signing
->db
);
16590 for (current
= ISC_LIST_HEAD(zone
->signing
);
16592 current
= ISC_LIST_NEXT(current
, link
)) {
16593 if (current
->db
== signing
->db
&&
16594 current
->algorithm
== signing
->algorithm
&&
16595 current
->keyid
== signing
->keyid
) {
16596 if (current
->delete != signing
->delete)
16597 current
->done
= ISC_TRUE
;
16603 result
= dns_db_createiterator(signing
->db
, 0,
16604 &signing
->dbiterator
);
16606 if (result
== ISC_R_SUCCESS
)
16607 result
= dns_dbiterator_first(signing
->dbiterator
);
16608 if (result
== ISC_R_SUCCESS
) {
16609 dns_dbiterator_pause(signing
->dbiterator
);
16610 ISC_LIST_INITANDAPPEND(zone
->signing
, signing
, link
);
16612 if (isc_time_isepoch(&zone
->signingtime
)) {
16613 zone
->signingtime
= now
;
16614 if (zone
->task
!= NULL
)
16615 zone_settimer(zone
, &now
);
16620 if (signing
!= NULL
) {
16621 if (signing
->db
!= NULL
)
16622 dns_db_detach(&signing
->db
);
16623 if (signing
->dbiterator
!= NULL
)
16624 dns_dbiterator_destroy(&signing
->dbiterator
);
16625 isc_mem_put(zone
->mctx
, signing
, sizeof *signing
);
16628 dns_db_detach(&db
);
16633 logmsg(const char *format
, ...) {
16635 va_start(args
, format
);
16636 isc_log_vwrite(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
16637 ISC_LOG_DEBUG(1), format
, args
);
16642 clear_keylist(dns_dnsseckeylist_t
*list
, isc_mem_t
*mctx
) {
16643 dns_dnsseckey_t
*key
;
16644 while (!ISC_LIST_EMPTY(*list
)) {
16645 key
= ISC_LIST_HEAD(*list
);
16646 ISC_LIST_UNLINK(*list
, key
, link
);
16647 dns_dnsseckey_destroy(mctx
, &key
);
16651 /* Called once; *timep should be set to the current time. */
16652 static isc_result_t
16653 next_keyevent(dst_key_t
*key
, isc_stdtime_t
*timep
) {
16654 isc_result_t result
;
16655 isc_stdtime_t now
, then
= 0, event
;
16660 for (i
= 0; i
<= DST_MAX_TIMES
; i
++) {
16661 result
= dst_key_gettime(key
, i
, &event
);
16662 if (result
== ISC_R_SUCCESS
&& event
> now
&&
16663 (then
== 0 || event
< then
))
16669 return (ISC_R_SUCCESS
);
16672 return (ISC_R_NOTFOUND
);
16675 static isc_result_t
16676 rr_exists(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_name_t
*name
,
16677 const dns_rdata_t
*rdata
, isc_boolean_t
*flag
)
16679 dns_rdataset_t rdataset
;
16680 dns_dbnode_t
*node
= NULL
;
16681 isc_result_t result
;
16683 dns_rdataset_init(&rdataset
);
16684 if (rdata
->type
== dns_rdatatype_nsec3
)
16685 CHECK(dns_db_findnsec3node(db
, name
, ISC_FALSE
, &node
));
16687 CHECK(dns_db_findnode(db
, name
, ISC_FALSE
, &node
));
16688 result
= dns_db_findrdataset(db
, node
, ver
, rdata
->type
, 0,
16689 (isc_stdtime_t
) 0, &rdataset
, NULL
);
16690 if (result
== ISC_R_NOTFOUND
) {
16692 result
= ISC_R_SUCCESS
;
16696 for (result
= dns_rdataset_first(&rdataset
);
16697 result
== ISC_R_SUCCESS
;
16698 result
= dns_rdataset_next(&rdataset
)) {
16699 dns_rdata_t myrdata
= DNS_RDATA_INIT
;
16700 dns_rdataset_current(&rdataset
, &myrdata
);
16701 if (!dns_rdata_compare(&myrdata
, rdata
))
16704 dns_rdataset_disassociate(&rdataset
);
16705 if (result
== ISC_R_SUCCESS
) {
16707 } else if (result
== ISC_R_NOMORE
) {
16709 result
= ISC_R_SUCCESS
;
16714 dns_db_detachnode(db
, &node
);
16719 * Add records to signal the state of signing or of key removal.
16721 static isc_result_t
16722 add_signing_records(dns_db_t
*db
, dns_rdatatype_t privatetype
,
16723 dns_dbversion_t
*ver
, dns_diff_t
*diff
,
16724 isc_boolean_t sign_all
)
16726 dns_difftuple_t
*tuple
, *newtuple
= NULL
;
16727 dns_rdata_dnskey_t dnskey
;
16728 dns_rdata_t rdata
= DNS_RDATA_INIT
;
16729 isc_boolean_t flag
;
16731 isc_result_t result
= ISC_R_SUCCESS
;
16732 isc_uint16_t keyid
;
16733 unsigned char buf
[5];
16734 dns_name_t
*name
= dns_db_origin(db
);
16736 for (tuple
= ISC_LIST_HEAD(diff
->tuples
);
16738 tuple
= ISC_LIST_NEXT(tuple
, link
)) {
16739 if (tuple
->rdata
.type
!= dns_rdatatype_dnskey
)
16742 result
= dns_rdata_tostruct(&tuple
->rdata
, &dnskey
, NULL
);
16743 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
16744 if ((dnskey
.flags
&
16745 (DNS_KEYFLAG_OWNERMASK
|DNS_KEYTYPE_NOAUTH
))
16746 != DNS_KEYOWNER_ZONE
)
16749 dns_rdata_toregion(&tuple
->rdata
, &r
);
16751 keyid
= dst_region_computeid(&r
, dnskey
.algorithm
);
16753 buf
[0] = dnskey
.algorithm
;
16754 buf
[1] = (keyid
& 0xff00) >> 8;
16755 buf
[2] = (keyid
& 0xff);
16756 buf
[3] = (tuple
->op
== DNS_DIFFOP_ADD
) ? 0 : 1;
16759 rdata
.length
= sizeof(buf
);
16760 rdata
.type
= privatetype
;
16761 rdata
.rdclass
= tuple
->rdata
.rdclass
;
16763 if (sign_all
|| tuple
->op
== DNS_DIFFOP_DEL
) {
16764 CHECK(rr_exists(db
, ver
, name
, &rdata
, &flag
));
16767 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
16768 name
, 0, &rdata
, &newtuple
));
16769 CHECK(do_one_tuple(&newtuple
, db
, ver
, diff
));
16770 INSIST(newtuple
== NULL
);
16774 * Remove any record which says this operation has already
16778 CHECK(rr_exists(db
, ver
, name
, &rdata
, &flag
));
16780 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_DEL
,
16781 name
, 0, &rdata
, &newtuple
));
16782 CHECK(do_one_tuple(&newtuple
, db
, ver
, diff
));
16783 INSIST(newtuple
== NULL
);
16790 static isc_result_t
16791 sign_apex(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
16792 dns_diff_t
*diff
, zonediff_t
*zonediff
)
16794 isc_result_t result
;
16795 isc_stdtime_t now
, inception
, soaexpire
;
16796 isc_boolean_t check_ksk
, keyset_kskonly
;
16797 dst_key_t
*zone_keys
[DNS_MAXZONEKEYS
];
16798 unsigned int nkeys
= 0, i
;
16799 dns_difftuple_t
*tuple
;
16801 result
= find_zone_keys(zone
, db
, ver
, zone
->mctx
, DNS_MAXZONEKEYS
,
16802 zone_keys
, &nkeys
);
16803 if (result
!= ISC_R_SUCCESS
) {
16804 dns_zone_log(zone
, ISC_LOG_ERROR
,
16805 "sign_apex:find_zone_keys -> %s",
16806 dns_result_totext(result
));
16810 isc_stdtime_get(&now
);
16811 inception
= now
- 3600; /* Allow for clock skew. */
16812 soaexpire
= now
+ dns_zone_getsigvalidityinterval(zone
);
16814 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
16815 keyset_kskonly
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
);
16818 * See if update_sigs will update DNSKEY signature and if not
16819 * cause them to sign so that so that newly activated keys
16822 for (tuple
= ISC_LIST_HEAD(diff
->tuples
);
16824 tuple
= ISC_LIST_NEXT(tuple
, link
)) {
16825 if (tuple
->rdata
.type
== dns_rdatatype_dnskey
&&
16826 dns_name_equal(&tuple
->name
, &zone
->origin
))
16830 if (tuple
== NULL
) {
16831 result
= del_sigs(zone
, db
, ver
, &zone
->origin
,
16832 dns_rdatatype_dnskey
, zonediff
,
16833 zone_keys
, nkeys
, now
, ISC_FALSE
);
16834 if (result
!= ISC_R_SUCCESS
) {
16835 dns_zone_log(zone
, ISC_LOG_ERROR
,
16836 "sign_apex:del_sigs -> %s",
16837 dns_result_totext(result
));
16840 result
= add_sigs(db
, ver
, &zone
->origin
, dns_rdatatype_dnskey
,
16841 zonediff
->diff
, zone_keys
, nkeys
, zone
->mctx
,
16842 inception
, soaexpire
, check_ksk
,
16844 if (result
!= ISC_R_SUCCESS
) {
16845 dns_zone_log(zone
, ISC_LOG_ERROR
,
16846 "sign_apex:add_sigs -> %s",
16847 dns_result_totext(result
));
16852 result
= update_sigs(diff
, db
, ver
, zone_keys
, nkeys
, zone
,
16853 inception
, soaexpire
, now
, check_ksk
,
16854 keyset_kskonly
, zonediff
);
16856 if (result
!= ISC_R_SUCCESS
) {
16857 dns_zone_log(zone
, ISC_LOG_ERROR
,
16858 "sign_apex:update_sigs -> %s",
16859 dns_result_totext(result
));
16864 for (i
= 0; i
< nkeys
; i
++)
16865 dst_key_free(&zone_keys
[i
]);
16870 * Prevent the zone entering a inconsistent state where
16871 * NSEC only DNSKEYs are present with NSEC3 chains.
16872 * See update.c:check_dnssec()
16874 static isc_boolean_t
16875 dnskey_sane(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
16878 isc_result_t result
;
16879 dns_difftuple_t
*tuple
;
16880 isc_boolean_t nseconly
= ISC_FALSE
, nsec3
= ISC_FALSE
;
16881 dns_rdatatype_t privatetype
= dns_zone_getprivatetype(zone
);
16883 /* Scan the tuples for an NSEC-only DNSKEY */
16884 for (tuple
= ISC_LIST_HEAD(diff
->tuples
);
16886 tuple
= ISC_LIST_NEXT(tuple
, link
)) {
16888 if (tuple
->rdata
.type
!= dns_rdatatype_dnskey
||
16889 tuple
->op
!= DNS_DIFFOP_ADD
)
16892 alg
= tuple
->rdata
.data
[3];
16893 if (alg
== DST_ALG_RSAMD5
|| alg
== DST_ALG_RSASHA1
||
16894 alg
== DST_ALG_DSA
|| alg
== DST_ALG_ECC
) {
16895 nseconly
= ISC_TRUE
;
16900 /* Check existing DB for NSEC-only DNSKEY */
16902 result
= dns_nsec_nseconly(db
, ver
, &nseconly
);
16903 if (result
== ISC_R_NOTFOUND
)
16904 result
= ISC_R_SUCCESS
;
16908 /* Check existing DB for NSEC3 */
16910 CHECK(dns_nsec3_activex(db
, ver
, ISC_FALSE
,
16911 privatetype
, &nsec3
));
16913 /* Refuse to allow NSEC3 with NSEC-only keys */
16914 if (nseconly
&& nsec3
) {
16915 dns_zone_log(zone
, ISC_LOG_ERROR
,
16916 "NSEC only DNSKEYs and NSEC3 chains not allowed");
16923 return (ISC_FALSE
);
16926 static isc_result_t
16927 clean_nsec3param(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
16930 isc_result_t result
;
16931 dns_dbnode_t
*node
= NULL
;
16932 dns_rdataset_t rdataset
;
16934 dns_rdataset_init(&rdataset
);
16935 CHECK(dns_db_getoriginnode(db
, &node
));
16937 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_dnskey
,
16938 dns_rdatatype_none
, 0, &rdataset
, NULL
);
16939 if (dns_rdataset_isassociated(&rdataset
))
16940 dns_rdataset_disassociate(&rdataset
);
16941 if (result
!= ISC_R_NOTFOUND
)
16944 result
= dns_nsec3param_deletechains(db
, ver
, zone
, ISC_TRUE
, diff
);
16948 dns_db_detachnode(db
, &node
);
16953 * Given an RRSIG rdataset and an algorithm, determine whether there
16954 * are any signatures using that algorithm.
16956 static isc_boolean_t
16957 signed_with_alg(dns_rdataset_t
*rdataset
, dns_secalg_t alg
) {
16958 dns_rdata_t rdata
= DNS_RDATA_INIT
;
16959 dns_rdata_rrsig_t rrsig
;
16960 isc_result_t result
;
16962 REQUIRE(rdataset
== NULL
|| rdataset
->type
== dns_rdatatype_rrsig
);
16963 if (rdataset
== NULL
|| !dns_rdataset_isassociated(rdataset
)) {
16964 return (ISC_FALSE
);
16967 for (result
= dns_rdataset_first(rdataset
);
16968 result
== ISC_R_SUCCESS
;
16969 result
= dns_rdataset_next(rdataset
))
16971 dns_rdataset_current(rdataset
, &rdata
);
16972 result
= dns_rdata_tostruct(&rdata
, &rrsig
, NULL
);
16973 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
16974 dns_rdata_reset(&rdata
);
16975 if (rrsig
.algorithm
== alg
)
16979 return (ISC_FALSE
);
16982 static isc_result_t
16983 add_chains(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*ver
,
16986 dns_name_t
*origin
;
16987 isc_boolean_t build_nsec3
;
16988 isc_result_t result
;
16990 origin
= dns_db_origin(db
);
16991 CHECK(dns_private_chains(db
, ver
, zone
->privatetype
, NULL
,
16994 CHECK(dns_nsec3_addnsec3sx(db
, ver
, origin
, zone
->minimum
,
16995 ISC_FALSE
, zone
->privatetype
, diff
));
16996 CHECK(updatesecure(db
, ver
, origin
, zone
->minimum
, ISC_TRUE
, diff
));
17003 zone_rekey(dns_zone_t
*zone
) {
17004 isc_result_t result
;
17005 dns_db_t
*db
= NULL
;
17006 dns_dbnode_t
*node
= NULL
;
17007 dns_dbversion_t
*ver
= NULL
;
17008 dns_rdataset_t soaset
, soasigs
, keyset
, keysigs
;
17009 dns_dnsseckeylist_t dnskeys
, keys
, rmkeys
;
17010 dns_dnsseckey_t
*key
;
17011 dns_diff_t diff
, _sig_diff
;
17012 zonediff_t zonediff
;
17013 isc_boolean_t commit
= ISC_FALSE
, newactive
= ISC_FALSE
;
17014 isc_boolean_t newalg
= ISC_FALSE
;
17015 isc_boolean_t fullsign
;
17016 dns_ttl_t ttl
= 3600;
17020 isc_time_t timenow
;
17021 isc_interval_t ival
;
17024 REQUIRE(DNS_ZONE_VALID(zone
));
17026 ISC_LIST_INIT(dnskeys
);
17027 ISC_LIST_INIT(keys
);
17028 ISC_LIST_INIT(rmkeys
);
17029 dns_rdataset_init(&soaset
);
17030 dns_rdataset_init(&soasigs
);
17031 dns_rdataset_init(&keyset
);
17032 dns_rdataset_init(&keysigs
);
17033 dir
= dns_zone_getkeydirectory(zone
);
17035 dns_diff_init(mctx
, &diff
);
17036 dns_diff_init(mctx
, &_sig_diff
);
17037 zonediff_init(&zonediff
, &_sig_diff
);
17039 CHECK(dns_zone_getdb(zone
, &db
));
17040 CHECK(dns_db_newversion(db
, &ver
));
17041 CHECK(dns_db_getoriginnode(db
, &node
));
17043 TIME_NOW(&timenow
);
17044 now
= isc_time_seconds(&timenow
);
17046 dns_zone_log(zone
, ISC_LOG_INFO
, "reconfiguring zone keys");
17048 /* Get the SOA record's TTL */
17049 CHECK(dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_soa
,
17050 dns_rdatatype_none
, 0, &soaset
, &soasigs
));
17052 dns_rdataset_disassociate(&soaset
);
17054 /* Get the DNSKEY rdataset */
17055 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_dnskey
,
17056 dns_rdatatype_none
, 0, &keyset
, &keysigs
);
17057 if (result
== ISC_R_SUCCESS
) {
17059 CHECK(dns_dnssec_keylistfromrdataset(&zone
->origin
, dir
,
17061 &keysigs
, &soasigs
,
17062 ISC_FALSE
, ISC_FALSE
,
17064 } else if (result
!= ISC_R_NOTFOUND
)
17068 * True when called from "rndc sign". Indicates the zone should be
17069 * fully signed now.
17071 fullsign
= ISC_TF(DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_FULLSIGN
) != 0);
17073 result
= dns_dnssec_findmatchingkeys(&zone
->origin
, dir
, mctx
, &keys
);
17074 if (result
== ISC_R_SUCCESS
) {
17075 isc_boolean_t check_ksk
;
17076 check_ksk
= DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_UPDATECHECKKSK
);
17078 result
= dns_dnssec_updatekeys(&dnskeys
, &keys
, &rmkeys
,
17079 &zone
->origin
, ttl
, &diff
,
17080 ISC_TF(!check_ksk
),
17083 /* Keys couldn't be updated for some reason;
17084 * try again later. */
17085 if (result
!= ISC_R_SUCCESS
) {
17086 dns_zone_log(zone
, ISC_LOG_ERROR
, "zone_rekey:"
17087 "couldn't update zone keys: %s",
17088 isc_result_totext(result
));
17093 * See if any pre-existing keys have newly become active;
17094 * also, see if any new key is for a new algorithm, as in that
17095 * event, we need to sign the zone fully. (If there's a new
17096 * key, but it's for an already-existing algorithm, then
17097 * the zone signing can be handled incrementally.)
17099 for (key
= ISC_LIST_HEAD(dnskeys
);
17101 key
= ISC_LIST_NEXT(key
, link
)) {
17102 if (!key
->first_sign
)
17105 newactive
= ISC_TRUE
;
17107 if (!dns_rdataset_isassociated(&keysigs
)) {
17112 if (signed_with_alg(&keysigs
, dst_key_alg(key
->key
))) {
17114 * This isn't a new algorithm; clear
17115 * first_sign so we won't sign the
17116 * whole zone with this key later
17118 key
->first_sign
= ISC_FALSE
;
17125 if ((newactive
|| fullsign
|| !ISC_LIST_EMPTY(diff
.tuples
)) &&
17126 dnskey_sane(zone
, db
, ver
, &diff
)) {
17127 CHECK(dns_diff_apply(&diff
, db
, ver
));
17128 CHECK(clean_nsec3param(zone
, db
, ver
, &diff
));
17129 CHECK(add_signing_records(db
, zone
->privatetype
,
17131 ISC_TF(newalg
|| fullsign
)));
17132 CHECK(update_soa_serial(db
, ver
, &diff
, mctx
,
17133 zone
->updatemethod
));
17134 CHECK(add_chains(zone
, db
, ver
, &diff
));
17135 CHECK(sign_apex(zone
, db
, ver
, &diff
, &zonediff
));
17136 CHECK(zone_journal(zone
, zonediff
.diff
, NULL
,
17142 dns_db_closeversion(db
, &ver
, ISC_TRUE
);
17145 dns_difftuple_t
*tuple
;
17148 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
17150 zone_needdump(zone
, DNS_DUMP_DELAY
);
17152 zone_settimer(zone
, &timenow
);
17154 /* Remove any signatures from removed keys. */
17155 if (!ISC_LIST_EMPTY(rmkeys
)) {
17156 for (key
= ISC_LIST_HEAD(rmkeys
);
17158 key
= ISC_LIST_NEXT(key
, link
)) {
17159 result
= zone_signwithkey(zone
,
17160 dst_key_alg(key
->key
),
17161 dst_key_id(key
->key
),
17163 if (result
!= ISC_R_SUCCESS
) {
17164 dns_zone_log(zone
, ISC_LOG_ERROR
,
17165 "zone_signwithkey failed: %s",
17166 dns_result_totext(result
));
17173 * "rndc sign" was called, so we now sign the zone
17174 * with all active keys, whether they're new or not.
17176 for (key
= ISC_LIST_HEAD(dnskeys
);
17178 key
= ISC_LIST_NEXT(key
, link
)) {
17179 if (!key
->force_sign
&& !key
->hint_sign
)
17182 result
= zone_signwithkey(zone
,
17183 dst_key_alg(key
->key
),
17184 dst_key_id(key
->key
),
17186 if (result
!= ISC_R_SUCCESS
) {
17187 dns_zone_log(zone
, ISC_LOG_ERROR
,
17188 "zone_signwithkey failed: %s",
17189 dns_result_totext(result
));
17192 } else if (newalg
) {
17194 * We haven't been told to sign fully, but a new
17195 * algorithm was added to the DNSKEY. We sign
17196 * the full zone, but only with newly active
17199 for (key
= ISC_LIST_HEAD(dnskeys
);
17201 key
= ISC_LIST_NEXT(key
, link
)) {
17202 if (!key
->first_sign
)
17205 result
= zone_signwithkey(zone
,
17206 dst_key_alg(key
->key
),
17207 dst_key_id(key
->key
),
17209 if (result
!= ISC_R_SUCCESS
) {
17210 dns_zone_log(zone
, ISC_LOG_ERROR
,
17211 "zone_signwithkey failed: %s",
17212 dns_result_totext(result
));
17218 * Clear fullsign flag, if it was set, so we don't do
17219 * another full signing next time
17221 zone
->keyopts
&= ~DNS_ZONEKEY_FULLSIGN
;
17224 * Cause the zone to add/delete NSEC3 chains for the
17225 * deferred NSEC3PARAM changes.
17227 for (tuple
= ISC_LIST_HEAD(zonediff
.diff
->tuples
);
17229 tuple
= ISC_LIST_NEXT(tuple
, link
)) {
17230 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
17231 dns_rdata_t rdata
= DNS_RDATA_INIT
;
17232 dns_rdata_nsec3param_t nsec3param
;
17234 if (tuple
->rdata
.type
!= zone
->privatetype
||
17235 tuple
->op
!= DNS_DIFFOP_ADD
)
17238 if (!dns_nsec3param_fromprivate(&tuple
->rdata
, &rdata
,
17241 result
= dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
);
17242 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
17243 if (nsec3param
.flags
== 0)
17246 result
= zone_addnsec3chain(zone
, &nsec3param
);
17247 if (result
!= ISC_R_SUCCESS
) {
17248 dns_zone_log(zone
, ISC_LOG_ERROR
,
17249 "zone_addnsec3chain failed: %s",
17250 dns_result_totext(result
));
17255 * Activate any NSEC3 chain updates that may have
17256 * been scheduled before this rekey.
17258 if (fullsign
|| newalg
)
17259 resume_addnsec3chain(zone
);
17262 * Schedule the next resigning event
17264 set_resigntime(zone
);
17268 isc_time_settoepoch(&zone
->refreshkeytime
);
17271 * If we're doing key maintenance, set the key refresh timer to
17272 * the next scheduled key event or to 'dnssec-loadkeys-interval'
17273 * seconds in the future, whichever is sooner.
17275 if (DNS_ZONEKEY_OPTION(zone
, DNS_ZONEKEY_MAINTAIN
)) {
17276 isc_time_t timethen
;
17277 isc_stdtime_t then
;
17280 DNS_ZONE_TIME_ADD(&timenow
, zone
->refreshkeyinterval
,
17282 zone
->refreshkeytime
= timethen
;
17285 for (key
= ISC_LIST_HEAD(dnskeys
);
17287 key
= ISC_LIST_NEXT(key
, link
)) {
17289 result
= next_keyevent(key
->key
, &then
);
17290 if (result
!= ISC_R_SUCCESS
)
17293 DNS_ZONE_TIME_ADD(&timenow
, then
- now
, &timethen
);
17295 if (isc_time_compare(&timethen
,
17296 &zone
->refreshkeytime
) < 0) {
17297 zone
->refreshkeytime
= timethen
;
17302 zone_settimer(zone
, &timenow
);
17304 isc_time_formattimestamp(&zone
->refreshkeytime
, timebuf
, 80);
17305 dns_zone_log(zone
, ISC_LOG_INFO
, "next key event: %s", timebuf
);
17309 dns_diff_clear(&diff
);
17310 dns_diff_clear(&_sig_diff
);
17312 clear_keylist(&dnskeys
, mctx
);
17313 clear_keylist(&keys
, mctx
);
17314 clear_keylist(&rmkeys
, mctx
);
17317 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
17318 if (dns_rdataset_isassociated(&keyset
))
17319 dns_rdataset_disassociate(&keyset
);
17320 if (dns_rdataset_isassociated(&keysigs
))
17321 dns_rdataset_disassociate(&keysigs
);
17322 if (dns_rdataset_isassociated(&soasigs
))
17323 dns_rdataset_disassociate(&soasigs
);
17325 dns_db_detachnode(db
, &node
);
17327 dns_db_detach(&db
);
17329 INSIST(ver
== NULL
);
17334 * Something went wrong; try again in ten minutes or
17335 * after a key refresh interval, whichever is shorter.
17337 isc_interval_set(&ival
, ISC_MIN(zone
->refreshkeyinterval
, 600), 0);
17338 isc_time_nowplusinterval(&zone
->refreshkeytime
, &ival
);
17343 dns_zone_rekey(dns_zone_t
*zone
, isc_boolean_t fullsign
) {
17346 if (zone
->type
== dns_zone_master
&& zone
->task
!= NULL
) {
17350 zone
->keyopts
|= DNS_ZONEKEY_FULLSIGN
;
17353 zone
->refreshkeytime
= now
;
17354 zone_settimer(zone
, &now
);
17361 dns_zone_nscheck(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbversion_t
*version
,
17362 unsigned int *errors
)
17364 isc_result_t result
;
17365 dns_dbnode_t
*node
= NULL
;
17367 REQUIRE(DNS_ZONE_VALID(zone
));
17368 REQUIRE(errors
!= NULL
);
17370 result
= dns_db_getoriginnode(db
, &node
);
17371 if (result
!= ISC_R_SUCCESS
)
17373 result
= zone_count_ns_rr(zone
, db
, node
, version
, NULL
, errors
,
17375 dns_db_detachnode(db
, &node
);
17380 dns_zone_setadded(dns_zone_t
*zone
, isc_boolean_t added
) {
17381 REQUIRE(DNS_ZONE_VALID(zone
));
17384 zone
->added
= added
;
17389 dns_zone_getadded(dns_zone_t
*zone
) {
17390 REQUIRE(DNS_ZONE_VALID(zone
));
17391 return (zone
->added
);
17395 dns_zone_dlzpostload(dns_zone_t
*zone
, dns_db_t
*db
)
17397 isc_time_t loadtime
;
17398 isc_result_t result
;
17399 dns_zone_t
*secure
= NULL
;
17401 TIME_NOW(&loadtime
);
17404 * Lock hierarchy: zmgr, zone, raw.
17408 INSIST(zone
!= zone
->raw
);
17409 if (inline_secure(zone
))
17410 LOCK_ZONE(zone
->raw
);
17411 else if (inline_raw(zone
)) {
17412 secure
= zone
->secure
;
17413 TRYLOCK_ZONE(result
, secure
);
17414 if (result
!= ISC_R_SUCCESS
) {
17417 #if ISC_PLATFORM_USETHREADS
17418 isc_thread_yield();
17423 result
= zone_postload(zone
, db
, loadtime
, ISC_R_SUCCESS
);
17424 if (inline_secure(zone
))
17425 UNLOCK_ZONE(zone
->raw
);
17426 else if (secure
!= NULL
)
17427 UNLOCK_ZONE(secure
);
17433 dns_zone_setrefreshkeyinterval(dns_zone_t
*zone
, isc_uint32_t interval
) {
17434 REQUIRE(DNS_ZONE_VALID(zone
));
17436 return (ISC_R_RANGE
);
17437 /* Maximum value: 24 hours (3600 minutes) */
17438 if (interval
> (24 * 60))
17439 interval
= (24 * 60);
17440 /* Multiply by 60 for seconds */
17441 zone
->refreshkeyinterval
= interval
* 60;
17442 return (ISC_R_SUCCESS
);
17446 dns_zone_setrequestixfr(dns_zone_t
*zone
, isc_boolean_t flag
) {
17447 REQUIRE(DNS_ZONE_VALID(zone
));
17448 zone
->requestixfr
= flag
;
17452 dns_zone_getrequestixfr(dns_zone_t
*zone
) {
17453 REQUIRE(DNS_ZONE_VALID(zone
));
17454 return (zone
->requestixfr
);
17458 dns_zone_setserialupdatemethod(dns_zone_t
*zone
, dns_updatemethod_t method
) {
17459 REQUIRE(DNS_ZONE_VALID(zone
));
17460 zone
->updatemethod
= method
;
17464 dns_zone_getserialupdatemethod(dns_zone_t
*zone
) {
17465 REQUIRE(DNS_ZONE_VALID(zone
));
17466 return(zone
->updatemethod
);
17470 * Lock hierarchy: zmgr, zone, raw.
17473 dns_zone_link(dns_zone_t
*zone
, dns_zone_t
*raw
) {
17474 isc_result_t result
;
17475 dns_zonemgr_t
*zmgr
;
17477 REQUIRE(DNS_ZONE_VALID(zone
));
17478 REQUIRE(zone
->zmgr
!= NULL
);
17479 REQUIRE(zone
->task
!= NULL
);
17480 REQUIRE(zone
->loadtask
!= NULL
);
17481 REQUIRE(zone
->raw
== NULL
);
17483 REQUIRE(DNS_ZONE_VALID(raw
));
17484 REQUIRE(raw
->zmgr
== NULL
);
17485 REQUIRE(raw
->task
== NULL
);
17486 REQUIRE(raw
->loadtask
== NULL
);
17487 REQUIRE(raw
->secure
== NULL
);
17489 REQUIRE(zone
!= raw
);
17492 * Lock hierarchy: zmgr, zone, raw.
17495 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
17499 result
= isc_timer_create(zmgr
->timermgr
, isc_timertype_inactive
,
17500 NULL
, NULL
, zone
->task
, zone_timer
, raw
,
17502 if (result
!= ISC_R_SUCCESS
)
17506 * The timer "holds" a iref.
17509 INSIST(raw
->irefs
!= 0);
17512 /* dns_zone_attach(raw, &zone->raw); */
17513 isc_refcount_increment(&raw
->erefs
, NULL
);
17516 /* dns_zone_iattach(zone, &raw->secure); */
17517 zone_iattach(zone
, &raw
->secure
);
17519 isc_task_attach(zone
->task
, &raw
->task
);
17520 isc_task_attach(zone
->loadtask
, &raw
->loadtask
);
17522 ISC_LIST_APPEND(zmgr
->zones
, raw
, link
);
17529 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
17534 dns_zone_getraw(dns_zone_t
*zone
, dns_zone_t
**raw
) {
17535 REQUIRE(DNS_ZONE_VALID(zone
));
17536 REQUIRE(raw
!= NULL
&& *raw
== NULL
);
17539 INSIST(zone
!= zone
->raw
);
17540 if (zone
->raw
!= NULL
)
17541 dns_zone_attach(zone
->raw
, raw
);
17542 UNLOCK(&zone
->lock
);
17548 unsigned char data
[5];
17551 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
17554 keydone(isc_task_t
*task
, isc_event_t
*event
) {
17555 const char *me
= "keydone";
17556 isc_boolean_t commit
= ISC_FALSE
;
17557 isc_result_t result
;
17558 dns_rdata_t rdata
= DNS_RDATA_INIT
;
17559 dns_dbversion_t
*oldver
= NULL
, *newver
= NULL
;
17561 dns_db_t
*db
= NULL
;
17562 dns_dbnode_t
*node
= NULL
;
17563 dns_rdataset_t rdataset
;
17565 struct keydone
*keydone
= (struct keydone
*)event
;
17566 dns_update_log_t log
= { update_log_cb
, NULL
};
17567 isc_boolean_t clear_pending
= ISC_FALSE
;
17571 zone
= event
->ev_arg
;
17572 INSIST(DNS_ZONE_VALID(zone
));
17576 dns_rdataset_init(&rdataset
);
17577 dns_diff_init(zone
->mctx
, &diff
);
17579 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
17580 if (zone
->db
!= NULL
) {
17581 dns_db_attach(zone
->db
, &db
);
17582 dns_db_currentversion(db
, &oldver
);
17583 result
= dns_db_newversion(db
, &newver
);
17584 if (result
!= ISC_R_SUCCESS
) {
17585 dns_zone_log(zone
, ISC_LOG_ERROR
,
17586 "keydone:dns_db_newversion -> %s",
17587 dns_result_totext(result
));
17591 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
17595 result
= dns_db_getoriginnode(db
, &node
);
17596 if (result
!= ISC_R_SUCCESS
)
17599 result
= dns_db_findrdataset(db
, node
, newver
, zone
->privatetype
,
17600 dns_rdatatype_none
, 0, &rdataset
, NULL
);
17601 if (result
== ISC_R_NOTFOUND
) {
17602 INSIST(!dns_rdataset_isassociated(&rdataset
));
17605 if (result
!= ISC_R_SUCCESS
) {
17606 INSIST(!dns_rdataset_isassociated(&rdataset
));
17610 for (result
= dns_rdataset_first(&rdataset
);
17611 result
== ISC_R_SUCCESS
;
17612 result
= dns_rdataset_next(&rdataset
)) {
17613 isc_boolean_t found
= ISC_FALSE
;
17615 dns_rdataset_current(&rdataset
, &rdata
);
17617 if (keydone
->all
) {
17618 if (rdata
.length
== 5 && rdata
.data
[0] != 0 &&
17619 rdata
.data
[3] == 0 && rdata
.data
[4] == 1)
17621 else if (rdata
.data
[0] == 0 &&
17622 (rdata
.data
[2] & PENDINGFLAGS
) != 0) {
17624 clear_pending
= ISC_TRUE
;
17626 } else if (rdata
.length
== 5 &&
17627 memcmp(rdata
.data
, keydone
->data
, 5) == 0)
17631 CHECK(update_one_rr(db
, newver
, &diff
, DNS_DIFFOP_DEL
,
17632 &zone
->origin
, rdataset
.ttl
,
17634 dns_rdata_reset(&rdata
);
17637 if (!ISC_LIST_EMPTY(diff
.tuples
)) {
17638 /* Write changes to journal file. */
17639 CHECK(update_soa_serial(db
, newver
, &diff
, zone
->mctx
,
17640 zone
->updatemethod
));
17642 result
= dns_update_signatures(&log
, zone
, db
,
17643 oldver
, newver
, &diff
,
17644 zone
->sigvalidityinterval
);
17645 if (!clear_pending
)
17648 CHECK(zone_journal(zone
, &diff
, NULL
, "keydone"));
17652 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
);
17653 zone_needdump(zone
, 30);
17658 if (dns_rdataset_isassociated(&rdataset
))
17659 dns_rdataset_disassociate(&rdataset
);
17662 dns_db_detachnode(db
, &node
);
17663 if (oldver
!= NULL
)
17664 dns_db_closeversion(db
, &oldver
, ISC_FALSE
);
17665 if (newver
!= NULL
)
17666 dns_db_closeversion(db
, &newver
, commit
);
17667 dns_db_detach(&db
);
17669 dns_diff_clear(&diff
);
17670 isc_event_free(&event
);
17671 dns_zone_idetach(&zone
);
17673 INSIST(oldver
== NULL
);
17674 INSIST(newver
== NULL
);
17678 dns_zone_keydone(dns_zone_t
*zone
, const char *keystr
) {
17679 isc_result_t result
= ISC_R_SUCCESS
;
17682 dns_zone_t
*dummy
= NULL
;
17683 struct keydone
*kd
;
17685 REQUIRE(DNS_ZONE_VALID(zone
));
17689 e
= isc_event_allocate(zone
->mctx
, zone
, DNS_EVENT_KEYDONE
, keydone
,
17690 zone
, sizeof(struct keydone
));
17692 result
= ISC_R_NOMEMORY
;
17696 kd
= (struct keydone
*) e
;
17697 if (strcasecmp(keystr
, "all") == 0)
17698 kd
->all
= ISC_TRUE
;
17700 isc_textregion_t r
;
17702 dns_keytag_t keyid
;
17706 kd
->all
= ISC_FALSE
;
17708 n
= sscanf(keystr
, "%hd/", &keyid
);
17710 CHECK(ISC_R_FAILURE
);
17712 algstr
= strchr(keystr
, '/');
17713 if (algstr
!= NULL
)
17716 CHECK(ISC_R_FAILURE
);
17718 n
= sscanf(algstr
, "%hhd", &alg
);
17720 DE_CONST(algstr
, r
.base
);
17721 r
.length
= strlen(algstr
);
17722 CHECK(dns_secalg_fromtext(&alg
, &r
));
17725 /* construct a private-type rdata */
17726 isc_buffer_init(&b
, kd
->data
, sizeof(kd
->data
));
17727 isc_buffer_putuint8(&b
, alg
);
17728 isc_buffer_putuint8(&b
, (keyid
& 0xff00) >> 8);
17729 isc_buffer_putuint8(&b
, (keyid
& 0xff));
17730 isc_buffer_putuint8(&b
, 0);
17731 isc_buffer_putuint8(&b
, 1);
17734 zone_iattach(zone
, &dummy
);
17735 isc_task_send(zone
->task
, &e
);
17739 isc_event_free(&e
);
17745 setnsec3param(isc_task_t
*task
, isc_event_t
*event
) {
17746 const char *me
= "setnsec3param";
17747 isc_boolean_t commit
= ISC_FALSE
;
17748 isc_result_t result
;
17749 dns_dbversion_t
*oldver
= NULL
, *newver
= NULL
;
17751 dns_db_t
*db
= NULL
;
17752 dns_dbnode_t
*node
= NULL
;
17753 dns_rdataset_t prdataset
, nrdataset
;
17755 struct np3event
*npe
= (struct np3event
*)event
;
17757 dns_update_log_t log
= { update_log_cb
, NULL
};
17759 isc_boolean_t nseconly
;
17760 isc_boolean_t exists
= ISC_FALSE
;
17764 zone
= event
->ev_arg
;
17765 INSIST(DNS_ZONE_VALID(zone
));
17771 dns_rdataset_init(&prdataset
);
17772 dns_rdataset_init(&nrdataset
);
17773 dns_diff_init(zone
->mctx
, &diff
);
17775 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
17776 if (zone
->db
!= NULL
) {
17777 dns_db_attach(zone
->db
, &db
);
17778 dns_db_currentversion(db
, &oldver
);
17779 result
= dns_db_newversion(db
, &newver
);
17780 if (result
!= ISC_R_SUCCESS
) {
17781 dns_zone_log(zone
, ISC_LOG_ERROR
,
17782 "setnsec3param:dns_db_newversion -> %s",
17783 dns_result_totext(result
));
17787 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
17791 CHECK(dns_db_getoriginnode(db
, &node
));
17794 * Does a private-type record already exist for this chain?
17796 result
= dns_db_findrdataset(db
, node
, newver
, zone
->privatetype
,
17797 dns_rdatatype_none
, 0, &prdataset
, NULL
);
17798 if (result
== ISC_R_SUCCESS
) {
17799 for (result
= dns_rdataset_first(&prdataset
);
17800 result
== ISC_R_SUCCESS
;
17801 result
= dns_rdataset_next(&prdataset
)) {
17802 dns_rdata_init(&rdata
);
17803 dns_rdataset_current(&prdataset
, &rdata
);
17805 if (np
->length
== rdata
.length
&&
17806 memcmp(rdata
.data
, np
->data
, np
->length
) == 0) {
17811 } else if (result
!= ISC_R_NOTFOUND
) {
17812 INSIST(!dns_rdataset_isassociated(&prdataset
));
17817 * Does the chain already exist?
17819 result
= dns_db_findrdataset(db
, node
, newver
,
17820 dns_rdatatype_nsec3param
,
17821 dns_rdatatype_none
, 0, &nrdataset
, NULL
);
17822 if (result
== ISC_R_SUCCESS
) {
17823 for (result
= dns_rdataset_first(&nrdataset
);
17824 result
== ISC_R_SUCCESS
;
17825 result
= dns_rdataset_next(&nrdataset
)) {
17826 dns_rdata_init(&rdata
);
17827 dns_rdataset_current(&nrdataset
, &rdata
);
17829 if (np
->length
== (rdata
.length
+ 1) &&
17830 memcmp(rdata
.data
, np
->data
+ 1,
17831 np
->length
- 1) == 0)
17837 } else if (result
!= ISC_R_NOTFOUND
) {
17838 INSIST(!dns_rdataset_isassociated(&nrdataset
));
17844 * We need to remove any existing NSEC3 chains.
17846 if (!exists
&& np
->replace
&& (np
->length
!= 0 || np
->nsec
))
17847 CHECK(dns_nsec3param_deletechains(db
, newver
, zone
,
17848 !np
->nsec
, &diff
));
17850 if (!exists
&& np
->length
!= 0) {
17852 * We're creating an NSEC3 chain.
17854 * If the zone is not currently capable of supporting
17855 * an NSEC3 chain, add the INITIAL flag, so these
17856 * parameters can be used later when NSEC3 becomes
17859 dns_rdata_init(&rdata
);
17861 np
->data
[2] |= DNS_NSEC3FLAG_CREATE
;
17862 result
= dns_nsec_nseconly(db
, newver
, &nseconly
);
17863 if (result
== ISC_R_NOTFOUND
|| nseconly
)
17864 np
->data
[2] |= DNS_NSEC3FLAG_INITIAL
;
17866 rdata
.length
= np
->length
;
17867 rdata
.data
= np
->data
;
17868 rdata
.type
= zone
->privatetype
;
17869 rdata
.rdclass
= zone
->rdclass
;
17870 CHECK(update_one_rr(db
, newver
, &diff
, DNS_DIFFOP_ADD
,
17871 &zone
->origin
, 0, &rdata
));
17874 if (!ISC_LIST_EMPTY(diff
.tuples
)) {
17875 /* Write changes to journal file. */
17876 CHECK(update_soa_serial(db
, newver
, &diff
, zone
->mctx
,
17877 zone
->updatemethod
));
17878 result
= dns_update_signatures(&log
, zone
, db
,
17879 oldver
, newver
, &diff
,
17880 zone
->sigvalidityinterval
);
17881 if (result
!= ISC_R_NOTFOUND
)
17883 CHECK(zone_journal(zone
, &diff
, NULL
, "setnsec3param"));
17887 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
);
17888 zone_needdump(zone
, 30);
17893 if (dns_rdataset_isassociated(&prdataset
))
17894 dns_rdataset_disassociate(&prdataset
);
17895 if (dns_rdataset_isassociated(&nrdataset
))
17896 dns_rdataset_disassociate(&nrdataset
);
17898 dns_db_detachnode(db
, &node
);
17899 if (oldver
!= NULL
)
17900 dns_db_closeversion(db
, &oldver
, ISC_FALSE
);
17901 if (newver
!= NULL
)
17902 dns_db_closeversion(db
, &newver
, commit
);
17904 dns_db_detach(&db
);
17906 resume_addnsec3chain(zone
);
17907 dns_diff_clear(&diff
);
17908 isc_event_free(&event
);
17909 dns_zone_idetach(&zone
);
17911 INSIST(oldver
== NULL
);
17912 INSIST(newver
== NULL
);
17916 dns_zone_setnsec3param(dns_zone_t
*zone
, isc_uint8_t hash
, isc_uint8_t flags
,
17917 isc_uint16_t iter
, isc_uint8_t saltlen
,
17918 unsigned char *salt
, isc_boolean_t replace
)
17920 isc_result_t result
= ISC_R_SUCCESS
;
17921 dns_rdata_nsec3param_t param
;
17922 dns_rdata_t nrdata
= DNS_RDATA_INIT
;
17923 dns_rdata_t prdata
= DNS_RDATA_INIT
;
17924 unsigned char nbuf
[DNS_NSEC3PARAM_BUFFERSIZE
];
17925 struct np3event
*npe
;
17927 dns_zone_t
*dummy
= NULL
;
17931 REQUIRE(DNS_ZONE_VALID(zone
));
17932 REQUIRE(salt
!= NULL
);
17936 e
= isc_event_allocate(zone
->mctx
, zone
, DNS_EVENT_SETNSEC3PARAM
,
17937 setnsec3param
, zone
, sizeof(struct np3event
));
17939 result
= ISC_R_NOMEMORY
;
17943 npe
= (struct np3event
*) e
;
17946 np
->replace
= replace
;
17949 np
->nsec
= ISC_TRUE
;
17951 param
.common
.rdclass
= zone
->rdclass
;
17952 param
.common
.rdtype
= dns_rdatatype_nsec3param
;
17953 ISC_LINK_INIT(¶m
.common
, link
);
17956 param
.flags
= flags
;
17957 param
.iterations
= iter
;
17958 param
.salt_length
= saltlen
;
17960 isc_buffer_init(&b
, nbuf
, sizeof(nbuf
));
17961 CHECK(dns_rdata_fromstruct(&nrdata
, zone
->rdclass
,
17962 dns_rdatatype_nsec3param
,
17964 dns_nsec3param_toprivate(&nrdata
, &prdata
, zone
->privatetype
,
17965 np
->data
, sizeof(np
->data
));
17966 np
->length
= prdata
.length
;
17969 zone_iattach(zone
, &dummy
);
17970 isc_task_send(zone
->task
, &e
);
17974 isc_event_free(&e
);
17980 dns_zone_getloadtime(dns_zone_t
*zone
, isc_time_t
*loadtime
) {
17981 REQUIRE(DNS_ZONE_VALID(zone
));
17982 REQUIRE(loadtime
!= NULL
);
17985 *loadtime
= zone
->loadtime
;
17987 return (ISC_R_SUCCESS
);
17991 dns_zone_getexpiretime(dns_zone_t
*zone
, isc_time_t
*expiretime
) {
17992 REQUIRE(DNS_ZONE_VALID(zone
));
17993 REQUIRE(expiretime
!= NULL
);
17996 *expiretime
= zone
->expiretime
;
17998 return (ISC_R_SUCCESS
);
18002 dns_zone_getrefreshtime(dns_zone_t
*zone
, isc_time_t
*refreshtime
) {
18003 REQUIRE(DNS_ZONE_VALID(zone
));
18004 REQUIRE(refreshtime
!= NULL
);
18007 *refreshtime
= zone
->refreshtime
;
18009 return (ISC_R_SUCCESS
);
18013 dns_zone_getrefreshkeytime(dns_zone_t
*zone
, isc_time_t
*refreshkeytime
) {
18014 REQUIRE(DNS_ZONE_VALID(zone
));
18015 REQUIRE(refreshkeytime
!= NULL
);
18018 *refreshkeytime
= zone
->refreshkeytime
;
18020 return (ISC_R_SUCCESS
);
18024 dns_zone_getincludes(dns_zone_t
*zone
, char ***includesp
) {
18025 dns_include_t
*include
;
18026 char **array
= NULL
;
18027 unsigned int n
= 0;
18029 REQUIRE(DNS_ZONE_VALID(zone
));
18030 REQUIRE(includesp
!= NULL
&& *includesp
== NULL
);
18033 if (zone
->nincludes
== 0)
18036 array
= isc_mem_allocate(zone
->mctx
, sizeof(char *) * zone
->nincludes
);
18039 for (include
= ISC_LIST_HEAD(zone
->includes
);
18041 include
= ISC_LIST_NEXT(include
, link
)) {
18042 INSIST(n
< zone
->nincludes
);
18043 array
[n
++] = isc_mem_strdup(zone
->mctx
, include
->name
);
18045 INSIST(n
== zone
->nincludes
);
18046 *includesp
= array
;
18054 dns_zone_setstatlevel(dns_zone_t
*zone
, dns_zonestat_level_t level
) {
18055 REQUIRE(DNS_ZONE_VALID(zone
));
18057 zone
->statlevel
= level
;
18060 dns_zonestat_level_t
18061 dns_zone_getstatlevel(dns_zone_t
*zone
) {
18062 REQUIRE(DNS_ZONE_VALID(zone
));
18064 return (zone
->statlevel
);