2 * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
25 #include <isc/mutex.h>
27 #include <isc/print.h>
28 #include <isc/random.h>
29 #include <isc/ratelimiter.h>
30 #include <isc/refcount.h>
31 #include <isc/rwlock.h>
32 #include <isc/serial.h>
33 #include <isc/stats.h>
34 #include <isc/stdtime.h>
35 #include <isc/strerror.h>
36 #include <isc/string.h>
37 #include <isc/taskpool.h>
38 #include <isc/thread.h>
39 #include <isc/timer.h>
42 #include <dns/acache.h>
45 #include <dns/callbacks.h>
47 #include <dns/dbiterator.h>
48 #include <dns/dnssec.h>
50 #include <dns/events.h>
51 #include <dns/journal.h>
52 #include <dns/keydata.h>
53 #include <dns/keytable.h>
54 #include <dns/keyvalues.h>
56 #include <dns/master.h>
57 #include <dns/masterdump.h>
58 #include <dns/message.h>
61 #include <dns/nsec3.h>
63 #include <dns/private.h>
65 #include <dns/rcode.h>
66 #include <dns/rdata.h>
67 #include <dns/rdataclass.h>
68 #include <dns/rdatalist.h>
69 #include <dns/rdataset.h>
70 #include <dns/rdatasetiter.h>
71 #include <dns/rdatastruct.h>
72 #include <dns/rdatatype.h>
73 #include <dns/request.h>
74 #include <dns/resolver.h>
75 #include <dns/result.h>
76 #include <dns/rriterator.h>
79 #include <dns/stats.h>
82 #include <dns/update.h>
83 #include <dns/xfrin.h>
89 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
90 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
92 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
93 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
95 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
96 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
98 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
99 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
101 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
102 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
104 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
105 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
107 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
108 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
111 * Ensure 'a' is at least 'min' but not more than 'max'.
113 #define RANGE(a, min, max) \
114 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
116 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
121 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
122 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
123 #define ALG(x) dst_key_alg(x)
128 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
129 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
130 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
131 #define RESIGN_DELAY 3600 /*%< 1 hour */
133 #ifndef DNS_MAX_EXPIRE
134 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
137 #ifndef DNS_DUMP_DELAY
138 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
141 typedef struct dns_notify dns_notify_t;
142 typedef struct dns_stub dns_stub_t;
143 typedef struct dns_load dns_load_t;
144 typedef struct dns_forward dns_forward_t;
145 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
146 typedef struct dns_io dns_io_t;
147 typedef ISC_LIST(dns_io_t) dns_iolist_t;
148 typedef struct dns_signing dns_signing_t;
149 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
150 typedef struct dns_nsec3chain dns_nsec3chain_t;
151 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
152 typedef struct dns_keyfetch dns_keyfetch_t;
153 typedef struct dns_asyncload dns_asyncload_t;
155 #define DNS_ZONE_CHECKLOCK
156 #ifdef DNS_ZONE_CHECKLOCK
157 #define LOCK_ZONE(z) \
158 do { LOCK(&(z)->lock); \
159 INSIST((z)->locked == ISC_FALSE); \
160 (z)->locked = ISC_TRUE; \
162 #define UNLOCK_ZONE(z) \
163 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
164 #define LOCKED_ZONE(z) ((z)->locked)
165 #define TRYLOCK_ZONE(result, z) \
167 result = isc_mutex_trylock(&(z)->lock); \
168 if (result == ISC_R_SUCCESS) { \
169 INSIST((z)->locked == ISC_FALSE); \
170 (z)->locked = ISC_TRUE; \
174 #define LOCK_ZONE(z) LOCK(&(z)->lock)
175 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
176 #define LOCKED_ZONE(z) ISC_TRUE
177 #define TRYLOCK_ZONE(result, z) \
178 do { result = isc_mutex_trylock(&(z)->lock); } while (0)
181 #ifdef ISC_RWLOCK_USEATOMIC
182 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
183 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
184 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
185 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
187 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
188 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
189 #define ZONEDB_LOCK(l, t) LOCK(l)
190 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
197 #ifdef DNS_ZONE_CHECKLOCK
198 isc_boolean_t locked;
201 isc_refcount_t erefs;
203 #ifdef ISC_RWLOCK_USEATOMIC
208 dns_db_t *db; /* Locked by dblock */
212 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
217 dns_masterformat_t masterformat;
219 isc_int32_t journalsize;
220 dns_rdataclass_t rdclass;
223 unsigned int options;
224 unsigned int db_argc;
226 isc_time_t expiretime;
227 isc_time_t refreshtime;
230 isc_time_t notifytime;
231 isc_time_t resigntime;
232 isc_time_t keywarntime;
233 isc_time_t signingtime;
234 isc_time_t nsec3chaintime;
235 isc_time_t refreshkeytime;
236 isc_uint32_t refreshkeyinterval;
237 isc_uint32_t refreshkeycount;
238 isc_uint32_t refresh;
241 isc_uint32_t minimum;
242 isc_stdtime_t key_expiry;
243 isc_stdtime_t log_key_expired_timer;
246 isc_uint32_t maxrefresh;
247 isc_uint32_t minrefresh;
248 isc_uint32_t maxretry;
249 isc_uint32_t minretry;
251 isc_sockaddr_t *masters;
252 dns_name_t **masterkeynames;
253 isc_boolean_t *mastersok;
254 unsigned int masterscnt;
255 unsigned int curmaster;
256 isc_sockaddr_t masteraddr;
257 dns_notifytype_t notifytype;
258 isc_sockaddr_t *notify;
259 dns_name_t **notifykeynames;
260 unsigned int notifycnt;
261 isc_sockaddr_t notifyfrom;
263 isc_task_t *loadtask;
264 isc_sockaddr_t notifysrc4;
265 isc_sockaddr_t notifysrc6;
266 isc_sockaddr_t xfrsource4;
267 isc_sockaddr_t xfrsource6;
268 isc_sockaddr_t altxfrsource4;
269 isc_sockaddr_t altxfrsource6;
270 isc_sockaddr_t sourceaddr;
271 dns_xfrin_ctx_t *xfr; /* task locked */
272 dns_tsigkey_t *tsigkey; /* key used for xfr */
273 /* Access Control Lists */
274 dns_acl_t *update_acl;
275 dns_acl_t *forward_acl;
276 dns_acl_t *notify_acl;
277 dns_acl_t *query_acl;
278 dns_acl_t *queryon_acl;
280 isc_boolean_t update_disabled;
281 isc_boolean_t zero_no_soa_ttl;
282 dns_severity_t check_names;
283 ISC_LIST(dns_notify_t) notifies;
284 dns_request_t *request;
289 isc_uint32_t maxxfrin;
290 isc_uint32_t maxxfrout;
292 isc_uint32_t idleout;
293 isc_event_t ctlevent;
294 dns_ssutable_t *ssutable;
295 isc_uint32_t sigvalidityinterval;
296 isc_uint32_t sigresigninginterval;
298 dns_acache_t *acache;
299 dns_checkmxfunc_t checkmx;
300 dns_checksrvfunc_t checksrv;
301 dns_checknsfunc_t checkns;
303 * Zones in certain states such as "waiting for zone transfer"
304 * or "zone transfer in progress" are kept on per-state linked lists
305 * in the zone manager using the 'statelink' field. The 'statelist'
306 * field points at the list the zone is currently on. It the zone
307 * is not on any such list, statelist is NULL.
309 ISC_LINK(dns_zone_t) statelink;
310 dns_zonelist_t *statelist;
312 * Statistics counters about zone management.
316 * Optional per-zone statistics counters. Counted outside of this
319 dns_zonestat_level_t statlevel;
320 isc_boolean_t requeststats_on;
321 isc_stats_t *requeststats;
322 dns_stats_t *rcvquerystats;
323 isc_uint32_t notifydelay;
324 dns_isselffunc_t isself;
333 * Serial number for deferred journal compaction.
335 isc_uint32_t compact_serial;
337 * Keys that are signing the zone for the first time.
339 dns_signinglist_t signing;
340 dns_nsec3chainlist_t nsec3chain;
342 * Signing / re-signing quantum stopping parameters.
344 isc_uint32_t signatures;
346 dns_rdatatype_t privatetype;
349 * Autosigning/key-maintenance options
351 isc_uint32_t keyopts;
354 * True if added by "rndc addzone"
359 * whether this is a response policy zone
361 isc_boolean_t is_rpz;
364 * Serial number update method.
366 dns_updatemethod_t updatemethod;
369 * whether ixfr is requested
371 isc_boolean_t requestixfr;
374 * Outstanding forwarded UPDATE requests.
376 dns_forwardlist_t forwards;
381 isc_boolean_t sourceserialset;
382 isc_uint32_t sourceserial;
390 * Inline zone signing state.
393 isc_eventlist_t rss_events;
394 dns_dbversion_t *rss_newver;
395 dns_dbversion_t *rss_oldver;
398 isc_event_t *rss_event;
399 dns_update_state_t *rss_state;
404 isc_boolean_t offline;
407 #define zonediff_init(z, d) \
409 zonediff_t *_z = (z); \
411 (_z)->offline = ISC_FALSE; \
414 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
415 #define DNS_ZONE_SETFLAG(z,f) do { \
416 INSIST(LOCKED_ZONE(z)); \
419 #define DNS_ZONE_CLRFLAG(z,f) do { \
420 INSIST(LOCKED_ZONE(z)); \
421 (z)->flags &= ~(f); \
423 /* XXX MPA these may need to go back into zone.h */
424 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
425 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
426 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
427 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
428 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
429 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
430 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
431 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
432 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
433 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
435 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
437 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
439 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
440 * zone with no masters
442 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
443 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
444 * from SOA (if not set, we
446 * default timer values) */
447 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
448 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
449 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
450 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
451 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
452 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
453 #define DNS_ZONEFLG_FLUSH 0x00200000U
454 #define DNS_ZONEFLG_NOEDNS 0x00400000U
455 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
456 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
457 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
458 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
459 #define DNS_ZONEFLG_THAW 0x08000000U
460 #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
461 #define DNS_ZONEFLG_NODELAY 0x20000000U
462 #define DNS_ZONEFLG_SENDSECURE 0x40000000U
463 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
464 * due to the zone just
465 * being loaded for the
468 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
469 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
471 /* Flags for zone_load() */
472 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
473 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
476 #define UNREACH_CHACHE_SIZE 10U
477 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
480 do { result = (op); \
481 if (result != ISC_R_SUCCESS) goto failure; \
484 struct dns_unreachable {
485 isc_sockaddr_t remote;
486 isc_sockaddr_t local;
495 int refs; /* Locked by rwlock */
496 isc_taskmgr_t * taskmgr;
497 isc_timermgr_t * timermgr;
498 isc_socketmgr_t * socketmgr;
499 isc_taskpool_t * zonetasks;
500 isc_taskpool_t * loadtasks;
502 isc_pool_t * mctxpool;
503 isc_ratelimiter_t * notifyrl;
504 isc_ratelimiter_t * refreshrl;
505 isc_ratelimiter_t * startupnotifyrl;
506 isc_ratelimiter_t * startuprefreshrl;
511 /* Locked by rwlock. */
512 dns_zonelist_t zones;
513 dns_zonelist_t waiting_for_xfrin;
514 dns_zonelist_t xfrin_in_progress;
516 /* Configuration data. */
517 isc_uint32_t transfersin;
518 isc_uint32_t transfersperns;
519 unsigned int notifyrate;
520 unsigned int startupnotifyrate;
521 unsigned int serialqueryrate;
522 unsigned int startupserialqueryrate;
524 /* Locked by iolock */
525 isc_uint32_t iolimit;
526 isc_uint32_t ioactive;
530 /* Locked by urlock. */
532 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
544 dns_request_t *request;
548 ISC_LINK(dns_notify_t) link;
552 #define DNS_NOTIFY_NOSOA 0x0001U
553 #define DNS_NOTIFY_STARTUP 0x0002U
556 * dns_stub holds state while performing a 'stub' transfer.
557 * 'db' is the zone's 'db' or a new one if this is the initial
566 dns_dbversion_t *version;
578 dns_rdatacallbacks_t callbacks;
582 * Hold forward state.
588 isc_buffer_t *msgbuf;
589 dns_request_t *request;
592 dns_updatecallback_t callback;
594 unsigned int options;
595 ISC_LINK(dns_forward_t) link;
599 * Hold IO request state.
606 ISC_LINK(dns_io_t) link;
611 * Hold state for when we are signing a zone with a new
612 * DNSKEY as result of an update.
617 dns_dbiterator_t *dbiterator;
618 dns_secalg_t algorithm;
620 isc_boolean_t delete;
622 ISC_LINK(dns_signing_t) link;
625 struct dns_nsec3chain {
628 dns_dbiterator_t *dbiterator;
629 dns_rdata_nsec3param_t nsec3param;
630 unsigned char salt[255];
632 isc_boolean_t seen_nsec;
633 isc_boolean_t delete_nsec;
634 isc_boolean_t save_delete_nsec;
635 ISC_LINK(dns_nsec3chain_t) link;
638 * 'dbiterator' contains a iterator for the database. If we are creating
639 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
640 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
643 * 'nsec3param' contains the parameters of the NSEC3 chain being created
646 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
648 * 'seen_nsec' will be set to true if, while iterating the zone to create a
649 * NSEC3 chain, a NSEC record is seen.
651 * 'delete_nsec' will be set to true if, at the completion of the creation
652 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
653 * are in the process of deleting the NSEC chain.
655 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
656 * so it can be recovered in the event of a error.
659 struct dns_keyfetch {
660 dns_fixedname_t name;
661 dns_rdataset_t keydataset;
662 dns_rdataset_t dnskeyset;
663 dns_rdataset_t dnskeysigset;
670 * Hold state for an asynchronous load
672 struct dns_asyncload {
674 dns_zt_zoneloaded_t loaded;
679 #define DAY (24*HOUR)
680 #define MONTH (30*DAY)
683 * These can be overridden by the -T mkeytimers option on the command
684 * line, so that we can test with shorter periods than specified in
687 unsigned int dns_zone_mkey_hour = HOUR;
688 unsigned int dns_zone_mkey_day = DAY;
689 unsigned int dns_zone_mkey_month = MONTH;
691 #define SEND_BUFFER_SIZE 2048
693 static void zone_settimer(dns_zone_t *, isc_time_t *);
694 static void cancel_refresh(dns_zone_t *);
695 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
696 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
697 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
698 ISC_FORMAT_PRINTF(3, 4);
699 static void queue_xfrin(dns_zone_t *zone);
700 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
701 dns_diff_t *diff, dns_diffop_t op,
702 dns_name_t *name, dns_ttl_t ttl,
704 static void zone_unload(dns_zone_t *zone);
705 static void zone_expire(dns_zone_t *zone);
706 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
707 static void zone_idetach(dns_zone_t **zonep);
708 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
710 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
711 static inline void zone_detachdb(dns_zone_t *zone);
712 static isc_result_t default_journal(dns_zone_t *zone);
713 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
714 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
715 isc_time_t loadtime, isc_result_t result);
716 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
717 static void zone_shutdown(isc_task_t *, isc_event_t *);
718 static void zone_loaddone(void *arg, isc_result_t result);
719 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
720 isc_time_t loadtime);
721 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
722 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
723 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
724 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
725 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
726 isc_uint32_t serial);
729 /* ondestroy example */
730 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
733 static void refresh_callback(isc_task_t *, isc_event_t *);
734 static void stub_callback(isc_task_t *, isc_event_t *);
735 static void queue_soa_query(dns_zone_t *zone);
736 static void soa_query(isc_task_t *, isc_event_t *);
737 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
739 static int message_count(dns_message_t *msg, dns_section_t section,
740 dns_rdatatype_t type);
741 static void notify_cancel(dns_zone_t *zone);
742 static void notify_find_address(dns_notify_t *notify);
743 static void notify_send(dns_notify_t *notify);
744 static isc_result_t notify_createmessage(dns_zone_t *zone,
746 dns_message_t **messagep);
747 static void notify_done(isc_task_t *task, isc_event_t *event);
748 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
749 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
750 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
751 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
753 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
754 static void zonemgr_free(dns_zonemgr_t *zmgr);
755 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
756 isc_task_t *task, isc_taskaction_t action,
757 void *arg, dns_io_t **iop);
758 static void zonemgr_putio(dns_io_t **iop);
759 static void zonemgr_cancelio(dns_io_t *io);
762 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
763 unsigned int *soacount, isc_uint32_t *serial,
764 isc_uint32_t *refresh, isc_uint32_t *retry,
765 isc_uint32_t *expire, isc_uint32_t *minimum,
766 unsigned int *errors);
768 static void zone_freedbargs(dns_zone_t *zone);
769 static void forward_callback(isc_task_t *task, isc_event_t *event);
770 static void zone_saveunique(dns_zone_t *zone, const char *path,
771 const char *templat);
772 static void zone_maintenance(dns_zone_t *zone);
773 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
774 static void dump_done(void *arg, isc_result_t result);
775 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
776 isc_uint16_t keyid, isc_boolean_t delete);
777 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
778 dns_dbnode_t *node, dns_name_t *name,
780 static void zone_rekey(dns_zone_t *zone);
781 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
782 static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
785 #define ENTER zone_debuglog(zone, me, 1, "enter")
787 static const unsigned int dbargc_default = 1;
788 static const char *dbargv_default[] = { "rbt" };
790 #define DNS_ZONE_JITTER_ADD(a, b, c) \
794 _j = isc_random_jitter((b), (b)/4); \
795 isc_interval_set(&_i, _j, 0); \
796 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
797 dns_zone_log(zone, ISC_LOG_WARNING, \
798 "epoch approaching: upgrade required: " \
799 "now + %s failed", #b); \
800 isc_interval_set(&_i, _j/2, 0); \
801 (void)isc_time_add((a), &_i, (c)); \
805 #define DNS_ZONE_TIME_ADD(a, b, c) \
808 isc_interval_set(&_i, (b), 0); \
809 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
810 dns_zone_log(zone, ISC_LOG_WARNING, \
811 "epoch approaching: upgrade required: " \
812 "now + %s failed", #b); \
813 isc_interval_set(&_i, (b)/2, 0); \
814 (void)isc_time_add((a), &_i, (c)); \
818 typedef struct nsec3param nsec3param_t;
820 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
823 isc_boolean_t replace;
824 ISC_LINK(nsec3param_t) link;
826 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
833 * Increment resolver-related statistics counters. Zone must be locked.
836 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
837 if (zone->stats != NULL)
838 isc_stats_increment(zone->stats, counter);
842 *** Public functions.
846 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
851 REQUIRE(zonep != NULL && *zonep == NULL);
852 REQUIRE(mctx != NULL);
855 zone = isc_mem_get(mctx, sizeof(*zone));
857 return (ISC_R_NOMEMORY);
860 isc_mem_attach(mctx, &zone->mctx);
862 result = isc_mutex_init(&zone->lock);
863 if (result != ISC_R_SUCCESS)
866 result = ZONEDB_INITLOCK(&zone->dblock);
867 if (result != ISC_R_SUCCESS)
870 /* XXX MPA check that all elements are initialised */
871 #ifdef DNS_ZONE_CHECKLOCK
872 zone->locked = ISC_FALSE;
876 ISC_LINK_INIT(zone, link);
877 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
878 if (result != ISC_R_SUCCESS)
881 dns_name_init(&zone->origin, NULL);
882 zone->strnamerd = NULL;
883 zone->strname = NULL;
884 zone->strrdclass = NULL;
885 zone->strviewname = NULL;
886 zone->masterfile = NULL;
887 zone->masterformat = dns_masterformat_none;
888 zone->keydirectory = NULL;
889 zone->journalsize = -1;
890 zone->journal = NULL;
891 zone->rdclass = dns_rdataclass_none;
892 zone->type = dns_zone_none;
897 zone->db_argv = NULL;
898 isc_time_settoepoch(&zone->expiretime);
899 isc_time_settoepoch(&zone->refreshtime);
900 isc_time_settoepoch(&zone->dumptime);
901 isc_time_settoepoch(&zone->loadtime);
902 zone->notifytime = now;
903 isc_time_settoepoch(&zone->resigntime);
904 isc_time_settoepoch(&zone->keywarntime);
905 isc_time_settoepoch(&zone->signingtime);
906 isc_time_settoepoch(&zone->nsec3chaintime);
907 isc_time_settoepoch(&zone->refreshkeytime);
908 zone->refreshkeyinterval = 0;
909 zone->refreshkeycount = 0;
910 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
911 zone->retry = DNS_ZONE_DEFAULTRETRY;
914 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
915 zone->minrefresh = DNS_ZONE_MINREFRESH;
916 zone->maxretry = DNS_ZONE_MAXRETRY;
917 zone->minretry = DNS_ZONE_MINRETRY;
918 zone->masters = NULL;
919 zone->masterkeynames = NULL;
920 zone->mastersok = NULL;
921 zone->masterscnt = 0;
924 zone->notifykeynames = NULL;
925 zone->notifytype = dns_notifytype_yes;
928 zone->loadtask = NULL;
929 zone->update_acl = NULL;
930 zone->forward_acl = NULL;
931 zone->notify_acl = NULL;
932 zone->query_acl = NULL;
933 zone->queryon_acl = NULL;
934 zone->xfr_acl = NULL;
935 zone->update_disabled = ISC_FALSE;
936 zone->zero_no_soa_ttl = ISC_TRUE;
937 zone->check_names = dns_severity_ignore;
938 zone->request = NULL;
942 zone->writeio = NULL;
944 zone->idlein = DNS_DEFAULT_IDLEIN;
945 zone->idleout = DNS_DEFAULT_IDLEOUT;
946 zone->log_key_expired_timer = 0;
947 ISC_LIST_INIT(zone->notifies);
948 isc_sockaddr_any(&zone->notifysrc4);
949 isc_sockaddr_any6(&zone->notifysrc6);
950 isc_sockaddr_any(&zone->xfrsource4);
951 isc_sockaddr_any6(&zone->xfrsource6);
952 isc_sockaddr_any(&zone->altxfrsource4);
953 isc_sockaddr_any6(&zone->altxfrsource6);
955 zone->tsigkey = NULL;
956 zone->maxxfrin = MAX_XFER_TIME;
957 zone->maxxfrout = MAX_XFER_TIME;
958 zone->ssutable = NULL;
959 zone->sigvalidityinterval = 30 * 24 * 3600;
960 zone->sigresigninginterval = 7 * 24 * 3600;
963 zone->checkmx = NULL;
964 zone->checksrv = NULL;
965 zone->checkns = NULL;
966 ISC_LINK_INIT(zone, statelink);
967 zone->statelist = NULL;
969 zone->requeststats_on = ISC_FALSE;
970 zone->statlevel = dns_zonestat_none;
971 zone->requeststats = NULL;
972 zone->rcvquerystats = NULL;
973 zone->notifydelay = 5;
975 zone->isselfarg = NULL;
976 ISC_LIST_INIT(zone->signing);
977 ISC_LIST_INIT(zone->nsec3chain);
978 zone->signatures = 10;
980 zone->privatetype = (dns_rdatatype_t)0xffffU;
981 zone->added = ISC_FALSE;
982 zone->is_rpz = ISC_FALSE;
983 ISC_LIST_INIT(zone->forwards);
986 zone->sourceserial = 0;
987 zone->sourceserialset = ISC_FALSE;
988 ISC_LIST_INIT(zone->rss_events);
990 zone->rss_raw = NULL;
991 zone->rss_newver = NULL;
992 zone->rss_oldver = NULL;
993 zone->rss_event = NULL;
994 zone->rss_state = NULL;
995 zone->updatemethod = dns_updatemethod_increment;
997 zone->magic = ZONE_MAGIC;
999 /* Must be after magic is set. */
1000 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
1001 if (result != ISC_R_SUCCESS)
1004 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
1005 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
1008 return (ISC_R_SUCCESS);
1011 isc_refcount_decrement(&zone->erefs, NULL);
1012 isc_refcount_destroy(&zone->erefs);
1015 ZONEDB_DESTROYLOCK(&zone->dblock);
1018 DESTROYLOCK(&zone->lock);
1021 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
1026 * Free a zone. Because we require that there be no more
1027 * outstanding events or references, no locking is necessary.
1030 zone_free(dns_zone_t *zone) {
1031 isc_mem_t *mctx = NULL;
1032 dns_signing_t *signing;
1033 dns_nsec3chain_t *nsec3chain;
1035 REQUIRE(DNS_ZONE_VALID(zone));
1036 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
1037 REQUIRE(zone->irefs == 0);
1038 REQUIRE(!LOCKED_ZONE(zone));
1039 REQUIRE(zone->timer == NULL);
1040 REQUIRE(zone->zmgr == NULL);
1043 * Managed objects. Order is important.
1045 if (zone->request != NULL)
1046 dns_request_destroy(&zone->request); /* XXXMPA */
1047 INSIST(zone->readio == NULL);
1048 INSIST(zone->statelist == NULL);
1049 INSIST(zone->writeio == NULL);
1051 if (zone->task != NULL)
1052 isc_task_detach(&zone->task);
1053 if (zone->loadtask != NULL)
1054 isc_task_detach(&zone->loadtask);
1056 /* Unmanaged objects */
1057 for (signing = ISC_LIST_HEAD(zone->signing);
1059 signing = ISC_LIST_HEAD(zone->signing)) {
1060 ISC_LIST_UNLINK(zone->signing, signing, link);
1061 dns_db_detach(&signing->db);
1062 dns_dbiterator_destroy(&signing->dbiterator);
1063 isc_mem_put(zone->mctx, signing, sizeof *signing);
1065 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
1067 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
1068 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
1069 dns_db_detach(&nsec3chain->db);
1070 dns_dbiterator_destroy(&nsec3chain->dbiterator);
1071 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
1073 if (zone->masterfile != NULL)
1074 isc_mem_free(zone->mctx, zone->masterfile);
1075 zone->masterfile = NULL;
1076 if (zone->keydirectory != NULL)
1077 isc_mem_free(zone->mctx, zone->keydirectory);
1078 zone->keydirectory = NULL;
1079 zone->journalsize = -1;
1080 if (zone->journal != NULL)
1081 isc_mem_free(zone->mctx, zone->journal);
1082 zone->journal = NULL;
1083 if (zone->stats != NULL)
1084 isc_stats_detach(&zone->stats);
1085 if (zone->requeststats != NULL)
1086 isc_stats_detach(&zone->requeststats);
1087 if(zone->rcvquerystats != NULL )
1088 dns_stats_detach(&zone->rcvquerystats);
1089 if (zone->db != NULL)
1090 zone_detachdb(zone);
1091 if (zone->acache != NULL)
1092 dns_acache_detach(&zone->acache);
1093 zone_freedbargs(zone);
1094 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
1096 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
1098 zone->check_names = dns_severity_ignore;
1099 if (zone->update_acl != NULL)
1100 dns_acl_detach(&zone->update_acl);
1101 if (zone->forward_acl != NULL)
1102 dns_acl_detach(&zone->forward_acl);
1103 if (zone->notify_acl != NULL)
1104 dns_acl_detach(&zone->notify_acl);
1105 if (zone->query_acl != NULL)
1106 dns_acl_detach(&zone->query_acl);
1107 if (zone->queryon_acl != NULL)
1108 dns_acl_detach(&zone->queryon_acl);
1109 if (zone->xfr_acl != NULL)
1110 dns_acl_detach(&zone->xfr_acl);
1111 if (dns_name_dynamic(&zone->origin))
1112 dns_name_free(&zone->origin, zone->mctx);
1113 if (zone->strnamerd != NULL)
1114 isc_mem_free(zone->mctx, zone->strnamerd);
1115 if (zone->strname != NULL)
1116 isc_mem_free(zone->mctx, zone->strname);
1117 if (zone->strrdclass != NULL)
1118 isc_mem_free(zone->mctx, zone->strrdclass);
1119 if (zone->strviewname != NULL)
1120 isc_mem_free(zone->mctx, zone->strviewname);
1121 if (zone->ssutable != NULL)
1122 dns_ssutable_detach(&zone->ssutable);
1125 ZONEDB_DESTROYLOCK(&zone->dblock);
1126 DESTROYLOCK(&zone->lock);
1127 isc_refcount_destroy(&zone->erefs);
1130 isc_mem_put(mctx, zone, sizeof(*zone));
1131 isc_mem_detach(&mctx);
1135 * Returns ISC_TRUE iff this the signed side of an inline-signing zone.
1136 * Caller should hold zone lock.
1138 static inline isc_boolean_t
1139 inline_secure(dns_zone_t *zone) {
1140 REQUIRE(DNS_ZONE_VALID(zone));
1141 if (zone->raw != NULL)
1147 * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone
1148 * Caller should hold zone lock.
1150 static inline isc_boolean_t
1151 inline_raw(dns_zone_t *zone) {
1152 REQUIRE(DNS_ZONE_VALID(zone));
1153 if (zone->secure != NULL)
1162 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1165 REQUIRE(DNS_ZONE_VALID(zone));
1166 REQUIRE(rdclass != dns_rdataclass_none);
1172 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1173 zone->rdclass == rdclass);
1174 zone->rdclass = rdclass;
1176 if (zone->strnamerd != NULL)
1177 isc_mem_free(zone->mctx, zone->strnamerd);
1178 if (zone->strrdclass != NULL)
1179 isc_mem_free(zone->mctx, zone->strrdclass);
1181 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1182 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1183 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1184 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1186 if (inline_secure(zone))
1187 dns_zone_setclass(zone->raw, rdclass);
1192 dns_zone_getclass(dns_zone_t *zone) {
1193 REQUIRE(DNS_ZONE_VALID(zone));
1195 return (zone->rdclass);
1199 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1200 REQUIRE(DNS_ZONE_VALID(zone));
1203 zone->notifytype = notifytype;
1208 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1209 isc_result_t result;
1210 unsigned int soacount;
1212 REQUIRE(DNS_ZONE_VALID(zone));
1213 REQUIRE(serialp != NULL);
1216 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1217 if (zone->db != NULL) {
1218 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
1219 serialp, NULL, NULL, NULL, NULL,
1221 if (result == ISC_R_SUCCESS && soacount == 0)
1222 result = ISC_R_FAILURE;
1224 result = DNS_R_NOTLOADED;
1225 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1232 dns_zone_getserial(dns_zone_t *zone) {
1233 isc_result_t result;
1234 isc_uint32_t serial;
1236 result = dns_zone_getserial2(zone, &serial);
1237 if (result != ISC_R_SUCCESS)
1238 serial = 0; /* XXX: not really correct, but no other choice */
1247 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1250 REQUIRE(DNS_ZONE_VALID(zone));
1251 REQUIRE(type != dns_zone_none);
1257 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1260 if (zone->strnamerd != NULL)
1261 isc_mem_free(zone->mctx, zone->strnamerd);
1263 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1264 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1269 zone_freedbargs(dns_zone_t *zone) {
1272 /* Free the old database argument list. */
1273 if (zone->db_argv != NULL) {
1274 for (i = 0; i < zone->db_argc; i++)
1275 isc_mem_free(zone->mctx, zone->db_argv[i]);
1276 isc_mem_put(zone->mctx, zone->db_argv,
1277 zone->db_argc * sizeof(*zone->db_argv));
1280 zone->db_argv = NULL;
1284 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1287 isc_result_t result = ISC_R_SUCCESS;
1291 REQUIRE(DNS_ZONE_VALID(zone));
1292 REQUIRE(argv != NULL && *argv == NULL);
1295 size = (zone->db_argc + 1) * sizeof(char *);
1296 for (i = 0; i < zone->db_argc; i++)
1297 size += strlen(zone->db_argv[i]) + 1;
1298 mem = isc_mem_allocate(mctx, size);
1302 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1303 for (i = 0; i < zone->db_argc; i++) {
1305 strcpy(tmp2, zone->db_argv[i]);
1306 tmp2 += strlen(tmp2) + 1;
1310 result = ISC_R_NOMEMORY;
1317 dns_zone_setdbtype(dns_zone_t *zone,
1318 unsigned int dbargc, const char * const *dbargv) {
1319 isc_result_t result = ISC_R_SUCCESS;
1323 REQUIRE(DNS_ZONE_VALID(zone));
1324 REQUIRE(dbargc >= 1);
1325 REQUIRE(dbargv != NULL);
1329 /* Set up a new database argument list. */
1330 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1333 for (i = 0; i < dbargc; i++)
1335 for (i = 0; i < dbargc; i++) {
1336 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1341 /* Free the old list. */
1342 zone_freedbargs(zone);
1344 zone->db_argc = dbargc;
1345 zone->db_argv = new;
1346 result = ISC_R_SUCCESS;
1351 for (i = 0; i < dbargc; i++)
1353 isc_mem_free(zone->mctx, new[i]);
1354 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1356 result = ISC_R_NOMEMORY;
1364 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1366 REQUIRE(DNS_ZONE_VALID(zone));
1369 if (zone->view != NULL)
1370 dns_view_weakdetach(&zone->view);
1371 dns_view_weakattach(view, &zone->view);
1373 if (zone->strviewname != NULL)
1374 isc_mem_free(zone->mctx, zone->strviewname);
1375 if (zone->strnamerd != NULL)
1376 isc_mem_free(zone->mctx, zone->strnamerd);
1378 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1379 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1380 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1381 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1383 if (inline_secure(zone))
1384 dns_zone_setview(zone->raw, view);
1390 dns_zone_getview(dns_zone_t *zone) {
1391 REQUIRE(DNS_ZONE_VALID(zone));
1393 return (zone->view);
1398 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1399 isc_result_t result;
1402 REQUIRE(DNS_ZONE_VALID(zone));
1403 REQUIRE(origin != NULL);
1406 if (dns_name_dynamic(&zone->origin)) {
1407 dns_name_free(&zone->origin, zone->mctx);
1408 dns_name_init(&zone->origin, NULL);
1410 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1412 if (zone->strnamerd != NULL)
1413 isc_mem_free(zone->mctx, zone->strnamerd);
1414 if (zone->strname != NULL)
1415 isc_mem_free(zone->mctx, zone->strname);
1417 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1418 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1419 zone_name_tostr(zone, namebuf, sizeof namebuf);
1420 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1422 if (result == ISC_R_SUCCESS && inline_secure(zone))
1423 result = dns_zone_setorigin(zone->raw, origin);
1429 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1430 REQUIRE(DNS_ZONE_VALID(zone));
1431 REQUIRE(acache != NULL);
1434 if (zone->acache != NULL)
1435 dns_acache_detach(&zone->acache);
1436 dns_acache_attach(acache, &zone->acache);
1437 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1438 if (zone->db != NULL) {
1439 isc_result_t result;
1442 * If the zone reuses an existing DB, the DB needs to be
1443 * set in the acache explicitly. We can safely ignore the
1444 * case where the DB is already set. If other error happens,
1445 * the acache will not work effectively.
1447 result = dns_acache_setdb(acache, zone->db);
1448 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1449 UNEXPECTED_ERROR(__FILE__, __LINE__,
1450 "dns_acache_setdb() failed: %s",
1451 isc_result_totext(result));
1454 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1459 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1462 if (value != NULL) {
1463 copy = isc_mem_strdup(zone->mctx, value);
1465 return (ISC_R_NOMEMORY);
1471 isc_mem_free(zone->mctx, *field);
1474 return (ISC_R_SUCCESS);
1478 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1479 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1483 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1484 dns_masterformat_t format) {
1485 isc_result_t result = ISC_R_SUCCESS;
1487 REQUIRE(DNS_ZONE_VALID(zone));
1490 result = dns_zone_setstring(zone, &zone->masterfile, file);
1491 if (result == ISC_R_SUCCESS) {
1492 zone->masterformat = format;
1493 result = default_journal(zone);
1501 dns_zone_getfile(dns_zone_t *zone) {
1502 REQUIRE(DNS_ZONE_VALID(zone));
1504 return (zone->masterfile);
1508 default_journal(dns_zone_t *zone) {
1509 isc_result_t result;
1512 REQUIRE(DNS_ZONE_VALID(zone));
1513 REQUIRE(LOCKED_ZONE(zone));
1515 if (zone->masterfile != NULL) {
1516 /* Calculate string length including '\0'. */
1517 int len = strlen(zone->masterfile) + sizeof(".jnl");
1518 journal = isc_mem_allocate(zone->mctx, len);
1519 if (journal == NULL)
1520 return (ISC_R_NOMEMORY);
1521 strcpy(journal, zone->masterfile);
1522 strcat(journal, ".jnl");
1526 result = dns_zone_setstring(zone, &zone->journal, journal);
1527 if (journal != NULL)
1528 isc_mem_free(zone->mctx, journal);
1533 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1534 isc_result_t result = ISC_R_SUCCESS;
1536 REQUIRE(DNS_ZONE_VALID(zone));
1539 result = dns_zone_setstring(zone, &zone->journal, journal);
1546 dns_zone_getjournal(dns_zone_t *zone) {
1547 REQUIRE(DNS_ZONE_VALID(zone));
1549 return (zone->journal);
1553 * Return true iff the zone is "dynamic", in the sense that the zone's
1554 * master file (if any) is written by the server, rather than being
1555 * updated manually and read by the server.
1557 * This is true for slave zones, stub zones, key zones, and zones that
1558 * allow dynamic updates either by having an update policy ("ssutable")
1559 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1562 dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) {
1563 REQUIRE(DNS_ZONE_VALID(zone));
1565 if (zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1566 zone->type == dns_zone_key ||
1567 (zone->type == dns_zone_redirect && zone->masters != NULL))
1570 /* If !ignore_freeze, we need check whether updates are disabled. */
1571 if (zone->type == dns_zone_master &&
1572 (!zone->update_disabled || ignore_freeze) &&
1573 ((zone->ssutable != NULL) ||
1574 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
1582 * Set the response policy index and information for a zone.
1585 dns_zone_rpz_enable(dns_zone_t *zone) {
1587 * Only RBTDB zones can be used for response policy zones,
1588 * because only they have the code to load the create the summary data.
1589 * Only zones that are loaded instead of mmap()ed create the
1590 * summary data and so can be policy zones.
1592 if (strcmp(zone->db_argv[0], "rbt") != 0 &&
1593 strcmp(zone->db_argv[0], "rbt64") != 0)
1594 return (ISC_R_NOTIMPLEMENTED);
1596 zone->is_rpz = ISC_TRUE;
1598 return (ISC_R_SUCCESS);
1602 dns_zone_get_rpz(dns_zone_t *zone) {
1603 return (zone->is_rpz);
1607 * If a zone is a response policy zone, mark its new database.
1610 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1613 return (dns_db_rpz_enabled(db, NULL));
1615 return (ISC_R_SUCCESS);
1619 zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) {
1620 isc_result_t result;
1622 isc_time_t loadtime, filetime;
1623 dns_db_t *db = NULL;
1624 isc_boolean_t rbt, hasraw;
1626 REQUIRE(DNS_ZONE_VALID(zone));
1630 hasraw = inline_secure(zone);
1632 result = zone_load(zone->raw, flags, ISC_FALSE);
1633 if (result != ISC_R_SUCCESS) {
1638 LOCK_ZONE(zone->raw);
1643 INSIST(zone->type != dns_zone_none);
1645 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1646 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1647 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1648 result = DNS_R_CONTINUE;
1652 INSIST(zone->db_argc >= 1);
1654 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1655 strcmp(zone->db_argv[0], "rbt64") == 0;
1657 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1659 * The zone has no master file configured.
1661 result = ISC_R_SUCCESS;
1665 if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) {
1667 * This is a slave, stub, or dynamically updated
1668 * zone being reloaded. Do nothing - the database
1669 * we already have is guaranteed to be up-to-date.
1671 if (zone->type == dns_zone_master)
1672 result = DNS_R_DYNAMIC;
1674 result = ISC_R_SUCCESS;
1679 * Store the current time before the zone is loaded, so that if the
1680 * file changes between the time of the load and the time that
1681 * zone->loadtime is set, then the file will still be reloaded
1682 * the next time dns_zone_load is called.
1684 TIME_NOW(&loadtime);
1687 * Don't do the load if the file that stores the zone is older
1688 * than the last time the zone was loaded. If the zone has not
1689 * been loaded yet, zone->loadtime will be the epoch.
1691 if (zone->masterfile != NULL) {
1693 * The file is already loaded. If we are just doing a
1694 * "rndc reconfig", we are done.
1696 if (!isc_time_isepoch(&zone->loadtime) &&
1697 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1698 result = ISC_R_SUCCESS;
1702 result = isc_file_getmodtime(zone->masterfile, &filetime);
1703 if (result == ISC_R_SUCCESS) {
1704 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1705 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1706 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1707 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1708 "skipping load: master file "
1709 "older than last load");
1710 result = DNS_R_UPTODATE;
1713 loadtime = filetime;
1718 * Built in zones (with the exception of empty zones) don't need
1721 if (zone->type == dns_zone_master &&
1722 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1723 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1724 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1725 result = ISC_R_SUCCESS;
1729 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1730 (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
1732 if (zone->masterfile == NULL ||
1733 !isc_file_exists(zone->masterfile)) {
1734 if (zone->masterfile != NULL) {
1735 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1738 zone->refreshtime = now;
1739 if (zone->task != NULL)
1740 zone_settimer(zone, &now);
1741 result = ISC_R_SUCCESS;
1746 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1748 result = dns_db_create(zone->mctx, zone->db_argv[0],
1749 &zone->origin, (zone->type == dns_zone_stub) ?
1750 dns_dbtype_stub : dns_dbtype_zone,
1752 zone->db_argc - 1, zone->db_argv + 1,
1755 if (result != ISC_R_SUCCESS) {
1756 dns_zone_log(zone, ISC_LOG_ERROR,
1757 "loading zone: creating database: %s",
1758 isc_result_totext(result));
1761 dns_db_settask(db, zone->task);
1763 if (! dns_db_ispersistent(db)) {
1764 if (zone->masterfile != NULL) {
1765 result = zone_startload(db, zone, loadtime);
1767 result = DNS_R_NOMASTERFILE;
1768 if (zone->type == dns_zone_master ||
1769 (zone->type == dns_zone_redirect &&
1770 zone->masters == NULL)) {
1771 dns_zone_log(zone, ISC_LOG_ERROR,
1773 "no master file configured");
1776 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1777 "no master file configured: continuing");
1781 if (result == DNS_R_CONTINUE) {
1782 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1783 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1784 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1788 result = zone_postload(zone, db, loadtime, result);
1792 UNLOCK_ZONE(zone->raw);
1801 dns_zone_load(dns_zone_t *zone) {
1802 return (zone_load(zone, 0, ISC_FALSE));
1806 dns_zone_loadnew(dns_zone_t *zone) {
1807 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, ISC_FALSE));
1811 zone_asyncload(isc_task_t *task, isc_event_t *event) {
1812 dns_asyncload_t *asl = event->ev_arg;
1813 dns_zone_t *zone = asl->zone;
1814 isc_result_t result = ISC_R_SUCCESS;
1815 isc_boolean_t load_pending;
1819 REQUIRE(DNS_ZONE_VALID(zone));
1821 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1822 result = ISC_R_CANCELED;
1823 isc_event_free(&event);
1825 if (result == ISC_R_CANCELED)
1828 /* Make sure load is still pending */
1830 load_pending = ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
1832 if (!load_pending) {
1837 zone_load(zone, 0, ISC_TRUE);
1839 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
1842 /* Inform the zone table we've finished loading */
1843 if (asl->loaded != NULL)
1844 (asl->loaded)(asl->loaded_arg, zone, task);
1847 isc_mem_put(zone->mctx, asl, sizeof (*asl));
1848 dns_zone_idetach(&zone);
1852 dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
1854 dns_asyncload_t *asl = NULL;
1855 isc_result_t result = ISC_R_SUCCESS;
1857 REQUIRE(DNS_ZONE_VALID(zone));
1859 if (zone->zmgr == NULL)
1860 return (ISC_R_FAILURE);
1862 /* If we already have a load pending, stop now */
1863 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
1864 return (ISC_R_ALREADYRUNNING);
1866 asl = isc_mem_get(zone->mctx, sizeof (*asl));
1868 CHECK(ISC_R_NOMEMORY);
1872 asl->loaded_arg = arg;
1874 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
1876 zone_asyncload, asl,
1877 sizeof(isc_event_t));
1879 CHECK(ISC_R_NOMEMORY);
1882 zone_iattach(zone, &asl->zone);
1883 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
1884 isc_task_send(zone->loadtask, &e);
1887 return (ISC_R_SUCCESS);
1891 isc_mem_put(zone->mctx, asl, sizeof (*asl));
1896 dns__zone_loadpending(dns_zone_t *zone) {
1897 REQUIRE(DNS_ZONE_VALID(zone));
1899 return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)));
1903 dns_zone_loadandthaw(dns_zone_t *zone) {
1904 isc_result_t result;
1906 if (inline_raw(zone))
1907 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW,
1910 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, ISC_FALSE);
1913 case DNS_R_CONTINUE:
1914 /* Deferred thaw. */
1916 case DNS_R_UPTODATE:
1918 case DNS_R_SEENINCLUDE:
1919 zone->update_disabled = ISC_FALSE;
1921 case DNS_R_NOMASTERFILE:
1922 zone->update_disabled = ISC_FALSE;
1925 /* Error, remain in disabled state. */
1932 get_master_options(dns_zone_t *zone) {
1933 unsigned int options;
1935 options = DNS_MASTER_ZONE;
1936 if (zone->type == dns_zone_slave ||
1937 (zone->type == dns_zone_redirect && zone->masters == NULL))
1938 options |= DNS_MASTER_SLAVE;
1939 if (zone->type == dns_zone_key)
1940 options |= DNS_MASTER_KEY;
1941 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1942 options |= DNS_MASTER_CHECKNS;
1943 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1944 options |= DNS_MASTER_FATALNS;
1945 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1946 options |= DNS_MASTER_CHECKNAMES;
1947 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1948 options |= DNS_MASTER_CHECKNAMESFAIL;
1949 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1950 options |= DNS_MASTER_CHECKMX;
1951 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1952 options |= DNS_MASTER_CHECKMXFAIL;
1953 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1954 options |= DNS_MASTER_CHECKWILDCARD;
1955 if (inline_secure(zone) || (zone->type == dns_zone_master &&
1956 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1957 zone->ssutable != NULL)))
1958 options |= DNS_MASTER_RESIGN;
1963 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1964 dns_load_t *load = event->ev_arg;
1965 isc_result_t result = ISC_R_SUCCESS;
1966 unsigned int options;
1968 REQUIRE(DNS_LOAD_VALID(load));
1970 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1971 result = ISC_R_CANCELED;
1972 isc_event_free(&event);
1973 if (result == ISC_R_CANCELED)
1976 options = get_master_options(load->zone);
1978 result = dns_master_loadfileinc3(load->zone->masterfile,
1979 dns_db_origin(load->db),
1980 dns_db_origin(load->db),
1981 load->zone->rdclass, options, 0,
1982 &load->callbacks, task,
1983 zone_loaddone, load,
1984 &load->zone->lctx, load->zone->mctx,
1985 load->zone->masterformat);
1986 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1987 result != DNS_R_SEENINCLUDE)
1992 zone_loaddone(load, result);
1996 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
1997 isc_result_t result;
1998 unsigned int soacount;
2001 if (raw->db != NULL) {
2002 result = zone_get_from_db(raw, raw->db, NULL, &soacount,
2003 &rawdata->sourceserial,
2004 NULL, NULL, NULL, NULL,
2006 if (result == ISC_R_SUCCESS && soacount > 0U)
2007 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
2013 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
2014 const char me[] = "zone_gotwritehandle";
2015 dns_zone_t *zone = event->ev_arg;
2016 isc_result_t result = ISC_R_SUCCESS;
2017 dns_dbversion_t *version = NULL;
2018 dns_masterrawheader_t rawdata;
2020 REQUIRE(DNS_ZONE_VALID(zone));
2021 INSIST(task == zone->task);
2024 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
2025 result = ISC_R_CANCELED;
2026 isc_event_free(&event);
2027 if (result == ISC_R_CANCELED)
2031 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2032 if (zone->db != NULL) {
2033 const dns_master_style_t *output_style;
2035 dns_db_currentversion(zone->db, &version);
2036 dns_master_initrawheader(&rawdata);
2037 if (inline_secure(zone))
2038 get_raw_serial(zone->raw, &rawdata);
2039 if (zone->type == dns_zone_key)
2040 output_style = &dns_master_style_keyzone;
2042 output_style = &dns_master_style_default;
2043 result = dns_master_dumpinc3(zone->mctx, zone->db, version,
2044 output_style, zone->masterfile,
2045 zone->task, dump_done, zone, &zone->dctx, zone->masterformat,
2047 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2049 result = ISC_R_CANCELED;
2050 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2052 if (result != DNS_R_CONTINUE)
2057 dump_done(zone, result);
2061 * Save the raw serial number for inline-signing zones.
2062 * (XXX: Other information from the header will be used
2063 * for other purposes in the future, but for now this is
2064 * all we're interested in.)
2067 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2068 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
2071 zone->sourceserial = header->sourceserial;
2072 zone->sourceserialset = ISC_TRUE;
2076 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2081 zone_setrawdata(zone, header);
2086 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
2088 isc_result_t result;
2089 isc_result_t tresult;
2090 unsigned int options;
2092 result = dns_zone_rpz_enable_db(zone, db);
2093 if (result != ISC_R_SUCCESS)
2095 options = get_master_options(zone);
2096 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
2097 options |= DNS_MASTER_MANYERRORS;
2099 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
2100 load = isc_mem_get(zone->mctx, sizeof(*load));
2102 return (ISC_R_NOMEMORY);
2107 load->loadtime = loadtime;
2108 load->magic = LOAD_MAGIC;
2110 isc_mem_attach(zone->mctx, &load->mctx);
2111 zone_iattach(zone, &load->zone);
2112 dns_db_attach(db, &load->db);
2113 dns_rdatacallbacks_init(&load->callbacks);
2114 load->callbacks.rawdata = zone_setrawdata;
2115 zone_iattach(zone, &load->callbacks.zone);
2116 result = dns_db_beginload(db, &load->callbacks.add,
2117 &load->callbacks.add_private);
2118 if (result != ISC_R_SUCCESS)
2120 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask,
2121 zone_gotreadhandle, load,
2123 if (result != ISC_R_SUCCESS) {
2125 * We can't report multiple errors so ignore
2126 * the result of dns_db_endload().
2128 (void)dns_db_endload(load->db,
2129 &load->callbacks.add_private);
2132 result = DNS_R_CONTINUE;
2134 dns_rdatacallbacks_t callbacks;
2136 dns_rdatacallbacks_init(&callbacks);
2137 callbacks.rawdata = zone_setrawdata;
2138 zone_iattach(zone, &callbacks.zone);
2139 result = dns_db_beginload(db, &callbacks.add,
2140 &callbacks.add_private);
2141 if (result != ISC_R_SUCCESS) {
2142 zone_idetach(&callbacks.zone);
2145 result = dns_master_loadfile3(zone->masterfile,
2146 &zone->origin, &zone->origin,
2147 zone->rdclass, options, 0,
2148 &callbacks, zone->mctx,
2149 zone->masterformat);
2150 tresult = dns_db_endload(db, &callbacks.add_private);
2151 if (result == ISC_R_SUCCESS)
2153 zone_idetach(&callbacks.zone);
2160 dns_db_detach(&load->db);
2161 zone_idetach(&load->zone);
2162 zone_idetach(&load->callbacks.zone);
2163 isc_mem_detach(&load->mctx);
2164 isc_mem_put(zone->mctx, load, sizeof(*load));
2168 static isc_boolean_t
2169 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2172 isc_result_t result;
2173 char ownerbuf[DNS_NAME_FORMATSIZE];
2174 char namebuf[DNS_NAME_FORMATSIZE];
2175 char altbuf[DNS_NAME_FORMATSIZE];
2176 dns_fixedname_t fixed;
2177 dns_name_t *foundname;
2181 * "." means the services does not exist.
2183 if (dns_name_equal(name, dns_rootname))
2189 if (!dns_name_issubdomain(name, &zone->origin)) {
2190 if (zone->checkmx != NULL)
2191 return ((zone->checkmx)(zone, name, owner));
2195 if (zone->type == dns_zone_master)
2196 level = ISC_LOG_ERROR;
2198 level = ISC_LOG_WARNING;
2200 dns_fixedname_init(&fixed);
2201 foundname = dns_fixedname_name(&fixed);
2203 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2204 0, 0, NULL, foundname, NULL, NULL);
2205 if (result == ISC_R_SUCCESS)
2208 if (result == DNS_R_NXRRSET) {
2209 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2210 0, 0, NULL, foundname, NULL, NULL);
2211 if (result == ISC_R_SUCCESS)
2215 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2216 dns_name_format(name, namebuf, sizeof namebuf);
2217 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2218 result == DNS_R_EMPTYNAME) {
2219 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
2220 level = ISC_LOG_WARNING;
2221 dns_zone_log(zone, level,
2222 "%s/MX '%s' has no address records (A or AAAA)",
2224 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2227 if (result == DNS_R_CNAME) {
2228 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2229 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2230 level = ISC_LOG_WARNING;
2231 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2232 dns_zone_log(zone, level,
2233 "%s/MX '%s' is a CNAME (illegal)",
2235 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2238 if (result == DNS_R_DNAME) {
2239 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2240 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2241 level = ISC_LOG_WARNING;
2242 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
2243 dns_name_format(foundname, altbuf, sizeof altbuf);
2244 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
2245 " '%s' (illegal)", ownerbuf, namebuf,
2248 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2251 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
2252 return ((zone->checkmx)(zone, name, owner));
2257 static isc_boolean_t
2258 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2261 isc_result_t result;
2262 char ownerbuf[DNS_NAME_FORMATSIZE];
2263 char namebuf[DNS_NAME_FORMATSIZE];
2264 char altbuf[DNS_NAME_FORMATSIZE];
2265 dns_fixedname_t fixed;
2266 dns_name_t *foundname;
2270 * "." means the services does not exist.
2272 if (dns_name_equal(name, dns_rootname))
2278 if (!dns_name_issubdomain(name, &zone->origin)) {
2279 if (zone->checksrv != NULL)
2280 return ((zone->checksrv)(zone, name, owner));
2284 if (zone->type == dns_zone_master)
2285 level = ISC_LOG_ERROR;
2287 level = ISC_LOG_WARNING;
2289 dns_fixedname_init(&fixed);
2290 foundname = dns_fixedname_name(&fixed);
2292 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2293 0, 0, NULL, foundname, NULL, NULL);
2294 if (result == ISC_R_SUCCESS)
2297 if (result == DNS_R_NXRRSET) {
2298 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2299 0, 0, NULL, foundname, NULL, NULL);
2300 if (result == ISC_R_SUCCESS)
2304 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2305 dns_name_format(name, namebuf, sizeof namebuf);
2306 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2307 result == DNS_R_EMPTYNAME) {
2308 dns_zone_log(zone, level,
2309 "%s/SRV '%s' has no address records (A or AAAA)",
2311 /* XXX950 make fatal for 9.5.0. */
2315 if (result == DNS_R_CNAME) {
2316 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2317 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2318 level = ISC_LOG_WARNING;
2319 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2320 dns_zone_log(zone, level,
2321 "%s/SRV '%s' is a CNAME (illegal)",
2323 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2326 if (result == DNS_R_DNAME) {
2327 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2328 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2329 level = ISC_LOG_WARNING;
2330 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
2331 dns_name_format(foundname, altbuf, sizeof altbuf);
2332 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
2333 "DNAME '%s' (illegal)", ownerbuf, namebuf,
2336 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2339 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
2340 return ((zone->checksrv)(zone, name, owner));
2345 static isc_boolean_t
2346 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2349 isc_boolean_t answer = ISC_TRUE;
2350 isc_result_t result, tresult;
2351 char ownerbuf[DNS_NAME_FORMATSIZE];
2352 char namebuf[DNS_NAME_FORMATSIZE];
2353 char altbuf[DNS_NAME_FORMATSIZE];
2354 dns_fixedname_t fixed;
2355 dns_name_t *foundname;
2357 dns_rdataset_t aaaa;
2363 if (!dns_name_issubdomain(name, &zone->origin)) {
2364 if (zone->checkns != NULL)
2365 return ((zone->checkns)(zone, name, owner, NULL, NULL));
2369 if (zone->type == dns_zone_master)
2370 level = ISC_LOG_ERROR;
2372 level = ISC_LOG_WARNING;
2374 dns_fixedname_init(&fixed);
2375 foundname = dns_fixedname_name(&fixed);
2376 dns_rdataset_init(&a);
2377 dns_rdataset_init(&aaaa);
2379 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2380 DNS_DBFIND_GLUEOK, 0, NULL,
2381 foundname, &a, NULL);
2383 if (result == ISC_R_SUCCESS) {
2384 dns_rdataset_disassociate(&a);
2386 } else if (result == DNS_R_DELEGATION)
2387 dns_rdataset_disassociate(&a);
2389 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
2390 result == DNS_R_GLUE) {
2391 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2392 DNS_DBFIND_GLUEOK, 0, NULL,
2393 foundname, &aaaa, NULL);
2394 if (tresult == ISC_R_SUCCESS) {
2395 if (dns_rdataset_isassociated(&a))
2396 dns_rdataset_disassociate(&a);
2397 dns_rdataset_disassociate(&aaaa);
2400 if (tresult == DNS_R_DELEGATION)
2401 dns_rdataset_disassociate(&aaaa);
2402 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2404 * Check glue against child zone.
2406 if (zone->checkns != NULL)
2407 answer = (zone->checkns)(zone, name, owner,
2409 if (dns_rdataset_isassociated(&a))
2410 dns_rdataset_disassociate(&a);
2411 if (dns_rdataset_isassociated(&aaaa))
2412 dns_rdataset_disassociate(&aaaa);
2417 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2418 dns_name_format(name, namebuf, sizeof namebuf);
2419 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2420 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2422 isc_boolean_t required = ISC_FALSE;
2423 if (dns_name_issubdomain(name, owner)) {
2424 what = "REQUIRED GLUE ";
2425 required = ISC_TRUE;
2426 } else if (result == DNS_R_DELEGATION)
2427 what = "SIBLING GLUE ";
2431 if (result != DNS_R_DELEGATION || required ||
2432 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2433 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2434 "address records (A or AAAA)",
2435 ownerbuf, namebuf, what);
2437 * Log missing address record.
2439 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2440 (void)(zone->checkns)(zone, name, owner,
2442 /* XXX950 make fatal for 9.5.0. */
2443 /* answer = ISC_FALSE; */
2445 } else if (result == DNS_R_CNAME) {
2446 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2448 /* XXX950 make fatal for 9.5.0. */
2449 /* answer = ISC_FALSE; */
2450 } else if (result == DNS_R_DNAME) {
2451 dns_name_format(foundname, altbuf, sizeof altbuf);
2452 dns_zone_log(zone, level,
2453 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2454 ownerbuf, namebuf, altbuf);
2455 /* XXX950 make fatal for 9.5.0. */
2456 /* answer = ISC_FALSE; */
2459 if (dns_rdataset_isassociated(&a))
2460 dns_rdataset_disassociate(&a);
2461 if (dns_rdataset_isassociated(&aaaa))
2462 dns_rdataset_disassociate(&aaaa);
2466 static isc_boolean_t
2467 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2468 dns_rdataset_t *rdataset)
2470 dns_rdataset_t tmprdataset;
2471 isc_result_t result;
2472 isc_boolean_t answer = ISC_TRUE;
2473 isc_boolean_t format = ISC_TRUE;
2474 int level = ISC_LOG_WARNING;
2475 char ownerbuf[DNS_NAME_FORMATSIZE];
2476 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2477 unsigned int count1 = 0;
2479 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2480 level = ISC_LOG_ERROR;
2482 dns_rdataset_init(&tmprdataset);
2483 for (result = dns_rdataset_first(rdataset);
2484 result == ISC_R_SUCCESS;
2485 result = dns_rdataset_next(rdataset)) {
2486 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2487 unsigned int count2 = 0;
2490 dns_rdataset_current(rdataset, &rdata1);
2491 dns_rdataset_clone(rdataset, &tmprdataset);
2492 for (result = dns_rdataset_first(&tmprdataset);
2493 result == ISC_R_SUCCESS;
2494 result = dns_rdataset_next(&tmprdataset)) {
2495 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2497 if (count1 >= count2)
2499 dns_rdataset_current(&tmprdataset, &rdata2);
2500 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2502 dns_name_format(owner, ownerbuf,
2504 dns_rdatatype_format(rdata1.type,
2509 dns_zone_log(zone, level, "%s/%s has "
2510 "semantically identical records",
2512 if (level == ISC_LOG_ERROR)
2517 dns_rdataset_disassociate(&tmprdataset);
2524 static isc_boolean_t
2525 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2526 dns_dbiterator_t *dbiterator = NULL;
2527 dns_dbnode_t *node = NULL;
2528 dns_fixedname_t fixed;
2530 dns_rdataset_t rdataset;
2531 dns_rdatasetiter_t *rdsit = NULL;
2532 isc_boolean_t ok = ISC_TRUE;
2533 isc_result_t result;
2535 dns_fixedname_init(&fixed);
2536 name = dns_fixedname_name(&fixed);
2537 dns_rdataset_init(&rdataset);
2539 result = dns_db_createiterator(db, 0, &dbiterator);
2540 if (result != ISC_R_SUCCESS)
2543 for (result = dns_dbiterator_first(dbiterator);
2544 result == ISC_R_SUCCESS;
2545 result = dns_dbiterator_next(dbiterator)) {
2546 result = dns_dbiterator_current(dbiterator, &node, name);
2547 if (result != ISC_R_SUCCESS)
2550 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2551 if (result != ISC_R_SUCCESS)
2554 for (result = dns_rdatasetiter_first(rdsit);
2555 result == ISC_R_SUCCESS;
2556 result = dns_rdatasetiter_next(rdsit)) {
2557 dns_rdatasetiter_current(rdsit, &rdataset);
2558 if (!zone_rrset_check_dup(zone, name, &rdataset))
2560 dns_rdataset_disassociate(&rdataset);
2562 dns_rdatasetiter_destroy(&rdsit);
2563 dns_db_detachnode(db, &node);
2567 dns_db_detachnode(db, &node);
2568 dns_dbiterator_destroy(&dbiterator);
2573 static isc_boolean_t
2574 isspf(const dns_rdata_t *rdata) {
2576 const unsigned char *data = rdata->data;
2577 unsigned int rdl = rdata->length, i = 0, tl, len;
2584 if (len > sizeof(buf) - i - 1)
2585 len = sizeof(buf) - i - 1;
2586 memmove(buf + i, data, len);
2596 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
2601 static isc_boolean_t
2602 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2603 dns_dbiterator_t *dbiterator = NULL;
2604 dns_dbnode_t *node = NULL;
2605 dns_rdataset_t rdataset;
2606 dns_fixedname_t fixed;
2607 dns_fixedname_t fixedbottom;
2610 dns_rdata_in_srv_t srv;
2614 isc_result_t result;
2615 isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
2617 dns_fixedname_init(&fixed);
2618 name = dns_fixedname_name(&fixed);
2619 dns_fixedname_init(&fixedbottom);
2620 bottom = dns_fixedname_name(&fixedbottom);
2621 dns_rdataset_init(&rdataset);
2622 dns_rdata_init(&rdata);
2624 result = dns_db_createiterator(db, 0, &dbiterator);
2625 if (result != ISC_R_SUCCESS)
2628 result = dns_dbiterator_first(dbiterator);
2629 while (result == ISC_R_SUCCESS) {
2630 result = dns_dbiterator_current(dbiterator, &node, name);
2631 if (result != ISC_R_SUCCESS)
2635 * Is this name visible in the zone?
2637 if (!dns_name_issubdomain(name, &zone->origin) ||
2638 (dns_name_countlabels(bottom) > 0 &&
2639 dns_name_issubdomain(name, bottom)))
2643 * Don't check the NS records at the origin.
2645 if (dns_name_equal(name, &zone->origin))
2648 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2649 0, 0, &rdataset, NULL);
2650 if (result != ISC_R_SUCCESS)
2653 * Remember bottom of zone.
2655 dns_name_copy(name, bottom, NULL);
2657 result = dns_rdataset_first(&rdataset);
2658 while (result == ISC_R_SUCCESS) {
2659 dns_rdataset_current(&rdataset, &rdata);
2660 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2661 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2662 if (!zone_check_glue(zone, db, &ns.name, name))
2664 dns_rdata_reset(&rdata);
2665 result = dns_rdataset_next(&rdataset);
2667 dns_rdataset_disassociate(&rdataset);
2671 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2672 0, 0, &rdataset, NULL);
2673 if (result != ISC_R_SUCCESS)
2675 result = dns_rdataset_first(&rdataset);
2676 while (result == ISC_R_SUCCESS) {
2677 dns_rdataset_current(&rdataset, &rdata);
2678 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2679 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2680 if (!zone_check_mx(zone, db, &mx.mx, name))
2682 dns_rdata_reset(&rdata);
2683 result = dns_rdataset_next(&rdataset);
2685 dns_rdataset_disassociate(&rdataset);
2688 if (zone->rdclass != dns_rdataclass_in)
2690 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2691 0, 0, &rdataset, NULL);
2692 if (result != ISC_R_SUCCESS)
2694 result = dns_rdataset_first(&rdataset);
2695 while (result == ISC_R_SUCCESS) {
2696 dns_rdataset_current(&rdataset, &rdata);
2697 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2698 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2699 if (!zone_check_srv(zone, db, &srv.target, name))
2701 dns_rdata_reset(&rdata);
2702 result = dns_rdataset_next(&rdataset);
2704 dns_rdataset_disassociate(&rdataset);
2708 * Check if there is a type SPF record without an
2709 * SPF-formatted type TXT record also being present.
2711 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
2713 if (zone->rdclass != dns_rdataclass_in)
2715 have_spf = have_txt = ISC_FALSE;
2716 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
2717 0, 0, &rdataset, NULL);
2718 if (result == ISC_R_SUCCESS) {
2719 dns_rdataset_disassociate(&rdataset);
2720 have_spf = ISC_TRUE;
2722 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
2723 0, 0, &rdataset, NULL);
2724 if (result != ISC_R_SUCCESS)
2726 result = dns_rdataset_first(&rdataset);
2727 while (result == ISC_R_SUCCESS) {
2728 dns_rdataset_current(&rdataset, &rdata);
2729 have_txt = isspf(&rdata);
2730 dns_rdata_reset(&rdata);
2733 result = dns_rdataset_next(&rdataset);
2735 dns_rdataset_disassociate(&rdataset);
2738 if (have_spf && !have_txt) {
2739 char namebuf[DNS_NAME_FORMATSIZE];
2741 dns_name_format(name, namebuf, sizeof(namebuf));
2742 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type "
2743 "SPF record but no SPF TXT record found, "
2744 "add matching type TXT record", namebuf);
2748 dns_db_detachnode(db, &node);
2749 result = dns_dbiterator_next(dbiterator);
2754 dns_db_detachnode(db, &node);
2755 dns_dbiterator_destroy(&dbiterator);
2761 * OpenSSL verification of RSA keys with exponent 3 is known to be
2762 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2763 * if they are in use.
2766 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2767 dns_dbnode_t *node = NULL;
2768 dns_dbversion_t *version = NULL;
2769 dns_rdata_dnskey_t dnskey;
2770 dns_rdata_t rdata = DNS_RDATA_INIT;
2771 dns_rdataset_t rdataset;
2772 isc_result_t result;
2773 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2774 const char *algorithm;
2776 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2777 if (result != ISC_R_SUCCESS)
2780 dns_db_currentversion(db, &version);
2781 dns_rdataset_init(&rdataset);
2782 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2783 dns_rdatatype_none, 0, &rdataset, NULL);
2784 if (result != ISC_R_SUCCESS)
2787 for (result = dns_rdataset_first(&rdataset);
2788 result == ISC_R_SUCCESS;
2789 result = dns_rdataset_next(&rdataset))
2791 dns_rdataset_current(&rdataset, &rdata);
2792 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2793 INSIST(result == ISC_R_SUCCESS);
2795 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2796 dnskey.algorithm == DST_ALG_RSAMD5) &&
2797 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2798 dnskey.data[1] == 3)
2800 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2802 foundrsa = ISC_TRUE;
2803 algorithm = "RSASHA1";
2806 foundmd5 = ISC_TRUE;
2807 algorithm = "RSAMD5";
2810 dns_zone_log(zone, ISC_LOG_WARNING,
2811 "weak %s (%u) key found "
2812 "(exponent=3)", algorithm,
2814 if (foundrsa && foundmd5)
2817 dns_rdata_reset(&rdata);
2819 dns_rdataset_disassociate(&rdataset);
2823 dns_db_detachnode(db, &node);
2824 if (version != NULL)
2825 dns_db_closeversion(db, &version, ISC_FALSE);
2829 resume_signingwithkey(dns_zone_t *zone) {
2830 dns_dbnode_t *node = NULL;
2831 dns_dbversion_t *version = NULL;
2832 dns_rdata_t rdata = DNS_RDATA_INIT;
2833 dns_rdataset_t rdataset;
2834 isc_result_t result;
2835 dns_db_t *db = NULL;
2837 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2838 if (zone->db != NULL)
2839 dns_db_attach(zone->db, &db);
2840 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2844 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2845 if (result != ISC_R_SUCCESS)
2848 dns_db_currentversion(db, &version);
2849 dns_rdataset_init(&rdataset);
2850 result = dns_db_findrdataset(db, node, version,
2852 dns_rdatatype_none, 0,
2854 if (result != ISC_R_SUCCESS) {
2855 INSIST(!dns_rdataset_isassociated(&rdataset));
2859 for (result = dns_rdataset_first(&rdataset);
2860 result == ISC_R_SUCCESS;
2861 result = dns_rdataset_next(&rdataset))
2863 dns_rdataset_current(&rdataset, &rdata);
2864 if (rdata.length != 5 ||
2865 rdata.data[0] == 0 || rdata.data[4] != 0) {
2866 dns_rdata_reset(&rdata);
2870 result = zone_signwithkey(zone, rdata.data[0],
2871 (rdata.data[1] << 8) | rdata.data[2],
2872 ISC_TF(rdata.data[3]));
2873 if (result != ISC_R_SUCCESS) {
2874 dns_zone_log(zone, ISC_LOG_ERROR,
2875 "zone_signwithkey failed: %s",
2876 dns_result_totext(result));
2878 dns_rdata_reset(&rdata);
2880 dns_rdataset_disassociate(&rdataset);
2885 dns_db_detachnode(db, &node);
2886 if (version != NULL)
2887 dns_db_closeversion(db, &version, ISC_FALSE);
2893 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2894 dns_nsec3chain_t *nsec3chain, *current;
2895 dns_dbversion_t *version = NULL;
2896 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
2897 isc_result_t result;
2899 unsigned int options = 0;
2900 char saltbuf[255*2+1];
2901 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
2902 dns_db_t *db = NULL;
2905 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2906 if (zone->db != NULL)
2907 dns_db_attach(zone->db, &db);
2908 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2911 result = ISC_R_SUCCESS;
2915 dns_db_currentversion(db, &version);
2916 result = dns_nsec_nseconly(db, version, &nseconly);
2917 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
2918 dns_db_closeversion(db, &version, ISC_FALSE);
2919 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
2920 result = ISC_R_SUCCESS;
2924 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2925 if (nsec3chain == NULL) {
2926 result = ISC_R_NOMEMORY;
2930 nsec3chain->magic = 0;
2931 nsec3chain->done = ISC_FALSE;
2932 nsec3chain->db = NULL;
2933 nsec3chain->dbiterator = NULL;
2934 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2935 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2936 nsec3chain->nsec3param.hash = nsec3param->hash;
2937 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2938 nsec3chain->nsec3param.flags = nsec3param->flags;
2939 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2940 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2941 nsec3chain->nsec3param.salt = nsec3chain->salt;
2942 nsec3chain->seen_nsec = ISC_FALSE;
2943 nsec3chain->delete_nsec = ISC_FALSE;
2944 nsec3chain->save_delete_nsec = ISC_FALSE;
2946 if (nsec3param->flags == 0)
2947 strlcpy(flags, "NONE", sizeof(flags));
2950 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
2951 strlcat(flags, "REMOVE", sizeof(flags));
2952 if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) {
2953 if (flags[0] == '\0')
2954 strlcpy(flags, "INITIAL", sizeof(flags));
2956 strlcat(flags, "|INITIAL", sizeof(flags));
2958 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
2959 if (flags[0] == '\0')
2960 strlcpy(flags, "CREATE", sizeof(flags));
2962 strlcat(flags, "|CREATE", sizeof(flags));
2964 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
2965 if (flags[0] == '\0')
2966 strlcpy(flags, "NONSEC", sizeof(flags));
2968 strlcat(flags, "|NONSEC", sizeof(flags));
2970 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
2971 if (flags[0] == '\0')
2972 strlcpy(flags, "OPTOUT", sizeof(flags));
2974 strlcat(flags, "|OPTOUT", sizeof(flags));
2977 if (nsec3param->salt_length == 0)
2978 strlcpy(saltbuf, "-", sizeof(saltbuf));
2980 for (i = 0; i < nsec3param->salt_length; i++)
2981 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
2982 dns_zone_log(zone, ISC_LOG_INFO,
2983 "zone_addnsec3chain(%u,%s,%u,%s)",
2984 nsec3param->hash, flags, nsec3param->iterations,
2987 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2989 current = ISC_LIST_NEXT(current, link)) {
2990 if (current->db == db &&
2991 current->nsec3param.hash == nsec3param->hash &&
2992 current->nsec3param.iterations == nsec3param->iterations &&
2993 current->nsec3param.salt_length == nsec3param->salt_length
2994 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2995 nsec3param->salt_length))
2996 current->done = ISC_TRUE;
2999 dns_db_attach(db, &nsec3chain->db);
3000 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
3001 options = DNS_DB_NONSEC3;
3002 result = dns_db_createiterator(nsec3chain->db, options,
3003 &nsec3chain->dbiterator);
3004 if (result == ISC_R_SUCCESS)
3005 dns_dbiterator_first(nsec3chain->dbiterator);
3006 if (result == ISC_R_SUCCESS) {
3007 dns_dbiterator_pause(nsec3chain->dbiterator);
3008 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
3011 if (isc_time_isepoch(&zone->nsec3chaintime)) {
3013 zone->nsec3chaintime = now;
3014 if (zone->task != NULL)
3015 zone_settimer(zone, &now);
3019 if (nsec3chain != NULL) {
3020 if (nsec3chain->db != NULL)
3021 dns_db_detach(&nsec3chain->db);
3022 if (nsec3chain->dbiterator != NULL)
3023 dns_dbiterator_destroy(&nsec3chain->dbiterator);
3024 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
3034 resume_addnsec3chain(dns_zone_t *zone) {
3035 dns_dbnode_t *node = NULL;
3036 dns_dbversion_t *version = NULL;
3037 dns_rdataset_t rdataset;
3038 isc_result_t result;
3039 dns_rdata_nsec3param_t nsec3param;
3040 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
3041 dns_db_t *db = NULL;
3043 if (zone->privatetype == 0)
3046 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3047 if (zone->db != NULL)
3048 dns_db_attach(zone->db, &db);
3049 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3053 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3054 if (result != ISC_R_SUCCESS)
3057 dns_db_currentversion(db, &version);
3059 result = dns_nsec_nseconly(db, version, &nseconly);
3060 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
3062 dns_rdataset_init(&rdataset);
3063 result = dns_db_findrdataset(db, node, version,
3064 zone->privatetype, dns_rdatatype_none,
3065 0, &rdataset, NULL);
3066 if (result != ISC_R_SUCCESS) {
3067 INSIST(!dns_rdataset_isassociated(&rdataset));
3071 for (result = dns_rdataset_first(&rdataset);
3072 result == ISC_R_SUCCESS;
3073 result = dns_rdataset_next(&rdataset))
3075 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
3076 dns_rdata_t rdata = DNS_RDATA_INIT;
3077 dns_rdata_t private = DNS_RDATA_INIT;
3079 dns_rdataset_current(&rdataset, &private);
3080 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
3083 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3084 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3085 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
3086 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
3088 result = zone_addnsec3chain(zone, &nsec3param);
3089 if (result != ISC_R_SUCCESS) {
3090 dns_zone_log(zone, ISC_LOG_ERROR,
3091 "zone_addnsec3chain failed: %s",
3092 dns_result_totext(result));
3096 dns_rdataset_disassociate(&rdataset);
3100 dns_db_detachnode(db, &node);
3101 if (version != NULL)
3102 dns_db_closeversion(db, &version, ISC_FALSE);
3108 set_resigntime(dns_zone_t *zone) {
3109 dns_rdataset_t rdataset;
3110 dns_fixedname_t fixed;
3111 unsigned int resign;
3112 isc_result_t result;
3113 isc_uint32_t nanosecs;
3114 dns_db_t *db = NULL;
3116 dns_rdataset_init(&rdataset);
3117 dns_fixedname_init(&fixed);
3119 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3120 if (zone->db != NULL)
3121 dns_db_attach(zone->db, &db);
3122 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3124 isc_time_settoepoch(&zone->resigntime);
3128 result = dns_db_getsigningtime(db, &rdataset,
3129 dns_fixedname_name(&fixed));
3130 if (result != ISC_R_SUCCESS) {
3131 isc_time_settoepoch(&zone->resigntime);
3135 resign = rdataset.resign - zone->sigresigninginterval;
3136 dns_rdataset_disassociate(&rdataset);
3137 isc_random_get(&nanosecs);
3138 nanosecs %= 1000000000;
3139 isc_time_set(&zone->resigntime, resign, nanosecs);
3146 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
3147 dns_dbnode_t *node = NULL;
3148 dns_rdataset_t rdataset;
3149 dns_dbversion_t *version = NULL;
3150 dns_rdata_nsec3param_t nsec3param;
3151 isc_boolean_t ok = ISC_FALSE;
3152 isc_result_t result;
3153 dns_rdata_t rdata = DNS_RDATA_INIT;
3154 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
3155 dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE;
3157 dns_rdataset_init(&rdataset);
3158 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3159 if (result != ISC_R_SUCCESS) {
3160 dns_zone_log(zone, ISC_LOG_ERROR,
3161 "nsec3param lookup failure: %s",
3162 dns_result_totext(result));
3165 dns_db_currentversion(db, &version);
3167 result = dns_db_findrdataset(db, node, version,
3168 dns_rdatatype_nsec3param,
3169 dns_rdatatype_none, 0, &rdataset, NULL);
3170 if (result == ISC_R_NOTFOUND) {
3171 INSIST(!dns_rdataset_isassociated(&rdataset));
3172 result = ISC_R_SUCCESS;
3175 if (result != ISC_R_SUCCESS) {
3176 INSIST(!dns_rdataset_isassociated(&rdataset));
3177 dns_zone_log(zone, ISC_LOG_ERROR,
3178 "nsec3param lookup failure: %s",
3179 dns_result_totext(result));
3184 * For dynamic zones we must support every algorithm so we can
3185 * regenerate all the NSEC3 chains.
3186 * For non-dynamic zones we only need to find a supported algorithm.
3188 for (result = dns_rdataset_first(&rdataset);
3189 result == ISC_R_SUCCESS;
3190 result = dns_rdataset_next(&rdataset))
3192 dns_rdataset_current(&rdataset, &rdata);
3193 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3194 dns_rdata_reset(&rdata);
3195 INSIST(result == ISC_R_SUCCESS);
3196 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
3197 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
3199 dns_zone_log(zone, ISC_LOG_WARNING,
3200 "nsec3 test \"unknown\" hash algorithm found: %u",
3203 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
3205 dns_zone_log(zone, ISC_LOG_ERROR,
3206 "unsupported nsec3 hash algorithm"
3207 " in dynamic zone: %u",
3209 result = DNS_R_BADZONE;
3210 /* Stop second error message. */
3214 dns_zone_log(zone, ISC_LOG_WARNING,
3215 "unsupported nsec3 hash algorithm: %u",
3220 if (result == ISC_R_NOMORE)
3221 result = ISC_R_SUCCESS;
3224 result = DNS_R_BADZONE;
3225 dns_zone_log(zone, ISC_LOG_ERROR,
3226 "no supported nsec3 hash algorithm");
3230 if (dns_rdataset_isassociated(&rdataset))
3231 dns_rdataset_disassociate(&rdataset);
3232 dns_db_closeversion(db, &version, ISC_FALSE);
3233 dns_db_detachnode(db, &node);
3238 * Set the timer for refreshing the key zone to the soonest future time
3239 * of the set (current timer, keydata->refresh, keydata->addhd,
3240 * keydata->removehd).
3243 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
3244 isc_stdtime_t now, isc_boolean_t force)
3246 const char me[] = "set_refreshkeytimer";
3248 isc_time_t timenow, timethen;
3252 then = key->refresh;
3255 if (key->addhd > now && key->addhd < then)
3257 if (key->removehd > now && key->removehd < then)
3258 then = key->removehd;
3262 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
3265 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
3266 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
3267 zone->refreshkeytime = timethen;
3269 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
3270 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
3271 zone_settimer(zone, &timenow);
3275 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
3276 * If the key zone is changed, set '*changed' to ISC_TRUE.
3279 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3280 dns_diff_t *diff, dns_keytable_t *keytable,
3281 dns_keynode_t **keynodep, isc_boolean_t *changed)
3283 const char me[] = "create_keydata";
3284 isc_result_t result = ISC_R_SUCCESS;
3285 isc_buffer_t keyb, dstb;
3286 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
3287 dns_rdata_keydata_t keydata;
3288 dns_rdata_dnskey_t dnskey;
3289 dns_rdata_t rdata = DNS_RDATA_INIT;
3290 dns_keynode_t *keynode;
3295 REQUIRE(keynodep != NULL);
3296 keynode = *keynodep;
3299 isc_stdtime_get(&now);
3301 /* Loop in case there's more than one key. */
3302 while (result == ISC_R_SUCCESS) {
3303 dns_keynode_t *nextnode = NULL;
3305 key = dns_keynode_key(keynode);
3309 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
3310 CHECK(dst_key_todns(key, &dstb));
3312 /* Convert DST key to DNSKEY. */
3313 dns_rdata_reset(&rdata);
3314 isc_buffer_usedregion(&dstb, &r);
3315 dns_rdata_fromregion(&rdata, dst_key_class(key),
3316 dns_rdatatype_dnskey, &r);
3318 /* DSTKEY to KEYDATA. */
3319 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3320 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
3323 /* KEYDATA to rdata. */
3324 dns_rdata_reset(&rdata);
3325 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
3326 CHECK(dns_rdata_fromstruct(&rdata,
3327 zone->rdclass, dns_rdatatype_keydata,
3330 /* Add rdata to zone. */
3331 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
3332 dst_key_name(key), 0, &rdata));
3333 *changed = ISC_TRUE;
3335 /* Refresh new keys from the zone apex as soon as possible. */
3336 set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
3339 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
3340 if (result != ISC_R_NOTFOUND) {
3341 dns_keytable_detachkeynode(keytable, &keynode);
3346 if (keynode != NULL)
3347 dns_keytable_detachkeynode(keytable, &keynode);
3350 return (ISC_R_SUCCESS);
3357 * Remove from the key zone all the KEYDATA records found in rdataset.
3360 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3361 dns_name_t *name, dns_rdataset_t *rdataset)
3363 dns_rdata_t rdata = DNS_RDATA_INIT;
3364 isc_result_t result, uresult;
3366 for (result = dns_rdataset_first(rdataset);
3367 result == ISC_R_SUCCESS;
3368 result = dns_rdataset_next(rdataset)) {
3369 dns_rdata_reset(&rdata);
3370 dns_rdataset_current(rdataset, &rdata);
3371 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3373 if (uresult != ISC_R_SUCCESS)
3376 if (result == ISC_R_NOMORE)
3377 result = ISC_R_SUCCESS;
3382 * Compute the DNSSEC key ID for a DNSKEY record.
3385 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
3388 isc_result_t result;
3389 dns_rdata_t rdata = DNS_RDATA_INIT;
3390 unsigned char data[4096];
3391 isc_buffer_t buffer;
3392 dst_key_t *dstkey = NULL;
3394 isc_buffer_init(&buffer, data, sizeof(data));
3395 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3396 dns_rdatatype_dnskey, dnskey, &buffer);
3398 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
3399 if (result == ISC_R_SUCCESS)
3400 *tag = dst_key_id(dstkey);
3401 dst_key_free(&dstkey);
3407 * Add key to the security roots.
3410 trust_key(dns_zone_t *zone, dns_name_t *keyname,
3411 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
3412 isc_result_t result;
3413 dns_rdata_t rdata = DNS_RDATA_INIT;
3414 unsigned char data[4096];
3415 isc_buffer_t buffer;
3416 dns_keytable_t *sr = NULL;
3417 dst_key_t *dstkey = NULL;
3419 /* Convert dnskey to DST key. */
3420 isc_buffer_init(&buffer, data, sizeof(data));
3421 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3422 dns_rdatatype_dnskey, dnskey, &buffer);
3424 result = dns_view_getsecroots(zone->view, &sr);
3425 if (result != ISC_R_SUCCESS)
3428 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
3429 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
3430 dns_keytable_detach(&sr);
3434 dst_key_free(&dstkey);
3436 dns_keytable_detach(&sr);
3441 * Add a null key to the security roots for so that all queries
3442 * to the zone will fail.
3445 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
3446 isc_result_t result;
3447 dns_keytable_t *sr = NULL;
3449 result = dns_view_getsecroots(zone->view, &sr);
3450 if (result == ISC_R_SUCCESS) {
3451 dns_keytable_marksecure(sr, keyname);
3452 dns_keytable_detach(&sr);
3457 * Scan a set of KEYDATA records from the key zone. The ones that are
3458 * valid (i.e., the add holddown timer has expired) become trusted keys.
3461 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
3462 isc_result_t result;
3463 dns_rdata_t rdata = DNS_RDATA_INIT;
3464 dns_rdata_keydata_t keydata;
3465 dns_rdata_dnskey_t dnskey;
3466 isc_mem_t *mctx = zone->mctx;
3467 int trusted = 0, revoked = 0, pending = 0;
3469 dns_keytable_t *sr = NULL;
3471 isc_stdtime_get(&now);
3473 result = dns_view_getsecroots(zone->view, &sr);
3474 if (result == ISC_R_SUCCESS) {
3475 dns_keytable_delete(sr, name);
3476 dns_keytable_detach(&sr);
3479 /* Now insert all the accepted trust anchors from this keydata set. */
3480 for (result = dns_rdataset_first(rdataset);
3481 result == ISC_R_SUCCESS;
3482 result = dns_rdataset_next(rdataset)) {
3483 dns_rdata_reset(&rdata);
3484 dns_rdataset_current(rdataset, &rdata);
3486 /* Convert rdata to keydata. */
3487 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
3488 if (result == ISC_R_UNEXPECTEDEND)
3490 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3492 /* Set the key refresh timer to force a fast refresh. */
3493 set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
3495 /* If the removal timer is nonzero, this key was revoked. */
3496 if (keydata.removehd != 0) {
3502 * If the add timer is still pending, this key is not
3505 if (now < keydata.addhd) {
3510 /* Convert keydata to dnskey. */
3511 dns_keydata_todnskey(&keydata, &dnskey, NULL);
3513 /* Add to keytables. */
3515 trust_key(zone, name, &dnskey, mctx);
3518 if (trusted == 0 && pending != 0) {
3519 char namebuf[DNS_NAME_FORMATSIZE];
3520 dns_name_format(name, namebuf, sizeof namebuf);
3521 dns_zone_log(zone, ISC_LOG_ERROR,
3522 "No valid trust anchors for '%s'!", namebuf);
3523 dns_zone_log(zone, ISC_LOG_ERROR,
3524 "%d key(s) revoked, %d still pending",
3526 dns_zone_log(zone, ISC_LOG_ERROR,
3527 "All queries to '%s' will fail", namebuf);
3528 fail_secure(zone, name);
3533 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3536 dns_diff_t temp_diff;
3537 isc_result_t result;
3540 * Create a singleton diff.
3542 dns_diff_init(diff->mctx, &temp_diff);
3543 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3546 * Apply it to the database.
3548 result = dns_diff_apply(&temp_diff, db, ver);
3549 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3550 if (result != ISC_R_SUCCESS) {
3551 dns_difftuple_free(tuple);
3556 * Merge it into the current pending journal entry.
3558 dns_diff_appendminimal(diff, tuple);
3561 * Do not clear temp_diff.
3563 return (ISC_R_SUCCESS);
3567 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3568 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3571 dns_difftuple_t *tuple = NULL;
3572 isc_result_t result;
3573 result = dns_difftuple_create(diff->mctx, op,
3574 name, ttl, rdata, &tuple);
3575 if (result != ISC_R_SUCCESS)
3577 return (do_one_tuple(&tuple, db, ver, diff));
3581 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3582 isc_mem_t *mctx, dns_updatemethod_t method) {
3583 dns_difftuple_t *deltuple = NULL;
3584 dns_difftuple_t *addtuple = NULL;
3585 isc_uint32_t serial;
3586 isc_result_t result;
3588 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3589 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3590 addtuple->op = DNS_DIFFOP_ADD;
3592 serial = dns_soa_getserial(&addtuple->rdata);
3593 serial = dns_update_soaserial(serial, method);
3594 dns_soa_setserial(serial, &addtuple->rdata);
3595 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3596 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3597 result = ISC_R_SUCCESS;
3600 if (addtuple != NULL)
3601 dns_difftuple_free(&addtuple);
3602 if (deltuple != NULL)
3603 dns_difftuple_free(&deltuple);
3608 * Write all transactions in 'diff' to the zone journal file.
3611 zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
3614 const char me[] = "zone_journal";
3615 const char *journalfile;
3616 isc_result_t result = ISC_R_SUCCESS;
3617 dns_journal_t *journal = NULL;
3618 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
3621 journalfile = dns_zone_getjournal(zone);
3622 if (journalfile != NULL) {
3623 result = dns_journal_open(zone->mctx, journalfile, mode,
3625 if (result != ISC_R_SUCCESS) {
3626 dns_zone_log(zone, ISC_LOG_ERROR,
3627 "%s:dns_journal_open -> %s",
3628 caller, dns_result_totext(result));
3632 if (sourceserial != NULL)
3633 dns_journal_set_sourceserial(journal, *sourceserial);
3635 result = dns_journal_write_transaction(journal, diff);
3636 if (result != ISC_R_SUCCESS) {
3637 dns_zone_log(zone, ISC_LOG_ERROR,
3638 "%s:dns_journal_write_transaction -> %s",
3639 caller, dns_result_totext(result));
3641 dns_journal_destroy(&journal);
3648 * Create an SOA record for a newly-created zone
3651 add_soa(dns_zone_t *zone, dns_db_t *db) {
3652 isc_result_t result;
3653 dns_rdata_t rdata = DNS_RDATA_INIT;
3654 unsigned char buf[DNS_SOA_BUFFERSIZE];
3655 dns_dbversion_t *ver = NULL;
3658 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
3660 dns_diff_init(zone->mctx, &diff);
3661 result = dns_db_newversion(db, &ver);
3662 if (result != ISC_R_SUCCESS) {
3663 dns_zone_log(zone, ISC_LOG_ERROR,
3664 "add_soa:dns_db_newversion -> %s",
3665 dns_result_totext(result));
3669 /* Build SOA record */
3670 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
3671 0, 0, 0, 0, 0, buf, &rdata);
3672 if (result != ISC_R_SUCCESS) {
3673 dns_zone_log(zone, ISC_LOG_ERROR,
3674 "add_soa:dns_soa_buildrdata -> %s",
3675 dns_result_totext(result));
3679 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
3680 &zone->origin, 0, &rdata);
3683 dns_diff_clear(&diff);
3685 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
3687 INSIST(ver == NULL);
3693 * Synchronize the set of initializing keys found in managed-keys {}
3694 * statements with the set of trust anchors found in the managed-keys.bind
3695 * zone. If a domain is no longer named in managed-keys, delete all keys
3696 * from that domain from the key zone. If a domain is mentioned in in
3697 * managed-keys but there are no references to it in the key zone, load
3698 * the key zone with the initializing key(s) for that domain.
3701 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
3702 isc_result_t result = ISC_R_SUCCESS;
3703 isc_boolean_t changed = ISC_FALSE;
3704 isc_boolean_t commit = ISC_FALSE;
3705 dns_rbtnodechain_t chain;
3707 dns_name_t foundname, *origin;
3708 dns_keynode_t *keynode = NULL;
3709 dns_view_t *view = zone->view;
3710 dns_keytable_t *sr = NULL;
3711 dns_dbversion_t *ver = NULL;
3713 dns_rriterator_t rrit;
3715 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3717 dns_name_init(&foundname, NULL);
3718 dns_fixedname_init(&fn);
3719 origin = dns_fixedname_name(&fn);
3721 dns_diff_init(zone->mctx, &diff);
3723 CHECK(dns_view_getsecroots(view, &sr));
3725 result = dns_db_newversion(db, &ver);
3726 if (result != ISC_R_SUCCESS) {
3727 dns_zone_log(zone, ISC_LOG_ERROR,
3728 "sync_keyzone:dns_db_newversion -> %s",
3729 dns_result_totext(result));
3734 * Walk the zone DB. If we find any keys whose names are no longer
3735 * in managed-keys (or *are* in trusted-keys, meaning they are
3736 * permanent and not RFC5011-maintained), delete them from the
3737 * zone. Otherwise call load_secroots(), which loads keys into
3738 * secroots as appropriate.
3740 dns_rriterator_init(&rrit, db, ver, 0);
3741 for (result = dns_rriterator_first(&rrit);
3742 result == ISC_R_SUCCESS;
3743 result = dns_rriterator_nextrrset(&rrit)) {
3744 dns_rdataset_t *rdataset = NULL;
3745 dns_name_t *rrname = NULL;
3748 dns_rriterator_current(&rrit, &rrname, &ttl,
3750 if (!dns_rdataset_isassociated(rdataset)) {
3751 dns_rriterator_destroy(&rrit);
3755 if (rdataset->type != dns_rdatatype_keydata)
3758 result = dns_keytable_find(sr, rrname, &keynode);
3759 if ((result != ISC_R_SUCCESS &&
3760 result != DNS_R_PARTIALMATCH) ||
3761 dns_keynode_managed(keynode) == ISC_FALSE)
3763 CHECK(delete_keydata(db, ver, &diff,
3767 load_secroots(zone, rrname, rdataset);
3770 if (keynode != NULL)
3771 dns_keytable_detachkeynode(sr, &keynode);
3773 dns_rriterator_destroy(&rrit);
3776 * Now walk secroots to find any managed keys that aren't
3777 * in the zone. If we find any, we add them to the zone.
3779 RWLOCK(&sr->rwlock, isc_rwlocktype_write);
3780 dns_rbtnodechain_init(&chain, zone->mctx);
3781 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
3782 if (result == ISC_R_NOTFOUND)
3783 result = ISC_R_NOMORE;
3784 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
3785 dns_rbtnode_t *rbtnode = NULL;
3787 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
3788 if (rbtnode->data == NULL)
3791 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
3792 if (dns_keynode_managed(keynode)) {
3793 dns_fixedname_t fname;
3794 dns_name_t *keyname;
3797 key = dns_keynode_key(keynode);
3798 dns_fixedname_init(&fname);
3800 if (key == NULL) /* fail_secure() was called. */
3803 keyname = dst_key_name(key);
3804 result = dns_db_find(db, keyname, ver,
3805 dns_rdatatype_keydata,
3806 DNS_DBFIND_NOWILD, 0, NULL,
3807 dns_fixedname_name(&fname),
3809 if (result != ISC_R_SUCCESS)
3810 result = create_keydata(zone, db, ver, &diff,
3811 sr, &keynode, &changed);
3812 if (result != ISC_R_SUCCESS)
3816 result = dns_rbtnodechain_next(&chain, &foundname, origin);
3817 if (keynode != NULL)
3818 dns_keytable_detachkeynode(sr, &keynode);
3820 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
3822 if (result == ISC_R_NOMORE)
3823 result = ISC_R_SUCCESS;
3826 /* Write changes to journal file. */
3827 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
3828 zone->updatemethod));
3829 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
3831 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
3832 zone_needdump(zone, 30);
3837 if (result != ISC_R_SUCCESS &&
3838 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3839 dns_zone_log(zone, ISC_LOG_ERROR,
3840 "unable to synchronize managed keys: %s",
3841 dns_result_totext(result));
3842 isc_time_settoepoch(&zone->refreshkeytime);
3844 if (keynode != NULL)
3845 dns_keytable_detachkeynode(sr, &keynode);
3847 dns_keytable_detach(&sr);
3849 dns_db_closeversion(db, &ver, commit);
3850 dns_diff_clear(&diff);
3852 INSIST(ver == NULL);
3858 dns_zone_synckeyzone(dns_zone_t *zone) {
3859 isc_result_t result;
3860 dns_db_t *db = NULL;
3862 if (zone->type != dns_zone_key)
3863 return (DNS_R_BADZONE);
3865 CHECK(dns_zone_getdb(zone, &db));
3868 result = sync_keyzone(zone, db);
3878 maybe_send_secure(dns_zone_t *zone) {
3879 isc_result_t result;
3882 * We've finished loading, or else failed to load, an inline-signing
3883 * 'secure' zone. We now need information about the status of the
3884 * 'raw' zone. If we failed to load, then we need it to send a
3885 * copy of its database; if we succeeded, we need it to send its
3886 * serial number so that we can sync with it. If it has not yet
3887 * loaded, we set a flag so that it will send the necessary
3888 * information when it has finished loading.
3890 if (zone->raw->db != NULL) {
3891 if (zone->db != NULL) {
3892 isc_uint32_t serial;
3893 unsigned int soacount;
3895 result = zone_get_from_db(zone->raw, zone->raw->db,
3896 NULL, &soacount, &serial, NULL,
3897 NULL, NULL, NULL, NULL);
3898 if (result == ISC_R_SUCCESS && soacount > 0U)
3899 zone_send_secureserial(zone->raw, serial);
3901 zone_send_securedb(zone->raw, zone->raw->db);
3904 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
3907 static isc_boolean_t
3908 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
3909 isc_result_t result;
3910 isc_boolean_t answer = ISC_FALSE;
3913 dns_diff_init(mctx, &diff);
3914 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
3915 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
3917 dns_diff_clear(&diff);
3922 * The zone is presumed to be locked.
3923 * If this is a inline_raw zone the secure version is also locked.
3926 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
3927 isc_result_t result)
3929 unsigned int soacount = 0;
3930 unsigned int nscount = 0;
3931 unsigned int errors = 0;
3932 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
3934 isc_boolean_t needdump = ISC_FALSE;
3935 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3936 isc_boolean_t nomaster = ISC_FALSE;
3937 unsigned int options;
3939 INSIST(LOCKED_ZONE(zone));
3940 if (inline_raw(zone))
3941 INSIST(LOCKED_ZONE(zone->secure));
3946 * Initiate zone transfer? We may need a error code that
3947 * indicates that the "permanent" form does not exist.
3948 * XXX better error feedback to log.
3950 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
3951 if (zone->type == dns_zone_slave ||
3952 zone->type == dns_zone_stub ||
3953 (zone->type == dns_zone_redirect &&
3954 zone->masters == NULL)) {
3955 if (result == ISC_R_FILENOTFOUND)
3956 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3958 else if (result != DNS_R_NOMASTERFILE)
3959 dns_zone_log(zone, ISC_LOG_ERROR,
3960 "loading from master file %s "
3963 dns_result_totext(result));
3964 } else if (zone->type == dns_zone_master &&
3965 inline_secure(zone) && result == ISC_R_FILENOTFOUND)
3967 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3968 "no master file, requesting db");
3969 maybe_send_secure(zone);
3971 int level = ISC_LOG_ERROR;
3972 if (zone->type == dns_zone_key &&
3973 result == ISC_R_FILENOTFOUND)
3974 level = ISC_LOG_DEBUG(1);
3975 dns_zone_log(zone, level,
3976 "loading from master file %s failed: %s",
3978 dns_result_totext(result));
3979 nomaster = ISC_TRUE;
3982 if (zone->type != dns_zone_key)
3986 dns_zone_log(zone, ISC_LOG_DEBUG(2),
3987 "number of nodes in database: %u",
3988 dns_db_nodecount(db));
3990 if (result == DNS_R_SEENINCLUDE)
3991 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3993 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3996 * If there's no master file for a key zone, then the zone is new:
3997 * create an SOA record. (We do this now, instead of later, so that
3998 * if there happens to be a journal file, we can roll forward from
3999 * a sane starting point.)
4001 if (nomaster && zone->type == dns_zone_key) {
4002 result = add_soa(zone, db);
4003 if (result != ISC_R_SUCCESS)
4008 * Apply update log, if any, on initial load.
4010 if (zone->journal != NULL &&
4011 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
4012 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
4014 if (zone->type == dns_zone_master &&
4015 (zone->update_acl != NULL || zone->ssutable != NULL))
4016 options = DNS_JOURNALOPT_RESIGN;
4019 result = dns_journal_rollforward2(zone->mctx, db, options,
4021 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
4022 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
4023 result != ISC_R_RANGE) {
4024 dns_zone_log(zone, ISC_LOG_ERROR,
4025 "journal rollforward failed: %s",
4026 dns_result_totext(result));
4031 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
4032 dns_zone_log(zone, ISC_LOG_ERROR,
4033 "journal rollforward failed: "
4034 "journal out of sync with zone");
4037 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4038 "journal rollforward completed "
4040 dns_result_totext(result));
4041 if (result == ISC_R_SUCCESS)
4042 needdump = ISC_TRUE;
4046 * Obtain ns, soa and cname counts for top of zone.
4049 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
4050 &refresh, &retry, &expire, &minimum,
4052 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
4053 dns_zone_log(zone, ISC_LOG_ERROR,
4054 "could not find NS and/or SOA records");
4058 * Check to make sure the journal is up to date, and remove the
4059 * journal file if it isn't, as we wouldn't be able to apply
4060 * updates otherwise.
4062 if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) &&
4063 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
4064 isc_uint32_t jserial;
4065 dns_journal_t *journal = NULL;
4067 result = dns_journal_open(zone->mctx, zone->journal,
4068 DNS_JOURNAL_READ, &journal);
4069 if (result == ISC_R_SUCCESS) {
4070 jserial = dns_journal_last_serial(journal);
4071 dns_journal_destroy(&journal);
4074 result = ISC_R_SUCCESS;
4077 if (jserial != serial) {
4078 dns_zone_log(zone, ISC_LOG_INFO,
4079 "journal file is out of date: "
4080 "removing journal file");
4081 if (remove(zone->journal) < 0 && errno != ENOENT) {
4082 char strbuf[ISC_STRERRORSIZE];
4083 isc__strerror(errno, strbuf, sizeof(strbuf));
4084 isc_log_write(dns_lctx,
4085 DNS_LOGCATEGORY_GENERAL,
4088 "unable to remove journal "
4090 zone->journal, strbuf);
4095 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
4098 * Master / Slave / Stub zones require both NS and SOA records at
4099 * the top of the zone.
4102 switch (zone->type) {
4104 case dns_zone_master:
4105 case dns_zone_slave:
4107 case dns_zone_redirect:
4108 if (soacount != 1) {
4109 dns_zone_log(zone, ISC_LOG_ERROR,
4110 "has %d SOA records", soacount);
4111 result = DNS_R_BADZONE;
4114 dns_zone_log(zone, ISC_LOG_ERROR,
4115 "has no NS records");
4116 result = DNS_R_BADZONE;
4118 if (result != ISC_R_SUCCESS)
4120 if (zone->type == dns_zone_master && errors != 0) {
4121 result = DNS_R_BADZONE;
4124 if (zone->type != dns_zone_stub &&
4125 zone->type != dns_zone_redirect) {
4126 result = check_nsec3param(zone, db);
4127 if (result != ISC_R_SUCCESS)
4130 if (zone->type == dns_zone_master &&
4131 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
4132 !integrity_checks(zone, db)) {
4133 result = DNS_R_BADZONE;
4136 if (zone->type == dns_zone_master &&
4137 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
4138 !zone_check_dup(zone, db)) {
4139 result = DNS_R_BADZONE;
4143 if (zone->db != NULL) {
4144 unsigned int oldsoacount;
4147 * This is checked in zone_replacedb() for slave zones
4148 * as they don't reload from disk.
4150 result = zone_get_from_db(zone, zone->db, NULL,
4151 &oldsoacount, &oldserial,
4152 NULL, NULL, NULL, NULL,
4154 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4155 RUNTIME_CHECK(soacount > 0U);
4156 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
4157 !isc_serial_gt(serial, oldserial)) {
4158 isc_uint32_t serialmin, serialmax;
4160 INSIST(zone->type == dns_zone_master);
4162 if (serial == oldserial &&
4163 zone_unchanged(zone->db, db, zone->mctx)) {
4164 dns_zone_log(zone, ISC_LOG_INFO,
4165 "ixfr-from-differences: "
4167 return(ISC_R_SUCCESS);
4170 serialmin = (oldserial + 1) & 0xffffffffU;
4171 serialmax = (oldserial + 0x7fffffffU) &
4173 dns_zone_log(zone, ISC_LOG_ERROR,
4174 "ixfr-from-differences: "
4175 "new serial (%u) out of range "
4176 "[%u - %u]", serial, serialmin,
4178 result = DNS_R_BADZONE;
4180 } else if (!isc_serial_ge(serial, oldserial))
4181 dns_zone_log(zone, ISC_LOG_ERROR,
4182 "zone serial (%u/%u) has gone "
4183 "backwards", serial, oldserial);
4184 else if (serial == oldserial && !hasinclude &&
4185 strcmp(zone->db_argv[0], "_builtin") != 0)
4186 dns_zone_log(zone, ISC_LOG_ERROR,
4187 "zone serial (%u) unchanged. "
4188 "zone may fail to transfer "
4189 "to slaves.", serial);
4192 if (zone->type == dns_zone_master &&
4193 (zone->update_acl != NULL || zone->ssutable != NULL) &&
4194 zone->sigresigninginterval < (3 * refresh) &&
4195 dns_db_issecure(db))
4197 dns_zone_log(zone, ISC_LOG_WARNING,
4198 "sig-re-signing-interval less than "
4202 zone->refresh = RANGE(refresh,
4203 zone->minrefresh, zone->maxrefresh);
4204 zone->retry = RANGE(retry,
4205 zone->minretry, zone->maxretry);
4206 zone->expire = RANGE(expire, zone->refresh + zone->retry,
4208 zone->minimum = minimum;
4209 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
4211 if (zone->type == dns_zone_slave ||
4212 zone->type == dns_zone_stub ||
4213 (zone->type == dns_zone_redirect &&
4214 zone->masters != NULL)) {
4218 result = isc_file_getmodtime(zone->journal, &t);
4219 if (result != ISC_R_SUCCESS)
4220 result = isc_file_getmodtime(zone->masterfile,
4222 if (result == ISC_R_SUCCESS)
4223 DNS_ZONE_TIME_ADD(&t, zone->expire,
4226 DNS_ZONE_TIME_ADD(&now, zone->retry,
4229 delay = isc_random_jitter(zone->retry,
4230 (zone->retry * 3) / 4);
4231 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
4232 if (isc_time_compare(&zone->refreshtime,
4233 &zone->expiretime) >= 0)
4234 zone->refreshtime = now;
4240 result = sync_keyzone(zone, db);
4241 if (result != ISC_R_SUCCESS)
4246 UNEXPECTED_ERROR(__FILE__, __LINE__,
4247 "unexpected zone type %d", zone->type);
4248 result = ISC_R_UNEXPECTED;
4253 * Check for weak DNSKEY's.
4255 if (zone->type == dns_zone_master)
4256 zone_check_dnskeys(zone, db);
4259 * Schedule DNSSEC key refresh.
4261 if (zone->type == dns_zone_master &&
4262 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
4263 zone->refreshkeytime = now;
4266 /* destroy notification example. */
4268 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
4269 DNS_EVENT_DBDESTROYED,
4270 dns_zonemgr_dbdestroyed,
4272 sizeof(isc_event_t));
4273 dns_db_ondestroy(db, zone->task, &e);
4277 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4278 if (zone->db != NULL) {
4279 result = zone_replacedb(zone, db, ISC_FALSE);
4280 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4281 if (result != ISC_R_SUCCESS)
4284 zone_attachdb(zone, db);
4285 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4286 DNS_ZONE_SETFLAG(zone,
4288 DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
4289 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
4292 if (zone->secure->db == NULL)
4293 zone_send_securedb(zone, db);
4295 zone_send_secureserial(zone, serial);
4300 * Finished loading inline-signing zone; need to get status
4301 * from the raw side now.
4303 if (zone->type == dns_zone_master && inline_secure(zone))
4304 maybe_send_secure(zone);
4307 result = ISC_R_SUCCESS;
4310 if (zone->type == dns_zone_key)
4311 zone_needdump(zone, 30);
4313 zone_needdump(zone, DNS_DUMP_DELAY);
4316 if (zone->task != NULL) {
4317 if (zone->type == dns_zone_master) {
4318 set_resigntime(zone);
4319 resume_signingwithkey(zone);
4320 resume_addnsec3chain(zone);
4323 if (zone->type == dns_zone_master &&
4324 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
4325 dns_zone_isdynamic(zone, ISC_FALSE) &&
4326 dns_db_issecure(db)) {
4328 dns_fixedname_t fixed;
4329 dns_rdataset_t next;
4331 dns_rdataset_init(&next);
4332 dns_fixedname_init(&fixed);
4333 name = dns_fixedname_name(&fixed);
4335 result = dns_db_getsigningtime(db, &next, name);
4336 if (result == ISC_R_SUCCESS) {
4337 isc_stdtime_t timenow;
4338 char namebuf[DNS_NAME_FORMATSIZE];
4339 char typebuf[DNS_RDATATYPE_FORMATSIZE];
4341 isc_stdtime_get(&timenow);
4342 dns_name_format(name, namebuf, sizeof(namebuf));
4343 dns_rdatatype_format(next.covers,
4344 typebuf, sizeof(typebuf));
4345 dns_zone_log(zone, ISC_LOG_DEBUG(3),
4346 "next resign: %s/%s in %d seconds",
4348 next.resign - timenow -
4349 zone->sigresigninginterval);
4350 dns_rdataset_disassociate(&next);
4352 dns_zone_log(zone, ISC_LOG_WARNING,
4353 "signed dynamic zone has no "
4354 "resign event scheduled");
4357 zone_settimer(zone, &now);
4360 if (! dns_db_ispersistent(db))
4361 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
4362 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
4364 zone->loadtime = loadtime;
4365 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
4369 if (zone->type == dns_zone_slave ||
4370 zone->type == dns_zone_stub ||
4371 zone->type == dns_zone_key ||
4372 (zone->type == dns_zone_redirect && zone->masters != NULL)) {
4373 if (result != ISC_R_NOMEMORY) {
4374 if (zone->journal != NULL)
4375 zone_saveunique(zone, zone->journal,
4377 if (zone->masterfile != NULL)
4378 zone_saveunique(zone, zone->masterfile,
4382 /* Mark the zone for immediate refresh. */
4383 zone->refreshtime = now;
4384 if (zone->task != NULL)
4385 zone_settimer(zone, &now);
4386 result = ISC_R_SUCCESS;
4387 } else if (zone->type == dns_zone_master ||
4388 zone->type == dns_zone_redirect) {
4389 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND))
4390 dns_zone_log(zone, ISC_LOG_ERROR,
4391 "not loaded due to errors.");
4392 else if (zone->type == dns_zone_master)
4393 result = ISC_R_SUCCESS;
4399 static isc_boolean_t
4400 exit_check(dns_zone_t *zone) {
4401 REQUIRE(LOCKED_ZONE(zone));
4403 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) {
4405 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
4407 INSIST(isc_refcount_current(&zone->erefs) == 0);
4413 static isc_boolean_t
4414 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
4415 dns_name_t *name, isc_boolean_t logit)
4417 isc_result_t result;
4418 char namebuf[DNS_NAME_FORMATSIZE];
4419 char altbuf[DNS_NAME_FORMATSIZE];
4420 dns_fixedname_t fixed;
4421 dns_name_t *foundname;
4424 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
4427 if (zone->type == dns_zone_master)
4428 level = ISC_LOG_ERROR;
4430 level = ISC_LOG_WARNING;
4432 dns_fixedname_init(&fixed);
4433 foundname = dns_fixedname_name(&fixed);
4435 result = dns_db_find(db, name, version, dns_rdatatype_a,
4436 0, 0, NULL, foundname, NULL, NULL);
4437 if (result == ISC_R_SUCCESS)
4440 if (result == DNS_R_NXRRSET) {
4441 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
4442 0, 0, NULL, foundname, NULL, NULL);
4443 if (result == ISC_R_SUCCESS)
4447 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
4448 result == DNS_R_EMPTYNAME) {
4450 dns_name_format(name, namebuf, sizeof namebuf);
4451 dns_zone_log(zone, level, "NS '%s' has no address "
4452 "records (A or AAAA)", namebuf);
4457 if (result == DNS_R_CNAME) {
4459 dns_name_format(name, namebuf, sizeof namebuf);
4460 dns_zone_log(zone, level, "NS '%s' is a CNAME "
4461 "(illegal)", namebuf);
4466 if (result == DNS_R_DNAME) {
4468 dns_name_format(name, namebuf, sizeof namebuf);
4469 dns_name_format(foundname, altbuf, sizeof altbuf);
4470 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
4471 "'%s' (illegal)", namebuf, altbuf);
4480 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
4481 dns_dbversion_t *version, unsigned int *nscount,
4482 unsigned int *errors, isc_boolean_t logit)
4484 isc_result_t result;
4485 unsigned int count = 0;
4486 unsigned int ecount = 0;
4487 dns_rdataset_t rdataset;
4491 dns_rdataset_init(&rdataset);
4492 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
4493 dns_rdatatype_none, 0, &rdataset, NULL);
4494 if (result == ISC_R_NOTFOUND) {
4495 INSIST(!dns_rdataset_isassociated(&rdataset));
4498 if (result != ISC_R_SUCCESS) {
4499 INSIST(!dns_rdataset_isassociated(&rdataset));
4500 goto invalidate_rdataset;
4503 result = dns_rdataset_first(&rdataset);
4504 while (result == ISC_R_SUCCESS) {
4505 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
4506 (zone->type == dns_zone_master ||
4507 zone->type == dns_zone_slave)) {
4508 dns_rdata_init(&rdata);
4509 dns_rdataset_current(&rdataset, &rdata);
4510 result = dns_rdata_tostruct(&rdata, &ns, NULL);
4511 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4512 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
4513 !zone_check_ns(zone, db, version, &ns.name, logit))
4517 result = dns_rdataset_next(&rdataset);
4519 dns_rdataset_disassociate(&rdataset);
4522 if (nscount != NULL)
4527 result = ISC_R_SUCCESS;
4529 invalidate_rdataset:
4530 dns_rdataset_invalidate(&rdataset);
4536 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4537 unsigned int *soacount,
4538 isc_uint32_t *serial, isc_uint32_t *refresh,
4539 isc_uint32_t *retry, isc_uint32_t *expire,
4540 isc_uint32_t *minimum)
4542 isc_result_t result;
4544 dns_rdataset_t rdataset;
4545 dns_rdata_t rdata = DNS_RDATA_INIT;
4546 dns_rdata_soa_t soa;
4548 dns_rdataset_init(&rdataset);
4549 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
4550 dns_rdatatype_none, 0, &rdataset, NULL);
4551 if (result == ISC_R_NOTFOUND) {
4552 INSIST(!dns_rdataset_isassociated(&rdataset));
4553 if (soacount != NULL)
4557 if (refresh != NULL)
4563 if (minimum != NULL)
4565 result = ISC_R_SUCCESS;
4566 goto invalidate_rdataset;
4568 if (result != ISC_R_SUCCESS) {
4569 INSIST(!dns_rdataset_isassociated(&rdataset));
4570 goto invalidate_rdataset;
4574 result = dns_rdataset_first(&rdataset);
4575 while (result == ISC_R_SUCCESS) {
4576 dns_rdata_init(&rdata);
4577 dns_rdataset_current(&rdataset, &rdata);
4580 result = dns_rdata_tostruct(&rdata, &soa, NULL);
4581 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4584 result = dns_rdataset_next(&rdataset);
4585 dns_rdata_reset(&rdata);
4587 dns_rdataset_disassociate(&rdataset);
4589 if (soacount != NULL)
4594 *serial = soa.serial;
4595 if (refresh != NULL)
4596 *refresh = soa.refresh;
4600 *expire = soa.expire;
4601 if (minimum != NULL)
4602 *minimum = soa.minimum;
4604 if (soacount != NULL)
4608 if (refresh != NULL)
4614 if (minimum != NULL)
4618 result = ISC_R_SUCCESS;
4620 invalidate_rdataset:
4621 dns_rdataset_invalidate(&rdataset);
4627 * zone must be locked.
4630 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
4631 unsigned int *soacount, isc_uint32_t *serial,
4632 isc_uint32_t *refresh, isc_uint32_t *retry,
4633 isc_uint32_t *expire, isc_uint32_t *minimum,
4634 unsigned int *errors)
4636 isc_result_t result;
4637 isc_result_t answer = ISC_R_SUCCESS;
4638 dns_dbversion_t *version = NULL;
4641 REQUIRE(db != NULL);
4642 REQUIRE(zone != NULL);
4644 dns_db_currentversion(db, &version);
4646 if (nscount != NULL)
4648 if (soacount != NULL)
4652 if (refresh != NULL)
4662 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
4663 if (result != ISC_R_SUCCESS) {
4668 if (nscount != NULL || errors != NULL) {
4669 result = zone_count_ns_rr(zone, db, node, version,
4670 nscount, errors, ISC_TRUE);
4671 if (result != ISC_R_SUCCESS)
4675 if (soacount != NULL || serial != NULL || refresh != NULL
4676 || retry != NULL || expire != NULL || minimum != NULL) {
4677 result = zone_load_soa_rr(db, node, version, soacount,
4678 serial, refresh, retry, expire,
4680 if (result != ISC_R_SUCCESS)
4684 dns_db_detachnode(db, &node);
4686 dns_db_closeversion(db, &version, ISC_FALSE);
4692 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
4693 REQUIRE(DNS_ZONE_VALID(source));
4694 REQUIRE(target != NULL && *target == NULL);
4695 isc_refcount_increment(&source->erefs, NULL);
4700 dns_zone_detach(dns_zone_t **zonep) {
4702 dns_zone_t *raw = NULL;
4703 dns_zone_t *secure = NULL;
4705 isc_boolean_t free_now = ISC_FALSE;
4707 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4711 isc_refcount_decrement(&zone->erefs, &refs);
4716 * We just detached the last external reference.
4718 if (zone->task != NULL) {
4720 * This zone is being managed. Post
4721 * its control event and let it clean
4722 * up synchronously in the context of
4725 isc_event_t *ev = &zone->ctlevent;
4726 isc_task_send(zone->task, &ev);
4729 * This zone is not being managed; it has
4730 * no task and can have no outstanding
4731 * events. Free it immediately.
4734 * Unmanaged zones should not have non-null views;
4735 * we have no way of detaching from the view here
4736 * without causing deadlock because this code is called
4737 * with the view already locked.
4739 INSIST(zone->view == NULL);
4740 free_now = ISC_TRUE;
4743 secure = zone->secure;
4744 zone->secure = NULL;
4751 dns_zone_detach(&raw);
4753 dns_zone_idetach(&secure);
4759 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4760 REQUIRE(DNS_ZONE_VALID(source));
4761 REQUIRE(target != NULL && *target == NULL);
4763 zone_iattach(source, target);
4764 UNLOCK_ZONE(source);
4768 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4771 * 'source' locked by caller.
4773 REQUIRE(LOCKED_ZONE(source));
4774 REQUIRE(DNS_ZONE_VALID(source));
4775 REQUIRE(target != NULL && *target == NULL);
4776 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
4778 INSIST(source->irefs != 0);
4783 zone_idetach(dns_zone_t **zonep) {
4787 * 'zone' locked by caller.
4789 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4791 REQUIRE(LOCKED_ZONE(*zonep));
4794 INSIST(zone->irefs > 0);
4796 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
4800 dns_zone_idetach(dns_zone_t **zonep) {
4802 isc_boolean_t free_needed;
4804 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4809 INSIST(zone->irefs > 0);
4811 free_needed = exit_check(zone);
4818 dns_zone_getmctx(dns_zone_t *zone) {
4819 REQUIRE(DNS_ZONE_VALID(zone));
4821 return (zone->mctx);
4825 dns_zone_getmgr(dns_zone_t *zone) {
4826 REQUIRE(DNS_ZONE_VALID(zone));
4828 return (zone->zmgr);
4832 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
4833 REQUIRE(DNS_ZONE_VALID(zone));
4837 DNS_ZONE_SETFLAG(zone, flags);
4839 DNS_ZONE_CLRFLAG(zone, flags);
4844 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
4846 REQUIRE(DNS_ZONE_VALID(zone));
4850 zone->options |= option;
4852 zone->options &= ~option;
4857 dns_zone_getoptions(dns_zone_t *zone) {
4859 REQUIRE(DNS_ZONE_VALID(zone));
4861 return (zone->options);
4865 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
4867 REQUIRE(DNS_ZONE_VALID(zone));
4871 zone->keyopts |= keyopt;
4873 zone->keyopts &= ~keyopt;
4878 dns_zone_getkeyopts(dns_zone_t *zone) {
4880 REQUIRE(DNS_ZONE_VALID(zone));
4882 return (zone->keyopts);
4886 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4887 REQUIRE(DNS_ZONE_VALID(zone));
4890 zone->xfrsource4 = *xfrsource;
4893 return (ISC_R_SUCCESS);
4897 dns_zone_getxfrsource4(dns_zone_t *zone) {
4898 REQUIRE(DNS_ZONE_VALID(zone));
4899 return (&zone->xfrsource4);
4903 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4904 REQUIRE(DNS_ZONE_VALID(zone));
4907 zone->xfrsource6 = *xfrsource;
4910 return (ISC_R_SUCCESS);
4914 dns_zone_getxfrsource6(dns_zone_t *zone) {
4915 REQUIRE(DNS_ZONE_VALID(zone));
4916 return (&zone->xfrsource6);
4920 dns_zone_setaltxfrsource4(dns_zone_t *zone,
4921 const isc_sockaddr_t *altxfrsource)
4923 REQUIRE(DNS_ZONE_VALID(zone));
4926 zone->altxfrsource4 = *altxfrsource;
4929 return (ISC_R_SUCCESS);
4933 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
4934 REQUIRE(DNS_ZONE_VALID(zone));
4935 return (&zone->altxfrsource4);
4939 dns_zone_setaltxfrsource6(dns_zone_t *zone,
4940 const isc_sockaddr_t *altxfrsource)
4942 REQUIRE(DNS_ZONE_VALID(zone));
4945 zone->altxfrsource6 = *altxfrsource;
4948 return (ISC_R_SUCCESS);
4952 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
4953 REQUIRE(DNS_ZONE_VALID(zone));
4954 return (&zone->altxfrsource6);
4958 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4959 REQUIRE(DNS_ZONE_VALID(zone));
4962 zone->notifysrc4 = *notifysrc;
4965 return (ISC_R_SUCCESS);
4969 dns_zone_getnotifysrc4(dns_zone_t *zone) {
4970 REQUIRE(DNS_ZONE_VALID(zone));
4971 return (&zone->notifysrc4);
4975 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4976 REQUIRE(DNS_ZONE_VALID(zone));
4979 zone->notifysrc6 = *notifysrc;
4982 return (ISC_R_SUCCESS);
4986 dns_zone_getnotifysrc6(dns_zone_t *zone) {
4987 REQUIRE(DNS_ZONE_VALID(zone));
4988 return (&zone->notifysrc6);
4991 static isc_boolean_t
4992 same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
4997 for (i = 0; i < count; i++)
4998 if (!isc_sockaddr_equal(&old[i], &new[i]))
5003 static isc_boolean_t
5004 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
5007 if (old == NULL && new == NULL)
5009 if (old == NULL || new == NULL)
5012 for (i = 0; i < count; i++) {
5013 if (old[i] == NULL && new[i] == NULL)
5015 if (old[i] == NULL || new[i] == NULL ||
5016 !dns_name_equal(old[i], new[i]))
5023 clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp,
5024 unsigned int *countp, isc_mem_t *mctx)
5027 isc_sockaddr_t *addrs;
5028 dns_name_t **keynames;
5030 REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL);
5036 keynames = *keynamesp;
5040 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
5042 if (keynames != NULL) {
5044 for (i = 0; i < count; i++) {
5045 if (keynames[i] != NULL) {
5046 dns_name_free(keynames[i], mctx);
5047 isc_mem_put(mctx, keynames[i],
5048 sizeof(dns_name_t));
5052 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
5057 set_addrkeylist(unsigned int count,
5058 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
5059 dns_name_t **names, dns_name_t ***newnamesp,
5062 isc_result_t result;
5063 isc_sockaddr_t *newaddrs = NULL;
5064 dns_name_t **newnames = NULL;
5067 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
5068 REQUIRE(newnamesp != NULL && *newnamesp == NULL);
5070 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
5071 if (newaddrs == NULL)
5072 return (ISC_R_NOMEMORY);
5073 memmove(newaddrs, addrs, count * sizeof(*newaddrs));
5076 if (names != NULL) {
5077 newnames = isc_mem_get(mctx, count * sizeof(*newnames));
5078 if (newnames == NULL) {
5079 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
5080 return (ISC_R_NOMEMORY);
5082 for (i = 0; i < count; i++)
5084 for (i = 0; i < count; i++) {
5085 if (names[i] != NULL) {
5086 newnames[i] = isc_mem_get(mctx,
5087 sizeof(dns_name_t));
5088 if (newnames[i] == NULL)
5090 dns_name_init(newnames[i], NULL);
5091 result = dns_name_dup(names[i], mctx,
5093 if (result != ISC_R_SUCCESS) {
5095 for (i = 0; i < count; i++)
5096 if (newnames[i] != NULL)
5100 isc_mem_put(mctx, newaddrs,
5101 count * sizeof(*newaddrs));
5102 isc_mem_put(mctx, newnames,
5103 count * sizeof(*newnames));
5104 return (ISC_R_NOMEMORY);
5110 *newaddrsp = newaddrs;
5111 *newnamesp = newnames;
5112 return (ISC_R_SUCCESS);
5116 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
5119 return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count));
5123 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
5124 dns_name_t **keynames, isc_uint32_t count)
5126 isc_result_t result;
5127 isc_sockaddr_t *newaddrs = NULL;
5128 dns_name_t **newnames = NULL;
5130 REQUIRE(DNS_ZONE_VALID(zone));
5131 REQUIRE(count == 0 || notify != NULL);
5132 if (keynames != NULL)
5133 REQUIRE(count != 0);
5137 if (count == zone->notifycnt &&
5138 same_addrs(zone->notify, notify, count) &&
5139 same_keynames(zone->notifykeynames, keynames, count))
5142 clear_addresskeylist(&zone->notify, &zone->notifykeynames,
5143 &zone->notifycnt, zone->mctx);
5149 * Set up the notify and notifykey lists
5151 result = set_addrkeylist(count, notify, &newaddrs,
5152 keynames, &newnames, zone->mctx);
5153 if (result != ISC_R_SUCCESS)
5157 * Everything is ok so attach to the zone.
5159 zone->notify = newaddrs;
5160 zone->notifykeynames = newnames;
5161 zone->notifycnt = count;
5164 return (ISC_R_SUCCESS);
5168 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
5171 isc_result_t result;
5173 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
5178 dns_zone_setmasterswithkeys(dns_zone_t *zone,
5179 const isc_sockaddr_t *masters,
5180 dns_name_t **keynames,
5183 isc_result_t result = ISC_R_SUCCESS;
5184 isc_sockaddr_t *newaddrs = NULL;
5185 dns_name_t **newnames = NULL;
5186 isc_boolean_t *newok;
5189 REQUIRE(DNS_ZONE_VALID(zone));
5190 REQUIRE(count == 0 || masters != NULL);
5191 if (keynames != NULL) {
5192 REQUIRE(count != 0);
5197 * The refresh code assumes that 'masters' wouldn't change under it.
5198 * If it will change then kill off any current refresh in progress
5199 * and update the masters info. If it won't change then we can just
5202 if (count != zone->masterscnt ||
5203 !same_addrs(zone->masters, masters, count) ||
5204 !same_keynames(zone->masterkeynames, keynames, count)) {
5205 if (zone->request != NULL)
5206 dns_request_cancel(zone->request);
5211 * This needs to happen before clear_addresskeylist() sets
5212 * zone->masterscnt to 0:
5214 if (zone->mastersok != NULL) {
5215 isc_mem_put(zone->mctx, zone->mastersok,
5216 zone->masterscnt * sizeof(isc_boolean_t));
5217 zone->mastersok = NULL;
5219 clear_addresskeylist(&zone->masters, &zone->masterkeynames,
5220 &zone->masterscnt, zone->mctx);
5222 * If count == 0, don't allocate any space for masters, mastersok or
5223 * keynames so internally, those pointers are NULL if count == 0
5229 * mastersok must contain count elements
5231 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
5232 if (newok == NULL) {
5233 result = ISC_R_NOMEMORY;
5234 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
5237 for (i = 0; i < count; i++)
5238 newok[i] = ISC_FALSE;
5241 * Now set up the masters and masterkey lists
5243 result = set_addrkeylist(count, masters, &newaddrs,
5244 keynames, &newnames, zone->mctx);
5245 if (result != ISC_R_SUCCESS) {
5246 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
5251 * Everything is ok so attach to the zone.
5253 zone->curmaster = 0;
5254 zone->mastersok = newok;
5255 zone->masters = newaddrs;
5256 zone->masterkeynames = newnames;
5257 zone->masterscnt = count;
5258 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
5266 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
5267 isc_result_t result = ISC_R_SUCCESS;
5269 REQUIRE(DNS_ZONE_VALID(zone));
5271 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5272 if (zone->db == NULL)
5273 result = DNS_R_NOTLOADED;
5275 dns_db_attach(zone->db, dpb);
5276 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5282 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
5283 REQUIRE(DNS_ZONE_VALID(zone));
5284 REQUIRE(zone->type == dns_zone_staticstub);
5286 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
5287 REQUIRE(zone->db == NULL);
5288 dns_db_attach(db, &zone->db);
5289 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
5293 * Co-ordinates the starting of routine jobs.
5297 dns_zone_maintenance(dns_zone_t *zone) {
5298 const char me[] = "dns_zone_maintenance";
5301 REQUIRE(DNS_ZONE_VALID(zone));
5306 zone_settimer(zone, &now);
5310 static inline isc_boolean_t
5311 was_dumping(dns_zone_t *zone) {
5312 isc_boolean_t dumping;
5314 REQUIRE(LOCKED_ZONE(zone));
5316 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
5317 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
5319 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
5320 isc_time_settoepoch(&zone->dumptime);
5326 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
5327 isc_mem_t *mctx, unsigned int maxkeys,
5328 dst_key_t **keys, unsigned int *nkeys)
5330 isc_result_t result;
5331 dns_dbnode_t *node = NULL;
5332 const char *directory = dns_zone_getkeydirectory(zone);
5334 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
5335 memset(keys, 0, sizeof(*keys) * maxkeys);
5336 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
5337 directory, mctx, maxkeys, keys,
5339 if (result == ISC_R_NOTFOUND)
5340 result = ISC_R_SUCCESS;
5343 dns_db_detachnode(db, &node);
5348 offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
5349 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
5351 isc_result_t result;
5353 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
5354 return (ISC_R_SUCCESS);
5355 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
5357 if (result != ISC_R_SUCCESS)
5359 rdata->flags |= DNS_RDATA_OFFLINE;
5360 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
5362 zonediff->offline = ISC_TRUE;
5367 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
5372 zone->key_expiry = when;
5374 dns_zone_log(zone, ISC_LOG_ERROR,
5375 "DNSKEY RRSIG(s) have expired");
5376 isc_time_settoepoch(&zone->keywarntime);
5377 } else if (when < now + 7 * 24 * 3600) {
5379 isc_time_set(&t, when, 0);
5380 isc_time_formattimestamp(&t, timebuf, 80);
5381 dns_zone_log(zone, ISC_LOG_WARNING,
5382 "DNSKEY RRSIG(s) will expire within 7 days: %s",
5385 delta--; /* loop prevention */
5386 delta /= 24 * 3600; /* to whole days */
5387 delta *= 24 * 3600; /* to seconds */
5388 isc_time_set(&zone->keywarntime, when - delta, 0);
5390 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
5391 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
5392 dns_zone_log(zone, ISC_LOG_NOTICE,
5393 "setting keywarntime to %s", timebuf);
5398 * Helper function to del_sigs(). We don't want to delete RRSIGs that
5401 static isc_boolean_t
5402 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
5403 isc_boolean_t *warn)
5406 isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE;
5407 isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE;
5409 for (i = 0; i < nkeys; i++) {
5410 if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
5412 if (dst_key_isprivate(keys[i])) {
5414 have_ksk = have_pksk = ISC_TRUE;
5416 have_zsk = have_pzsk = ISC_TRUE;
5419 have_ksk = ISC_TRUE;
5421 have_zsk = ISC_TRUE;
5425 if (have_zsk && have_ksk && !have_pzsk)
5429 * It's okay to delete a signature if there is an active key
5430 * with the same algorithm to replace it.
5432 if (have_pksk || have_pzsk)
5436 * Failing that, it is *not* okay to delete a signature
5437 * if the associated public key is still in the DNSKEY RRset
5439 for (i = 0; i < nkeys; i++) {
5440 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
5441 (rrsig_ptr->keyid == dst_key_id(keys[i])))
5446 * But if the key is gone, then go ahead.
5452 * Delete expired RRsigs and any RRsigs we are about to re-sign.
5453 * See also update.c:del_keysigs().
5456 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5457 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
5458 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
5460 isc_result_t result;
5461 dns_dbnode_t *node = NULL;
5462 dns_rdataset_t rdataset;
5464 dns_rdata_rrsig_t rrsig;
5465 isc_boolean_t found;
5466 isc_int64_t timewarn = 0, timemaybe = 0;
5468 dns_rdataset_init(&rdataset);
5470 if (type == dns_rdatatype_nsec3)
5471 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5473 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5474 if (result == ISC_R_NOTFOUND)
5475 return (ISC_R_SUCCESS);
5476 if (result != ISC_R_SUCCESS)
5478 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
5479 (isc_stdtime_t) 0, &rdataset, NULL);
5480 dns_db_detachnode(db, &node);
5482 if (result == ISC_R_NOTFOUND) {
5483 INSIST(!dns_rdataset_isassociated(&rdataset));
5484 return (ISC_R_SUCCESS);
5486 if (result != ISC_R_SUCCESS) {
5487 INSIST(!dns_rdataset_isassociated(&rdataset));
5491 for (result = dns_rdataset_first(&rdataset);
5492 result == ISC_R_SUCCESS;
5493 result = dns_rdataset_next(&rdataset)) {
5494 dns_rdata_t rdata = DNS_RDATA_INIT;
5496 dns_rdataset_current(&rdataset, &rdata);
5497 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5498 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5500 if (type != dns_rdatatype_dnskey) {
5501 isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE;
5502 if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
5503 result = update_one_rr(db, ver, zonediff->diff,
5504 DNS_DIFFOP_DELRESIGN, name,
5505 rdataset.ttl, &rdata);
5506 if (result != ISC_R_SUCCESS)
5512 * At this point, we've got an RRSIG,
5513 * which is signed by an inactive key.
5514 * An administrator needs to provide a new
5515 * key/alg, but until that time, we want to
5516 * keep the old RRSIG. Marking the key as
5517 * offline will prevent us spinning waiting
5518 * for the private part.
5520 if (incremental && !deleted) {
5521 result = offline(db, ver, zonediff,
5524 if (result != ISC_R_SUCCESS)
5529 * Log the key id and algorithm of
5530 * the inactive key with no replacement
5532 if (zone->log_key_expired_timer <= now) {
5533 char origin[DNS_NAME_FORMATSIZE];
5534 char algbuf[DNS_NAME_FORMATSIZE];
5535 dns_name_format(&zone->origin, origin,
5537 dns_secalg_format(rrsig.algorithm,
5540 dns_zone_log(zone, ISC_LOG_WARNING,
5542 "missing or inactive "
5543 "and has no replacement: "
5544 "retaining signatures.",
5547 zone->log_key_expired_timer = now +
5555 * RRSIG(DNSKEY) requires special processing.
5558 for (i = 0; i < nkeys; i++) {
5559 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
5560 rrsig.keyid == dst_key_id(keys[i])) {
5563 * Mark offline RRSIG(DNSKEY).
5564 * We want the earliest offline expire time
5565 * iff there is a new offline signature.
5567 if (!dst_key_inactive(keys[i]) &&
5568 !dst_key_isprivate(keys[i]))
5570 isc_int64_t timeexpire =
5571 dns_time64_from32(rrsig.timeexpire);
5572 if (timewarn != 0 &&
5573 timewarn > timeexpire)
5574 timewarn = timeexpire;
5575 if (rdata.flags & DNS_RDATA_OFFLINE) {
5576 if (timemaybe == 0 ||
5577 timemaybe > timeexpire)
5578 timemaybe = timeexpire;
5582 timewarn = timemaybe;
5583 if (timewarn == 0 ||
5584 timewarn > timeexpire)
5585 timewarn = timeexpire;
5586 result = offline(db, ver, zonediff,
5591 result = update_one_rr(db, ver, zonediff->diff,
5592 DNS_DIFFOP_DELRESIGN,
5600 * If there is not a matching DNSKEY then
5604 result = update_one_rr(db, ver, zonediff->diff,
5605 DNS_DIFFOP_DELRESIGN, name,
5606 rdataset.ttl, &rdata);
5607 if (result != ISC_R_SUCCESS)
5611 dns_rdataset_disassociate(&rdataset);
5612 if (result == ISC_R_NOMORE)
5613 result = ISC_R_SUCCESS;
5615 #if defined(STDTIME_ON_32BITS)
5616 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
5617 if (timewarn == stdwarn)
5619 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
5621 #if defined(STDTIME_ON_32BITS)
5623 dns_zone_log(zone, ISC_LOG_ERROR,
5624 "key expiry warning time out of range");
5629 dns_db_detachnode(db, &node);
5634 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5635 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
5636 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
5637 isc_stdtime_t expire, isc_boolean_t check_ksk,
5638 isc_boolean_t keyset_kskonly)
5640 isc_result_t result;
5641 dns_dbnode_t *node = NULL;
5642 dns_rdataset_t rdataset;
5643 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
5644 unsigned char data[1024]; /* XXX */
5645 isc_buffer_t buffer;
5648 dns_rdataset_init(&rdataset);
5649 isc_buffer_init(&buffer, data, sizeof(data));
5651 if (type == dns_rdatatype_nsec3)
5652 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5654 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5655 if (result == ISC_R_NOTFOUND)
5656 return (ISC_R_SUCCESS);
5657 if (result != ISC_R_SUCCESS)
5659 result = dns_db_findrdataset(db, node, ver, type, 0,
5660 (isc_stdtime_t) 0, &rdataset, NULL);
5661 dns_db_detachnode(db, &node);
5662 if (result == ISC_R_NOTFOUND) {
5663 INSIST(!dns_rdataset_isassociated(&rdataset));
5664 return (ISC_R_SUCCESS);
5666 if (result != ISC_R_SUCCESS) {
5667 INSIST(!dns_rdataset_isassociated(&rdataset));
5671 for (i = 0; i < nkeys; i++) {
5672 isc_boolean_t both = ISC_FALSE;
5674 if (!dst_key_isprivate(keys[i]))
5677 if (check_ksk && !REVOKE(keys[i])) {
5678 isc_boolean_t have_ksk, have_nonksk;
5680 have_ksk = ISC_TRUE;
5681 have_nonksk = ISC_FALSE;
5683 have_ksk = ISC_FALSE;
5684 have_nonksk = ISC_TRUE;
5686 for (j = 0; j < nkeys; j++) {
5687 if (j == i || ALG(keys[i]) != ALG(keys[j]))
5689 if (REVOKE(keys[j]))
5692 have_ksk = ISC_TRUE;
5694 have_nonksk = ISC_TRUE;
5695 both = have_ksk && have_nonksk;
5701 if (type == dns_rdatatype_dnskey) {
5702 if (!KSK(keys[i]) && keyset_kskonly)
5704 } else if (KSK(keys[i]))
5706 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
5709 /* Calculate the signature, creating a RRSIG RDATA. */
5710 isc_buffer_clear(&buffer);
5711 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
5712 &inception, &expire,
5713 mctx, &buffer, &sig_rdata));
5714 /* Update the database and journal with the RRSIG. */
5715 /* XXX inefficient - will cause dataset merging */
5716 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
5717 name, rdataset.ttl, &sig_rdata));
5718 dns_rdata_reset(&sig_rdata);
5719 isc_buffer_init(&buffer, data, sizeof(data));
5723 if (dns_rdataset_isassociated(&rdataset))
5724 dns_rdataset_disassociate(&rdataset);
5726 dns_db_detachnode(db, &node);
5731 zone_resigninc(dns_zone_t *zone) {
5732 const char *me = "zone_resigninc";
5733 dns_db_t *db = NULL;
5734 dns_dbversion_t *version = NULL;
5735 dns_diff_t _sig_diff;
5736 zonediff_t zonediff;
5737 dns_fixedname_t fixed;
5739 dns_rdataset_t rdataset;
5740 dns_rdatatype_t covers;
5741 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
5742 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
5743 isc_result_t result;
5744 isc_stdtime_t now, inception, soaexpire, expire, stop;
5745 isc_uint32_t jitter;
5747 unsigned int nkeys = 0;
5748 unsigned int resign;
5752 dns_rdataset_init(&rdataset);
5753 dns_fixedname_init(&fixed);
5754 dns_diff_init(zone->mctx, &_sig_diff);
5755 zonediff_init(&zonediff, &_sig_diff);
5758 * Zone is frozen or automatic resigning is disabled.
5759 * Pause for 5 minutes.
5761 if (zone->update_disabled ||
5762 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
5764 result = ISC_R_FAILURE;
5768 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5769 dns_db_attach(zone->db, &db);
5770 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5772 result = dns_db_newversion(db, &version);
5773 if (result != ISC_R_SUCCESS) {
5774 dns_zone_log(zone, ISC_LOG_ERROR,
5775 "zone_resigninc:dns_db_newversion -> %s",
5776 dns_result_totext(result));
5780 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
5782 if (result != ISC_R_SUCCESS) {
5783 dns_zone_log(zone, ISC_LOG_ERROR,
5784 "zone_resigninc:find_zone_keys -> %s",
5785 dns_result_totext(result));
5789 isc_stdtime_get(&now);
5790 inception = now - 3600; /* Allow for clock skew. */
5791 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5793 * Spread out signatures over time if they happen to be
5794 * clumped. We don't do this for each add_sigs() call as
5795 * we still want some clustering to occur.
5797 isc_random_get(&jitter);
5798 expire = soaexpire - jitter % 3600;
5801 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5802 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
5804 name = dns_fixedname_name(&fixed);
5805 result = dns_db_getsigningtime(db, &rdataset, name);
5806 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
5807 dns_zone_log(zone, ISC_LOG_ERROR,
5808 "zone_resigninc:dns_db_getsigningtime -> %s",
5809 dns_result_totext(result));
5813 while (result == ISC_R_SUCCESS) {
5814 resign = rdataset.resign - zone->sigresigninginterval;
5815 covers = rdataset.covers;
5816 dns_rdataset_disassociate(&rdataset);
5819 * Stop if we hit the SOA as that means we have walked the
5820 * entire zone. The SOA record should always be the most
5823 /* XXXMPA increase number of RRsets signed pre call */
5824 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
5828 result = del_sigs(zone, db, version, name, covers, &zonediff,
5829 zone_keys, nkeys, now, ISC_TRUE);
5830 if (result != ISC_R_SUCCESS) {
5831 dns_zone_log(zone, ISC_LOG_ERROR,
5832 "zone_resigninc:del_sigs -> %s",
5833 dns_result_totext(result));
5837 result = add_sigs(db, version, name, covers, zonediff.diff,
5838 zone_keys, nkeys, zone->mctx, inception,
5839 expire, check_ksk, keyset_kskonly);
5840 if (result != ISC_R_SUCCESS) {
5841 dns_zone_log(zone, ISC_LOG_ERROR,
5842 "zone_resigninc:add_sigs -> %s",
5843 dns_result_totext(result));
5846 result = dns_db_getsigningtime(db, &rdataset, name);
5847 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
5848 result = ISC_R_SUCCESS;
5851 if (result != ISC_R_SUCCESS)
5852 dns_zone_log(zone, ISC_LOG_ERROR,
5853 "zone_resigninc:dns_db_getsigningtime -> %s",
5854 dns_result_totext(result));
5857 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
5860 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5861 &zonediff, zone_keys, nkeys, now, ISC_TRUE);
5862 if (result != ISC_R_SUCCESS) {
5863 dns_zone_log(zone, ISC_LOG_ERROR,
5864 "zone_resigninc:del_sigs -> %s",
5865 dns_result_totext(result));
5870 * Did we change anything in the zone?
5872 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
5874 * Commit the changes if any key has been marked as offline. */
5875 if (zonediff.offline)
5876 dns_db_closeversion(db, &version, ISC_TRUE);
5880 /* Increment SOA serial if we have made changes */
5881 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
5882 zone->updatemethod);
5883 if (result != ISC_R_SUCCESS) {
5884 dns_zone_log(zone, ISC_LOG_ERROR,
5885 "zone_resigninc:update_soa_serial -> %s",
5886 dns_result_totext(result));
5891 * Generate maximum life time signatures so that the above loop
5892 * termination is sensible.
5894 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5895 zonediff.diff, zone_keys, nkeys, zone->mctx,
5896 inception, soaexpire, check_ksk, keyset_kskonly);
5897 if (result != ISC_R_SUCCESS) {
5898 dns_zone_log(zone, ISC_LOG_ERROR,
5899 "zone_resigninc:add_sigs -> %s",
5900 dns_result_totext(result));
5904 /* Write changes to journal file. */
5905 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
5907 /* Everything has succeeded. Commit the changes. */
5908 dns_db_closeversion(db, &version, ISC_TRUE);
5911 dns_diff_clear(&_sig_diff);
5912 for (i = 0; i < nkeys; i++)
5913 dst_key_free(&zone_keys[i]);
5914 if (version != NULL) {
5915 dns_db_closeversion(zone->db, &version, ISC_FALSE);
5917 } else if (db != NULL)
5919 if (result == ISC_R_SUCCESS) {
5920 set_resigntime(zone);
5922 zone_needdump(zone, DNS_DUMP_DELAY);
5923 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5927 * Something failed. Retry in 5 minutes.
5929 isc_interval_t ival;
5930 isc_interval_set(&ival, 300, 0);
5931 isc_time_nowplusinterval(&zone->resigntime, &ival);
5934 INSIST(version == NULL);
5938 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
5939 dns_name_t *newname, isc_boolean_t bottom)
5941 isc_result_t result;
5942 dns_dbiterator_t *dbit = NULL;
5943 dns_rdatasetiter_t *rdsit = NULL;
5944 dns_dbnode_t *node = NULL;
5946 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
5947 CHECK(dns_dbiterator_seek(dbit, oldname));
5949 result = dns_dbiterator_next(dbit);
5950 if (result == ISC_R_NOMORE)
5951 CHECK(dns_dbiterator_first(dbit));
5952 CHECK(dns_dbiterator_current(dbit, &node, newname));
5953 if (bottom && dns_name_issubdomain(newname, oldname) &&
5954 !dns_name_equal(newname, oldname)) {
5955 dns_db_detachnode(db, &node);
5959 * Is this node empty?
5961 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
5962 result = dns_rdatasetiter_first(rdsit);
5963 dns_db_detachnode(db, &node);
5964 dns_rdatasetiter_destroy(&rdsit);
5965 if (result != ISC_R_NOMORE)
5970 dns_db_detachnode(db, &node);
5972 dns_dbiterator_destroy(&dbit);
5976 static isc_boolean_t
5977 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5978 dns_rdatatype_t type, dst_key_t *key)
5980 isc_result_t result;
5981 dns_rdataset_t rdataset;
5982 dns_rdata_t rdata = DNS_RDATA_INIT;
5983 dns_rdata_rrsig_t rrsig;
5985 dns_rdataset_init(&rdataset);
5986 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
5987 type, 0, &rdataset, NULL);
5988 if (result != ISC_R_SUCCESS) {
5989 INSIST(!dns_rdataset_isassociated(&rdataset));
5992 for (result = dns_rdataset_first(&rdataset);
5993 result == ISC_R_SUCCESS;
5994 result = dns_rdataset_next(&rdataset)) {
5995 dns_rdataset_current(&rdataset, &rdata);
5996 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5997 INSIST(result == ISC_R_SUCCESS);
5998 if (rrsig.algorithm == dst_key_alg(key) &&
5999 rrsig.keyid == dst_key_id(key)) {
6000 dns_rdataset_disassociate(&rdataset);
6003 dns_rdata_reset(&rdata);
6005 dns_rdataset_disassociate(&rdataset);
6010 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6011 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
6014 dns_fixedname_t fixed;
6016 dns_rdata_t rdata = DNS_RDATA_INIT;
6017 isc_result_t result;
6018 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
6020 dns_fixedname_init(&fixed);
6021 next = dns_fixedname_name(&fixed);
6023 CHECK(next_active(db, version, name, next, bottom));
6024 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
6026 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
6033 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
6034 dns_dbversion_t *version, isc_boolean_t build_nsec3,
6035 isc_boolean_t build_nsec, dst_key_t *key,
6036 isc_stdtime_t inception, isc_stdtime_t expire,
6037 unsigned int minimum, isc_boolean_t is_ksk,
6038 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
6039 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
6041 isc_result_t result;
6042 dns_rdatasetiter_t *iterator = NULL;
6043 dns_rdataset_t rdataset;
6044 dns_rdata_t rdata = DNS_RDATA_INIT;
6045 isc_buffer_t buffer;
6046 unsigned char data[1024];
6047 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
6048 seen_nsec3, seen_ds;
6049 isc_boolean_t bottom;
6051 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6052 if (result != ISC_R_SUCCESS) {
6053 if (result == ISC_R_NOTFOUND)
6054 result = ISC_R_SUCCESS;
6058 dns_rdataset_init(&rdataset);
6059 isc_buffer_init(&buffer, data, sizeof(data));
6060 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
6061 seen_nsec3 = seen_ds = ISC_FALSE;
6062 for (result = dns_rdatasetiter_first(iterator);
6063 result == ISC_R_SUCCESS;
6064 result = dns_rdatasetiter_next(iterator)) {
6065 dns_rdatasetiter_current(iterator, &rdataset);
6066 if (rdataset.type == dns_rdatatype_soa)
6067 seen_soa = ISC_TRUE;
6068 else if (rdataset.type == dns_rdatatype_ns)
6070 else if (rdataset.type == dns_rdatatype_ds)
6072 else if (rdataset.type == dns_rdatatype_dname)
6073 seen_dname = ISC_TRUE;
6074 else if (rdataset.type == dns_rdatatype_nsec)
6075 seen_nsec = ISC_TRUE;
6076 else if (rdataset.type == dns_rdatatype_nsec3)
6077 seen_nsec3 = ISC_TRUE;
6078 if (rdataset.type != dns_rdatatype_rrsig)
6080 dns_rdataset_disassociate(&rdataset);
6082 if (result != ISC_R_NOMORE)
6084 if (seen_ns && !seen_soa)
6085 *delegation = ISC_TRUE;
6087 * Going from insecure to NSEC3.
6088 * Don't generate NSEC3 records for NSEC3 records.
6090 if (build_nsec3 && !seen_nsec3 && seen_rr) {
6091 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
6092 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
6097 * Going from insecure to NSEC.
6098 * Don't generate NSEC records for NSEC3 records.
6100 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
6101 /* Build and add NSEC. */
6102 bottom = (seen_ns && !seen_soa) || seen_dname;
6104 * Build a NSEC record except at the origin.
6106 if (!dns_name_equal(name, dns_db_origin(db))) {
6107 CHECK(add_nsec(db, version, name, node, minimum,
6109 /* Count a NSEC generation as a signature generation. */
6113 result = dns_rdatasetiter_first(iterator);
6114 while (result == ISC_R_SUCCESS) {
6115 dns_rdatasetiter_current(iterator, &rdataset);
6116 if (rdataset.type == dns_rdatatype_soa ||
6117 rdataset.type == dns_rdatatype_rrsig)
6119 if (rdataset.type == dns_rdatatype_dnskey) {
6120 if (!is_ksk && keyset_kskonly)
6122 } else if (is_ksk) {
6124 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
6126 if (rdataset.type != dns_rdatatype_cds &&
6127 rdataset.type != dns_rdatatype_cdnskey)
6131 rdataset.type != dns_rdatatype_ds &&
6132 rdataset.type != dns_rdatatype_nsec)
6134 if (signed_with_key(db, node, version, rdataset.type, key))
6136 /* Calculate the signature, creating a RRSIG RDATA. */
6137 isc_buffer_clear(&buffer);
6138 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
6139 &expire, mctx, &buffer, &rdata));
6140 /* Update the database and journal with the RRSIG. */
6141 /* XXX inefficient - will cause dataset merging */
6142 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
6143 name, rdataset.ttl, &rdata));
6144 dns_rdata_reset(&rdata);
6147 dns_rdataset_disassociate(&rdataset);
6148 result = dns_rdatasetiter_next(iterator);
6150 if (result == ISC_R_NOMORE)
6151 result = ISC_R_SUCCESS;
6153 *delegation = ISC_TRUE;
6155 if (dns_rdataset_isassociated(&rdataset))
6156 dns_rdataset_disassociate(&rdataset);
6157 if (iterator != NULL)
6158 dns_rdatasetiter_destroy(&iterator);
6163 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
6166 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6167 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
6169 isc_result_t result;
6170 dns_rdataset_t rdataset;
6171 dns_dbnode_t *node = NULL;
6173 CHECK(dns_db_getoriginnode(db, &node));
6175 dns_rdataset_init(&rdataset);
6176 result = dns_db_findrdataset(db, node, version,
6179 0, &rdataset, NULL);
6180 if (dns_rdataset_isassociated(&rdataset))
6181 dns_rdataset_disassociate(&rdataset);
6182 if (result == ISC_R_NOTFOUND)
6184 if (result != ISC_R_SUCCESS)
6187 CHECK(delete_nsec(db, version, node, name, diff));
6188 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
6190 result = ISC_R_SUCCESS;
6193 dns_db_detachnode(db, &node);
6198 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
6199 dns_dbversion_t *version, isc_boolean_t build_nsec3,
6200 dns_ttl_t minimum, dns_diff_t *diff)
6202 isc_result_t result;
6203 dns_dbnode_t *node = NULL;
6204 dns_rdataset_t rdataset;
6205 dns_rdata_t rdata = DNS_RDATA_INIT;
6206 unsigned char data[5];
6207 isc_boolean_t seen_done = ISC_FALSE;
6208 isc_boolean_t have_rr = ISC_FALSE;
6210 dns_rdataset_init(&rdataset);
6211 result = dns_db_getoriginnode(signing->db, &node);
6212 if (result != ISC_R_SUCCESS)
6215 result = dns_db_findrdataset(signing->db, node, version,
6216 zone->privatetype, dns_rdatatype_none,
6217 0, &rdataset, NULL);
6218 if (result == ISC_R_NOTFOUND) {
6219 INSIST(!dns_rdataset_isassociated(&rdataset));
6220 result = ISC_R_SUCCESS;
6223 if (result != ISC_R_SUCCESS) {
6224 INSIST(!dns_rdataset_isassociated(&rdataset));
6227 for (result = dns_rdataset_first(&rdataset);
6228 result == ISC_R_SUCCESS;
6229 result = dns_rdataset_next(&rdataset)) {
6230 dns_rdataset_current(&rdataset, &rdata);
6232 * If we don't match the algorithm or keyid skip the record.
6234 if (rdata.length != 5 ||
6235 rdata.data[0] != signing->algorithm ||
6236 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
6237 rdata.data[2] != (signing->keyid & 0xff)) {
6239 dns_rdata_reset(&rdata);
6243 * We have a match. If we were signing (!signing->delete)
6244 * and we already have a record indicating that we have
6245 * finished signing (rdata.data[4] != 0) then keep it.
6246 * Otherwise it needs to be deleted as we have removed all
6247 * the signatures (signing->delete), so any record indicating
6248 * completion is now out of date, or we have finished signing
6249 * with the new record so we no longer need to remember that
6250 * we need to sign the zone with the matching key across a
6251 * nameserver re-start.
6253 if (!signing->delete && rdata.data[4] != 0) {
6254 seen_done = ISC_TRUE;
6257 CHECK(update_one_rr(signing->db, version, diff,
6258 DNS_DIFFOP_DEL, &zone->origin,
6259 rdataset.ttl, &rdata));
6260 dns_rdata_reset(&rdata);
6262 if (result == ISC_R_NOMORE)
6263 result = ISC_R_SUCCESS;
6264 if (!signing->delete && !seen_done) {
6266 * If we were signing then we need to indicate that we have
6267 * finished signing the zone with this key. If it is already
6268 * there we don't need to add it a second time.
6270 data[0] = signing->algorithm;
6271 data[1] = (signing->keyid >> 8) & 0xff;
6272 data[2] = signing->keyid & 0xff;
6275 rdata.length = sizeof(data);
6277 rdata.type = zone->privatetype;
6278 rdata.rdclass = dns_db_class(signing->db);
6279 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
6280 &zone->origin, rdataset.ttl, &rdata));
6281 } else if (!have_rr) {
6282 dns_name_t *origin = dns_db_origin(signing->db);
6284 * Rebuild the NSEC/NSEC3 record for the origin as we no
6285 * longer have any private records.
6288 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
6289 minimum, ISC_FALSE, diff));
6290 CHECK(updatesecure(signing->db, version, origin, minimum,
6295 if (dns_rdataset_isassociated(&rdataset))
6296 dns_rdataset_disassociate(&rdataset);
6298 dns_db_detachnode(signing->db, &node);
6303 * If 'active' is set then we are not done with the chain yet so only
6304 * delete the nsec3param record which indicates a full chain exists
6308 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
6309 isc_boolean_t active, dns_rdatatype_t privatetype,
6312 dns_dbnode_t *node = NULL;
6313 dns_name_t *name = dns_db_origin(db);
6314 dns_rdata_t rdata = DNS_RDATA_INIT;
6315 dns_rdataset_t rdataset;
6316 dns_rdata_nsec3param_t nsec3param;
6317 isc_result_t result;
6318 isc_buffer_t buffer;
6319 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
6321 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
6323 dns_rdataset_init(&rdataset);
6325 result = dns_db_getoriginnode(db, &node);
6326 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6327 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6328 0, 0, &rdataset, NULL);
6329 if (result == ISC_R_NOTFOUND)
6331 if (result != ISC_R_SUCCESS)
6335 * Preserve the existing ttl.
6340 * Delete all NSEC3PARAM records which match that in nsec3chain.
6342 for (result = dns_rdataset_first(&rdataset);
6343 result == ISC_R_SUCCESS;
6344 result = dns_rdataset_next(&rdataset)) {
6346 dns_rdataset_current(&rdataset, &rdata);
6347 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6349 if (nsec3param.hash != chain->nsec3param.hash ||
6350 (active && nsec3param.flags != 0) ||
6351 nsec3param.iterations != chain->nsec3param.iterations ||
6352 nsec3param.salt_length != chain->nsec3param.salt_length ||
6353 memcmp(nsec3param.salt, chain->nsec3param.salt,
6354 nsec3param.salt_length)) {
6355 dns_rdata_reset(&rdata);
6359 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6360 name, rdataset.ttl, &rdata));
6361 dns_rdata_reset(&rdata);
6363 if (result != ISC_R_NOMORE)
6366 dns_rdataset_disassociate(&rdataset);
6373 result = dns_nsec_nseconly(db, ver, &nseconly);
6374 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
6377 * Delete all private records which match that in nsec3chain.
6379 result = dns_db_findrdataset(db, node, ver, privatetype,
6380 0, 0, &rdataset, NULL);
6381 if (result == ISC_R_NOTFOUND)
6383 if (result != ISC_R_SUCCESS)
6386 for (result = dns_rdataset_first(&rdataset);
6387 result == ISC_R_SUCCESS;
6388 result = dns_rdataset_next(&rdataset)) {
6389 dns_rdata_t private = DNS_RDATA_INIT;
6390 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
6392 dns_rdataset_current(&rdataset, &private);
6393 if (!dns_nsec3param_fromprivate(&private, &rdata,
6396 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6399 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
6400 nsec3param.hash != chain->nsec3param.hash ||
6401 nsec3param.iterations != chain->nsec3param.iterations ||
6402 nsec3param.salt_length != chain->nsec3param.salt_length ||
6403 memcmp(nsec3param.salt, chain->nsec3param.salt,
6404 nsec3param.salt_length)) {
6405 dns_rdata_reset(&rdata);
6409 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6410 name, rdataset.ttl, &private));
6411 dns_rdata_reset(&rdata);
6413 if (result != ISC_R_NOMORE)
6417 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
6418 result = ISC_R_SUCCESS;
6423 * Add a NSEC3PARAM record which matches that in nsec3chain but
6424 * with all flags bits cleared.
6426 * Note: we do not clear chain->nsec3param.flags as this change
6429 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
6430 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
6431 dns_rdatatype_nsec3param,
6432 &chain->nsec3param, &buffer));
6433 rdata.data[1] = 0; /* Clear flag bits. */
6434 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
6437 dns_db_detachnode(db, &node);
6438 if (dns_rdataset_isassociated(&rdataset))
6439 dns_rdataset_disassociate(&rdataset);
6444 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6445 dns_name_t *name, dns_diff_t *diff)
6447 dns_rdataset_t rdataset;
6448 isc_result_t result;
6450 dns_rdataset_init(&rdataset);
6452 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6453 0, 0, &rdataset, NULL);
6454 if (result == ISC_R_NOTFOUND)
6455 return (ISC_R_SUCCESS);
6456 if (result != ISC_R_SUCCESS)
6458 for (result = dns_rdataset_first(&rdataset);
6459 result == ISC_R_SUCCESS;
6460 result = dns_rdataset_next(&rdataset)) {
6461 dns_rdata_t rdata = DNS_RDATA_INIT;
6463 dns_rdataset_current(&rdataset, &rdata);
6464 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6465 rdataset.ttl, &rdata));
6467 if (result == ISC_R_NOMORE)
6468 result = ISC_R_SUCCESS;
6470 dns_rdataset_disassociate(&rdataset);
6475 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6476 dns_name_t *name, const dns_rdata_nsec3param_t *param,
6479 dns_rdataset_t rdataset;
6480 dns_rdata_nsec3_t nsec3;
6481 isc_result_t result;
6483 dns_rdataset_init(&rdataset);
6484 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
6485 0, 0, &rdataset, NULL);
6486 if (result == ISC_R_NOTFOUND)
6487 return (ISC_R_SUCCESS);
6488 if (result != ISC_R_SUCCESS)
6491 for (result = dns_rdataset_first(&rdataset);
6492 result == ISC_R_SUCCESS;
6493 result = dns_rdataset_next(&rdataset)) {
6494 dns_rdata_t rdata = DNS_RDATA_INIT;
6496 dns_rdataset_current(&rdataset, &rdata);
6497 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
6498 if (nsec3.hash != param->hash ||
6499 nsec3.iterations != param->iterations ||
6500 nsec3.salt_length != param->salt_length ||
6501 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
6503 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6504 rdataset.ttl, &rdata));
6506 if (result == ISC_R_NOMORE)
6507 result = ISC_R_SUCCESS;
6509 dns_rdataset_disassociate(&rdataset);
6514 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
6515 const dns_rdata_nsec3param_t *param,
6516 isc_boolean_t *answer)
6518 dns_dbnode_t *node = NULL;
6519 dns_rdata_t rdata = DNS_RDATA_INIT;
6520 dns_rdata_nsec3param_t myparam;
6521 dns_rdataset_t rdataset;
6522 isc_result_t result;
6524 *answer = ISC_FALSE;
6526 result = dns_db_getoriginnode(db, &node);
6527 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6529 dns_rdataset_init(&rdataset);
6531 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6532 0, 0, &rdataset, NULL);
6533 if (result == ISC_R_SUCCESS) {
6534 dns_rdataset_disassociate(&rdataset);
6535 dns_db_detachnode(db, &node);
6538 if (result != ISC_R_NOTFOUND) {
6539 dns_db_detachnode(db, &node);
6543 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6544 0, 0, &rdataset, NULL);
6545 if (result == ISC_R_NOTFOUND) {
6547 dns_db_detachnode(db, &node);
6548 return (ISC_R_SUCCESS);
6550 if (result != ISC_R_SUCCESS) {
6551 dns_db_detachnode(db, &node);
6555 for (result = dns_rdataset_first(&rdataset);
6556 result == ISC_R_SUCCESS;
6557 result = dns_rdataset_next(&rdataset)) {
6558 dns_rdataset_current(&rdataset, &rdata);
6559 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
6560 dns_rdata_reset(&rdata);
6562 * Ignore any NSEC3PARAM removals.
6564 if (NSEC3REMOVE(myparam.flags))
6567 * Ignore the chain that we are in the process of deleting.
6569 if (myparam.hash == param->hash &&
6570 myparam.iterations == param->iterations &&
6571 myparam.salt_length == param->salt_length &&
6572 !memcmp(myparam.salt, param->salt, myparam.salt_length))
6575 * Found an active NSEC3 chain.
6579 if (result == ISC_R_NOMORE) {
6581 result = ISC_R_SUCCESS;
6585 if (dns_rdataset_isassociated(&rdataset))
6586 dns_rdataset_disassociate(&rdataset);
6587 dns_db_detachnode(db, &node);
6592 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
6593 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
6594 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
6595 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
6596 zonediff_t *zonediff)
6598 dns_difftuple_t *tuple;
6599 isc_result_t result;
6601 for (tuple = ISC_LIST_HEAD(diff->tuples);
6603 tuple = ISC_LIST_HEAD(diff->tuples)) {
6604 result = del_sigs(zone, db, version, &tuple->name,
6605 tuple->rdata.type, zonediff,
6606 zone_keys, nkeys, now, ISC_FALSE);
6607 if (result != ISC_R_SUCCESS) {
6608 dns_zone_log(zone, ISC_LOG_ERROR,
6609 "update_sigs:del_sigs -> %s",
6610 dns_result_totext(result));
6613 result = add_sigs(db, version, &tuple->name,
6614 tuple->rdata.type, zonediff->diff,
6615 zone_keys, nkeys, zone->mctx, inception,
6616 expire, check_ksk, keyset_kskonly);
6617 if (result != ISC_R_SUCCESS) {
6618 dns_zone_log(zone, ISC_LOG_ERROR,
6619 "update_sigs:add_sigs -> %s",
6620 dns_result_totext(result));
6625 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
6626 while (next != NULL &&
6627 (tuple->rdata.type != next->rdata.type ||
6628 !dns_name_equal(&tuple->name, &next->name)))
6629 next = ISC_LIST_NEXT(next, link);
6630 ISC_LIST_UNLINK(diff->tuples, tuple, link);
6631 dns_diff_appendminimal(zonediff->diff, &tuple);
6632 INSIST(tuple == NULL);
6634 } while (tuple != NULL);
6636 return (ISC_R_SUCCESS);
6640 * Incrementally build and sign a new NSEC3 chain using the parameters
6644 zone_nsec3chain(dns_zone_t *zone) {
6645 const char *me = "zone_nsec3chain";
6646 dns_db_t *db = NULL;
6647 dns_dbnode_t *node = NULL;
6648 dns_dbversion_t *version = NULL;
6649 dns_diff_t _sig_diff;
6650 dns_diff_t nsec_diff;
6651 dns_diff_t nsec3_diff;
6652 dns_diff_t param_diff;
6653 zonediff_t zonediff;
6654 dns_fixedname_t fixed;
6655 dns_fixedname_t nextfixed;
6656 dns_name_t *name, *nextname;
6657 dns_rdataset_t rdataset;
6658 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
6659 dns_nsec3chainlist_t cleanup;
6660 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6661 isc_int32_t signatures;
6662 isc_boolean_t check_ksk, keyset_kskonly;
6663 isc_boolean_t delegation;
6664 isc_boolean_t first;
6665 isc_result_t result;
6666 isc_stdtime_t now, inception, soaexpire, expire;
6667 isc_uint32_t jitter;
6669 unsigned int nkeys = 0;
6671 isc_boolean_t unsecure = ISC_FALSE;
6672 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
6673 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
6674 dns_rdatasetiter_t *iterator = NULL;
6675 isc_boolean_t buildnsecchain;
6676 isc_boolean_t updatensec = ISC_FALSE;
6677 dns_rdatatype_t privatetype = zone->privatetype;
6681 dns_rdataset_init(&rdataset);
6682 dns_fixedname_init(&fixed);
6683 name = dns_fixedname_name(&fixed);
6684 dns_fixedname_init(&nextfixed);
6685 nextname = dns_fixedname_name(&nextfixed);
6686 dns_diff_init(zone->mctx, ¶m_diff);
6687 dns_diff_init(zone->mctx, &nsec3_diff);
6688 dns_diff_init(zone->mctx, &nsec_diff);
6689 dns_diff_init(zone->mctx, &_sig_diff);
6690 zonediff_init(&zonediff, &_sig_diff);
6691 ISC_LIST_INIT(cleanup);
6694 * Updates are disabled. Pause for 5 minutes.
6696 if (zone->update_disabled) {
6697 result = ISC_R_FAILURE;
6701 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6702 dns_db_attach(zone->db, &db);
6703 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6705 result = dns_db_newversion(db, &version);
6706 if (result != ISC_R_SUCCESS) {
6707 dns_zone_log(zone, ISC_LOG_ERROR,
6708 "zone_nsec3chain:dns_db_newversion -> %s",
6709 dns_result_totext(result));
6713 result = find_zone_keys(zone, db, version, zone->mctx,
6714 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6715 if (result != ISC_R_SUCCESS) {
6716 dns_zone_log(zone, ISC_LOG_ERROR,
6717 "zone_nsec3chain:find_zone_keys -> %s",
6718 dns_result_totext(result));
6722 isc_stdtime_get(&now);
6723 inception = now - 3600; /* Allow for clock skew. */
6724 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6727 * Spread out signatures over time if they happen to be
6728 * clumped. We don't do this for each add_sigs() call as
6729 * we still want some clustering to occur.
6731 isc_random_get(&jitter);
6732 expire = soaexpire - jitter % 3600;
6734 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6735 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6738 * We keep pulling nodes off each iterator in turn until
6739 * we have no more nodes to pull off or we reach the limits
6742 nodes = zone->nodes;
6743 signatures = zone->signatures;
6745 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6749 if (nsec3chain != NULL)
6750 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6752 * Generate new NSEC3 chains first.
6754 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6756 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6758 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6759 if (nsec3chain->done || nsec3chain->db != zone->db) {
6760 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
6761 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6763 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6765 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
6769 * Possible future db.
6771 if (nsec3chain->db != db) {
6775 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
6778 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6780 if (nsec3chain->delete_nsec) {
6781 delegation = ISC_FALSE;
6782 dns_dbiterator_pause(nsec3chain->dbiterator);
6783 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
6787 * On the first pass we need to check if the current node
6788 * has not been obscured.
6790 delegation = ISC_FALSE;
6791 unsecure = ISC_FALSE;
6793 dns_fixedname_t ffound;
6795 dns_fixedname_init(&ffound);
6796 found = dns_fixedname_name(&ffound);
6797 result = dns_db_find(db, name, version,
6799 DNS_DBFIND_NOWILD, 0, NULL, found,
6801 if ((result == DNS_R_DELEGATION ||
6802 result == DNS_R_DNAME) &&
6803 !dns_name_equal(name, found)) {
6805 * Remember the obscuring name so that
6806 * we skip all obscured names.
6808 dns_name_copy(found, name, NULL);
6809 delegation = ISC_TRUE;
6815 * Check to see if this is a bottom of zone node.
6817 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6818 if (result == ISC_R_NOTFOUND) /* Empty node? */
6820 if (result != ISC_R_SUCCESS)
6823 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
6825 for (result = dns_rdatasetiter_first(iterator);
6826 result == ISC_R_SUCCESS;
6827 result = dns_rdatasetiter_next(iterator)) {
6828 dns_rdatasetiter_current(iterator, &rdataset);
6829 INSIST(rdataset.type != dns_rdatatype_nsec3);
6830 if (rdataset.type == dns_rdatatype_soa)
6831 seen_soa = ISC_TRUE;
6832 else if (rdataset.type == dns_rdatatype_ns)
6834 else if (rdataset.type == dns_rdatatype_dname)
6835 seen_dname = ISC_TRUE;
6836 else if (rdataset.type == dns_rdatatype_ds)
6838 else if (rdataset.type == dns_rdatatype_nsec)
6839 seen_nsec = ISC_TRUE;
6840 dns_rdataset_disassociate(&rdataset);
6842 dns_rdatasetiter_destroy(&iterator);
6844 * Is there a NSEC chain than needs to be cleaned up?
6847 nsec3chain->seen_nsec = ISC_TRUE;
6848 if (seen_ns && !seen_soa && !seen_ds)
6849 unsecure = ISC_TRUE;
6850 if ((seen_ns && !seen_soa) || seen_dname)
6851 delegation = ISC_TRUE;
6856 dns_dbiterator_pause(nsec3chain->dbiterator);
6857 result = dns_nsec3_addnsec3(db, version, name,
6858 &nsec3chain->nsec3param,
6859 zone->minimum, unsecure,
6861 if (result != ISC_R_SUCCESS) {
6862 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6863 "dns_nsec3_addnsec3 -> %s",
6864 dns_result_totext(result));
6869 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
6870 * two signatures. Additionally there will, in general, be
6871 * two signature generated below.
6873 * If we are only changing the optout flag the cost is half
6874 * that of the cost of generating a completely new chain.
6879 * Go onto next node.
6883 dns_db_detachnode(db, &node);
6885 result = dns_dbiterator_next(nsec3chain->dbiterator);
6887 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
6888 dns_dbiterator_pause(nsec3chain->dbiterator);
6889 CHECK(fixup_nsec3param(db, version, nsec3chain,
6890 ISC_FALSE, privatetype,
6893 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6896 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6899 if (result == ISC_R_NOMORE) {
6900 dns_dbiterator_pause(nsec3chain->dbiterator);
6901 if (nsec3chain->seen_nsec) {
6902 CHECK(fixup_nsec3param(db, version,
6907 nsec3chain->delete_nsec = ISC_TRUE;
6910 CHECK(fixup_nsec3param(db, version, nsec3chain,
6911 ISC_FALSE, privatetype,
6914 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6917 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6919 } else if (result != ISC_R_SUCCESS) {
6920 dns_zone_log(zone, ISC_LOG_ERROR,
6922 "dns_dbiterator_next -> %s",
6923 dns_result_totext(result));
6925 } else if (delegation) {
6926 dns_dbiterator_current(nsec3chain->dbiterator,
6928 dns_db_detachnode(db, &node);
6929 if (!dns_name_issubdomain(nextname, name))
6937 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6942 dns_dbiterator_pause(nsec3chain->dbiterator);
6943 nsec3chain = nextnsec3chain;
6945 if (nsec3chain != NULL)
6946 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6953 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6956 buildnsecchain = ISC_FALSE;
6957 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6959 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6962 if (nsec3chain->db != db)
6963 goto next_removechain;
6965 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
6966 goto next_removechain;
6969 * Work out if we need to build a NSEC chain as a consequence
6970 * of removing this NSEC3 chain.
6972 if (first && !updatensec &&
6973 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
6975 result = need_nsec_chain(db, version,
6976 &nsec3chain->nsec3param,
6978 if (result != ISC_R_SUCCESS) {
6979 dns_zone_log(zone, ISC_LOG_ERROR,
6981 "need_nsec_chain -> %s",
6982 dns_result_totext(result));
6988 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
6989 "buildnsecchain = %u\n", buildnsecchain);
6991 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6992 delegation = ISC_FALSE;
6994 if (!buildnsecchain) {
6996 * Delete the NSECPARAM record that matches this chain.
6999 result = fixup_nsec3param(db, version,
7001 ISC_TRUE, privatetype,
7003 if (result != ISC_R_SUCCESS) {
7004 dns_zone_log(zone, ISC_LOG_ERROR,
7006 "fixup_nsec3param -> %s",
7007 dns_result_totext(result));
7013 * Delete the NSEC3 records.
7015 result = deletematchingnsec3(db, version, node, name,
7016 &nsec3chain->nsec3param,
7018 if (result != ISC_R_SUCCESS) {
7019 dns_zone_log(zone, ISC_LOG_ERROR,
7021 "deletematchingnsec3 -> %s",
7022 dns_result_totext(result));
7025 goto next_removenode;
7029 dns_fixedname_t ffound;
7031 dns_fixedname_init(&ffound);
7032 found = dns_fixedname_name(&ffound);
7033 result = dns_db_find(db, name, version,
7035 DNS_DBFIND_NOWILD, 0, NULL, found,
7037 if ((result == DNS_R_DELEGATION ||
7038 result == DNS_R_DNAME) &&
7039 !dns_name_equal(name, found)) {
7041 * Remember the obscuring name so that
7042 * we skip all obscured names.
7044 dns_name_copy(found, name, NULL);
7045 delegation = ISC_TRUE;
7046 goto next_removenode;
7051 * Check to see if this is a bottom of zone node.
7053 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7054 if (result == ISC_R_NOTFOUND) /* Empty node? */
7055 goto next_removenode;
7056 if (result != ISC_R_SUCCESS)
7059 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
7060 seen_rr = ISC_FALSE;
7061 for (result = dns_rdatasetiter_first(iterator);
7062 result == ISC_R_SUCCESS;
7063 result = dns_rdatasetiter_next(iterator)) {
7064 dns_rdatasetiter_current(iterator, &rdataset);
7065 if (rdataset.type == dns_rdatatype_soa)
7066 seen_soa = ISC_TRUE;
7067 else if (rdataset.type == dns_rdatatype_ns)
7069 else if (rdataset.type == dns_rdatatype_dname)
7070 seen_dname = ISC_TRUE;
7071 else if (rdataset.type == dns_rdatatype_nsec)
7072 seen_nsec = ISC_TRUE;
7073 else if (rdataset.type == dns_rdatatype_nsec3)
7074 seen_nsec3 = ISC_TRUE;
7075 if (rdataset.type != dns_rdatatype_rrsig)
7077 dns_rdataset_disassociate(&rdataset);
7079 dns_rdatasetiter_destroy(&iterator);
7081 if (!seen_rr || seen_nsec3 || seen_nsec)
7082 goto next_removenode;
7083 if ((seen_ns && !seen_soa) || seen_dname)
7084 delegation = ISC_TRUE;
7087 * Add a NSEC record except at the origin.
7089 if (!dns_name_equal(name, dns_db_origin(db))) {
7090 dns_dbiterator_pause(nsec3chain->dbiterator);
7091 CHECK(add_nsec(db, version, name, node, zone->minimum,
7092 delegation, &nsec_diff));
7097 dns_db_detachnode(db, &node);
7099 result = dns_dbiterator_next(nsec3chain->dbiterator);
7100 if (result == ISC_R_NOMORE && buildnsecchain) {
7102 * The NSEC chain should now be built.
7103 * We can now remove the NSEC3 chain.
7105 updatensec = ISC_TRUE;
7106 goto same_removechain;
7108 if (result == ISC_R_NOMORE) {
7110 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
7113 ISC_LIST_APPEND(cleanup, nsec3chain, link);
7114 dns_dbiterator_pause(nsec3chain->dbiterator);
7115 result = fixup_nsec3param(db, version,
7116 nsec3chain, ISC_FALSE,
7119 if (result != ISC_R_SUCCESS) {
7120 dns_zone_log(zone, ISC_LOG_ERROR,
7122 "fixup_nsec3param -> %s",
7123 dns_result_totext(result));
7126 goto next_removechain;
7127 } else if (result != ISC_R_SUCCESS) {
7128 dns_zone_log(zone, ISC_LOG_ERROR,
7130 "dns_dbiterator_next -> %s",
7131 dns_result_totext(result));
7133 } else if (delegation) {
7134 dns_dbiterator_current(nsec3chain->dbiterator,
7136 dns_db_detachnode(db, &node);
7137 if (!dns_name_issubdomain(nextname, name))
7145 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
7146 buildnsecchain = ISC_FALSE;
7151 dns_dbiterator_pause(nsec3chain->dbiterator);
7152 nsec3chain = nextnsec3chain;
7157 * We may need to update the NSEC/NSEC3 records for the zone apex.
7159 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
7160 isc_boolean_t rebuild_nsec = ISC_FALSE,
7161 rebuild_nsec3 = ISC_FALSE;
7162 result = dns_db_getoriginnode(db, &node);
7163 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7164 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7165 if (result != ISC_R_SUCCESS) {
7166 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7167 "dns_db_allrdatasets -> %s",
7168 dns_result_totext(result));
7171 for (result = dns_rdatasetiter_first(iterator);
7172 result == ISC_R_SUCCESS;
7173 result = dns_rdatasetiter_next(iterator)) {
7174 dns_rdatasetiter_current(iterator, &rdataset);
7175 if (rdataset.type == dns_rdatatype_nsec)
7176 rebuild_nsec = ISC_TRUE;
7177 if (rdataset.type == dns_rdatatype_nsec3param)
7178 rebuild_nsec3 = ISC_TRUE;
7179 dns_rdataset_disassociate(&rdataset);
7181 dns_rdatasetiter_destroy(&iterator);
7182 dns_db_detachnode(db, &node);
7185 if (nsec3chain != NULL)
7186 dns_dbiterator_pause(nsec3chain->dbiterator);
7188 result = updatesecure(db, version, &zone->origin,
7189 zone->minimum, ISC_TRUE,
7191 if (result != ISC_R_SUCCESS) {
7192 dns_zone_log(zone, ISC_LOG_ERROR,
7194 "updatesecure -> %s",
7195 dns_result_totext(result));
7200 if (rebuild_nsec3) {
7201 if (nsec3chain != NULL)
7202 dns_dbiterator_pause(nsec3chain->dbiterator);
7204 result = dns_nsec3_addnsec3s(db, version,
7206 zone->minimum, ISC_FALSE,
7208 if (result != ISC_R_SUCCESS) {
7209 dns_zone_log(zone, ISC_LOG_ERROR,
7211 "dns_nsec3_addnsec3s -> %s",
7212 dns_result_totext(result));
7218 if (nsec3chain != NULL)
7219 dns_dbiterator_pause(nsec3chain->dbiterator);
7222 * Add / update signatures for the NSEC3 records.
7224 if (nsec3chain != NULL)
7225 dns_dbiterator_pause(nsec3chain->dbiterator);
7226 result = update_sigs(&nsec3_diff, db, version, zone_keys,
7227 nkeys, zone, inception, expire, now,
7228 check_ksk, keyset_kskonly, &zonediff);
7229 if (result != ISC_R_SUCCESS) {
7230 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7231 "update_sigs -> %s", dns_result_totext(result));
7236 * We have changed the NSEC3PARAM or private RRsets
7237 * above so we need to update the signatures.
7239 result = update_sigs(¶m_diff, db, version, zone_keys,
7240 nkeys, zone, inception, expire, now,
7241 check_ksk, keyset_kskonly, &zonediff);
7242 if (result != ISC_R_SUCCESS) {
7243 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7244 "update_sigs -> %s", dns_result_totext(result));
7249 result = updatesecure(db, version, &zone->origin,
7250 zone->minimum, ISC_FALSE, &nsec_diff);
7251 if (result != ISC_R_SUCCESS) {
7252 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7253 "updatesecure -> %s",
7254 dns_result_totext(result));
7259 result = update_sigs(&nsec_diff, db, version, zone_keys,
7260 nkeys, zone, inception, expire, now,
7261 check_ksk, keyset_kskonly, &zonediff);
7262 if (result != ISC_R_SUCCESS) {
7263 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7264 "update_sigs -> %s", dns_result_totext(result));
7269 * If we made no effective changes to the zone then we can just
7270 * cleanup otherwise we need to increment the serial.
7272 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7274 * No need to call dns_db_closeversion() here as it is
7275 * called with commit = ISC_TRUE below.
7280 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7281 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7282 if (result != ISC_R_SUCCESS) {
7283 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7284 "del_sigs -> %s", dns_result_totext(result));
7288 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7289 zone->updatemethod);
7290 if (result != ISC_R_SUCCESS) {
7291 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7292 "update_soa_serial -> %s",
7293 dns_result_totext(result));
7297 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7298 zonediff.diff, zone_keys, nkeys, zone->mctx,
7299 inception, soaexpire, check_ksk, keyset_kskonly);
7300 if (result != ISC_R_SUCCESS) {
7301 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7302 "add_sigs -> %s", dns_result_totext(result));
7306 /* Write changes to journal file. */
7307 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
7310 zone_needdump(zone, DNS_DUMP_DELAY);
7311 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7316 * Pause all iterators so that dns_db_closeversion() can succeed.
7319 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7321 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7322 dns_dbiterator_pause(nsec3chain->dbiterator);
7326 * Everything has succeeded. Commit the changes.
7327 * Unconditionally commit as zonediff.offline not checked above.
7329 dns_db_closeversion(db, &version, ISC_TRUE);
7332 * Everything succeeded so we can clean these up now.
7334 nsec3chain = ISC_LIST_HEAD(cleanup);
7335 while (nsec3chain != NULL) {
7336 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7337 dns_db_detach(&nsec3chain->db);
7338 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7339 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7340 nsec3chain = ISC_LIST_HEAD(cleanup);
7343 set_resigntime(zone);
7346 if (result != ISC_R_SUCCESS)
7347 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
7348 dns_result_totext(result));
7350 * On error roll back the current nsec3chain.
7352 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
7353 if (nsec3chain->done) {
7354 dns_db_detach(&nsec3chain->db);
7355 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7356 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7358 result = dns_dbiterator_first(nsec3chain->dbiterator);
7359 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7360 dns_dbiterator_pause(nsec3chain->dbiterator);
7361 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7366 * Rollback the cleanup list.
7368 nsec3chain = ISC_LIST_TAIL(cleanup);
7369 while (nsec3chain != NULL) {
7370 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7371 if (nsec3chain->done) {
7372 dns_db_detach(&nsec3chain->db);
7373 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7374 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7377 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
7379 result = dns_dbiterator_first(nsec3chain->dbiterator);
7380 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7381 dns_dbiterator_pause(nsec3chain->dbiterator);
7382 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7384 nsec3chain = ISC_LIST_TAIL(cleanup);
7388 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7390 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7391 dns_dbiterator_pause(nsec3chain->dbiterator);
7394 dns_diff_clear(¶m_diff);
7395 dns_diff_clear(&nsec3_diff);
7396 dns_diff_clear(&nsec_diff);
7397 dns_diff_clear(&_sig_diff);
7399 if (iterator != NULL)
7400 dns_rdatasetiter_destroy(&iterator);
7402 for (i = 0; i < nkeys; i++)
7403 dst_key_free(&zone_keys[i]);
7406 dns_db_detachnode(db, &node);
7407 if (version != NULL) {
7408 dns_db_closeversion(db, &version, ISC_FALSE);
7410 } else if (db != NULL)
7414 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
7415 isc_interval_t interval;
7416 if (zone->update_disabled || result != ISC_R_SUCCESS)
7417 isc_interval_set(&interval, 60, 0); /* 1 minute */
7419 isc_interval_set(&interval, 0, 10000000); /* 10 ms */
7420 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
7422 isc_time_settoepoch(&zone->nsec3chaintime);
7425 INSIST(version == NULL);
7429 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
7430 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
7431 isc_uint16_t keyid, dns_diff_t *diff)
7433 dns_rdata_rrsig_t rrsig;
7434 dns_rdataset_t rdataset;
7435 dns_rdatasetiter_t *iterator = NULL;
7436 isc_result_t result;
7438 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7439 if (result != ISC_R_SUCCESS) {
7440 if (result == ISC_R_NOTFOUND)
7441 result = ISC_R_SUCCESS;
7445 dns_rdataset_init(&rdataset);
7446 for (result = dns_rdatasetiter_first(iterator);
7447 result == ISC_R_SUCCESS;
7448 result = dns_rdatasetiter_next(iterator)) {
7449 dns_rdatasetiter_current(iterator, &rdataset);
7450 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
7451 for (result = dns_rdataset_first(&rdataset);
7452 result == ISC_R_SUCCESS;
7453 result = dns_rdataset_next(&rdataset)) {
7454 dns_rdata_t rdata = DNS_RDATA_INIT;
7455 dns_rdataset_current(&rdataset, &rdata);
7456 CHECK(update_one_rr(db, version, diff,
7457 DNS_DIFFOP_DEL, name,
7458 rdataset.ttl, &rdata));
7460 if (result != ISC_R_NOMORE)
7462 dns_rdataset_disassociate(&rdataset);
7465 if (rdataset.type != dns_rdatatype_rrsig) {
7466 dns_rdataset_disassociate(&rdataset);
7469 for (result = dns_rdataset_first(&rdataset);
7470 result == ISC_R_SUCCESS;
7471 result = dns_rdataset_next(&rdataset)) {
7472 dns_rdata_t rdata = DNS_RDATA_INIT;
7473 dns_rdataset_current(&rdataset, &rdata);
7474 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
7475 if (rrsig.algorithm != algorithm ||
7476 rrsig.keyid != keyid)
7478 CHECK(update_one_rr(db, version, diff,
7479 DNS_DIFFOP_DELRESIGN, name,
7480 rdataset.ttl, &rdata));
7482 dns_rdataset_disassociate(&rdataset);
7483 if (result != ISC_R_NOMORE)
7486 if (result == ISC_R_NOMORE)
7487 result = ISC_R_SUCCESS;
7489 if (dns_rdataset_isassociated(&rdataset))
7490 dns_rdataset_disassociate(&rdataset);
7491 dns_rdatasetiter_destroy(&iterator);
7496 * Incrementally sign the zone using the keys requested.
7497 * Builds the NSEC chain if required.
7500 zone_sign(dns_zone_t *zone) {
7501 const char *me = "zone_sign";
7502 dns_db_t *db = NULL;
7503 dns_dbnode_t *node = NULL;
7504 dns_dbversion_t *version = NULL;
7505 dns_diff_t _sig_diff;
7506 dns_diff_t post_diff;
7507 zonediff_t zonediff;
7508 dns_fixedname_t fixed;
7509 dns_fixedname_t nextfixed;
7510 dns_name_t *name, *nextname;
7511 dns_rdataset_t rdataset;
7512 dns_signing_t *signing, *nextsigning;
7513 dns_signinglist_t cleanup;
7514 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
7515 isc_int32_t signatures;
7516 isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
7517 isc_boolean_t commit = ISC_FALSE;
7518 isc_boolean_t delegation;
7519 isc_boolean_t build_nsec = ISC_FALSE;
7520 isc_boolean_t build_nsec3 = ISC_FALSE;
7521 isc_boolean_t first;
7522 isc_result_t result;
7523 isc_stdtime_t now, inception, soaexpire, expire;
7524 isc_uint32_t jitter;
7526 unsigned int nkeys = 0;
7531 dns_rdataset_init(&rdataset);
7532 dns_fixedname_init(&fixed);
7533 name = dns_fixedname_name(&fixed);
7534 dns_fixedname_init(&nextfixed);
7535 nextname = dns_fixedname_name(&nextfixed);
7536 dns_diff_init(zone->mctx, &_sig_diff);
7537 dns_diff_init(zone->mctx, &post_diff);
7538 zonediff_init(&zonediff, &_sig_diff);
7539 ISC_LIST_INIT(cleanup);
7542 * Updates are disabled. Pause for 5 minutes.
7544 if (zone->update_disabled) {
7545 result = ISC_R_FAILURE;
7549 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7550 if (zone->db != NULL)
7551 dns_db_attach(zone->db, &db);
7552 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7554 result = ISC_R_FAILURE;
7558 result = dns_db_newversion(db, &version);
7559 if (result != ISC_R_SUCCESS) {
7560 dns_zone_log(zone, ISC_LOG_ERROR,
7561 "zone_sign:dns_db_newversion -> %s",
7562 dns_result_totext(result));
7566 result = find_zone_keys(zone, db, version, zone->mctx,
7567 DNS_MAXZONEKEYS, zone_keys, &nkeys);
7568 if (result != ISC_R_SUCCESS) {
7569 dns_zone_log(zone, ISC_LOG_ERROR,
7570 "zone_sign:find_zone_keys -> %s",
7571 dns_result_totext(result));
7575 isc_stdtime_get(&now);
7576 inception = now - 3600; /* Allow for clock skew. */
7577 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
7580 * Spread out signatures over time if they happen to be
7581 * clumped. We don't do this for each add_sigs() call as
7582 * we still want some clustering to occur.
7584 isc_random_get(&jitter);
7585 expire = soaexpire - jitter % 3600;
7588 * We keep pulling nodes off each iterator in turn until
7589 * we have no more nodes to pull off or we reach the limits
7592 nodes = zone->nodes;
7593 signatures = zone->signatures;
7594 signing = ISC_LIST_HEAD(zone->signing);
7597 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
7598 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
7600 /* Determine which type of chain to build */
7601 CHECK(dns_private_chains(db, version, zone->privatetype,
7602 &build_nsec, &build_nsec3));
7604 /* If neither chain is found, default to NSEC */
7605 if (!build_nsec && !build_nsec3)
7606 build_nsec = ISC_TRUE;
7608 while (signing != NULL && nodes-- > 0 && signatures > 0) {
7609 nextsigning = ISC_LIST_NEXT(signing, link);
7611 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7612 if (signing->done || signing->db != zone->db) {
7614 * The zone has been reloaded. We will have
7615 * created new signings as part of the reload
7616 * process so we can destroy this one.
7618 ISC_LIST_UNLINK(zone->signing, signing, link);
7619 ISC_LIST_APPEND(cleanup, signing, link);
7620 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7623 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7625 if (signing->db != db)
7628 delegation = ISC_FALSE;
7630 if (first && signing->delete) {
7632 * Remove the key we are deleting from consideration.
7634 for (i = 0, j = 0; i < nkeys; i++) {
7636 * Find the key we want to remove.
7638 if (ALG(zone_keys[i]) == signing->algorithm &&
7639 dst_key_id(zone_keys[i]) == signing->keyid)
7641 if (KSK(zone_keys[i]))
7642 dst_key_free(&zone_keys[i]);
7645 zone_keys[j] = zone_keys[i];
7651 dns_dbiterator_current(signing->dbiterator, &node, name);
7653 if (signing->delete) {
7654 dns_dbiterator_pause(signing->dbiterator);
7655 CHECK(del_sig(db, version, name, node, nkeys,
7656 signing->algorithm, signing->keyid,
7661 * On the first pass we need to check if the current node
7662 * has not been obscured.
7665 dns_fixedname_t ffound;
7667 dns_fixedname_init(&ffound);
7668 found = dns_fixedname_name(&ffound);
7669 result = dns_db_find(db, name, version,
7671 DNS_DBFIND_NOWILD, 0, NULL, found,
7673 if ((result == DNS_R_DELEGATION ||
7674 result == DNS_R_DNAME) &&
7675 !dns_name_equal(name, found)) {
7677 * Remember the obscuring name so that
7678 * we skip all obscured names.
7680 dns_name_copy(found, name, NULL);
7681 delegation = ISC_TRUE;
7689 dns_dbiterator_pause(signing->dbiterator);
7690 for (i = 0; i < nkeys; i++) {
7691 isc_boolean_t both = ISC_FALSE;
7694 * Find the keys we want to sign with.
7696 if (!dst_key_isprivate(zone_keys[i]))
7700 * When adding look for the specific key.
7702 if (!signing->delete &&
7703 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
7704 dst_key_id(zone_keys[i]) != signing->keyid))
7708 * When deleting make sure we are properly signed
7709 * with the algorithm that was being removed.
7711 if (signing->delete &&
7712 ALG(zone_keys[i]) != signing->algorithm)
7716 * Do we do KSK processing?
7718 if (check_ksk && !REVOKE(zone_keys[i])) {
7719 isc_boolean_t have_ksk, have_nonksk;
7720 if (KSK(zone_keys[i])) {
7721 have_ksk = ISC_TRUE;
7722 have_nonksk = ISC_FALSE;
7724 have_ksk = ISC_FALSE;
7725 have_nonksk = ISC_TRUE;
7727 for (j = 0; j < nkeys; j++) {
7729 ALG(zone_keys[i]) !=
7732 if (REVOKE(zone_keys[j]))
7734 if (KSK(zone_keys[j]))
7735 have_ksk = ISC_TRUE;
7737 have_nonksk = ISC_TRUE;
7738 both = have_ksk && have_nonksk;
7743 if (both || REVOKE(zone_keys[i]))
7744 is_ksk = KSK(zone_keys[i]);
7748 CHECK(sign_a_node(db, name, node, version, build_nsec3,
7749 build_nsec, zone_keys[i], inception,
7750 expire, zone->minimum, is_ksk,
7751 ISC_TF(both && keyset_kskonly),
7752 &delegation, zonediff.diff,
7753 &signatures, zone->mctx));
7755 * If we are adding we are done. Look for other keys
7756 * of the same algorithm if deleting.
7758 if (!signing->delete)
7763 * Go onto next node.
7767 dns_db_detachnode(db, &node);
7769 result = dns_dbiterator_next(signing->dbiterator);
7770 if (result == ISC_R_NOMORE) {
7771 ISC_LIST_UNLINK(zone->signing, signing, link);
7772 ISC_LIST_APPEND(cleanup, signing, link);
7773 dns_dbiterator_pause(signing->dbiterator);
7774 if (nkeys != 0 && build_nsec) {
7776 * We have finished regenerating the
7777 * zone with a zone signing key.
7778 * The NSEC chain is now complete and
7779 * there is a full set of signatures
7780 * for the zone. We can now clear the
7781 * OPT bit from the NSEC record.
7783 result = updatesecure(db, version,
7788 if (result != ISC_R_SUCCESS) {
7791 "updatesecure -> %s",
7792 dns_result_totext(result));
7796 result = updatesignwithkey(zone, signing,
7801 if (result != ISC_R_SUCCESS) {
7802 dns_zone_log(zone, ISC_LOG_ERROR,
7803 "updatesignwithkey -> %s",
7804 dns_result_totext(result));
7807 build_nsec = ISC_FALSE;
7809 } else if (result != ISC_R_SUCCESS) {
7810 dns_zone_log(zone, ISC_LOG_ERROR,
7811 "zone_sign:dns_dbiterator_next -> %s",
7812 dns_result_totext(result));
7814 } else if (delegation) {
7815 dns_dbiterator_current(signing->dbiterator,
7817 dns_db_detachnode(db, &node);
7818 if (!dns_name_issubdomain(nextname, name))
7826 dns_dbiterator_pause(signing->dbiterator);
7827 signing = nextsigning;
7831 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
7832 result = update_sigs(&post_diff, db, version, zone_keys,
7833 nkeys, zone, inception, expire, now,
7834 check_ksk, keyset_kskonly, &zonediff);
7835 if (result != ISC_R_SUCCESS) {
7836 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
7837 "update_sigs -> %s",
7838 dns_result_totext(result));
7844 * Have we changed anything?
7846 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7847 if (zonediff.offline)
7849 result = ISC_R_SUCCESS;
7855 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7856 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7857 if (result != ISC_R_SUCCESS) {
7858 dns_zone_log(zone, ISC_LOG_ERROR,
7859 "zone_sign:del_sigs -> %s",
7860 dns_result_totext(result));
7864 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7865 zone->updatemethod);
7866 if (result != ISC_R_SUCCESS) {
7867 dns_zone_log(zone, ISC_LOG_ERROR,
7868 "zone_sign:update_soa_serial -> %s",
7869 dns_result_totext(result));
7874 * Generate maximum life time signatures so that the above loop
7875 * termination is sensible.
7877 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7878 zonediff.diff, zone_keys, nkeys, zone->mctx,
7879 inception, soaexpire, check_ksk, keyset_kskonly);
7880 if (result != ISC_R_SUCCESS) {
7881 dns_zone_log(zone, ISC_LOG_ERROR,
7882 "zone_sign:add_sigs -> %s",
7883 dns_result_totext(result));
7888 * Write changes to journal file.
7890 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
7894 * Pause all iterators so that dns_db_closeversion() can succeed.
7896 for (signing = ISC_LIST_HEAD(zone->signing);
7898 signing = ISC_LIST_NEXT(signing, link))
7899 dns_dbiterator_pause(signing->dbiterator);
7901 for (signing = ISC_LIST_HEAD(cleanup);
7903 signing = ISC_LIST_NEXT(signing, link))
7904 dns_dbiterator_pause(signing->dbiterator);
7907 * Everything has succeeded. Commit the changes.
7909 dns_db_closeversion(db, &version, commit);
7912 * Everything succeeded so we can clean these up now.
7914 signing = ISC_LIST_HEAD(cleanup);
7915 while (signing != NULL) {
7916 ISC_LIST_UNLINK(cleanup, signing, link);
7917 dns_db_detach(&signing->db);
7918 dns_dbiterator_destroy(&signing->dbiterator);
7919 isc_mem_put(zone->mctx, signing, sizeof *signing);
7920 signing = ISC_LIST_HEAD(cleanup);
7923 set_resigntime(zone);
7927 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7928 zone_needdump(zone, DNS_DUMP_DELAY);
7934 * Rollback the cleanup list.
7936 signing = ISC_LIST_HEAD(cleanup);
7937 while (signing != NULL) {
7938 ISC_LIST_UNLINK(cleanup, signing, link);
7939 ISC_LIST_PREPEND(zone->signing, signing, link);
7940 dns_dbiterator_first(signing->dbiterator);
7941 dns_dbiterator_pause(signing->dbiterator);
7942 signing = ISC_LIST_HEAD(cleanup);
7945 for (signing = ISC_LIST_HEAD(zone->signing);
7947 signing = ISC_LIST_NEXT(signing, link))
7948 dns_dbiterator_pause(signing->dbiterator);
7950 dns_diff_clear(&_sig_diff);
7952 for (i = 0; i < nkeys; i++)
7953 dst_key_free(&zone_keys[i]);
7956 dns_db_detachnode(db, &node);
7958 if (version != NULL) {
7959 dns_db_closeversion(db, &version, ISC_FALSE);
7961 } else if (db != NULL)
7964 if (ISC_LIST_HEAD(zone->signing) != NULL) {
7965 isc_interval_t interval;
7966 if (zone->update_disabled || result != ISC_R_SUCCESS)
7967 isc_interval_set(&interval, 60, 0); /* 1 minute */
7969 isc_interval_set(&interval, 0, 10000000); /* 10 ms */
7970 isc_time_nowplusinterval(&zone->signingtime, &interval);
7972 isc_time_settoepoch(&zone->signingtime);
7974 INSIST(version == NULL);
7978 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
7979 unsigned char *data, int size)
7981 dns_rdata_dnskey_t dnskey;
7982 dns_rdata_keydata_t keydata;
7984 isc_result_t result;
7986 dns_rdata_reset(target);
7987 isc_buffer_init(&buf, data, size);
7990 case dns_rdatatype_dnskey:
7991 result = dns_rdata_tostruct(rr, &dnskey, NULL);
7992 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7993 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
7994 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7997 case dns_rdatatype_keydata:
7998 result = dns_rdata_tostruct(rr, &keydata, NULL);
7999 if (result == ISC_R_UNEXPECTEDEND)
8001 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8002 dns_keydata_todnskey(&keydata, &dnskey, NULL);
8003 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
8009 return (ISC_R_SUCCESS);
8013 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
8014 * a KEYDATA rdataset from the key zone.
8016 * 'rr' contains either a DNSKEY record, or a KEYDATA record
8018 * After normalizing keys to the same format (DNSKEY, with revoke bit
8019 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
8020 * 'rdset', or ISC_FALSE if not.
8023 static isc_boolean_t
8024 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
8025 unsigned char data1[4096], data2[4096];
8026 dns_rdata_t rdata, rdata1, rdata2;
8027 isc_result_t result;
8029 dns_rdata_init(&rdata);
8030 dns_rdata_init(&rdata1);
8031 dns_rdata_init(&rdata2);
8033 result = normalize_key(rr, &rdata1, data1, sizeof(data1));
8034 if (result != ISC_R_SUCCESS)
8037 for (result = dns_rdataset_first(rdset);
8038 result == ISC_R_SUCCESS;
8039 result = dns_rdataset_next(rdset)) {
8040 dns_rdata_reset(&rdata);
8041 dns_rdataset_current(rdset, &rdata);
8042 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
8043 if (result != ISC_R_SUCCESS)
8045 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
8053 * Calculate the refresh interval for a keydata zone, per
8054 * RFC5011: MAX(1 hr,
8057 * 1/2 * RRSigExpirationInterval))
8058 * or for retries: MAX(1 hr,
8061 * 1/10 * RRSigExpirationInterval))
8063 static inline isc_stdtime_t
8064 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
8065 isc_result_t result;
8067 dns_rdataset_t *rdset;
8068 dns_rdata_t sigrr = DNS_RDATA_INIT;
8069 dns_rdata_sig_t sig;
8072 isc_stdtime_get(&now);
8074 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8075 rdset = &kfetch->dnskeysigset;
8077 return (now + dns_zone_mkey_hour);
8079 result = dns_rdataset_first(rdset);
8080 if (result != ISC_R_SUCCESS)
8081 return (now + dns_zone_mkey_hour);
8083 dns_rdataset_current(rdset, &sigrr);
8084 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8085 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8088 t = sig.originalttl / 2;
8090 if (isc_serial_gt(sig.timeexpire, now)) {
8091 isc_uint32_t exp = (sig.timeexpire - now) / 2;
8096 if (t > (15 * dns_zone_mkey_day))
8097 t = (15 * dns_zone_mkey_day);
8099 if (t < dns_zone_mkey_hour)
8100 t = dns_zone_mkey_hour;
8102 t = sig.originalttl / 10;
8104 if (isc_serial_gt(sig.timeexpire, now)) {
8105 isc_uint32_t exp = (sig.timeexpire - now) / 10;
8110 if (t > dns_zone_mkey_day)
8111 t = dns_zone_mkey_day;
8113 if (t < dns_zone_mkey_hour)
8114 t = dns_zone_mkey_hour;
8121 * This routine is called when no changes are needed in a KEYDATA
8122 * record except to simply update the refresh timer. Caller should
8126 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
8128 isc_result_t result;
8130 unsigned char key_buf[4096];
8131 dns_rdata_t rdata = DNS_RDATA_INIT;
8132 dns_rdata_keydata_t keydata;
8134 dns_zone_t *zone = kfetch->zone;
8137 name = dns_fixedname_name(&kfetch->name);
8138 isc_stdtime_get(&now);
8140 for (result = dns_rdataset_first(&kfetch->keydataset);
8141 result == ISC_R_SUCCESS;
8142 result = dns_rdataset_next(&kfetch->keydataset)) {
8143 dns_rdata_reset(&rdata);
8144 dns_rdataset_current(&kfetch->keydataset, &rdata);
8146 /* Delete old version */
8147 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
8150 /* Update refresh timer */
8151 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
8152 if (result == ISC_R_UNEXPECTEDEND)
8154 if (result != ISC_R_SUCCESS)
8156 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
8157 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
8159 dns_rdata_reset(&rdata);
8160 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8161 CHECK(dns_rdata_fromstruct(&rdata,
8162 zone->rdclass, dns_rdatatype_keydata,
8165 /* Insert updated version */
8166 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
8169 result = ISC_R_SUCCESS;
8175 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
8177 static isc_boolean_t
8178 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
8179 isc_result_t result;
8180 dns_name_t *keyname;
8182 dns_rdata_t sigrr = DNS_RDATA_INIT;
8183 dns_rdata_t rr = DNS_RDATA_INIT;
8184 dns_rdata_rrsig_t sig;
8185 dns_rdata_dnskey_t dnskey;
8186 dst_key_t *dstkey = NULL;
8187 unsigned char key_buf[4096];
8189 isc_boolean_t answer = ISC_FALSE;
8191 REQUIRE(kfetch != NULL && keydata != NULL);
8192 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
8194 keyname = dns_fixedname_name(&kfetch->name);
8195 mctx = kfetch->zone->view->mctx;
8197 /* Generate a key from keydata */
8198 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8199 dns_keydata_todnskey(keydata, &dnskey, NULL);
8200 dns_rdata_fromstruct(&rr, keydata->common.rdclass,
8201 dns_rdatatype_dnskey, &dnskey, &keyb);
8202 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
8203 if (result != ISC_R_SUCCESS)
8206 /* See if that key generated any of the signatures */
8207 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8208 result == ISC_R_SUCCESS;
8209 result = dns_rdataset_next(&kfetch->dnskeysigset))
8211 dns_fixedname_t fixed;
8212 dns_fixedname_init(&fixed);
8214 dns_rdata_reset(&sigrr);
8215 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8216 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8217 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8219 if (dst_key_alg(dstkey) == sig.algorithm &&
8220 dst_key_rid(dstkey) == sig.keyid)
8222 result = dns_dnssec_verify2(keyname,
8224 dstkey, ISC_FALSE, mctx, &sigrr,
8225 dns_fixedname_name(&fixed));
8227 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
8228 "Confirm revoked DNSKEY is self-signed: "
8229 "%s", dns_result_totext(result));
8231 if (result == ISC_R_SUCCESS) {
8238 dst_key_free(&dstkey);
8243 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
8244 * anchors are being managed; scan the keyset, and update the key zone and the
8245 * local trust anchors according to RFC5011.
8248 keyfetch_done(isc_task_t *task, isc_event_t *event) {
8249 isc_result_t result, eresult;
8250 dns_fetchevent_t *devent;
8251 dns_keyfetch_t *kfetch;
8253 isc_mem_t *mctx = NULL;
8254 dns_keytable_t *secroots = NULL;
8255 dns_dbversion_t *ver = NULL;
8257 isc_boolean_t alldone = ISC_FALSE;
8258 isc_boolean_t commit = ISC_FALSE;
8259 dns_name_t *keyname;
8260 dns_rdata_t sigrr = DNS_RDATA_INIT;
8261 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
8262 dns_rdata_t keydatarr = DNS_RDATA_INIT;
8263 dns_rdata_rrsig_t sig;
8264 dns_rdata_dnskey_t dnskey;
8265 dns_rdata_keydata_t keydata;
8266 isc_boolean_t initializing;
8267 char namebuf[DNS_NAME_FORMATSIZE];
8268 unsigned char key_buf[4096];
8273 isc_boolean_t secure;
8274 isc_boolean_t free_needed;
8277 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
8278 INSIST(event->ev_arg != NULL);
8280 kfetch = event->ev_arg;
8281 zone = kfetch->zone;
8282 isc_mem_attach(zone->mctx, &mctx);
8283 keyname = dns_fixedname_name(&kfetch->name);
8285 devent = (dns_fetchevent_t *) event;
8286 eresult = devent->result;
8288 /* Free resources which are not of interest */
8289 if (devent->node != NULL)
8290 dns_db_detachnode(devent->db, &devent->node);
8291 if (devent->db != NULL)
8292 dns_db_detach(&devent->db);
8293 isc_event_free(&event);
8294 dns_resolver_destroyfetch(&kfetch->fetch);
8297 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
8300 isc_stdtime_get(&now);
8301 dns_name_format(keyname, namebuf, sizeof(namebuf));
8303 result = dns_view_getsecroots(zone->view, &secroots);
8304 INSIST(result == ISC_R_SUCCESS);
8306 dns_diff_init(mctx, &diff);
8308 CHECK(dns_db_newversion(kfetch->db, &ver));
8310 zone->refreshkeycount--;
8311 alldone = ISC_TF(zone->refreshkeycount == 0);
8314 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8317 if (eresult != ISC_R_SUCCESS ||
8318 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
8319 dns_zone_log(zone, ISC_LOG_WARNING,
8320 "Unable to fetch DNSKEY set "
8321 "'%s': %s", namebuf, dns_result_totext(eresult));
8322 CHECK(minimal_update(kfetch, ver, &diff));
8326 /* No RRSIGs found */
8327 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
8328 dns_zone_log(zone, ISC_LOG_WARNING,
8329 "No DNSKEY RRSIGs found for "
8330 "'%s': %s", namebuf, dns_result_totext(eresult));
8331 CHECK(minimal_update(kfetch, ver, &diff));
8336 * Clear any cached trust level, as we need to run validation
8337 * over again; trusted keys might have changed.
8339 kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
8342 * Validate the dnskeyset against the current trusted keys.
8344 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8345 result == ISC_R_SUCCESS;
8346 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
8347 dns_keynode_t *keynode = NULL;
8349 dns_rdata_reset(&sigrr);
8350 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8351 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8352 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8354 result = dns_keytable_find(secroots, keyname, &keynode);
8355 while (result == ISC_R_SUCCESS) {
8356 dns_keynode_t *nextnode = NULL;
8357 dns_fixedname_t fixed;
8358 dns_fixedname_init(&fixed);
8360 dstkey = dns_keynode_key(keynode);
8361 if (dstkey == NULL) /* fail_secure() was called */
8364 if (dst_key_alg(dstkey) == sig.algorithm &&
8365 dst_key_id(dstkey) == sig.keyid) {
8366 result = dns_dnssec_verify2(keyname,
8369 zone->view->mctx, &sigrr,
8370 dns_fixedname_name(&fixed));
8372 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8373 "Verifying DNSKEY set for zone "
8374 "'%s' using key %d/%d: %s",
8375 namebuf, sig.keyid, sig.algorithm,
8376 dns_result_totext(result));
8378 if (result == ISC_R_SUCCESS) {
8379 kfetch->dnskeyset.trust =
8381 kfetch->dnskeysigset.trust =
8387 result = dns_keytable_nextkeynode(secroots,
8388 keynode, &nextnode);
8389 dns_keytable_detachkeynode(secroots, &keynode);
8393 if (keynode != NULL)
8394 dns_keytable_detachkeynode(secroots, &keynode);
8396 if (kfetch->dnskeyset.trust == dns_trust_secure)
8401 * If we were not able to verify the answer using the current
8402 * trusted keys then all we can do is look at any revoked keys.
8404 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
8407 * First scan keydataset to find keys that are not in dnskeyset
8408 * - Missing keys which are not scheduled for removal,
8410 * - Missing keys which are scheduled for removal and
8411 * the remove hold-down timer has completed should
8412 * be removed from the key zone
8413 * - Missing keys whose acceptance timers have not yet
8414 * completed, log a warning and reset the acceptance
8415 * timer to 30 days in the future
8416 * - All keys not being removed have their refresh timers
8419 initializing = ISC_TRUE;
8420 for (result = dns_rdataset_first(&kfetch->keydataset);
8421 result == ISC_R_SUCCESS;
8422 result = dns_rdataset_next(&kfetch->keydataset)) {
8423 dns_rdata_reset(&keydatarr);
8424 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8425 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8426 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8429 * If any keydata record has a nonzero add holddown, then
8430 * there was a pre-existing trust anchor for this domain;
8431 * that means we are *not* initializing it and shouldn't
8432 * automatically trust all the keys we find at the zone apex.
8434 initializing = initializing && ISC_TF(keydata.addhd == 0);
8436 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
8437 isc_boolean_t deletekey = ISC_FALSE;
8440 if (keydata.removehd != 0 &&
8441 keydata.removehd <= now)
8442 deletekey = ISC_TRUE;
8443 } else if (keydata.addhd == 0) {
8444 deletekey = ISC_TRUE;
8445 } else if (keydata.addhd > now) {
8446 dns_zone_log(zone, ISC_LOG_WARNING,
8447 "Pending key unexpectedly missing "
8448 "from %s; restarting acceptance "
8450 if (keydata.addhd < now + dns_zone_mkey_month)
8452 now + dns_zone_mkey_month;
8453 keydata.refresh = refresh_time(kfetch,
8455 } else if (keydata.removehd == 0) {
8456 dns_zone_log(zone, ISC_LOG_WARNING,
8457 "Active key unexpectedly missing "
8458 "from %s", namebuf);
8459 keydata.refresh = now + dns_zone_mkey_hour;
8460 } else if (keydata.removehd <= now) {
8461 deletekey = ISC_TRUE;
8463 keydata.refresh = refresh_time(kfetch,
8467 if (secure || deletekey) {
8468 /* Delete old version */
8469 CHECK(update_one_rr(kfetch->db, ver, &diff,
8470 DNS_DIFFOP_DEL, keyname, 0,
8474 if (!secure || deletekey)
8477 dns_rdata_reset(&keydatarr);
8478 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8479 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8480 dns_rdatatype_keydata,
8483 /* Insert updated version */
8484 CHECK(update_one_rr(kfetch->db, ver, &diff,
8485 DNS_DIFFOP_ADD, keyname, 0,
8488 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
8493 * Next scan dnskeyset:
8494 * - If new keys are found (i.e., lacking a match in keydataset)
8495 * add them to the key zone and set the acceptance timer
8496 * to 30 days in the future (or to immediately if we've
8497 * determined that we're initializing the zone for the
8499 * - Previously-known keys that have been revoked
8500 * must be scheduled for removal from the key zone (or,
8501 * if they hadn't been accepted as trust anchors yet
8502 * anyway, removed at once)
8503 * - Previously-known unrevoked keys whose acceptance timers
8504 * have completed are promoted to trust anchors
8505 * - All keys not being removed have their refresh
8508 for (result = dns_rdataset_first(&kfetch->dnskeyset);
8509 result == ISC_R_SUCCESS;
8510 result = dns_rdataset_next(&kfetch->dnskeyset))
8512 isc_boolean_t revoked = ISC_FALSE;
8513 isc_boolean_t newkey = ISC_FALSE;
8514 isc_boolean_t updatekey = ISC_FALSE;
8515 isc_boolean_t deletekey = ISC_FALSE;
8516 isc_boolean_t trustkey = ISC_FALSE;
8518 dns_rdata_reset(&dnskeyrr);
8519 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
8520 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8521 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8524 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
8527 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
8529 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
8530 dns_rdata_reset(&keydatarr);
8531 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8532 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8533 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8535 if (revoked && revocable(kfetch, &keydata)) {
8536 if (keydata.addhd > now) {
8538 * Key wasn't trusted yet, and now
8539 * it's been revoked? Just remove it
8541 deletekey = ISC_TRUE;
8542 } else if (keydata.removehd == 0) {
8543 /* Remove from secroots */
8544 dns_view_untrust(zone->view, keyname,
8547 /* But ensure there's a null key */
8548 fail_secure(zone, keyname);
8550 /* If initializing, delete now */
8551 if (keydata.addhd == 0)
8552 deletekey = ISC_TRUE;
8554 keydata.removehd = now +
8555 dns_zone_mkey_month;
8559 } else if (keydata.removehd < now) {
8560 /* Scheduled for removal */
8561 deletekey = ISC_TRUE;
8563 } else if (revoked && keydata.removehd == 0) {
8564 dns_zone_log(zone, ISC_LOG_WARNING,
8565 "Active key for zone "
8566 "'%s' is revoked but "
8567 "did not self-sign; "
8568 "ignoring.", namebuf);
8570 } else if (secure) {
8571 if (keydata.removehd != 0) {
8573 * Key isn't revoked--but it
8574 * seems it used to be.
8575 * Remove it now and add it
8576 * back as if it were a fresh key,
8577 * with a 30 day acceptance timer.
8579 deletekey = ISC_TRUE;
8581 keydata.removehd = 0;
8583 now + dns_zone_mkey_month;
8584 } else if (keydata.addhd > now)
8586 else if (keydata.addhd == 0)
8587 keydata.addhd = now;
8589 if (keydata.addhd <= now)
8590 trustkey = ISC_TRUE;
8591 } else if (keydata.addhd > now) {
8593 * Not secure, and key is pending:
8594 * reset the acceptance timer
8597 keydata.addhd = now + dns_zone_mkey_month;
8600 if (!deletekey && !newkey)
8601 updatekey = ISC_TRUE;
8602 } else if (secure) {
8604 * Key wasn't in the key zone but it's
8605 * revoked now anyway, so just skip it
8610 /* Key wasn't in the key zone: add it */
8614 dns_keytag_t tag = 0;
8615 CHECK(compute_tag(keyname, &dnskey,
8617 dns_zone_log(zone, ISC_LOG_WARNING,
8618 "Initializing automatic trust "
8619 "anchor management for zone '%s'; "
8620 "DNSKEY ID %d is now trusted, "
8621 "waiving the normal 30-day "
8624 trustkey = ISC_TRUE;
8628 * No previously known key, and the key is not
8629 * secure, so skip it.
8634 /* Delete old version */
8635 if (deletekey || !newkey)
8636 CHECK(update_one_rr(kfetch->db, ver, &diff,
8637 DNS_DIFFOP_DEL, keyname, 0,
8641 /* Set refresh timer */
8642 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
8643 dns_rdata_reset(&keydatarr);
8644 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8645 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8646 dns_rdatatype_keydata,
8649 /* Insert updated version */
8650 CHECK(update_one_rr(kfetch->db, ver, &diff,
8651 DNS_DIFFOP_ADD, keyname, 0,
8653 } else if (newkey) {
8654 /* Convert DNSKEY to KEYDATA */
8655 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8656 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8657 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
8659 keydata.addhd = initializing
8660 ? now : now + dns_zone_mkey_month;
8661 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
8662 dns_rdata_reset(&keydatarr);
8663 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8664 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8665 dns_rdatatype_keydata,
8668 /* Insert into key zone */
8669 CHECK(update_one_rr(kfetch->db, ver, &diff,
8670 DNS_DIFFOP_ADD, keyname, 0,
8675 /* Trust this key. */
8676 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8677 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8678 trust_key(zone, keyname, &dnskey, mctx);
8681 if (secure && !deletekey) {
8682 INSIST(newkey || updatekey);
8683 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
8688 * RFC5011 says, "A trust point that has all of its trust anchors
8689 * revoked is considered deleted and is treated as if the trust
8690 * point was never configured." But if someone revoked their
8691 * active key before the standby was trusted, that would mean the
8692 * zone would suddenly be nonsecured. We avoid this by checking to
8693 * see if there's pending keydata. If so, we put a null key in
8694 * the security roots; then all queries to the zone will fail.
8697 fail_secure(zone, keyname);
8701 if (!ISC_LIST_EMPTY(diff.tuples)) {
8702 /* Write changes to journal file. */
8703 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
8704 zone->updatemethod));
8705 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
8708 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8709 zone_needdump(zone, 30);
8714 dns_diff_clear(&diff);
8716 dns_db_closeversion(kfetch->db, &ver, commit);
8719 dns_db_detach(&kfetch->db);
8721 INSIST(zone->irefs > 0);
8723 kfetch->zone = NULL;
8725 if (dns_rdataset_isassociated(&kfetch->keydataset))
8726 dns_rdataset_disassociate(&kfetch->keydataset);
8727 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
8728 dns_rdataset_disassociate(&kfetch->dnskeyset);
8729 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8730 dns_rdataset_disassociate(&kfetch->dnskeysigset);
8732 dns_name_free(keyname, mctx);
8733 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
8734 isc_mem_detach(&mctx);
8736 if (secroots != NULL)
8737 dns_keytable_detach(&secroots);
8739 free_needed = exit_check(zone);
8744 INSIST(ver == NULL);
8748 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
8749 * records from the zone apex.
8752 zone_refreshkeys(dns_zone_t *zone) {
8753 const char me[] = "zone_refreshkeys";
8754 isc_result_t result;
8755 dns_rriterator_t rrit;
8756 dns_db_t *db = NULL;
8757 dns_dbversion_t *ver = NULL;
8759 dns_rdata_t rdata = DNS_RDATA_INIT;
8760 dns_rdata_keydata_t kd;
8762 isc_boolean_t commit = ISC_FALSE;
8763 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
8766 REQUIRE(zone->db != NULL);
8768 isc_stdtime_get(&now);
8771 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
8772 isc_time_settoepoch(&zone->refreshkeytime);
8777 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8778 dns_db_attach(zone->db, &db);
8779 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8781 dns_diff_init(zone->mctx, &diff);
8783 CHECK(dns_db_newversion(db, &ver));
8785 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
8787 dns_rriterator_init(&rrit, db, ver, 0);
8788 for (result = dns_rriterator_first(&rrit);
8789 result == ISC_R_SUCCESS;
8790 result = dns_rriterator_nextrrset(&rrit)) {
8791 isc_stdtime_t timer = 0xffffffff;
8792 dns_name_t *name = NULL, *kname = NULL;
8793 dns_rdataset_t *kdset = NULL;
8794 dns_keyfetch_t *kfetch;
8797 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
8798 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
8799 !dns_rdataset_isassociated(kdset))
8803 * Scan the stored keys looking for ones that need
8804 * removal or refreshing
8806 for (result = dns_rdataset_first(kdset);
8807 result == ISC_R_SUCCESS;
8808 result = dns_rdataset_next(kdset)) {
8809 dns_rdata_reset(&rdata);
8810 dns_rdataset_current(kdset, &rdata);
8811 result = dns_rdata_tostruct(&rdata, &kd, NULL);
8812 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8814 /* Removal timer expired? */
8815 if (kd.removehd != 0 && kd.removehd < now) {
8816 CHECK(update_one_rr(db, ver, &diff,
8817 DNS_DIFFOP_DEL, name, ttl,
8822 /* Acceptance timer expired? */
8823 if (kd.addhd != 0 && kd.addhd < now)
8826 /* Or do we just need to refresh the keyset? */
8827 if (timer > kd.refresh)
8834 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
8835 if (kfetch == NULL) {
8836 fetch_err = ISC_TRUE;
8840 zone->refreshkeycount++;
8841 kfetch->zone = zone;
8843 INSIST(zone->irefs != 0);
8844 dns_fixedname_init(&kfetch->name);
8845 kname = dns_fixedname_name(&kfetch->name);
8846 dns_name_dup(name, zone->mctx, kname);
8847 dns_rdataset_init(&kfetch->dnskeyset);
8848 dns_rdataset_init(&kfetch->dnskeysigset);
8849 dns_rdataset_init(&kfetch->keydataset);
8850 dns_rdataset_clone(kdset, &kfetch->keydataset);
8852 dns_db_attach(db, &kfetch->db);
8853 kfetch->fetch = NULL;
8855 result = dns_resolver_createfetch(zone->view->resolver,
8856 kname, dns_rdatatype_dnskey,
8858 DNS_FETCHOPT_NOVALIDATE,
8860 keyfetch_done, kfetch,
8862 &kfetch->dnskeysigset,
8864 if (result == ISC_R_SUCCESS)
8865 fetching = ISC_TRUE;
8867 zone->refreshkeycount--;
8869 dns_db_detach(&kfetch->db);
8870 dns_rdataset_disassociate(&kfetch->keydataset);
8871 dns_name_free(kname, zone->mctx);
8872 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
8873 dns_zone_log(zone, ISC_LOG_WARNING,
8874 "Failed to create fetch for "
8876 fetch_err = ISC_TRUE;
8879 if (!ISC_LIST_EMPTY(diff.tuples)) {
8880 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
8881 zone->updatemethod));
8882 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
8884 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8885 zone_needdump(zone, 30);
8891 * Error during a key fetch; retry in an hour.
8893 isc_time_t timenow, timethen;
8897 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
8898 zone->refreshkeytime = timethen;
8899 zone_settimer(zone, &timenow);
8901 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
8902 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
8906 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8911 dns_diff_clear(&diff);
8913 dns_rriterator_destroy(&rrit);
8914 dns_db_closeversion(db, &ver, commit);
8918 INSIST(ver == NULL);
8922 zone_maintenance(dns_zone_t *zone) {
8923 const char me[] = "zone_maintenance";
8925 isc_result_t result;
8926 isc_boolean_t dumping;
8928 REQUIRE(DNS_ZONE_VALID(zone));
8932 * Are we pending load/reload?
8934 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
8938 * Configuring the view of this zone may have
8939 * failed, for example because the config file
8940 * had a syntax error. In that case, the view
8941 * adb or resolver will be NULL, and we had better not try
8942 * to do further maintenance on it.
8944 if (zone->view == NULL || zone->view->adb == NULL)
8952 switch (zone->type) {
8953 case dns_zone_redirect:
8954 if (zone->masters == NULL)
8956 case dns_zone_slave:
8959 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
8960 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8962 zone->refreshtime = now;
8973 switch (zone->type) {
8974 case dns_zone_redirect:
8975 if (zone->masters == NULL)
8977 case dns_zone_slave:
8979 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
8980 isc_time_compare(&now, &zone->refreshtime) >= 0)
8981 dns_zone_refresh(zone);
8988 * Slaves send notifies before backing up to disk, masters after.
8990 if (zone->type == dns_zone_slave &&
8991 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
8992 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
8993 isc_time_compare(&now, &zone->notifytime) >= 0)
8994 zone_notify(zone, &now);
8997 * Do we need to consolidate the backing store?
8999 switch (zone->type) {
9000 case dns_zone_master:
9001 case dns_zone_slave:
9003 case dns_zone_redirect:
9006 if (zone->masterfile != NULL &&
9007 isc_time_compare(&now, &zone->dumptime) >= 0 &&
9008 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
9009 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
9010 dumping = was_dumping(zone);
9015 result = zone_dump(zone, ISC_TRUE); /* task locked */
9016 if (result != ISC_R_SUCCESS)
9017 dns_zone_log(zone, ISC_LOG_WARNING,
9019 dns_result_totext(result));
9027 * Master/redirect zones send notifies now, if needed
9029 switch (zone->type) {
9030 case dns_zone_master:
9031 case dns_zone_redirect:
9032 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
9033 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&&
9034 isc_time_compare(&now, &zone->notifytime) >= 0)
9035 zone_notify(zone, &now);
9041 * Do we need to refresh keys?
9043 switch (zone->type) {
9045 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
9046 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
9047 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
9048 zone_refreshkeys(zone);
9052 case dns_zone_master:
9053 if (!isc_time_isepoch(&zone->refreshkeytime) &&
9054 isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
9055 zone->rss_event == NULL)
9061 switch (zone->type) {
9062 case dns_zone_master:
9063 case dns_zone_redirect:
9064 case dns_zone_slave:
9066 * Do we need to sign/resign some RRsets?
9068 if (zone->rss_event != NULL)
9070 if (!isc_time_isepoch(&zone->signingtime) &&
9071 isc_time_compare(&now, &zone->signingtime) >= 0)
9073 else if (!isc_time_isepoch(&zone->resigntime) &&
9074 isc_time_compare(&now, &zone->resigntime) >= 0)
9075 zone_resigninc(zone);
9076 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
9077 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
9078 zone_nsec3chain(zone);
9080 * Do we need to issue a key expiry warning?
9082 if (!isc_time_isepoch(&zone->keywarntime) &&
9083 isc_time_compare(&now, &zone->keywarntime) >= 0)
9084 set_key_expiry_warning(zone, zone->key_expiry,
9085 isc_time_seconds(&now));
9091 zone_settimer(zone, &now);
9095 dns_zone_markdirty(dns_zone_t *zone) {
9096 isc_uint32_t serial;
9097 isc_result_t result = ISC_R_SUCCESS;
9098 dns_zone_t *secure = NULL;
9101 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
9102 * could result in a deadlock due to a LOR so we will spin if we
9103 * can't obtain the both locks.
9107 if (zone->type == dns_zone_master) {
9108 if (inline_raw(zone)) {
9109 unsigned int soacount;
9110 secure = zone->secure;
9111 INSIST(secure != zone);
9112 TRYLOCK_ZONE(result, secure);
9113 if (result != ISC_R_SUCCESS) {
9116 #ifdef ISC_PLATFORM_USETHREADS
9122 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9123 if (zone->db != NULL) {
9124 result = zone_get_from_db(zone, zone->db, NULL,
9129 result = DNS_R_NOTLOADED;
9130 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9131 if (result == ISC_R_SUCCESS && soacount > 0U)
9132 zone_send_secureserial(zone, serial);
9135 /* XXXMPA make separate call back */
9136 if (result == ISC_R_SUCCESS)
9137 set_resigntime(zone);
9140 UNLOCK_ZONE(secure);
9141 zone_needdump(zone, DNS_DUMP_DELAY);
9146 dns_zone_expire(dns_zone_t *zone) {
9147 REQUIRE(DNS_ZONE_VALID(zone));
9155 zone_expire(dns_zone_t *zone) {
9157 * 'zone' locked by caller.
9160 REQUIRE(LOCKED_ZONE(zone));
9162 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
9164 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
9165 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9166 zone->retry = DNS_ZONE_DEFAULTRETRY;
9167 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9172 dns_zone_refresh(dns_zone_t *zone) {
9174 isc_uint32_t oldflags;
9176 isc_result_t result;
9178 REQUIRE(DNS_ZONE_VALID(zone));
9180 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9184 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
9185 * in progress at a time.
9189 oldflags = zone->flags;
9190 if (zone->masterscnt == 0) {
9191 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
9192 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
9193 dns_zone_log(zone, ISC_LOG_ERROR,
9194 "cannot refresh: no masters");
9197 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9198 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9199 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9200 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
9204 * Set the next refresh time as if refresh check has failed.
9205 * Setting this to the retry time will do that. XXXMLG
9206 * If we are successful it will be reset using zone->refresh.
9208 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
9210 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
9211 if (result != ISC_R_SUCCESS)
9212 dns_zone_log(zone, ISC_LOG_WARNING,
9213 "isc_time_nowplusinterval() failed: %s",
9214 dns_result_totext(result));
9217 * When lacking user-specified timer values from the SOA,
9218 * do exponential backoff of the retry time up to a
9219 * maximum of six hours.
9221 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
9222 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
9224 zone->curmaster = 0;
9225 for (j = 0; j < zone->masterscnt; j++)
9226 zone->mastersok[j] = ISC_FALSE;
9227 /* initiate soa query */
9228 queue_soa_query(zone);
9234 dns_zone_flush(dns_zone_t *zone) {
9235 isc_result_t result = ISC_R_SUCCESS;
9236 isc_boolean_t dumping;
9238 REQUIRE(DNS_ZONE_VALID(zone));
9241 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
9242 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9243 zone->masterfile != NULL) {
9244 result = ISC_R_ALREADYRUNNING;
9245 dumping = was_dumping(zone);
9250 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
9255 dns_zone_dump(dns_zone_t *zone) {
9256 isc_result_t result = ISC_R_ALREADYRUNNING;
9257 isc_boolean_t dumping;
9259 REQUIRE(DNS_ZONE_VALID(zone));
9262 dumping = was_dumping(zone);
9265 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
9270 zone_needdump(dns_zone_t *zone, unsigned int delay) {
9271 const char me[] = "zone_needdump";
9272 isc_time_t dumptime;
9276 * 'zone' locked by caller
9279 REQUIRE(DNS_ZONE_VALID(zone));
9280 REQUIRE(LOCKED_ZONE(zone));
9284 * Do we have a place to dump to and are we loaded?
9286 if (zone->masterfile == NULL ||
9287 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
9291 /* add some noise */
9292 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
9294 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9295 if (isc_time_isepoch(&zone->dumptime) ||
9296 isc_time_compare(&zone->dumptime, &dumptime) > 0)
9297 zone->dumptime = dumptime;
9298 if (zone->task != NULL)
9299 zone_settimer(zone, &now);
9303 dump_done(void *arg, isc_result_t result) {
9304 const char me[] = "dump_done";
9305 dns_zone_t *zone = arg;
9307 dns_dbversion_t *version;
9308 isc_boolean_t again = ISC_FALSE;
9309 isc_boolean_t compact = ISC_FALSE;
9310 isc_uint32_t serial;
9311 isc_result_t tresult;
9313 REQUIRE(DNS_ZONE_VALID(zone));
9317 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
9318 zone->journalsize != -1) {
9321 * We don't own these, zone->dctx must stay valid.
9323 db = dns_dumpctx_db(zone->dctx);
9324 version = dns_dumpctx_version(zone->dctx);
9326 tresult = dns_db_getsoaserial(db, version, &serial);
9328 * If there is a secure version of this zone
9329 * use its serial if it is less than ours.
9331 if (tresult == ISC_R_SUCCESS && inline_raw(zone) &&
9332 zone->secure->db != NULL)
9334 isc_uint32_t sserial;
9335 isc_result_t mresult;
9337 mresult = dns_db_getsoaserial(zone->secure->db,
9339 if (mresult == ISC_R_SUCCESS &&
9340 isc_serial_lt(sserial, serial))
9344 * Note: we are task locked here so we can test
9347 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
9348 tresult = dns_journal_compact(zone->mctx,
9355 case ISC_R_NOTFOUND:
9356 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9357 "dns_journal_compact: %s",
9358 dns_result_totext(tresult));
9361 dns_zone_log(zone, ISC_LOG_ERROR,
9362 "dns_journal_compact failed: %s",
9363 dns_result_totext(tresult));
9366 } else if (tresult == ISC_R_SUCCESS) {
9368 zone->compact_serial = serial;
9373 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9375 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9376 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
9378 * Try again in a short while.
9380 zone_needdump(zone, DNS_DUMP_DELAY);
9381 } else if (result == ISC_R_SUCCESS &&
9382 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9383 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9384 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9385 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9386 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9387 isc_time_settoepoch(&zone->dumptime);
9389 } else if (result == ISC_R_SUCCESS)
9390 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9392 if (zone->dctx != NULL)
9393 dns_dumpctx_detach(&zone->dctx);
9394 zonemgr_putio(&zone->writeio);
9397 (void)zone_dump(zone, ISC_FALSE);
9398 dns_zone_idetach(&zone);
9402 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
9403 const char me[] = "zone_dump";
9404 isc_result_t result;
9405 dns_dbversion_t *version = NULL;
9406 isc_boolean_t again;
9407 dns_db_t *db = NULL;
9408 char *masterfile = NULL;
9409 dns_masterformat_t masterformat = dns_masterformat_none;
9412 * 'compact' MUST only be set if we are task locked.
9415 REQUIRE(DNS_ZONE_VALID(zone));
9419 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9420 if (zone->db != NULL)
9421 dns_db_attach(zone->db, &db);
9422 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9424 if (zone->masterfile != NULL) {
9425 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
9426 masterformat = zone->masterformat;
9430 result = DNS_R_NOTLOADED;
9433 if (masterfile == NULL) {
9434 result = DNS_R_NOMASTERFILE;
9438 if (compact && zone->type != dns_zone_stub) {
9439 dns_zone_t *dummy = NULL;
9441 zone_iattach(zone, &dummy);
9442 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
9443 zone_gotwritehandle, zone,
9445 if (result != ISC_R_SUCCESS)
9446 zone_idetach(&dummy);
9448 result = DNS_R_CONTINUE;
9451 const dns_master_style_t *output_style;
9453 dns_masterrawheader_t rawdata;
9454 dns_db_currentversion(db, &version);
9455 dns_master_initrawheader(&rawdata);
9456 if (inline_secure(zone))
9457 get_raw_serial(zone->raw, &rawdata);
9458 if (zone->type == dns_zone_key)
9459 output_style = &dns_master_style_keyzone;
9461 output_style = &dns_master_style_default;
9462 result = dns_master_dump3(zone->mctx, db, version,
9463 output_style, masterfile,
9464 masterformat, &rawdata);
9465 dns_db_closeversion(db, &version, ISC_FALSE);
9470 if (masterfile != NULL)
9471 isc_mem_free(zone->mctx, masterfile);
9474 if (result == DNS_R_CONTINUE)
9475 return (ISC_R_SUCCESS); /* XXXMPA */
9479 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9480 if (result != ISC_R_SUCCESS) {
9482 * Try again in a short while.
9484 zone_needdump(zone, DNS_DUMP_DELAY);
9485 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9486 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9487 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9488 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9489 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9490 isc_time_settoepoch(&zone->dumptime);
9493 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9502 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
9503 dns_masterformat_t format, const isc_uint32_t rawversion)
9505 isc_result_t result;
9506 dns_dbversion_t *version = NULL;
9507 dns_db_t *db = NULL;
9508 dns_masterrawheader_t rawdata;
9510 REQUIRE(DNS_ZONE_VALID(zone));
9512 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9513 if (zone->db != NULL)
9514 dns_db_attach(zone->db, &db);
9515 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9517 return (DNS_R_NOTLOADED);
9519 dns_db_currentversion(db, &version);
9520 dns_master_initrawheader(&rawdata);
9521 if (rawversion == 0)
9522 rawdata.flags |= DNS_MASTERRAW_COMPAT;
9523 else if (inline_secure(zone))
9524 get_raw_serial(zone->raw, &rawdata);
9525 else if (zone->sourceserialset) {
9526 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
9527 rawdata.sourceserial = zone->sourceserial;
9529 result = dns_master_dumptostream3(zone->mctx, db, version, style,
9530 format, &rawdata, fd);
9531 dns_db_closeversion(db, &version, ISC_FALSE);
9537 dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9538 const dns_master_style_t *style,
9539 const isc_uint32_t rawversion)
9541 return (dumptostream(zone, fd, style, format, rawversion));
9545 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9546 const dns_master_style_t *style) {
9547 return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
9551 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
9552 return (dumptostream(zone, fd, &dns_master_style_default,
9553 dns_masterformat_text, 0));
9557 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
9558 return (dumptostream(zone, fd, &dns_master_style_full,
9559 dns_masterformat_text, 0));
9563 dns_zone_unload(dns_zone_t *zone) {
9564 REQUIRE(DNS_ZONE_VALID(zone));
9572 notify_cancel(dns_zone_t *zone) {
9573 dns_notify_t *notify;
9576 * 'zone' locked by caller.
9579 REQUIRE(LOCKED_ZONE(zone));
9581 for (notify = ISC_LIST_HEAD(zone->notifies);
9583 notify = ISC_LIST_NEXT(notify, link)) {
9584 if (notify->find != NULL)
9585 dns_adb_cancelfind(notify->find);
9586 if (notify->request != NULL)
9587 dns_request_cancel(notify->request);
9592 forward_cancel(dns_zone_t *zone) {
9593 dns_forward_t *forward;
9596 * 'zone' locked by caller.
9599 REQUIRE(LOCKED_ZONE(zone));
9601 for (forward = ISC_LIST_HEAD(zone->forwards);
9603 forward = ISC_LIST_NEXT(forward, link)) {
9604 if (forward->request != NULL)
9605 dns_request_cancel(forward->request);
9610 zone_unload(dns_zone_t *zone) {
9612 * 'zone' locked by caller.
9615 REQUIRE(LOCKED_ZONE(zone));
9617 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
9618 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
9619 if (zone->writeio != NULL)
9620 zonemgr_cancelio(zone->writeio);
9622 if (zone->dctx != NULL)
9623 dns_dumpctx_cancel(zone->dctx);
9625 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9626 zone_detachdb(zone);
9627 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9628 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
9629 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9633 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
9634 REQUIRE(DNS_ZONE_VALID(zone));
9637 zone->minrefresh = val;
9641 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
9642 REQUIRE(DNS_ZONE_VALID(zone));
9645 zone->maxrefresh = val;
9649 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
9650 REQUIRE(DNS_ZONE_VALID(zone));
9653 zone->minretry = val;
9657 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
9658 REQUIRE(DNS_ZONE_VALID(zone));
9661 zone->maxretry = val;
9664 static isc_boolean_t
9665 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
9666 isc_sockaddr_t *addr, dns_tsigkey_t *key)
9668 dns_notify_t *notify;
9669 dns_zonemgr_t *zmgr;
9670 isc_result_t result;
9672 for (notify = ISC_LIST_HEAD(zone->notifies);
9674 notify = ISC_LIST_NEXT(notify, link)) {
9675 if (notify->request != NULL)
9677 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
9678 dns_name_equal(name, ¬ify->ns))
9680 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) &&
9688 * If we are enqueued on the startup ratelimiter and this is
9689 * not a startup notify, re-enqueue on the normal notify
9692 if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
9693 (notify->flags & DNS_NOTIFY_STARTUP) != 0) {
9694 zmgr = notify->zone->zmgr;
9695 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
9697 if (result != ISC_R_SUCCESS)
9700 notify->flags &= ~DNS_NOTIFY_STARTUP;
9701 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
9704 if (result != ISC_R_SUCCESS) {
9705 isc_event_free(¬ify->event);
9713 static isc_boolean_t
9714 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
9715 dns_tsigkey_t *key = NULL;
9718 isc_boolean_t isself;
9719 isc_netaddr_t dstaddr;
9720 isc_result_t result;
9722 if (zone->view == NULL || zone->isself == NULL)
9725 switch (isc_sockaddr_pf(dst)) {
9727 src = zone->notifysrc4;
9728 isc_sockaddr_any(&any);
9731 src = zone->notifysrc6;
9732 isc_sockaddr_any6(&any);
9739 * When sending from any the kernel will assign a source address
9740 * that matches the destination address.
9742 if (isc_sockaddr_eqaddr(&any, &src))
9745 isc_netaddr_fromsockaddr(&dstaddr, dst);
9746 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
9747 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
9749 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
9752 dns_tsigkey_detach(&key);
9757 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
9760 REQUIRE(DNS_NOTIFY_VALID(notify));
9762 if (notify->zone != NULL) {
9764 LOCK_ZONE(notify->zone);
9765 REQUIRE(LOCKED_ZONE(notify->zone));
9766 if (ISC_LINK_LINKED(notify, link))
9767 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
9769 UNLOCK_ZONE(notify->zone);
9771 zone_idetach(¬ify->zone);
9773 dns_zone_idetach(¬ify->zone);
9775 if (notify->find != NULL)
9776 dns_adb_destroyfind(¬ify->find);
9777 if (notify->request != NULL)
9778 dns_request_destroy(¬ify->request);
9779 if (dns_name_dynamic(¬ify->ns))
9780 dns_name_free(¬ify->ns, notify->mctx);
9781 if (notify->key != NULL)
9782 dns_tsigkey_detach(¬ify->key);
9783 mctx = notify->mctx;
9784 isc_mem_put(notify->mctx, notify, sizeof(*notify));
9785 isc_mem_detach(&mctx);
9789 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
9790 dns_notify_t *notify;
9792 REQUIRE(notifyp != NULL && *notifyp == NULL);
9794 notify = isc_mem_get(mctx, sizeof(*notify));
9796 return (ISC_R_NOMEMORY);
9798 notify->mctx = NULL;
9799 isc_mem_attach(mctx, ¬ify->mctx);
9800 notify->flags = flags;
9801 notify->zone = NULL;
9802 notify->find = NULL;
9803 notify->request = NULL;
9805 notify->event = NULL;
9806 isc_sockaddr_any(¬ify->dst);
9807 dns_name_init(¬ify->ns, NULL);
9808 ISC_LINK_INIT(notify, link);
9809 notify->magic = NOTIFY_MAGIC;
9811 return (ISC_R_SUCCESS);
9815 * XXXAG should check for DNS_ZONEFLG_EXITING
9818 process_adb_event(isc_task_t *task, isc_event_t *ev) {
9819 dns_notify_t *notify;
9820 isc_eventtype_t result;
9824 notify = ev->ev_arg;
9825 REQUIRE(DNS_NOTIFY_VALID(notify));
9826 INSIST(task == notify->zone->task);
9827 result = ev->ev_type;
9828 isc_event_free(&ev);
9829 if (result == DNS_EVENT_ADBMOREADDRESSES) {
9830 dns_adb_destroyfind(¬ify->find);
9831 notify_find_address(notify);
9834 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
9835 LOCK_ZONE(notify->zone);
9836 notify_send(notify);
9837 UNLOCK_ZONE(notify->zone);
9839 notify_destroy(notify, ISC_FALSE);
9843 notify_find_address(dns_notify_t *notify) {
9844 isc_result_t result;
9845 unsigned int options;
9847 REQUIRE(DNS_NOTIFY_VALID(notify));
9848 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
9849 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
9851 if (notify->zone->view->adb == NULL)
9854 result = dns_adb_createfind(notify->zone->view->adb,
9856 process_adb_event, notify,
9857 ¬ify->ns, dns_rootname, 0,
9859 notify->zone->view->dstport,
9862 /* Something failed? */
9863 if (result != ISC_R_SUCCESS)
9866 /* More addresses pending? */
9867 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
9870 /* We have as many addresses as we can get. */
9871 LOCK_ZONE(notify->zone);
9872 notify_send(notify);
9873 UNLOCK_ZONE(notify->zone);
9876 notify_destroy(notify, ISC_FALSE);
9881 notify_send_queue(dns_notify_t *notify, isc_boolean_t startup) {
9883 isc_result_t result;
9885 INSIST(notify->event == NULL);
9886 e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
9887 notify_send_toaddr, notify, sizeof(isc_event_t));
9889 return (ISC_R_NOMEMORY);
9893 e->ev_sender = NULL;
9894 result = isc_ratelimiter_enqueue(startup
9895 ? notify->zone->zmgr->startupnotifyrl
9896 : notify->zone->zmgr->notifyrl,
9897 notify->zone->task, &e);
9898 if (result != ISC_R_SUCCESS) {
9900 notify->event = NULL;
9906 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
9907 dns_notify_t *notify;
9908 isc_result_t result;
9909 dns_message_t *message = NULL;
9910 isc_netaddr_t dstip;
9911 dns_tsigkey_t *key = NULL;
9912 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9915 isc_boolean_t have_notifysource = ISC_FALSE;
9917 notify = event->ev_arg;
9918 REQUIRE(DNS_NOTIFY_VALID(notify));
9922 LOCK_ZONE(notify->zone);
9924 notify->event = NULL;
9926 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
9927 result = ISC_R_CANCELED;
9931 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
9932 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
9933 notify->zone->view->requestmgr == NULL ||
9934 notify->zone->db == NULL) {
9935 result = ISC_R_CANCELED;
9940 * The raw IPv4 address should also exist. Don't send to the
9943 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
9944 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
9945 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9946 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9947 "notify: ignoring IPv6 mapped IPV4 address: %s",
9949 result = ISC_R_CANCELED;
9953 result = notify_createmessage(notify->zone, notify->flags, &message);
9954 if (result != ISC_R_SUCCESS)
9957 if (notify->key != NULL) {
9958 /* Transfer ownership of key */
9962 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
9963 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9964 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
9965 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
9966 notify_log(notify->zone, ISC_LOG_ERROR,
9967 "NOTIFY to %s not sent. "
9968 "Peer TSIG key lookup failure.", addrbuf);
9969 goto cleanup_message;
9973 /* XXX: should we log the tsig key too? */
9974 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
9976 if (notify->zone->view->peers != NULL) {
9977 dns_peer_t *peer = NULL;
9978 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
9980 if (result == ISC_R_SUCCESS) {
9981 result = dns_peer_getnotifysource(peer, &src);
9982 if (result == ISC_R_SUCCESS)
9983 have_notifysource = ISC_TRUE;
9986 switch (isc_sockaddr_pf(¬ify->dst)) {
9988 if (!have_notifysource)
9989 src = notify->zone->notifysrc4;
9992 if (!have_notifysource)
9993 src = notify->zone->notifysrc6;
9996 result = ISC_R_NOTIMPLEMENTED;
10000 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
10002 result = dns_request_createvia2(notify->zone->view->requestmgr,
10003 message, &src, ¬ify->dst, 0, key,
10004 timeout * 3, timeout,
10005 notify->zone->task, notify_done,
10006 notify, ¬ify->request);
10007 if (result == ISC_R_SUCCESS) {
10008 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
10009 inc_stats(notify->zone,
10010 dns_zonestatscounter_notifyoutv4);
10012 inc_stats(notify->zone,
10013 dns_zonestatscounter_notifyoutv6);
10019 dns_tsigkey_detach(&key);
10021 dns_message_destroy(&message);
10023 UNLOCK_ZONE(notify->zone);
10024 isc_event_free(&event);
10025 if (result != ISC_R_SUCCESS)
10026 notify_destroy(notify, ISC_FALSE);
10030 notify_send(dns_notify_t *notify) {
10031 dns_adbaddrinfo_t *ai;
10032 isc_sockaddr_t dst;
10033 isc_result_t result;
10034 dns_notify_t *new = NULL;
10035 unsigned int flags;
10036 isc_boolean_t startup;
10039 * Zone lock held by caller.
10041 REQUIRE(DNS_NOTIFY_VALID(notify));
10042 REQUIRE(LOCKED_ZONE(notify->zone));
10044 for (ai = ISC_LIST_HEAD(notify->find->list);
10046 ai = ISC_LIST_NEXT(ai, publink)) {
10047 dst = ai->sockaddr;
10048 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
10051 if (notify_isself(notify->zone, &dst))
10054 flags = notify->flags & DNS_NOTIFY_NOSOA;
10055 result = notify_create(notify->mctx, flags, &new);
10056 if (result != ISC_R_SUCCESS)
10058 zone_iattach(notify->zone, &new->zone);
10059 ISC_LIST_APPEND(new->zone->notifies, new, link);
10061 startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
10062 result = notify_send_queue(new, startup);
10063 if (result != ISC_R_SUCCESS)
10070 notify_destroy(new, ISC_TRUE);
10074 dns_zone_notify(dns_zone_t *zone) {
10077 REQUIRE(DNS_ZONE_VALID(zone));
10080 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10083 zone_settimer(zone, &now);
10088 zone_notify(dns_zone_t *zone, isc_time_t *now) {
10089 dns_dbnode_t *node = NULL;
10090 dns_db_t *zonedb = NULL;
10091 dns_dbversion_t *version = NULL;
10092 dns_name_t *origin = NULL;
10095 dns_rdata_soa_t soa;
10096 isc_uint32_t serial;
10097 dns_rdata_t rdata = DNS_RDATA_INIT;
10098 dns_rdataset_t nsrdset;
10099 dns_rdataset_t soardset;
10100 isc_result_t result;
10102 isc_sockaddr_t dst;
10103 isc_boolean_t isqueued;
10104 dns_notifytype_t notifytype;
10105 unsigned int flags = 0;
10106 isc_boolean_t loggednotify = ISC_FALSE;
10107 isc_boolean_t startup;
10109 REQUIRE(DNS_ZONE_VALID(zone));
10112 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10113 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10114 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
10115 notifytype = zone->notifytype;
10116 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
10119 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
10122 if (notifytype == dns_notifytype_no)
10125 if (notifytype == dns_notifytype_masteronly &&
10126 zone->type != dns_zone_master)
10129 origin = &zone->origin;
10132 * If the zone is dialup we are done as we don't want to send
10133 * the current soa so as to force a refresh query.
10135 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
10136 flags |= DNS_NOTIFY_NOSOA;
10139 * Record that this was a notify due to starting up.
10142 flags |= DNS_NOTIFY_STARTUP;
10147 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10148 if (zone->db != NULL)
10149 dns_db_attach(zone->db, &zonedb);
10150 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10151 if (zonedb == NULL)
10153 dns_db_currentversion(zonedb, &version);
10154 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
10155 if (result != ISC_R_SUCCESS)
10158 dns_rdataset_init(&soardset);
10159 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
10160 dns_rdatatype_none, 0, &soardset, NULL);
10161 if (result != ISC_R_SUCCESS)
10165 * Find serial and master server's name.
10167 dns_name_init(&master, NULL);
10168 result = dns_rdataset_first(&soardset);
10169 if (result != ISC_R_SUCCESS)
10171 dns_rdataset_current(&soardset, &rdata);
10172 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10173 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10174 dns_rdata_reset(&rdata);
10175 result = dns_name_dup(&soa.origin, zone->mctx, &master);
10176 serial = soa.serial;
10177 dns_rdataset_disassociate(&soardset);
10178 if (result != ISC_R_SUCCESS)
10182 * Enqueue notify requests for 'also-notify' servers.
10185 for (i = 0; i < zone->notifycnt; i++) {
10186 dns_tsigkey_t *key = NULL;
10187 dns_notify_t *notify = NULL;
10189 if ((zone->notifykeynames != NULL) &&
10190 (zone->notifykeynames[i] != NULL)) {
10191 dns_view_t *view = dns_zone_getview(zone);
10192 dns_name_t *keyname = zone->notifykeynames[i];
10193 (void)dns_view_gettsig(view, keyname, &key);
10196 dst = zone->notify[i];
10197 if (notify_isqueued(zone, flags, NULL, &dst, key)) {
10199 dns_tsigkey_detach(&key);
10203 result = notify_create(zone->mctx, flags, ¬ify);
10204 if (result != ISC_R_SUCCESS) {
10206 dns_tsigkey_detach(&key);
10210 zone_iattach(zone, ¬ify->zone);
10213 INSIST(notify->key == NULL);
10220 ISC_LIST_APPEND(zone->notifies, notify, link);
10221 result = notify_send_queue(notify, startup);
10222 if (result != ISC_R_SUCCESS)
10223 notify_destroy(notify, ISC_TRUE);
10224 if (!loggednotify) {
10225 notify_log(zone, ISC_LOG_INFO,
10226 "sending notifies (serial %u)",
10228 loggednotify = ISC_TRUE;
10233 if (notifytype == dns_notifytype_explicit)
10237 * Process NS RRset to generate notifies.
10240 dns_rdataset_init(&nsrdset);
10241 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
10242 dns_rdatatype_none, 0, &nsrdset, NULL);
10243 if (result != ISC_R_SUCCESS)
10246 result = dns_rdataset_first(&nsrdset);
10247 while (result == ISC_R_SUCCESS) {
10248 dns_notify_t *notify = NULL;
10250 dns_rdataset_current(&nsrdset, &rdata);
10251 result = dns_rdata_tostruct(&rdata, &ns, NULL);
10252 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10253 dns_rdata_reset(&rdata);
10255 * Don't notify the master server unless explicitly
10256 * configured to do so.
10258 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
10259 dns_name_compare(&master, &ns.name) == 0) {
10260 result = dns_rdataset_next(&nsrdset);
10264 if (!loggednotify) {
10265 notify_log(zone, ISC_LOG_INFO,
10266 "sending notifies (serial %u)",
10268 loggednotify = ISC_TRUE;
10272 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
10275 result = dns_rdataset_next(&nsrdset);
10278 result = notify_create(zone->mctx, flags, ¬ify);
10279 if (result != ISC_R_SUCCESS)
10281 dns_zone_iattach(zone, ¬ify->zone);
10282 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
10283 if (result != ISC_R_SUCCESS) {
10285 notify_destroy(notify, ISC_TRUE);
10290 ISC_LIST_APPEND(zone->notifies, notify, link);
10292 notify_find_address(notify);
10293 result = dns_rdataset_next(&nsrdset);
10295 dns_rdataset_disassociate(&nsrdset);
10298 if (dns_name_dynamic(&master))
10299 dns_name_free(&master, zone->mctx);
10301 dns_db_detachnode(zonedb, &node);
10303 dns_db_closeversion(zonedb, &version, ISC_FALSE);
10304 dns_db_detach(&zonedb);
10311 static inline isc_result_t
10312 save_nsrrset(dns_message_t *message, dns_name_t *name,
10313 dns_db_t *db, dns_dbversion_t *version)
10315 dns_rdataset_t *nsrdataset = NULL;
10316 dns_rdataset_t *rdataset = NULL;
10317 dns_dbnode_t *node = NULL;
10319 isc_result_t result;
10320 dns_rdata_t rdata = DNS_RDATA_INIT;
10323 * Extract NS RRset from message.
10325 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
10326 dns_rdatatype_ns, dns_rdatatype_none,
10327 NULL, &nsrdataset);
10328 if (result != ISC_R_SUCCESS)
10334 result = dns_db_findnode(db, name, ISC_TRUE, &node);
10335 if (result != ISC_R_SUCCESS)
10337 result = dns_db_addrdataset(db, node, version, 0,
10338 nsrdataset, 0, NULL);
10339 dns_db_detachnode(db, &node);
10340 if (result != ISC_R_SUCCESS)
10343 * Add glue rdatasets.
10345 for (result = dns_rdataset_first(nsrdataset);
10346 result == ISC_R_SUCCESS;
10347 result = dns_rdataset_next(nsrdataset)) {
10348 dns_rdataset_current(nsrdataset, &rdata);
10349 result = dns_rdata_tostruct(&rdata, &ns, NULL);
10350 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10351 dns_rdata_reset(&rdata);
10352 if (!dns_name_issubdomain(&ns.name, name))
10355 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10356 &ns.name, dns_rdatatype_aaaa,
10357 dns_rdatatype_none, NULL,
10359 if (result == ISC_R_SUCCESS) {
10360 result = dns_db_findnode(db, &ns.name,
10362 if (result != ISC_R_SUCCESS)
10364 result = dns_db_addrdataset(db, node, version, 0,
10365 rdataset, 0, NULL);
10366 dns_db_detachnode(db, &node);
10367 if (result != ISC_R_SUCCESS)
10371 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10372 &ns.name, dns_rdatatype_a,
10373 dns_rdatatype_none, NULL,
10375 if (result == ISC_R_SUCCESS) {
10376 result = dns_db_findnode(db, &ns.name,
10378 if (result != ISC_R_SUCCESS)
10380 result = dns_db_addrdataset(db, node, version, 0,
10381 rdataset, 0, NULL);
10382 dns_db_detachnode(db, &node);
10383 if (result != ISC_R_SUCCESS)
10387 if (result != ISC_R_NOMORE)
10390 return (ISC_R_SUCCESS);
10397 stub_callback(isc_task_t *task, isc_event_t *event) {
10398 const char me[] = "stub_callback";
10399 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10400 dns_stub_t *stub = NULL;
10401 dns_message_t *msg = NULL;
10402 dns_zone_t *zone = NULL;
10403 char master[ISC_SOCKADDR_FORMATSIZE];
10404 char source[ISC_SOCKADDR_FORMATSIZE];
10405 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
10406 isc_result_t result;
10408 isc_boolean_t exiting = ISC_FALSE;
10410 unsigned int j, soacount;
10412 stub = revent->ev_arg;
10413 INSIST(DNS_STUB_VALID(stub));
10425 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10426 zone_debuglog(zone, me, 1, "exiting");
10427 exiting = ISC_TRUE;
10431 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10432 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10434 if (revent->result != ISC_R_SUCCESS) {
10435 if (revent->result == ISC_R_TIMEDOUT &&
10436 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10437 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10438 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10439 "refreshing stub: timeout retrying "
10440 " without EDNS master %s (source %s)",
10444 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
10445 &zone->sourceaddr, &now);
10446 dns_zone_log(zone, ISC_LOG_INFO,
10447 "could not refresh stub from master %s"
10448 " (source %s): %s", master, source,
10449 dns_result_totext(revent->result));
10453 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10454 if (result != ISC_R_SUCCESS)
10457 result = dns_request_getresponse(revent->request, msg, 0);
10458 if (result != ISC_R_SUCCESS)
10462 * Unexpected rcode.
10464 if (msg->rcode != dns_rcode_noerror) {
10468 isc_buffer_init(&rb, rcode, sizeof(rcode));
10469 (void)dns_rcode_totext(msg->rcode, &rb);
10471 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10472 (msg->rcode == dns_rcode_servfail ||
10473 msg->rcode == dns_rcode_notimp ||
10474 msg->rcode == dns_rcode_formerr)) {
10475 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10476 "refreshing stub: rcode (%.*s) retrying "
10477 "without EDNS master %s (source %s)",
10478 (int)rb.used, rcode, master, source);
10479 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10483 dns_zone_log(zone, ISC_LOG_INFO,
10484 "refreshing stub: "
10485 "unexpected rcode (%.*s) from %s (source %s)",
10486 (int)rb.used, rcode, master, source);
10491 * We need complete messages.
10493 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10494 if (dns_request_usedtcp(revent->request)) {
10495 dns_zone_log(zone, ISC_LOG_INFO,
10496 "refreshing stub: truncated TCP "
10497 "response from master %s (source %s)",
10501 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10506 * If non-auth log and next master.
10508 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10509 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10510 "non-authoritative answer from "
10511 "master %s (source %s)", master, source);
10518 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10519 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
10521 if (cnamecnt != 0) {
10522 dns_zone_log(zone, ISC_LOG_INFO,
10523 "refreshing stub: unexpected CNAME response "
10524 "from master %s (source %s)", master, source);
10529 dns_zone_log(zone, ISC_LOG_INFO,
10530 "refreshing stub: no NS records in response "
10531 "from master %s (source %s)", master, source);
10538 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
10539 if (result != ISC_R_SUCCESS) {
10540 dns_zone_log(zone, ISC_LOG_INFO,
10541 "refreshing stub: unable to save NS records "
10542 "from master %s (source %s)", master, source);
10549 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
10550 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
10551 if (zone->db == NULL)
10552 zone_attachdb(zone, stub->db);
10553 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
10554 &refresh, &retry, &expire, NULL, NULL);
10555 if (result == ISC_R_SUCCESS && soacount > 0U) {
10556 zone->refresh = RANGE(refresh, zone->minrefresh,
10558 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
10559 zone->expire = RANGE(expire, zone->refresh + zone->retry,
10561 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
10563 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
10564 dns_db_detach(&stub->db);
10566 dns_message_destroy(&msg);
10567 isc_event_free(&event);
10568 dns_request_destroy(&zone->request);
10570 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10571 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
10572 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10573 isc_interval_set(&i, zone->expire, 0);
10574 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10576 if (zone->masterfile != NULL)
10577 zone_needdump(zone, 0);
10579 zone_settimer(zone, &now);
10583 if (stub->version != NULL)
10584 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
10585 if (stub->db != NULL)
10586 dns_db_detach(&stub->db);
10588 dns_message_destroy(&msg);
10589 isc_event_free(&event);
10590 dns_request_destroy(&zone->request);
10592 * Skip to next failed / untried master.
10596 } while (zone->curmaster < zone->masterscnt &&
10597 zone->mastersok[zone->curmaster]);
10598 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10599 if (exiting || zone->curmaster >= zone->masterscnt) {
10600 isc_boolean_t done = ISC_TRUE;
10602 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10603 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10605 * Did we get a good answer from all the masters?
10607 for (j = 0; j < zone->masterscnt; j++)
10608 if (zone->mastersok[j] == ISC_FALSE) {
10615 zone->curmaster = 0;
10617 * Find the next failed master.
10619 while (zone->curmaster < zone->masterscnt &&
10620 zone->mastersok[zone->curmaster])
10622 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10624 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10626 zone_settimer(zone, &now);
10630 queue_soa_query(zone);
10635 dns_message_destroy(&msg);
10636 isc_event_free(&event);
10637 dns_request_destroy(&zone->request);
10638 ns_query(zone, NULL, stub);
10645 dns_zone_idetach(&stub->zone);
10646 INSIST(stub->db == NULL);
10647 INSIST(stub->version == NULL);
10648 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10651 INSIST(event == NULL);
10656 * An SOA query has finished (successfully or not).
10659 refresh_callback(isc_task_t *task, isc_event_t *event) {
10660 const char me[] = "refresh_callback";
10661 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10663 dns_message_t *msg = NULL;
10664 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
10666 char master[ISC_SOCKADDR_FORMATSIZE];
10667 char source[ISC_SOCKADDR_FORMATSIZE];
10668 dns_rdataset_t *rdataset = NULL;
10669 dns_rdata_t rdata = DNS_RDATA_INIT;
10670 dns_rdata_soa_t soa;
10671 isc_result_t result;
10672 isc_uint32_t serial, oldserial = 0;
10674 isc_boolean_t do_queue_xfrin = ISC_FALSE;
10676 zone = revent->ev_arg;
10677 INSIST(DNS_ZONE_VALID(zone));
10687 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10688 isc_event_free(&event);
10689 dns_request_destroy(&zone->request);
10694 * if timeout log and next master;
10697 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10698 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10700 if (revent->result != ISC_R_SUCCESS) {
10701 if (revent->result == ISC_R_TIMEDOUT &&
10702 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10703 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10704 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10705 "refresh: timeout retrying without EDNS "
10706 "master %s (source %s)", master, source);
10709 if (revent->result == ISC_R_TIMEDOUT &&
10710 !dns_request_usedtcp(revent->request)) {
10711 dns_zone_log(zone, ISC_LOG_INFO,
10712 "refresh: retry limit for "
10713 "master %s exceeded (source %s)",
10715 /* Try with slave with TCP. */
10716 if ((zone->type == dns_zone_slave ||
10717 zone->type == dns_zone_redirect) &&
10718 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
10719 if (!dns_zonemgr_unreachable(zone->zmgr,
10724 DNS_ZONE_SETFLAG(zone,
10725 DNS_ZONEFLG_SOABEFOREAXFR);
10728 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10729 "refresh: skipped tcp fallback "
10730 "as master %s (source %s) is "
10731 "unreachable (cached)",
10735 dns_zone_log(zone, ISC_LOG_INFO,
10736 "refresh: failure trying master "
10737 "%s (source %s): %s", master, source,
10738 dns_result_totext(revent->result));
10742 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10743 if (result != ISC_R_SUCCESS)
10745 result = dns_request_getresponse(revent->request, msg, 0);
10746 if (result != ISC_R_SUCCESS) {
10747 dns_zone_log(zone, ISC_LOG_INFO,
10748 "refresh: failure trying master "
10749 "%s (source %s): %s", master, source,
10750 dns_result_totext(result));
10755 * Unexpected rcode.
10757 if (msg->rcode != dns_rcode_noerror) {
10761 isc_buffer_init(&rb, rcode, sizeof(rcode));
10762 (void)dns_rcode_totext(msg->rcode, &rb);
10764 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10765 (msg->rcode == dns_rcode_servfail ||
10766 msg->rcode == dns_rcode_notimp ||
10767 msg->rcode == dns_rcode_formerr)) {
10768 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10769 "refresh: rcode (%.*s) retrying without "
10770 "EDNS master %s (source %s)",
10771 (int)rb.used, rcode, master, source);
10772 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10775 dns_zone_log(zone, ISC_LOG_INFO,
10776 "refresh: unexpected rcode (%.*s) from "
10777 "master %s (source %s)", (int)rb.used, rcode,
10780 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
10782 if (msg->rcode == dns_rcode_refused &&
10783 (zone->type == dns_zone_slave ||
10784 zone->type == dns_zone_redirect))
10790 * If truncated punt to zone transfer which will query again.
10792 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10793 if (zone->type == dns_zone_slave ||
10794 zone->type == dns_zone_redirect) {
10795 dns_zone_log(zone, ISC_LOG_INFO,
10796 "refresh: truncated UDP answer, "
10797 "initiating TCP zone xfer "
10798 "for master %s (source %s)",
10800 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
10803 INSIST(zone->type == dns_zone_stub);
10804 if (dns_request_usedtcp(revent->request)) {
10805 dns_zone_log(zone, ISC_LOG_INFO,
10806 "refresh: truncated TCP response "
10807 "from master %s (source %s)",
10811 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10817 * if non-auth log and next master;
10819 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10820 dns_zone_log(zone, ISC_LOG_INFO,
10821 "refresh: non-authoritative answer from "
10822 "master %s (source %s)", master, source);
10826 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10827 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
10828 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
10829 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
10830 dns_rdatatype_soa);
10833 * There should not be a CNAME record at top of zone.
10835 if (cnamecnt != 0) {
10836 dns_zone_log(zone, ISC_LOG_INFO,
10837 "refresh: CNAME at top of zone "
10838 "in master %s (source %s)", master, source);
10843 * if referral log and next master;
10845 if (soacnt == 0 && soacount == 0 && nscount != 0) {
10846 dns_zone_log(zone, ISC_LOG_INFO,
10847 "refresh: referral response "
10848 "from master %s (source %s)", master, source);
10853 * if nodata log and next master;
10855 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
10856 dns_zone_log(zone, ISC_LOG_INFO,
10857 "refresh: NODATA response "
10858 "from master %s (source %s)", master, source);
10863 * Only one soa at top of zone.
10866 dns_zone_log(zone, ISC_LOG_INFO,
10867 "refresh: answer SOA count (%d) != 1 "
10868 "from master %s (source %s)",
10869 soacnt, master, source);
10877 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
10878 dns_rdatatype_soa, dns_rdatatype_none,
10880 if (result != ISC_R_SUCCESS) {
10881 dns_zone_log(zone, ISC_LOG_INFO,
10882 "refresh: unable to get SOA record "
10883 "from master %s (source %s)", master, source);
10887 result = dns_rdataset_first(rdataset);
10888 if (result != ISC_R_SUCCESS) {
10889 dns_zone_log(zone, ISC_LOG_INFO,
10890 "refresh: dns_rdataset_first() failed");
10894 dns_rdataset_current(rdataset, &rdata);
10895 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10896 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10898 serial = soa.serial;
10899 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10900 unsigned int dbsoacount;
10901 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
10902 &oldserial, NULL, NULL, NULL, NULL,
10904 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10905 RUNTIME_CHECK(dbsoacount > 0U);
10906 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
10907 serial, oldserial);
10909 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
10912 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
10913 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
10914 isc_serial_gt(serial, oldserial)) {
10915 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10916 &zone->sourceaddr, &now))
10918 dns_zone_log(zone, ISC_LOG_INFO,
10919 "refresh: skipping %s as master %s "
10920 "(source %s) is unreachable (cached)",
10921 (zone->type == dns_zone_slave ||
10922 zone->type == dns_zone_redirect) ?
10923 "zone transfer" : "NS query",
10928 isc_event_free(&event);
10929 dns_request_destroy(&zone->request);
10930 if (zone->type == dns_zone_slave ||
10931 zone->type == dns_zone_redirect) {
10932 do_queue_xfrin = ISC_TRUE;
10934 INSIST(zone->type == dns_zone_stub);
10935 ns_query(zone, rdataset, NULL);
10938 dns_message_destroy(&msg);
10939 } else if (isc_serial_eq(soa.serial, oldserial)) {
10940 if (zone->masterfile != NULL) {
10941 result = ISC_R_FAILURE;
10942 if (zone->journal != NULL)
10943 result = isc_file_settime(zone->journal, &now);
10944 if (result == ISC_R_SUCCESS &&
10945 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10946 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10947 result = isc_file_settime(zone->masterfile,
10949 } else if (result != ISC_R_SUCCESS)
10950 result = isc_file_settime(zone->masterfile,
10952 /* Someone removed the file from underneath us! */
10953 if (result == ISC_R_FILENOTFOUND) {
10954 zone_needdump(zone, DNS_DUMP_DELAY);
10955 } else if (result != ISC_R_SUCCESS)
10956 dns_zone_log(zone, ISC_LOG_ERROR,
10957 "refresh: could not set file "
10958 "modification time of '%s': %s",
10960 dns_result_totext(result));
10962 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10963 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10964 zone->mastersok[zone->curmaster] = ISC_TRUE;
10967 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
10968 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
10969 "received from master %s < ours (%u)",
10970 soa.serial, master, oldserial);
10972 zone_debuglog(zone, me, 1, "ahead");
10973 zone->mastersok[zone->curmaster] = ISC_TRUE;
10977 dns_message_destroy(&msg);
10982 dns_message_destroy(&msg);
10983 isc_event_free(&event);
10984 dns_request_destroy(&zone->request);
10986 * Skip to next failed / untried master.
10990 } while (zone->curmaster < zone->masterscnt &&
10991 zone->mastersok[zone->curmaster]);
10992 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10993 if (zone->curmaster >= zone->masterscnt) {
10994 isc_boolean_t done = ISC_TRUE;
10995 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10996 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10998 * Did we get a good answer from all the masters?
11000 for (j = 0; j < zone->masterscnt; j++)
11001 if (zone->mastersok[j] == ISC_FALSE) {
11008 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11009 zone->curmaster = 0;
11011 * Find the next failed master.
11013 while (zone->curmaster < zone->masterscnt &&
11014 zone->mastersok[zone->curmaster])
11018 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11019 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
11020 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11021 zone->refreshtime = now;
11023 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11024 zone_settimer(zone, &now);
11029 queue_soa_query(zone);
11034 dns_message_destroy(&msg);
11035 isc_event_free(&event);
11036 dns_request_destroy(&zone->request);
11037 queue_soa_query(zone);
11041 if (do_queue_xfrin)
11043 dns_zone_idetach(&zone);
11048 queue_soa_query(dns_zone_t *zone) {
11049 const char me[] = "queue_soa_query";
11051 dns_zone_t *dummy = NULL;
11052 isc_result_t result;
11058 REQUIRE(LOCKED_ZONE(zone));
11060 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
11061 cancel_refresh(zone);
11065 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
11066 soa_query, zone, sizeof(isc_event_t));
11068 cancel_refresh(zone);
11073 * Attach so that we won't clean up
11074 * until the event is delivered.
11076 zone_iattach(zone, &dummy);
11079 e->ev_sender = NULL;
11080 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
11081 if (result != ISC_R_SUCCESS) {
11082 zone_idetach(&dummy);
11083 isc_event_free(&e);
11084 cancel_refresh(zone);
11088 static inline isc_result_t
11089 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
11090 dns_message_t **messagep)
11092 dns_message_t *message = NULL;
11093 dns_name_t *qname = NULL;
11094 dns_rdataset_t *qrdataset = NULL;
11095 isc_result_t result;
11097 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
11099 if (result != ISC_R_SUCCESS)
11102 message->opcode = dns_opcode_query;
11103 message->rdclass = zone->rdclass;
11105 result = dns_message_gettempname(message, &qname);
11106 if (result != ISC_R_SUCCESS)
11109 result = dns_message_gettemprdataset(message, &qrdataset);
11110 if (result != ISC_R_SUCCESS)
11116 dns_name_init(qname, NULL);
11117 dns_name_clone(&zone->origin, qname);
11118 dns_rdataset_init(qrdataset);
11119 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
11120 ISC_LIST_APPEND(qname->list, qrdataset, link);
11121 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
11123 *messagep = message;
11124 return (ISC_R_SUCCESS);
11128 dns_message_puttempname(message, &qname);
11129 if (qrdataset != NULL)
11130 dns_message_puttemprdataset(message, &qrdataset);
11131 if (message != NULL)
11132 dns_message_destroy(&message);
11136 static isc_result_t
11137 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
11138 isc_result_t result;
11139 dns_rdataset_t *rdataset = NULL;
11140 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
11143 /* Set EDNS options if applicable */
11145 INSIST(count < DNS_EDNSOPTIONS);
11146 ednsopts[count].code = DNS_OPT_NSID;
11147 ednsopts[count].length = 0;
11148 ednsopts[count].value = NULL;
11151 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
11153 if (result != ISC_R_SUCCESS)
11156 return (dns_message_setopt(message, rdataset));
11160 soa_query(isc_task_t *task, isc_event_t *event) {
11161 const char me[] = "soa_query";
11162 isc_result_t result = ISC_R_FAILURE;
11163 dns_message_t *message = NULL;
11164 dns_zone_t *zone = event->ev_arg;
11165 dns_zone_t *dummy = NULL;
11166 isc_netaddr_t masterip;
11167 dns_tsigkey_t *key = NULL;
11168 isc_uint32_t options;
11169 isc_boolean_t cancel = ISC_TRUE;
11171 isc_boolean_t have_xfrsource, reqnsid;
11172 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11174 REQUIRE(DNS_ZONE_VALID(zone));
11181 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
11182 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
11183 zone->view->requestmgr == NULL) {
11184 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11185 cancel = ISC_FALSE;
11190 result = create_query(zone, dns_rdatatype_soa, &message);
11191 if (result != ISC_R_SUCCESS)
11194 INSIST(zone->masterscnt > 0);
11195 INSIST(zone->curmaster < zone->masterscnt);
11197 zone->masteraddr = zone->masters[zone->curmaster];
11199 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11201 * First, look for a tsig key in the master statement, then
11202 * try for a server key.
11204 if ((zone->masterkeynames != NULL) &&
11205 (zone->masterkeynames[zone->curmaster] != NULL)) {
11206 dns_view_t *view = dns_zone_getview(zone);
11207 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11208 result = dns_view_gettsig(view, keyname, &key);
11209 if (result != ISC_R_SUCCESS) {
11210 char namebuf[DNS_NAME_FORMATSIZE];
11211 dns_name_format(keyname, namebuf, sizeof(namebuf));
11212 dns_zone_log(zone, ISC_LOG_ERROR,
11213 "unable to find key: %s", namebuf);
11218 result = dns_view_getpeertsig(zone->view, &masterip, &key);
11219 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
11220 char addrbuf[ISC_NETADDR_FORMATSIZE];
11221 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
11222 dns_zone_log(zone, ISC_LOG_ERROR,
11223 "unable to find TSIG key for %s", addrbuf);
11228 have_xfrsource = ISC_FALSE;
11229 reqnsid = zone->view->requestnsid;
11230 if (zone->view->peers != NULL) {
11231 dns_peer_t *peer = NULL;
11232 isc_boolean_t edns;
11233 result = dns_peerlist_peerbyaddr(zone->view->peers,
11235 if (result == ISC_R_SUCCESS) {
11236 result = dns_peer_getsupportedns(peer, &edns);
11237 if (result == ISC_R_SUCCESS && !edns)
11238 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11239 result = dns_peer_gettransfersource(peer,
11240 &zone->sourceaddr);
11241 if (result == ISC_R_SUCCESS)
11242 have_xfrsource = ISC_TRUE;
11243 if (zone->view->resolver != NULL)
11245 dns_resolver_getudpsize(zone->view->resolver);
11246 (void)dns_peer_getudpsize(peer, &udpsize);
11247 (void)dns_peer_getrequestnsid(peer, &reqnsid);
11251 switch (isc_sockaddr_pf(&zone->masteraddr)) {
11253 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11254 if (isc_sockaddr_equal(&zone->altxfrsource4,
11255 &zone->xfrsource4))
11257 zone->sourceaddr = zone->altxfrsource4;
11258 } else if (!have_xfrsource)
11259 zone->sourceaddr = zone->xfrsource4;
11262 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11263 if (isc_sockaddr_equal(&zone->altxfrsource6,
11264 &zone->xfrsource6))
11266 zone->sourceaddr = zone->altxfrsource6;
11267 } else if (!have_xfrsource)
11268 zone->sourceaddr = zone->xfrsource6;
11271 result = ISC_R_NOTIMPLEMENTED;
11275 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
11276 DNS_REQUESTOPT_TCP : 0;
11278 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11279 result = add_opt(message, udpsize, reqnsid);
11280 if (result != ISC_R_SUCCESS)
11281 zone_debuglog(zone, me, 1,
11282 "unable to add opt record: %s",
11283 dns_result_totext(result));
11286 zone_iattach(zone, &dummy);
11288 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11290 result = dns_request_createvia2(zone->view->requestmgr, message,
11291 &zone->sourceaddr, &zone->masteraddr,
11292 options, key, timeout * 3, timeout,
11293 zone->task, refresh_callback, zone,
11295 if (result != ISC_R_SUCCESS) {
11296 zone_idetach(&dummy);
11297 zone_debuglog(zone, me, 1,
11298 "dns_request_createvia4() failed: %s",
11299 dns_result_totext(result));
11302 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
11303 inc_stats(zone, dns_zonestatscounter_soaoutv4);
11305 inc_stats(zone, dns_zonestatscounter_soaoutv6);
11307 cancel = ISC_FALSE;
11311 dns_tsigkey_detach(&key);
11312 if (result != ISC_R_SUCCESS)
11313 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11314 if (message != NULL)
11315 dns_message_destroy(&message);
11317 cancel_refresh(zone);
11318 isc_event_free(&event);
11320 dns_zone_idetach(&zone);
11325 dns_tsigkey_detach(&key);
11326 dns_message_destroy(&message);
11328 * Skip to next failed / untried master.
11332 } while (zone->curmaster < zone->masterscnt &&
11333 zone->mastersok[zone->curmaster]);
11334 if (zone->curmaster < zone->masterscnt)
11336 zone->curmaster = 0;
11341 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
11342 const char me[] = "ns_query";
11343 isc_result_t result;
11344 dns_message_t *message = NULL;
11345 isc_netaddr_t masterip;
11346 dns_tsigkey_t *key = NULL;
11347 dns_dbnode_t *node = NULL;
11349 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
11350 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11352 REQUIRE(DNS_ZONE_VALID(zone));
11353 REQUIRE(LOCKED_ZONE(zone));
11354 REQUIRE((soardataset != NULL && stub == NULL) ||
11355 (soardataset == NULL && stub != NULL));
11356 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
11360 if (stub == NULL) {
11361 stub = isc_mem_get(zone->mctx, sizeof(*stub));
11364 stub->magic = STUB_MAGIC;
11365 stub->mctx = zone->mctx;
11368 stub->version = NULL;
11371 * Attach so that the zone won't disappear from under us.
11373 zone_iattach(zone, &stub->zone);
11376 * If a db exists we will update it, otherwise we create a
11377 * new one and attach it to the zone once we have the NS
11380 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11381 if (zone->db != NULL) {
11382 dns_db_attach(zone->db, &stub->db);
11383 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11385 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11387 INSIST(zone->db_argc >= 1);
11388 result = dns_db_create(zone->mctx, zone->db_argv[0],
11389 &zone->origin, dns_dbtype_stub,
11394 if (result != ISC_R_SUCCESS) {
11395 dns_zone_log(zone, ISC_LOG_ERROR,
11396 "refreshing stub: "
11397 "could not create "
11399 dns_result_totext(result));
11402 dns_db_settask(stub->db, zone->task);
11405 result = dns_db_newversion(stub->db, &stub->version);
11406 if (result != ISC_R_SUCCESS) {
11407 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11408 "dns_db_newversion() failed: %s",
11409 dns_result_totext(result));
11414 * Update SOA record.
11416 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
11418 if (result != ISC_R_SUCCESS) {
11419 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11420 "dns_db_findnode() failed: %s",
11421 dns_result_totext(result));
11425 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
11426 soardataset, 0, NULL);
11427 dns_db_detachnode(stub->db, &node);
11428 if (result != ISC_R_SUCCESS) {
11429 dns_zone_log(zone, ISC_LOG_INFO,
11430 "refreshing stub: "
11431 "dns_db_addrdataset() failed: %s",
11432 dns_result_totext(result));
11438 * XXX Optimisation: Create message when zone is setup and reuse.
11440 result = create_query(zone, dns_rdatatype_ns, &message);
11441 INSIST(result == ISC_R_SUCCESS);
11443 INSIST(zone->masterscnt > 0);
11444 INSIST(zone->curmaster < zone->masterscnt);
11445 zone->masteraddr = zone->masters[zone->curmaster];
11447 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11449 * First, look for a tsig key in the master statement, then
11450 * try for a server key.
11452 if ((zone->masterkeynames != NULL) &&
11453 (zone->masterkeynames[zone->curmaster] != NULL)) {
11454 dns_view_t *view = dns_zone_getview(zone);
11455 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11456 result = dns_view_gettsig(view, keyname, &key);
11457 if (result != ISC_R_SUCCESS) {
11458 char namebuf[DNS_NAME_FORMATSIZE];
11459 dns_name_format(keyname, namebuf, sizeof(namebuf));
11460 dns_zone_log(zone, ISC_LOG_ERROR,
11461 "unable to find key: %s", namebuf);
11465 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
11467 reqnsid = zone->view->requestnsid;
11468 if (zone->view->peers != NULL) {
11469 dns_peer_t *peer = NULL;
11470 isc_boolean_t edns;
11471 result = dns_peerlist_peerbyaddr(zone->view->peers,
11473 if (result == ISC_R_SUCCESS) {
11474 result = dns_peer_getsupportedns(peer, &edns);
11475 if (result == ISC_R_SUCCESS && !edns)
11476 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11477 result = dns_peer_gettransfersource(peer,
11478 &zone->sourceaddr);
11479 if (result == ISC_R_SUCCESS)
11480 have_xfrsource = ISC_TRUE;
11481 if (zone->view->resolver != NULL)
11483 dns_resolver_getudpsize(zone->view->resolver);
11484 (void)dns_peer_getudpsize(peer, &udpsize);
11485 (void)dns_peer_getrequestnsid(peer, &reqnsid);
11489 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11490 result = add_opt(message, udpsize, reqnsid);
11491 if (result != ISC_R_SUCCESS)
11492 zone_debuglog(zone, me, 1,
11493 "unable to add opt record: %s",
11494 dns_result_totext(result));
11498 * Always use TCP so that we shouldn't truncate in additional section.
11500 switch (isc_sockaddr_pf(&zone->masteraddr)) {
11502 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
11503 zone->sourceaddr = zone->altxfrsource4;
11504 else if (!have_xfrsource)
11505 zone->sourceaddr = zone->xfrsource4;
11508 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
11509 zone->sourceaddr = zone->altxfrsource6;
11510 else if (!have_xfrsource)
11511 zone->sourceaddr = zone->xfrsource6;
11514 result = ISC_R_NOTIMPLEMENTED;
11519 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11521 result = dns_request_createvia2(zone->view->requestmgr, message,
11522 &zone->sourceaddr, &zone->masteraddr,
11523 DNS_REQUESTOPT_TCP, key, timeout * 3,
11524 timeout, zone->task, stub_callback,
11525 stub, &zone->request);
11526 if (result != ISC_R_SUCCESS) {
11527 zone_debuglog(zone, me, 1,
11528 "dns_request_createvia() failed: %s",
11529 dns_result_totext(result));
11532 dns_message_destroy(&message);
11536 cancel_refresh(zone);
11537 if (stub != NULL) {
11539 if (stub->version != NULL)
11540 dns_db_closeversion(stub->db, &stub->version,
11542 if (stub->db != NULL)
11543 dns_db_detach(&stub->db);
11544 if (stub->zone != NULL)
11545 zone_idetach(&stub->zone);
11546 isc_mem_put(stub->mctx, stub, sizeof(*stub));
11548 if (message != NULL)
11549 dns_message_destroy(&message);
11552 dns_tsigkey_detach(&key);
11557 * Handle the control event. Note that although this event causes the zone
11558 * to shut down, it is not a shutdown event in the sense of the task library.
11561 zone_shutdown(isc_task_t *task, isc_event_t *event) {
11562 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
11563 isc_boolean_t free_needed, linked = ISC_FALSE;
11564 dns_zone_t *raw = NULL, *secure = NULL;
11567 REQUIRE(DNS_ZONE_VALID(zone));
11568 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
11569 INSIST(isc_refcount_current(&zone->erefs) == 0);
11571 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
11574 * Stop things being restarted after we cancel them below.
11577 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
11581 * If we were waiting for xfrin quota, step out of
11583 * If there's no zone manager, we can't be waiting for the
11586 if (zone->zmgr != NULL) {
11587 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11588 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
11589 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
11592 zone->statelist = NULL;
11594 if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
11595 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
11597 zone->statelist = NULL;
11598 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
11600 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11604 * In task context, no locking required. See zone_xfrdone().
11606 if (zone->xfr != NULL)
11607 dns_xfrin_shutdown(zone->xfr);
11609 /* Safe to release the zone now */
11610 if (zone->zmgr != NULL)
11611 dns_zonemgr_releasezone(zone->zmgr, zone);
11615 INSIST(zone->irefs > 0);
11618 if (zone->request != NULL) {
11619 dns_request_cancel(zone->request);
11622 if (zone->readio != NULL)
11623 zonemgr_cancelio(zone->readio);
11625 if (zone->lctx != NULL)
11626 dns_loadctx_cancel(zone->lctx);
11628 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
11629 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11630 if (zone->writeio != NULL)
11631 zonemgr_cancelio(zone->writeio);
11633 if (zone->dctx != NULL)
11634 dns_dumpctx_cancel(zone->dctx);
11637 notify_cancel(zone);
11639 forward_cancel(zone);
11641 if (zone->timer != NULL) {
11642 isc_timer_detach(&zone->timer);
11643 INSIST(zone->irefs > 0);
11647 if (zone->view != NULL)
11648 dns_view_weakdetach(&zone->view);
11651 * We have now canceled everything set the flag to allow exit_check()
11652 * to succeed. We must not unlock between setting this flag and
11653 * calling exit_check().
11655 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
11656 free_needed = exit_check(zone);
11657 if (inline_secure(zone)) {
11661 if (inline_raw(zone)) {
11662 secure = zone->secure;
11663 zone->secure = NULL;
11667 dns_zone_detach(&raw);
11668 if (secure != NULL)
11669 dns_zone_idetach(&secure);
11675 zone_timer(isc_task_t *task, isc_event_t *event) {
11676 const char me[] = "zone_timer";
11677 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
11680 REQUIRE(DNS_ZONE_VALID(zone));
11684 zone_maintenance(zone);
11686 isc_event_free(&event);
11690 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
11691 const char me[] = "zone_settimer";
11693 isc_result_t result;
11696 REQUIRE(DNS_ZONE_VALID(zone));
11697 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11700 isc_time_settoepoch(&next);
11702 switch (zone->type) {
11703 case dns_zone_redirect:
11704 if (zone->masters != NULL)
11705 goto treat_as_slave;
11708 case dns_zone_master:
11709 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
11710 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
11711 next = zone->notifytime;
11712 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11713 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11714 INSIST(!isc_time_isepoch(&zone->dumptime));
11715 if (isc_time_isepoch(&next) ||
11716 isc_time_compare(&zone->dumptime, &next) < 0)
11717 next = zone->dumptime;
11719 if (zone->type == dns_zone_redirect)
11721 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
11722 !isc_time_isepoch(&zone->refreshkeytime)) {
11723 if (isc_time_isepoch(&next) ||
11724 isc_time_compare(&zone->refreshkeytime, &next) < 0)
11725 next = zone->refreshkeytime;
11727 if (!isc_time_isepoch(&zone->resigntime)) {
11728 if (isc_time_isepoch(&next) ||
11729 isc_time_compare(&zone->resigntime, &next) < 0)
11730 next = zone->resigntime;
11732 if (!isc_time_isepoch(&zone->keywarntime)) {
11733 if (isc_time_isepoch(&next) ||
11734 isc_time_compare(&zone->keywarntime, &next) < 0)
11735 next = zone->keywarntime;
11737 if (!isc_time_isepoch(&zone->signingtime)) {
11738 if (isc_time_isepoch(&next) ||
11739 isc_time_compare(&zone->signingtime, &next) < 0)
11740 next = zone->signingtime;
11742 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
11743 if (isc_time_isepoch(&next) ||
11744 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
11745 next = zone->nsec3chaintime;
11749 case dns_zone_slave:
11751 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
11752 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
11753 next = zone->notifytime;
11756 case dns_zone_stub:
11757 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
11758 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
11759 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
11760 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
11761 INSIST(!isc_time_isepoch(&zone->refreshtime));
11762 if (isc_time_isepoch(&next) ||
11763 isc_time_compare(&zone->refreshtime, &next) < 0)
11764 next = zone->refreshtime;
11766 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
11767 !isc_time_isepoch(&zone->expiretime)) {
11768 if (isc_time_isepoch(&next) ||
11769 isc_time_compare(&zone->expiretime, &next) < 0)
11770 next = zone->expiretime;
11772 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11773 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11774 INSIST(!isc_time_isepoch(&zone->dumptime));
11775 if (isc_time_isepoch(&next) ||
11776 isc_time_compare(&zone->dumptime, &next) < 0)
11777 next = zone->dumptime;
11782 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11783 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11784 INSIST(!isc_time_isepoch(&zone->dumptime));
11785 if (isc_time_isepoch(&next) ||
11786 isc_time_compare(&zone->dumptime, &next) < 0)
11787 next = zone->dumptime;
11789 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
11790 if (isc_time_isepoch(&next) ||
11791 (!isc_time_isepoch(&zone->refreshkeytime) &&
11792 isc_time_compare(&zone->refreshkeytime, &next) < 0))
11793 next = zone->refreshkeytime;
11801 if (isc_time_isepoch(&next)) {
11802 zone_debuglog(zone, me, 10, "settimer inactive");
11803 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
11804 NULL, NULL, ISC_TRUE);
11805 if (result != ISC_R_SUCCESS)
11806 dns_zone_log(zone, ISC_LOG_ERROR,
11807 "could not deactivate zone timer: %s",
11808 isc_result_totext(result));
11810 if (isc_time_compare(&next, now) <= 0)
11812 result = isc_timer_reset(zone->timer, isc_timertype_once,
11813 &next, NULL, ISC_TRUE);
11814 if (result != ISC_R_SUCCESS)
11815 dns_zone_log(zone, ISC_LOG_ERROR,
11816 "could not reset zone timer: %s",
11817 isc_result_totext(result));
11822 cancel_refresh(dns_zone_t *zone) {
11823 const char me[] = "cancel_refresh";
11827 * 'zone' locked by caller.
11830 REQUIRE(DNS_ZONE_VALID(zone));
11831 REQUIRE(LOCKED_ZONE(zone));
11835 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11837 zone_settimer(zone, &now);
11840 static isc_result_t
11841 notify_createmessage(dns_zone_t *zone, unsigned int flags,
11842 dns_message_t **messagep)
11844 dns_db_t *zonedb = NULL;
11845 dns_dbnode_t *node = NULL;
11846 dns_dbversion_t *version = NULL;
11847 dns_message_t *message = NULL;
11848 dns_rdataset_t rdataset;
11849 dns_rdata_t rdata = DNS_RDATA_INIT;
11851 dns_name_t *tempname = NULL;
11852 dns_rdata_t *temprdata = NULL;
11853 dns_rdatalist_t *temprdatalist = NULL;
11854 dns_rdataset_t *temprdataset = NULL;
11856 isc_result_t result;
11858 isc_buffer_t *b = NULL;
11860 REQUIRE(DNS_ZONE_VALID(zone));
11861 REQUIRE(messagep != NULL && *messagep == NULL);
11863 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
11865 if (result != ISC_R_SUCCESS)
11868 message->opcode = dns_opcode_notify;
11869 message->flags |= DNS_MESSAGEFLAG_AA;
11870 message->rdclass = zone->rdclass;
11872 result = dns_message_gettempname(message, &tempname);
11873 if (result != ISC_R_SUCCESS)
11876 result = dns_message_gettemprdataset(message, &temprdataset);
11877 if (result != ISC_R_SUCCESS)
11883 dns_name_init(tempname, NULL);
11884 dns_name_clone(&zone->origin, tempname);
11885 dns_rdataset_init(temprdataset);
11886 dns_rdataset_makequestion(temprdataset, zone->rdclass,
11887 dns_rdatatype_soa);
11888 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11889 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
11891 temprdataset = NULL;
11893 if ((flags & DNS_NOTIFY_NOSOA) != 0)
11896 result = dns_message_gettempname(message, &tempname);
11897 if (result != ISC_R_SUCCESS)
11899 result = dns_message_gettemprdata(message, &temprdata);
11900 if (result != ISC_R_SUCCESS)
11902 result = dns_message_gettemprdataset(message, &temprdataset);
11903 if (result != ISC_R_SUCCESS)
11905 result = dns_message_gettemprdatalist(message, &temprdatalist);
11906 if (result != ISC_R_SUCCESS)
11909 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11910 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
11911 dns_db_attach(zone->db, &zonedb);
11912 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11914 dns_name_init(tempname, NULL);
11915 dns_name_clone(&zone->origin, tempname);
11916 dns_db_currentversion(zonedb, &version);
11917 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
11918 if (result != ISC_R_SUCCESS)
11921 dns_rdataset_init(&rdataset);
11922 result = dns_db_findrdataset(zonedb, node, version,
11924 dns_rdatatype_none, 0, &rdataset,
11926 if (result != ISC_R_SUCCESS)
11928 result = dns_rdataset_first(&rdataset);
11929 if (result != ISC_R_SUCCESS)
11931 dns_rdataset_current(&rdataset, &rdata);
11932 dns_rdata_toregion(&rdata, &r);
11933 result = isc_buffer_allocate(zone->mctx, &b, r.length);
11934 if (result != ISC_R_SUCCESS)
11936 isc_buffer_putmem(b, r.base, r.length);
11937 isc_buffer_usedregion(b, &r);
11938 dns_rdata_init(temprdata);
11939 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
11940 dns_message_takebuffer(message, &b);
11941 result = dns_rdataset_next(&rdataset);
11942 dns_rdataset_disassociate(&rdataset);
11943 if (result != ISC_R_NOMORE)
11945 temprdatalist->rdclass = rdata.rdclass;
11946 temprdatalist->type = rdata.type;
11947 temprdatalist->ttl = rdataset.ttl;
11948 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
11950 dns_rdataset_init(temprdataset);
11951 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
11952 if (result != ISC_R_SUCCESS)
11955 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11956 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
11957 temprdatalist = NULL;
11958 temprdataset = NULL;
11964 dns_db_detachnode(zonedb, &node);
11965 if (version != NULL)
11966 dns_db_closeversion(zonedb, &version, ISC_FALSE);
11967 if (zonedb != NULL)
11968 dns_db_detach(&zonedb);
11969 if (tempname != NULL)
11970 dns_message_puttempname(message, &tempname);
11971 if (temprdata != NULL)
11972 dns_message_puttemprdata(message, &temprdata);
11973 if (temprdataset != NULL)
11974 dns_message_puttemprdataset(message, &temprdataset);
11975 if (temprdatalist != NULL)
11976 dns_message_puttemprdatalist(message, &temprdatalist);
11979 *messagep = message;
11980 return (ISC_R_SUCCESS);
11983 if (tempname != NULL)
11984 dns_message_puttempname(message, &tempname);
11985 if (temprdataset != NULL)
11986 dns_message_puttemprdataset(message, &temprdataset);
11987 dns_message_destroy(&message);
11992 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
11993 dns_message_t *msg)
11996 dns_rdata_soa_t soa;
11997 dns_rdataset_t *rdataset = NULL;
11998 dns_rdata_t rdata = DNS_RDATA_INIT;
11999 isc_result_t result;
12000 char fromtext[ISC_SOCKADDR_FORMATSIZE];
12002 isc_netaddr_t netaddr;
12003 isc_sockaddr_t local, remote;
12004 dns_tsigkey_t *tsigkey;
12007 REQUIRE(DNS_ZONE_VALID(zone));
12010 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
12014 * Check that 'from' is a valid notify source, (zone->masters).
12015 * Return DNS_R_REFUSED if not.
12017 * If the notify message contains a serial number check it
12018 * against the zones serial and return if <= current serial
12020 * If a refresh check is progress, if so just record the
12021 * fact we received a NOTIFY and from where and return.
12022 * We will perform a new refresh check when the current one
12023 * completes. Return ISC_R_SUCCESS.
12025 * Otherwise initiate a refresh check using 'from' as the
12026 * first address to check. Return ISC_R_SUCCESS.
12029 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
12032 * Notify messages are processed by the raw zone.
12035 if (inline_secure(zone)) {
12036 result = dns_zone_notifyreceive(zone->raw, from, msg);
12041 * We only handle NOTIFY (SOA) at the present.
12043 if (isc_sockaddr_pf(from) == PF_INET)
12044 inc_stats(zone, dns_zonestatscounter_notifyinv4);
12046 inc_stats(zone, dns_zonestatscounter_notifyinv6);
12047 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
12048 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
12049 dns_rdatatype_soa, dns_rdatatype_none,
12050 NULL, NULL) != ISC_R_SUCCESS) {
12052 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
12053 dns_zone_log(zone, ISC_LOG_NOTICE,
12055 "question section from: %s", fromtext);
12056 return (DNS_R_FORMERR);
12058 dns_zone_log(zone, ISC_LOG_NOTICE,
12059 "NOTIFY zone does not match");
12060 return (DNS_R_NOTIMP);
12064 * If we are a master zone just succeed.
12066 if (zone->type == dns_zone_master) {
12068 return (ISC_R_SUCCESS);
12071 isc_netaddr_fromsockaddr(&netaddr, from);
12072 for (i = 0; i < zone->masterscnt; i++) {
12073 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
12075 if (zone->view->aclenv.match_mapped &&
12076 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
12077 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
12078 isc_netaddr_t na1, na2;
12079 isc_netaddr_fromv4mapped(&na1, &netaddr);
12080 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
12081 if (isc_netaddr_equal(&na1, &na2))
12087 * Accept notify requests from non masters if they are on
12088 * 'zone->notify_acl'.
12090 tsigkey = dns_message_gettsigkey(msg);
12091 tsig = dns_tsigkey_identity(tsigkey);
12092 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
12093 dns_acl_match(&netaddr, tsig, zone->notify_acl,
12094 &zone->view->aclenv,
12095 &match, NULL) == ISC_R_SUCCESS &&
12098 /* Accept notify. */
12099 } else if (i >= zone->masterscnt) {
12101 dns_zone_log(zone, ISC_LOG_INFO,
12102 "refused notify from non-master: %s", fromtext);
12103 inc_stats(zone, dns_zonestatscounter_notifyrej);
12104 return (DNS_R_REFUSED);
12108 * If the zone is loaded and there are answers check the serial
12109 * to see if we need to do a refresh. Do not worry about this
12110 * check if we are a dialup zone as we use the notify request
12111 * to trigger a refresh check.
12113 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
12114 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
12115 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
12116 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
12119 dns_rdatatype_none, NULL,
12121 if (result == ISC_R_SUCCESS)
12122 result = dns_rdataset_first(rdataset);
12123 if (result == ISC_R_SUCCESS) {
12124 isc_uint32_t serial = 0, oldserial;
12125 unsigned int soacount;
12127 dns_rdataset_current(rdataset, &rdata);
12128 result = dns_rdata_tostruct(&rdata, &soa, NULL);
12129 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12130 serial = soa.serial;
12132 * The following should safely be performed without DB
12133 * lock and succeed in this context.
12135 result = zone_get_from_db(zone, zone->db, NULL,
12136 &soacount, &oldserial, NULL,
12137 NULL, NULL, NULL, NULL);
12138 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12139 RUNTIME_CHECK(soacount > 0U);
12140 if (isc_serial_le(serial, oldserial)) {
12144 "zone is up to date",
12147 return (ISC_R_SUCCESS);
12153 * If we got this far and there was a refresh in progress just
12154 * let it complete. Record where we got the notify from so we
12155 * can perform a refresh check when the current one completes
12157 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
12158 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12159 zone->notifyfrom = *from;
12161 dns_zone_log(zone, ISC_LOG_INFO,
12162 "notify from %s: refresh in progress, "
12163 "refresh check queued",
12165 return (ISC_R_SUCCESS);
12167 zone->notifyfrom = *from;
12168 remote = zone->masteraddr;
12169 local = zone->sourceaddr;
12171 dns_zonemgr_unreachabledel(zone->zmgr, &remote, &local);
12172 dns_zone_refresh(zone);
12173 return (ISC_R_SUCCESS);
12177 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
12179 REQUIRE(DNS_ZONE_VALID(zone));
12182 if (zone->notify_acl != NULL)
12183 dns_acl_detach(&zone->notify_acl);
12184 dns_acl_attach(acl, &zone->notify_acl);
12189 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
12191 REQUIRE(DNS_ZONE_VALID(zone));
12194 if (zone->query_acl != NULL)
12195 dns_acl_detach(&zone->query_acl);
12196 dns_acl_attach(acl, &zone->query_acl);
12201 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
12203 REQUIRE(DNS_ZONE_VALID(zone));
12206 if (zone->queryon_acl != NULL)
12207 dns_acl_detach(&zone->queryon_acl);
12208 dns_acl_attach(acl, &zone->queryon_acl);
12213 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
12215 REQUIRE(DNS_ZONE_VALID(zone));
12218 if (zone->update_acl != NULL)
12219 dns_acl_detach(&zone->update_acl);
12220 dns_acl_attach(acl, &zone->update_acl);
12225 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
12227 REQUIRE(DNS_ZONE_VALID(zone));
12230 if (zone->forward_acl != NULL)
12231 dns_acl_detach(&zone->forward_acl);
12232 dns_acl_attach(acl, &zone->forward_acl);
12237 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
12239 REQUIRE(DNS_ZONE_VALID(zone));
12242 if (zone->xfr_acl != NULL)
12243 dns_acl_detach(&zone->xfr_acl);
12244 dns_acl_attach(acl, &zone->xfr_acl);
12249 dns_zone_getnotifyacl(dns_zone_t *zone) {
12251 REQUIRE(DNS_ZONE_VALID(zone));
12253 return (zone->notify_acl);
12257 dns_zone_getqueryacl(dns_zone_t *zone) {
12259 REQUIRE(DNS_ZONE_VALID(zone));
12261 return (zone->query_acl);
12265 dns_zone_getqueryonacl(dns_zone_t *zone) {
12267 REQUIRE(DNS_ZONE_VALID(zone));
12269 return (zone->queryon_acl);
12273 dns_zone_getupdateacl(dns_zone_t *zone) {
12275 REQUIRE(DNS_ZONE_VALID(zone));
12277 return (zone->update_acl);
12281 dns_zone_getforwardacl(dns_zone_t *zone) {
12283 REQUIRE(DNS_ZONE_VALID(zone));
12285 return (zone->forward_acl);
12289 dns_zone_getxfracl(dns_zone_t *zone) {
12291 REQUIRE(DNS_ZONE_VALID(zone));
12293 return (zone->xfr_acl);
12297 dns_zone_clearupdateacl(dns_zone_t *zone) {
12299 REQUIRE(DNS_ZONE_VALID(zone));
12302 if (zone->update_acl != NULL)
12303 dns_acl_detach(&zone->update_acl);
12308 dns_zone_clearforwardacl(dns_zone_t *zone) {
12310 REQUIRE(DNS_ZONE_VALID(zone));
12313 if (zone->forward_acl != NULL)
12314 dns_acl_detach(&zone->forward_acl);
12319 dns_zone_clearnotifyacl(dns_zone_t *zone) {
12321 REQUIRE(DNS_ZONE_VALID(zone));
12324 if (zone->notify_acl != NULL)
12325 dns_acl_detach(&zone->notify_acl);
12330 dns_zone_clearqueryacl(dns_zone_t *zone) {
12332 REQUIRE(DNS_ZONE_VALID(zone));
12335 if (zone->query_acl != NULL)
12336 dns_acl_detach(&zone->query_acl);
12341 dns_zone_clearqueryonacl(dns_zone_t *zone) {
12343 REQUIRE(DNS_ZONE_VALID(zone));
12346 if (zone->queryon_acl != NULL)
12347 dns_acl_detach(&zone->queryon_acl);
12352 dns_zone_clearxfracl(dns_zone_t *zone) {
12354 REQUIRE(DNS_ZONE_VALID(zone));
12357 if (zone->xfr_acl != NULL)
12358 dns_acl_detach(&zone->xfr_acl);
12363 dns_zone_getupdatedisabled(dns_zone_t *zone) {
12364 REQUIRE(DNS_ZONE_VALID(zone));
12365 return (zone->update_disabled);
12370 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
12371 REQUIRE(DNS_ZONE_VALID(zone));
12372 zone->update_disabled = state;
12376 dns_zone_getzeronosoattl(dns_zone_t *zone) {
12377 REQUIRE(DNS_ZONE_VALID(zone));
12378 return (zone->zero_no_soa_ttl);
12383 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
12384 REQUIRE(DNS_ZONE_VALID(zone));
12385 zone->zero_no_soa_ttl = state;
12389 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
12391 REQUIRE(DNS_ZONE_VALID(zone));
12393 zone->check_names = severity;
12397 dns_zone_getchecknames(dns_zone_t *zone) {
12399 REQUIRE(DNS_ZONE_VALID(zone));
12401 return (zone->check_names);
12405 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
12407 REQUIRE(DNS_ZONE_VALID(zone));
12409 zone->journalsize = size;
12413 dns_zone_getjournalsize(dns_zone_t *zone) {
12415 REQUIRE(DNS_ZONE_VALID(zone));
12417 return (zone->journalsize);
12421 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
12422 isc_result_t result = ISC_R_FAILURE;
12423 isc_buffer_t buffer;
12425 REQUIRE(buf != NULL);
12426 REQUIRE(length > 1U);
12429 * Leave space for terminating '\0'.
12431 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12432 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
12433 if (dns_name_dynamic(&zone->origin))
12434 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12435 if (result != ISC_R_SUCCESS &&
12436 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12437 isc_buffer_putstr(&buffer, "<UNKNOWN>");
12439 if (isc_buffer_availablelength(&buffer) > 0)
12440 isc_buffer_putstr(&buffer, "/");
12441 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
12444 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
12445 strcmp(zone->view->name, "_default") != 0 &&
12446 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
12447 isc_buffer_putstr(&buffer, "/");
12448 isc_buffer_putstr(&buffer, zone->view->name);
12450 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
12451 isc_buffer_putstr(&buffer, " (signed)");
12452 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
12453 isc_buffer_putstr(&buffer, " (unsigned)");
12455 buf[isc_buffer_usedlength(&buffer)] = '\0';
12459 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
12460 isc_result_t result = ISC_R_FAILURE;
12461 isc_buffer_t buffer;
12463 REQUIRE(buf != NULL);
12464 REQUIRE(length > 1U);
12467 * Leave space for terminating '\0'.
12469 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12470 if (dns_name_dynamic(&zone->origin))
12471 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12472 if (result != ISC_R_SUCCESS &&
12473 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12474 isc_buffer_putstr(&buffer, "<UNKNOWN>");
12476 buf[isc_buffer_usedlength(&buffer)] = '\0';
12480 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
12481 isc_buffer_t buffer;
12483 REQUIRE(buf != NULL);
12484 REQUIRE(length > 1U);
12487 * Leave space for terminating '\0'.
12489 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12490 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
12492 buf[isc_buffer_usedlength(&buffer)] = '\0';
12496 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
12497 isc_buffer_t buffer;
12499 REQUIRE(buf != NULL);
12500 REQUIRE(length > 1U);
12504 * Leave space for terminating '\0'.
12506 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12508 if (zone->view == NULL) {
12509 isc_buffer_putstr(&buffer, "_none");
12510 } else if (strlen(zone->view->name)
12511 < isc_buffer_availablelength(&buffer)) {
12512 isc_buffer_putstr(&buffer, zone->view->name);
12514 isc_buffer_putstr(&buffer, "_toolong");
12517 buf[isc_buffer_usedlength(&buffer)] = '\0';
12521 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
12522 REQUIRE(DNS_ZONE_VALID(zone));
12523 REQUIRE(buf != NULL);
12524 zone_namerd_tostr(zone, buf, length);
12528 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
12529 REQUIRE(DNS_ZONE_VALID(zone));
12530 REQUIRE(buf != NULL);
12531 zone_name_tostr(zone, buf, length);
12535 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12537 char message[4096];
12539 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12543 vsnprintf(message, sizeof(message), fmt, ap);
12545 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
12546 level, "zone %s: %s", zone->strnamerd, message);
12550 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
12551 int level, const char *fmt, ...) {
12553 char message[4096];
12555 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12559 vsnprintf(message, sizeof(message), fmt, ap);
12561 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
12562 level, "%s%s: %s", (zone->type == dns_zone_key) ?
12563 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
12564 "redirect-zone" : "zone ", zone->strnamerd, message);
12568 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12570 char message[4096];
12572 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12576 vsnprintf(message, sizeof(message), fmt, ap);
12578 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
12579 level, "%s%s: %s", (zone->type == dns_zone_key) ?
12580 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
12581 "redirect-zone" : "zone ", zone->strnamerd, message);
12585 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
12586 const char *fmt, ...)
12589 char message[4096];
12590 int level = ISC_LOG_DEBUG(debuglevel);
12593 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12597 vsnprintf(message, sizeof(message), fmt, ap);
12600 switch (zone->type) {
12602 zstr = "managed-keys-zone";
12604 case dns_zone_redirect:
12605 zstr = "redirect-zone";
12611 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
12612 level, "%s: %s %s: %s", me, zstr, zone->strnamerd,
12617 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
12619 isc_result_t result;
12621 dns_rdataset_t *curr;
12624 result = dns_message_firstname(msg, section);
12625 while (result == ISC_R_SUCCESS) {
12627 dns_message_currentname(msg, section, &name);
12629 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
12630 curr = ISC_LIST_PREV(curr, link)) {
12631 if (curr->type == type)
12634 result = dns_message_nextname(msg, section);
12641 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
12642 REQUIRE(DNS_ZONE_VALID(zone));
12644 zone->maxxfrin = maxxfrin;
12648 dns_zone_getmaxxfrin(dns_zone_t *zone) {
12649 REQUIRE(DNS_ZONE_VALID(zone));
12651 return (zone->maxxfrin);
12655 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
12656 REQUIRE(DNS_ZONE_VALID(zone));
12657 zone->maxxfrout = maxxfrout;
12661 dns_zone_getmaxxfrout(dns_zone_t *zone) {
12662 REQUIRE(DNS_ZONE_VALID(zone));
12664 return (zone->maxxfrout);
12668 dns_zone_gettype(dns_zone_t *zone) {
12669 REQUIRE(DNS_ZONE_VALID(zone));
12671 return (zone->type);
12675 dns_zone_getorigin(dns_zone_t *zone) {
12676 REQUIRE(DNS_ZONE_VALID(zone));
12678 return (&zone->origin);
12682 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
12683 REQUIRE(DNS_ZONE_VALID(zone));
12686 if (zone->task != NULL)
12687 isc_task_detach(&zone->task);
12688 isc_task_attach(task, &zone->task);
12689 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12690 if (zone->db != NULL)
12691 dns_db_settask(zone->db, zone->task);
12692 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12697 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
12698 REQUIRE(DNS_ZONE_VALID(zone));
12699 isc_task_attach(zone->task, target);
12703 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
12704 REQUIRE(DNS_ZONE_VALID(zone));
12707 idlein = DNS_DEFAULT_IDLEIN;
12708 zone->idlein = idlein;
12712 dns_zone_getidlein(dns_zone_t *zone) {
12713 REQUIRE(DNS_ZONE_VALID(zone));
12715 return (zone->idlein);
12719 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
12720 REQUIRE(DNS_ZONE_VALID(zone));
12722 zone->idleout = idleout;
12726 dns_zone_getidleout(dns_zone_t *zone) {
12727 REQUIRE(DNS_ZONE_VALID(zone));
12729 return (zone->idleout);
12733 notify_done(isc_task_t *task, isc_event_t *event) {
12734 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12735 dns_notify_t *notify;
12736 isc_result_t result;
12737 dns_message_t *message = NULL;
12740 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
12744 notify = event->ev_arg;
12745 REQUIRE(DNS_NOTIFY_VALID(notify));
12746 INSIST(task == notify->zone->task);
12748 isc_buffer_init(&buf, rcode, sizeof(rcode));
12749 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
12751 result = revent->result;
12752 if (result == ISC_R_SUCCESS)
12753 result = dns_message_create(notify->zone->mctx,
12754 DNS_MESSAGE_INTENTPARSE, &message);
12755 if (result == ISC_R_SUCCESS)
12756 result = dns_request_getresponse(revent->request, message,
12757 DNS_MESSAGEPARSE_PRESERVEORDER);
12758 if (result == ISC_R_SUCCESS)
12759 result = dns_rcode_totext(message->rcode, &buf);
12760 if (result == ISC_R_SUCCESS)
12761 notify_log(notify->zone, ISC_LOG_DEBUG(3),
12762 "notify response from %s: %.*s",
12763 addrbuf, (int)buf.used, rcode);
12765 notify_log(notify->zone, ISC_LOG_DEBUG(2),
12766 "notify to %s failed: %s", addrbuf,
12767 dns_result_totext(result));
12770 * Old bind's return formerr if they see a soa record. Retry w/o
12771 * the soa if we see a formerr and had sent a SOA.
12773 isc_event_free(&event);
12774 if (message != NULL && message->rcode == dns_rcode_formerr &&
12775 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
12776 isc_boolean_t startup;
12778 notify->flags |= DNS_NOTIFY_NOSOA;
12779 dns_request_destroy(¬ify->request);
12780 startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
12781 result = notify_send_queue(notify, startup);
12782 if (result != ISC_R_SUCCESS)
12783 notify_destroy(notify, ISC_FALSE);
12785 if (result == ISC_R_TIMEDOUT)
12786 notify_log(notify->zone, ISC_LOG_DEBUG(1),
12787 "notify to %s: retries exceeded", addrbuf);
12788 notify_destroy(notify, ISC_FALSE);
12790 if (message != NULL)
12791 dns_message_destroy(&message);
12794 struct secure_event {
12797 isc_uint32_t serial;
12801 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
12803 dns_zone_log(zone, level, "%s", message);
12806 static isc_result_t
12807 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
12808 isc_uint32_t start, isc_uint32_t end,
12809 dns_difftuple_t **soatuplep, dns_diff_t *diff)
12811 isc_result_t result;
12812 dns_difftuple_t *tuple = NULL;
12813 dns_diffop_t op = DNS_DIFFOP_ADD;
12816 REQUIRE(soatuplep != NULL);
12819 return (DNS_R_UNCHANGED);
12821 CHECK(dns_journal_iter_init(journal, start, end));
12822 for (result = dns_journal_first_rr(journal);
12823 result == ISC_R_SUCCESS;
12824 result = dns_journal_next_rr(journal))
12826 dns_name_t *name = NULL;
12828 dns_rdata_t *rdata = NULL;
12829 dns_journal_current_rr(journal, &name, &ttl, &rdata);
12831 if (rdata->type == dns_rdatatype_soa) {
12835 * Save the latest raw SOA record.
12837 if (*soatuplep != NULL)
12838 dns_difftuple_free(soatuplep);
12839 CHECK(dns_difftuple_create(diff->mctx,
12851 dns_zone_log(raw, ISC_LOG_ERROR,
12852 "corrupt journal file: '%s'\n",
12854 return (ISC_R_FAILURE);
12857 if (zone->privatetype != 0 &&
12858 rdata->type == zone->privatetype)
12861 if (rdata->type == dns_rdatatype_nsec ||
12862 rdata->type == dns_rdatatype_rrsig ||
12863 rdata->type == dns_rdatatype_nsec3 ||
12864 rdata->type == dns_rdatatype_dnskey ||
12865 rdata->type == dns_rdatatype_nsec3param)
12868 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
12870 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
12872 dns_diff_appendminimal(diff, &tuple);
12874 if (result == ISC_R_NOMORE)
12875 result = ISC_R_SUCCESS;
12881 static isc_result_t
12882 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
12883 dns_dbversion_t *secver, dns_difftuple_t **soatuple,
12886 isc_result_t result;
12887 dns_db_t *rawdb = NULL;
12888 dns_dbversion_t *rawver = NULL;
12889 dns_difftuple_t *tuple = NULL, *next;
12890 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
12891 dns_rdata_soa_t oldsoa, newsoa;
12893 REQUIRE(DNS_ZONE_VALID(seczone));
12894 REQUIRE(soatuple != NULL && *soatuple == NULL);
12896 if (!seczone->sourceserialset)
12897 return (DNS_R_UNCHANGED);
12899 dns_db_attach(raw->db, &rawdb);
12900 dns_db_currentversion(rawdb, &rawver);
12901 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
12902 dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
12903 dns_db_detach(&rawdb);
12905 if (result != ISC_R_SUCCESS)
12908 for (tuple = ISC_LIST_HEAD(diff->tuples);
12912 next = ISC_LIST_NEXT(tuple, link);
12913 if (tuple->rdata.type == dns_rdatatype_nsec ||
12914 tuple->rdata.type == dns_rdatatype_rrsig ||
12915 tuple->rdata.type == dns_rdatatype_dnskey ||
12916 tuple->rdata.type == dns_rdatatype_nsec3 ||
12917 tuple->rdata.type == dns_rdatatype_nsec3param)
12919 ISC_LIST_UNLINK(diff->tuples, tuple, link);
12920 dns_difftuple_free(&tuple);
12923 if (tuple->rdata.type == dns_rdatatype_soa) {
12924 if (tuple->op == DNS_DIFFOP_DEL) {
12925 INSIST(oldtuple == NULL);
12928 if (tuple->op == DNS_DIFFOP_ADD) {
12929 INSIST(newtuple == NULL);
12935 if (oldtuple != NULL && newtuple != NULL) {
12937 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
12938 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12940 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
12941 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12944 * If the SOA records are the same except for the serial
12945 * remove them from the diff.
12947 if (oldsoa.refresh == newsoa.refresh &&
12948 oldsoa.retry == newsoa.retry &&
12949 oldsoa.minimum == newsoa.minimum &&
12950 oldsoa.expire == newsoa.expire &&
12951 dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
12952 dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
12953 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
12954 dns_difftuple_free(&oldtuple);
12955 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
12956 dns_difftuple_free(&newtuple);
12960 if (ISC_LIST_EMPTY(diff->tuples))
12961 return (DNS_R_UNCHANGED);
12964 * If there are still SOA records in the diff they can now be removed
12965 * saving the new SOA record.
12967 if (oldtuple != NULL) {
12968 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
12969 dns_difftuple_free(&oldtuple);
12972 if (newtuple != NULL) {
12973 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
12974 *soatuple = newtuple;
12977 return (ISC_R_SUCCESS);
12981 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
12982 static char me[] = "receive_secure_serial";
12983 isc_result_t result = ISC_R_SUCCESS;
12984 dns_journal_t *rjournal = NULL;
12985 dns_journal_t *sjournal = NULL;
12986 isc_uint32_t start, end;
12988 dns_difftuple_t *tuple = NULL, *soatuple = NULL;
12989 dns_update_log_t log = { update_log_cb, NULL };
12990 isc_time_t timenow;
12994 zone = event->ev_arg;
12995 end = ((struct secure_event *)event)->serial;
13002 * If we are already processing a receive secure serial event
13003 * for the zone, just queue the new one and exit.
13005 if (zone->rss_event != NULL && zone->rss_event != event) {
13006 ISC_LIST_APPEND(zone->rss_events, event, ev_link);
13012 if (zone->rss_event != NULL) {
13013 INSIST(zone->rss_event == event);
13016 zone->rss_event = event;
13017 dns_diff_init(zone->mctx, &zone->rss_diff);
13020 * zone->db may be NULL, if the load from disk failed.
13022 result = ISC_R_SUCCESS;
13023 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13024 if (zone->db != NULL)
13025 dns_db_attach(zone->db, &zone->rss_db);
13027 result = ISC_R_FAILURE;
13028 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13030 if (result == ISC_R_SUCCESS && zone->raw != NULL)
13031 dns_zone_attach(zone->raw, &zone->rss_raw);
13033 result = ISC_R_FAILURE;
13040 * We first attempt to sync the raw zone to the secure zone
13041 * by using the raw zone's journal, applying all the deltas
13042 * from the latest source-serial of the secure zone up to
13043 * the current serial number of the raw zone.
13045 * If that fails, then we'll fall back to a direct comparison
13046 * between raw and secure zones.
13048 CHECK(dns_journal_open(zone->rss_raw->mctx,
13049 zone->rss_raw->journal,
13050 DNS_JOURNAL_WRITE, &rjournal));
13052 result = dns_journal_open(zone->mctx, zone->journal,
13053 DNS_JOURNAL_READ, &sjournal);
13054 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
13057 if (!dns_journal_get_sourceserial(rjournal, &start)) {
13058 start = dns_journal_first_serial(rjournal);
13059 dns_journal_set_sourceserial(rjournal, start);
13061 if (sjournal != NULL) {
13062 isc_uint32_t serial;
13064 * We read the secure journal first, if that
13065 * exists use its value provided it is greater
13066 * that from the raw journal.
13068 if (dns_journal_get_sourceserial(sjournal, &serial)) {
13069 if (isc_serial_gt(serial, start))
13072 dns_journal_destroy(&sjournal);
13075 dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
13076 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
13079 * Try to apply diffs from the raw zone's journal to the secure
13080 * zone. If that fails, we recover by syncing up the databases
13083 result = sync_secure_journal(zone, zone->rss_raw, rjournal,
13084 start, end, &soatuple,
13086 if (result == DNS_R_UNCHANGED)
13088 else if (result != ISC_R_SUCCESS)
13089 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
13090 zone->rss_oldver, &soatuple,
13093 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
13094 zone->rss_newver));
13096 if (soatuple != NULL) {
13097 isc_uint32_t oldserial, newserial, desired;
13099 CHECK(dns_db_createsoatuple(zone->rss_db,
13101 zone->rss_diff.mctx,
13102 DNS_DIFFOP_DEL, &tuple));
13103 oldserial = dns_soa_getserial(&tuple->rdata);
13104 newserial = desired =
13105 dns_soa_getserial(&soatuple->rdata);
13106 if (!isc_serial_gt(newserial, oldserial)) {
13107 newserial = oldserial + 1;
13108 if (newserial == 0)
13110 dns_soa_setserial(newserial, &soatuple->rdata);
13112 CHECK(do_one_tuple(&tuple, zone->rss_db,
13113 zone->rss_newver, &zone->rss_diff));
13114 CHECK(do_one_tuple(&soatuple, zone->rss_db,
13115 zone->rss_newver, &zone->rss_diff));
13116 dns_zone_log(zone, ISC_LOG_INFO,
13117 "serial %u (unsigned %u)",
13118 newserial, desired);
13120 CHECK(update_soa_serial(zone->rss_db, zone->rss_newver,
13121 &zone->rss_diff, zone->mctx,
13122 zone->updatemethod));
13125 result = dns_update_signaturesinc(&log, zone, zone->rss_db,
13126 zone->rss_oldver, zone->rss_newver,
13128 zone->sigvalidityinterval,
13130 if (result == DNS_R_CONTINUE) {
13131 if (rjournal != NULL)
13132 dns_journal_destroy(&rjournal);
13133 isc_task_send(task, &event);
13134 fprintf(stderr, "looping on dns_update_signaturesinc\n");
13137 if (result != ISC_R_SUCCESS)
13140 if (rjournal == NULL)
13141 CHECK(dns_journal_open(zone->rss_raw->mctx,
13142 zone->rss_raw->journal,
13143 DNS_JOURNAL_WRITE, &rjournal));
13144 CHECK(zone_journal(zone, &zone->rss_diff, &end,
13145 "receive_secure_serial"));
13147 dns_journal_set_sourceserial(rjournal, end);
13148 dns_journal_commit(rjournal);
13151 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13153 zone->sourceserial = end;
13154 zone->sourceserialset = ISC_TRUE;
13155 zone_needdump(zone, DNS_DUMP_DELAY);
13157 TIME_NOW(&timenow);
13158 zone_settimer(zone, &timenow);
13161 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, ISC_FALSE);
13162 dns_db_closeversion(zone->rss_db, &zone->rss_newver, ISC_TRUE);
13165 isc_event_free(&zone->rss_event);
13166 event = ISC_LIST_HEAD(zone->rss_events);
13168 if (zone->rss_raw != NULL)
13169 dns_zone_detach(&zone->rss_raw);
13170 if (result != ISC_R_SUCCESS)
13171 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
13172 dns_result_totext(result));
13174 dns_difftuple_free(&tuple);
13175 if (soatuple != NULL)
13176 dns_difftuple_free(&soatuple);
13177 if (zone->rss_db != NULL) {
13178 if (zone->rss_oldver != NULL)
13179 dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
13181 if (zone->rss_newver != NULL)
13182 dns_db_closeversion(zone->rss_db, &zone->rss_newver,
13184 dns_db_detach(&zone->rss_db);
13186 INSIST(zone->rss_oldver == NULL);
13187 INSIST(zone->rss_newver == NULL);
13188 if (rjournal != NULL)
13189 dns_journal_destroy(&rjournal);
13190 dns_diff_clear(&zone->rss_diff);
13192 if (event != NULL) {
13194 INSIST(zone->irefs > 1);
13198 dns_zone_idetach(&zone);
13201 static isc_result_t
13202 zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) {
13204 dns_zone_t *dummy = NULL;
13206 e = isc_event_allocate(zone->secure->mctx, zone,
13207 DNS_EVENT_ZONESECURESERIAL,
13208 receive_secure_serial, zone->secure,
13209 sizeof(struct secure_event));
13211 return (ISC_R_NOMEMORY);
13212 ((struct secure_event *)e)->serial = serial;
13213 INSIST(LOCKED_ZONE(zone->secure));
13214 zone_iattach(zone->secure, &dummy);
13215 isc_task_send(zone->secure->task, &e);
13217 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
13218 return (ISC_R_SUCCESS);
13221 static isc_result_t
13222 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
13223 dns_rdataset_t *rdataset, isc_uint32_t oldserial)
13225 dns_rdata_soa_t soa;
13226 dns_rdata_t rdata = DNS_RDATA_INIT;
13227 dns_rdatalist_t temprdatalist;
13228 dns_rdataset_t temprdataset;
13230 isc_result_t result;
13231 unsigned char buf[DNS_SOA_BUFFERSIZE];
13233 result = dns_rdataset_first(rdataset);
13234 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13235 dns_rdataset_current(rdataset, &rdata);
13236 result = dns_rdata_tostruct(&rdata, &soa, NULL);
13237 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13239 if (isc_serial_gt(soa.serial, oldserial))
13240 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
13243 * Always bump the serial.
13246 if (oldserial == 0)
13248 soa.serial = oldserial;
13251 * Construct a replacement rdataset.
13253 dns_rdata_reset(&rdata);
13254 isc_buffer_init(&b, buf, sizeof(buf));
13255 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
13256 dns_rdatatype_soa, &soa, &b);
13257 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13258 dns_rdatalist_init(&temprdatalist);
13259 temprdatalist.rdclass = rdata.rdclass;
13260 temprdatalist.type = rdata.type;
13261 temprdatalist.ttl = rdataset->ttl;
13262 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
13264 dns_rdataset_init(&temprdataset);
13265 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
13266 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13267 return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
13272 * This function should populate an nsec3paramlist_t with the
13273 * nsecparam_t data from a zone.
13275 static isc_result_t
13276 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
13277 isc_result_t result;
13278 dns_dbnode_t *node = NULL;
13279 dns_rdataset_t rdataset, prdataset;
13280 dns_dbversion_t *version = NULL;
13281 nsec3param_t *nsec3param = NULL;
13282 nsec3param_t *nsec3p = NULL;
13283 nsec3param_t *next;
13284 dns_db_t *db = NULL;
13285 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
13287 REQUIRE(DNS_ZONE_VALID(zone));
13288 REQUIRE(nsec3list != NULL);
13289 REQUIRE(ISC_LIST_EMPTY(*nsec3list));
13291 dns_rdataset_init(&rdataset);
13292 dns_rdataset_init(&prdataset);
13294 dns_db_attach(zone->db, &db);
13295 CHECK(dns_db_getoriginnode(db, &node));
13297 dns_db_currentversion(db, &version);
13298 result = dns_db_findrdataset(db, node, version,
13299 dns_rdatatype_nsec3param,
13300 dns_rdatatype_none, 0, &rdataset, NULL);
13302 if (result != ISC_R_SUCCESS)
13306 * walk nsec3param rdataset making a list of parameters (note that
13307 * multiple simultaneous nsec3 chains are annoyingly legal -- this
13308 * is why we use an nsec3list, even tho we will usually only have
13311 for (result = dns_rdataset_first(&rdataset);
13312 result == ISC_R_SUCCESS;
13313 result = dns_rdataset_next(&rdataset))
13315 dns_rdata_t rdata = DNS_RDATA_INIT;
13316 dns_rdata_t private = DNS_RDATA_INIT;
13318 dns_rdataset_current(&rdataset, &rdata);
13319 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13320 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13321 "looping through nsec3param data");
13322 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13323 if (nsec3param == NULL)
13324 CHECK(ISC_R_NOMEMORY);
13325 ISC_LINK_INIT(nsec3param, link);
13328 * now transfer the data from the rdata to
13331 dns_nsec3param_toprivate(&rdata, &private,
13332 zone->privatetype, nsec3param->data,
13333 sizeof(nsec3param->data));
13334 nsec3param->length = private.length;
13335 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13339 result = dns_db_findrdataset(db, node, version, zone->privatetype,
13340 dns_rdatatype_none, 0, &prdataset, NULL);
13341 if (result != ISC_R_SUCCESS)
13345 * walk private type records, converting them to nsec3 parameters
13346 * using dns_nsec3param_fromprivate(), do the right thing based on
13347 * CREATE and REMOVE flags
13349 for (result = dns_rdataset_first(&prdataset);
13350 result == ISC_R_SUCCESS;
13351 result = dns_rdataset_next(&prdataset))
13353 dns_rdata_t rdata = DNS_RDATA_INIT;
13354 dns_rdata_t private = DNS_RDATA_INIT;
13356 dns_rdataset_current(&prdataset, &private);
13357 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13358 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13359 "looping through nsec3param private data");
13362 * Do we have a valid private record?
13364 if (!dns_nsec3param_fromprivate(&private, &rdata,
13369 * Remove any NSEC3PARAM records scheduled to be removed.
13371 if (NSEC3REMOVE(rdata.data[1])) {
13373 * Zero out the flags.
13377 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13381 next = ISC_LIST_NEXT(nsec3p, link);
13383 if (nsec3p->length == rdata.length + 1 &&
13384 memcmp(rdata.data, nsec3p->data + 1,
13385 nsec3p->length - 1) == 0) {
13386 ISC_LIST_UNLINK(*nsec3list,
13388 isc_mem_put(zone->mctx, nsec3p,
13389 sizeof(nsec3param_t));
13395 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13396 if (nsec3param == NULL)
13397 CHECK(ISC_R_NOMEMORY);
13398 ISC_LINK_INIT(nsec3param, link);
13401 * Copy the remaining private records so the nsec/nsec3
13402 * chain gets created.
13404 INSIST(private.length <= sizeof(nsec3param->data));
13405 memmove(nsec3param->data, private.data, private.length);
13406 nsec3param->length = private.length;
13407 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13411 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
13412 result = ISC_R_SUCCESS;
13416 dns_db_detachnode(db, &node);
13417 if (version != NULL)
13418 dns_db_closeversion(db, &version, ISC_FALSE);
13420 dns_db_detach(&db);
13421 if (dns_rdataset_isassociated(&rdataset))
13422 dns_rdataset_disassociate(&rdataset);
13423 if (dns_rdataset_isassociated(&prdataset))
13424 dns_rdataset_disassociate(&prdataset);
13429 * Walk the list of the nsec3 chains desired for the zone, converting
13430 * parameters to private type records using dns_nsec3param_toprivate(),
13431 * and insert them into the new zone db.
13433 static isc_result_t
13434 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
13435 nsec3paramlist_t *nsec3list)
13437 isc_result_t result;
13440 nsec3param_t *nsec3p = NULL;
13441 nsec3param_t *next;
13443 REQUIRE(DNS_ZONE_VALID(zone));
13444 REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
13446 dns_diff_init(zone->mctx, &diff);
13449 * Loop through the list of private-type records, set the INITIAL
13450 * and CREATE flags, and the add the record to the apex of the tree
13453 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13457 next = ISC_LIST_NEXT(nsec3p, link);
13458 dns_rdata_init(&rdata);
13459 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
13460 rdata.length = nsec3p->length;
13461 rdata.data = nsec3p->data;
13462 rdata.type = zone->privatetype;
13463 rdata.rdclass = zone->rdclass;
13464 CHECK(update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
13465 &zone->origin, 0, &rdata));
13468 result = ISC_R_SUCCESS;
13471 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13475 next = ISC_LIST_NEXT(nsec3p, link);
13476 ISC_LIST_UNLINK(*nsec3list, nsec3p, link);
13477 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
13480 dns_diff_clear(&diff);
13485 receive_secure_db(isc_task_t *task, isc_event_t *event) {
13486 isc_result_t result;
13488 dns_db_t *rawdb, *db = NULL;
13489 dns_dbnode_t *rawnode = NULL, *node = NULL;
13490 dns_fixedname_t fname;
13492 dns_dbiterator_t *dbiterator = NULL;
13493 dns_rdatasetiter_t *rdsit = NULL;
13494 dns_rdataset_t rdataset;
13495 dns_dbversion_t *version = NULL;
13496 isc_time_t loadtime;
13497 unsigned int oldserial = 0;
13498 isc_boolean_t have_oldserial = ISC_FALSE;
13499 nsec3paramlist_t nsec3list;
13503 ISC_LIST_INIT(nsec3list);
13505 zone = event->ev_arg;
13506 rawdb = ((struct secure_event *)event)->db;
13507 isc_event_free(&event);
13509 dns_fixedname_init(&fname);
13510 name = dns_fixedname_name(&fname);
13511 dns_rdataset_init(&rdataset);
13514 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
13515 result = ISC_R_SHUTTINGDOWN;
13519 TIME_NOW(&loadtime);
13520 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13521 if (zone->db != NULL) {
13522 result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
13523 if (result == ISC_R_SUCCESS)
13524 have_oldserial = ISC_TRUE;
13527 * assemble nsec3parameters from the old zone, and set a flag
13530 result = save_nsec3param(zone, &nsec3list);
13531 if (result != ISC_R_SUCCESS) {
13532 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13536 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13538 result = dns_db_create(zone->mctx, zone->db_argv[0],
13539 &zone->origin, dns_dbtype_zone, zone->rdclass,
13540 zone->db_argc - 1, zone->db_argv + 1, &db);
13541 if (result != ISC_R_SUCCESS)
13544 result = dns_db_newversion(db, &version);
13545 if (result != ISC_R_SUCCESS)
13548 result = dns_db_createiterator(rawdb, 0, &dbiterator);
13549 if (result != ISC_R_SUCCESS)
13552 for (result = dns_dbiterator_first(dbiterator);
13553 result == ISC_R_SUCCESS;
13554 result = dns_dbiterator_next(dbiterator)) {
13555 result = dns_dbiterator_current(dbiterator, &rawnode, name);
13556 if (result != ISC_R_SUCCESS)
13559 result = dns_db_findnode(db, name, ISC_TRUE, &node);
13560 if (result != ISC_R_SUCCESS)
13563 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
13564 if (result != ISC_R_SUCCESS)
13567 for (result = dns_rdatasetiter_first(rdsit);
13568 result == ISC_R_SUCCESS;
13569 result = dns_rdatasetiter_next(rdsit)) {
13570 dns_rdatasetiter_current(rdsit, &rdataset);
13571 if (rdataset.type == dns_rdatatype_nsec ||
13572 rdataset.type == dns_rdatatype_rrsig ||
13573 rdataset.type == dns_rdatatype_nsec3 ||
13574 rdataset.type == dns_rdatatype_dnskey ||
13575 rdataset.type == dns_rdatatype_nsec3param) {
13576 dns_rdataset_disassociate(&rdataset);
13579 if (rdataset.type == dns_rdatatype_soa &&
13581 result = checkandaddsoa(db, node, version,
13582 &rdataset, oldserial);
13584 result = dns_db_addrdataset(db, node, version,
13587 if (result != ISC_R_SUCCESS)
13590 dns_rdataset_disassociate(&rdataset);
13592 dns_rdatasetiter_destroy(&rdsit);
13593 dns_db_detachnode(rawdb, &rawnode);
13594 dns_db_detachnode(db, &node);
13598 * Call restore_nsec3param() to create private-type records from
13599 * the old nsec3 parameters and insert them into db
13601 if (!ISC_LIST_EMPTY(nsec3list))
13602 restore_nsec3param(zone, db, version, &nsec3list);
13604 dns_db_closeversion(db, &version, ISC_TRUE);
13607 * Lock hierarchy: zmgr, zone, raw.
13609 INSIST(zone != zone->raw);
13610 LOCK_ZONE(zone->raw);
13611 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13612 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
13613 zone_needdump(zone, 0); /* XXXMPA */
13614 UNLOCK_ZONE(zone->raw);
13618 if (result != ISC_R_SUCCESS)
13619 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
13620 dns_result_totext(result));
13622 while (!ISC_LIST_EMPTY(nsec3list)) {
13623 nsec3param_t *nsec3p;
13624 nsec3p = ISC_LIST_HEAD(nsec3list);
13625 ISC_LIST_UNLINK(nsec3list, nsec3p, link);
13626 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
13628 if (dns_rdataset_isassociated(&rdataset))
13629 dns_rdataset_disassociate(&rdataset);
13632 dns_db_detachnode(db, &node);
13633 if (version != NULL)
13634 dns_db_closeversion(db, &version, ISC_FALSE);
13635 dns_db_detach(&db);
13637 if (rawnode != NULL)
13638 dns_db_detachnode(rawdb, &rawnode);
13639 dns_db_detach(&rawdb);
13640 if (dbiterator != NULL)
13641 dns_dbiterator_destroy(&dbiterator);
13642 dns_zone_idetach(&zone);
13644 INSIST(version == NULL);
13647 static isc_result_t
13648 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
13650 dns_db_t *dummy = NULL;
13651 dns_zone_t *secure = NULL;
13653 e = isc_event_allocate(zone->secure->mctx, zone,
13654 DNS_EVENT_ZONESECUREDB,
13655 receive_secure_db, zone->secure,
13656 sizeof(struct secure_event));
13658 return (ISC_R_NOMEMORY);
13659 dns_db_attach(db, &dummy);
13660 ((struct secure_event *)e)->db = dummy;
13661 INSIST(LOCKED_ZONE(zone->secure));
13662 zone_iattach(zone->secure, &secure);
13663 isc_task_send(zone->secure->task, &e);
13664 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
13665 return (ISC_R_SUCCESS);
13669 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
13670 isc_result_t result;
13671 dns_zone_t *secure = NULL;
13673 REQUIRE(DNS_ZONE_VALID(zone));
13676 if (inline_raw(zone)) {
13677 secure = zone->secure;
13678 INSIST(secure != zone);
13679 TRYLOCK_ZONE(result, secure);
13680 if (result != ISC_R_SUCCESS) {
13683 #if ISC_PLATFORM_USETHREADS
13684 isc_thread_yield();
13689 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
13690 result = zone_replacedb(zone, db, dump);
13691 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
13692 if (secure != NULL)
13693 UNLOCK_ZONE(secure);
13698 static isc_result_t
13699 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
13700 dns_dbversion_t *ver;
13701 isc_result_t result;
13702 unsigned int soacount = 0;
13703 unsigned int nscount = 0;
13706 * 'zone' and 'zonedb' locked by caller.
13708 REQUIRE(DNS_ZONE_VALID(zone));
13709 REQUIRE(LOCKED_ZONE(zone));
13710 if (inline_raw(zone))
13711 REQUIRE(LOCKED_ZONE(zone->secure));
13713 result = zone_get_from_db(zone, db, &nscount, &soacount,
13714 NULL, NULL, NULL, NULL, NULL, NULL);
13715 if (result == ISC_R_SUCCESS) {
13716 if (soacount != 1) {
13717 dns_zone_log(zone, ISC_LOG_ERROR,
13718 "has %d SOA records", soacount);
13719 result = DNS_R_BADZONE;
13721 if (nscount == 0 && zone->type != dns_zone_key) {
13722 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
13723 result = DNS_R_BADZONE;
13725 if (result != ISC_R_SUCCESS)
13728 dns_zone_log(zone, ISC_LOG_ERROR,
13729 "retrieving SOA and NS records failed: %s",
13730 dns_result_totext(result));
13734 result = check_nsec3param(zone, db);
13735 if (result != ISC_R_SUCCESS)
13739 dns_db_currentversion(db, &ver);
13742 * The initial version of a slave zone is always dumped;
13743 * subsequent versions may be journaled instead if this
13744 * is enabled in the configuration.
13746 if (zone->db != NULL && zone->journal != NULL &&
13747 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
13748 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
13750 isc_uint32_t serial, oldserial;
13752 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
13754 result = dns_db_getsoaserial(db, ver, &serial);
13755 if (result != ISC_R_SUCCESS) {
13756 dns_zone_log(zone, ISC_LOG_ERROR,
13757 "ixfr-from-differences: unable to get "
13763 * This is checked in zone_postload() for master zones.
13765 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
13766 &oldserial, NULL, NULL, NULL, NULL,
13768 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13769 RUNTIME_CHECK(soacount > 0U);
13770 if ((zone->type == dns_zone_slave ||
13771 (zone->type == dns_zone_redirect &&
13772 zone->masters != NULL))
13773 && !isc_serial_gt(serial, oldserial)) {
13774 isc_uint32_t serialmin, serialmax;
13775 serialmin = (oldserial + 1) & 0xffffffffU;
13776 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
13777 dns_zone_log(zone, ISC_LOG_ERROR,
13778 "ixfr-from-differences: failed: "
13779 "new serial (%u) out of range [%u - %u]",
13780 serial, serialmin, serialmax);
13781 result = ISC_R_RANGE;
13785 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
13787 if (result != ISC_R_SUCCESS)
13790 zone_needdump(zone, DNS_DUMP_DELAY);
13791 else if (zone->journalsize != -1) {
13792 result = dns_journal_compact(zone->mctx, zone->journal,
13793 serial, zone->journalsize);
13795 case ISC_R_SUCCESS:
13796 case ISC_R_NOSPACE:
13797 case ISC_R_NOTFOUND:
13798 dns_zone_log(zone, ISC_LOG_DEBUG(3),
13799 "dns_journal_compact: %s",
13800 dns_result_totext(result));
13803 dns_zone_log(zone, ISC_LOG_ERROR,
13804 "dns_journal_compact failed: %s",
13805 dns_result_totext(result));
13809 if (zone->type == dns_zone_master && inline_raw(zone))
13810 zone_send_secureserial(zone, serial);
13812 if (dump && zone->masterfile != NULL) {
13814 * If DNS_ZONEFLG_FORCEXFER was set we don't want
13815 * to keep the old masterfile.
13817 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
13818 remove(zone->masterfile) < 0 && errno != ENOENT) {
13819 char strbuf[ISC_STRERRORSIZE];
13820 isc__strerror(errno, strbuf, sizeof(strbuf));
13821 isc_log_write(dns_lctx,
13822 DNS_LOGCATEGORY_GENERAL,
13823 DNS_LOGMODULE_ZONE,
13825 "unable to remove masterfile "
13827 zone->masterfile, strbuf);
13829 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
13830 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
13832 zone_needdump(zone, 0);
13834 if (dump && zone->journal != NULL) {
13836 * The in-memory database just changed, and
13837 * because 'dump' is set, it didn't change by
13838 * being loaded from disk. Also, we have not
13839 * journaled diffs for this change.
13840 * Therefore, the on-disk journal is missing
13841 * the deltas for this change. Since it can
13842 * no longer be used to bring the zone
13843 * up-to-date, it is useless and should be
13846 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13847 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13848 "removing journal file");
13849 if (remove(zone->journal) < 0 && errno != ENOENT) {
13850 char strbuf[ISC_STRERRORSIZE];
13851 isc__strerror(errno, strbuf, sizeof(strbuf));
13852 isc_log_write(dns_lctx,
13853 DNS_LOGCATEGORY_GENERAL,
13854 DNS_LOGMODULE_ZONE,
13856 "unable to remove journal "
13858 zone->journal, strbuf);
13862 if (inline_raw(zone))
13863 zone_send_securedb(zone, db);
13866 dns_db_closeversion(db, &ver, ISC_FALSE);
13868 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
13870 if (zone->db != NULL)
13871 zone_detachdb(zone);
13872 zone_attachdb(zone, db);
13873 dns_db_settask(zone->db, zone->task);
13874 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
13875 return (ISC_R_SUCCESS);
13878 dns_db_closeversion(db, &ver, ISC_FALSE);
13882 /* The caller must hold the dblock as a writer. */
13884 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
13885 REQUIRE(zone->db == NULL && db != NULL);
13887 dns_db_attach(db, &zone->db);
13888 if (zone->acache != NULL) {
13889 isc_result_t result;
13890 result = dns_acache_setdb(zone->acache, db);
13891 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
13892 UNEXPECTED_ERROR(__FILE__, __LINE__,
13893 "dns_acache_setdb() failed: %s",
13894 isc_result_totext(result));
13899 /* The caller must hold the dblock as a writer. */
13901 zone_detachdb(dns_zone_t *zone) {
13902 REQUIRE(zone->db != NULL);
13904 if (zone->acache != NULL)
13905 (void)dns_acache_putdb(zone->acache, zone->db);
13906 dns_db_detach(&zone->db);
13910 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
13912 isc_boolean_t again = ISC_FALSE;
13913 unsigned int soacount;
13914 unsigned int nscount;
13915 isc_uint32_t serial, refresh, retry, expire, minimum;
13916 isc_result_t xfrresult = result;
13917 isc_boolean_t free_needed;
13918 dns_zone_t *secure = NULL;
13920 REQUIRE(DNS_ZONE_VALID(zone));
13922 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13923 "zone transfer finished: %s", dns_result_totext(result));
13926 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
13927 * could result in a deadlock due to a LOR so we will spin if we
13928 * can't obtain the both locks.
13932 if (inline_raw(zone)) {
13933 secure = zone->secure;
13934 INSIST(secure != zone);
13935 TRYLOCK_ZONE(result, secure);
13936 if (result != ISC_R_SUCCESS) {
13939 #if ISC_PLATFORM_USETHREADS
13940 isc_thread_yield();
13946 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
13947 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
13948 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
13952 case ISC_R_SUCCESS:
13953 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13955 case DNS_R_UPTODATE:
13956 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13958 * Has the zone expired underneath us?
13960 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13961 if (zone->db == NULL) {
13962 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13967 * Update the zone structure's data from the actual
13972 INSIST(zone->db != NULL);
13973 result = zone_get_from_db(zone, zone->db, &nscount,
13974 &soacount, &serial, &refresh,
13975 &retry, &expire, &minimum, NULL);
13976 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13977 if (result == ISC_R_SUCCESS) {
13979 dns_zone_log(zone, ISC_LOG_ERROR,
13980 "transferred zone "
13981 "has %d SOA record%s", soacount,
13982 (soacount != 0) ? "s" : "");
13983 if (nscount == 0) {
13984 dns_zone_log(zone, ISC_LOG_ERROR,
13985 "transferred zone "
13986 "has no NS records");
13987 if (DNS_ZONE_FLAG(zone,
13988 DNS_ZONEFLG_HAVETIMERS)) {
13989 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
13990 zone->retry = DNS_ZONE_DEFAULTRETRY;
13992 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
13996 zone->refresh = RANGE(refresh, zone->minrefresh,
13998 zone->retry = RANGE(retry, zone->minretry,
14000 zone->expire = RANGE(expire,
14001 zone->refresh + zone->retry,
14003 zone->minimum = minimum;
14004 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
14008 * Set our next update/expire times.
14010 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
14011 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
14012 zone->refreshtime = now;
14013 DNS_ZONE_TIME_ADD(&now, zone->expire,
14014 &zone->expiretime);
14016 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
14017 &zone->refreshtime);
14018 DNS_ZONE_TIME_ADD(&now, zone->expire,
14019 &zone->expiretime);
14021 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
14022 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
14023 if (zone->tsigkey != NULL) {
14024 char namebuf[DNS_NAME_FORMATSIZE];
14025 dns_name_format(&zone->tsigkey->name, namebuf,
14027 snprintf(buf, sizeof(buf), ": TSIG '%s'",
14031 dns_zone_log(zone, ISC_LOG_INFO,
14032 "transferred serial %u%s",
14034 if (inline_raw(zone))
14035 zone_send_secureserial(zone, serial);
14039 * This is not necessary if we just performed a AXFR
14040 * however it is necessary for an IXFR / UPTODATE and
14041 * won't hurt with an AXFR.
14043 if (zone->masterfile != NULL || zone->journal != NULL) {
14044 unsigned int delay = DNS_DUMP_DELAY;
14046 result = ISC_R_FAILURE;
14047 if (zone->journal != NULL)
14048 result = isc_file_settime(zone->journal, &now);
14049 if (result != ISC_R_SUCCESS &&
14050 zone->masterfile != NULL)
14051 result = isc_file_settime(zone->masterfile,
14054 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
14055 result == ISC_R_FILENOTFOUND)
14058 if ((result == ISC_R_SUCCESS ||
14059 result == ISC_R_FILENOTFOUND) &&
14060 zone->masterfile != NULL)
14061 zone_needdump(zone, delay);
14062 else if (result != ISC_R_SUCCESS)
14063 dns_zone_log(zone, ISC_LOG_ERROR,
14064 "transfer: could not set file "
14065 "modification time of '%s': %s",
14067 dns_result_totext(result));
14069 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
14070 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
14073 case DNS_R_BADIXFR:
14074 /* Force retry with AXFR. */
14075 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
14081 * Skip to next failed / untried master.
14085 } while (zone->curmaster < zone->masterscnt &&
14086 zone->mastersok[zone->curmaster]);
14089 if (zone->curmaster >= zone->masterscnt) {
14090 zone->curmaster = 0;
14091 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
14092 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
14093 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
14094 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
14095 while (zone->curmaster < zone->masterscnt &&
14096 zone->mastersok[zone->curmaster])
14100 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
14102 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
14105 inc_stats(zone, dns_zonestatscounter_xfrfail);
14108 zone_settimer(zone, &now);
14111 * If creating the transfer object failed, zone->xfr is NULL.
14112 * Otherwise, we are called as the done callback of a zone
14113 * transfer object that just entered its shutting-down
14114 * state. Since we are no longer responsible for shutting
14115 * it down, we can detach our reference.
14117 if (zone->xfr != NULL)
14118 dns_xfrin_detach(&zone->xfr);
14120 if (zone->tsigkey != NULL)
14121 dns_tsigkey_detach(&zone->tsigkey);
14124 * Handle any deferred journal compaction.
14126 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
14127 result = dns_journal_compact(zone->mctx, zone->journal,
14128 zone->compact_serial,
14129 zone->journalsize);
14131 case ISC_R_SUCCESS:
14132 case ISC_R_NOSPACE:
14133 case ISC_R_NOTFOUND:
14134 dns_zone_log(zone, ISC_LOG_DEBUG(3),
14135 "dns_journal_compact: %s",
14136 dns_result_totext(result));
14139 dns_zone_log(zone, ISC_LOG_ERROR,
14140 "dns_journal_compact failed: %s",
14141 dns_result_totext(result));
14144 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
14147 if (secure != NULL)
14148 UNLOCK_ZONE(secure);
14150 * This transfer finishing freed up a transfer quota slot.
14151 * Let any other zones waiting for quota have it.
14153 if (zone->zmgr != NULL &&
14154 zone->statelist == &zone->zmgr->xfrin_in_progress) {
14156 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
14157 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
14158 zone->statelist = NULL;
14159 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
14160 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
14165 * Retry with a different server if necessary.
14167 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
14168 queue_soa_query(zone);
14170 INSIST(zone->irefs > 0);
14172 free_needed = exit_check(zone);
14179 zone_loaddone(void *arg, isc_result_t result) {
14180 static char me[] = "zone_loaddone";
14181 dns_load_t *load = arg;
14183 isc_result_t tresult;
14184 dns_zone_t *secure = NULL;
14186 REQUIRE(DNS_LOAD_VALID(load));
14191 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
14192 if (tresult != ISC_R_SUCCESS &&
14193 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
14197 * Lock hierarchy: zmgr, zone, raw.
14201 if (inline_secure(zone))
14202 LOCK_ZONE(zone->raw);
14203 else if (inline_raw(zone)) {
14204 secure = zone->secure;
14205 TRYLOCK_ZONE(result, secure);
14206 if (result != ISC_R_SUCCESS) {
14209 #if ISC_PLATFORM_USETHREADS
14210 isc_thread_yield();
14215 (void)zone_postload(zone, load->db, load->loadtime, result);
14216 zonemgr_putio(&zone->readio);
14217 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
14218 zone_idetach(&load->callbacks.zone);
14220 * Leave the zone frozen if the reload fails.
14222 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
14223 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
14224 zone->update_disabled = ISC_FALSE;
14225 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
14226 if (inline_secure(zone))
14227 UNLOCK_ZONE(zone->raw);
14228 else if (secure != NULL)
14229 UNLOCK_ZONE(secure);
14233 dns_db_detach(&load->db);
14234 if (load->zone->lctx != NULL)
14235 dns_loadctx_detach(&load->zone->lctx);
14236 dns_zone_idetach(&load->zone);
14237 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
14241 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
14242 REQUIRE(DNS_ZONE_VALID(zone));
14243 REQUIRE(table != NULL);
14244 REQUIRE(*table == NULL);
14247 if (zone->ssutable != NULL)
14248 dns_ssutable_attach(zone->ssutable, table);
14253 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
14254 REQUIRE(DNS_ZONE_VALID(zone));
14257 if (zone->ssutable != NULL)
14258 dns_ssutable_detach(&zone->ssutable);
14260 dns_ssutable_attach(table, &zone->ssutable);
14265 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
14266 REQUIRE(DNS_ZONE_VALID(zone));
14268 zone->sigvalidityinterval = interval;
14272 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
14273 REQUIRE(DNS_ZONE_VALID(zone));
14275 return (zone->sigvalidityinterval);
14279 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
14282 REQUIRE(DNS_ZONE_VALID(zone));
14285 zone->sigresigninginterval = interval;
14286 set_resigntime(zone);
14287 if (zone->task != NULL) {
14289 zone_settimer(zone, &now);
14295 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
14296 REQUIRE(DNS_ZONE_VALID(zone));
14298 return (zone->sigresigninginterval);
14302 queue_xfrin(dns_zone_t *zone) {
14303 const char me[] = "queue_xfrin";
14304 isc_result_t result;
14305 dns_zonemgr_t *zmgr = zone->zmgr;
14309 INSIST(zone->statelist == NULL);
14311 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14312 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
14316 zone->statelist = &zmgr->waiting_for_xfrin;
14317 result = zmgr_start_xfrin_ifquota(zmgr, zone);
14318 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14320 if (result == ISC_R_QUOTA) {
14321 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
14322 "zone transfer deferred due to quota");
14323 } else if (result != ISC_R_SUCCESS) {
14324 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
14325 "starting zone transfer: %s",
14326 isc_result_totext(result));
14331 * This event callback is called when a zone has received
14332 * any necessary zone transfer quota. This is the time
14333 * to go ahead and start the transfer.
14336 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
14337 isc_result_t result = ISC_R_SUCCESS;
14338 dns_peer_t *peer = NULL;
14339 char master[ISC_SOCKADDR_FORMATSIZE];
14340 char source[ISC_SOCKADDR_FORMATSIZE];
14341 dns_rdatatype_t xfrtype;
14342 dns_zone_t *zone = event->ev_arg;
14343 isc_netaddr_t masterip;
14344 isc_sockaddr_t sourceaddr;
14345 isc_sockaddr_t masteraddr;
14347 const char *soa_before = "";
14348 isc_boolean_t loaded;
14352 INSIST(task == zone->task);
14354 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
14355 result = ISC_R_CANCELED;
14361 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
14362 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
14363 &zone->sourceaddr, &now))
14365 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
14366 dns_zone_log(zone, ISC_LOG_INFO,
14367 "got_transfer_quota: skipping zone transfer as "
14368 "master %s (source %s) is unreachable (cached)",
14370 result = ISC_R_CANCELED;
14374 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
14375 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
14377 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14378 soa_before = "SOA before ";
14380 * Decide whether we should request IXFR or AXFR.
14382 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14383 loaded = ISC_TF(zone->db != NULL);
14384 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14387 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14388 "no database exists yet, requesting AXFR of "
14389 "initial version from %s", master);
14390 xfrtype = dns_rdatatype_axfr;
14391 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
14392 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14393 "forced reload, requesting AXFR of "
14394 "initial version from %s", master);
14395 xfrtype = dns_rdatatype_axfr;
14396 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
14397 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14398 "retrying with AXFR from %s due to "
14399 "previous IXFR failure", master);
14400 xfrtype = dns_rdatatype_axfr;
14402 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
14405 isc_boolean_t use_ixfr = ISC_TRUE;
14407 result = dns_peer_getrequestixfr(peer, &use_ixfr);
14408 if (peer == NULL || result != ISC_R_SUCCESS)
14409 use_ixfr = zone->requestixfr;
14410 if (use_ixfr == ISC_FALSE) {
14411 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14412 "IXFR disabled, requesting %sAXFR from %s",
14413 soa_before, master);
14414 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14415 xfrtype = dns_rdatatype_soa;
14417 xfrtype = dns_rdatatype_axfr;
14419 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14420 "requesting IXFR from %s", master);
14421 xfrtype = dns_rdatatype_ixfr;
14426 * Determine if we should attempt to sign the request with TSIG.
14428 result = ISC_R_NOTFOUND;
14430 * First, look for a tsig key in the master statement, then
14431 * try for a server key.
14433 if ((zone->masterkeynames != NULL) &&
14434 (zone->masterkeynames[zone->curmaster] != NULL)) {
14435 dns_view_t *view = dns_zone_getview(zone);
14436 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
14437 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
14439 if (zone->tsigkey == NULL)
14440 result = dns_view_getpeertsig(zone->view, &masterip,
14443 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
14444 dns_zone_log(zone, ISC_LOG_ERROR,
14445 "could not get TSIG key for zone transfer: %s",
14446 isc_result_totext(result));
14450 masteraddr = zone->masteraddr;
14451 sourceaddr = zone->sourceaddr;
14453 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
14454 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
14455 zone->tsigkey, zone->mctx,
14456 zone->zmgr->timermgr, zone->zmgr->socketmgr,
14457 zone->task, zone_xfrdone, &zone->xfr);
14458 if (result == ISC_R_SUCCESS) {
14460 if (xfrtype == dns_rdatatype_axfr) {
14461 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
14462 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
14464 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
14465 } else if (xfrtype == dns_rdatatype_ixfr) {
14466 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
14467 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
14469 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
14475 * Any failure in this function is handled like a failed
14476 * zone transfer. This ensures that we get removed from
14477 * zmgr->xfrin_in_progress.
14479 if (result != ISC_R_SUCCESS)
14480 zone_xfrdone(zone, result);
14482 isc_event_free(&event);
14486 * Update forwarding support.
14490 forward_destroy(dns_forward_t *forward) {
14492 forward->magic = 0;
14493 if (forward->request != NULL)
14494 dns_request_destroy(&forward->request);
14495 if (forward->msgbuf != NULL)
14496 isc_buffer_free(&forward->msgbuf);
14497 if (forward->zone != NULL) {
14498 LOCK(&forward->zone->lock);
14499 if (ISC_LINK_LINKED(forward, link))
14500 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
14501 UNLOCK(&forward->zone->lock);
14502 dns_zone_idetach(&forward->zone);
14504 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
14507 static isc_result_t
14508 sendtomaster(dns_forward_t *forward) {
14509 isc_result_t result;
14510 isc_sockaddr_t src;
14512 LOCK_ZONE(forward->zone);
14514 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
14515 UNLOCK_ZONE(forward->zone);
14516 return (ISC_R_CANCELED);
14519 if (forward->which >= forward->zone->masterscnt) {
14520 UNLOCK_ZONE(forward->zone);
14521 return (ISC_R_NOMORE);
14524 forward->addr = forward->zone->masters[forward->which];
14526 * Always use TCP regardless of whether the original update
14528 * XXX The timeout may but a bit small if we are far down a
14529 * transfer graph and the master has to try several masters.
14531 switch (isc_sockaddr_pf(&forward->addr)) {
14533 src = forward->zone->xfrsource4;
14536 src = forward->zone->xfrsource6;
14539 result = ISC_R_NOTIMPLEMENTED;
14542 result = dns_request_createraw(forward->zone->view->requestmgr,
14544 &src, &forward->addr,
14545 forward->options, 15 /* XXX */,
14546 forward->zone->task,
14547 forward_callback, forward,
14548 &forward->request);
14549 if (result == ISC_R_SUCCESS) {
14550 if (!ISC_LINK_LINKED(forward, link))
14551 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
14555 UNLOCK_ZONE(forward->zone);
14560 forward_callback(isc_task_t *task, isc_event_t *event) {
14561 const char me[] = "forward_callback";
14562 dns_requestevent_t *revent = (dns_requestevent_t *)event;
14563 dns_message_t *msg = NULL;
14564 char master[ISC_SOCKADDR_FORMATSIZE];
14565 isc_result_t result;
14566 dns_forward_t *forward;
14571 forward = revent->ev_arg;
14572 INSIST(DNS_FORWARD_VALID(forward));
14573 zone = forward->zone;
14574 INSIST(DNS_ZONE_VALID(zone));
14578 isc_sockaddr_format(&forward->addr, master, sizeof(master));
14580 if (revent->result != ISC_R_SUCCESS) {
14581 dns_zone_log(zone, ISC_LOG_INFO,
14582 "could not forward dynamic update to %s: %s",
14583 master, dns_result_totext(revent->result));
14587 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
14588 if (result != ISC_R_SUCCESS)
14591 result = dns_request_getresponse(revent->request, msg,
14592 DNS_MESSAGEPARSE_PRESERVEORDER |
14593 DNS_MESSAGEPARSE_CLONEBUFFER);
14594 if (result != ISC_R_SUCCESS)
14597 switch (msg->rcode) {
14599 * Pass these rcodes back to client.
14601 case dns_rcode_noerror:
14602 case dns_rcode_yxdomain:
14603 case dns_rcode_yxrrset:
14604 case dns_rcode_nxrrset:
14605 case dns_rcode_refused:
14606 case dns_rcode_nxdomain: {
14610 isc_buffer_init(&rb, rcode, sizeof(rcode));
14611 (void)dns_rcode_totext(msg->rcode, &rb);
14612 dns_zone_log(zone, ISC_LOG_INFO,
14613 "forwarded dynamic update: "
14614 "master %s returned: %.*s",
14615 master, (int)rb.used, rcode);
14619 /* These should not occur if the masters/zone are valid. */
14620 case dns_rcode_notzone:
14621 case dns_rcode_notauth: {
14625 isc_buffer_init(&rb, rcode, sizeof(rcode));
14626 (void)dns_rcode_totext(msg->rcode, &rb);
14627 dns_zone_log(zone, ISC_LOG_WARNING,
14628 "forwarding dynamic update: "
14629 "unexpected response: master %s returned: %.*s",
14630 master, (int)rb.used, rcode);
14634 /* Try another server for these rcodes. */
14635 case dns_rcode_formerr:
14636 case dns_rcode_servfail:
14637 case dns_rcode_notimp:
14638 case dns_rcode_badvers:
14643 /* call callback */
14644 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
14646 dns_request_destroy(&forward->request);
14647 forward_destroy(forward);
14648 isc_event_free(&event);
14653 dns_message_destroy(&msg);
14654 isc_event_free(&event);
14656 dns_request_destroy(&forward->request);
14657 result = sendtomaster(forward);
14658 if (result != ISC_R_SUCCESS) {
14659 /* call callback */
14660 dns_zone_log(zone, ISC_LOG_DEBUG(3),
14661 "exhausted dynamic update forwarder list");
14662 (forward->callback)(forward->callback_arg, result, NULL);
14663 forward_destroy(forward);
14668 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
14669 dns_updatecallback_t callback, void *callback_arg)
14671 dns_forward_t *forward;
14672 isc_result_t result;
14675 REQUIRE(DNS_ZONE_VALID(zone));
14676 REQUIRE(msg != NULL);
14677 REQUIRE(callback != NULL);
14679 forward = isc_mem_get(zone->mctx, sizeof(*forward));
14680 if (forward == NULL)
14681 return (ISC_R_NOMEMORY);
14683 forward->request = NULL;
14684 forward->zone = NULL;
14685 forward->msgbuf = NULL;
14686 forward->which = 0;
14688 forward->callback = callback;
14689 forward->callback_arg = callback_arg;
14690 ISC_LINK_INIT(forward, link);
14691 forward->magic = FORWARD_MAGIC;
14692 forward->options = DNS_REQUESTOPT_TCP;
14694 * If we have a SIG(0) signed message we need to preserve the
14695 * query id as that is included in the SIG(0) computation.
14697 if (msg->sig0 != NULL)
14698 forward->options |= DNS_REQUESTOPT_FIXEDID;
14700 mr = dns_message_getrawmessage(msg);
14702 result = ISC_R_UNEXPECTEDEND;
14706 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
14707 if (result != ISC_R_SUCCESS)
14709 result = isc_buffer_copyregion(forward->msgbuf, mr);
14710 if (result != ISC_R_SUCCESS)
14713 isc_mem_attach(zone->mctx, &forward->mctx);
14714 dns_zone_iattach(zone, &forward->zone);
14715 result = sendtomaster(forward);
14718 if (result != ISC_R_SUCCESS) {
14719 forward_destroy(forward);
14725 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
14726 REQUIRE(DNS_ZONE_VALID(zone));
14727 REQUIRE(next != NULL && *next == NULL);
14729 *next = ISC_LIST_NEXT(zone, link);
14731 return (ISC_R_NOMORE);
14733 return (ISC_R_SUCCESS);
14737 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
14738 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14739 REQUIRE(first != NULL && *first == NULL);
14741 *first = ISC_LIST_HEAD(zmgr->zones);
14742 if (*first == NULL)
14743 return (ISC_R_NOMORE);
14745 return (ISC_R_SUCCESS);
14753 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
14754 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
14755 dns_zonemgr_t **zmgrp)
14757 dns_zonemgr_t *zmgr;
14758 isc_result_t result;
14760 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
14762 return (ISC_R_NOMEMORY);
14765 isc_mem_attach(mctx, &zmgr->mctx);
14766 zmgr->taskmgr = taskmgr;
14767 zmgr->timermgr = timermgr;
14768 zmgr->socketmgr = socketmgr;
14769 zmgr->zonetasks = NULL;
14770 zmgr->loadtasks = NULL;
14771 zmgr->mctxpool = NULL;
14773 zmgr->notifyrl = NULL;
14774 zmgr->refreshrl = NULL;
14775 zmgr->startupnotifyrl = NULL;
14776 zmgr->startuprefreshrl = NULL;
14777 ISC_LIST_INIT(zmgr->zones);
14778 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
14779 ISC_LIST_INIT(zmgr->xfrin_in_progress);
14780 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
14781 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
14782 if (result != ISC_R_SUCCESS)
14785 zmgr->transfersin = 10;
14786 zmgr->transfersperns = 2;
14788 /* Unreachable lock. */
14789 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
14790 if (result != ISC_R_SUCCESS)
14793 /* Create a single task for queueing of SOA queries. */
14794 result = isc_task_create(taskmgr, 1, &zmgr->task);
14795 if (result != ISC_R_SUCCESS)
14798 isc_task_setname(zmgr->task, "zmgr", zmgr);
14799 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14801 if (result != ISC_R_SUCCESS)
14804 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14806 if (result != ISC_R_SUCCESS)
14807 goto free_notifyrl;
14809 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14810 &zmgr->startupnotifyrl);
14811 if (result != ISC_R_SUCCESS)
14812 goto free_refreshrl;
14814 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14815 &zmgr->startuprefreshrl);
14816 if (result != ISC_R_SUCCESS)
14817 goto free_startupnotifyrl;
14819 /* default to 20 refresh queries / notifies per second. */
14820 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
14821 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
14822 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
14823 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
14826 zmgr->ioactive = 0;
14827 ISC_LIST_INIT(zmgr->high);
14828 ISC_LIST_INIT(zmgr->low);
14830 result = isc_mutex_init(&zmgr->iolock);
14831 if (result != ISC_R_SUCCESS)
14832 goto free_startuprefreshrl;
14834 zmgr->magic = ZONEMGR_MAGIC;
14837 return (ISC_R_SUCCESS);
14841 DESTROYLOCK(&zmgr->iolock);
14843 free_startuprefreshrl:
14844 isc_ratelimiter_detach(&zmgr->startuprefreshrl);
14845 free_startupnotifyrl:
14846 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
14848 isc_ratelimiter_detach(&zmgr->refreshrl);
14850 isc_ratelimiter_detach(&zmgr->notifyrl);
14852 isc_task_detach(&zmgr->task);
14854 isc_rwlock_destroy(&zmgr->urlock);
14856 isc_rwlock_destroy(&zmgr->rwlock);
14858 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
14859 isc_mem_detach(&mctx);
14864 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
14865 isc_result_t result;
14866 isc_mem_t *mctx = NULL;
14867 dns_zone_t *zone = NULL;
14870 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14871 REQUIRE(zonep != NULL && *zonep == NULL);
14873 if (zmgr->mctxpool == NULL)
14874 return (ISC_R_FAILURE);
14876 item = isc_pool_get(zmgr->mctxpool);
14878 return (ISC_R_FAILURE);
14880 isc_mem_attach((isc_mem_t *) item, &mctx);
14881 result = dns_zone_create(&zone, mctx);
14882 isc_mem_detach(&mctx);
14884 if (result == ISC_R_SUCCESS)
14891 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14892 isc_result_t result;
14894 REQUIRE(DNS_ZONE_VALID(zone));
14895 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14897 if (zmgr->zonetasks == NULL)
14898 return (ISC_R_FAILURE);
14900 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14902 REQUIRE(zone->task == NULL);
14903 REQUIRE(zone->timer == NULL);
14904 REQUIRE(zone->zmgr == NULL);
14906 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
14907 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
14910 * Set the task name. The tag will arbitrarily point to one
14911 * of the zones sharing the task (in practice, the one
14912 * to be managed last).
14914 isc_task_setname(zone->task, "zone", zone);
14915 isc_task_setname(zone->loadtask, "loadzone", zone);
14917 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
14919 zone->task, zone_timer, zone,
14922 if (result != ISC_R_SUCCESS)
14923 goto cleanup_tasks;
14926 * The timer "holds" a iref.
14929 INSIST(zone->irefs != 0);
14931 ISC_LIST_APPEND(zmgr->zones, zone, link);
14938 isc_task_detach(&zone->loadtask);
14939 isc_task_detach(&zone->task);
14943 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14948 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14949 isc_boolean_t free_now = ISC_FALSE;
14951 REQUIRE(DNS_ZONE_VALID(zone));
14952 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14953 REQUIRE(zone->zmgr == zmgr);
14955 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14958 ISC_LIST_UNLINK(zmgr->zones, zone, link);
14961 if (zmgr->refs == 0)
14962 free_now = ISC_TRUE;
14965 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14968 zonemgr_free(zmgr);
14969 ENSURE(zone->zmgr == NULL);
14973 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
14974 REQUIRE(DNS_ZONEMGR_VALID(source));
14975 REQUIRE(target != NULL && *target == NULL);
14977 RWLOCK(&source->rwlock, isc_rwlocktype_write);
14978 REQUIRE(source->refs > 0);
14980 INSIST(source->refs > 0);
14981 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
14986 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
14987 dns_zonemgr_t *zmgr;
14988 isc_boolean_t free_now = ISC_FALSE;
14990 REQUIRE(zmgrp != NULL);
14992 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14994 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14996 if (zmgr->refs == 0)
14997 free_now = ISC_TRUE;
14998 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15001 zonemgr_free(zmgr);
15006 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
15009 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15011 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15012 for (p = ISC_LIST_HEAD(zmgr->zones);
15014 p = ISC_LIST_NEXT(p, link))
15016 dns_zone_maintenance(p);
15018 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15021 * Recent configuration changes may have increased the
15022 * amount of available transfers quota. Make sure any
15023 * transfers currently blocked on quota get started if
15026 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15027 zmgr_resume_xfrs(zmgr, ISC_TRUE);
15028 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15029 return (ISC_R_SUCCESS);
15033 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
15035 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15037 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15038 zmgr_resume_xfrs(zmgr, ISC_TRUE);
15039 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15043 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
15046 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15048 isc_ratelimiter_shutdown(zmgr->notifyrl);
15049 isc_ratelimiter_shutdown(zmgr->refreshrl);
15050 isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
15051 isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
15053 if (zmgr->task != NULL)
15054 isc_task_destroy(&zmgr->task);
15055 if (zmgr->zonetasks != NULL)
15056 isc_taskpool_destroy(&zmgr->zonetasks);
15057 if (zmgr->loadtasks != NULL)
15058 isc_taskpool_destroy(&zmgr->loadtasks);
15059 if (zmgr->mctxpool != NULL)
15060 isc_pool_destroy(&zmgr->mctxpool);
15062 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15063 for (zone = ISC_LIST_HEAD(zmgr->zones);
15065 zone = ISC_LIST_NEXT(zone, link))
15068 forward_cancel(zone);
15071 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15074 static isc_result_t
15075 mctxinit(void **target, void *arg) {
15076 isc_result_t result;
15077 isc_mem_t *mctx = NULL;
15081 REQUIRE(target != NULL && *target == NULL);
15083 result = isc_mem_create(0, 0, &mctx);
15084 if (result != ISC_R_SUCCESS)
15086 isc_mem_setname(mctx, "zonemgr-pool", NULL);
15089 return (ISC_R_SUCCESS);
15093 mctxfree(void **target) {
15094 isc_mem_t *mctx = *(isc_mem_t **) target;
15095 isc_mem_detach(&mctx);
15099 #define ZONES_PER_TASK 100
15100 #define ZONES_PER_MCTX 1000
15103 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
15104 isc_result_t result;
15105 int ntasks = num_zones / ZONES_PER_TASK;
15106 int nmctx = num_zones / ZONES_PER_MCTX;
15107 isc_taskpool_t *pool = NULL;
15108 isc_pool_t *mctxpool = NULL;
15110 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15113 * For anything fewer than 1000 zones we use 10 tasks in
15114 * the task pools. More than that, and we'll scale at one
15115 * task per 100 zones. Similarly, for anything smaller than
15116 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
15123 /* Create or resize the zone task pools. */
15124 if (zmgr->zonetasks == NULL)
15125 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
15128 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
15130 if (result == ISC_R_SUCCESS)
15131 zmgr->zonetasks = pool;
15134 if (zmgr->loadtasks == NULL)
15135 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
15138 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
15140 if (result == ISC_R_SUCCESS)
15141 zmgr->loadtasks = pool;
15145 * We always set all tasks in the zone-load task pool to
15146 * privileged. This prevents other tasks in the system from
15147 * running while the server task manager is in privileged
15150 * NOTE: If we start using task privileges for any other
15151 * part of the system than zone tasks, then this will need to be
15152 * revisted. In that case we'd want to turn on privileges for
15153 * zone tasks only when we were loading, and turn them off the
15154 * rest of the time. For now, however, it's okay to just
15155 * set it and forget it.
15157 isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE);
15160 /* Create or resize the zone memory context pool. */
15161 if (zmgr->mctxpool == NULL)
15162 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
15163 mctxinit, NULL, &mctxpool);
15165 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
15167 if (result == ISC_R_SUCCESS)
15168 zmgr->mctxpool = mctxpool;
15174 zonemgr_free(dns_zonemgr_t *zmgr) {
15177 INSIST(zmgr->refs == 0);
15178 INSIST(ISC_LIST_EMPTY(zmgr->zones));
15182 DESTROYLOCK(&zmgr->iolock);
15183 isc_ratelimiter_detach(&zmgr->notifyrl);
15184 isc_ratelimiter_detach(&zmgr->refreshrl);
15185 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
15186 isc_ratelimiter_detach(&zmgr->startuprefreshrl);
15188 isc_rwlock_destroy(&zmgr->urlock);
15189 isc_rwlock_destroy(&zmgr->rwlock);
15191 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
15192 isc_mem_detach(&mctx);
15196 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
15197 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15199 zmgr->transfersin = value;
15203 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
15204 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15206 return (zmgr->transfersin);
15210 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
15211 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15213 zmgr->transfersperns = value;
15217 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
15218 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15220 return (zmgr->transfersperns);
15224 * Try to start a new incoming zone transfer to fill a quota
15225 * slot that was just vacated.
15228 * The zone manager is locked by the caller.
15231 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
15235 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
15239 isc_result_t result;
15240 next = ISC_LIST_NEXT(zone, statelink);
15241 result = zmgr_start_xfrin_ifquota(zmgr, zone);
15242 if (result == ISC_R_SUCCESS) {
15246 * We successfully filled the slot. We're done.
15249 } else if (result == ISC_R_QUOTA) {
15251 * Not enough quota. This is probably the per-server
15252 * quota, because we usually get called when a unit of
15253 * global quota has just been freed. Try the next
15254 * zone, it may succeed if it uses another master.
15258 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15259 "starting zone transfer: %s",
15260 isc_result_totext(result));
15267 * Try to start an incoming zone transfer for 'zone', quota permitting.
15270 * The zone manager is locked by the caller.
15273 * ISC_R_SUCCESS There was enough quota and we attempted to
15274 * start a transfer. zone_xfrdone() has been or will
15276 * ISC_R_QUOTA Not enough quota.
15279 static isc_result_t
15280 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15281 dns_peer_t *peer = NULL;
15282 isc_netaddr_t masterip;
15283 isc_uint32_t nxfrsin, nxfrsperns;
15285 isc_uint32_t maxtransfersin, maxtransfersperns;
15289 * If we are exiting just pretend we got quota so the zone will
15290 * be cleaned up in the zone's task context.
15293 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
15299 * Find any configured information about the server we'd
15300 * like to transfer this zone from.
15302 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
15303 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
15307 * Determine the total maximum number of simultaneous
15308 * transfers allowed, and the maximum for this specific
15311 maxtransfersin = zmgr->transfersin;
15312 maxtransfersperns = zmgr->transfersperns;
15314 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
15317 * Count the total number of transfers that are in progress,
15318 * and the number of transfers in progress from this master.
15319 * We linearly scan a list of all transfers; if this turns
15320 * out to be too slow, we could hash on the master address.
15322 nxfrsin = nxfrsperns = 0;
15323 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15325 x = ISC_LIST_NEXT(x, statelink))
15330 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
15334 if (isc_netaddr_equal(&xip, &masterip))
15338 /* Enforce quota. */
15339 if (nxfrsin >= maxtransfersin)
15340 return (ISC_R_QUOTA);
15342 if (nxfrsperns >= maxtransfersperns)
15343 return (ISC_R_QUOTA);
15347 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
15348 * list and send it an event to let it start the actual transfer in the
15349 * context of its own task.
15351 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
15352 got_transfer_quota, zone, sizeof(isc_event_t));
15354 return (ISC_R_NOMEMORY);
15357 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
15358 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
15359 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
15360 zone->statelist = &zmgr->xfrin_in_progress;
15361 isc_task_send(zone->task, &e);
15362 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
15365 return (ISC_R_SUCCESS);
15369 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
15371 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15372 REQUIRE(iolimit > 0);
15374 zmgr->iolimit = iolimit;
15378 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
15380 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15382 return (zmgr->iolimit);
15386 * Get permission to request a file handle from the OS.
15387 * An event will be sent to action when one is available.
15388 * There are two queues available (high and low), the high
15389 * queue will be serviced before the low one.
15391 * zonemgr_putio() must be called after the event is delivered to
15395 static isc_result_t
15396 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
15397 isc_task_t *task, isc_taskaction_t action, void *arg,
15401 isc_boolean_t queue;
15403 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15404 REQUIRE(iop != NULL && *iop == NULL);
15406 io = isc_mem_get(zmgr->mctx, sizeof(*io));
15408 return (ISC_R_NOMEMORY);
15410 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
15411 action, arg, sizeof(*io->event));
15412 if (io->event == NULL) {
15413 isc_mem_put(zmgr->mctx, io, sizeof(*io));
15414 return (ISC_R_NOMEMORY);
15420 isc_task_attach(task, &io->task);
15421 ISC_LINK_INIT(io, link);
15422 io->magic = IO_MAGIC;
15424 LOCK(&zmgr->iolock);
15426 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
15429 ISC_LIST_APPEND(zmgr->high, io, link);
15431 ISC_LIST_APPEND(zmgr->low, io, link);
15433 UNLOCK(&zmgr->iolock);
15437 isc_task_send(io->task, &io->event);
15438 return (ISC_R_SUCCESS);
15442 zonemgr_putio(dns_io_t **iop) {
15445 dns_zonemgr_t *zmgr;
15447 REQUIRE(iop != NULL);
15449 REQUIRE(DNS_IO_VALID(io));
15453 INSIST(!ISC_LINK_LINKED(io, link));
15454 INSIST(io->event == NULL);
15457 isc_task_detach(&io->task);
15459 isc_mem_put(zmgr->mctx, io, sizeof(*io));
15461 LOCK(&zmgr->iolock);
15462 INSIST(zmgr->ioactive > 0);
15464 next = HEAD(zmgr->high);
15466 next = HEAD(zmgr->low);
15467 if (next != NULL) {
15469 ISC_LIST_UNLINK(zmgr->high, next, link);
15471 ISC_LIST_UNLINK(zmgr->low, next, link);
15472 INSIST(next->event != NULL);
15474 UNLOCK(&zmgr->iolock);
15476 isc_task_send(next->task, &next->event);
15480 zonemgr_cancelio(dns_io_t *io) {
15481 isc_boolean_t send_event = ISC_FALSE;
15483 REQUIRE(DNS_IO_VALID(io));
15486 * If we are queued to be run then dequeue.
15488 LOCK(&io->zmgr->iolock);
15489 if (ISC_LINK_LINKED(io, link)) {
15491 ISC_LIST_UNLINK(io->zmgr->high, io, link);
15493 ISC_LIST_UNLINK(io->zmgr->low, io, link);
15495 send_event = ISC_TRUE;
15496 INSIST(io->event != NULL);
15498 UNLOCK(&io->zmgr->iolock);
15500 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
15501 isc_task_send(io->task, &io->event);
15506 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
15509 isc_result_t result;
15511 buflen = strlen(path) + strlen(templat) + 2;
15513 buf = isc_mem_get(zone->mctx, buflen);
15517 result = isc_file_template(path, templat, buf, buflen);
15518 if (result != ISC_R_SUCCESS)
15521 result = isc_file_renameunique(path, buf);
15522 if (result != ISC_R_SUCCESS)
15525 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
15526 "renaming file to '%s' for failure analysis and "
15527 "retransferring.", path, buf);
15530 isc_mem_put(zone->mctx, buf, buflen);
15534 /* Hook for ondestroy notification from a database. */
15537 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
15538 dns_db_t *db = event->sender;
15541 isc_event_free(&event);
15543 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15544 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
15545 "database (%p) destroyed", (void*) db);
15550 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
15551 isc_interval_t interval;
15552 isc_uint32_t s, ns;
15553 isc_uint32_t pertic;
15554 isc_result_t result;
15563 } else if (value <= 10) {
15565 ns = 1000000000 / value;
15569 ns = (1000000000 / value) * 10;
15573 isc_interval_set(&interval, s, ns);
15575 result = isc_ratelimiter_setinterval(rl, &interval);
15576 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15577 isc_ratelimiter_setpertic(rl, pertic);
15583 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
15585 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15587 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
15589 /* Seperately controlled in BIND 9.11.x */
15590 setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
15591 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
15593 /* XXXMPA seperate out once we have the code to support this. */
15594 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
15598 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
15599 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15601 return (zmgr->serialqueryrate);
15605 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15606 isc_sockaddr_t *local, isc_time_t *now)
15609 isc_rwlocktype_t locktype;
15610 isc_result_t result;
15611 isc_uint32_t seconds = isc_time_seconds(now);
15612 isc_uint32_t count = 0;
15614 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15616 locktype = isc_rwlocktype_read;
15617 RWLOCK(&zmgr->urlock, locktype);
15618 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15619 if (zmgr->unreachable[i].expire >= seconds &&
15620 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15621 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
15622 result = isc_rwlock_tryupgrade(&zmgr->urlock);
15623 if (result == ISC_R_SUCCESS) {
15624 locktype = isc_rwlocktype_write;
15625 zmgr->unreachable[i].last = seconds;
15626 count = zmgr->unreachable[i].count;
15631 RWUNLOCK(&zmgr->urlock, locktype);
15632 return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U));
15636 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15637 isc_sockaddr_t *local)
15640 isc_rwlocktype_t locktype;
15641 isc_result_t result;
15643 char master[ISC_SOCKADDR_FORMATSIZE];
15644 char source[ISC_SOCKADDR_FORMATSIZE];
15646 isc_sockaddr_format(remote, master, sizeof(master));
15647 isc_sockaddr_format(local, source, sizeof(source));
15649 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15651 locktype = isc_rwlocktype_read;
15652 RWLOCK(&zmgr->urlock, locktype);
15653 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15654 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15655 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
15656 if (zmgr->unreachable[i].expire == 0)
15658 result = isc_rwlock_tryupgrade(&zmgr->urlock);
15659 if (result == ISC_R_SUCCESS) {
15660 locktype = isc_rwlocktype_write;
15661 zmgr->unreachable[i].expire = 0;
15662 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15663 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
15664 "master %s (source %s) deleted "
15665 "from unreachable cache",
15671 RWUNLOCK(&zmgr->urlock, locktype);
15675 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15676 isc_sockaddr_t *local, isc_time_t *now)
15678 isc_uint32_t seconds = isc_time_seconds(now);
15679 isc_uint32_t last = seconds;
15680 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
15682 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15684 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
15685 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15686 /* Existing entry? */
15687 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15688 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
15691 if (zmgr->unreachable[i].expire < seconds)
15693 /* Least recently used slot? */
15694 if (zmgr->unreachable[i].last < last) {
15695 last = zmgr->unreachable[i].last;
15699 if (i < UNREACH_CHACHE_SIZE) {
15701 * Found a existing entry. Update the expire timer and
15702 * last usage timestamps.
15704 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
15705 zmgr->unreachable[i].last = seconds;
15706 if (zmgr->unreachable[i].expire < seconds)
15707 zmgr->unreachable[i].count = 1;
15709 zmgr->unreachable[i].count++;
15710 } else if (slot != UNREACH_CHACHE_SIZE) {
15712 * Found a empty slot. Add a new entry to the cache.
15714 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
15715 zmgr->unreachable[slot].last = seconds;
15716 zmgr->unreachable[slot].remote = *remote;
15717 zmgr->unreachable[slot].local = *local;
15718 zmgr->unreachable[slot].count = 1;
15721 * Replace the least recently used entry in the cache.
15723 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
15724 zmgr->unreachable[oldest].last = seconds;
15725 zmgr->unreachable[oldest].remote = *remote;
15726 zmgr->unreachable[oldest].local = *local;
15727 zmgr->unreachable[oldest].count = 1;
15729 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
15733 dns_zone_forcereload(dns_zone_t *zone) {
15734 REQUIRE(DNS_ZONE_VALID(zone));
15736 if (zone->type == dns_zone_master ||
15737 (zone->type == dns_zone_redirect && zone->masters == NULL))
15741 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
15743 dns_zone_refresh(zone);
15747 dns_zone_isforced(dns_zone_t *zone) {
15748 REQUIRE(DNS_ZONE_VALID(zone));
15750 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
15754 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
15756 * This function is obsoleted.
15760 return (ISC_R_NOTIMPLEMENTED);
15764 dns_zone_getstatscounters(dns_zone_t *zone) {
15766 * This function is obsoleted.
15773 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
15774 REQUIRE(DNS_ZONE_VALID(zone));
15775 REQUIRE(zone->stats == NULL);
15778 zone->stats = NULL;
15779 isc_stats_attach(stats, &zone->stats);
15784 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
15786 REQUIRE(DNS_ZONE_VALID(zone));
15789 if (zone->requeststats_on && stats == NULL)
15790 zone->requeststats_on = ISC_FALSE;
15791 else if (!zone->requeststats_on && stats != NULL) {
15792 if (zone->requeststats == NULL) {
15793 isc_stats_attach(stats, &zone->requeststats);
15794 zone->requeststats_on = ISC_TRUE;
15802 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
15804 REQUIRE(DNS_ZONE_VALID(zone));
15807 if (zone->requeststats_on && stats != NULL) {
15808 if (zone->rcvquerystats == NULL) {
15809 dns_stats_attach(stats, &zone->rcvquerystats);
15810 zone->requeststats_on = ISC_TRUE;
15818 dns_zone_getrequeststats(dns_zone_t *zone) {
15820 * We don't lock zone for efficiency reason. This is not catastrophic
15821 * because requeststats must always be valid when requeststats_on is
15823 * Some counters may be incremented while requeststats_on is becoming
15824 * false, or some cannot be incremented just after the statistics are
15825 * installed, but it shouldn't matter much in practice.
15827 if (zone->requeststats_on)
15828 return (zone->requeststats);
15835 * Return the received query stats bucket
15836 * see note from dns_zone_getrequeststats()
15839 dns_zone_getrcvquerystats(dns_zone_t *zone) {
15840 if (zone->requeststats_on)
15841 return (zone->rcvquerystats);
15848 dns_zone_dialup(dns_zone_t *zone) {
15850 REQUIRE(DNS_ZONE_VALID(zone));
15852 zone_debuglog(zone, "dns_zone_dialup", 3,
15853 "notify = %d, refresh = %d",
15854 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
15855 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
15857 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
15858 dns_zone_notify(zone);
15859 if (zone->type != dns_zone_master && zone->masters != NULL &&
15860 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
15861 dns_zone_refresh(zone);
15865 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
15866 REQUIRE(DNS_ZONE_VALID(zone));
15869 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
15870 DNS_ZONEFLG_DIALREFRESH |
15871 DNS_ZONEFLG_NOREFRESH);
15873 case dns_dialuptype_no:
15875 case dns_dialuptype_yes:
15876 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
15877 DNS_ZONEFLG_DIALREFRESH |
15878 DNS_ZONEFLG_NOREFRESH));
15880 case dns_dialuptype_notify:
15881 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
15883 case dns_dialuptype_notifypassive:
15884 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
15885 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15887 case dns_dialuptype_refresh:
15888 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
15889 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15891 case dns_dialuptype_passive:
15892 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15901 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
15902 isc_result_t result = ISC_R_SUCCESS;
15904 REQUIRE(DNS_ZONE_VALID(zone));
15907 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
15914 dns_zone_getkeydirectory(dns_zone_t *zone) {
15915 REQUIRE(DNS_ZONE_VALID(zone));
15917 return (zone->keydirectory);
15921 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
15923 unsigned int count = 0;
15925 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15927 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15929 case DNS_ZONESTATE_XFERRUNNING:
15930 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15932 zone = ISC_LIST_NEXT(zone, statelink))
15935 case DNS_ZONESTATE_XFERDEFERRED:
15936 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
15938 zone = ISC_LIST_NEXT(zone, statelink))
15941 case DNS_ZONESTATE_SOAQUERY:
15942 for (zone = ISC_LIST_HEAD(zmgr->zones);
15944 zone = ISC_LIST_NEXT(zone, link))
15945 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
15948 case DNS_ZONESTATE_ANY:
15949 for (zone = ISC_LIST_HEAD(zmgr->zones);
15951 zone = ISC_LIST_NEXT(zone, link)) {
15952 dns_view_t *view = zone->view;
15953 if (view != NULL && strcmp(view->name, "_bind") == 0)
15962 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15968 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
15969 isc_boolean_t ok = ISC_TRUE;
15970 isc_boolean_t fail = ISC_FALSE;
15971 char namebuf[DNS_NAME_FORMATSIZE];
15972 char namebuf2[DNS_NAME_FORMATSIZE];
15973 char typebuf[DNS_RDATATYPE_FORMATSIZE];
15974 int level = ISC_LOG_WARNING;
15977 REQUIRE(DNS_ZONE_VALID(zone));
15979 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
15980 rdata->type != dns_rdatatype_nsec3)
15981 return (ISC_R_SUCCESS);
15983 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
15984 rdata->type == dns_rdatatype_nsec3) {
15985 level = ISC_LOG_ERROR;
15989 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
15991 dns_name_format(name, namebuf, sizeof(namebuf));
15992 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
15993 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
15994 dns_result_totext(DNS_R_BADOWNERNAME));
15996 return (DNS_R_BADOWNERNAME);
15999 dns_name_init(&bad, NULL);
16000 ok = dns_rdata_checknames(rdata, name, &bad);
16002 dns_name_format(name, namebuf, sizeof(namebuf));
16003 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
16004 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
16005 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
16006 namebuf2, dns_result_totext(DNS_R_BADNAME));
16008 return (DNS_R_BADNAME);
16011 return (ISC_R_SUCCESS);
16015 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
16016 REQUIRE(DNS_ZONE_VALID(zone));
16017 zone->checkmx = checkmx;
16021 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
16022 REQUIRE(DNS_ZONE_VALID(zone));
16023 zone->checksrv = checksrv;
16027 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
16028 REQUIRE(DNS_ZONE_VALID(zone));
16029 zone->checkns = checkns;
16033 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
16034 REQUIRE(DNS_ZONE_VALID(zone));
16037 zone->isself = isself;
16038 zone->isselfarg = arg;
16043 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
16044 REQUIRE(DNS_ZONE_VALID(zone));
16047 zone->notifydelay = delay;
16052 dns_zone_getnotifydelay(dns_zone_t *zone) {
16053 REQUIRE(DNS_ZONE_VALID(zone));
16055 return (zone->notifydelay);
16059 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
16060 isc_uint16_t keyid, isc_boolean_t delete)
16062 isc_result_t result;
16063 REQUIRE(DNS_ZONE_VALID(zone));
16065 dns_zone_log(zone, ISC_LOG_NOTICE,
16066 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
16069 result = zone_signwithkey(zone, algorithm, keyid, delete);
16075 static const char *hex = "0123456789ABCDEF";
16078 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
16079 isc_result_t result;
16080 char salt[255*2+1];
16083 REQUIRE(DNS_ZONE_VALID(zone));
16085 if (nsec3param->salt_length != 0) {
16086 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
16087 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
16088 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
16089 salt[j++] = hex[nsec3param->salt[i] & 0xf];
16094 dns_zone_log(zone, ISC_LOG_NOTICE,
16095 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
16096 nsec3param->hash, nsec3param->iterations,
16099 result = zone_addnsec3chain(zone, nsec3param);
16106 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
16107 REQUIRE(DNS_ZONE_VALID(zone));
16111 zone->nodes = nodes;
16115 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
16116 REQUIRE(DNS_ZONE_VALID(zone));
16119 * We treat signatures as a signed value so explicitly
16120 * limit its range here.
16122 if (signatures > ISC_INT32_MAX)
16123 signatures = ISC_INT32_MAX;
16124 else if (signatures == 0)
16126 zone->signatures = signatures;
16130 dns_zone_getsignatures(dns_zone_t *zone) {
16131 REQUIRE(DNS_ZONE_VALID(zone));
16132 return (zone->signatures);
16136 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
16137 REQUIRE(DNS_ZONE_VALID(zone));
16138 zone->privatetype = type;
16142 dns_zone_getprivatetype(dns_zone_t *zone) {
16143 REQUIRE(DNS_ZONE_VALID(zone));
16144 return (zone->privatetype);
16147 static isc_result_t
16148 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
16149 isc_boolean_t delete)
16151 dns_signing_t *signing;
16152 dns_signing_t *current;
16153 isc_result_t result = ISC_R_SUCCESS;
16155 dns_db_t *db = NULL;
16157 signing = isc_mem_get(zone->mctx, sizeof *signing);
16158 if (signing == NULL)
16159 return (ISC_R_NOMEMORY);
16161 signing->magic = 0;
16162 signing->db = NULL;
16163 signing->dbiterator = NULL;
16164 signing->algorithm = algorithm;
16165 signing->keyid = keyid;
16166 signing->delete = delete;
16167 signing->done = ISC_FALSE;
16171 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
16172 if (zone->db != NULL)
16173 dns_db_attach(zone->db, &db);
16174 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
16177 result = ISC_R_NOTFOUND;
16181 dns_db_attach(db, &signing->db);
16183 for (current = ISC_LIST_HEAD(zone->signing);
16185 current = ISC_LIST_NEXT(current, link)) {
16186 if (current->db == signing->db &&
16187 current->algorithm == signing->algorithm &&
16188 current->keyid == signing->keyid) {
16189 if (current->delete != signing->delete)
16190 current->done = ISC_TRUE;
16196 result = dns_db_createiterator(signing->db, 0,
16197 &signing->dbiterator);
16199 if (result == ISC_R_SUCCESS)
16200 result = dns_dbiterator_first(signing->dbiterator);
16201 if (result == ISC_R_SUCCESS) {
16202 dns_dbiterator_pause(signing->dbiterator);
16203 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
16205 if (isc_time_isepoch(&zone->signingtime)) {
16206 zone->signingtime = now;
16207 if (zone->task != NULL)
16208 zone_settimer(zone, &now);
16213 if (signing != NULL) {
16214 if (signing->db != NULL)
16215 dns_db_detach(&signing->db);
16216 if (signing->dbiterator != NULL)
16217 dns_dbiterator_destroy(&signing->dbiterator);
16218 isc_mem_put(zone->mctx, signing, sizeof *signing);
16221 dns_db_detach(&db);
16226 logmsg(const char *format, ...) {
16228 va_start(args, format);
16229 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
16230 ISC_LOG_DEBUG(1), format, args);
16235 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
16236 dns_dnsseckey_t *key;
16237 while (!ISC_LIST_EMPTY(*list)) {
16238 key = ISC_LIST_HEAD(*list);
16239 ISC_LIST_UNLINK(*list, key, link);
16240 dns_dnsseckey_destroy(mctx, &key);
16244 /* Called once; *timep should be set to the current time. */
16245 static isc_result_t
16246 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
16247 isc_result_t result;
16248 isc_stdtime_t now, then = 0, event;
16253 for (i = 0; i <= DST_MAX_TIMES; i++) {
16254 result = dst_key_gettime(key, i, &event);
16255 if (result == ISC_R_SUCCESS && event > now &&
16256 (then == 0 || event < then))
16262 return (ISC_R_SUCCESS);
16265 return (ISC_R_NOTFOUND);
16268 static isc_result_t
16269 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
16270 const dns_rdata_t *rdata, isc_boolean_t *flag)
16272 dns_rdataset_t rdataset;
16273 dns_dbnode_t *node = NULL;
16274 isc_result_t result;
16276 dns_rdataset_init(&rdataset);
16277 if (rdata->type == dns_rdatatype_nsec3)
16278 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
16280 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
16281 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
16282 (isc_stdtime_t) 0, &rdataset, NULL);
16283 if (result == ISC_R_NOTFOUND) {
16285 result = ISC_R_SUCCESS;
16289 for (result = dns_rdataset_first(&rdataset);
16290 result == ISC_R_SUCCESS;
16291 result = dns_rdataset_next(&rdataset)) {
16292 dns_rdata_t myrdata = DNS_RDATA_INIT;
16293 dns_rdataset_current(&rdataset, &myrdata);
16294 if (!dns_rdata_compare(&myrdata, rdata))
16297 dns_rdataset_disassociate(&rdataset);
16298 if (result == ISC_R_SUCCESS) {
16300 } else if (result == ISC_R_NOMORE) {
16302 result = ISC_R_SUCCESS;
16307 dns_db_detachnode(db, &node);
16312 * Add records to signal the state of signing or of key removal.
16314 static isc_result_t
16315 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
16316 dns_dbversion_t *ver, dns_diff_t *diff,
16317 isc_boolean_t sign_all)
16319 dns_difftuple_t *tuple, *newtuple = NULL;
16320 dns_rdata_dnskey_t dnskey;
16321 dns_rdata_t rdata = DNS_RDATA_INIT;
16322 isc_boolean_t flag;
16324 isc_result_t result = ISC_R_SUCCESS;
16325 isc_uint16_t keyid;
16326 unsigned char buf[5];
16327 dns_name_t *name = dns_db_origin(db);
16329 for (tuple = ISC_LIST_HEAD(diff->tuples);
16331 tuple = ISC_LIST_NEXT(tuple, link)) {
16332 if (tuple->rdata.type != dns_rdatatype_dnskey)
16335 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
16336 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16337 if ((dnskey.flags &
16338 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
16339 != DNS_KEYOWNER_ZONE)
16342 dns_rdata_toregion(&tuple->rdata, &r);
16344 keyid = dst_region_computeid(&r, dnskey.algorithm);
16346 buf[0] = dnskey.algorithm;
16347 buf[1] = (keyid & 0xff00) >> 8;
16348 buf[2] = (keyid & 0xff);
16349 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
16352 rdata.length = sizeof(buf);
16353 rdata.type = privatetype;
16354 rdata.rdclass = tuple->rdata.rdclass;
16356 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
16357 CHECK(rr_exists(db, ver, name, &rdata, &flag));
16360 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
16361 name, 0, &rdata, &newtuple));
16362 CHECK(do_one_tuple(&newtuple, db, ver, diff));
16363 INSIST(newtuple == NULL);
16367 * Remove any record which says this operation has already
16371 CHECK(rr_exists(db, ver, name, &rdata, &flag));
16373 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
16374 name, 0, &rdata, &newtuple));
16375 CHECK(do_one_tuple(&newtuple, db, ver, diff));
16376 INSIST(newtuple == NULL);
16383 static isc_result_t
16384 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16385 dns_diff_t *diff, zonediff_t *zonediff)
16387 isc_result_t result;
16388 isc_stdtime_t now, inception, soaexpire;
16389 isc_boolean_t check_ksk, keyset_kskonly;
16390 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
16391 unsigned int nkeys = 0, i;
16392 dns_difftuple_t *tuple;
16394 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
16395 zone_keys, &nkeys);
16396 if (result != ISC_R_SUCCESS) {
16397 dns_zone_log(zone, ISC_LOG_ERROR,
16398 "sign_apex:find_zone_keys -> %s",
16399 dns_result_totext(result));
16403 isc_stdtime_get(&now);
16404 inception = now - 3600; /* Allow for clock skew. */
16405 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
16407 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
16408 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
16411 * See if update_sigs will update DNSKEY signature and if not
16412 * cause them to sign so that so that newly activated keys
16415 for (tuple = ISC_LIST_HEAD(diff->tuples);
16417 tuple = ISC_LIST_NEXT(tuple, link)) {
16418 if (tuple->rdata.type == dns_rdatatype_dnskey &&
16419 dns_name_equal(&tuple->name, &zone->origin))
16423 if (tuple == NULL) {
16424 result = del_sigs(zone, db, ver, &zone->origin,
16425 dns_rdatatype_dnskey, zonediff,
16426 zone_keys, nkeys, now, ISC_FALSE);
16427 if (result != ISC_R_SUCCESS) {
16428 dns_zone_log(zone, ISC_LOG_ERROR,
16429 "sign_apex:del_sigs -> %s",
16430 dns_result_totext(result));
16433 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
16434 zonediff->diff, zone_keys, nkeys, zone->mctx,
16435 inception, soaexpire, check_ksk,
16437 if (result != ISC_R_SUCCESS) {
16438 dns_zone_log(zone, ISC_LOG_ERROR,
16439 "sign_apex:add_sigs -> %s",
16440 dns_result_totext(result));
16445 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
16446 inception, soaexpire, now, check_ksk,
16447 keyset_kskonly, zonediff);
16449 if (result != ISC_R_SUCCESS) {
16450 dns_zone_log(zone, ISC_LOG_ERROR,
16451 "sign_apex:update_sigs -> %s",
16452 dns_result_totext(result));
16457 for (i = 0; i < nkeys; i++)
16458 dst_key_free(&zone_keys[i]);
16463 * Prevent the zone entering a inconsistent state where
16464 * NSEC only DNSKEYs are present with NSEC3 chains.
16465 * See update.c:check_dnssec()
16467 static isc_boolean_t
16468 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16471 isc_result_t result;
16472 dns_difftuple_t *tuple;
16473 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
16474 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
16476 /* Scan the tuples for an NSEC-only DNSKEY */
16477 for (tuple = ISC_LIST_HEAD(diff->tuples);
16479 tuple = ISC_LIST_NEXT(tuple, link)) {
16481 if (tuple->rdata.type != dns_rdatatype_dnskey ||
16482 tuple->op != DNS_DIFFOP_ADD)
16485 alg = tuple->rdata.data[3];
16486 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
16487 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
16488 nseconly = ISC_TRUE;
16493 /* Check existing DB for NSEC-only DNSKEY */
16495 result = dns_nsec_nseconly(db, ver, &nseconly);
16496 if (result == ISC_R_NOTFOUND)
16497 result = ISC_R_SUCCESS;
16501 /* Check existing DB for NSEC3 */
16503 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
16504 privatetype, &nsec3));
16506 /* Refuse to allow NSEC3 with NSEC-only keys */
16507 if (nseconly && nsec3) {
16508 dns_zone_log(zone, ISC_LOG_ERROR,
16509 "NSEC only DNSKEYs and NSEC3 chains not allowed");
16516 return (ISC_FALSE);
16519 static isc_result_t
16520 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16523 isc_result_t result;
16524 dns_dbnode_t *node = NULL;
16525 dns_rdataset_t rdataset;
16527 dns_rdataset_init(&rdataset);
16528 CHECK(dns_db_getoriginnode(db, &node));
16530 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
16531 dns_rdatatype_none, 0, &rdataset, NULL);
16532 if (dns_rdataset_isassociated(&rdataset))
16533 dns_rdataset_disassociate(&rdataset);
16534 if (result != ISC_R_NOTFOUND)
16537 result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff);
16541 dns_db_detachnode(db, &node);
16546 * Given an RRSIG rdataset and an algorithm, determine whether there
16547 * are any signatures using that algorithm.
16549 static isc_boolean_t
16550 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
16551 dns_rdata_t rdata = DNS_RDATA_INIT;
16552 dns_rdata_rrsig_t rrsig;
16553 isc_result_t result;
16555 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
16556 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
16557 return (ISC_FALSE);
16560 for (result = dns_rdataset_first(rdataset);
16561 result == ISC_R_SUCCESS;
16562 result = dns_rdataset_next(rdataset))
16564 dns_rdataset_current(rdataset, &rdata);
16565 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
16566 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16567 dns_rdata_reset(&rdata);
16568 if (rrsig.algorithm == alg)
16572 return (ISC_FALSE);
16575 static isc_result_t
16576 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16579 dns_name_t *origin;
16580 isc_boolean_t build_nsec3;
16581 isc_result_t result;
16583 origin = dns_db_origin(db);
16584 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
16587 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
16588 ISC_FALSE, zone->privatetype, diff));
16589 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
16596 zone_rekey(dns_zone_t *zone) {
16597 isc_result_t result;
16598 dns_db_t *db = NULL;
16599 dns_dbnode_t *node = NULL;
16600 dns_dbversion_t *ver = NULL;
16601 dns_rdataset_t soaset, soasigs, keyset, keysigs;
16602 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
16603 dns_dnsseckey_t *key;
16604 dns_diff_t diff, _sig_diff;
16605 zonediff_t zonediff;
16606 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
16607 isc_boolean_t newalg = ISC_FALSE;
16608 isc_boolean_t fullsign;
16609 dns_ttl_t ttl = 3600;
16613 isc_time_t timenow;
16614 isc_interval_t ival;
16617 REQUIRE(DNS_ZONE_VALID(zone));
16619 ISC_LIST_INIT(dnskeys);
16620 ISC_LIST_INIT(keys);
16621 ISC_LIST_INIT(rmkeys);
16622 dns_rdataset_init(&soaset);
16623 dns_rdataset_init(&soasigs);
16624 dns_rdataset_init(&keyset);
16625 dns_rdataset_init(&keysigs);
16626 dir = dns_zone_getkeydirectory(zone);
16628 dns_diff_init(mctx, &diff);
16629 dns_diff_init(mctx, &_sig_diff);
16630 zonediff_init(&zonediff, &_sig_diff);
16632 CHECK(dns_zone_getdb(zone, &db));
16633 CHECK(dns_db_newversion(db, &ver));
16634 CHECK(dns_db_getoriginnode(db, &node));
16636 TIME_NOW(&timenow);
16637 now = isc_time_seconds(&timenow);
16639 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
16641 /* Get the SOA record's TTL */
16642 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
16643 dns_rdatatype_none, 0, &soaset, &soasigs));
16645 dns_rdataset_disassociate(&soaset);
16647 /* Get the DNSKEY rdataset */
16648 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
16649 dns_rdatatype_none, 0, &keyset, &keysigs);
16650 if (result == ISC_R_SUCCESS) {
16652 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
16654 &keysigs, &soasigs,
16655 ISC_FALSE, ISC_FALSE,
16657 } else if (result != ISC_R_NOTFOUND)
16661 * True when called from "rndc sign". Indicates the zone should be
16662 * fully signed now.
16664 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
16666 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
16667 if (result == ISC_R_SUCCESS) {
16668 isc_boolean_t check_ksk;
16669 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
16671 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
16672 &zone->origin, ttl, &diff,
16673 ISC_TF(!check_ksk),
16676 /* Keys couldn't be updated for some reason;
16677 * try again later. */
16678 if (result != ISC_R_SUCCESS) {
16679 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
16680 "couldn't update zone keys: %s",
16681 isc_result_totext(result));
16686 * See if any pre-existing keys have newly become active;
16687 * also, see if any new key is for a new algorithm, as in that
16688 * event, we need to sign the zone fully. (If there's a new
16689 * key, but it's for an already-existing algorithm, then
16690 * the zone signing can be handled incrementally.)
16692 for (key = ISC_LIST_HEAD(dnskeys);
16694 key = ISC_LIST_NEXT(key, link)) {
16695 if (!key->first_sign)
16698 newactive = ISC_TRUE;
16700 if (!dns_rdataset_isassociated(&keysigs)) {
16705 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
16707 * This isn't a new algorithm; clear
16708 * first_sign so we won't sign the
16709 * whole zone with this key later
16711 key->first_sign = ISC_FALSE;
16718 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
16719 dnskey_sane(zone, db, ver, &diff)) {
16720 CHECK(dns_diff_apply(&diff, db, ver));
16721 CHECK(clean_nsec3param(zone, db, ver, &diff));
16722 CHECK(add_signing_records(db, zone->privatetype,
16724 ISC_TF(newalg || fullsign)));
16725 CHECK(update_soa_serial(db, ver, &diff, mctx,
16726 zone->updatemethod));
16727 CHECK(add_chains(zone, db, ver, &diff));
16728 CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
16729 CHECK(zone_journal(zone, zonediff.diff, NULL,
16735 dns_db_closeversion(db, &ver, ISC_TRUE);
16738 dns_difftuple_t *tuple;
16741 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
16743 zone_needdump(zone, DNS_DUMP_DELAY);
16745 zone_settimer(zone, &timenow);
16747 /* Remove any signatures from removed keys. */
16748 if (!ISC_LIST_EMPTY(rmkeys)) {
16749 for (key = ISC_LIST_HEAD(rmkeys);
16751 key = ISC_LIST_NEXT(key, link)) {
16752 result = zone_signwithkey(zone,
16753 dst_key_alg(key->key),
16754 dst_key_id(key->key),
16756 if (result != ISC_R_SUCCESS) {
16757 dns_zone_log(zone, ISC_LOG_ERROR,
16758 "zone_signwithkey failed: %s",
16759 dns_result_totext(result));
16766 * "rndc sign" was called, so we now sign the zone
16767 * with all active keys, whether they're new or not.
16769 for (key = ISC_LIST_HEAD(dnskeys);
16771 key = ISC_LIST_NEXT(key, link)) {
16772 if (!key->force_sign && !key->hint_sign)
16775 result = zone_signwithkey(zone,
16776 dst_key_alg(key->key),
16777 dst_key_id(key->key),
16779 if (result != ISC_R_SUCCESS) {
16780 dns_zone_log(zone, ISC_LOG_ERROR,
16781 "zone_signwithkey failed: %s",
16782 dns_result_totext(result));
16785 } else if (newalg) {
16787 * We haven't been told to sign fully, but a new
16788 * algorithm was added to the DNSKEY. We sign
16789 * the full zone, but only with newly active
16792 for (key = ISC_LIST_HEAD(dnskeys);
16794 key = ISC_LIST_NEXT(key, link)) {
16795 if (!key->first_sign)
16798 result = zone_signwithkey(zone,
16799 dst_key_alg(key->key),
16800 dst_key_id(key->key),
16802 if (result != ISC_R_SUCCESS) {
16803 dns_zone_log(zone, ISC_LOG_ERROR,
16804 "zone_signwithkey failed: %s",
16805 dns_result_totext(result));
16811 * Clear fullsign flag, if it was set, so we don't do
16812 * another full signing next time
16814 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
16817 * Cause the zone to add/delete NSEC3 chains for the
16818 * deferred NSEC3PARAM changes.
16820 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
16822 tuple = ISC_LIST_NEXT(tuple, link)) {
16823 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
16824 dns_rdata_t rdata = DNS_RDATA_INIT;
16825 dns_rdata_nsec3param_t nsec3param;
16827 if (tuple->rdata.type != zone->privatetype ||
16828 tuple->op != DNS_DIFFOP_ADD)
16831 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
16834 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
16835 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16836 if (nsec3param.flags == 0)
16839 result = zone_addnsec3chain(zone, &nsec3param);
16840 if (result != ISC_R_SUCCESS) {
16841 dns_zone_log(zone, ISC_LOG_ERROR,
16842 "zone_addnsec3chain failed: %s",
16843 dns_result_totext(result));
16848 * Activate any NSEC3 chain updates that may have
16849 * been scheduled before this rekey.
16851 if (fullsign || newalg)
16852 resume_addnsec3chain(zone);
16855 * Schedule the next resigning event
16857 set_resigntime(zone);
16861 isc_time_settoepoch(&zone->refreshkeytime);
16864 * If we're doing key maintenance, set the key refresh timer to
16865 * the next scheduled key event or to 'dnssec-loadkeys-interval'
16866 * seconds in the future, whichever is sooner.
16868 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
16869 isc_time_t timethen;
16870 isc_stdtime_t then;
16873 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
16875 zone->refreshkeytime = timethen;
16878 for (key = ISC_LIST_HEAD(dnskeys);
16880 key = ISC_LIST_NEXT(key, link)) {
16882 result = next_keyevent(key->key, &then);
16883 if (result != ISC_R_SUCCESS)
16886 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
16888 if (isc_time_compare(&timethen,
16889 &zone->refreshkeytime) < 0) {
16890 zone->refreshkeytime = timethen;
16895 zone_settimer(zone, &timenow);
16897 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
16898 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
16902 dns_diff_clear(&diff);
16903 dns_diff_clear(&_sig_diff);
16905 clear_keylist(&dnskeys, mctx);
16906 clear_keylist(&keys, mctx);
16907 clear_keylist(&rmkeys, mctx);
16910 dns_db_closeversion(db, &ver, ISC_FALSE);
16911 if (dns_rdataset_isassociated(&keyset))
16912 dns_rdataset_disassociate(&keyset);
16913 if (dns_rdataset_isassociated(&keysigs))
16914 dns_rdataset_disassociate(&keysigs);
16915 if (dns_rdataset_isassociated(&soasigs))
16916 dns_rdataset_disassociate(&soasigs);
16918 dns_db_detachnode(db, &node);
16920 dns_db_detach(&db);
16922 INSIST(ver == NULL);
16927 * Something went wrong; try again in ten minutes or
16928 * after a key refresh interval, whichever is shorter.
16930 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
16931 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
16936 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
16939 if (zone->type == dns_zone_master && zone->task != NULL) {
16943 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
16946 zone->refreshkeytime = now;
16947 zone_settimer(zone, &now);
16954 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
16955 unsigned int *errors)
16957 isc_result_t result;
16958 dns_dbnode_t *node = NULL;
16960 REQUIRE(DNS_ZONE_VALID(zone));
16961 REQUIRE(errors != NULL);
16963 result = dns_db_getoriginnode(db, &node);
16964 if (result != ISC_R_SUCCESS)
16966 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
16968 dns_db_detachnode(db, &node);
16973 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
16974 isc_result_t result;
16975 dns_dbnode_t *node = NULL;
16976 dns_rdataset_t dnskey, cds, cdnskey;
16977 unsigned char buffer[DNS_DS_BUFFERSIZE];
16978 unsigned char algorithms[256];
16981 REQUIRE(DNS_ZONE_VALID(zone));
16983 result = dns_db_getoriginnode(db, &node);
16984 if (result != ISC_R_SUCCESS)
16987 dns_rdataset_init(&cds);
16988 dns_rdataset_init(&dnskey);
16989 dns_rdataset_init(&cdnskey);
16991 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
16992 dns_rdatatype_none, 0, &cds, NULL);
16993 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
16996 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
16997 dns_rdatatype_none, 0, &cdnskey, NULL);
16998 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
17001 if (!dns_rdataset_isassociated(&cds) &&
17002 !dns_rdataset_isassociated(&cdnskey)) {
17003 result = ISC_R_SUCCESS;
17007 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
17008 dns_rdatatype_none, 0, &dnskey, NULL);
17009 if (result == ISC_R_NOTFOUND) {
17010 if (dns_rdataset_isassociated(&cds))
17011 result = DNS_R_BADCDS;
17013 result = DNS_R_BADCDNSKEY;
17016 if (result != ISC_R_SUCCESS)
17020 * For each DNSSEC algorithm in the CDS RRset there must be
17021 * a matching DNSKEY record.
17023 if (dns_rdataset_isassociated(&cds)) {
17024 memset(algorithms, 0, sizeof(algorithms));
17025 for (result = dns_rdataset_first(&cds);
17026 result == ISC_R_SUCCESS;
17027 result = dns_rdataset_next(&cds)) {
17028 dns_rdata_t crdata = DNS_RDATA_INIT;
17029 dns_rdata_cds_t structcds;
17031 dns_rdataset_current(&cds, &crdata);
17032 CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
17033 if (algorithms[structcds.algorithm] == 0)
17034 algorithms[structcds.algorithm] = 1;
17035 for (result = dns_rdataset_first(&dnskey);
17036 result == ISC_R_SUCCESS;
17037 result = dns_rdataset_next(&dnskey)) {
17038 dns_rdata_t rdata = DNS_RDATA_INIT;
17039 dns_rdata_t dsrdata = DNS_RDATA_INIT;
17041 dns_rdataset_current(&dnskey, &rdata);
17042 CHECK(dns_ds_buildrdata(&zone->origin, &rdata,
17043 structcds.digest_type,
17044 buffer, &dsrdata));
17045 if (crdata.length == dsrdata.length &&
17046 memcmp(crdata.data, dsrdata.data,
17047 dsrdata.length) == 0) {
17048 algorithms[structcds.algorithm] = 2;
17051 if (result != ISC_R_NOMORE)
17054 for (i = 0; i < sizeof(algorithms); i++) {
17055 if (algorithms[i] == 1) {
17056 result = DNS_R_BADCDNSKEY;
17063 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
17064 * a matching DNSKEY record.
17066 if (dns_rdataset_isassociated(&cdnskey)) {
17067 memset(algorithms, 0, sizeof(algorithms));
17068 for (result = dns_rdataset_first(&cdnskey);
17069 result == ISC_R_SUCCESS;
17070 result = dns_rdataset_next(&cdnskey)) {
17071 dns_rdata_t crdata = DNS_RDATA_INIT;
17072 dns_rdata_cdnskey_t structcdnskey;
17074 dns_rdataset_current(&cdnskey, &crdata);
17075 CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
17077 if (algorithms[structcdnskey.algorithm] == 0)
17078 algorithms[structcdnskey.algorithm] = 1;
17079 for (result = dns_rdataset_first(&dnskey);
17080 result == ISC_R_SUCCESS;
17081 result = dns_rdataset_next(&dnskey)) {
17082 dns_rdata_t rdata = DNS_RDATA_INIT;
17084 dns_rdataset_current(&dnskey, &rdata);
17085 if (crdata.length == rdata.length &&
17086 memcmp(crdata.data, rdata.data,
17087 rdata.length) == 0) {
17088 algorithms[structcdnskey.algorithm] = 2;
17091 if (result != ISC_R_NOMORE)
17094 for (i = 0; i < sizeof(algorithms); i++) {
17095 if (algorithms[i] == 1) {
17096 result = DNS_R_BADCDS;
17101 result = ISC_R_SUCCESS;
17104 if (dns_rdataset_isassociated(&cds))
17105 dns_rdataset_disassociate(&cds);
17106 if (dns_rdataset_isassociated(&dnskey))
17107 dns_rdataset_disassociate(&dnskey);
17108 if (dns_rdataset_isassociated(&cdnskey))
17109 dns_rdataset_disassociate(&cdnskey);
17110 dns_db_detachnode(db, &node);
17115 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
17116 REQUIRE(DNS_ZONE_VALID(zone));
17118 zone->added = added;
17123 dns_zone_getadded(dns_zone_t *zone) {
17124 REQUIRE(DNS_ZONE_VALID(zone));
17125 return (zone->added);
17129 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
17131 isc_time_t loadtime;
17132 isc_result_t result;
17133 dns_zone_t *secure = NULL;
17135 TIME_NOW(&loadtime);
17138 * Lock hierarchy: zmgr, zone, raw.
17142 if (inline_secure(zone))
17143 LOCK_ZONE(zone->raw);
17144 else if (inline_raw(zone)) {
17145 secure = zone->secure;
17146 TRYLOCK_ZONE(result, secure);
17147 if (result != ISC_R_SUCCESS) {
17150 #if ISC_PLATFORM_USETHREADS
17151 isc_thread_yield();
17156 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
17157 if (inline_secure(zone))
17158 UNLOCK_ZONE(zone->raw);
17159 else if (secure != NULL)
17160 UNLOCK_ZONE(secure);
17166 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) {
17167 REQUIRE(DNS_ZONE_VALID(zone));
17169 return (ISC_R_RANGE);
17170 /* Maximum value: 24 hours (3600 minutes) */
17171 if (interval > (24 * 60))
17172 interval = (24 * 60);
17173 /* Multiply by 60 for seconds */
17174 zone->refreshkeyinterval = interval * 60;
17175 return (ISC_R_SUCCESS);
17179 dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) {
17180 REQUIRE(DNS_ZONE_VALID(zone));
17181 zone->requestixfr = flag;
17185 dns_zone_getrequestixfr(dns_zone_t *zone) {
17186 REQUIRE(DNS_ZONE_VALID(zone));
17187 return (zone->requestixfr);
17191 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
17192 REQUIRE(DNS_ZONE_VALID(zone));
17193 zone->updatemethod = method;
17197 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
17198 REQUIRE(DNS_ZONE_VALID(zone));
17199 return(zone->updatemethod);
17203 * Lock hierarchy: zmgr, zone, raw.
17206 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
17207 isc_result_t result;
17208 dns_zonemgr_t *zmgr;
17210 REQUIRE(DNS_ZONE_VALID(zone));
17211 REQUIRE(zone->zmgr != NULL);
17212 REQUIRE(zone->task != NULL);
17213 REQUIRE(zone->loadtask != NULL);
17214 REQUIRE(zone->raw == NULL);
17216 REQUIRE(DNS_ZONE_VALID(raw));
17217 REQUIRE(raw->zmgr == NULL);
17218 REQUIRE(raw->task == NULL);
17219 REQUIRE(raw->loadtask == NULL);
17220 REQUIRE(raw->secure == NULL);
17223 * Lock hierarchy: zmgr, zone, raw.
17226 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
17230 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
17231 NULL, NULL, zone->task, zone_timer, raw,
17233 if (result != ISC_R_SUCCESS)
17237 * The timer "holds" a iref.
17240 INSIST(raw->irefs != 0);
17243 /* dns_zone_attach(raw, &zone->raw); */
17244 isc_refcount_increment(&raw->erefs, NULL);
17247 /* dns_zone_iattach(zone, &raw->secure); */
17248 zone_iattach(zone, &raw->secure);
17250 isc_task_attach(zone->task, &raw->task);
17251 isc_task_attach(zone->loadtask, &raw->loadtask);
17253 ISC_LIST_APPEND(zmgr->zones, raw, link);
17260 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
17265 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
17266 REQUIRE(DNS_ZONE_VALID(zone));
17267 REQUIRE(raw != NULL && *raw == NULL);
17270 if (zone->raw != NULL)
17271 dns_zone_attach(zone->raw, raw);
17272 UNLOCK(&zone->lock);
17278 unsigned char data[5];
17281 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
17284 keydone(isc_task_t *task, isc_event_t *event) {
17285 const char *me = "keydone";
17286 isc_boolean_t commit = ISC_FALSE;
17287 isc_result_t result;
17288 dns_rdata_t rdata = DNS_RDATA_INIT;
17289 dns_dbversion_t *oldver = NULL, *newver = NULL;
17291 dns_db_t *db = NULL;
17292 dns_dbnode_t *node = NULL;
17293 dns_rdataset_t rdataset;
17295 struct keydone *kd = (struct keydone *)event;
17296 dns_update_log_t log = { update_log_cb, NULL };
17297 isc_boolean_t clear_pending = ISC_FALSE;
17301 zone = event->ev_arg;
17302 INSIST(DNS_ZONE_VALID(zone));
17306 dns_rdataset_init(&rdataset);
17307 dns_diff_init(zone->mctx, &diff);
17309 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17310 if (zone->db != NULL) {
17311 dns_db_attach(zone->db, &db);
17312 dns_db_currentversion(db, &oldver);
17313 result = dns_db_newversion(db, &newver);
17314 if (result != ISC_R_SUCCESS) {
17315 dns_zone_log(zone, ISC_LOG_ERROR,
17316 "keydone:dns_db_newversion -> %s",
17317 dns_result_totext(result));
17321 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17325 result = dns_db_getoriginnode(db, &node);
17326 if (result != ISC_R_SUCCESS)
17329 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
17330 dns_rdatatype_none, 0, &rdataset, NULL);
17331 if (result == ISC_R_NOTFOUND) {
17332 INSIST(!dns_rdataset_isassociated(&rdataset));
17335 if (result != ISC_R_SUCCESS) {
17336 INSIST(!dns_rdataset_isassociated(&rdataset));
17340 for (result = dns_rdataset_first(&rdataset);
17341 result == ISC_R_SUCCESS;
17342 result = dns_rdataset_next(&rdataset)) {
17343 isc_boolean_t found = ISC_FALSE;
17345 dns_rdataset_current(&rdataset, &rdata);
17348 if (rdata.length == 5 && rdata.data[0] != 0 &&
17349 rdata.data[3] == 0 && rdata.data[4] == 1)
17351 else if (rdata.data[0] == 0 &&
17352 (rdata.data[2] & PENDINGFLAGS) != 0) {
17354 clear_pending = ISC_TRUE;
17356 } else if (rdata.length == 5 &&
17357 memcmp(rdata.data, kd->data, 5) == 0)
17361 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
17362 &zone->origin, rdataset.ttl,
17364 dns_rdata_reset(&rdata);
17367 if (!ISC_LIST_EMPTY(diff.tuples)) {
17368 /* Write changes to journal file. */
17369 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
17370 zone->updatemethod));
17372 result = dns_update_signatures(&log, zone, db,
17373 oldver, newver, &diff,
17374 zone->sigvalidityinterval);
17375 if (!clear_pending)
17378 CHECK(zone_journal(zone, &diff, NULL, "keydone"));
17382 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
17383 zone_needdump(zone, 30);
17388 if (dns_rdataset_isassociated(&rdataset))
17389 dns_rdataset_disassociate(&rdataset);
17392 dns_db_detachnode(db, &node);
17393 if (oldver != NULL)
17394 dns_db_closeversion(db, &oldver, ISC_FALSE);
17395 if (newver != NULL)
17396 dns_db_closeversion(db, &newver, commit);
17397 dns_db_detach(&db);
17399 dns_diff_clear(&diff);
17400 isc_event_free(&event);
17401 dns_zone_idetach(&zone);
17403 INSIST(oldver == NULL);
17404 INSIST(newver == NULL);
17408 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
17409 isc_result_t result = ISC_R_SUCCESS;
17412 dns_zone_t *dummy = NULL;
17413 struct keydone *kd;
17415 REQUIRE(DNS_ZONE_VALID(zone));
17419 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
17420 zone, sizeof(struct keydone));
17422 result = ISC_R_NOMEMORY;
17426 kd = (struct keydone *) e;
17427 if (strcasecmp(keystr, "all") == 0)
17428 kd->all = ISC_TRUE;
17430 isc_textregion_t r;
17432 dns_keytag_t keyid;
17436 kd->all = ISC_FALSE;
17438 n = sscanf(keystr, "%hd/", &keyid);
17440 CHECK(ISC_R_FAILURE);
17442 algstr = strchr(keystr, '/');
17443 if (algstr != NULL)
17446 CHECK(ISC_R_FAILURE);
17448 n = sscanf(algstr, "%hhd", &alg);
17450 DE_CONST(algstr, r.base);
17451 r.length = strlen(algstr);
17452 CHECK(dns_secalg_fromtext(&alg, &r));
17455 /* construct a private-type rdata */
17456 isc_buffer_init(&b, kd->data, sizeof(kd->data));
17457 isc_buffer_putuint8(&b, alg);
17458 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
17459 isc_buffer_putuint8(&b, (keyid & 0xff));
17460 isc_buffer_putuint8(&b, 0);
17461 isc_buffer_putuint8(&b, 1);
17464 zone_iattach(zone, &dummy);
17465 isc_task_send(zone->task, &e);
17469 isc_event_free(&e);
17475 setnsec3param(isc_task_t *task, isc_event_t *event) {
17476 const char *me = "setnsec3param";
17477 isc_boolean_t commit = ISC_FALSE;
17478 isc_result_t result;
17479 dns_dbversion_t *oldver = NULL, *newver = NULL;
17481 dns_db_t *db = NULL;
17482 dns_dbnode_t *node = NULL;
17483 dns_rdataset_t prdataset, nrdataset;
17485 struct np3event *npe = (struct np3event *)event;
17487 dns_update_log_t log = { update_log_cb, NULL };
17489 isc_boolean_t nseconly;
17490 isc_boolean_t exists = ISC_FALSE;
17494 zone = event->ev_arg;
17495 INSIST(DNS_ZONE_VALID(zone));
17501 dns_rdataset_init(&prdataset);
17502 dns_rdataset_init(&nrdataset);
17503 dns_diff_init(zone->mctx, &diff);
17505 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17506 if (zone->db != NULL) {
17507 dns_db_attach(zone->db, &db);
17508 dns_db_currentversion(db, &oldver);
17509 result = dns_db_newversion(db, &newver);
17510 if (result != ISC_R_SUCCESS) {
17511 dns_zone_log(zone, ISC_LOG_ERROR,
17512 "setnsec3param:dns_db_newversion -> %s",
17513 dns_result_totext(result));
17517 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17521 CHECK(dns_db_getoriginnode(db, &node));
17524 * Does a private-type record already exist for this chain?
17526 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
17527 dns_rdatatype_none, 0, &prdataset, NULL);
17528 if (result == ISC_R_SUCCESS) {
17529 for (result = dns_rdataset_first(&prdataset);
17530 result == ISC_R_SUCCESS;
17531 result = dns_rdataset_next(&prdataset)) {
17532 dns_rdata_init(&rdata);
17533 dns_rdataset_current(&prdataset, &rdata);
17535 if (np->length == rdata.length &&
17536 memcmp(rdata.data, np->data, np->length) == 0) {
17541 } else if (result != ISC_R_NOTFOUND) {
17542 INSIST(!dns_rdataset_isassociated(&prdataset));
17547 * Does the chain already exist?
17549 result = dns_db_findrdataset(db, node, newver,
17550 dns_rdatatype_nsec3param,
17551 dns_rdatatype_none, 0, &nrdataset, NULL);
17552 if (result == ISC_R_SUCCESS) {
17553 for (result = dns_rdataset_first(&nrdataset);
17554 result == ISC_R_SUCCESS;
17555 result = dns_rdataset_next(&nrdataset)) {
17556 dns_rdata_init(&rdata);
17557 dns_rdataset_current(&nrdataset, &rdata);
17559 if (np->length == (rdata.length + 1) &&
17560 memcmp(rdata.data, np->data + 1,
17561 np->length - 1) == 0)
17567 } else if (result != ISC_R_NOTFOUND) {
17568 INSIST(!dns_rdataset_isassociated(&nrdataset));
17574 * We need to remove any existing NSEC3 chains.
17576 if (!exists && np->replace && (np->length != 0 || np->nsec))
17577 CHECK(dns_nsec3param_deletechains(db, newver, zone,
17578 !np->nsec, &diff));
17580 if (!exists && np->length != 0) {
17582 * We're creating an NSEC3 chain.
17584 * If the zone is not currently capable of supporting
17585 * an NSEC3 chain, add the INITIAL flag, so these
17586 * parameters can be used later when NSEC3 becomes
17589 dns_rdata_init(&rdata);
17591 np->data[2] |= DNS_NSEC3FLAG_CREATE;
17592 result = dns_nsec_nseconly(db, newver, &nseconly);
17593 if (result == ISC_R_NOTFOUND || nseconly)
17594 np->data[2] |= DNS_NSEC3FLAG_INITIAL;
17596 rdata.length = np->length;
17597 rdata.data = np->data;
17598 rdata.type = zone->privatetype;
17599 rdata.rdclass = zone->rdclass;
17600 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
17601 &zone->origin, 0, &rdata));
17604 if (!ISC_LIST_EMPTY(diff.tuples)) {
17605 /* Write changes to journal file. */
17606 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
17607 zone->updatemethod));
17608 result = dns_update_signatures(&log, zone, db,
17609 oldver, newver, &diff,
17610 zone->sigvalidityinterval);
17611 if (result != ISC_R_NOTFOUND)
17613 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
17617 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
17618 zone_needdump(zone, 30);
17623 if (dns_rdataset_isassociated(&prdataset))
17624 dns_rdataset_disassociate(&prdataset);
17625 if (dns_rdataset_isassociated(&nrdataset))
17626 dns_rdataset_disassociate(&nrdataset);
17628 dns_db_detachnode(db, &node);
17629 if (oldver != NULL)
17630 dns_db_closeversion(db, &oldver, ISC_FALSE);
17631 if (newver != NULL)
17632 dns_db_closeversion(db, &newver, commit);
17634 dns_db_detach(&db);
17636 resume_addnsec3chain(zone);
17637 dns_diff_clear(&diff);
17638 isc_event_free(&event);
17639 dns_zone_idetach(&zone);
17641 INSIST(oldver == NULL);
17642 INSIST(newver == NULL);
17646 dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
17647 isc_uint16_t iter, isc_uint8_t saltlen,
17648 unsigned char *salt, isc_boolean_t replace)
17650 isc_result_t result = ISC_R_SUCCESS;
17651 dns_rdata_nsec3param_t param;
17652 dns_rdata_t nrdata = DNS_RDATA_INIT;
17653 dns_rdata_t prdata = DNS_RDATA_INIT;
17654 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
17655 struct np3event *npe;
17657 dns_zone_t *dummy = NULL;
17661 REQUIRE(DNS_ZONE_VALID(zone));
17662 REQUIRE(salt != NULL);
17666 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
17667 setnsec3param, zone, sizeof(struct np3event));
17669 result = ISC_R_NOMEMORY;
17673 npe = (struct np3event *) e;
17676 np->replace = replace;
17679 np->nsec = ISC_TRUE;
17681 param.common.rdclass = zone->rdclass;
17682 param.common.rdtype = dns_rdatatype_nsec3param;
17683 ISC_LINK_INIT(¶m.common, link);
17686 param.flags = flags;
17687 param.iterations = iter;
17688 param.salt_length = saltlen;
17690 isc_buffer_init(&b, nbuf, sizeof(nbuf));
17691 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
17692 dns_rdatatype_nsec3param,
17694 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
17695 np->data, sizeof(np->data));
17696 np->length = prdata.length;
17699 zone_iattach(zone, &dummy);
17700 isc_task_send(zone->task, &e);
17704 isc_event_free(&e);
17710 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
17711 REQUIRE(DNS_ZONE_VALID(zone));
17713 zone->statlevel = level;
17716 dns_zonestat_level_t
17717 dns_zone_getstatlevel(dns_zone_t *zone) {
17718 REQUIRE(DNS_ZONE_VALID(zone));
17720 return (zone->statlevel);