2 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: zone.c,v 1.470.12.12 2009/07/11 04:28:14 marka Exp $ */
26 #include <isc/mutex.h>
27 #include <isc/print.h>
28 #include <isc/random.h>
29 #include <isc/ratelimiter.h>
30 #include <isc/refcount.h>
31 #include <isc/rwlock.h>
32 #include <isc/serial.h>
33 #include <isc/strerror.h>
34 #include <isc/stats.h>
35 #include <isc/string.h>
36 #include <isc/taskpool.h>
37 #include <isc/timer.h>
40 #include <dns/acache.h>
43 #include <dns/callbacks.h>
45 #include <dns/dbiterator.h>
46 #include <dns/events.h>
47 #include <dns/journal.h>
49 #include <dns/master.h>
50 #include <dns/masterdump.h>
51 #include <dns/message.h>
54 #include <dns/rcode.h>
55 #include <dns/rdataclass.h>
56 #include <dns/rdatalist.h>
57 #include <dns/rdataset.h>
58 #include <dns/rdatastruct.h>
59 #include <dns/rdatatype.h>
60 #include <dns/request.h>
61 #include <dns/resolver.h>
62 #include <dns/result.h>
63 #include <dns/stats.h>
66 #include <dns/xfrin.h>
69 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
70 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
72 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
73 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
75 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
76 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
78 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
79 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
81 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
82 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
84 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
85 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
87 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
88 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
91 * Ensure 'a' is at least 'min' but not more than 'max'.
93 #define RANGE(a, min, max) \
94 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
99 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
100 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
101 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
103 #ifndef DNS_MAX_EXPIRE
104 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
107 #ifndef DNS_DUMP_DELAY
108 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
111 typedef struct dns_notify dns_notify_t
;
112 typedef struct dns_stub dns_stub_t
;
113 typedef struct dns_load dns_load_t
;
114 typedef struct dns_forward dns_forward_t
;
115 typedef struct dns_io dns_io_t
;
116 typedef ISC_LIST(dns_io_t
) dns_iolist_t
;
118 #define DNS_ZONE_CHECKLOCK
119 #ifdef DNS_ZONE_CHECKLOCK
120 #define LOCK_ZONE(z) \
121 do { LOCK(&(z)->lock); \
122 INSIST((z)->locked == ISC_FALSE); \
123 (z)->locked = ISC_TRUE; \
125 #define UNLOCK_ZONE(z) \
126 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
127 #define LOCKED_ZONE(z) ((z)->locked)
129 #define LOCK_ZONE(z) LOCK(&(z)->lock)
130 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
131 #define LOCKED_ZONE(z) ISC_TRUE
134 #ifdef ISC_RWLOCK_USEATOMIC
135 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
136 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
137 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
138 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
140 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
141 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
142 #define ZONEDB_LOCK(l, t) LOCK(l)
143 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
150 #ifdef DNS_ZONE_CHECKLOCK
151 isc_boolean_t locked
;
154 isc_refcount_t erefs
;
156 #ifdef ISC_RWLOCK_USEATOMIC
161 dns_db_t
*db
; /* Locked by dblock */
165 ISC_LINK(dns_zone_t
) link
; /* Used by zmgr. */
170 dns_masterformat_t masterformat
;
172 isc_int32_t journalsize
;
173 dns_rdataclass_t rdclass
;
176 unsigned int options
;
177 unsigned int db_argc
;
179 isc_time_t expiretime
;
180 isc_time_t refreshtime
;
183 isc_time_t notifytime
;
185 isc_uint32_t refresh
;
188 isc_uint32_t minimum
;
191 isc_uint32_t maxrefresh
;
192 isc_uint32_t minrefresh
;
193 isc_uint32_t maxretry
;
194 isc_uint32_t minretry
;
196 isc_sockaddr_t
*masters
;
197 dns_name_t
**masterkeynames
;
198 isc_boolean_t
*mastersok
;
199 unsigned int masterscnt
;
200 unsigned int curmaster
;
201 isc_sockaddr_t masteraddr
;
202 dns_notifytype_t notifytype
;
203 isc_sockaddr_t
*notify
;
204 unsigned int notifycnt
;
205 isc_sockaddr_t notifyfrom
;
207 isc_sockaddr_t notifysrc4
;
208 isc_sockaddr_t notifysrc6
;
209 isc_sockaddr_t xfrsource4
;
210 isc_sockaddr_t xfrsource6
;
211 isc_sockaddr_t altxfrsource4
;
212 isc_sockaddr_t altxfrsource6
;
213 isc_sockaddr_t sourceaddr
;
214 dns_xfrin_ctx_t
*xfr
; /* task locked */
215 dns_tsigkey_t
*tsigkey
; /* key used for xfr */
216 /* Access Control Lists */
217 dns_acl_t
*update_acl
;
218 dns_acl_t
*forward_acl
;
219 dns_acl_t
*notify_acl
;
220 dns_acl_t
*query_acl
;
221 dns_acl_t
*queryon_acl
;
223 isc_boolean_t update_disabled
;
224 isc_boolean_t zero_no_soa_ttl
;
225 dns_severity_t check_names
;
226 ISC_LIST(dns_notify_t
) notifies
;
227 dns_request_t
*request
;
232 isc_uint32_t maxxfrin
;
233 isc_uint32_t maxxfrout
;
235 isc_uint32_t idleout
;
236 isc_event_t ctlevent
;
237 dns_ssutable_t
*ssutable
;
238 isc_uint32_t sigvalidityinterval
;
240 dns_acache_t
*acache
;
241 dns_checkmxfunc_t checkmx
;
242 dns_checksrvfunc_t checksrv
;
243 dns_checknsfunc_t checkns
;
245 * Zones in certain states such as "waiting for zone transfer"
246 * or "zone transfer in progress" are kept on per-state linked lists
247 * in the zone manager using the 'statelink' field. The 'statelist'
248 * field points at the list the zone is currently on. It the zone
249 * is not on any such list, statelist is NULL.
251 ISC_LINK(dns_zone_t
) statelink
;
252 dns_zonelist_t
*statelist
;
254 * Statistics counters about zone management.
258 * Optional per-zone statistics counters. Counted outside of this
261 isc_boolean_t requeststats_on
;
262 isc_stats_t
*requeststats
;
263 isc_uint32_t notifydelay
;
264 dns_isselffunc_t isself
;
273 * Serial number for deferred journal compaction.
275 isc_uint32_t compact_serial
;
278 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
279 #define DNS_ZONE_SETFLAG(z,f) do { \
280 INSIST(LOCKED_ZONE(z)); \
283 #define DNS_ZONE_CLRFLAG(z,f) do { \
284 INSIST(LOCKED_ZONE(z)); \
285 (z)->flags &= ~(f); \
287 /* XXX MPA these may need to go back into zone.h */
288 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
289 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
290 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
291 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
292 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
293 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
294 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
295 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
296 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
297 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
299 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
301 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
303 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
304 * zone with no masters
306 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
307 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
308 * from SOA (if not set, we
310 * default timer values) */
311 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
312 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
313 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
314 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
315 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
316 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
317 #define DNS_ZONEFLG_FLUSH 0x00200000U
318 #define DNS_ZONEFLG_NOEDNS 0x00400000U
319 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
320 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
321 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
322 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
323 #define DNS_ZONEFLG_THAW 0x08000000U
325 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
327 /* Flags for zone_load() */
328 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
329 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
332 #define UNREACH_CHACHE_SIZE 10U
333 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
335 struct dns_unreachable
{
336 isc_sockaddr_t remote
;
337 isc_sockaddr_t local
;
345 int refs
; /* Locked by rwlock */
346 isc_taskmgr_t
* taskmgr
;
347 isc_timermgr_t
* timermgr
;
348 isc_socketmgr_t
* socketmgr
;
349 isc_taskpool_t
* zonetasks
;
351 isc_ratelimiter_t
* rl
;
355 /* Locked by rwlock. */
356 dns_zonelist_t zones
;
357 dns_zonelist_t waiting_for_xfrin
;
358 dns_zonelist_t xfrin_in_progress
;
360 /* Configuration data. */
361 isc_uint32_t transfersin
;
362 isc_uint32_t transfersperns
;
363 unsigned int serialqueryrate
;
365 /* Locked by iolock */
366 isc_uint32_t iolimit
;
367 isc_uint32_t ioactive
;
371 /* Locked by rwlock. */
373 struct dns_unreachable unreachable
[UNREACH_CHACHE_SIZE
];
385 dns_request_t
*request
;
388 ISC_LINK(dns_notify_t
) link
;
391 #define DNS_NOTIFY_NOSOA 0x0001U
394 * dns_stub holds state while performing a 'stub' transfer.
395 * 'db' is the zone's 'db' or a new one if this is the initial
404 dns_dbversion_t
*version
;
416 dns_rdatacallbacks_t callbacks
;
420 * Hold forward state.
426 isc_buffer_t
*msgbuf
;
427 dns_request_t
*request
;
430 dns_updatecallback_t callback
;
435 * Hold IO request state.
442 ISC_LINK(dns_io_t
) link
;
446 #define SEND_BUFFER_SIZE 2048
448 static void zone_settimer(dns_zone_t
*, isc_time_t
*);
449 static void cancel_refresh(dns_zone_t
*);
450 static void zone_debuglog(dns_zone_t
*zone
, const char *, int debuglevel
,
451 const char *msg
, ...) ISC_FORMAT_PRINTF(4, 5);
452 static void notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...)
453 ISC_FORMAT_PRINTF(3, 4);
454 static void queue_xfrin(dns_zone_t
*zone
);
455 static void zone_unload(dns_zone_t
*zone
);
456 static void zone_expire(dns_zone_t
*zone
);
457 static void zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
);
458 static void zone_idetach(dns_zone_t
**zonep
);
459 static isc_result_t
zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
,
461 static inline void zone_attachdb(dns_zone_t
*zone
, dns_db_t
*db
);
462 static inline void zone_detachdb(dns_zone_t
*zone
);
463 static isc_result_t
default_journal(dns_zone_t
*zone
);
464 static void zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
);
465 static isc_result_t
zone_postload(dns_zone_t
*zone
, dns_db_t
*db
,
466 isc_time_t loadtime
, isc_result_t result
);
467 static void zone_needdump(dns_zone_t
*zone
, unsigned int delay
);
468 static void zone_shutdown(isc_task_t
*, isc_event_t
*);
469 static void zone_loaddone(void *arg
, isc_result_t result
);
470 static isc_result_t
zone_startload(dns_db_t
*db
, dns_zone_t
*zone
,
471 isc_time_t loadtime
);
472 static void zone_namerd_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
473 static void zone_name_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
474 static void zone_rdclass_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
475 static void zone_viewname_tostr(dns_zone_t
*zone
, char *buf
, size_t length
);
478 /* ondestroy example */
479 static void dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
);
482 static void refresh_callback(isc_task_t
*, isc_event_t
*);
483 static void stub_callback(isc_task_t
*, isc_event_t
*);
484 static void queue_soa_query(dns_zone_t
*zone
);
485 static void soa_query(isc_task_t
*, isc_event_t
*);
486 static void ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
,
488 static int message_count(dns_message_t
*msg
, dns_section_t section
,
489 dns_rdatatype_t type
);
490 static void notify_cancel(dns_zone_t
*zone
);
491 static void notify_find_address(dns_notify_t
*notify
);
492 static void notify_send(dns_notify_t
*notify
);
493 static isc_result_t
notify_createmessage(dns_zone_t
*zone
,
495 dns_message_t
**messagep
);
496 static void notify_done(isc_task_t
*task
, isc_event_t
*event
);
497 static void notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
);
498 static isc_result_t
zone_dump(dns_zone_t
*, isc_boolean_t
);
499 static void got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
);
500 static isc_result_t
zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
,
502 static void zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
);
503 static void zonemgr_free(dns_zonemgr_t
*zmgr
);
504 static isc_result_t
zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
505 isc_task_t
*task
, isc_taskaction_t action
,
506 void *arg
, dns_io_t
**iop
);
507 static void zonemgr_putio(dns_io_t
**iop
);
508 static void zonemgr_cancelio(dns_io_t
*io
);
511 zone_get_from_db(dns_zone_t
*zone
, dns_db_t
*db
, unsigned int *nscount
,
512 unsigned int *soacount
, isc_uint32_t
*serial
,
513 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
514 isc_uint32_t
*expire
, isc_uint32_t
*minimum
,
515 unsigned int *errors
);
517 static void zone_freedbargs(dns_zone_t
*zone
);
518 static void forward_callback(isc_task_t
*task
, isc_event_t
*event
);
519 static void zone_saveunique(dns_zone_t
*zone
, const char *path
,
520 const char *templat
);
521 static void zone_maintenance(dns_zone_t
*zone
);
522 static void zone_notify(dns_zone_t
*zone
, isc_time_t
*now
);
523 static void dump_done(void *arg
, isc_result_t result
);
524 static isc_boolean_t
dns_zonemgr_unreachable(dns_zonemgr_t
*zmgr
,
525 isc_sockaddr_t
*remote
,
526 isc_sockaddr_t
*local
,
529 #define ENTER zone_debuglog(zone, me, 1, "enter")
531 static const unsigned int dbargc_default
= 1;
532 static const char *dbargv_default
[] = { "rbt" };
534 #define DNS_ZONE_JITTER_ADD(a, b, c) \
538 _j = isc_random_jitter((b), (b)/4); \
539 isc_interval_set(&_i, _j, 0); \
540 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
541 dns_zone_log(zone, ISC_LOG_WARNING, \
542 "epoch approaching: upgrade required: " \
543 "now + %s failed", #b); \
544 isc_interval_set(&_i, _j/2, 0); \
545 (void)isc_time_add((a), &_i, (c)); \
549 #define DNS_ZONE_TIME_ADD(a, b, c) \
552 isc_interval_set(&_i, (b), 0); \
553 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
554 dns_zone_log(zone, ISC_LOG_WARNING, \
555 "epoch approaching: upgrade required: " \
556 "now + %s failed", #b); \
557 isc_interval_set(&_i, (b)/2, 0); \
558 (void)isc_time_add((a), &_i, (c)); \
563 * Increment resolver-related statistics counters. Zone must be locked.
566 inc_stats(dns_zone_t
*zone
, isc_statscounter_t counter
) {
567 if (zone
->stats
!= NULL
)
568 isc_stats_increment(zone
->stats
, counter
);
572 *** Public functions.
576 dns_zone_create(dns_zone_t
**zonep
, isc_mem_t
*mctx
) {
581 REQUIRE(zonep
!= NULL
&& *zonep
== NULL
);
582 REQUIRE(mctx
!= NULL
);
585 zone
= isc_mem_get(mctx
, sizeof(*zone
));
587 return (ISC_R_NOMEMORY
);
590 isc_mem_attach(mctx
, &zone
->mctx
);
592 result
= isc_mutex_init(&zone
->lock
);
593 if (result
!= ISC_R_SUCCESS
)
596 result
= ZONEDB_INITLOCK(&zone
->dblock
);
597 if (result
!= ISC_R_SUCCESS
)
600 /* XXX MPA check that all elements are initialised */
601 #ifdef DNS_ZONE_CHECKLOCK
602 zone
->locked
= ISC_FALSE
;
606 ISC_LINK_INIT(zone
, link
);
607 result
= isc_refcount_init(&zone
->erefs
, 1); /* Implicit attach. */
608 if (result
!= ISC_R_SUCCESS
)
611 dns_name_init(&zone
->origin
, NULL
);
612 zone
->strnamerd
= NULL
;
613 zone
->strname
= NULL
;
614 zone
->strrdclass
= NULL
;
615 zone
->strviewname
= NULL
;
616 zone
->masterfile
= NULL
;
617 zone
->masterformat
= dns_masterformat_none
;
618 zone
->keydirectory
= NULL
;
619 zone
->journalsize
= -1;
620 zone
->journal
= NULL
;
621 zone
->rdclass
= dns_rdataclass_none
;
622 zone
->type
= dns_zone_none
;
626 zone
->db_argv
= NULL
;
627 isc_time_settoepoch(&zone
->expiretime
);
628 isc_time_settoepoch(&zone
->refreshtime
);
629 isc_time_settoepoch(&zone
->dumptime
);
630 isc_time_settoepoch(&zone
->loadtime
);
631 zone
->notifytime
= now
;
633 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
634 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
637 zone
->maxrefresh
= DNS_ZONE_MAXREFRESH
;
638 zone
->minrefresh
= DNS_ZONE_MINREFRESH
;
639 zone
->maxretry
= DNS_ZONE_MAXRETRY
;
640 zone
->minretry
= DNS_ZONE_MINRETRY
;
641 zone
->masters
= NULL
;
642 zone
->masterkeynames
= NULL
;
643 zone
->mastersok
= NULL
;
644 zone
->masterscnt
= 0;
647 zone
->notifytype
= dns_notifytype_yes
;
650 zone
->update_acl
= NULL
;
651 zone
->forward_acl
= NULL
;
652 zone
->notify_acl
= NULL
;
653 zone
->query_acl
= NULL
;
654 zone
->queryon_acl
= NULL
;
655 zone
->xfr_acl
= NULL
;
656 zone
->update_disabled
= ISC_FALSE
;
657 zone
->zero_no_soa_ttl
= ISC_TRUE
;
658 zone
->check_names
= dns_severity_ignore
;
659 zone
->request
= NULL
;
663 zone
->writeio
= NULL
;
665 zone
->idlein
= DNS_DEFAULT_IDLEIN
;
666 zone
->idleout
= DNS_DEFAULT_IDLEOUT
;
667 ISC_LIST_INIT(zone
->notifies
);
668 isc_sockaddr_any(&zone
->notifysrc4
);
669 isc_sockaddr_any6(&zone
->notifysrc6
);
670 isc_sockaddr_any(&zone
->xfrsource4
);
671 isc_sockaddr_any6(&zone
->xfrsource6
);
672 isc_sockaddr_any(&zone
->altxfrsource4
);
673 isc_sockaddr_any6(&zone
->altxfrsource6
);
675 zone
->tsigkey
= NULL
;
676 zone
->maxxfrin
= MAX_XFER_TIME
;
677 zone
->maxxfrout
= MAX_XFER_TIME
;
678 zone
->ssutable
= NULL
;
679 zone
->sigvalidityinterval
= 30 * 24 * 3600;
682 zone
->checkmx
= NULL
;
683 zone
->checksrv
= NULL
;
684 zone
->checkns
= NULL
;
685 ISC_LINK_INIT(zone
, statelink
);
686 zone
->statelist
= NULL
;
688 zone
->requeststats_on
= ISC_FALSE
;
689 zone
->requeststats
= NULL
;
690 zone
->notifydelay
= 5;
692 zone
->isselfarg
= NULL
;
694 zone
->magic
= ZONE_MAGIC
;
696 /* Must be after magic is set. */
697 result
= dns_zone_setdbtype(zone
, dbargc_default
, dbargv_default
);
698 if (result
!= ISC_R_SUCCESS
)
701 ISC_EVENT_INIT(&zone
->ctlevent
, sizeof(zone
->ctlevent
), 0, NULL
,
702 DNS_EVENT_ZONECONTROL
, zone_shutdown
, zone
, zone
,
705 return (ISC_R_SUCCESS
);
708 isc_refcount_decrement(&zone
->erefs
, NULL
);
709 isc_refcount_destroy(&zone
->erefs
);
712 ZONEDB_DESTROYLOCK(&zone
->dblock
);
715 DESTROYLOCK(&zone
->lock
);
718 isc_mem_putanddetach(&zone
->mctx
, zone
, sizeof(*zone
));
723 * Free a zone. Because we require that there be no more
724 * outstanding events or references, no locking is necessary.
727 zone_free(dns_zone_t
*zone
) {
728 isc_mem_t
*mctx
= NULL
;
730 REQUIRE(DNS_ZONE_VALID(zone
));
731 REQUIRE(isc_refcount_current(&zone
->erefs
) == 0);
732 REQUIRE(zone
->irefs
== 0);
733 REQUIRE(!LOCKED_ZONE(zone
));
734 REQUIRE(zone
->timer
== NULL
);
737 * Managed objects. Order is important.
739 if (zone
->request
!= NULL
)
740 dns_request_destroy(&zone
->request
); /* XXXMPA */
741 INSIST(zone
->readio
== NULL
);
742 INSIST(zone
->statelist
== NULL
);
743 INSIST(zone
->writeio
== NULL
);
745 if (zone
->task
!= NULL
)
746 isc_task_detach(&zone
->task
);
747 if (zone
->zmgr
!= NULL
)
748 dns_zonemgr_releasezone(zone
->zmgr
, zone
);
750 /* Unmanaged objects */
751 if (zone
->masterfile
!= NULL
)
752 isc_mem_free(zone
->mctx
, zone
->masterfile
);
753 zone
->masterfile
= NULL
;
754 if (zone
->keydirectory
!= NULL
)
755 isc_mem_free(zone
->mctx
, zone
->keydirectory
);
756 zone
->keydirectory
= NULL
;
757 zone
->journalsize
= -1;
758 if (zone
->journal
!= NULL
)
759 isc_mem_free(zone
->mctx
, zone
->journal
);
760 zone
->journal
= NULL
;
761 if (zone
->stats
!= NULL
)
762 isc_stats_detach(&zone
->stats
);
763 if (zone
->requeststats
!= NULL
)
764 isc_stats_detach(&zone
->requeststats
);
765 if (zone
->db
!= NULL
)
767 if (zone
->acache
!= NULL
)
768 dns_acache_detach(&zone
->acache
);
769 zone_freedbargs(zone
);
770 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone
, NULL
, NULL
, 0)
772 RUNTIME_CHECK(dns_zone_setalsonotify(zone
, NULL
, 0)
774 zone
->check_names
= dns_severity_ignore
;
775 if (zone
->update_acl
!= NULL
)
776 dns_acl_detach(&zone
->update_acl
);
777 if (zone
->forward_acl
!= NULL
)
778 dns_acl_detach(&zone
->forward_acl
);
779 if (zone
->notify_acl
!= NULL
)
780 dns_acl_detach(&zone
->notify_acl
);
781 if (zone
->query_acl
!= NULL
)
782 dns_acl_detach(&zone
->query_acl
);
783 if (zone
->queryon_acl
!= NULL
)
784 dns_acl_detach(&zone
->queryon_acl
);
785 if (zone
->xfr_acl
!= NULL
)
786 dns_acl_detach(&zone
->xfr_acl
);
787 if (dns_name_dynamic(&zone
->origin
))
788 dns_name_free(&zone
->origin
, zone
->mctx
);
789 if (zone
->strnamerd
!= NULL
)
790 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
791 if (zone
->strname
!= NULL
)
792 isc_mem_free(zone
->mctx
, zone
->strname
);
793 if (zone
->strrdclass
!= NULL
)
794 isc_mem_free(zone
->mctx
, zone
->strrdclass
);
795 if (zone
->strviewname
!= NULL
)
796 isc_mem_free(zone
->mctx
, zone
->strviewname
);
797 if (zone
->ssutable
!= NULL
)
798 dns_ssutable_detach(&zone
->ssutable
);
801 ZONEDB_DESTROYLOCK(&zone
->dblock
);
802 DESTROYLOCK(&zone
->lock
);
803 isc_refcount_destroy(&zone
->erefs
);
806 isc_mem_put(mctx
, zone
, sizeof(*zone
));
807 isc_mem_detach(&mctx
);
814 dns_zone_setclass(dns_zone_t
*zone
, dns_rdataclass_t rdclass
) {
817 REQUIRE(DNS_ZONE_VALID(zone
));
818 REQUIRE(rdclass
!= dns_rdataclass_none
);
824 REQUIRE(zone
->rdclass
== dns_rdataclass_none
||
825 zone
->rdclass
== rdclass
);
826 zone
->rdclass
= rdclass
;
828 if (zone
->strnamerd
!= NULL
)
829 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
830 if (zone
->strrdclass
!= NULL
)
831 isc_mem_free(zone
->mctx
, zone
->strrdclass
);
833 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
834 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
835 zone_rdclass_tostr(zone
, namebuf
, sizeof namebuf
);
836 zone
->strrdclass
= isc_mem_strdup(zone
->mctx
, namebuf
);
842 dns_zone_getclass(dns_zone_t
*zone
) {
843 REQUIRE(DNS_ZONE_VALID(zone
));
845 return (zone
->rdclass
);
849 dns_zone_setnotifytype(dns_zone_t
*zone
, dns_notifytype_t notifytype
) {
850 REQUIRE(DNS_ZONE_VALID(zone
));
853 zone
->notifytype
= notifytype
;
858 dns_zone_getserial(dns_zone_t
*zone
) {
861 REQUIRE(DNS_ZONE_VALID(zone
));
864 serial
= zone
->serial
;
874 dns_zone_settype(dns_zone_t
*zone
, dns_zonetype_t type
) {
876 REQUIRE(DNS_ZONE_VALID(zone
));
877 REQUIRE(type
!= dns_zone_none
);
883 REQUIRE(zone
->type
== dns_zone_none
|| zone
->type
== type
);
889 zone_freedbargs(dns_zone_t
*zone
) {
892 /* Free the old database argument list. */
893 if (zone
->db_argv
!= NULL
) {
894 for (i
= 0; i
< zone
->db_argc
; i
++)
895 isc_mem_free(zone
->mctx
, zone
->db_argv
[i
]);
896 isc_mem_put(zone
->mctx
, zone
->db_argv
,
897 zone
->db_argc
* sizeof(*zone
->db_argv
));
900 zone
->db_argv
= NULL
;
904 dns_zone_getdbtype(dns_zone_t
*zone
, char ***argv
, isc_mem_t
*mctx
) {
907 isc_result_t result
= ISC_R_SUCCESS
;
911 REQUIRE(DNS_ZONE_VALID(zone
));
912 REQUIRE(argv
!= NULL
&& *argv
== NULL
);
915 size
= (zone
->db_argc
+ 1) * sizeof(char *);
916 for (i
= 0; i
< zone
->db_argc
; i
++)
917 size
+= strlen(zone
->db_argv
[i
]) + 1;
918 mem
= isc_mem_allocate(mctx
, size
);
922 tmp2
+= (zone
->db_argc
+ 1) * sizeof(char *);
923 for (i
= 0; i
< zone
->db_argc
; i
++) {
925 strcpy(tmp2
, zone
->db_argv
[i
]);
926 tmp2
+= strlen(tmp2
) + 1;
930 result
= ISC_R_NOMEMORY
;
937 dns_zone_setdbtype(dns_zone_t
*zone
,
938 unsigned int dbargc
, const char * const *dbargv
) {
939 isc_result_t result
= ISC_R_SUCCESS
;
943 REQUIRE(DNS_ZONE_VALID(zone
));
944 REQUIRE(dbargc
>= 1);
945 REQUIRE(dbargv
!= NULL
);
949 /* Set up a new database argument list. */
950 new = isc_mem_get(zone
->mctx
, dbargc
* sizeof(*new));
953 for (i
= 0; i
< dbargc
; i
++)
955 for (i
= 0; i
< dbargc
; i
++) {
956 new[i
] = isc_mem_strdup(zone
->mctx
, dbargv
[i
]);
961 /* Free the old list. */
962 zone_freedbargs(zone
);
964 zone
->db_argc
= dbargc
;
966 result
= ISC_R_SUCCESS
;
971 for (i
= 0; i
< dbargc
; i
++)
973 isc_mem_free(zone
->mctx
, new[i
]);
974 isc_mem_put(zone
->mctx
, new, dbargc
* sizeof(*new));
976 result
= ISC_R_NOMEMORY
;
984 dns_zone_setview(dns_zone_t
*zone
, dns_view_t
*view
) {
986 REQUIRE(DNS_ZONE_VALID(zone
));
989 if (zone
->view
!= NULL
)
990 dns_view_weakdetach(&zone
->view
);
991 dns_view_weakattach(view
, &zone
->view
);
993 if (zone
->strviewname
!= NULL
)
994 isc_mem_free(zone
->mctx
, zone
->strviewname
);
995 if (zone
->strnamerd
!= NULL
)
996 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
998 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
999 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
1000 zone_viewname_tostr(zone
, namebuf
, sizeof namebuf
);
1001 zone
->strviewname
= isc_mem_strdup(zone
->mctx
, namebuf
);
1008 dns_zone_getview(dns_zone_t
*zone
) {
1009 REQUIRE(DNS_ZONE_VALID(zone
));
1011 return (zone
->view
);
1016 dns_zone_setorigin(dns_zone_t
*zone
, const dns_name_t
*origin
) {
1017 isc_result_t result
;
1020 REQUIRE(DNS_ZONE_VALID(zone
));
1021 REQUIRE(origin
!= NULL
);
1024 if (dns_name_dynamic(&zone
->origin
)) {
1025 dns_name_free(&zone
->origin
, zone
->mctx
);
1026 dns_name_init(&zone
->origin
, NULL
);
1028 result
= dns_name_dup(origin
, zone
->mctx
, &zone
->origin
);
1030 if (zone
->strnamerd
!= NULL
)
1031 isc_mem_free(zone
->mctx
, zone
->strnamerd
);
1032 if (zone
->strname
!= NULL
)
1033 isc_mem_free(zone
->mctx
, zone
->strname
);
1035 zone_namerd_tostr(zone
, namebuf
, sizeof namebuf
);
1036 zone
->strnamerd
= isc_mem_strdup(zone
->mctx
, namebuf
);
1037 zone_name_tostr(zone
, namebuf
, sizeof namebuf
);
1038 zone
->strname
= isc_mem_strdup(zone
->mctx
, namebuf
);
1045 dns_zone_setacache(dns_zone_t
*zone
, dns_acache_t
*acache
) {
1046 REQUIRE(DNS_ZONE_VALID(zone
));
1047 REQUIRE(acache
!= NULL
);
1050 if (zone
->acache
!= NULL
)
1051 dns_acache_detach(&zone
->acache
);
1052 dns_acache_attach(acache
, &zone
->acache
);
1053 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
1054 if (zone
->db
!= NULL
) {
1055 isc_result_t result
;
1058 * If the zone reuses an existing DB, the DB needs to be
1059 * set in the acache explicitly. We can safely ignore the
1060 * case where the DB is already set. If other error happens,
1061 * the acache will not work effectively.
1063 result
= dns_acache_setdb(acache
, zone
->db
);
1064 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_EXISTS
) {
1065 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
1066 "dns_acache_setdb() failed: %s",
1067 isc_result_totext(result
));
1070 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
1075 dns_zone_setstring(dns_zone_t
*zone
, char **field
, const char *value
) {
1078 if (value
!= NULL
) {
1079 copy
= isc_mem_strdup(zone
->mctx
, value
);
1081 return (ISC_R_NOMEMORY
);
1087 isc_mem_free(zone
->mctx
, *field
);
1090 return (ISC_R_SUCCESS
);
1094 dns_zone_setfile(dns_zone_t
*zone
, const char *file
) {
1095 return (dns_zone_setfile2(zone
, file
, dns_masterformat_text
));
1099 dns_zone_setfile2(dns_zone_t
*zone
, const char *file
,
1100 dns_masterformat_t format
) {
1101 isc_result_t result
= ISC_R_SUCCESS
;
1103 REQUIRE(DNS_ZONE_VALID(zone
));
1106 result
= dns_zone_setstring(zone
, &zone
->masterfile
, file
);
1107 if (result
== ISC_R_SUCCESS
) {
1108 zone
->masterformat
= format
;
1109 result
= default_journal(zone
);
1117 dns_zone_getfile(dns_zone_t
*zone
) {
1118 REQUIRE(DNS_ZONE_VALID(zone
));
1120 return (zone
->masterfile
);
1124 default_journal(dns_zone_t
*zone
) {
1125 isc_result_t result
;
1128 REQUIRE(DNS_ZONE_VALID(zone
));
1129 REQUIRE(LOCKED_ZONE(zone
));
1131 if (zone
->masterfile
!= NULL
) {
1132 /* Calculate string length including '\0'. */
1133 int len
= strlen(zone
->masterfile
) + sizeof(".jnl");
1134 journal
= isc_mem_allocate(zone
->mctx
, len
);
1135 if (journal
== NULL
)
1136 return (ISC_R_NOMEMORY
);
1137 strcpy(journal
, zone
->masterfile
);
1138 strcat(journal
, ".jnl");
1142 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
1143 if (journal
!= NULL
)
1144 isc_mem_free(zone
->mctx
, journal
);
1149 dns_zone_setjournal(dns_zone_t
*zone
, const char *journal
) {
1150 isc_result_t result
= ISC_R_SUCCESS
;
1152 REQUIRE(DNS_ZONE_VALID(zone
));
1155 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
1162 dns_zone_getjournal(dns_zone_t
*zone
) {
1163 REQUIRE(DNS_ZONE_VALID(zone
));
1165 return (zone
->journal
);
1169 * Return true iff the zone is "dynamic", in the sense that the zone's
1170 * master file (if any) is written by the server, rather than being
1171 * updated manually and read by the server.
1173 * This is true for slave zones, stub zones, and zones that allow
1174 * dynamic updates either by having an update policy ("ssutable")
1175 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1177 static isc_boolean_t
1178 zone_isdynamic(dns_zone_t
*zone
) {
1179 REQUIRE(DNS_ZONE_VALID(zone
));
1181 return (ISC_TF(zone
->type
== dns_zone_slave
||
1182 zone
->type
== dns_zone_stub
||
1183 (!zone
->update_disabled
&& zone
->ssutable
!= NULL
) ||
1184 (!zone
->update_disabled
&& zone
->update_acl
!= NULL
&&
1185 !dns_acl_isnone(zone
->update_acl
))));
1190 zone_load(dns_zone_t
*zone
, unsigned int flags
) {
1191 isc_result_t result
;
1193 isc_time_t loadtime
, filetime
;
1194 dns_db_t
*db
= NULL
;
1196 REQUIRE(DNS_ZONE_VALID(zone
));
1201 INSIST(zone
->type
!= dns_zone_none
);
1203 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
1204 if ((flags
& DNS_ZONELOADFLAG_THAW
) != 0)
1205 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_THAW
);
1206 result
= DNS_R_CONTINUE
;
1210 if (zone
->db
!= NULL
&& zone
->masterfile
== NULL
) {
1212 * The zone has no master file configured, but it already
1213 * has a database. It could be the built-in
1214 * version.bind. CH zone, a zone with a persistent
1215 * database being reloaded, or maybe a zone that
1216 * used to have a master file but whose configuration
1217 * was changed so that it no longer has one. Do nothing.
1219 result
= ISC_R_SUCCESS
;
1223 if (zone
->db
!= NULL
&& zone_isdynamic(zone
)) {
1225 * This is a slave, stub, or dynamically updated
1226 * zone being reloaded. Do nothing - the database
1227 * we already have is guaranteed to be up-to-date.
1229 if (zone
->type
== dns_zone_master
)
1230 result
= DNS_R_DYNAMIC
;
1232 result
= ISC_R_SUCCESS
;
1238 * Store the current time before the zone is loaded, so that if the
1239 * file changes between the time of the load and the time that
1240 * zone->loadtime is set, then the file will still be reloaded
1241 * the next time dns_zone_load is called.
1243 TIME_NOW(&loadtime
);
1246 * Don't do the load if the file that stores the zone is older
1247 * than the last time the zone was loaded. If the zone has not
1248 * been loaded yet, zone->loadtime will be the epoch.
1250 if (zone
->masterfile
!= NULL
) {
1252 * The file is already loaded. If we are just doing a
1253 * "rndc reconfig", we are done.
1255 if (!isc_time_isepoch(&zone
->loadtime
) &&
1256 (flags
& DNS_ZONELOADFLAG_NOSTAT
) != 0) {
1257 result
= ISC_R_SUCCESS
;
1261 result
= isc_file_getmodtime(zone
->masterfile
, &filetime
);
1262 if (result
== ISC_R_SUCCESS
) {
1263 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
1264 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HASINCLUDE
) &&
1265 isc_time_compare(&filetime
, &zone
->loadtime
) <= 0) {
1266 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1267 "skipping load: master file "
1268 "older than last load");
1269 result
= DNS_R_UPTODATE
;
1272 loadtime
= filetime
;
1276 INSIST(zone
->db_argc
>= 1);
1279 * Built in zones don't need to be reloaded.
1281 if (zone
->type
== dns_zone_master
&&
1282 strcmp(zone
->db_argv
[0], "_builtin") == 0 &&
1283 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
1284 result
= ISC_R_SUCCESS
;
1288 if ((zone
->type
== dns_zone_slave
|| zone
->type
== dns_zone_stub
) &&
1289 (strcmp(zone
->db_argv
[0], "rbt") == 0 ||
1290 strcmp(zone
->db_argv
[0], "rbt64") == 0)) {
1291 if (zone
->masterfile
== NULL
||
1292 !isc_file_exists(zone
->masterfile
)) {
1293 if (zone
->masterfile
!= NULL
) {
1294 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1297 zone
->refreshtime
= now
;
1298 if (zone
->task
!= NULL
)
1299 zone_settimer(zone
, &now
);
1300 result
= ISC_R_SUCCESS
;
1305 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "starting load");
1307 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
1308 &zone
->origin
, (zone
->type
== dns_zone_stub
) ?
1309 dns_dbtype_stub
: dns_dbtype_zone
,
1311 zone
->db_argc
- 1, zone
->db_argv
+ 1,
1314 if (result
!= ISC_R_SUCCESS
) {
1315 dns_zone_log(zone
, ISC_LOG_ERROR
,
1316 "loading zone: creating database: %s",
1317 isc_result_totext(result
));
1320 dns_db_settask(db
, zone
->task
);
1322 if (! dns_db_ispersistent(db
)) {
1323 if (zone
->masterfile
!= NULL
) {
1324 result
= zone_startload(db
, zone
, loadtime
);
1326 result
= DNS_R_NOMASTERFILE
;
1327 if (zone
->type
== dns_zone_master
) {
1328 dns_zone_log(zone
, ISC_LOG_ERROR
,
1330 "no master file configured");
1333 dns_zone_log(zone
, ISC_LOG_INFO
, "loading zone: "
1334 "no master file configured: continuing");
1338 if (result
== DNS_R_CONTINUE
) {
1339 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADING
);
1340 if ((flags
& DNS_ZONELOADFLAG_THAW
) != 0)
1341 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_THAW
);
1345 result
= zone_postload(zone
, db
, loadtime
, result
);
1355 dns_zone_load(dns_zone_t
*zone
) {
1356 return (zone_load(zone
, 0));
1360 dns_zone_loadnew(dns_zone_t
*zone
) {
1361 return (zone_load(zone
, DNS_ZONELOADFLAG_NOSTAT
));
1365 dns_zone_loadandthaw(dns_zone_t
*zone
) {
1366 isc_result_t result
;
1368 result
= zone_load(zone
, DNS_ZONELOADFLAG_THAW
);
1370 case DNS_R_CONTINUE
:
1371 /* Deferred thaw. */
1374 case DNS_R_UPTODATE
:
1375 case DNS_R_SEENINCLUDE
:
1376 zone
->update_disabled
= ISC_FALSE
;
1378 case DNS_R_NOMASTERFILE
:
1379 zone
->update_disabled
= ISC_FALSE
;
1382 /* Error, remain in disabled state. */
1389 zone_gotreadhandle(isc_task_t
*task
, isc_event_t
*event
) {
1390 dns_load_t
*load
= event
->ev_arg
;
1391 isc_result_t result
= ISC_R_SUCCESS
;
1392 unsigned int options
;
1394 REQUIRE(DNS_LOAD_VALID(load
));
1396 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
1397 result
= ISC_R_CANCELED
;
1398 isc_event_free(&event
);
1399 if (result
== ISC_R_CANCELED
)
1402 options
= DNS_MASTER_ZONE
;
1403 if (load
->zone
->type
== dns_zone_slave
)
1404 options
|= DNS_MASTER_SLAVE
;
1405 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKNS
))
1406 options
|= DNS_MASTER_CHECKNS
;
1407 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_FATALNS
))
1408 options
|= DNS_MASTER_FATALNS
;
1409 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKNAMES
))
1410 options
|= DNS_MASTER_CHECKNAMES
;
1411 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKNAMESFAIL
))
1412 options
|= DNS_MASTER_CHECKNAMESFAIL
;
1413 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKMX
))
1414 options
|= DNS_MASTER_CHECKMX
;
1415 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKMXFAIL
))
1416 options
|= DNS_MASTER_CHECKMXFAIL
;
1417 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKWILDCARD
))
1418 options
|= DNS_MASTER_CHECKWILDCARD
;
1419 result
= dns_master_loadfileinc2(load
->zone
->masterfile
,
1420 dns_db_origin(load
->db
),
1421 dns_db_origin(load
->db
),
1422 load
->zone
->rdclass
,
1424 &load
->callbacks
, task
,
1425 zone_loaddone
, load
,
1426 &load
->zone
->lctx
, load
->zone
->mctx
,
1427 load
->zone
->masterformat
);
1428 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_CONTINUE
&&
1429 result
!= DNS_R_SEENINCLUDE
)
1434 zone_loaddone(load
, result
);
1438 zone_gotwritehandle(isc_task_t
*task
, isc_event_t
*event
) {
1439 const char me
[] = "zone_gotwritehandle";
1440 dns_zone_t
*zone
= event
->ev_arg
;
1441 isc_result_t result
= ISC_R_SUCCESS
;
1442 dns_dbversion_t
*version
= NULL
;
1444 REQUIRE(DNS_ZONE_VALID(zone
));
1445 INSIST(task
== zone
->task
);
1448 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
1449 result
= ISC_R_CANCELED
;
1450 isc_event_free(&event
);
1451 if (result
== ISC_R_CANCELED
)
1455 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
1456 dns_db_currentversion(zone
->db
, &version
);
1457 result
= dns_master_dumpinc2(zone
->mctx
, zone
->db
, version
,
1458 &dns_master_style_default
,
1459 zone
->masterfile
, zone
->task
, dump_done
,
1460 zone
, &zone
->dctx
, zone
->masterformat
);
1461 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
1462 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
1464 if (result
!= DNS_R_CONTINUE
)
1469 dump_done(zone
, result
);
1473 zone_startload(dns_db_t
*db
, dns_zone_t
*zone
, isc_time_t loadtime
) {
1475 isc_result_t result
;
1476 isc_result_t tresult
;
1477 unsigned int options
;
1479 options
= DNS_MASTER_ZONE
;
1480 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MANYERRORS
))
1481 options
|= DNS_MASTER_MANYERRORS
;
1482 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNS
))
1483 options
|= DNS_MASTER_CHECKNS
;
1484 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_FATALNS
))
1485 options
|= DNS_MASTER_FATALNS
;
1486 if (zone
->type
== dns_zone_slave
)
1487 options
|= DNS_MASTER_SLAVE
;
1488 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMES
))
1489 options
|= DNS_MASTER_CHECKNAMES
;
1490 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
))
1491 options
|= DNS_MASTER_CHECKNAMESFAIL
;
1492 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKMX
))
1493 options
|= DNS_MASTER_CHECKMX
;
1494 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKMXFAIL
))
1495 options
|= DNS_MASTER_CHECKMXFAIL
;
1496 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKWILDCARD
))
1497 options
|= DNS_MASTER_CHECKWILDCARD
;
1499 if (zone
->zmgr
!= NULL
&& zone
->db
!= NULL
&& zone
->task
!= NULL
) {
1500 load
= isc_mem_get(zone
->mctx
, sizeof(*load
));
1502 return (ISC_R_NOMEMORY
);
1507 load
->loadtime
= loadtime
;
1508 load
->magic
= LOAD_MAGIC
;
1510 isc_mem_attach(zone
->mctx
, &load
->mctx
);
1511 zone_iattach(zone
, &load
->zone
);
1512 dns_db_attach(db
, &load
->db
);
1513 dns_rdatacallbacks_init(&load
->callbacks
);
1514 result
= dns_db_beginload(db
, &load
->callbacks
.add
,
1515 &load
->callbacks
.add_private
);
1516 if (result
!= ISC_R_SUCCESS
)
1518 result
= zonemgr_getio(zone
->zmgr
, ISC_TRUE
, zone
->task
,
1519 zone_gotreadhandle
, load
,
1521 if (result
!= ISC_R_SUCCESS
) {
1523 * We can't report multiple errors so ignore
1524 * the result of dns_db_endload().
1526 (void)dns_db_endload(load
->db
,
1527 &load
->callbacks
.add_private
);
1530 result
= DNS_R_CONTINUE
;
1532 dns_rdatacallbacks_t callbacks
;
1534 dns_rdatacallbacks_init(&callbacks
);
1535 result
= dns_db_beginload(db
, &callbacks
.add
,
1536 &callbacks
.add_private
);
1537 if (result
!= ISC_R_SUCCESS
)
1539 result
= dns_master_loadfile2(zone
->masterfile
, &zone
->origin
,
1540 &zone
->origin
, zone
->rdclass
,
1541 options
, &callbacks
, zone
->mctx
,
1542 zone
->masterformat
);
1543 tresult
= dns_db_endload(db
, &callbacks
.add_private
);
1544 if (result
== ISC_R_SUCCESS
)
1552 dns_db_detach(&load
->db
);
1553 zone_idetach(&load
->zone
);
1554 isc_mem_detach(&load
->mctx
);
1555 isc_mem_put(zone
->mctx
, load
, sizeof(*load
));
1559 static isc_boolean_t
1560 zone_check_mx(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
1563 isc_result_t result
;
1564 char ownerbuf
[DNS_NAME_FORMATSIZE
];
1565 char namebuf
[DNS_NAME_FORMATSIZE
];
1566 char altbuf
[DNS_NAME_FORMATSIZE
];
1567 dns_fixedname_t fixed
;
1568 dns_name_t
*foundname
;
1574 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
1575 if (zone
->checkmx
!= NULL
)
1576 return ((zone
->checkmx
)(zone
, name
, owner
));
1580 if (zone
->type
== dns_zone_master
)
1581 level
= ISC_LOG_ERROR
;
1583 level
= ISC_LOG_WARNING
;
1585 dns_fixedname_init(&fixed
);
1586 foundname
= dns_fixedname_name(&fixed
);
1588 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
1589 0, 0, NULL
, foundname
, NULL
, NULL
);
1590 if (result
== ISC_R_SUCCESS
)
1593 if (result
== DNS_R_NXRRSET
) {
1594 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
1595 0, 0, NULL
, foundname
, NULL
, NULL
);
1596 if (result
== ISC_R_SUCCESS
)
1600 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
1601 dns_name_format(name
, namebuf
, sizeof namebuf
);
1602 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
1603 result
== DNS_R_EMPTYNAME
) {
1604 dns_zone_log(zone
, level
,
1605 "%s/MX '%s' has no address records (A or AAAA)",
1607 /* XXX950 make fatal for 9.5.0. */
1611 if (result
== DNS_R_CNAME
) {
1612 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNMXCNAME
) ||
1613 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
1614 level
= ISC_LOG_WARNING
;
1615 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
1616 dns_zone_log(zone
, level
,
1617 "%s/MX '%s' is a CNAME (illegal)",
1619 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1622 if (result
== DNS_R_DNAME
) {
1623 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNMXCNAME
) ||
1624 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
))
1625 level
= ISC_LOG_WARNING
;
1626 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNOREMXCNAME
)) {
1627 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
1628 dns_zone_log(zone
, level
, "%s/MX '%s' is below a DNAME"
1629 " '%s' (illegal)", ownerbuf
, namebuf
,
1632 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1635 if (zone
->checkmx
!= NULL
&& result
== DNS_R_DELEGATION
)
1636 return ((zone
->checkmx
)(zone
, name
, owner
));
1641 static isc_boolean_t
1642 zone_check_srv(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
1645 isc_result_t result
;
1646 char ownerbuf
[DNS_NAME_FORMATSIZE
];
1647 char namebuf
[DNS_NAME_FORMATSIZE
];
1648 char altbuf
[DNS_NAME_FORMATSIZE
];
1649 dns_fixedname_t fixed
;
1650 dns_name_t
*foundname
;
1654 * "." means the services does not exist.
1656 if (dns_name_equal(name
, dns_rootname
))
1662 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
1663 if (zone
->checksrv
!= NULL
)
1664 return ((zone
->checksrv
)(zone
, name
, owner
));
1668 if (zone
->type
== dns_zone_master
)
1669 level
= ISC_LOG_ERROR
;
1671 level
= ISC_LOG_WARNING
;
1673 dns_fixedname_init(&fixed
);
1674 foundname
= dns_fixedname_name(&fixed
);
1676 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
1677 0, 0, NULL
, foundname
, NULL
, NULL
);
1678 if (result
== ISC_R_SUCCESS
)
1681 if (result
== DNS_R_NXRRSET
) {
1682 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
1683 0, 0, NULL
, foundname
, NULL
, NULL
);
1684 if (result
== ISC_R_SUCCESS
)
1688 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
1689 dns_name_format(name
, namebuf
, sizeof namebuf
);
1690 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
1691 result
== DNS_R_EMPTYNAME
) {
1692 dns_zone_log(zone
, level
,
1693 "%s/SRV '%s' has no address records (A or AAAA)",
1695 /* XXX950 make fatal for 9.5.0. */
1699 if (result
== DNS_R_CNAME
) {
1700 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNSRVCNAME
) ||
1701 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
1702 level
= ISC_LOG_WARNING
;
1703 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
1704 dns_zone_log(zone
, level
,
1705 "%s/SRV '%s' is a CNAME (illegal)",
1707 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1710 if (result
== DNS_R_DNAME
) {
1711 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_WARNSRVCNAME
) ||
1712 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
))
1713 level
= ISC_LOG_WARNING
;
1714 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IGNORESRVCNAME
)) {
1715 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
1716 dns_zone_log(zone
, level
, "%s/SRV '%s' is below a "
1717 "DNAME '%s' (illegal)", ownerbuf
, namebuf
,
1720 return ((level
== ISC_LOG_WARNING
) ? ISC_TRUE
: ISC_FALSE
);
1723 if (zone
->checksrv
!= NULL
&& result
== DNS_R_DELEGATION
)
1724 return ((zone
->checksrv
)(zone
, name
, owner
));
1729 static isc_boolean_t
1730 zone_check_glue(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
,
1733 isc_boolean_t answer
= ISC_TRUE
;
1734 isc_result_t result
, tresult
;
1735 char ownerbuf
[DNS_NAME_FORMATSIZE
];
1736 char namebuf
[DNS_NAME_FORMATSIZE
];
1737 char altbuf
[DNS_NAME_FORMATSIZE
];
1738 dns_fixedname_t fixed
;
1739 dns_name_t
*foundname
;
1741 dns_rdataset_t aaaa
;
1747 if (!dns_name_issubdomain(name
, &zone
->origin
)) {
1748 if (zone
->checkns
!= NULL
)
1749 return ((zone
->checkns
)(zone
, name
, owner
, NULL
, NULL
));
1753 if (zone
->type
== dns_zone_master
)
1754 level
= ISC_LOG_ERROR
;
1756 level
= ISC_LOG_WARNING
;
1758 dns_fixedname_init(&fixed
);
1759 foundname
= dns_fixedname_name(&fixed
);
1760 dns_rdataset_init(&a
);
1761 dns_rdataset_init(&aaaa
);
1763 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
1764 DNS_DBFIND_GLUEOK
, 0, NULL
,
1765 foundname
, &a
, NULL
);
1767 if (result
== ISC_R_SUCCESS
) {
1768 dns_rdataset_disassociate(&a
);
1770 } else if (result
== DNS_R_DELEGATION
)
1771 dns_rdataset_disassociate(&a
);
1773 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_DELEGATION
||
1774 result
== DNS_R_GLUE
) {
1775 tresult
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
1776 DNS_DBFIND_GLUEOK
, 0, NULL
,
1777 foundname
, &aaaa
, NULL
);
1778 if (tresult
== ISC_R_SUCCESS
) {
1779 dns_rdataset_disassociate(&aaaa
);
1782 if (tresult
== DNS_R_DELEGATION
)
1783 dns_rdataset_disassociate(&aaaa
);
1784 if (result
== DNS_R_GLUE
|| tresult
== DNS_R_GLUE
) {
1786 * Check glue against child zone.
1788 if (zone
->checkns
!= NULL
)
1789 answer
= (zone
->checkns
)(zone
, name
, owner
,
1791 if (dns_rdataset_isassociated(&a
))
1792 dns_rdataset_disassociate(&a
);
1793 if (dns_rdataset_isassociated(&aaaa
))
1794 dns_rdataset_disassociate(&aaaa
);
1800 dns_name_format(owner
, ownerbuf
, sizeof ownerbuf
);
1801 dns_name_format(name
, namebuf
, sizeof namebuf
);
1802 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
1803 result
== DNS_R_EMPTYNAME
|| result
== DNS_R_DELEGATION
) {
1805 isc_boolean_t required
= ISC_FALSE
;
1806 if (dns_name_issubdomain(name
, owner
)) {
1807 what
= "REQUIRED GLUE ";
1808 required
= ISC_TRUE
;
1809 } else if (result
== DNS_R_DELEGATION
)
1810 what
= "SIBLING GLUE ";
1814 if (result
!= DNS_R_DELEGATION
|| required
||
1815 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKSIBLING
)) {
1816 dns_zone_log(zone
, level
, "%s/NS '%s' has no %s"
1817 "address records (A or AAAA)",
1818 ownerbuf
, namebuf
, what
);
1820 * Log missing address record.
1822 if (result
== DNS_R_DELEGATION
&& zone
->checkns
!= NULL
)
1823 (void)(zone
->checkns
)(zone
, name
, owner
,
1825 /* XXX950 make fatal for 9.5.0. */
1826 /* answer = ISC_FALSE; */
1828 } else if (result
== DNS_R_CNAME
) {
1829 dns_zone_log(zone
, level
, "%s/NS '%s' is a CNAME (illegal)",
1831 /* XXX950 make fatal for 9.5.0. */
1832 /* answer = ISC_FALSE; */
1833 } else if (result
== DNS_R_DNAME
) {
1834 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
1835 dns_zone_log(zone
, level
,
1836 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1837 ownerbuf
, namebuf
, altbuf
);
1838 /* XXX950 make fatal for 9.5.0. */
1839 /* answer = ISC_FALSE; */
1842 if (dns_rdataset_isassociated(&a
))
1843 dns_rdataset_disassociate(&a
);
1844 if (dns_rdataset_isassociated(&aaaa
))
1845 dns_rdataset_disassociate(&aaaa
);
1849 static isc_boolean_t
1850 integrity_checks(dns_zone_t
*zone
, dns_db_t
*db
) {
1851 dns_dbiterator_t
*dbiterator
= NULL
;
1852 dns_dbnode_t
*node
= NULL
;
1853 dns_rdataset_t rdataset
;
1854 dns_fixedname_t fixed
;
1855 dns_fixedname_t fixedbottom
;
1858 dns_rdata_in_srv_t srv
;
1862 isc_result_t result
;
1863 isc_boolean_t ok
= ISC_TRUE
;
1865 dns_fixedname_init(&fixed
);
1866 name
= dns_fixedname_name(&fixed
);
1867 dns_fixedname_init(&fixedbottom
);
1868 bottom
= dns_fixedname_name(&fixedbottom
);
1869 dns_rdataset_init(&rdataset
);
1870 dns_rdata_init(&rdata
);
1872 result
= dns_db_createiterator(db
, ISC_FALSE
, &dbiterator
);
1873 if (result
!= ISC_R_SUCCESS
)
1876 result
= dns_dbiterator_first(dbiterator
);
1877 while (result
== ISC_R_SUCCESS
) {
1878 result
= dns_dbiterator_current(dbiterator
, &node
, name
);
1879 if (result
!= ISC_R_SUCCESS
)
1883 * Is this name visible in the zone?
1885 if (!dns_name_issubdomain(name
, &zone
->origin
) ||
1886 (dns_name_countlabels(bottom
) > 0 &&
1887 dns_name_issubdomain(name
, bottom
)))
1891 * Don't check the NS records at the origin.
1893 if (dns_name_equal(name
, &zone
->origin
))
1896 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_ns
,
1897 0, 0, &rdataset
, NULL
);
1898 if (result
!= ISC_R_SUCCESS
)
1901 * Remember bottom of zone.
1903 dns_name_copy(name
, bottom
, NULL
);
1905 result
= dns_rdataset_first(&rdataset
);
1906 while (result
== ISC_R_SUCCESS
) {
1907 dns_rdataset_current(&rdataset
, &rdata
);
1908 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
1909 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1910 if (!zone_check_glue(zone
, db
, &ns
.name
, name
))
1912 dns_rdata_reset(&rdata
);
1913 result
= dns_rdataset_next(&rdataset
);
1915 dns_rdataset_disassociate(&rdataset
);
1918 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_mx
,
1919 0, 0, &rdataset
, NULL
);
1920 if (result
!= ISC_R_SUCCESS
)
1922 result
= dns_rdataset_first(&rdataset
);
1923 while (result
== ISC_R_SUCCESS
) {
1924 dns_rdataset_current(&rdataset
, &rdata
);
1925 result
= dns_rdata_tostruct(&rdata
, &mx
, NULL
);
1926 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1927 if (!zone_check_mx(zone
, db
, &mx
.mx
, name
))
1929 dns_rdata_reset(&rdata
);
1930 result
= dns_rdataset_next(&rdataset
);
1932 dns_rdataset_disassociate(&rdataset
);
1935 if (zone
->rdclass
!= dns_rdataclass_in
)
1937 result
= dns_db_findrdataset(db
, node
, NULL
, dns_rdatatype_srv
,
1938 0, 0, &rdataset
, NULL
);
1939 if (result
!= ISC_R_SUCCESS
)
1941 result
= dns_rdataset_first(&rdataset
);
1942 while (result
== ISC_R_SUCCESS
) {
1943 dns_rdataset_current(&rdataset
, &rdata
);
1944 result
= dns_rdata_tostruct(&rdata
, &srv
, NULL
);
1945 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1946 if (!zone_check_srv(zone
, db
, &srv
.target
, name
))
1948 dns_rdata_reset(&rdata
);
1949 result
= dns_rdataset_next(&rdataset
);
1951 dns_rdataset_disassociate(&rdataset
);
1954 dns_db_detachnode(db
, &node
);
1955 result
= dns_dbiterator_next(dbiterator
);
1960 dns_db_detachnode(db
, &node
);
1961 dns_dbiterator_destroy(&dbiterator
);
1967 * OpenSSL verification of RSA keys with exponent 3 is known to be
1968 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
1969 * if they are in use.
1972 zone_check_dnskeys(dns_zone_t
*zone
, dns_db_t
*db
) {
1973 dns_dbnode_t
*node
= NULL
;
1974 dns_dbversion_t
*version
= NULL
;
1975 dns_rdata_dnskey_t dnskey
;
1976 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1977 dns_rdataset_t rdataset
;
1978 isc_result_t result
;
1979 isc_boolean_t logit
, foundrsa
= ISC_FALSE
, foundmd5
= ISC_FALSE
;
1980 const char *algorithm
;
1982 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
1983 if (result
!= ISC_R_SUCCESS
)
1986 dns_db_currentversion(db
, &version
);
1987 dns_rdataset_init(&rdataset
);
1988 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_dnskey
,
1989 dns_rdatatype_none
, 0, &rdataset
, NULL
);
1990 if (result
!= ISC_R_SUCCESS
)
1993 for (result
= dns_rdataset_first(&rdataset
);
1994 result
== ISC_R_SUCCESS
;
1995 result
= dns_rdataset_next(&rdataset
))
1997 dns_rdataset_current(&rdataset
, &rdata
);
1998 result
= dns_rdata_tostruct(&rdata
, &dnskey
, NULL
);
1999 INSIST(result
== ISC_R_SUCCESS
);
2001 if ((dnskey
.algorithm
== DST_ALG_RSASHA1
||
2002 dnskey
.algorithm
== DST_ALG_RSAMD5
) &&
2003 dnskey
.datalen
> 1 && dnskey
.data
[0] == 1 &&
2004 dnskey
.data
[1] == 3)
2006 if (dnskey
.algorithm
== DST_ALG_RSASHA1
) {
2008 foundrsa
= ISC_TRUE
;
2009 algorithm
= "RSASHA1";
2012 foundmd5
= ISC_TRUE
;
2013 algorithm
= "RSAMD5";
2016 dns_zone_log(zone
, ISC_LOG_WARNING
,
2017 "weak %s (%u) key found "
2018 "(exponent=3)", algorithm
,
2020 if (foundrsa
&& foundmd5
)
2023 dns_rdata_reset(&rdata
);
2025 dns_rdataset_disassociate(&rdataset
);
2029 dns_db_detachnode(db
, &node
);
2030 if (version
!= NULL
)
2031 dns_db_closeversion(db
, &version
, ISC_FALSE
);
2036 zone_postload(dns_zone_t
*zone
, dns_db_t
*db
, isc_time_t loadtime
,
2037 isc_result_t result
)
2039 unsigned int soacount
= 0;
2040 unsigned int nscount
= 0;
2041 unsigned int errors
= 0;
2042 isc_uint32_t serial
, refresh
, retry
, expire
, minimum
;
2044 isc_boolean_t needdump
= ISC_FALSE
;
2045 isc_boolean_t hasinclude
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
2050 * Initiate zone transfer? We may need a error code that
2051 * indicates that the "permanent" form does not exist.
2052 * XXX better error feedback to log.
2054 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_SEENINCLUDE
) {
2055 if (zone
->type
== dns_zone_slave
||
2056 zone
->type
== dns_zone_stub
) {
2057 if (result
== ISC_R_FILENOTFOUND
)
2058 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
2060 else if (result
!= DNS_R_NOMASTERFILE
)
2061 dns_zone_log(zone
, ISC_LOG_ERROR
,
2062 "loading from master file %s "
2065 dns_result_totext(result
));
2067 dns_zone_log(zone
, ISC_LOG_ERROR
,
2068 "loading from master file %s failed: %s",
2070 dns_result_totext(result
));
2074 dns_zone_log(zone
, ISC_LOG_DEBUG(2),
2075 "number of nodes in database: %u",
2076 dns_db_nodecount(db
));
2078 if (result
== DNS_R_SEENINCLUDE
)
2079 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
2081 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
2084 * Apply update log, if any, on initial load.
2086 if (zone
->journal
!= NULL
&&
2087 ! DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOMERGE
) &&
2088 ! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
2090 result
= dns_journal_rollforward(zone
->mctx
, db
,
2092 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
&&
2093 result
!= DNS_R_UPTODATE
&& result
!= DNS_R_NOJOURNAL
&&
2094 result
!= ISC_R_RANGE
) {
2095 dns_zone_log(zone
, ISC_LOG_ERROR
,
2096 "journal rollforward failed: %s",
2097 dns_result_totext(result
));
2100 if (result
== ISC_R_NOTFOUND
|| result
== ISC_R_RANGE
) {
2101 dns_zone_log(zone
, ISC_LOG_ERROR
,
2102 "journal rollforward failed: "
2103 "journal out of sync with zone");
2106 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
2107 "journal rollforward completed "
2109 dns_result_totext(result
));
2110 if (result
== ISC_R_SUCCESS
)
2111 needdump
= ISC_TRUE
;
2114 zone
->loadtime
= loadtime
;
2116 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "loaded");
2119 * Obtain ns, soa and cname counts for top of zone.
2122 result
= zone_get_from_db(zone
, db
, &nscount
, &soacount
, &serial
,
2123 &refresh
, &retry
, &expire
, &minimum
,
2125 if (result
!= ISC_R_SUCCESS
) {
2126 dns_zone_log(zone
, ISC_LOG_ERROR
,
2127 "could not find NS and/or SOA records");
2131 * Master / Slave / Stub zones require both NS and SOA records at
2132 * the top of the zone.
2135 switch (zone
->type
) {
2136 case dns_zone_master
:
2137 case dns_zone_slave
:
2139 if (soacount
!= 1) {
2140 dns_zone_log(zone
, ISC_LOG_ERROR
,
2141 "has %d SOA records", soacount
);
2142 result
= DNS_R_BADZONE
;
2145 dns_zone_log(zone
, ISC_LOG_ERROR
,
2146 "has no NS records");
2147 result
= DNS_R_BADZONE
;
2149 if (result
!= ISC_R_SUCCESS
)
2151 if (zone
->type
== dns_zone_master
&& errors
!= 0) {
2152 result
= DNS_R_BADZONE
;
2155 if (zone
->type
== dns_zone_master
&&
2156 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKINTEGRITY
) &&
2157 !integrity_checks(zone
, db
)) {
2158 result
= DNS_R_BADZONE
;
2162 if (zone
->db
!= NULL
) {
2164 * This is checked in zone_replacedb() for slave zones
2165 * as they don't reload from disk.
2167 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
) &&
2168 !isc_serial_gt(serial
, zone
->serial
)) {
2169 isc_uint32_t serialmin
, serialmax
;
2171 INSIST(zone
->type
== dns_zone_master
);
2173 serialmin
= (zone
->serial
+ 1) & 0xffffffffU
;
2174 serialmax
= (zone
->serial
+ 0x7fffffffU
) &
2176 dns_zone_log(zone
, ISC_LOG_ERROR
,
2177 "ixfr-from-differences: "
2178 "new serial (%u) out of range "
2179 "[%u - %u]", serial
, serialmin
,
2181 result
= DNS_R_BADZONE
;
2183 } else if (!isc_serial_ge(serial
, zone
->serial
))
2184 dns_zone_log(zone
, ISC_LOG_ERROR
,
2185 "zone serial has gone backwards");
2186 else if (serial
== zone
->serial
&& !hasinclude
)
2187 dns_zone_log(zone
, ISC_LOG_ERROR
,
2188 "zone serial unchanged. "
2189 "zone may fail to transfer "
2192 zone
->serial
= serial
;
2193 zone
->refresh
= RANGE(refresh
,
2194 zone
->minrefresh
, zone
->maxrefresh
);
2195 zone
->retry
= RANGE(retry
,
2196 zone
->minretry
, zone
->maxretry
);
2197 zone
->expire
= RANGE(expire
, zone
->refresh
+ zone
->retry
,
2199 zone
->minimum
= minimum
;
2200 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
2202 if (zone
->type
== dns_zone_slave
||
2203 zone
->type
== dns_zone_stub
) {
2207 result
= isc_file_getmodtime(zone
->journal
, &t
);
2208 if (result
!= ISC_R_SUCCESS
)
2209 result
= isc_file_getmodtime(zone
->masterfile
,
2211 if (result
== ISC_R_SUCCESS
)
2212 DNS_ZONE_TIME_ADD(&t
, zone
->expire
,
2215 DNS_ZONE_TIME_ADD(&now
, zone
->retry
,
2218 delay
= isc_random_jitter(zone
->retry
,
2219 (zone
->retry
* 3) / 4);
2220 DNS_ZONE_TIME_ADD(&now
, delay
, &zone
->refreshtime
);
2221 if (isc_time_compare(&zone
->refreshtime
,
2222 &zone
->expiretime
) >= 0)
2223 zone
->refreshtime
= now
;
2227 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
2228 "unexpected zone type %d", zone
->type
);
2229 result
= ISC_R_UNEXPECTED
;
2234 * Check for weak DNSKEY's.
2236 if (zone
->type
== dns_zone_master
)
2237 zone_check_dnskeys(zone
, db
);
2240 /* destroy notification example. */
2242 isc_event_t
*e
= isc_event_allocate(zone
->mctx
, NULL
,
2243 DNS_EVENT_DBDESTROYED
,
2244 dns_zonemgr_dbdestroyed
,
2246 sizeof(isc_event_t
));
2247 dns_db_ondestroy(db
, zone
->task
, &e
);
2251 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
2252 if (zone
->db
!= NULL
) {
2253 result
= zone_replacedb(zone
, db
, ISC_FALSE
);
2254 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
2255 if (result
!= ISC_R_SUCCESS
)
2258 zone_attachdb(zone
, db
);
2259 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
2260 DNS_ZONE_SETFLAG(zone
,
2261 DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
2263 result
= ISC_R_SUCCESS
;
2265 zone_needdump(zone
, DNS_DUMP_DELAY
);
2266 if (zone
->task
!= NULL
)
2267 zone_settimer(zone
, &now
);
2269 if (! dns_db_ispersistent(db
))
2270 dns_zone_log(zone
, ISC_LOG_INFO
, "loaded serial %u%s",
2272 dns_db_issecure(db
) ? " (signed)" : "");
2277 if (zone
->type
== dns_zone_slave
||
2278 zone
->type
== dns_zone_stub
) {
2279 if (zone
->journal
!= NULL
)
2280 zone_saveunique(zone
, zone
->journal
, "jn-XXXXXXXX");
2281 if (zone
->masterfile
!= NULL
)
2282 zone_saveunique(zone
, zone
->masterfile
, "db-XXXXXXXX");
2284 /* Mark the zone for immediate refresh. */
2285 zone
->refreshtime
= now
;
2286 if (zone
->task
!= NULL
)
2287 zone_settimer(zone
, &now
);
2288 result
= ISC_R_SUCCESS
;
2293 static isc_boolean_t
2294 exit_check(dns_zone_t
*zone
) {
2296 REQUIRE(LOCKED_ZONE(zone
));
2298 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SHUTDOWN
) &&
2302 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2304 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
2310 static isc_boolean_t
2311 zone_check_ns(dns_zone_t
*zone
, dns_db_t
*db
, dns_name_t
*name
) {
2312 isc_result_t result
;
2313 char namebuf
[DNS_NAME_FORMATSIZE
];
2314 char altbuf
[DNS_NAME_FORMATSIZE
];
2315 dns_fixedname_t fixed
;
2316 dns_name_t
*foundname
;
2319 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOCHECKNS
))
2322 if (zone
->type
== dns_zone_master
)
2323 level
= ISC_LOG_ERROR
;
2325 level
= ISC_LOG_WARNING
;
2327 dns_fixedname_init(&fixed
);
2328 foundname
= dns_fixedname_name(&fixed
);
2330 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_a
,
2331 0, 0, NULL
, foundname
, NULL
, NULL
);
2332 if (result
== ISC_R_SUCCESS
)
2335 if (result
== DNS_R_NXRRSET
) {
2336 result
= dns_db_find(db
, name
, NULL
, dns_rdatatype_aaaa
,
2337 0, 0, NULL
, foundname
, NULL
, NULL
);
2338 if (result
== ISC_R_SUCCESS
)
2342 dns_name_format(name
, namebuf
, sizeof namebuf
);
2343 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NXDOMAIN
||
2344 result
== DNS_R_EMPTYNAME
) {
2345 dns_zone_log(zone
, level
,
2346 "NS '%s' has no address records (A or AAAA)",
2348 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2352 if (result
== DNS_R_CNAME
) {
2353 dns_zone_log(zone
, level
, "NS '%s' is a CNAME (illegal)",
2355 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2359 if (result
== DNS_R_DNAME
) {
2360 dns_name_format(foundname
, altbuf
, sizeof altbuf
);
2361 dns_zone_log(zone
, level
,
2362 "NS '%s' is below a DNAME '%s' (illegal)",
2364 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2372 zone_count_ns_rr(dns_zone_t
*zone
, dns_db_t
*db
, dns_dbnode_t
*node
,
2373 dns_dbversion_t
*version
, unsigned int *nscount
,
2374 unsigned int *errors
)
2376 isc_result_t result
;
2377 unsigned int count
= 0;
2378 unsigned int ecount
= 0;
2379 dns_rdataset_t rdataset
;
2383 dns_rdataset_init(&rdataset
);
2384 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_ns
,
2385 dns_rdatatype_none
, 0, &rdataset
, NULL
);
2386 if (result
== ISC_R_NOTFOUND
)
2388 if (result
!= ISC_R_SUCCESS
)
2389 goto invalidate_rdataset
;
2391 result
= dns_rdataset_first(&rdataset
);
2392 while (result
== ISC_R_SUCCESS
) {
2393 if (errors
!= NULL
&& zone
->rdclass
== dns_rdataclass_in
&&
2394 (zone
->type
== dns_zone_master
||
2395 zone
->type
== dns_zone_slave
)) {
2396 dns_rdata_init(&rdata
);
2397 dns_rdataset_current(&rdataset
, &rdata
);
2398 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
2399 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2400 if (dns_name_issubdomain(&ns
.name
, &zone
->origin
) &&
2401 !zone_check_ns(zone
, db
, &ns
.name
))
2405 result
= dns_rdataset_next(&rdataset
);
2407 dns_rdataset_disassociate(&rdataset
);
2410 if (nscount
!= NULL
)
2415 result
= ISC_R_SUCCESS
;
2417 invalidate_rdataset
:
2418 dns_rdataset_invalidate(&rdataset
);
2424 zone_load_soa_rr(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
2425 unsigned int *soacount
,
2426 isc_uint32_t
*serial
, isc_uint32_t
*refresh
,
2427 isc_uint32_t
*retry
, isc_uint32_t
*expire
,
2428 isc_uint32_t
*minimum
)
2430 isc_result_t result
;
2432 dns_rdataset_t rdataset
;
2433 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2434 dns_rdata_soa_t soa
;
2436 dns_rdataset_init(&rdataset
);
2437 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_soa
,
2438 dns_rdatatype_none
, 0, &rdataset
, NULL
);
2439 if (result
== ISC_R_NOTFOUND
) {
2440 if (soacount
!= NULL
)
2444 if (refresh
!= NULL
)
2450 if (minimum
!= NULL
)
2452 result
= ISC_R_SUCCESS
;
2453 goto invalidate_rdataset
;
2455 if (result
!= ISC_R_SUCCESS
)
2456 goto invalidate_rdataset
;
2459 result
= dns_rdataset_first(&rdataset
);
2460 while (result
== ISC_R_SUCCESS
) {
2461 dns_rdata_init(&rdata
);
2462 dns_rdataset_current(&rdataset
, &rdata
);
2465 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
2466 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2469 result
= dns_rdataset_next(&rdataset
);
2470 dns_rdata_reset(&rdata
);
2472 dns_rdataset_disassociate(&rdataset
);
2474 if (soacount
!= NULL
)
2479 *serial
= soa
.serial
;
2480 if (refresh
!= NULL
)
2481 *refresh
= soa
.refresh
;
2485 *expire
= soa
.expire
;
2486 if (minimum
!= NULL
)
2487 *minimum
= soa
.minimum
;
2490 result
= ISC_R_SUCCESS
;
2492 invalidate_rdataset
:
2493 dns_rdataset_invalidate(&rdataset
);
2499 * zone must be locked.
2502 zone_get_from_db(dns_zone_t
*zone
, dns_db_t
*db
, unsigned int *nscount
,
2503 unsigned int *soacount
, isc_uint32_t
*serial
,
2504 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
2505 isc_uint32_t
*expire
, isc_uint32_t
*minimum
,
2506 unsigned int *errors
)
2508 dns_dbversion_t
*version
;
2509 isc_result_t result
;
2510 isc_result_t answer
= ISC_R_SUCCESS
;
2513 REQUIRE(db
!= NULL
);
2514 REQUIRE(zone
!= NULL
);
2517 dns_db_currentversion(db
, &version
);
2520 result
= dns_db_findnode(db
, &zone
->origin
, ISC_FALSE
, &node
);
2521 if (result
!= ISC_R_SUCCESS
) {
2526 if (nscount
!= NULL
|| errors
!= NULL
) {
2527 result
= zone_count_ns_rr(zone
, db
, node
, version
,
2529 if (result
!= ISC_R_SUCCESS
)
2533 if (soacount
!= NULL
|| serial
!= NULL
|| refresh
!= NULL
2534 || retry
!= NULL
|| expire
!= NULL
|| minimum
!= NULL
) {
2535 result
= zone_load_soa_rr(db
, node
, version
, soacount
,
2536 serial
, refresh
, retry
, expire
,
2538 if (result
!= ISC_R_SUCCESS
)
2542 dns_db_detachnode(db
, &node
);
2544 dns_db_closeversion(db
, &version
, ISC_FALSE
);
2550 dns_zone_attach(dns_zone_t
*source
, dns_zone_t
**target
) {
2551 REQUIRE(DNS_ZONE_VALID(source
));
2552 REQUIRE(target
!= NULL
&& *target
== NULL
);
2553 isc_refcount_increment(&source
->erefs
, NULL
);
2558 dns_zone_detach(dns_zone_t
**zonep
) {
2561 isc_boolean_t free_now
= ISC_FALSE
;
2563 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
2567 isc_refcount_decrement(&zone
->erefs
, &refs
);
2572 * We just detached the last external reference.
2574 if (zone
->task
!= NULL
) {
2576 * This zone is being managed. Post
2577 * its control event and let it clean
2578 * up synchronously in the context of
2581 isc_event_t
*ev
= &zone
->ctlevent
;
2582 isc_task_send(zone
->task
, &ev
);
2585 * This zone is not being managed; it has
2586 * no task and can have no outstanding
2587 * events. Free it immediately.
2590 * Unmanaged zones should not have non-null views;
2591 * we have no way of detaching from the view here
2592 * without causing deadlock because this code is called
2593 * with the view already locked.
2595 INSIST(zone
->view
== NULL
);
2596 free_now
= ISC_TRUE
;
2606 dns_zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
2607 REQUIRE(DNS_ZONE_VALID(source
));
2608 REQUIRE(target
!= NULL
&& *target
== NULL
);
2610 zone_iattach(source
, target
);
2611 UNLOCK_ZONE(source
);
2615 zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
2618 * 'source' locked by caller.
2620 REQUIRE(LOCKED_ZONE(source
));
2621 REQUIRE(DNS_ZONE_VALID(source
));
2622 REQUIRE(target
!= NULL
&& *target
== NULL
);
2623 INSIST(source
->irefs
+ isc_refcount_current(&source
->erefs
) > 0);
2625 INSIST(source
->irefs
!= 0);
2630 zone_idetach(dns_zone_t
**zonep
) {
2634 * 'zone' locked by caller.
2636 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
2638 REQUIRE(LOCKED_ZONE(*zonep
));
2641 INSIST(zone
->irefs
> 0);
2643 INSIST(zone
->irefs
+ isc_refcount_current(&zone
->erefs
) > 0);
2647 dns_zone_idetach(dns_zone_t
**zonep
) {
2649 isc_boolean_t free_needed
;
2651 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
2656 INSIST(zone
->irefs
> 0);
2658 free_needed
= exit_check(zone
);
2665 dns_zone_getmctx(dns_zone_t
*zone
) {
2666 REQUIRE(DNS_ZONE_VALID(zone
));
2668 return (zone
->mctx
);
2672 dns_zone_getmgr(dns_zone_t
*zone
) {
2673 REQUIRE(DNS_ZONE_VALID(zone
));
2675 return (zone
->zmgr
);
2679 dns_zone_setflag(dns_zone_t
*zone
, unsigned int flags
, isc_boolean_t value
) {
2680 REQUIRE(DNS_ZONE_VALID(zone
));
2684 DNS_ZONE_SETFLAG(zone
, flags
);
2686 DNS_ZONE_CLRFLAG(zone
, flags
);
2691 dns_zone_setoption(dns_zone_t
*zone
, unsigned int option
, isc_boolean_t value
)
2693 REQUIRE(DNS_ZONE_VALID(zone
));
2697 zone
->options
|= option
;
2699 zone
->options
&= ~option
;
2704 dns_zone_getoptions(dns_zone_t
*zone
) {
2706 REQUIRE(DNS_ZONE_VALID(zone
));
2708 return (zone
->options
);
2712 dns_zone_setxfrsource4(dns_zone_t
*zone
, const isc_sockaddr_t
*xfrsource
) {
2713 REQUIRE(DNS_ZONE_VALID(zone
));
2716 zone
->xfrsource4
= *xfrsource
;
2719 return (ISC_R_SUCCESS
);
2723 dns_zone_getxfrsource4(dns_zone_t
*zone
) {
2724 REQUIRE(DNS_ZONE_VALID(zone
));
2725 return (&zone
->xfrsource4
);
2729 dns_zone_setxfrsource6(dns_zone_t
*zone
, const isc_sockaddr_t
*xfrsource
) {
2730 REQUIRE(DNS_ZONE_VALID(zone
));
2733 zone
->xfrsource6
= *xfrsource
;
2736 return (ISC_R_SUCCESS
);
2740 dns_zone_getxfrsource6(dns_zone_t
*zone
) {
2741 REQUIRE(DNS_ZONE_VALID(zone
));
2742 return (&zone
->xfrsource6
);
2746 dns_zone_setaltxfrsource4(dns_zone_t
*zone
,
2747 const isc_sockaddr_t
*altxfrsource
)
2749 REQUIRE(DNS_ZONE_VALID(zone
));
2752 zone
->altxfrsource4
= *altxfrsource
;
2755 return (ISC_R_SUCCESS
);
2759 dns_zone_getaltxfrsource4(dns_zone_t
*zone
) {
2760 REQUIRE(DNS_ZONE_VALID(zone
));
2761 return (&zone
->altxfrsource4
);
2765 dns_zone_setaltxfrsource6(dns_zone_t
*zone
,
2766 const isc_sockaddr_t
*altxfrsource
)
2768 REQUIRE(DNS_ZONE_VALID(zone
));
2771 zone
->altxfrsource6
= *altxfrsource
;
2774 return (ISC_R_SUCCESS
);
2778 dns_zone_getaltxfrsource6(dns_zone_t
*zone
) {
2779 REQUIRE(DNS_ZONE_VALID(zone
));
2780 return (&zone
->altxfrsource6
);
2784 dns_zone_setnotifysrc4(dns_zone_t
*zone
, const isc_sockaddr_t
*notifysrc
) {
2785 REQUIRE(DNS_ZONE_VALID(zone
));
2788 zone
->notifysrc4
= *notifysrc
;
2791 return (ISC_R_SUCCESS
);
2795 dns_zone_getnotifysrc4(dns_zone_t
*zone
) {
2796 REQUIRE(DNS_ZONE_VALID(zone
));
2797 return (&zone
->notifysrc4
);
2801 dns_zone_setnotifysrc6(dns_zone_t
*zone
, const isc_sockaddr_t
*notifysrc
) {
2802 REQUIRE(DNS_ZONE_VALID(zone
));
2805 zone
->notifysrc6
= *notifysrc
;
2808 return (ISC_R_SUCCESS
);
2812 dns_zone_getnotifysrc6(dns_zone_t
*zone
) {
2813 REQUIRE(DNS_ZONE_VALID(zone
));
2814 return (&zone
->notifysrc6
);
2818 dns_zone_setalsonotify(dns_zone_t
*zone
, const isc_sockaddr_t
*notify
,
2821 isc_sockaddr_t
*new;
2823 REQUIRE(DNS_ZONE_VALID(zone
));
2824 REQUIRE(count
== 0 || notify
!= NULL
);
2827 if (zone
->notify
!= NULL
) {
2828 isc_mem_put(zone
->mctx
, zone
->notify
,
2829 zone
->notifycnt
* sizeof(*new));
2830 zone
->notify
= NULL
;
2831 zone
->notifycnt
= 0;
2834 new = isc_mem_get(zone
->mctx
, count
* sizeof(*new));
2837 return (ISC_R_NOMEMORY
);
2839 memcpy(new, notify
, count
* sizeof(*new));
2841 zone
->notifycnt
= count
;
2844 return (ISC_R_SUCCESS
);
2848 dns_zone_setmasters(dns_zone_t
*zone
, const isc_sockaddr_t
*masters
,
2851 isc_result_t result
;
2853 result
= dns_zone_setmasterswithkeys(zone
, masters
, NULL
, count
);
2857 static isc_boolean_t
2858 same_masters(const isc_sockaddr_t
*old
, const isc_sockaddr_t
*new,
2863 for (i
= 0; i
< count
; i
++)
2864 if (!isc_sockaddr_equal(&old
[i
], &new[i
]))
2869 static isc_boolean_t
2870 same_keynames(dns_name_t
**old
, dns_name_t
**new, isc_uint32_t count
) {
2873 if (old
== NULL
&& new == NULL
)
2875 if (old
== NULL
|| new == NULL
)
2878 for (i
= 0; i
< count
; i
++) {
2879 if (old
[i
] == NULL
&& new[i
] == NULL
)
2881 if (old
[i
] == NULL
|| new[i
] == NULL
||
2882 !dns_name_equal(old
[i
], new[i
]))
2889 dns_zone_setmasterswithkeys(dns_zone_t
*zone
,
2890 const isc_sockaddr_t
*masters
,
2891 dns_name_t
**keynames
,
2894 isc_sockaddr_t
*new;
2895 isc_result_t result
= ISC_R_SUCCESS
;
2896 dns_name_t
**newname
;
2897 isc_boolean_t
*newok
;
2900 REQUIRE(DNS_ZONE_VALID(zone
));
2901 REQUIRE(count
== 0 || masters
!= NULL
);
2902 if (keynames
!= NULL
) {
2903 REQUIRE(count
!= 0);
2908 * The refresh code assumes that 'masters' wouldn't change under it.
2909 * If it will change then kill off any current refresh in progress
2910 * and update the masters info. If it won't change then we can just
2913 if (count
!= zone
->masterscnt
||
2914 !same_masters(zone
->masters
, masters
, count
) ||
2915 !same_keynames(zone
->masterkeynames
, keynames
, count
)) {
2916 if (zone
->request
!= NULL
)
2917 dns_request_cancel(zone
->request
);
2920 if (zone
->masters
!= NULL
) {
2921 isc_mem_put(zone
->mctx
, zone
->masters
,
2922 zone
->masterscnt
* sizeof(*new));
2923 zone
->masters
= NULL
;
2925 if (zone
->masterkeynames
!= NULL
) {
2926 for (i
= 0; i
< zone
->masterscnt
; i
++) {
2927 if (zone
->masterkeynames
[i
] != NULL
) {
2928 dns_name_free(zone
->masterkeynames
[i
],
2930 isc_mem_put(zone
->mctx
,
2931 zone
->masterkeynames
[i
],
2932 sizeof(dns_name_t
));
2933 zone
->masterkeynames
[i
] = NULL
;
2936 isc_mem_put(zone
->mctx
, zone
->masterkeynames
,
2937 zone
->masterscnt
* sizeof(dns_name_t
*));
2938 zone
->masterkeynames
= NULL
;
2940 if (zone
->mastersok
!= NULL
) {
2941 isc_mem_put(zone
->mctx
, zone
->mastersok
,
2942 zone
->masterscnt
* sizeof(isc_boolean_t
));
2943 zone
->mastersok
= NULL
;
2945 zone
->masterscnt
= 0;
2947 * If count == 0, don't allocate any space for masters, mastersok or
2948 * keynames so internally, those pointers are NULL if count == 0
2954 * masters must contain count elements!
2956 new = isc_mem_get(zone
->mctx
, count
* sizeof(*new));
2958 result
= ISC_R_NOMEMORY
;
2961 memcpy(new, masters
, count
* sizeof(*new));
2964 * Similarly for mastersok.
2966 newok
= isc_mem_get(zone
->mctx
, count
* sizeof(*newok
));
2967 if (newok
== NULL
) {
2968 result
= ISC_R_NOMEMORY
;
2969 isc_mem_put(zone
->mctx
, new, count
* sizeof(*new));
2972 for (i
= 0; i
< count
; i
++)
2973 newok
[i
] = ISC_FALSE
;
2976 * if keynames is non-NULL, it must contain count elements!
2979 if (keynames
!= NULL
) {
2980 newname
= isc_mem_get(zone
->mctx
, count
* sizeof(*newname
));
2981 if (newname
== NULL
) {
2982 result
= ISC_R_NOMEMORY
;
2983 isc_mem_put(zone
->mctx
, new, count
* sizeof(*new));
2984 isc_mem_put(zone
->mctx
, newok
, count
* sizeof(*newok
));
2987 for (i
= 0; i
< count
; i
++)
2989 for (i
= 0; i
< count
; i
++) {
2990 if (keynames
[i
] != NULL
) {
2991 newname
[i
] = isc_mem_get(zone
->mctx
,
2992 sizeof(dns_name_t
));
2993 if (newname
[i
] == NULL
)
2995 dns_name_init(newname
[i
], NULL
);
2996 result
= dns_name_dup(keynames
[i
], zone
->mctx
,
2998 if (result
!= ISC_R_SUCCESS
) {
3000 for (i
= 0; i
< count
; i
++)
3001 if (newname
[i
] != NULL
)
3005 isc_mem_put(zone
->mctx
, new,
3006 count
* sizeof(*new));
3007 isc_mem_put(zone
->mctx
, newok
,
3008 count
* sizeof(*newok
));
3009 isc_mem_put(zone
->mctx
, newname
,
3010 count
* sizeof(*newname
));
3018 * Everything is ok so attach to the zone.
3020 zone
->masters
= new;
3021 zone
->mastersok
= newok
;
3022 zone
->masterkeynames
= newname
;
3023 zone
->masterscnt
= count
;
3024 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
3032 dns_zone_getdb(dns_zone_t
*zone
, dns_db_t
**dpb
) {
3033 isc_result_t result
= ISC_R_SUCCESS
;
3035 REQUIRE(DNS_ZONE_VALID(zone
));
3037 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
3038 if (zone
->db
== NULL
)
3039 result
= DNS_R_NOTLOADED
;
3041 dns_db_attach(zone
->db
, dpb
);
3042 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
3048 * Co-ordinates the starting of routine jobs.
3052 dns_zone_maintenance(dns_zone_t
*zone
) {
3053 const char me
[] = "dns_zone_maintenance";
3056 REQUIRE(DNS_ZONE_VALID(zone
));
3061 zone_settimer(zone
, &now
);
3065 static inline isc_boolean_t
3066 was_dumping(dns_zone_t
*zone
) {
3067 isc_boolean_t dumping
;
3069 REQUIRE(LOCKED_ZONE(zone
));
3071 dumping
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
);
3072 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
3074 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
3075 isc_time_settoepoch(&zone
->dumptime
);
3081 zone_maintenance(dns_zone_t
*zone
) {
3082 const char me
[] = "zone_maintenance";
3084 isc_result_t result
;
3085 isc_boolean_t dumping
;
3087 REQUIRE(DNS_ZONE_VALID(zone
));
3091 * Configuring the view of this zone may have
3092 * failed, for example because the config file
3093 * had a syntax error. In that case, the view
3094 * adb or resolver, and we had better not try
3095 * to do maintenance on it.
3097 if (zone
->view
== NULL
|| zone
->view
->adb
== NULL
)
3105 switch (zone
->type
) {
3106 case dns_zone_slave
:
3109 if (isc_time_compare(&now
, &zone
->expiretime
) >= 0 &&
3110 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
3112 zone
->refreshtime
= now
;
3123 switch (zone
->type
) {
3124 case dns_zone_slave
:
3126 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
) &&
3127 isc_time_compare(&now
, &zone
->refreshtime
) >= 0)
3128 dns_zone_refresh(zone
);
3135 * Do we need to consolidate the backing store?
3137 switch (zone
->type
) {
3138 case dns_zone_master
:
3139 case dns_zone_slave
:
3141 if (zone
->masterfile
!= NULL
&&
3142 isc_time_compare(&now
, &zone
->dumptime
) >= 0 &&
3143 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
3144 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
)) {
3145 dumping
= was_dumping(zone
);
3150 result
= zone_dump(zone
, ISC_TRUE
); /* task locked */
3151 if (result
!= ISC_R_SUCCESS
)
3152 dns_zone_log(zone
, ISC_LOG_WARNING
,
3154 dns_result_totext(result
));
3162 * Do we need to send out notify messages?
3164 switch (zone
->type
) {
3165 case dns_zone_master
:
3166 case dns_zone_slave
:
3167 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
) &&
3168 isc_time_compare(&now
, &zone
->notifytime
) >= 0)
3169 zone_notify(zone
, &now
);
3174 zone_settimer(zone
, &now
);
3178 dns_zone_markdirty(dns_zone_t
*zone
) {
3181 zone_needdump(zone
, DNS_DUMP_DELAY
);
3186 dns_zone_expire(dns_zone_t
*zone
) {
3187 REQUIRE(DNS_ZONE_VALID(zone
));
3195 zone_expire(dns_zone_t
*zone
) {
3197 * 'zone' locked by caller.
3200 REQUIRE(LOCKED_ZONE(zone
));
3202 dns_zone_log(zone
, ISC_LOG_WARNING
, "expired");
3204 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXPIRED
);
3205 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
3206 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
3207 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
3212 dns_zone_refresh(dns_zone_t
*zone
) {
3214 isc_uint32_t oldflags
;
3216 isc_result_t result
;
3218 REQUIRE(DNS_ZONE_VALID(zone
));
3220 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
3224 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
3225 * in progress at a time.
3229 oldflags
= zone
->flags
;
3230 if (zone
->masterscnt
== 0) {
3231 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
3232 if ((oldflags
& DNS_ZONEFLG_NOMASTERS
) == 0)
3233 dns_zone_log(zone
, ISC_LOG_ERROR
,
3234 "cannot refresh: no masters");
3237 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
3238 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
3239 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
3240 if ((oldflags
& (DNS_ZONEFLG_REFRESH
|DNS_ZONEFLG_LOADING
)) != 0)
3244 * Set the next refresh time as if refresh check has failed.
3245 * Setting this to the retry time will do that. XXXMLG
3246 * If we are successful it will be reset using zone->refresh.
3248 isc_interval_set(&i
, isc_random_jitter(zone
->retry
, zone
->retry
/ 4),
3250 result
= isc_time_nowplusinterval(&zone
->refreshtime
, &i
);
3251 if (result
|= ISC_R_SUCCESS
)
3252 dns_zone_log(zone
, ISC_LOG_WARNING
,
3253 "isc_time_nowplusinterval() failed: %s",
3254 dns_result_totext(result
));
3257 * When lacking user-specified timer values from the SOA,
3258 * do exponential backoff of the retry time up to a
3259 * maximum of six hours.
3261 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HAVETIMERS
))
3262 zone
->retry
= ISC_MIN(zone
->retry
* 2, 6 * 3600);
3264 zone
->curmaster
= 0;
3265 for (j
= 0; j
< zone
->masterscnt
; j
++)
3266 zone
->mastersok
[j
] = ISC_FALSE
;
3267 /* initiate soa query */
3268 queue_soa_query(zone
);
3274 dns_zone_flush(dns_zone_t
*zone
) {
3275 isc_result_t result
= ISC_R_SUCCESS
;
3276 isc_boolean_t dumping
;
3278 REQUIRE(DNS_ZONE_VALID(zone
));
3281 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FLUSH
);
3282 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
3283 zone
->masterfile
!= NULL
) {
3284 result
= ISC_R_ALREADYRUNNING
;
3285 dumping
= was_dumping(zone
);
3290 result
= zone_dump(zone
, ISC_FALSE
); /* Unknown task. */
3295 dns_zone_dump(dns_zone_t
*zone
) {
3296 isc_result_t result
= ISC_R_ALREADYRUNNING
;
3297 isc_boolean_t dumping
;
3299 REQUIRE(DNS_ZONE_VALID(zone
));
3302 dumping
= was_dumping(zone
);
3305 result
= zone_dump(zone
, ISC_FALSE
); /* Unknown task. */
3310 zone_needdump(dns_zone_t
*zone
, unsigned int delay
) {
3311 isc_time_t dumptime
;
3315 * 'zone' locked by caller
3318 REQUIRE(DNS_ZONE_VALID(zone
));
3319 REQUIRE(LOCKED_ZONE(zone
));
3322 * Do we have a place to dump to and are we loaded?
3324 if (zone
->masterfile
== NULL
||
3325 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) == 0)
3329 /* add some noise */
3330 DNS_ZONE_JITTER_ADD(&now
, delay
, &dumptime
);
3332 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
3333 if (isc_time_isepoch(&zone
->dumptime
) ||
3334 isc_time_compare(&zone
->dumptime
, &dumptime
) > 0)
3335 zone
->dumptime
= dumptime
;
3336 if (zone
->task
!= NULL
)
3337 zone_settimer(zone
, &now
);
3341 dump_done(void *arg
, isc_result_t result
) {
3342 const char me
[] = "dump_done";
3343 dns_zone_t
*zone
= arg
;
3345 dns_dbversion_t
*version
;
3346 isc_boolean_t again
= ISC_FALSE
;
3347 isc_boolean_t compact
= ISC_FALSE
;
3348 isc_uint32_t serial
;
3349 isc_result_t tresult
;
3351 REQUIRE(DNS_ZONE_VALID(zone
));
3355 if (result
== ISC_R_SUCCESS
&& zone
->journal
!= NULL
&&
3356 zone
->journalsize
!= -1) {
3359 * We don't own these, zone->dctx must stay valid.
3361 db
= dns_dumpctx_db(zone
->dctx
);
3362 version
= dns_dumpctx_version(zone
->dctx
);
3364 tresult
= dns_db_getsoaserial(db
, version
, &serial
);
3366 * Note: we are task locked here so we can test
3369 if (tresult
== ISC_R_SUCCESS
&& zone
->xfr
== NULL
) {
3370 tresult
= dns_journal_compact(zone
->mctx
,
3377 case ISC_R_NOTFOUND
:
3378 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
3379 "dns_journal_compact: %s",
3380 dns_result_totext(tresult
));
3383 dns_zone_log(zone
, ISC_LOG_ERROR
,
3384 "dns_journal_compact failed: %s",
3385 dns_result_totext(tresult
));
3388 } else if (tresult
== ISC_R_SUCCESS
) {
3390 zone
->compact_serial
= serial
;
3395 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
3397 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
);
3398 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_CANCELED
) {
3400 * Try again in a short while.
3402 zone_needdump(zone
, DNS_DUMP_DELAY
);
3403 } else if (result
== ISC_R_SUCCESS
&&
3404 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
3405 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
3406 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
3407 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
3408 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
3409 isc_time_settoepoch(&zone
->dumptime
);
3411 } else if (result
== ISC_R_SUCCESS
)
3412 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FLUSH
);
3414 if (zone
->dctx
!= NULL
)
3415 dns_dumpctx_detach(&zone
->dctx
);
3416 zonemgr_putio(&zone
->writeio
);
3419 (void)zone_dump(zone
, ISC_FALSE
);
3420 dns_zone_idetach(&zone
);
3424 zone_dump(dns_zone_t
*zone
, isc_boolean_t compact
) {
3425 const char me
[] = "zone_dump";
3426 isc_result_t result
;
3427 dns_dbversion_t
*version
= NULL
;
3428 isc_boolean_t again
;
3429 dns_db_t
*db
= NULL
;
3430 char *masterfile
= NULL
;
3431 dns_masterformat_t masterformat
= dns_masterformat_none
;
3434 * 'compact' MUST only be set if we are task locked.
3437 REQUIRE(DNS_ZONE_VALID(zone
));
3441 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
3442 if (zone
->db
!= NULL
)
3443 dns_db_attach(zone
->db
, &db
);
3444 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
3446 if (zone
->masterfile
!= NULL
) {
3447 masterfile
= isc_mem_strdup(zone
->mctx
, zone
->masterfile
);
3448 masterformat
= zone
->masterformat
;
3452 result
= DNS_R_NOTLOADED
;
3455 if (masterfile
== NULL
) {
3456 result
= DNS_R_NOMASTERFILE
;
3461 dns_zone_t
*dummy
= NULL
;
3463 zone_iattach(zone
, &dummy
);
3464 result
= zonemgr_getio(zone
->zmgr
, ISC_FALSE
, zone
->task
,
3465 zone_gotwritehandle
, zone
,
3467 if (result
!= ISC_R_SUCCESS
)
3468 zone_idetach(&dummy
);
3470 result
= DNS_R_CONTINUE
;
3473 dns_db_currentversion(db
, &version
);
3474 result
= dns_master_dump2(zone
->mctx
, db
, version
,
3475 &dns_master_style_default
,
3476 masterfile
, masterformat
);
3477 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3482 if (masterfile
!= NULL
)
3483 isc_mem_free(zone
->mctx
, masterfile
);
3486 if (result
== DNS_R_CONTINUE
)
3487 return (ISC_R_SUCCESS
); /* XXXMPA */
3491 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
3492 if (result
!= ISC_R_SUCCESS
) {
3494 * Try again in a short while.
3496 zone_needdump(zone
, DNS_DUMP_DELAY
);
3497 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
3498 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
3499 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
3500 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
3501 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
3502 isc_time_settoepoch(&zone
->dumptime
);
3505 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FLUSH
);
3514 dumptostream(dns_zone_t
*zone
, FILE *fd
, const dns_master_style_t
*style
,
3515 dns_masterformat_t format
)
3517 isc_result_t result
;
3518 dns_dbversion_t
*version
= NULL
;
3519 dns_db_t
*db
= NULL
;
3521 REQUIRE(DNS_ZONE_VALID(zone
));
3523 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
3524 if (zone
->db
!= NULL
)
3525 dns_db_attach(zone
->db
, &db
);
3526 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
3528 return (DNS_R_NOTLOADED
);
3530 dns_db_currentversion(db
, &version
);
3531 result
= dns_master_dumptostream2(zone
->mctx
, db
, version
, style
,
3533 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3539 dns_zone_dumptostream2(dns_zone_t
*zone
, FILE *fd
, dns_masterformat_t format
,
3540 const dns_master_style_t
*style
) {
3541 return dumptostream(zone
, fd
, style
, format
);
3545 dns_zone_dumptostream(dns_zone_t
*zone
, FILE *fd
) {
3546 return dumptostream(zone
, fd
, &dns_master_style_default
,
3547 dns_masterformat_text
);
3551 dns_zone_fulldumptostream(dns_zone_t
*zone
, FILE *fd
) {
3552 return dumptostream(zone
, fd
, &dns_master_style_full
,
3553 dns_masterformat_text
);
3557 dns_zone_unload(dns_zone_t
*zone
) {
3558 REQUIRE(DNS_ZONE_VALID(zone
));
3566 notify_cancel(dns_zone_t
*zone
) {
3567 dns_notify_t
*notify
;
3570 * 'zone' locked by caller.
3573 REQUIRE(LOCKED_ZONE(zone
));
3575 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
3577 notify
= ISC_LIST_NEXT(notify
, link
)) {
3578 if (notify
->find
!= NULL
)
3579 dns_adb_cancelfind(notify
->find
);
3580 if (notify
->request
!= NULL
)
3581 dns_request_cancel(notify
->request
);
3586 zone_unload(dns_zone_t
*zone
) {
3589 * 'zone' locked by caller.
3592 REQUIRE(LOCKED_ZONE(zone
));
3594 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
3595 zone_detachdb(zone
);
3596 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
3597 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_LOADED
);
3598 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
3602 dns_zone_setminrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
3603 REQUIRE(DNS_ZONE_VALID(zone
));
3606 zone
->minrefresh
= val
;
3610 dns_zone_setmaxrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
3611 REQUIRE(DNS_ZONE_VALID(zone
));
3614 zone
->maxrefresh
= val
;
3618 dns_zone_setminretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
3619 REQUIRE(DNS_ZONE_VALID(zone
));
3622 zone
->minretry
= val
;
3626 dns_zone_setmaxretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
3627 REQUIRE(DNS_ZONE_VALID(zone
));
3630 zone
->maxretry
= val
;
3633 static isc_boolean_t
3634 notify_isqueued(dns_zone_t
*zone
, dns_name_t
*name
, isc_sockaddr_t
*addr
) {
3635 dns_notify_t
*notify
;
3637 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
3639 notify
= ISC_LIST_NEXT(notify
, link
)) {
3640 if (notify
->request
!= NULL
)
3642 if (name
!= NULL
&& dns_name_dynamic(¬ify
->ns
) &&
3643 dns_name_equal(name
, ¬ify
->ns
))
3645 if (addr
!= NULL
&& isc_sockaddr_equal(addr
, ¬ify
->dst
))
3651 static isc_boolean_t
3652 notify_isself(dns_zone_t
*zone
, isc_sockaddr_t
*dst
) {
3653 dns_tsigkey_t
*key
= NULL
;
3656 isc_boolean_t isself
;
3657 isc_netaddr_t dstaddr
;
3659 if (zone
->view
== NULL
|| zone
->isself
== NULL
)
3662 switch (isc_sockaddr_pf(dst
)) {
3664 src
= zone
->notifysrc4
;
3665 isc_sockaddr_any(&any
);
3668 src
= zone
->notifysrc6
;
3669 isc_sockaddr_any6(&any
);
3676 * When sending from any the kernel will assign a source address
3677 * that matches the destination address.
3679 if (isc_sockaddr_eqaddr(&any
, &src
))
3682 isc_netaddr_fromsockaddr(&dstaddr
, dst
);
3683 (void)dns_view_getpeertsig(zone
->view
, &dstaddr
, &key
);
3684 isself
= (zone
->isself
)(zone
->view
, key
, &src
, dst
, zone
->rdclass
,
3687 dns_tsigkey_detach(&key
);
3692 notify_destroy(dns_notify_t
*notify
, isc_boolean_t locked
) {
3696 * Caller holds zone lock.
3698 REQUIRE(DNS_NOTIFY_VALID(notify
));
3700 if (notify
->zone
!= NULL
) {
3702 LOCK_ZONE(notify
->zone
);
3703 REQUIRE(LOCKED_ZONE(notify
->zone
));
3704 if (ISC_LINK_LINKED(notify
, link
))
3705 ISC_LIST_UNLINK(notify
->zone
->notifies
, notify
, link
);
3707 UNLOCK_ZONE(notify
->zone
);
3709 zone_idetach(¬ify
->zone
);
3711 dns_zone_idetach(¬ify
->zone
);
3713 if (notify
->find
!= NULL
)
3714 dns_adb_destroyfind(¬ify
->find
);
3715 if (notify
->request
!= NULL
)
3716 dns_request_destroy(¬ify
->request
);
3717 if (dns_name_dynamic(¬ify
->ns
))
3718 dns_name_free(¬ify
->ns
, notify
->mctx
);
3719 mctx
= notify
->mctx
;
3720 isc_mem_put(notify
->mctx
, notify
, sizeof(*notify
));
3721 isc_mem_detach(&mctx
);
3725 notify_create(isc_mem_t
*mctx
, unsigned int flags
, dns_notify_t
**notifyp
) {
3726 dns_notify_t
*notify
;
3728 REQUIRE(notifyp
!= NULL
&& *notifyp
== NULL
);
3730 notify
= isc_mem_get(mctx
, sizeof(*notify
));
3732 return (ISC_R_NOMEMORY
);
3734 notify
->mctx
= NULL
;
3735 isc_mem_attach(mctx
, ¬ify
->mctx
);
3736 notify
->flags
= flags
;
3737 notify
->zone
= NULL
;
3738 notify
->find
= NULL
;
3739 notify
->request
= NULL
;
3740 isc_sockaddr_any(¬ify
->dst
);
3741 dns_name_init(¬ify
->ns
, NULL
);
3742 ISC_LINK_INIT(notify
, link
);
3743 notify
->magic
= NOTIFY_MAGIC
;
3745 return (ISC_R_SUCCESS
);
3749 * XXXAG should check for DNS_ZONEFLG_EXITING
3752 process_adb_event(isc_task_t
*task
, isc_event_t
*ev
) {
3753 dns_notify_t
*notify
;
3754 isc_eventtype_t result
;
3758 notify
= ev
->ev_arg
;
3759 REQUIRE(DNS_NOTIFY_VALID(notify
));
3760 INSIST(task
== notify
->zone
->task
);
3761 result
= ev
->ev_type
;
3762 isc_event_free(&ev
);
3763 if (result
== DNS_EVENT_ADBMOREADDRESSES
) {
3764 dns_adb_destroyfind(¬ify
->find
);
3765 notify_find_address(notify
);
3768 if (result
== DNS_EVENT_ADBNOMOREADDRESSES
) {
3769 LOCK_ZONE(notify
->zone
);
3770 notify_send(notify
);
3771 UNLOCK_ZONE(notify
->zone
);
3773 notify_destroy(notify
, ISC_FALSE
);
3777 notify_find_address(dns_notify_t
*notify
) {
3778 isc_result_t result
;
3779 unsigned int options
;
3781 REQUIRE(DNS_NOTIFY_VALID(notify
));
3782 options
= DNS_ADBFIND_WANTEVENT
| DNS_ADBFIND_INET
|
3783 DNS_ADBFIND_INET6
| DNS_ADBFIND_RETURNLAME
;
3785 if (notify
->zone
->view
->adb
== NULL
)
3788 result
= dns_adb_createfind(notify
->zone
->view
->adb
,
3790 process_adb_event
, notify
,
3791 ¬ify
->ns
, dns_rootname
, 0,
3793 notify
->zone
->view
->dstport
,
3796 /* Something failed? */
3797 if (result
!= ISC_R_SUCCESS
)
3800 /* More addresses pending? */
3801 if ((notify
->find
->options
& DNS_ADBFIND_WANTEVENT
) != 0)
3804 /* We have as many addresses as we can get. */
3805 LOCK_ZONE(notify
->zone
);
3806 notify_send(notify
);
3807 UNLOCK_ZONE(notify
->zone
);
3810 notify_destroy(notify
, ISC_FALSE
);
3815 notify_send_queue(dns_notify_t
*notify
) {
3817 isc_result_t result
;
3819 e
= isc_event_allocate(notify
->mctx
, NULL
,
3820 DNS_EVENT_NOTIFYSENDTOADDR
,
3822 notify
, sizeof(isc_event_t
));
3824 return (ISC_R_NOMEMORY
);
3826 e
->ev_sender
= NULL
;
3827 result
= isc_ratelimiter_enqueue(notify
->zone
->zmgr
->rl
,
3828 notify
->zone
->task
, &e
);
3829 if (result
!= ISC_R_SUCCESS
)
3835 notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
) {
3836 dns_notify_t
*notify
;
3837 isc_result_t result
;
3838 dns_message_t
*message
= NULL
;
3839 isc_netaddr_t dstip
;
3840 dns_tsigkey_t
*key
= NULL
;
3841 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
3844 isc_boolean_t have_notifysource
= ISC_FALSE
;
3846 notify
= event
->ev_arg
;
3847 REQUIRE(DNS_NOTIFY_VALID(notify
));
3851 LOCK_ZONE(notify
->zone
);
3853 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_LOADED
) == 0) {
3854 result
= ISC_R_CANCELED
;
3858 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0 ||
3859 DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_EXITING
) ||
3860 notify
->zone
->view
->requestmgr
== NULL
||
3861 notify
->zone
->db
== NULL
) {
3862 result
= ISC_R_CANCELED
;
3867 * The raw IPv4 address should also exist. Don't send to the
3870 if (isc_sockaddr_pf(¬ify
->dst
) == PF_INET6
&&
3871 IN6_IS_ADDR_V4MAPPED(¬ify
->dst
.type
.sin6
.sin6_addr
)) {
3872 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
3873 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
3874 "notify: ignoring IPv6 mapped IPV4 address: %s",
3876 result
= ISC_R_CANCELED
;
3880 result
= notify_createmessage(notify
->zone
, notify
->flags
, &message
);
3881 if (result
!= ISC_R_SUCCESS
)
3884 isc_netaddr_fromsockaddr(&dstip
, ¬ify
->dst
);
3885 (void)dns_view_getpeertsig(notify
->zone
->view
, &dstip
, &key
);
3887 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
3888 notify_log(notify
->zone
, ISC_LOG_DEBUG(3), "sending notify to %s",
3890 if (notify
->zone
->view
->peers
!= NULL
) {
3891 dns_peer_t
*peer
= NULL
;
3892 result
= dns_peerlist_peerbyaddr(notify
->zone
->view
->peers
,
3894 if (result
== ISC_R_SUCCESS
) {
3895 result
= dns_peer_getnotifysource(peer
, &src
);
3896 if (result
== ISC_R_SUCCESS
)
3897 have_notifysource
= ISC_TRUE
;
3900 switch (isc_sockaddr_pf(¬ify
->dst
)) {
3902 if (!have_notifysource
)
3903 src
= notify
->zone
->notifysrc4
;
3906 if (!have_notifysource
)
3907 src
= notify
->zone
->notifysrc6
;
3910 result
= ISC_R_NOTIMPLEMENTED
;
3914 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_DIALNOTIFY
))
3916 result
= dns_request_createvia2(notify
->zone
->view
->requestmgr
,
3917 message
, &src
, ¬ify
->dst
, 0, key
,
3918 timeout
* 3, timeout
,
3919 notify
->zone
->task
, notify_done
,
3920 notify
, ¬ify
->request
);
3921 if (result
== ISC_R_SUCCESS
) {
3922 if (isc_sockaddr_pf(¬ify
->dst
) == AF_INET
) {
3923 inc_stats(notify
->zone
,
3924 dns_zonestatscounter_notifyoutv4
);
3926 inc_stats(notify
->zone
,
3927 dns_zonestatscounter_notifyoutv6
);
3933 dns_tsigkey_detach(&key
);
3934 dns_message_destroy(&message
);
3936 UNLOCK_ZONE(notify
->zone
);
3937 if (result
!= ISC_R_SUCCESS
)
3938 notify_destroy(notify
, ISC_FALSE
);
3939 isc_event_free(&event
);
3943 notify_send(dns_notify_t
*notify
) {
3944 dns_adbaddrinfo_t
*ai
;
3946 isc_result_t result
;
3947 dns_notify_t
*new = NULL
;
3950 * Zone lock held by caller.
3952 REQUIRE(DNS_NOTIFY_VALID(notify
));
3953 REQUIRE(LOCKED_ZONE(notify
->zone
));
3955 for (ai
= ISC_LIST_HEAD(notify
->find
->list
);
3957 ai
= ISC_LIST_NEXT(ai
, publink
)) {
3959 if (notify_isqueued(notify
->zone
, NULL
, &dst
))
3961 if (notify_isself(notify
->zone
, &dst
))
3964 result
= notify_create(notify
->mctx
,
3965 (notify
->flags
& DNS_NOTIFY_NOSOA
),
3967 if (result
!= ISC_R_SUCCESS
)
3969 zone_iattach(notify
->zone
, &new->zone
);
3970 ISC_LIST_APPEND(new->zone
->notifies
, new, link
);
3972 result
= notify_send_queue(new);
3973 if (result
!= ISC_R_SUCCESS
)
3980 notify_destroy(new, ISC_TRUE
);
3984 dns_zone_notify(dns_zone_t
*zone
) {
3987 REQUIRE(DNS_ZONE_VALID(zone
));
3990 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
3993 zone_settimer(zone
, &now
);
3998 zone_notify(dns_zone_t
*zone
, isc_time_t
*now
) {
3999 dns_dbnode_t
*node
= NULL
;
4000 dns_db_t
*zonedb
= NULL
;
4001 dns_dbversion_t
*version
= NULL
;
4002 dns_name_t
*origin
= NULL
;
4005 dns_rdata_soa_t soa
;
4006 isc_uint32_t serial
;
4007 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4008 dns_rdataset_t nsrdset
;
4009 dns_rdataset_t soardset
;
4010 isc_result_t result
;
4011 dns_notify_t
*notify
= NULL
;
4014 isc_boolean_t isqueued
;
4015 dns_notifytype_t notifytype
;
4016 unsigned int flags
= 0;
4017 isc_boolean_t loggednotify
= ISC_FALSE
;
4019 REQUIRE(DNS_ZONE_VALID(zone
));
4022 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
4023 notifytype
= zone
->notifytype
;
4024 DNS_ZONE_TIME_ADD(now
, zone
->notifydelay
, &zone
->notifytime
);
4027 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
4030 if (notifytype
== dns_notifytype_no
)
4033 if (notifytype
== dns_notifytype_masteronly
&&
4034 zone
->type
!= dns_zone_master
)
4037 origin
= &zone
->origin
;
4040 * If the zone is dialup we are done as we don't want to send
4041 * the current soa so as to force a refresh query.
4043 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
4044 flags
|= DNS_NOTIFY_NOSOA
;
4049 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
4050 if (zone
->db
!= NULL
)
4051 dns_db_attach(zone
->db
, &zonedb
);
4052 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
4055 dns_db_currentversion(zonedb
, &version
);
4056 result
= dns_db_findnode(zonedb
, origin
, ISC_FALSE
, &node
);
4057 if (result
!= ISC_R_SUCCESS
)
4060 dns_rdataset_init(&soardset
);
4061 result
= dns_db_findrdataset(zonedb
, node
, version
, dns_rdatatype_soa
,
4062 dns_rdatatype_none
, 0, &soardset
, NULL
);
4063 if (result
!= ISC_R_SUCCESS
)
4067 * Find serial and master server's name.
4069 dns_name_init(&master
, NULL
);
4070 result
= dns_rdataset_first(&soardset
);
4071 if (result
!= ISC_R_SUCCESS
)
4073 dns_rdataset_current(&soardset
, &rdata
);
4074 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
4075 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4076 dns_rdata_reset(&rdata
);
4077 result
= dns_name_dup(&soa
.origin
, zone
->mctx
, &master
);
4078 serial
= soa
.serial
;
4079 dns_rdataset_disassociate(&soardset
);
4080 if (result
!= ISC_R_SUCCESS
)
4084 * Enqueue notify requests for 'also-notify' servers.
4087 for (i
= 0; i
< zone
->notifycnt
; i
++) {
4088 dst
= zone
->notify
[i
];
4089 if (notify_isqueued(zone
, NULL
, &dst
))
4091 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
4092 if (result
!= ISC_R_SUCCESS
)
4094 zone_iattach(zone
, ¬ify
->zone
);
4096 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
4097 result
= notify_send_queue(notify
);
4098 if (result
!= ISC_R_SUCCESS
)
4099 notify_destroy(notify
, ISC_TRUE
);
4100 if (!loggednotify
) {
4101 notify_log(zone
, ISC_LOG_INFO
,
4102 "sending notifies (serial %u)",
4104 loggednotify
= ISC_TRUE
;
4110 if (notifytype
== dns_notifytype_explicit
)
4114 * Process NS RRset to generate notifies.
4117 dns_rdataset_init(&nsrdset
);
4118 result
= dns_db_findrdataset(zonedb
, node
, version
, dns_rdatatype_ns
,
4119 dns_rdatatype_none
, 0, &nsrdset
, NULL
);
4120 if (result
!= ISC_R_SUCCESS
)
4123 result
= dns_rdataset_first(&nsrdset
);
4124 while (result
== ISC_R_SUCCESS
) {
4125 dns_rdataset_current(&nsrdset
, &rdata
);
4126 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
4127 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4128 dns_rdata_reset(&rdata
);
4130 * Don't notify the master server unless explicitly
4131 * configured to do so.
4133 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOTIFYTOSOA
) &&
4134 dns_name_compare(&master
, &ns
.name
) == 0) {
4135 result
= dns_rdataset_next(&nsrdset
);
4139 if (!loggednotify
) {
4140 notify_log(zone
, ISC_LOG_INFO
,
4141 "sending notifies (serial %u)",
4143 loggednotify
= ISC_TRUE
;
4147 isqueued
= notify_isqueued(zone
, &ns
.name
, NULL
);
4150 result
= dns_rdataset_next(&nsrdset
);
4153 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
4154 if (result
!= ISC_R_SUCCESS
)
4156 dns_zone_iattach(zone
, ¬ify
->zone
);
4157 result
= dns_name_dup(&ns
.name
, zone
->mctx
, ¬ify
->ns
);
4158 if (result
!= ISC_R_SUCCESS
) {
4160 notify_destroy(notify
, ISC_TRUE
);
4165 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
4167 notify_find_address(notify
);
4169 result
= dns_rdataset_next(&nsrdset
);
4171 dns_rdataset_disassociate(&nsrdset
);
4174 if (dns_name_dynamic(&master
))
4175 dns_name_free(&master
, zone
->mctx
);
4177 dns_db_detachnode(zonedb
, &node
);
4179 dns_db_closeversion(zonedb
, &version
, ISC_FALSE
);
4180 dns_db_detach(&zonedb
);
4187 static inline isc_result_t
4188 save_nsrrset(dns_message_t
*message
, dns_name_t
*name
,
4189 dns_db_t
*db
, dns_dbversion_t
*version
)
4191 dns_rdataset_t
*nsrdataset
= NULL
;
4192 dns_rdataset_t
*rdataset
= NULL
;
4193 dns_dbnode_t
*node
= NULL
;
4195 isc_result_t result
;
4196 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4199 * Extract NS RRset from message.
4201 result
= dns_message_findname(message
, DNS_SECTION_ANSWER
, name
,
4202 dns_rdatatype_ns
, dns_rdatatype_none
,
4204 if (result
!= ISC_R_SUCCESS
)
4210 result
= dns_db_findnode(db
, name
, ISC_TRUE
, &node
);
4211 if (result
!= ISC_R_SUCCESS
)
4213 result
= dns_db_addrdataset(db
, node
, version
, 0,
4214 nsrdataset
, 0, NULL
);
4215 dns_db_detachnode(db
, &node
);
4216 if (result
!= ISC_R_SUCCESS
)
4219 * Add glue rdatasets.
4221 for (result
= dns_rdataset_first(nsrdataset
);
4222 result
== ISC_R_SUCCESS
;
4223 result
= dns_rdataset_next(nsrdataset
)) {
4224 dns_rdataset_current(nsrdataset
, &rdata
);
4225 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
4226 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4227 dns_rdata_reset(&rdata
);
4228 if (!dns_name_issubdomain(&ns
.name
, name
))
4231 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
4232 &ns
.name
, dns_rdatatype_aaaa
,
4233 dns_rdatatype_none
, NULL
,
4235 if (result
== ISC_R_SUCCESS
) {
4236 result
= dns_db_findnode(db
, &ns
.name
,
4238 if (result
!= ISC_R_SUCCESS
)
4240 result
= dns_db_addrdataset(db
, node
, version
, 0,
4242 dns_db_detachnode(db
, &node
);
4243 if (result
!= ISC_R_SUCCESS
)
4247 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
4248 &ns
.name
, dns_rdatatype_a
,
4249 dns_rdatatype_none
, NULL
,
4251 if (result
== ISC_R_SUCCESS
) {
4252 result
= dns_db_findnode(db
, &ns
.name
,
4254 if (result
!= ISC_R_SUCCESS
)
4256 result
= dns_db_addrdataset(db
, node
, version
, 0,
4258 dns_db_detachnode(db
, &node
);
4259 if (result
!= ISC_R_SUCCESS
)
4263 if (result
!= ISC_R_NOMORE
)
4266 return (ISC_R_SUCCESS
);
4273 stub_callback(isc_task_t
*task
, isc_event_t
*event
) {
4274 const char me
[] = "stub_callback";
4275 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
4276 dns_stub_t
*stub
= NULL
;
4277 dns_message_t
*msg
= NULL
;
4278 dns_zone_t
*zone
= NULL
;
4279 char master
[ISC_SOCKADDR_FORMATSIZE
];
4280 char source
[ISC_SOCKADDR_FORMATSIZE
];
4281 isc_uint32_t nscnt
, cnamecnt
;
4282 isc_result_t result
;
4284 isc_boolean_t exiting
= ISC_FALSE
;
4288 stub
= revent
->ev_arg
;
4289 INSIST(DNS_STUB_VALID(stub
));
4299 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
4300 zone_debuglog(zone
, me
, 1, "exiting");
4305 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
4306 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
4308 if (revent
->result
!= ISC_R_SUCCESS
) {
4309 if (revent
->result
== ISC_R_TIMEDOUT
&&
4310 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
4312 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
4314 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4315 "refreshing stub: timeout retrying "
4316 " without EDNS master %s (source %s)",
4320 dns_zonemgr_unreachableadd(zone
->zmgr
, &zone
->masteraddr
,
4321 &zone
->sourceaddr
, &now
);
4322 dns_zone_log(zone
, ISC_LOG_INFO
,
4323 "could not refresh stub from master %s"
4324 " (source %s): %s", master
, source
,
4325 dns_result_totext(revent
->result
));
4329 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
4330 if (result
!= ISC_R_SUCCESS
)
4333 result
= dns_request_getresponse(revent
->request
, msg
, 0);
4334 if (result
!= ISC_R_SUCCESS
)
4340 if (msg
->rcode
!= dns_rcode_noerror
) {
4344 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
4345 (void)dns_rcode_totext(msg
->rcode
, &rb
);
4347 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
) &&
4348 (msg
->rcode
== dns_rcode_servfail
||
4349 msg
->rcode
== dns_rcode_notimp
||
4350 msg
->rcode
== dns_rcode_formerr
)) {
4351 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4352 "refreshing stub: rcode (%.*s) retrying "
4353 "without EDNS master %s (source %s)",
4354 (int)rb
.used
, rcode
, master
, source
);
4356 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
4361 dns_zone_log(zone
, ISC_LOG_INFO
,
4363 "unexpected rcode (%.*s) from %s (source %s)",
4364 (int)rb
.used
, rcode
, master
, source
);
4369 * We need complete messages.
4371 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
4372 if (dns_request_usedtcp(revent
->request
)) {
4373 dns_zone_log(zone
, ISC_LOG_INFO
,
4374 "refreshing stub: truncated TCP "
4375 "response from master %s (source %s)",
4380 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
4386 * If non-auth log and next master.
4388 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
4389 dns_zone_log(zone
, ISC_LOG_INFO
, "refreshing stub: "
4390 "non-authoritative answer from "
4391 "master %s (source %s)", master
, source
);
4398 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
4399 nscnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_ns
);
4401 if (cnamecnt
!= 0) {
4402 dns_zone_log(zone
, ISC_LOG_INFO
,
4403 "refreshing stub: unexpected CNAME response "
4404 "from master %s (source %s)", master
, source
);
4409 dns_zone_log(zone
, ISC_LOG_INFO
,
4410 "refreshing stub: no NS records in response "
4411 "from master %s (source %s)", master
, source
);
4418 result
= save_nsrrset(msg
, &zone
->origin
, stub
->db
, stub
->version
);
4419 if (result
!= ISC_R_SUCCESS
) {
4420 dns_zone_log(zone
, ISC_LOG_INFO
,
4421 "refreshing stub: unable to save NS records "
4422 "from master %s (source %s)", master
, source
);
4429 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_TRUE
);
4430 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
4431 if (zone
->db
== NULL
)
4432 zone_attachdb(zone
, stub
->db
);
4433 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
4434 dns_db_detach(&stub
->db
);
4436 if (zone
->masterfile
!= NULL
) {
4437 dns_zone_dump(zone
);
4438 TIME_NOW(&zone
->loadtime
);
4441 dns_message_destroy(&msg
);
4442 isc_event_free(&event
);
4444 dns_request_destroy(&zone
->request
);
4445 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
4446 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
, &zone
->refreshtime
);
4447 isc_interval_set(&i
, zone
->expire
, 0);
4448 DNS_ZONE_TIME_ADD(&now
, zone
->expire
, &zone
->expiretime
);
4449 zone_settimer(zone
, &now
);
4454 if (stub
->version
!= NULL
)
4455 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_FALSE
);
4456 if (stub
->db
!= NULL
)
4457 dns_db_detach(&stub
->db
);
4459 dns_message_destroy(&msg
);
4460 isc_event_free(&event
);
4462 dns_request_destroy(&zone
->request
);
4464 * Skip to next failed / untried master.
4468 } while (zone
->curmaster
< zone
->masterscnt
&&
4469 zone
->mastersok
[zone
->curmaster
]);
4470 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
4471 if (exiting
|| zone
->curmaster
>= zone
->masterscnt
) {
4472 isc_boolean_t done
= ISC_TRUE
;
4474 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
4475 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
4477 * Did we get a good answer from all the masters?
4479 for (j
= 0; j
< zone
->masterscnt
; j
++)
4480 if (zone
->mastersok
[j
] == ISC_FALSE
) {
4487 zone
->curmaster
= 0;
4489 * Find the next failed master.
4491 while (zone
->curmaster
< zone
->masterscnt
&&
4492 zone
->mastersok
[zone
->curmaster
])
4494 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
4496 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
4498 zone_settimer(zone
, &now
);
4503 queue_soa_query(zone
);
4509 dns_message_destroy(&msg
);
4510 isc_event_free(&event
);
4512 dns_request_destroy(&zone
->request
);
4514 ns_query(zone
, NULL
, stub
);
4519 dns_zone_idetach(&stub
->zone
);
4520 INSIST(stub
->db
== NULL
);
4521 INSIST(stub
->version
== NULL
);
4522 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
4525 INSIST(event
== NULL
);
4530 * An SOA query has finished (successfully or not).
4533 refresh_callback(isc_task_t
*task
, isc_event_t
*event
) {
4534 const char me
[] = "refresh_callback";
4535 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
4537 dns_message_t
*msg
= NULL
;
4538 isc_uint32_t soacnt
, cnamecnt
, soacount
, nscount
;
4540 char master
[ISC_SOCKADDR_FORMATSIZE
];
4541 char source
[ISC_SOCKADDR_FORMATSIZE
];
4542 dns_rdataset_t
*rdataset
= NULL
;
4543 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4544 dns_rdata_soa_t soa
;
4545 isc_result_t result
;
4546 isc_uint32_t serial
;
4549 zone
= revent
->ev_arg
;
4550 INSIST(DNS_ZONE_VALID(zone
));
4557 * if timeout log and next master;
4560 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
4561 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
4565 if (revent
->result
!= ISC_R_SUCCESS
) {
4566 if (revent
->result
== ISC_R_TIMEDOUT
&&
4567 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
4569 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
4571 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4572 "refresh: timeout retrying without EDNS "
4573 "master %s (source %s)", master
, source
);
4576 if (revent
->result
== ISC_R_TIMEDOUT
&&
4577 !dns_request_usedtcp(revent
->request
)) {
4578 dns_zone_log(zone
, ISC_LOG_INFO
,
4579 "refresh: retry limit for "
4580 "master %s exceeded (source %s)",
4582 /* Try with slave with TCP. */
4583 if (zone
->type
== dns_zone_slave
&&
4584 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_TRYTCPREFRESH
)) {
4585 if (!dns_zonemgr_unreachable(zone
->zmgr
,
4590 DNS_ZONE_SETFLAG(zone
,
4591 DNS_ZONEFLG_SOABEFOREAXFR
);
4595 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4596 "refresh: skipped tcp fallback"
4597 "as master %s (source %s) is "
4598 "unreachable (cached)",
4602 dns_zone_log(zone
, ISC_LOG_INFO
,
4603 "refresh: failure trying master "
4604 "%s (source %s): %s", master
, source
,
4605 dns_result_totext(revent
->result
));
4609 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
4610 if (result
!= ISC_R_SUCCESS
)
4612 result
= dns_request_getresponse(revent
->request
, msg
, 0);
4613 if (result
!= ISC_R_SUCCESS
) {
4614 dns_zone_log(zone
, ISC_LOG_INFO
,
4615 "refresh: failure trying master "
4616 "%s (source %s): %s", master
, source
,
4617 dns_result_totext(result
));
4624 if (msg
->rcode
!= dns_rcode_noerror
) {
4628 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
4629 (void)dns_rcode_totext(msg
->rcode
, &rb
);
4631 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
) &&
4632 (msg
->rcode
== dns_rcode_servfail
||
4633 msg
->rcode
== dns_rcode_notimp
||
4634 msg
->rcode
== dns_rcode_formerr
)) {
4635 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4636 "refresh: rcode (%.*s) retrying without "
4637 "EDNS master %s (source %s)",
4638 (int)rb
.used
, rcode
, master
, source
);
4640 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
4644 dns_zone_log(zone
, ISC_LOG_INFO
,
4645 "refresh: unexpected rcode (%.*s) from "
4646 "master %s (source %s)", (int)rb
.used
, rcode
,
4649 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
4651 if (msg
->rcode
== dns_rcode_refused
&&
4652 zone
->type
== dns_zone_slave
)
4658 * If truncated punt to zone transfer which will query again.
4660 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
4661 if (zone
->type
== dns_zone_slave
) {
4662 dns_zone_log(zone
, ISC_LOG_INFO
,
4663 "refresh: truncated UDP answer, "
4664 "initiating TCP zone xfer "
4665 "for master %s (source %s)",
4668 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
);
4672 INSIST(zone
->type
== dns_zone_stub
);
4673 if (dns_request_usedtcp(revent
->request
)) {
4674 dns_zone_log(zone
, ISC_LOG_INFO
,
4675 "refresh: truncated TCP response "
4676 "from master %s (source %s)",
4681 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
4688 * if non-auth log and next master;
4690 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
4691 dns_zone_log(zone
, ISC_LOG_INFO
,
4692 "refresh: non-authoritative answer from "
4693 "master %s (source %s)", master
, source
);
4697 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
4698 soacnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_soa
);
4699 nscount
= message_count(msg
, DNS_SECTION_AUTHORITY
, dns_rdatatype_ns
);
4700 soacount
= message_count(msg
, DNS_SECTION_AUTHORITY
,
4704 * There should not be a CNAME record at top of zone.
4706 if (cnamecnt
!= 0) {
4707 dns_zone_log(zone
, ISC_LOG_INFO
,
4708 "refresh: CNAME at top of zone "
4709 "in master %s (source %s)", master
, source
);
4714 * if referral log and next master;
4716 if (soacnt
== 0 && soacount
== 0 && nscount
!= 0) {
4717 dns_zone_log(zone
, ISC_LOG_INFO
,
4718 "refresh: referral response "
4719 "from master %s (source %s)", master
, source
);
4724 * if nodata log and next master;
4726 if (soacnt
== 0 && (nscount
== 0 || soacount
!= 0)) {
4727 dns_zone_log(zone
, ISC_LOG_INFO
,
4728 "refresh: NODATA response "
4729 "from master %s (source %s)", master
, source
);
4734 * Only one soa at top of zone.
4737 dns_zone_log(zone
, ISC_LOG_INFO
,
4738 "refresh: answer SOA count (%d) != 1 "
4739 "from master %s (source %s)",
4740 soacnt
, master
, source
);
4747 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
, &zone
->origin
,
4748 dns_rdatatype_soa
, dns_rdatatype_none
,
4750 if (result
!= ISC_R_SUCCESS
) {
4751 dns_zone_log(zone
, ISC_LOG_INFO
,
4752 "refresh: unable to get SOA record "
4753 "from master %s (source %s)", master
, source
);
4757 result
= dns_rdataset_first(rdataset
);
4758 if (result
!= ISC_R_SUCCESS
) {
4759 dns_zone_log(zone
, ISC_LOG_INFO
,
4760 "refresh: dns_rdataset_first() failed");
4764 dns_rdataset_current(rdataset
, &rdata
);
4765 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
4766 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4768 serial
= soa
.serial
;
4770 zone_debuglog(zone
, me
, 1, "serial: new %u, old %u",
4771 serial
, zone
->serial
);
4772 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) ||
4773 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
) ||
4774 isc_serial_gt(serial
, zone
->serial
)) {
4775 if (dns_zonemgr_unreachable(zone
->zmgr
, &zone
->masteraddr
,
4776 &zone
->sourceaddr
, &now
)) {
4777 dns_zone_log(zone
, ISC_LOG_INFO
,
4778 "refresh: skipping %s as master %s "
4779 "(source %s) is unreachable (cached)",
4780 zone
->type
== dns_zone_slave
?
4781 "zone transfer" : "NS query",
4786 isc_event_free(&event
);
4788 dns_request_destroy(&zone
->request
);
4790 if (zone
->type
== dns_zone_slave
) {
4793 INSIST(zone
->type
== dns_zone_stub
);
4794 ns_query(zone
, rdataset
, NULL
);
4797 dns_message_destroy(&msg
);
4798 } else if (isc_serial_eq(soa
.serial
, zone
->serial
)) {
4799 if (zone
->masterfile
!= NULL
) {
4800 result
= ISC_R_FAILURE
;
4801 if (zone
->journal
!= NULL
)
4802 result
= isc_file_settime(zone
->journal
, &now
);
4803 if (result
== ISC_R_SUCCESS
&&
4804 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
4805 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
4806 result
= isc_file_settime(zone
->masterfile
,
4808 } else if (result
!= ISC_R_SUCCESS
)
4809 result
= isc_file_settime(zone
->masterfile
,
4811 /* Someone removed the file from underneath us! */
4812 if (result
== ISC_R_FILENOTFOUND
) {
4814 zone_needdump(zone
, DNS_DUMP_DELAY
);
4816 } else if (result
!= ISC_R_SUCCESS
)
4817 dns_zone_log(zone
, ISC_LOG_ERROR
,
4818 "refresh: could not set file "
4819 "modification time of '%s': %s",
4821 dns_result_totext(result
));
4823 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
, &zone
->refreshtime
);
4824 DNS_ZONE_TIME_ADD(&now
, zone
->expire
, &zone
->expiretime
);
4825 zone
->mastersok
[zone
->curmaster
] = ISC_TRUE
;
4828 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MULTIMASTER
))
4829 dns_zone_log(zone
, ISC_LOG_INFO
, "serial number (%u) "
4830 "received from master %s < ours (%u)",
4831 soa
.serial
, master
, zone
->serial
);
4833 zone_debuglog(zone
, me
, 1, "ahead");
4834 zone
->mastersok
[zone
->curmaster
] = ISC_TRUE
;
4838 dns_message_destroy(&msg
);
4843 dns_message_destroy(&msg
);
4844 isc_event_free(&event
);
4846 dns_request_destroy(&zone
->request
);
4848 * Skip to next failed / untried master.
4852 } while (zone
->curmaster
< zone
->masterscnt
&&
4853 zone
->mastersok
[zone
->curmaster
]);
4854 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
4855 if (zone
->curmaster
>= zone
->masterscnt
) {
4856 isc_boolean_t done
= ISC_TRUE
;
4857 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
4858 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
4860 * Did we get a good answer from all the masters?
4862 for (j
= 0; j
< zone
->masterscnt
; j
++)
4863 if (zone
->mastersok
[j
] == ISC_FALSE
) {
4870 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
4871 zone
->curmaster
= 0;
4873 * Find the next failed master.
4875 while (zone
->curmaster
< zone
->masterscnt
&&
4876 zone
->mastersok
[zone
->curmaster
])
4880 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
4881 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
4882 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
4883 zone
->refreshtime
= now
;
4885 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
4886 zone_settimer(zone
, &now
);
4892 queue_soa_query(zone
);
4898 dns_message_destroy(&msg
);
4899 isc_event_free(&event
);
4901 dns_request_destroy(&zone
->request
);
4902 queue_soa_query(zone
);
4906 dns_zone_idetach(&zone
);
4911 queue_soa_query(dns_zone_t
*zone
) {
4912 const char me
[] = "queue_soa_query";
4914 dns_zone_t
*dummy
= NULL
;
4915 isc_result_t result
;
4921 REQUIRE(LOCKED_ZONE(zone
));
4923 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
4924 cancel_refresh(zone
);
4928 e
= isc_event_allocate(zone
->mctx
, NULL
, DNS_EVENT_ZONE
,
4929 soa_query
, zone
, sizeof(isc_event_t
));
4931 cancel_refresh(zone
);
4936 * Attach so that we won't clean up
4937 * until the event is delivered.
4939 zone_iattach(zone
, &dummy
);
4942 e
->ev_sender
= NULL
;
4943 result
= isc_ratelimiter_enqueue(zone
->zmgr
->rl
, zone
->task
, &e
);
4944 if (result
!= ISC_R_SUCCESS
) {
4945 zone_idetach(&dummy
);
4947 cancel_refresh(zone
);
4951 static inline isc_result_t
4952 create_query(dns_zone_t
*zone
, dns_rdatatype_t rdtype
,
4953 dns_message_t
**messagep
)
4955 dns_message_t
*message
= NULL
;
4956 dns_name_t
*qname
= NULL
;
4957 dns_rdataset_t
*qrdataset
= NULL
;
4958 isc_result_t result
;
4960 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
4962 if (result
!= ISC_R_SUCCESS
)
4965 message
->opcode
= dns_opcode_query
;
4966 message
->rdclass
= zone
->rdclass
;
4968 result
= dns_message_gettempname(message
, &qname
);
4969 if (result
!= ISC_R_SUCCESS
)
4972 result
= dns_message_gettemprdataset(message
, &qrdataset
);
4973 if (result
!= ISC_R_SUCCESS
)
4979 dns_name_init(qname
, NULL
);
4980 dns_name_clone(&zone
->origin
, qname
);
4981 dns_rdataset_init(qrdataset
);
4982 dns_rdataset_makequestion(qrdataset
, zone
->rdclass
, rdtype
);
4983 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
4984 dns_message_addname(message
, qname
, DNS_SECTION_QUESTION
);
4986 *messagep
= message
;
4987 return (ISC_R_SUCCESS
);
4991 dns_message_puttempname(message
, &qname
);
4992 if (qrdataset
!= NULL
)
4993 dns_message_puttemprdataset(message
, &qrdataset
);
4994 if (message
!= NULL
)
4995 dns_message_destroy(&message
);
5000 add_opt(dns_message_t
*message
, isc_uint16_t udpsize
, isc_boolean_t reqnsid
) {
5001 dns_rdataset_t
*rdataset
= NULL
;
5002 dns_rdatalist_t
*rdatalist
= NULL
;
5003 dns_rdata_t
*rdata
= NULL
;
5004 isc_result_t result
;
5006 result
= dns_message_gettemprdatalist(message
, &rdatalist
);
5007 if (result
!= ISC_R_SUCCESS
)
5009 result
= dns_message_gettemprdata(message
, &rdata
);
5010 if (result
!= ISC_R_SUCCESS
)
5012 result
= dns_message_gettemprdataset(message
, &rdataset
);
5013 if (result
!= ISC_R_SUCCESS
)
5015 dns_rdataset_init(rdataset
);
5017 rdatalist
->type
= dns_rdatatype_opt
;
5018 rdatalist
->covers
= 0;
5021 * Set Maximum UDP buffer size.
5023 rdatalist
->rdclass
= udpsize
;
5026 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
5030 /* Set EDNS options if applicable */
5032 unsigned char data
[4];
5035 isc_buffer_init(&buf
, data
, sizeof(data
));
5036 isc_buffer_putuint16(&buf
, DNS_OPT_NSID
);
5037 isc_buffer_putuint16(&buf
, 0);
5039 rdata
->length
= sizeof(data
);
5045 rdata
->rdclass
= rdatalist
->rdclass
;
5046 rdata
->type
= rdatalist
->type
;
5049 ISC_LIST_INIT(rdatalist
->rdata
);
5050 ISC_LIST_APPEND(rdatalist
->rdata
, rdata
, link
);
5051 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist
, rdataset
)
5054 return (dns_message_setopt(message
, rdataset
));
5057 if (rdatalist
!= NULL
)
5058 dns_message_puttemprdatalist(message
, &rdatalist
);
5059 if (rdataset
!= NULL
)
5060 dns_message_puttemprdataset(message
, &rdataset
);
5062 dns_message_puttemprdata(message
, &rdata
);
5068 soa_query(isc_task_t
*task
, isc_event_t
*event
) {
5069 const char me
[] = "soa_query";
5070 isc_result_t result
= ISC_R_FAILURE
;
5071 dns_message_t
*message
= NULL
;
5072 dns_zone_t
*zone
= event
->ev_arg
;
5073 dns_zone_t
*dummy
= NULL
;
5074 isc_netaddr_t masterip
;
5075 dns_tsigkey_t
*key
= NULL
;
5076 isc_uint32_t options
;
5077 isc_boolean_t cancel
= ISC_TRUE
;
5079 isc_boolean_t have_xfrsource
, reqnsid
;
5080 isc_uint16_t udpsize
= SEND_BUFFER_SIZE
;
5082 REQUIRE(DNS_ZONE_VALID(zone
));
5089 if (((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0) ||
5090 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
) ||
5091 zone
->view
->requestmgr
== NULL
) {
5092 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
5098 * XXX Optimisation: Create message when zone is setup and reuse.
5100 result
= create_query(zone
, dns_rdatatype_soa
, &message
);
5101 if (result
!= ISC_R_SUCCESS
)
5105 INSIST(zone
->masterscnt
> 0);
5106 INSIST(zone
->curmaster
< zone
->masterscnt
);
5108 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
5110 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
5112 * First, look for a tsig key in the master statement, then
5113 * try for a server key.
5115 if ((zone
->masterkeynames
!= NULL
) &&
5116 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
5117 dns_view_t
*view
= dns_zone_getview(zone
);
5118 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
5119 result
= dns_view_gettsig(view
, keyname
, &key
);
5120 if (result
!= ISC_R_SUCCESS
) {
5121 char namebuf
[DNS_NAME_FORMATSIZE
];
5122 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
5123 dns_zone_log(zone
, ISC_LOG_ERROR
,
5124 "unable to find key: %s", namebuf
);
5128 (void)dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
5130 have_xfrsource
= ISC_FALSE
;
5131 reqnsid
= zone
->view
->requestnsid
;
5132 if (zone
->view
->peers
!= NULL
) {
5133 dns_peer_t
*peer
= NULL
;
5135 result
= dns_peerlist_peerbyaddr(zone
->view
->peers
,
5137 if (result
== ISC_R_SUCCESS
) {
5138 result
= dns_peer_getsupportedns(peer
, &edns
);
5139 if (result
== ISC_R_SUCCESS
&& !edns
)
5140 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
5141 result
= dns_peer_gettransfersource(peer
,
5143 if (result
== ISC_R_SUCCESS
)
5144 have_xfrsource
= ISC_TRUE
;
5145 if (zone
->view
->resolver
!= NULL
)
5147 dns_resolver_getudpsize(zone
->view
->resolver
);
5148 (void)dns_peer_getudpsize(peer
, &udpsize
);
5149 (void)dns_peer_getrequestnsid(peer
, &reqnsid
);
5153 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
5155 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
5156 if (isc_sockaddr_equal(&zone
->altxfrsource4
,
5159 zone
->sourceaddr
= zone
->altxfrsource4
;
5160 } else if (!have_xfrsource
)
5161 zone
->sourceaddr
= zone
->xfrsource4
;
5164 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
5165 if (isc_sockaddr_equal(&zone
->altxfrsource6
,
5168 zone
->sourceaddr
= zone
->altxfrsource6
;
5169 } else if (!have_xfrsource
)
5170 zone
->sourceaddr
= zone
->xfrsource6
;
5173 result
= ISC_R_NOTIMPLEMENTED
;
5177 options
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEVC
) ?
5178 DNS_REQUESTOPT_TCP
: 0;
5180 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
5181 result
= add_opt(message
, udpsize
, reqnsid
);
5182 if (result
!= ISC_R_SUCCESS
)
5183 zone_debuglog(zone
, me
, 1,
5184 "unable to add opt record: %s",
5185 dns_result_totext(result
));
5188 zone_iattach(zone
, &dummy
);
5190 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
5192 result
= dns_request_createvia2(zone
->view
->requestmgr
, message
,
5193 &zone
->sourceaddr
, &zone
->masteraddr
,
5194 options
, key
, timeout
* 3, timeout
,
5195 zone
->task
, refresh_callback
, zone
,
5197 if (result
!= ISC_R_SUCCESS
) {
5198 zone_idetach(&dummy
);
5199 zone_debuglog(zone
, me
, 1,
5200 "dns_request_createvia2() failed: %s",
5201 dns_result_totext(result
));
5204 if (isc_sockaddr_pf(&zone
->masteraddr
) == PF_INET
)
5205 inc_stats(zone
, dns_zonestatscounter_soaoutv4
);
5207 inc_stats(zone
, dns_zonestatscounter_soaoutv6
);
5213 dns_tsigkey_detach(&key
);
5214 if (result
!= ISC_R_SUCCESS
)
5215 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
5216 if (message
!= NULL
)
5217 dns_message_destroy(&message
);
5219 cancel_refresh(zone
);
5220 isc_event_free(&event
);
5222 dns_zone_idetach(&zone
);
5227 dns_tsigkey_detach(&key
);
5229 * Skip to next failed / untried master.
5233 } while (zone
->curmaster
< zone
->masterscnt
&&
5234 zone
->mastersok
[zone
->curmaster
]);
5235 if (zone
->curmaster
< zone
->masterscnt
)
5237 zone
->curmaster
= 0;
5242 ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
, dns_stub_t
*stub
) {
5243 const char me
[] = "ns_query";
5244 isc_result_t result
;
5245 dns_message_t
*message
= NULL
;
5246 isc_netaddr_t masterip
;
5247 dns_tsigkey_t
*key
= NULL
;
5248 dns_dbnode_t
*node
= NULL
;
5250 isc_boolean_t have_xfrsource
= ISC_FALSE
, reqnsid
;
5251 isc_uint16_t udpsize
= SEND_BUFFER_SIZE
;
5253 REQUIRE(DNS_ZONE_VALID(zone
));
5254 REQUIRE((soardataset
!= NULL
&& stub
== NULL
) ||
5255 (soardataset
== NULL
&& stub
!= NULL
));
5256 REQUIRE(stub
== NULL
|| DNS_STUB_VALID(stub
));
5262 stub
= isc_mem_get(zone
->mctx
, sizeof(*stub
));
5265 stub
->magic
= STUB_MAGIC
;
5266 stub
->mctx
= zone
->mctx
;
5269 stub
->version
= NULL
;
5272 * Attach so that the zone won't disappear from under us.
5274 zone_iattach(zone
, &stub
->zone
);
5277 * If a db exists we will update it, otherwise we create a
5278 * new one and attach it to the zone once we have the NS
5281 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
5282 if (zone
->db
!= NULL
) {
5283 dns_db_attach(zone
->db
, &stub
->db
);
5284 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
5286 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
5288 INSIST(zone
->db_argc
>= 1);
5289 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
5290 &zone
->origin
, dns_dbtype_stub
,
5295 if (result
!= ISC_R_SUCCESS
) {
5296 dns_zone_log(zone
, ISC_LOG_ERROR
,
5300 dns_result_totext(result
));
5303 dns_db_settask(stub
->db
, zone
->task
);
5306 dns_db_newversion(stub
->db
, &stub
->version
);
5309 * Update SOA record.
5311 result
= dns_db_findnode(stub
->db
, &zone
->origin
, ISC_TRUE
,
5313 if (result
!= ISC_R_SUCCESS
) {
5314 dns_zone_log(zone
, ISC_LOG_INFO
,
5316 "dns_db_findnode() failed: %s",
5317 dns_result_totext(result
));
5321 result
= dns_db_addrdataset(stub
->db
, node
, stub
->version
, 0,
5322 soardataset
, 0, NULL
);
5323 dns_db_detachnode(stub
->db
, &node
);
5324 if (result
!= ISC_R_SUCCESS
) {
5325 dns_zone_log(zone
, ISC_LOG_INFO
,
5327 "dns_db_addrdataset() failed: %s",
5328 dns_result_totext(result
));
5334 * XXX Optimisation: Create message when zone is setup and reuse.
5336 result
= create_query(zone
, dns_rdatatype_ns
, &message
);
5338 INSIST(zone
->masterscnt
> 0);
5339 INSIST(zone
->curmaster
< zone
->masterscnt
);
5340 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
5342 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
5344 * First, look for a tsig key in the master statement, then
5345 * try for a server key.
5347 if ((zone
->masterkeynames
!= NULL
) &&
5348 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
5349 dns_view_t
*view
= dns_zone_getview(zone
);
5350 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
5351 result
= dns_view_gettsig(view
, keyname
, &key
);
5352 if (result
!= ISC_R_SUCCESS
) {
5353 char namebuf
[DNS_NAME_FORMATSIZE
];
5354 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
5355 dns_zone_log(zone
, ISC_LOG_ERROR
,
5356 "unable to find key: %s", namebuf
);
5360 (void)dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
5362 reqnsid
= zone
->view
->requestnsid
;
5363 if (zone
->view
->peers
!= NULL
) {
5364 dns_peer_t
*peer
= NULL
;
5366 result
= dns_peerlist_peerbyaddr(zone
->view
->peers
,
5368 if (result
== ISC_R_SUCCESS
) {
5369 result
= dns_peer_getsupportedns(peer
, &edns
);
5370 if (result
== ISC_R_SUCCESS
&& !edns
)
5371 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
5372 result
= dns_peer_gettransfersource(peer
,
5374 if (result
== ISC_R_SUCCESS
)
5375 have_xfrsource
= ISC_TRUE
;
5376 if (zone
->view
->resolver
!= NULL
)
5378 dns_resolver_getudpsize(zone
->view
->resolver
);
5379 (void)dns_peer_getudpsize(peer
, &udpsize
);
5380 (void)dns_peer_getrequestnsid(peer
, &reqnsid
);
5384 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
5385 result
= add_opt(message
, udpsize
, reqnsid
);
5386 if (result
!= ISC_R_SUCCESS
)
5387 zone_debuglog(zone
, me
, 1,
5388 "unable to add opt record: %s",
5389 dns_result_totext(result
));
5393 * Always use TCP so that we shouldn't truncate in additional section.
5395 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
5397 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
))
5398 zone
->sourceaddr
= zone
->altxfrsource4
;
5399 else if (!have_xfrsource
)
5400 zone
->sourceaddr
= zone
->xfrsource4
;
5403 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
))
5404 zone
->sourceaddr
= zone
->altxfrsource6
;
5405 else if (!have_xfrsource
)
5406 zone
->sourceaddr
= zone
->xfrsource6
;
5409 result
= ISC_R_NOTIMPLEMENTED
;
5413 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
5415 result
= dns_request_createvia2(zone
->view
->requestmgr
, message
,
5416 &zone
->sourceaddr
, &zone
->masteraddr
,
5417 DNS_REQUESTOPT_TCP
, key
, timeout
* 3,
5418 timeout
, zone
->task
, stub_callback
,
5419 stub
, &zone
->request
);
5420 if (result
!= ISC_R_SUCCESS
) {
5421 zone_debuglog(zone
, me
, 1,
5422 "dns_request_createvia() failed: %s",
5423 dns_result_totext(result
));
5426 dns_message_destroy(&message
);
5430 cancel_refresh(zone
);
5433 if (stub
->version
!= NULL
)
5434 dns_db_closeversion(stub
->db
, &stub
->version
,
5436 if (stub
->db
!= NULL
)
5437 dns_db_detach(&stub
->db
);
5438 if (stub
->zone
!= NULL
)
5439 zone_idetach(&stub
->zone
);
5440 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
5442 if (message
!= NULL
)
5443 dns_message_destroy(&message
);
5446 dns_tsigkey_detach(&key
);
5452 * Handle the control event. Note that although this event causes the zone
5453 * to shut down, it is not a shutdown event in the sense of the task library.
5456 zone_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
5457 dns_zone_t
*zone
= (dns_zone_t
*) event
->ev_arg
;
5458 isc_boolean_t free_needed
, linked
= ISC_FALSE
;
5461 REQUIRE(DNS_ZONE_VALID(zone
));
5462 INSIST(event
->ev_type
== DNS_EVENT_ZONECONTROL
);
5463 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
5464 zone_debuglog(zone
, "zone_shutdown", 3, "shutting down");
5467 * Stop things being restarted after we cancel them below.
5470 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXITING
);
5474 * If we were waiting for xfrin quota, step out of
5476 * If there's no zone manager, we can't be waiting for the
5479 if (zone
->zmgr
!= NULL
) {
5480 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
5481 if (zone
->statelist
== &zone
->zmgr
->waiting_for_xfrin
) {
5482 ISC_LIST_UNLINK(zone
->zmgr
->waiting_for_xfrin
, zone
,
5485 zone
->statelist
= NULL
;
5487 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
5491 * In task context, no locking required. See zone_xfrdone().
5493 if (zone
->xfr
!= NULL
)
5494 dns_xfrin_shutdown(zone
->xfr
);
5498 INSIST(zone
->irefs
> 0);
5501 if (zone
->request
!= NULL
) {
5502 dns_request_cancel(zone
->request
);
5505 if (zone
->readio
!= NULL
)
5506 zonemgr_cancelio(zone
->readio
);
5508 if (zone
->lctx
!= NULL
)
5509 dns_loadctx_cancel(zone
->lctx
);
5511 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) ||
5512 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
5513 if (zone
->writeio
!= NULL
)
5514 zonemgr_cancelio(zone
->writeio
);
5516 if (zone
->dctx
!= NULL
)
5517 dns_dumpctx_cancel(zone
->dctx
);
5520 notify_cancel(zone
);
5522 if (zone
->timer
!= NULL
) {
5523 isc_timer_detach(&zone
->timer
);
5524 INSIST(zone
->irefs
> 0);
5528 if (zone
->view
!= NULL
)
5529 dns_view_weakdetach(&zone
->view
);
5532 * We have now canceled everything set the flag to allow exit_check()
5533 * to succeed. We must not unlock between setting this flag and
5534 * calling exit_check().
5536 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SHUTDOWN
);
5537 free_needed
= exit_check(zone
);
5544 zone_timer(isc_task_t
*task
, isc_event_t
*event
) {
5545 const char me
[] = "zone_timer";
5546 dns_zone_t
*zone
= (dns_zone_t
*)event
->ev_arg
;
5549 REQUIRE(DNS_ZONE_VALID(zone
));
5553 zone_maintenance(zone
);
5555 isc_event_free(&event
);
5559 zone_settimer(dns_zone_t
*zone
, isc_time_t
*now
) {
5560 const char me
[] = "zone_settimer";
5562 isc_result_t result
;
5564 REQUIRE(DNS_ZONE_VALID(zone
));
5565 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
5568 isc_time_settoepoch(&next
);
5570 switch (zone
->type
) {
5571 case dns_zone_master
:
5572 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
5573 next
= zone
->notifytime
;
5574 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
5575 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
5576 INSIST(!isc_time_isepoch(&zone
->dumptime
));
5577 if (isc_time_isepoch(&next
) ||
5578 isc_time_compare(&zone
->dumptime
, &next
) < 0)
5579 next
= zone
->dumptime
;
5583 case dns_zone_slave
:
5584 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
5585 next
= zone
->notifytime
;
5589 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
) &&
5590 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOMASTERS
) &&
5591 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
) &&
5592 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
5593 INSIST(!isc_time_isepoch(&zone
->refreshtime
));
5594 if (isc_time_isepoch(&next
) ||
5595 isc_time_compare(&zone
->refreshtime
, &next
) < 0)
5596 next
= zone
->refreshtime
;
5598 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
5599 INSIST(!isc_time_isepoch(&zone
->expiretime
));
5600 if (isc_time_isepoch(&next
) ||
5601 isc_time_compare(&zone
->expiretime
, &next
) < 0)
5602 next
= zone
->expiretime
;
5604 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
5605 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
5606 INSIST(!isc_time_isepoch(&zone
->dumptime
));
5607 if (isc_time_isepoch(&next
) ||
5608 isc_time_compare(&zone
->dumptime
, &next
) < 0)
5609 next
= zone
->dumptime
;
5617 if (isc_time_isepoch(&next
)) {
5618 zone_debuglog(zone
, me
, 10, "settimer inactive");
5619 result
= isc_timer_reset(zone
->timer
, isc_timertype_inactive
,
5620 NULL
, NULL
, ISC_TRUE
);
5621 if (result
!= ISC_R_SUCCESS
)
5622 dns_zone_log(zone
, ISC_LOG_ERROR
,
5623 "could not deactivate zone timer: %s",
5624 isc_result_totext(result
));
5626 if (isc_time_compare(&next
, now
) <= 0)
5628 result
= isc_timer_reset(zone
->timer
, isc_timertype_once
,
5629 &next
, NULL
, ISC_TRUE
);
5630 if (result
!= ISC_R_SUCCESS
)
5631 dns_zone_log(zone
, ISC_LOG_ERROR
,
5632 "could not reset zone timer: %s",
5633 isc_result_totext(result
));
5638 cancel_refresh(dns_zone_t
*zone
) {
5639 const char me
[] = "cancel_refresh";
5643 * 'zone' locked by caller.
5646 REQUIRE(DNS_ZONE_VALID(zone
));
5647 REQUIRE(LOCKED_ZONE(zone
));
5651 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
5653 zone_settimer(zone
, &now
);
5657 notify_createmessage(dns_zone_t
*zone
, unsigned int flags
,
5658 dns_message_t
**messagep
)
5660 dns_db_t
*zonedb
= NULL
;
5661 dns_dbnode_t
*node
= NULL
;
5662 dns_dbversion_t
*version
= NULL
;
5663 dns_message_t
*message
= NULL
;
5664 dns_rdataset_t rdataset
;
5665 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5667 dns_name_t
*tempname
= NULL
;
5668 dns_rdata_t
*temprdata
= NULL
;
5669 dns_rdatalist_t
*temprdatalist
= NULL
;
5670 dns_rdataset_t
*temprdataset
= NULL
;
5672 isc_result_t result
;
5674 isc_buffer_t
*b
= NULL
;
5676 REQUIRE(DNS_ZONE_VALID(zone
));
5677 REQUIRE(messagep
!= NULL
&& *messagep
== NULL
);
5679 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
5681 if (result
!= ISC_R_SUCCESS
)
5684 message
->opcode
= dns_opcode_notify
;
5685 message
->flags
|= DNS_MESSAGEFLAG_AA
;
5686 message
->rdclass
= zone
->rdclass
;
5688 result
= dns_message_gettempname(message
, &tempname
);
5689 if (result
!= ISC_R_SUCCESS
)
5692 result
= dns_message_gettemprdataset(message
, &temprdataset
);
5693 if (result
!= ISC_R_SUCCESS
)
5699 dns_name_init(tempname
, NULL
);
5700 dns_name_clone(&zone
->origin
, tempname
);
5701 dns_rdataset_init(temprdataset
);
5702 dns_rdataset_makequestion(temprdataset
, zone
->rdclass
,
5704 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
5705 dns_message_addname(message
, tempname
, DNS_SECTION_QUESTION
);
5707 temprdataset
= NULL
;
5709 if ((flags
& DNS_NOTIFY_NOSOA
) != 0)
5712 result
= dns_message_gettempname(message
, &tempname
);
5713 if (result
!= ISC_R_SUCCESS
)
5715 result
= dns_message_gettemprdata(message
, &temprdata
);
5716 if (result
!= ISC_R_SUCCESS
)
5718 result
= dns_message_gettemprdataset(message
, &temprdataset
);
5719 if (result
!= ISC_R_SUCCESS
)
5721 result
= dns_message_gettemprdatalist(message
, &temprdatalist
);
5722 if (result
!= ISC_R_SUCCESS
)
5725 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
5726 INSIST(zone
->db
!= NULL
); /* XXXJT: is this assumption correct? */
5727 dns_db_attach(zone
->db
, &zonedb
);
5728 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
5730 dns_name_init(tempname
, NULL
);
5731 dns_name_clone(&zone
->origin
, tempname
);
5732 dns_db_currentversion(zonedb
, &version
);
5733 result
= dns_db_findnode(zonedb
, tempname
, ISC_FALSE
, &node
);
5734 if (result
!= ISC_R_SUCCESS
)
5737 dns_rdataset_init(&rdataset
);
5738 result
= dns_db_findrdataset(zonedb
, node
, version
,
5740 dns_rdatatype_none
, 0, &rdataset
,
5742 if (result
!= ISC_R_SUCCESS
)
5744 result
= dns_rdataset_first(&rdataset
);
5745 if (result
!= ISC_R_SUCCESS
)
5747 dns_rdataset_current(&rdataset
, &rdata
);
5748 dns_rdata_toregion(&rdata
, &r
);
5749 result
= isc_buffer_allocate(zone
->mctx
, &b
, r
.length
);
5750 if (result
!= ISC_R_SUCCESS
)
5752 isc_buffer_putmem(b
, r
.base
, r
.length
);
5753 isc_buffer_usedregion(b
, &r
);
5754 dns_rdata_init(temprdata
);
5755 dns_rdata_fromregion(temprdata
, rdata
.rdclass
, rdata
.type
, &r
);
5756 dns_message_takebuffer(message
, &b
);
5757 result
= dns_rdataset_next(&rdataset
);
5758 dns_rdataset_disassociate(&rdataset
);
5759 if (result
!= ISC_R_NOMORE
)
5761 temprdatalist
->rdclass
= rdata
.rdclass
;
5762 temprdatalist
->type
= rdata
.type
;
5763 temprdatalist
->covers
= 0;
5764 temprdatalist
->ttl
= rdataset
.ttl
;
5765 ISC_LIST_INIT(temprdatalist
->rdata
);
5766 ISC_LIST_APPEND(temprdatalist
->rdata
, temprdata
, link
);
5768 dns_rdataset_init(temprdataset
);
5769 result
= dns_rdatalist_tordataset(temprdatalist
, temprdataset
);
5770 if (result
!= ISC_R_SUCCESS
)
5773 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
5774 dns_message_addname(message
, tempname
, DNS_SECTION_ANSWER
);
5775 temprdatalist
= NULL
;
5776 temprdataset
= NULL
;
5782 dns_db_detachnode(zonedb
, &node
);
5783 if (version
!= NULL
)
5784 dns_db_closeversion(zonedb
, &version
, ISC_FALSE
);
5786 dns_db_detach(&zonedb
);
5787 if (tempname
!= NULL
)
5788 dns_message_puttempname(message
, &tempname
);
5789 if (temprdata
!= NULL
)
5790 dns_message_puttemprdata(message
, &temprdata
);
5791 if (temprdataset
!= NULL
)
5792 dns_message_puttemprdataset(message
, &temprdataset
);
5793 if (temprdatalist
!= NULL
)
5794 dns_message_puttemprdatalist(message
, &temprdatalist
);
5797 *messagep
= message
;
5798 return (ISC_R_SUCCESS
);
5801 if (tempname
!= NULL
)
5802 dns_message_puttempname(message
, &tempname
);
5803 if (temprdataset
!= NULL
)
5804 dns_message_puttemprdataset(message
, &temprdataset
);
5805 dns_message_destroy(&message
);
5810 dns_zone_notifyreceive(dns_zone_t
*zone
, isc_sockaddr_t
*from
,
5814 dns_rdata_soa_t soa
;
5815 dns_rdataset_t
*rdataset
= NULL
;
5816 dns_rdata_t rdata
= DNS_RDATA_INIT
;
5817 isc_result_t result
;
5818 char fromtext
[ISC_SOCKADDR_FORMATSIZE
];
5820 isc_netaddr_t netaddr
;
5822 REQUIRE(DNS_ZONE_VALID(zone
));
5825 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
5829 * Check that 'from' is a valid notify source, (zone->masters).
5830 * Return DNS_R_REFUSED if not.
5832 * If the notify message contains a serial number check it
5833 * against the zones serial and return if <= current serial
5835 * If a refresh check is progress, if so just record the
5836 * fact we received a NOTIFY and from where and return.
5837 * We will perform a new refresh check when the current one
5838 * completes. Return ISC_R_SUCCESS.
5840 * Otherwise initiate a refresh check using 'from' as the
5841 * first address to check. Return ISC_R_SUCCESS.
5844 isc_sockaddr_format(from
, fromtext
, sizeof(fromtext
));
5847 * We only handle NOTIFY (SOA) at the present.
5850 if (isc_sockaddr_pf(from
) == PF_INET
)
5851 inc_stats(zone
, dns_zonestatscounter_notifyinv4
);
5853 inc_stats(zone
, dns_zonestatscounter_notifyinv6
);
5854 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0 ||
5855 dns_message_findname(msg
, DNS_SECTION_QUESTION
, &zone
->origin
,
5856 dns_rdatatype_soa
, dns_rdatatype_none
,
5857 NULL
, NULL
) != ISC_R_SUCCESS
) {
5859 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0) {
5860 dns_zone_log(zone
, ISC_LOG_NOTICE
,
5862 "question section from: %s", fromtext
);
5863 return (DNS_R_FORMERR
);
5865 dns_zone_log(zone
, ISC_LOG_NOTICE
,
5866 "NOTIFY zone does not match");
5867 return (DNS_R_NOTIMP
);
5871 * If we are a master zone just succeed.
5873 if (zone
->type
== dns_zone_master
) {
5875 return (ISC_R_SUCCESS
);
5878 isc_netaddr_fromsockaddr(&netaddr
, from
);
5879 for (i
= 0; i
< zone
->masterscnt
; i
++) {
5880 if (isc_sockaddr_eqaddr(from
, &zone
->masters
[i
]))
5882 if (zone
->view
->aclenv
.match_mapped
&&
5883 IN6_IS_ADDR_V4MAPPED(&from
->type
.sin6
.sin6_addr
) &&
5884 isc_sockaddr_pf(&zone
->masters
[i
]) == AF_INET
) {
5885 isc_netaddr_t na1
, na2
;
5886 isc_netaddr_fromv4mapped(&na1
, &netaddr
);
5887 isc_netaddr_fromsockaddr(&na2
, &zone
->masters
[i
]);
5888 if (isc_netaddr_equal(&na1
, &na2
))
5894 * Accept notify requests from non masters if they are on
5895 * 'zone->notify_acl'.
5897 if (i
>= zone
->masterscnt
&& zone
->notify_acl
!= NULL
&&
5898 dns_acl_match(&netaddr
, NULL
, zone
->notify_acl
,
5899 &zone
->view
->aclenv
,
5900 &match
, NULL
) == ISC_R_SUCCESS
&&
5903 /* Accept notify. */
5904 } else if (i
>= zone
->masterscnt
) {
5906 dns_zone_log(zone
, ISC_LOG_INFO
,
5907 "refused notify from non-master: %s", fromtext
);
5908 inc_stats(zone
, dns_zonestatscounter_notifyrej
);
5909 return (DNS_R_REFUSED
);
5913 * If the zone is loaded and there are answers check the serial
5914 * to see if we need to do a refresh. Do not worry about this
5915 * check if we are a dialup zone as we use the notify request
5916 * to trigger a refresh check.
5918 if (msg
->counts
[DNS_SECTION_ANSWER
] > 0 &&
5919 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
5920 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
)) {
5921 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
,
5924 dns_rdatatype_none
, NULL
,
5926 if (result
== ISC_R_SUCCESS
)
5927 result
= dns_rdataset_first(rdataset
);
5928 if (result
== ISC_R_SUCCESS
) {
5929 isc_uint32_t serial
= 0;
5931 dns_rdataset_current(rdataset
, &rdata
);
5932 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
5933 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
5934 serial
= soa
.serial
;
5935 if (isc_serial_le(serial
, zone
->serial
)) {
5936 dns_zone_log(zone
, ISC_LOG_INFO
,
5938 "zone is up to date",
5941 return (ISC_R_SUCCESS
);
5947 * If we got this far and there was a refresh in progress just
5948 * let it complete. Record where we got the notify from so we
5949 * can perform a refresh check when the current one completes
5951 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
)) {
5952 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
5953 zone
->notifyfrom
= *from
;
5955 dns_zone_log(zone
, ISC_LOG_INFO
,
5956 "notify from %s: refresh in progress, "
5957 "refresh check queued",
5959 return (ISC_R_SUCCESS
);
5961 zone
->notifyfrom
= *from
;
5963 dns_zone_refresh(zone
);
5964 return (ISC_R_SUCCESS
);
5968 dns_zone_setnotifyacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
5970 REQUIRE(DNS_ZONE_VALID(zone
));
5973 if (zone
->notify_acl
!= NULL
)
5974 dns_acl_detach(&zone
->notify_acl
);
5975 dns_acl_attach(acl
, &zone
->notify_acl
);
5980 dns_zone_setqueryacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
5982 REQUIRE(DNS_ZONE_VALID(zone
));
5985 if (zone
->query_acl
!= NULL
)
5986 dns_acl_detach(&zone
->query_acl
);
5987 dns_acl_attach(acl
, &zone
->query_acl
);
5992 dns_zone_setqueryonacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
5994 REQUIRE(DNS_ZONE_VALID(zone
));
5997 if (zone
->queryon_acl
!= NULL
)
5998 dns_acl_detach(&zone
->queryon_acl
);
5999 dns_acl_attach(acl
, &zone
->queryon_acl
);
6004 dns_zone_setupdateacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
6006 REQUIRE(DNS_ZONE_VALID(zone
));
6009 if (zone
->update_acl
!= NULL
)
6010 dns_acl_detach(&zone
->update_acl
);
6011 dns_acl_attach(acl
, &zone
->update_acl
);
6016 dns_zone_setforwardacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
6018 REQUIRE(DNS_ZONE_VALID(zone
));
6021 if (zone
->forward_acl
!= NULL
)
6022 dns_acl_detach(&zone
->forward_acl
);
6023 dns_acl_attach(acl
, &zone
->forward_acl
);
6028 dns_zone_setxfracl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
6030 REQUIRE(DNS_ZONE_VALID(zone
));
6033 if (zone
->xfr_acl
!= NULL
)
6034 dns_acl_detach(&zone
->xfr_acl
);
6035 dns_acl_attach(acl
, &zone
->xfr_acl
);
6040 dns_zone_getnotifyacl(dns_zone_t
*zone
) {
6042 REQUIRE(DNS_ZONE_VALID(zone
));
6044 return (zone
->notify_acl
);
6048 dns_zone_getqueryacl(dns_zone_t
*zone
) {
6050 REQUIRE(DNS_ZONE_VALID(zone
));
6052 return (zone
->query_acl
);
6056 dns_zone_getqueryonacl(dns_zone_t
*zone
) {
6058 REQUIRE(DNS_ZONE_VALID(zone
));
6060 return (zone
->queryon_acl
);
6064 dns_zone_getupdateacl(dns_zone_t
*zone
) {
6066 REQUIRE(DNS_ZONE_VALID(zone
));
6068 return (zone
->update_acl
);
6072 dns_zone_getforwardacl(dns_zone_t
*zone
) {
6074 REQUIRE(DNS_ZONE_VALID(zone
));
6076 return (zone
->forward_acl
);
6080 dns_zone_getxfracl(dns_zone_t
*zone
) {
6082 REQUIRE(DNS_ZONE_VALID(zone
));
6084 return (zone
->xfr_acl
);
6088 dns_zone_clearupdateacl(dns_zone_t
*zone
) {
6090 REQUIRE(DNS_ZONE_VALID(zone
));
6093 if (zone
->update_acl
!= NULL
)
6094 dns_acl_detach(&zone
->update_acl
);
6099 dns_zone_clearforwardacl(dns_zone_t
*zone
) {
6101 REQUIRE(DNS_ZONE_VALID(zone
));
6104 if (zone
->forward_acl
!= NULL
)
6105 dns_acl_detach(&zone
->forward_acl
);
6110 dns_zone_clearnotifyacl(dns_zone_t
*zone
) {
6112 REQUIRE(DNS_ZONE_VALID(zone
));
6115 if (zone
->notify_acl
!= NULL
)
6116 dns_acl_detach(&zone
->notify_acl
);
6121 dns_zone_clearqueryacl(dns_zone_t
*zone
) {
6123 REQUIRE(DNS_ZONE_VALID(zone
));
6126 if (zone
->query_acl
!= NULL
)
6127 dns_acl_detach(&zone
->query_acl
);
6132 dns_zone_clearqueryonacl(dns_zone_t
*zone
) {
6134 REQUIRE(DNS_ZONE_VALID(zone
));
6137 if (zone
->queryon_acl
!= NULL
)
6138 dns_acl_detach(&zone
->queryon_acl
);
6143 dns_zone_clearxfracl(dns_zone_t
*zone
) {
6145 REQUIRE(DNS_ZONE_VALID(zone
));
6148 if (zone
->xfr_acl
!= NULL
)
6149 dns_acl_detach(&zone
->xfr_acl
);
6154 dns_zone_getupdatedisabled(dns_zone_t
*zone
) {
6155 REQUIRE(DNS_ZONE_VALID(zone
));
6156 return (zone
->update_disabled
);
6161 dns_zone_setupdatedisabled(dns_zone_t
*zone
, isc_boolean_t state
) {
6162 REQUIRE(DNS_ZONE_VALID(zone
));
6163 zone
->update_disabled
= state
;
6167 dns_zone_getzeronosoattl(dns_zone_t
*zone
) {
6168 REQUIRE(DNS_ZONE_VALID(zone
));
6169 return (zone
->zero_no_soa_ttl
);
6174 dns_zone_setzeronosoattl(dns_zone_t
*zone
, isc_boolean_t state
) {
6175 REQUIRE(DNS_ZONE_VALID(zone
));
6176 zone
->zero_no_soa_ttl
= state
;
6180 dns_zone_setchecknames(dns_zone_t
*zone
, dns_severity_t severity
) {
6182 REQUIRE(DNS_ZONE_VALID(zone
));
6184 zone
->check_names
= severity
;
6188 dns_zone_getchecknames(dns_zone_t
*zone
) {
6190 REQUIRE(DNS_ZONE_VALID(zone
));
6192 return (zone
->check_names
);
6196 dns_zone_setjournalsize(dns_zone_t
*zone
, isc_int32_t size
) {
6198 REQUIRE(DNS_ZONE_VALID(zone
));
6200 zone
->journalsize
= size
;
6204 dns_zone_getjournalsize(dns_zone_t
*zone
) {
6206 REQUIRE(DNS_ZONE_VALID(zone
));
6208 return (zone
->journalsize
);
6212 zone_namerd_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
6213 isc_result_t result
= ISC_R_FAILURE
;
6214 isc_buffer_t buffer
;
6216 REQUIRE(buf
!= NULL
);
6217 REQUIRE(length
> 1U);
6220 * Leave space for terminating '\0'.
6222 isc_buffer_init(&buffer
, buf
, length
- 1);
6223 if (dns_name_dynamic(&zone
->origin
))
6224 result
= dns_name_totext(&zone
->origin
, ISC_TRUE
, &buffer
);
6225 if (result
!= ISC_R_SUCCESS
&&
6226 isc_buffer_availablelength(&buffer
) >= (sizeof("<UNKNOWN>") - 1))
6227 isc_buffer_putstr(&buffer
, "<UNKNOWN>");
6229 if (isc_buffer_availablelength(&buffer
) > 0)
6230 isc_buffer_putstr(&buffer
, "/");
6231 (void)dns_rdataclass_totext(zone
->rdclass
, &buffer
);
6233 if (zone
->view
!= NULL
&& strcmp(zone
->view
->name
, "_bind") != 0 &&
6234 strcmp(zone
->view
->name
, "_default") != 0 &&
6235 strlen(zone
->view
->name
) < isc_buffer_availablelength(&buffer
)) {
6236 isc_buffer_putstr(&buffer
, "/");
6237 isc_buffer_putstr(&buffer
, zone
->view
->name
);
6240 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
6244 zone_name_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
6245 isc_result_t result
= ISC_R_FAILURE
;
6246 isc_buffer_t buffer
;
6248 REQUIRE(buf
!= NULL
);
6249 REQUIRE(length
> 1U);
6252 * Leave space for terminating '\0'.
6254 isc_buffer_init(&buffer
, buf
, length
- 1);
6255 if (dns_name_dynamic(&zone
->origin
))
6256 result
= dns_name_totext(&zone
->origin
, ISC_TRUE
, &buffer
);
6257 if (result
!= ISC_R_SUCCESS
&&
6258 isc_buffer_availablelength(&buffer
) >= (sizeof("<UNKNOWN>") - 1))
6259 isc_buffer_putstr(&buffer
, "<UNKNOWN>");
6261 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
6265 zone_rdclass_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
6266 isc_buffer_t buffer
;
6268 REQUIRE(buf
!= NULL
);
6269 REQUIRE(length
> 1U);
6272 * Leave space for terminating '\0'.
6274 isc_buffer_init(&buffer
, buf
, length
- 1);
6275 (void)dns_rdataclass_totext(zone
->rdclass
, &buffer
);
6277 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
6281 zone_viewname_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
6282 isc_buffer_t buffer
;
6284 REQUIRE(buf
!= NULL
);
6285 REQUIRE(length
> 1U);
6289 * Leave space for terminating '\0'.
6291 isc_buffer_init(&buffer
, buf
, length
- 1);
6293 if (zone
->view
== NULL
) {
6294 isc_buffer_putstr(&buffer
, "_none");
6295 } else if (strlen(zone
->view
->name
)
6296 < isc_buffer_availablelength(&buffer
)) {
6297 isc_buffer_putstr(&buffer
, zone
->view
->name
);
6299 isc_buffer_putstr(&buffer
, "_toolong");
6302 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
6306 dns_zone_name(dns_zone_t
*zone
, char *buf
, size_t length
) {
6307 REQUIRE(DNS_ZONE_VALID(zone
));
6308 REQUIRE(buf
!= NULL
);
6309 zone_namerd_tostr(zone
, buf
, length
);
6313 notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
6317 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
6321 vsnprintf(message
, sizeof(message
), fmt
, ap
);
6323 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_NOTIFY
, DNS_LOGMODULE_ZONE
,
6324 level
, "zone %s: %s", zone
->strnamerd
, message
);
6328 dns_zone_logc(dns_zone_t
*zone
, isc_logcategory_t
*category
,
6329 int level
, const char *fmt
, ...) {
6333 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
6337 vsnprintf(message
, sizeof(message
), fmt
, ap
);
6339 isc_log_write(dns_lctx
, category
, DNS_LOGMODULE_ZONE
,
6340 level
, "zone %s: %s", zone
->strnamerd
, message
);
6344 dns_zone_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
6348 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
6352 vsnprintf(message
, sizeof(message
), fmt
, ap
);
6354 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
6355 level
, "zone %s: %s", zone
->strnamerd
, message
);
6359 zone_debuglog(dns_zone_t
*zone
, const char *me
, int debuglevel
,
6360 const char *fmt
, ...)
6364 int level
= ISC_LOG_DEBUG(debuglevel
);
6366 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
6370 vsnprintf(message
, sizeof(message
), fmt
, ap
);
6372 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
6373 level
, "%s: zone %s: %s", me
, zone
->strnamerd
, message
);
6377 message_count(dns_message_t
*msg
, dns_section_t section
, dns_rdatatype_t type
)
6379 isc_result_t result
;
6381 dns_rdataset_t
*curr
;
6384 result
= dns_message_firstname(msg
, section
);
6385 while (result
== ISC_R_SUCCESS
) {
6387 dns_message_currentname(msg
, section
, &name
);
6389 for (curr
= ISC_LIST_TAIL(name
->list
); curr
!= NULL
;
6390 curr
= ISC_LIST_PREV(curr
, link
)) {
6391 if (curr
->type
== type
)
6394 result
= dns_message_nextname(msg
, section
);
6401 dns_zone_setmaxxfrin(dns_zone_t
*zone
, isc_uint32_t maxxfrin
) {
6402 REQUIRE(DNS_ZONE_VALID(zone
));
6404 zone
->maxxfrin
= maxxfrin
;
6408 dns_zone_getmaxxfrin(dns_zone_t
*zone
) {
6409 REQUIRE(DNS_ZONE_VALID(zone
));
6411 return (zone
->maxxfrin
);
6415 dns_zone_setmaxxfrout(dns_zone_t
*zone
, isc_uint32_t maxxfrout
) {
6416 REQUIRE(DNS_ZONE_VALID(zone
));
6417 zone
->maxxfrout
= maxxfrout
;
6421 dns_zone_getmaxxfrout(dns_zone_t
*zone
) {
6422 REQUIRE(DNS_ZONE_VALID(zone
));
6424 return (zone
->maxxfrout
);
6428 dns_zone_gettype(dns_zone_t
*zone
) {
6429 REQUIRE(DNS_ZONE_VALID(zone
));
6431 return (zone
->type
);
6435 dns_zone_getorigin(dns_zone_t
*zone
) {
6436 REQUIRE(DNS_ZONE_VALID(zone
));
6438 return (&zone
->origin
);
6442 dns_zone_settask(dns_zone_t
*zone
, isc_task_t
*task
) {
6443 REQUIRE(DNS_ZONE_VALID(zone
));
6446 if (zone
->task
!= NULL
)
6447 isc_task_detach(&zone
->task
);
6448 isc_task_attach(task
, &zone
->task
);
6449 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
6450 if (zone
->db
!= NULL
)
6451 dns_db_settask(zone
->db
, zone
->task
);
6452 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
6457 dns_zone_gettask(dns_zone_t
*zone
, isc_task_t
**target
) {
6458 REQUIRE(DNS_ZONE_VALID(zone
));
6459 isc_task_attach(zone
->task
, target
);
6463 dns_zone_setidlein(dns_zone_t
*zone
, isc_uint32_t idlein
) {
6464 REQUIRE(DNS_ZONE_VALID(zone
));
6467 idlein
= DNS_DEFAULT_IDLEIN
;
6468 zone
->idlein
= idlein
;
6472 dns_zone_getidlein(dns_zone_t
*zone
) {
6473 REQUIRE(DNS_ZONE_VALID(zone
));
6475 return (zone
->idlein
);
6479 dns_zone_setidleout(dns_zone_t
*zone
, isc_uint32_t idleout
) {
6480 REQUIRE(DNS_ZONE_VALID(zone
));
6482 zone
->idleout
= idleout
;
6486 dns_zone_getidleout(dns_zone_t
*zone
) {
6487 REQUIRE(DNS_ZONE_VALID(zone
));
6489 return (zone
->idleout
);
6493 notify_done(isc_task_t
*task
, isc_event_t
*event
) {
6494 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
6495 dns_notify_t
*notify
;
6496 isc_result_t result
;
6497 dns_message_t
*message
= NULL
;
6500 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
6504 notify
= event
->ev_arg
;
6505 REQUIRE(DNS_NOTIFY_VALID(notify
));
6506 INSIST(task
== notify
->zone
->task
);
6508 isc_buffer_init(&buf
, rcode
, sizeof(rcode
));
6509 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
6511 result
= revent
->result
;
6512 if (result
== ISC_R_SUCCESS
)
6513 result
= dns_message_create(notify
->zone
->mctx
,
6514 DNS_MESSAGE_INTENTPARSE
, &message
);
6515 if (result
== ISC_R_SUCCESS
)
6516 result
= dns_request_getresponse(revent
->request
, message
,
6517 DNS_MESSAGEPARSE_PRESERVEORDER
);
6518 if (result
== ISC_R_SUCCESS
)
6519 result
= dns_rcode_totext(message
->rcode
, &buf
);
6520 if (result
== ISC_R_SUCCESS
)
6521 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
6522 "notify response from %s: %.*s",
6523 addrbuf
, (int)buf
.used
, rcode
);
6525 notify_log(notify
->zone
, ISC_LOG_DEBUG(2),
6526 "notify to %s failed: %s", addrbuf
,
6527 dns_result_totext(result
));
6530 * Old bind's return formerr if they see a soa record. Retry w/o
6531 * the soa if we see a formerr and had sent a SOA.
6533 isc_event_free(&event
);
6534 if (message
!= NULL
&& message
->rcode
== dns_rcode_formerr
&&
6535 (notify
->flags
& DNS_NOTIFY_NOSOA
) == 0) {
6536 notify
->flags
|= DNS_NOTIFY_NOSOA
;
6537 dns_request_destroy(¬ify
->request
);
6538 result
= notify_send_queue(notify
);
6539 if (result
!= ISC_R_SUCCESS
)
6540 notify_destroy(notify
, ISC_FALSE
);
6542 if (result
== ISC_R_TIMEDOUT
)
6543 notify_log(notify
->zone
, ISC_LOG_DEBUG(1),
6544 "notify to %s: retries exceeded", addrbuf
);
6545 notify_destroy(notify
, ISC_FALSE
);
6547 if (message
!= NULL
)
6548 dns_message_destroy(&message
);
6552 dns_zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
6553 isc_result_t result
;
6555 REQUIRE(DNS_ZONE_VALID(zone
));
6557 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_write
);
6558 result
= zone_replacedb(zone
, db
, dump
);
6559 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_write
);
6565 zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
6566 dns_dbversion_t
*ver
;
6567 isc_result_t result
;
6568 unsigned int soacount
= 0;
6569 unsigned int nscount
= 0;
6572 * 'zone' and 'zonedb' locked by caller.
6574 REQUIRE(DNS_ZONE_VALID(zone
));
6575 REQUIRE(LOCKED_ZONE(zone
));
6577 result
= zone_get_from_db(zone
, db
, &nscount
, &soacount
,
6578 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
6579 if (result
== ISC_R_SUCCESS
) {
6580 if (soacount
!= 1) {
6581 dns_zone_log(zone
, ISC_LOG_ERROR
,
6582 "has %d SOA records", soacount
);
6583 result
= DNS_R_BADZONE
;
6586 dns_zone_log(zone
, ISC_LOG_ERROR
, "has no NS records");
6587 result
= DNS_R_BADZONE
;
6589 if (result
!= ISC_R_SUCCESS
)
6592 dns_zone_log(zone
, ISC_LOG_ERROR
,
6593 "retrieving SOA and NS records failed: %s",
6594 dns_result_totext(result
));
6599 dns_db_currentversion(db
, &ver
);
6602 * The initial version of a slave zone is always dumped;
6603 * subsequent versions may be journaled instead if this
6604 * is enabled in the configuration.
6606 if (zone
->db
!= NULL
&& zone
->journal
!= NULL
&&
6607 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
) &&
6608 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
)) {
6609 isc_uint32_t serial
;
6611 dns_zone_log(zone
, ISC_LOG_DEBUG(3), "generating diffs");
6613 result
= dns_db_getsoaserial(db
, ver
, &serial
);
6614 if (result
!= ISC_R_SUCCESS
) {
6615 dns_zone_log(zone
, ISC_LOG_ERROR
,
6616 "ixfr-from-differences: unable to get "
6622 * This is checked in zone_postload() for master zones.
6624 if (zone
->type
== dns_zone_slave
&&
6625 !isc_serial_gt(serial
, zone
->serial
)) {
6626 isc_uint32_t serialmin
, serialmax
;
6627 serialmin
= (zone
->serial
+ 1) & 0xffffffffU
;
6628 serialmax
= (zone
->serial
+ 0x7fffffffU
) & 0xffffffffU
;
6629 dns_zone_log(zone
, ISC_LOG_ERROR
,
6630 "ixfr-from-differences: failed: "
6631 "new serial (%u) out of range [%u - %u]",
6632 serial
, serialmin
, serialmax
);
6633 result
= ISC_R_RANGE
;
6637 result
= dns_db_diff(zone
->mctx
, db
, ver
, zone
->db
, NULL
,
6639 if (result
!= ISC_R_SUCCESS
)
6642 zone_needdump(zone
, DNS_DUMP_DELAY
);
6643 else if (zone
->journalsize
!= -1) {
6644 result
= dns_journal_compact(zone
->mctx
, zone
->journal
,
6645 serial
, zone
->journalsize
);
6649 case ISC_R_NOTFOUND
:
6650 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
6651 "dns_journal_compact: %s",
6652 dns_result_totext(result
));
6655 dns_zone_log(zone
, ISC_LOG_ERROR
,
6656 "dns_journal_compact failed: %s",
6657 dns_result_totext(result
));
6662 if (dump
&& zone
->masterfile
!= NULL
) {
6663 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
6664 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
6665 "dumping new zone version");
6666 result
= dns_db_dump2(db
, ver
, zone
->masterfile
,
6667 zone
->masterformat
);
6668 if (result
!= ISC_R_SUCCESS
)
6672 * Update the time the zone was updated, so
6673 * dns_zone_load can avoid loading it when
6674 * the server is reloaded. If isc_time_now
6675 * fails for some reason, all that happens is
6676 * the timestamp is not updated.
6678 TIME_NOW(&zone
->loadtime
);
6681 if (dump
&& zone
->journal
!= NULL
) {
6683 * The in-memory database just changed, and
6684 * because 'dump' is set, it didn't change by
6685 * being loaded from disk. Also, we have not
6686 * journaled diffs for this change.
6687 * Therefore, the on-disk journal is missing
6688 * the deltas for this change. Since it can
6689 * no longer be used to bring the zone
6690 * up-to-date, it is useless and should be
6693 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
6694 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
6695 "removing journal file");
6696 if (remove(zone
->journal
) < 0 && errno
!= ENOENT
) {
6697 char strbuf
[ISC_STRERRORSIZE
];
6698 isc__strerror(errno
, strbuf
, sizeof(strbuf
));
6699 isc_log_write(dns_lctx
,
6700 DNS_LOGCATEGORY_GENERAL
,
6703 "unable to remove journal "
6705 zone
->journal
, strbuf
);
6710 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
6712 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
6713 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
6714 "replacing zone database");
6716 if (zone
->db
!= NULL
)
6717 zone_detachdb(zone
);
6718 zone_attachdb(zone
, db
);
6719 dns_db_settask(zone
->db
, zone
->task
);
6720 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
6721 return (ISC_R_SUCCESS
);
6724 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
6728 /* The caller must hold the dblock as a writer. */
6730 zone_attachdb(dns_zone_t
*zone
, dns_db_t
*db
) {
6731 REQUIRE(zone
->db
== NULL
&& db
!= NULL
);
6733 dns_db_attach(db
, &zone
->db
);
6734 if (zone
->acache
!= NULL
) {
6735 isc_result_t result
;
6736 result
= dns_acache_setdb(zone
->acache
, db
);
6737 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_EXISTS
) {
6738 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
6739 "dns_acache_setdb() failed: %s",
6740 isc_result_totext(result
));
6745 /* The caller must hold the dblock as a writer. */
6747 zone_detachdb(dns_zone_t
*zone
) {
6748 REQUIRE(zone
->db
!= NULL
);
6750 if (zone
->acache
!= NULL
)
6751 (void)dns_acache_putdb(zone
->acache
, zone
->db
);
6752 dns_db_detach(&zone
->db
);
6756 zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
) {
6758 isc_boolean_t again
= ISC_FALSE
;
6759 unsigned int soacount
;
6760 unsigned int nscount
;
6761 isc_uint32_t serial
, refresh
, retry
, expire
, minimum
;
6762 isc_result_t xfrresult
= result
;
6763 isc_boolean_t free_needed
;
6765 REQUIRE(DNS_ZONE_VALID(zone
));
6767 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
6768 "zone transfer finished: %s", dns_result_totext(result
));
6771 INSIST((zone
->flags
& DNS_ZONEFLG_REFRESH
) != 0);
6772 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
6773 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
);
6778 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
6780 case DNS_R_UPTODATE
:
6781 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
6783 * Has the zone expired underneath us?
6785 ZONEDB_LOCK(&zone
->dblock
, isc_rwlocktype_read
);
6786 if (zone
->db
== NULL
) {
6787 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
6792 * Update the zone structure's data from the actual
6797 INSIST(zone
->db
!= NULL
);
6798 result
= zone_get_from_db(zone
, zone
->db
, &nscount
,
6799 &soacount
, &serial
, &refresh
,
6800 &retry
, &expire
, &minimum
, NULL
);
6801 ZONEDB_UNLOCK(&zone
->dblock
, isc_rwlocktype_read
);
6802 if (result
== ISC_R_SUCCESS
) {
6804 dns_zone_log(zone
, ISC_LOG_ERROR
,
6806 "has %d SOA record%s", soacount
,
6807 (soacount
!= 0) ? "s" : "");
6809 dns_zone_log(zone
, ISC_LOG_ERROR
,
6811 "has no NS records");
6812 if (DNS_ZONE_FLAG(zone
,
6813 DNS_ZONEFLG_HAVETIMERS
)) {
6814 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
6815 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
6817 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
6821 zone
->serial
= serial
;
6822 zone
->refresh
= RANGE(refresh
, zone
->minrefresh
,
6824 zone
->retry
= RANGE(retry
, zone
->minretry
,
6826 zone
->expire
= RANGE(expire
,
6827 zone
->refresh
+ zone
->retry
,
6829 zone
->minimum
= minimum
;
6830 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
6834 * Set our next update/expire times.
6836 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
6837 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
6838 zone
->refreshtime
= now
;
6839 DNS_ZONE_TIME_ADD(&now
, zone
->expire
,
6842 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
,
6843 &zone
->refreshtime
);
6844 DNS_ZONE_TIME_ADD(&now
, zone
->expire
,
6847 if (result
== ISC_R_SUCCESS
&& xfrresult
== ISC_R_SUCCESS
) {
6848 char buf
[DNS_NAME_FORMATSIZE
+ sizeof(": TSIG ''")];
6849 if (zone
->tsigkey
!= NULL
) {
6850 char namebuf
[DNS_NAME_FORMATSIZE
];
6851 dns_name_format(&zone
->tsigkey
->name
, namebuf
,
6853 snprintf(buf
, sizeof(buf
), ": TSIG '%s'",
6857 dns_zone_log(zone
, ISC_LOG_INFO
,
6858 "transferred serial %u%s",
6863 * This is not necessary if we just performed a AXFR
6864 * however it is necessary for an IXFR / UPTODATE and
6865 * won't hurt with an AXFR.
6867 if (zone
->masterfile
!= NULL
|| zone
->journal
!= NULL
) {
6868 result
= ISC_R_FAILURE
;
6869 if (zone
->journal
!= NULL
)
6870 result
= isc_file_settime(zone
->journal
, &now
);
6871 if (result
!= ISC_R_SUCCESS
&&
6872 zone
->masterfile
!= NULL
)
6873 result
= isc_file_settime(zone
->masterfile
,
6875 /* Someone removed the file from underneath us! */
6876 if (result
== ISC_R_FILENOTFOUND
&&
6877 zone
->masterfile
!= NULL
)
6878 zone_needdump(zone
, DNS_DUMP_DELAY
);
6879 else if (result
!= ISC_R_SUCCESS
)
6880 dns_zone_log(zone
, ISC_LOG_ERROR
,
6881 "transfer: could not set file "
6882 "modification time of '%s': %s",
6884 dns_result_totext(result
));
6887 inc_stats(zone
, dns_zonestatscounter_xfrsuccess
);
6891 /* Force retry with AXFR. */
6892 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
6898 * Skip to next failed / untried master.
6902 } while (zone
->curmaster
< zone
->masterscnt
&&
6903 zone
->mastersok
[zone
->curmaster
]);
6906 if (zone
->curmaster
>= zone
->masterscnt
) {
6907 zone
->curmaster
= 0;
6908 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
6909 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
6910 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
6911 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
6912 while (zone
->curmaster
< zone
->masterscnt
&&
6913 zone
->mastersok
[zone
->curmaster
])
6917 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
6919 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
6922 inc_stats(zone
, dns_zonestatscounter_xfrfail
);
6925 zone_settimer(zone
, &now
);
6928 * If creating the transfer object failed, zone->xfr is NULL.
6929 * Otherwise, we are called as the done callback of a zone
6930 * transfer object that just entered its shutting-down
6931 * state. Since we are no longer responsible for shutting
6932 * it down, we can detach our reference.
6934 if (zone
->xfr
!= NULL
)
6935 dns_xfrin_detach(&zone
->xfr
);
6937 if (zone
->tsigkey
!= NULL
)
6938 dns_tsigkey_detach(&zone
->tsigkey
);
6941 * Handle any deferred journal compaction.
6943 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
)) {
6944 result
= dns_journal_compact(zone
->mctx
, zone
->journal
,
6945 zone
->compact_serial
,
6950 case ISC_R_NOTFOUND
:
6951 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
6952 "dns_journal_compact: %s",
6953 dns_result_totext(result
));
6956 dns_zone_log(zone
, ISC_LOG_ERROR
,
6957 "dns_journal_compact failed: %s",
6958 dns_result_totext(result
));
6961 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDCOMPACT
);
6965 * This transfer finishing freed up a transfer quota slot.
6966 * Let any other zones waiting for quota have it.
6968 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
6969 ISC_LIST_UNLINK(zone
->zmgr
->xfrin_in_progress
, zone
, statelink
);
6970 zone
->statelist
= NULL
;
6971 zmgr_resume_xfrs(zone
->zmgr
, ISC_FALSE
);
6972 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
6975 * Retry with a different server if necessary.
6977 if (again
&& !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
6978 queue_soa_query(zone
);
6980 INSIST(zone
->irefs
> 0);
6982 free_needed
= exit_check(zone
);
6989 zone_loaddone(void *arg
, isc_result_t result
) {
6990 static char me
[] = "zone_loaddone";
6991 dns_load_t
*load
= arg
;
6993 isc_result_t tresult
;
6995 REQUIRE(DNS_LOAD_VALID(load
));
7000 tresult
= dns_db_endload(load
->db
, &load
->callbacks
.add_private
);
7001 if (tresult
!= ISC_R_SUCCESS
&&
7002 (result
== ISC_R_SUCCESS
|| result
== DNS_R_SEENINCLUDE
))
7005 LOCK_ZONE(load
->zone
);
7006 (void)zone_postload(load
->zone
, load
->db
, load
->loadtime
, result
);
7007 zonemgr_putio(&load
->zone
->readio
);
7008 DNS_ZONE_CLRFLAG(load
->zone
, DNS_ZONEFLG_LOADING
);
7010 * Leave the zone frozen if the reload fails.
7012 if ((result
== ISC_R_SUCCESS
|| result
== DNS_R_SEENINCLUDE
) &&
7013 DNS_ZONE_FLAG(load
->zone
, DNS_ZONEFLG_THAW
))
7014 zone
->update_disabled
= ISC_FALSE
;
7015 DNS_ZONE_CLRFLAG(load
->zone
, DNS_ZONEFLG_THAW
);
7016 UNLOCK_ZONE(load
->zone
);
7019 dns_db_detach(&load
->db
);
7020 if (load
->zone
->lctx
!= NULL
)
7021 dns_loadctx_detach(&load
->zone
->lctx
);
7022 dns_zone_idetach(&load
->zone
);
7023 isc_mem_putanddetach(&load
->mctx
, load
, sizeof(*load
));
7027 dns_zone_getssutable(dns_zone_t
*zone
, dns_ssutable_t
**table
) {
7028 REQUIRE(DNS_ZONE_VALID(zone
));
7029 REQUIRE(table
!= NULL
);
7030 REQUIRE(*table
== NULL
);
7033 if (zone
->ssutable
!= NULL
)
7034 dns_ssutable_attach(zone
->ssutable
, table
);
7039 dns_zone_setssutable(dns_zone_t
*zone
, dns_ssutable_t
*table
) {
7040 REQUIRE(DNS_ZONE_VALID(zone
));
7043 if (zone
->ssutable
!= NULL
)
7044 dns_ssutable_detach(&zone
->ssutable
);
7046 dns_ssutable_attach(table
, &zone
->ssutable
);
7051 dns_zone_setsigvalidityinterval(dns_zone_t
*zone
, isc_uint32_t interval
) {
7052 REQUIRE(DNS_ZONE_VALID(zone
));
7054 zone
->sigvalidityinterval
= interval
;
7058 dns_zone_getsigvalidityinterval(dns_zone_t
*zone
) {
7059 REQUIRE(DNS_ZONE_VALID(zone
));
7061 return (zone
->sigvalidityinterval
);
7065 queue_xfrin(dns_zone_t
*zone
) {
7066 const char me
[] = "queue_xfrin";
7067 isc_result_t result
;
7068 dns_zonemgr_t
*zmgr
= zone
->zmgr
;
7072 INSIST(zone
->statelist
== NULL
);
7074 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7075 ISC_LIST_APPEND(zmgr
->waiting_for_xfrin
, zone
, statelink
);
7079 zone
->statelist
= &zmgr
->waiting_for_xfrin
;
7080 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
7081 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7083 if (result
== ISC_R_QUOTA
) {
7084 dns_zone_logc(zone
, DNS_LOGCATEGORY_XFER_IN
, ISC_LOG_INFO
,
7085 "zone transfer deferred due to quota");
7086 } else if (result
!= ISC_R_SUCCESS
) {
7087 dns_zone_logc(zone
, DNS_LOGCATEGORY_XFER_IN
, ISC_LOG_ERROR
,
7088 "starting zone transfer: %s",
7089 isc_result_totext(result
));
7094 * This event callback is called when a zone has received
7095 * any necessary zone transfer quota. This is the time
7096 * to go ahead and start the transfer.
7099 got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
) {
7100 isc_result_t result
;
7101 dns_peer_t
*peer
= NULL
;
7102 char master
[ISC_SOCKADDR_FORMATSIZE
];
7103 char source
[ISC_SOCKADDR_FORMATSIZE
];
7104 dns_rdatatype_t xfrtype
;
7105 dns_zone_t
*zone
= event
->ev_arg
;
7106 isc_netaddr_t masterip
;
7107 isc_sockaddr_t sourceaddr
;
7108 isc_sockaddr_t masteraddr
;
7113 INSIST(task
== zone
->task
);
7115 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
7116 result
= ISC_R_CANCELED
;
7122 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
7123 if (dns_zonemgr_unreachable(zone
->zmgr
, &zone
->masteraddr
,
7124 &zone
->sourceaddr
, &now
)) {
7125 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
7126 dns_zone_log(zone
, ISC_LOG_INFO
,
7127 "got_transfer_quota: skipping zone transfer as "
7128 "master %s (source %s) is unreachable (cached)",
7130 result
= ISC_R_CANCELED
;
7134 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
7135 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
, &masterip
, &peer
);
7138 * Decide whether we should request IXFR or AXFR.
7140 if (zone
->db
== NULL
) {
7141 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
7142 "no database exists yet, requesting AXFR of "
7143 "initial version from %s", master
);
7144 xfrtype
= dns_rdatatype_axfr
;
7145 } else if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
)) {
7146 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "ixfr-from-differences "
7147 "set, requesting AXFR from %s", master
);
7148 xfrtype
= dns_rdatatype_axfr
;
7149 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
)) {
7150 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
7151 "forced reload, requesting AXFR of "
7152 "initial version from %s", master
);
7153 xfrtype
= dns_rdatatype_axfr
;
7154 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLAG_NOIXFR
)) {
7155 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
7156 "retrying with AXFR from %s due to "
7157 "previous IXFR failure", master
);
7158 xfrtype
= dns_rdatatype_axfr
;
7160 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
7163 isc_boolean_t use_ixfr
= ISC_TRUE
;
7165 dns_peer_getrequestixfr(peer
, &use_ixfr
) ==
7167 ; /* Using peer setting */
7169 use_ixfr
= zone
->view
->requestixfr
;
7171 if (use_ixfr
== ISC_FALSE
) {
7172 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
7173 "IXFR disabled, requesting AXFR from %s",
7175 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
))
7176 xfrtype
= dns_rdatatype_soa
;
7178 xfrtype
= dns_rdatatype_axfr
;
7180 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
7181 "requesting IXFR from %s", master
);
7182 xfrtype
= dns_rdatatype_ixfr
;
7187 * Determine if we should attempt to sign the request with TSIG.
7189 result
= ISC_R_NOTFOUND
;
7191 * First, look for a tsig key in the master statement, then
7192 * try for a server key.
7194 if ((zone
->masterkeynames
!= NULL
) &&
7195 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
7196 dns_view_t
*view
= dns_zone_getview(zone
);
7197 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
7198 result
= dns_view_gettsig(view
, keyname
, &zone
->tsigkey
);
7200 if (zone
->tsigkey
== NULL
)
7201 result
= dns_view_getpeertsig(zone
->view
, &masterip
,
7204 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
7205 dns_zone_log(zone
, ISC_LOG_ERROR
,
7206 "could not get TSIG key for zone transfer: %s",
7207 isc_result_totext(result
));
7211 masteraddr
= zone
->masteraddr
;
7212 sourceaddr
= zone
->sourceaddr
;
7214 INSIST(isc_sockaddr_pf(&masteraddr
) == isc_sockaddr_pf(&sourceaddr
));
7215 result
= dns_xfrin_create2(zone
, xfrtype
, &masteraddr
, &sourceaddr
,
7216 zone
->tsigkey
, zone
->mctx
,
7217 zone
->zmgr
->timermgr
, zone
->zmgr
->socketmgr
,
7218 zone
->task
, zone_xfrdone
, &zone
->xfr
);
7219 if (result
== ISC_R_SUCCESS
) {
7221 if (xfrtype
== dns_rdatatype_axfr
) {
7222 if (isc_sockaddr_pf(&masteraddr
) == PF_INET
)
7223 inc_stats(zone
, dns_zonestatscounter_axfrreqv4
);
7225 inc_stats(zone
, dns_zonestatscounter_axfrreqv6
);
7226 } else if (xfrtype
== dns_rdatatype_ixfr
) {
7227 if (isc_sockaddr_pf(&masteraddr
) == PF_INET
)
7228 inc_stats(zone
, dns_zonestatscounter_ixfrreqv4
);
7230 inc_stats(zone
, dns_zonestatscounter_ixfrreqv6
);
7236 * Any failure in this function is handled like a failed
7237 * zone transfer. This ensures that we get removed from
7238 * zmgr->xfrin_in_progress.
7240 if (result
!= ISC_R_SUCCESS
)
7241 zone_xfrdone(zone
, result
);
7243 isc_event_free(&event
);
7247 * Update forwarding support.
7251 forward_destroy(dns_forward_t
*forward
) {
7254 if (forward
->request
!= NULL
)
7255 dns_request_destroy(&forward
->request
);
7256 if (forward
->msgbuf
!= NULL
)
7257 isc_buffer_free(&forward
->msgbuf
);
7258 if (forward
->zone
!= NULL
)
7259 dns_zone_idetach(&forward
->zone
);
7260 isc_mem_putanddetach(&forward
->mctx
, forward
, sizeof(*forward
));
7264 sendtomaster(dns_forward_t
*forward
) {
7265 isc_result_t result
;
7268 LOCK_ZONE(forward
->zone
);
7269 if (forward
->which
>= forward
->zone
->masterscnt
) {
7270 UNLOCK_ZONE(forward
->zone
);
7271 return (ISC_R_NOMORE
);
7274 forward
->addr
= forward
->zone
->masters
[forward
->which
];
7276 * Always use TCP regardless of whether the original update
7278 * XXX The timeout may but a bit small if we are far down a
7279 * transfer graph and the master has to try several masters.
7281 switch (isc_sockaddr_pf(&forward
->addr
)) {
7283 src
= forward
->zone
->xfrsource4
;
7286 src
= forward
->zone
->xfrsource6
;
7289 result
= ISC_R_NOTIMPLEMENTED
;
7292 result
= dns_request_createraw(forward
->zone
->view
->requestmgr
,
7294 &src
, &forward
->addr
,
7295 DNS_REQUESTOPT_TCP
, 15 /* XXX */,
7296 forward
->zone
->task
,
7297 forward_callback
, forward
,
7300 UNLOCK_ZONE(forward
->zone
);
7305 forward_callback(isc_task_t
*task
, isc_event_t
*event
) {
7306 const char me
[] = "forward_callback";
7307 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
7308 dns_message_t
*msg
= NULL
;
7309 char master
[ISC_SOCKADDR_FORMATSIZE
];
7310 isc_result_t result
;
7311 dns_forward_t
*forward
;
7316 forward
= revent
->ev_arg
;
7317 INSIST(DNS_FORWARD_VALID(forward
));
7318 zone
= forward
->zone
;
7319 INSIST(DNS_ZONE_VALID(zone
));
7323 isc_sockaddr_format(&forward
->addr
, master
, sizeof(master
));
7325 if (revent
->result
!= ISC_R_SUCCESS
) {
7326 dns_zone_log(zone
, ISC_LOG_INFO
,
7327 "could not forward dynamic update to %s: %s",
7328 master
, dns_result_totext(revent
->result
));
7332 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
7333 if (result
!= ISC_R_SUCCESS
)
7336 result
= dns_request_getresponse(revent
->request
, msg
,
7337 DNS_MESSAGEPARSE_PRESERVEORDER
|
7338 DNS_MESSAGEPARSE_CLONEBUFFER
);
7339 if (result
!= ISC_R_SUCCESS
)
7342 switch (msg
->rcode
) {
7344 * Pass these rcodes back to client.
7346 case dns_rcode_noerror
:
7347 case dns_rcode_yxdomain
:
7348 case dns_rcode_yxrrset
:
7349 case dns_rcode_nxrrset
:
7350 case dns_rcode_refused
:
7351 case dns_rcode_nxdomain
:
7354 /* These should not occur if the masters/zone are valid. */
7355 case dns_rcode_notzone
:
7356 case dns_rcode_notauth
: {
7360 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
7361 (void)dns_rcode_totext(msg
->rcode
, &rb
);
7362 dns_zone_log(zone
, ISC_LOG_WARNING
,
7363 "forwarding dynamic update: "
7364 "unexpected response: master %s returned: %.*s",
7365 master
, (int)rb
.used
, rcode
);
7369 /* Try another server for these rcodes. */
7370 case dns_rcode_formerr
:
7371 case dns_rcode_servfail
:
7372 case dns_rcode_notimp
:
7373 case dns_rcode_badvers
:
7379 (forward
->callback
)(forward
->callback_arg
, ISC_R_SUCCESS
, msg
);
7381 dns_request_destroy(&forward
->request
);
7382 forward_destroy(forward
);
7383 isc_event_free(&event
);
7388 dns_message_destroy(&msg
);
7389 isc_event_free(&event
);
7391 dns_request_destroy(&forward
->request
);
7392 result
= sendtomaster(forward
);
7393 if (result
!= ISC_R_SUCCESS
) {
7395 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
7396 "exhausted dynamic update forwarder list");
7397 (forward
->callback
)(forward
->callback_arg
, result
, NULL
);
7398 forward_destroy(forward
);
7403 dns_zone_forwardupdate(dns_zone_t
*zone
, dns_message_t
*msg
,
7404 dns_updatecallback_t callback
, void *callback_arg
)
7406 dns_forward_t
*forward
;
7407 isc_result_t result
;
7410 REQUIRE(DNS_ZONE_VALID(zone
));
7411 REQUIRE(msg
!= NULL
);
7412 REQUIRE(callback
!= NULL
);
7414 forward
= isc_mem_get(zone
->mctx
, sizeof(*forward
));
7415 if (forward
== NULL
)
7416 return (ISC_R_NOMEMORY
);
7418 forward
->request
= NULL
;
7419 forward
->zone
= NULL
;
7420 forward
->msgbuf
= NULL
;
7423 forward
->callback
= callback
;
7424 forward
->callback_arg
= callback_arg
;
7425 forward
->magic
= FORWARD_MAGIC
;
7427 mr
= dns_message_getrawmessage(msg
);
7429 result
= ISC_R_UNEXPECTEDEND
;
7433 result
= isc_buffer_allocate(zone
->mctx
, &forward
->msgbuf
, mr
->length
);
7434 if (result
!= ISC_R_SUCCESS
)
7436 result
= isc_buffer_copyregion(forward
->msgbuf
, mr
);
7437 if (result
!= ISC_R_SUCCESS
)
7440 isc_mem_attach(zone
->mctx
, &forward
->mctx
);
7441 dns_zone_iattach(zone
, &forward
->zone
);
7442 result
= sendtomaster(forward
);
7445 if (result
!= ISC_R_SUCCESS
) {
7446 forward_destroy(forward
);
7452 dns_zone_next(dns_zone_t
*zone
, dns_zone_t
**next
) {
7453 REQUIRE(DNS_ZONE_VALID(zone
));
7454 REQUIRE(next
!= NULL
&& *next
== NULL
);
7456 *next
= ISC_LIST_NEXT(zone
, link
);
7458 return (ISC_R_NOMORE
);
7460 return (ISC_R_SUCCESS
);
7464 dns_zone_first(dns_zonemgr_t
*zmgr
, dns_zone_t
**first
) {
7465 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7466 REQUIRE(first
!= NULL
&& *first
== NULL
);
7468 *first
= ISC_LIST_HEAD(zmgr
->zones
);
7470 return (ISC_R_NOMORE
);
7472 return (ISC_R_SUCCESS
);
7480 dns_zonemgr_create(isc_mem_t
*mctx
, isc_taskmgr_t
*taskmgr
,
7481 isc_timermgr_t
*timermgr
, isc_socketmgr_t
*socketmgr
,
7482 dns_zonemgr_t
**zmgrp
)
7484 dns_zonemgr_t
*zmgr
;
7485 isc_result_t result
;
7486 isc_interval_t interval
;
7488 zmgr
= isc_mem_get(mctx
, sizeof(*zmgr
));
7490 return (ISC_R_NOMEMORY
);
7493 isc_mem_attach(mctx
, &zmgr
->mctx
);
7494 zmgr
->taskmgr
= taskmgr
;
7495 zmgr
->timermgr
= timermgr
;
7496 zmgr
->socketmgr
= socketmgr
;
7497 zmgr
->zonetasks
= NULL
;
7500 ISC_LIST_INIT(zmgr
->zones
);
7501 ISC_LIST_INIT(zmgr
->waiting_for_xfrin
);
7502 ISC_LIST_INIT(zmgr
->xfrin_in_progress
);
7503 memset(zmgr
->unreachable
, 0, sizeof(zmgr
->unreachable
));
7504 result
= isc_rwlock_init(&zmgr
->rwlock
, 0, 0);
7505 if (result
!= ISC_R_SUCCESS
)
7508 zmgr
->transfersin
= 10;
7509 zmgr
->transfersperns
= 2;
7511 /* Create the zone task pool. */
7512 result
= isc_taskpool_create(taskmgr
, mctx
,
7513 8 /* XXX */, 2, &zmgr
->zonetasks
);
7514 if (result
!= ISC_R_SUCCESS
)
7517 /* Create a single task for queueing of SOA queries. */
7518 result
= isc_task_create(taskmgr
, 1, &zmgr
->task
);
7519 if (result
!= ISC_R_SUCCESS
)
7521 isc_task_setname(zmgr
->task
, "zmgr", zmgr
);
7522 result
= isc_ratelimiter_create(mctx
, timermgr
, zmgr
->task
,
7524 if (result
!= ISC_R_SUCCESS
)
7526 /* default to 20 refresh queries / notifies per second. */
7527 isc_interval_set(&interval
, 0, 1000000000/2);
7528 result
= isc_ratelimiter_setinterval(zmgr
->rl
, &interval
);
7529 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
7530 isc_ratelimiter_setpertic(zmgr
->rl
, 10);
7534 ISC_LIST_INIT(zmgr
->high
);
7535 ISC_LIST_INIT(zmgr
->low
);
7537 result
= isc_mutex_init(&zmgr
->iolock
);
7538 if (result
!= ISC_R_SUCCESS
)
7541 zmgr
->magic
= ZONEMGR_MAGIC
;
7544 return (ISC_R_SUCCESS
);
7548 DESTROYLOCK(&zmgr
->iolock
);
7551 isc_ratelimiter_detach(&zmgr
->rl
);
7553 isc_task_detach(&zmgr
->task
);
7555 isc_taskpool_destroy(&zmgr
->zonetasks
);
7557 isc_rwlock_destroy(&zmgr
->rwlock
);
7559 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof(*zmgr
));
7560 isc_mem_detach(&mctx
);
7565 dns_zonemgr_managezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
7566 isc_result_t result
;
7568 REQUIRE(DNS_ZONE_VALID(zone
));
7569 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7571 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7573 REQUIRE(zone
->task
== NULL
);
7574 REQUIRE(zone
->timer
== NULL
);
7575 REQUIRE(zone
->zmgr
== NULL
);
7577 isc_taskpool_gettask(zmgr
->zonetasks
,
7578 dns_name_hash(dns_zone_getorigin(zone
),
7583 * Set the task name. The tag will arbitrarily point to one
7584 * of the zones sharing the task (in practice, the one
7585 * to be managed last).
7587 isc_task_setname(zone
->task
, "zone", zone
);
7589 result
= isc_timer_create(zmgr
->timermgr
, isc_timertype_inactive
,
7591 zone
->task
, zone_timer
, zone
,
7594 if (result
!= ISC_R_SUCCESS
)
7598 * The timer "holds" a iref.
7601 INSIST(zone
->irefs
!= 0);
7603 ISC_LIST_APPEND(zmgr
->zones
, zone
, link
);
7610 isc_task_detach(&zone
->task
);
7614 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7619 dns_zonemgr_releasezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
7620 isc_boolean_t free_now
= ISC_FALSE
;
7622 REQUIRE(DNS_ZONE_VALID(zone
));
7623 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7624 REQUIRE(zone
->zmgr
== zmgr
);
7626 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7629 ISC_LIST_UNLINK(zmgr
->zones
, zone
, link
);
7632 if (zmgr
->refs
== 0)
7633 free_now
= ISC_TRUE
;
7636 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7640 ENSURE(zone
->zmgr
== NULL
);
7644 dns_zonemgr_attach(dns_zonemgr_t
*source
, dns_zonemgr_t
**target
) {
7645 REQUIRE(DNS_ZONEMGR_VALID(source
));
7646 REQUIRE(target
!= NULL
&& *target
== NULL
);
7648 RWLOCK(&source
->rwlock
, isc_rwlocktype_write
);
7649 REQUIRE(source
->refs
> 0);
7651 INSIST(source
->refs
> 0);
7652 RWUNLOCK(&source
->rwlock
, isc_rwlocktype_write
);
7657 dns_zonemgr_detach(dns_zonemgr_t
**zmgrp
) {
7658 dns_zonemgr_t
*zmgr
;
7659 isc_boolean_t free_now
= ISC_FALSE
;
7661 REQUIRE(zmgrp
!= NULL
);
7663 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7665 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7667 if (zmgr
->refs
== 0)
7668 free_now
= ISC_TRUE
;
7669 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7676 dns_zonemgr_forcemaint(dns_zonemgr_t
*zmgr
) {
7679 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7681 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
7682 for (p
= ISC_LIST_HEAD(zmgr
->zones
);
7684 p
= ISC_LIST_NEXT(p
, link
))
7686 dns_zone_maintenance(p
);
7688 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
7691 * Recent configuration changes may have increased the
7692 * amount of available transfers quota. Make sure any
7693 * transfers currently blocked on quota get started if
7696 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7697 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
7698 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7699 return (ISC_R_SUCCESS
);
7703 dns_zonemgr_resumexfrs(dns_zonemgr_t
*zmgr
) {
7705 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7707 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7708 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
7709 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
7713 dns_zonemgr_shutdown(dns_zonemgr_t
*zmgr
) {
7714 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7716 isc_ratelimiter_shutdown(zmgr
->rl
);
7718 if (zmgr
->task
!= NULL
)
7719 isc_task_destroy(&zmgr
->task
);
7720 if (zmgr
->zonetasks
!= NULL
)
7721 isc_taskpool_destroy(&zmgr
->zonetasks
);
7725 zonemgr_free(dns_zonemgr_t
*zmgr
) {
7728 INSIST(zmgr
->refs
== 0);
7729 INSIST(ISC_LIST_EMPTY(zmgr
->zones
));
7733 DESTROYLOCK(&zmgr
->iolock
);
7734 isc_ratelimiter_detach(&zmgr
->rl
);
7736 isc_rwlock_destroy(&zmgr
->rwlock
);
7738 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof(*zmgr
));
7739 isc_mem_detach(&mctx
);
7743 dns_zonemgr_settransfersin(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
7744 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7746 zmgr
->transfersin
= value
;
7750 dns_zonemgr_getttransfersin(dns_zonemgr_t
*zmgr
) {
7751 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7753 return (zmgr
->transfersin
);
7757 dns_zonemgr_settransfersperns(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
7758 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7760 zmgr
->transfersperns
= value
;
7764 dns_zonemgr_getttransfersperns(dns_zonemgr_t
*zmgr
) {
7765 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7767 return (zmgr
->transfersperns
);
7771 * Try to start a new incoming zone transfer to fill a quota
7772 * slot that was just vacated.
7775 * The zone manager is locked by the caller.
7778 zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
) {
7782 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
7786 isc_result_t result
;
7787 next
= ISC_LIST_NEXT(zone
, statelink
);
7788 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
7789 if (result
== ISC_R_SUCCESS
) {
7793 * We successfully filled the slot. We're done.
7796 } else if (result
== ISC_R_QUOTA
) {
7798 * Not enough quota. This is probably the per-server
7799 * quota, because we usually get called when a unit of
7800 * global quota has just been freed. Try the next
7801 * zone, it may succeed if it uses another master.
7805 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
7806 "starting zone transfer: %s",
7807 isc_result_totext(result
));
7814 * Try to start an incoming zone transfer for 'zone', quota permitting.
7817 * The zone manager is locked by the caller.
7820 * ISC_R_SUCCESS There was enough quota and we attempted to
7821 * start a transfer. zone_xfrdone() has been or will
7823 * ISC_R_QUOTA Not enough quota.
7827 zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
7828 dns_peer_t
*peer
= NULL
;
7829 isc_netaddr_t masterip
;
7830 isc_uint32_t nxfrsin
, nxfrsperns
;
7832 isc_uint32_t maxtransfersin
, maxtransfersperns
;
7836 * Find any configured information about the server we'd
7837 * like to transfer this zone from.
7839 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
7840 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
,
7844 * Determine the total maximum number of simultaneous
7845 * transfers allowed, and the maximum for this specific
7848 maxtransfersin
= zmgr
->transfersin
;
7849 maxtransfersperns
= zmgr
->transfersperns
;
7851 (void)dns_peer_gettransfers(peer
, &maxtransfersperns
);
7854 * Count the total number of transfers that are in progress,
7855 * and the number of transfers in progress from this master.
7856 * We linearly scan a list of all transfers; if this turns
7857 * out to be too slow, we could hash on the master address.
7859 nxfrsin
= nxfrsperns
= 0;
7860 for (x
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
7862 x
= ISC_LIST_NEXT(x
, statelink
))
7865 isc_netaddr_fromsockaddr(&xip
, &x
->masteraddr
);
7867 if (isc_netaddr_equal(&xip
, &masterip
))
7871 /* Enforce quota. */
7872 if (nxfrsin
>= maxtransfersin
)
7873 return (ISC_R_QUOTA
);
7875 if (nxfrsperns
>= maxtransfersperns
)
7876 return (ISC_R_QUOTA
);
7879 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
7880 * list and send it an event to let it start the actual transfer in the
7881 * context of its own task.
7883 e
= isc_event_allocate(zmgr
->mctx
, zmgr
,
7884 DNS_EVENT_ZONESTARTXFRIN
,
7885 got_transfer_quota
, zone
,
7886 sizeof(isc_event_t
));
7888 return (ISC_R_NOMEMORY
);
7891 INSIST(zone
->statelist
== &zmgr
->waiting_for_xfrin
);
7892 ISC_LIST_UNLINK(zmgr
->waiting_for_xfrin
, zone
, statelink
);
7893 ISC_LIST_APPEND(zmgr
->xfrin_in_progress
, zone
, statelink
);
7894 zone
->statelist
= &zmgr
->xfrin_in_progress
;
7895 isc_task_send(zone
->task
, &e
);
7896 dns_zone_log(zone
, ISC_LOG_INFO
, "Transfer started.");
7899 return (ISC_R_SUCCESS
);
7903 dns_zonemgr_setiolimit(dns_zonemgr_t
*zmgr
, isc_uint32_t iolimit
) {
7905 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7906 REQUIRE(iolimit
> 0);
7908 zmgr
->iolimit
= iolimit
;
7912 dns_zonemgr_getiolimit(dns_zonemgr_t
*zmgr
) {
7914 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7916 return (zmgr
->iolimit
);
7920 * Get permission to request a file handle from the OS.
7921 * An event will be sent to action when one is available.
7922 * There are two queues available (high and low), the high
7923 * queue will be serviced before the low one.
7925 * zonemgr_putio() must be called after the event is delivered to
7930 zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
7931 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
7935 isc_boolean_t queue
;
7937 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
7938 REQUIRE(iop
!= NULL
&& *iop
== NULL
);
7940 io
= isc_mem_get(zmgr
->mctx
, sizeof(*io
));
7942 return (ISC_R_NOMEMORY
);
7943 io
->event
= isc_event_allocate(zmgr
->mctx
, task
, DNS_EVENT_IOREADY
,
7944 action
, arg
, sizeof(*io
->event
));
7945 if (io
->event
== NULL
) {
7946 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
7947 return (ISC_R_NOMEMORY
);
7952 isc_task_attach(task
, &io
->task
);
7953 ISC_LINK_INIT(io
, link
);
7954 io
->magic
= IO_MAGIC
;
7956 LOCK(&zmgr
->iolock
);
7958 queue
= ISC_TF(zmgr
->ioactive
> zmgr
->iolimit
);
7961 ISC_LIST_APPEND(zmgr
->high
, io
, link
);
7963 ISC_LIST_APPEND(zmgr
->low
, io
, link
);
7965 UNLOCK(&zmgr
->iolock
);
7969 isc_task_send(io
->task
, &io
->event
);
7971 return (ISC_R_SUCCESS
);
7975 zonemgr_putio(dns_io_t
**iop
) {
7978 dns_zonemgr_t
*zmgr
;
7980 REQUIRE(iop
!= NULL
);
7982 REQUIRE(DNS_IO_VALID(io
));
7986 INSIST(!ISC_LINK_LINKED(io
, link
));
7987 INSIST(io
->event
== NULL
);
7990 isc_task_detach(&io
->task
);
7992 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
7994 LOCK(&zmgr
->iolock
);
7995 INSIST(zmgr
->ioactive
> 0);
7997 next
= HEAD(zmgr
->high
);
7999 next
= HEAD(zmgr
->low
);
8002 ISC_LIST_UNLINK(zmgr
->high
, next
, link
);
8004 ISC_LIST_UNLINK(zmgr
->low
, next
, link
);
8005 INSIST(next
->event
!= NULL
);
8007 UNLOCK(&zmgr
->iolock
);
8009 isc_task_send(next
->task
, &next
->event
);
8013 zonemgr_cancelio(dns_io_t
*io
) {
8014 isc_boolean_t send_event
= ISC_FALSE
;
8016 REQUIRE(DNS_IO_VALID(io
));
8019 * If we are queued to be run then dequeue.
8021 LOCK(&io
->zmgr
->iolock
);
8022 if (ISC_LINK_LINKED(io
, link
)) {
8024 ISC_LIST_UNLINK(io
->zmgr
->high
, io
, link
);
8026 ISC_LIST_UNLINK(io
->zmgr
->low
, io
, link
);
8028 send_event
= ISC_TRUE
;
8029 INSIST(io
->event
!= NULL
);
8031 UNLOCK(&io
->zmgr
->iolock
);
8033 io
->event
->ev_attributes
|= ISC_EVENTATTR_CANCELED
;
8034 isc_task_send(io
->task
, &io
->event
);
8039 zone_saveunique(dns_zone_t
*zone
, const char *path
, const char *templat
) {
8042 isc_result_t result
;
8044 buflen
= strlen(path
) + strlen(templat
) + 2;
8046 buf
= isc_mem_get(zone
->mctx
, buflen
);
8050 result
= isc_file_template(path
, templat
, buf
, buflen
);
8051 if (result
!= ISC_R_SUCCESS
)
8054 result
= isc_file_renameunique(path
, buf
);
8055 if (result
!= ISC_R_SUCCESS
)
8058 dns_zone_log(zone
, ISC_LOG_WARNING
, "saved '%s' as '%s'",
8062 isc_mem_put(zone
->mctx
, buf
, buflen
);
8066 /* Hook for ondestroy notification from a database. */
8069 dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
) {
8070 dns_db_t
*db
= event
->sender
;
8073 isc_event_free(&event
);
8075 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
8076 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
8077 "database (%p) destroyed", (void*) db
);
8082 dns_zonemgr_setserialqueryrate(dns_zonemgr_t
*zmgr
, unsigned int value
) {
8083 isc_interval_t interval
;
8085 isc_uint32_t pertic
;
8086 isc_result_t result
;
8088 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
8097 } else if (value
<= 10) {
8099 ns
= 1000000000 / value
;
8103 ns
= (1000000000 / value
) * 10;
8107 isc_interval_set(&interval
, s
, ns
);
8108 result
= isc_ratelimiter_setinterval(zmgr
->rl
, &interval
);
8109 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
8110 isc_ratelimiter_setpertic(zmgr
->rl
, pertic
);
8112 zmgr
->serialqueryrate
= value
;
8116 dns_zonemgr_getserialqueryrate(dns_zonemgr_t
*zmgr
) {
8117 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
8119 return (zmgr
->serialqueryrate
);
8122 static isc_boolean_t
8123 dns_zonemgr_unreachable(dns_zonemgr_t
*zmgr
, isc_sockaddr_t
*remote
,
8124 isc_sockaddr_t
*local
, isc_time_t
*now
)
8127 isc_rwlocktype_t locktype
;
8128 isc_result_t result
;
8129 isc_uint32_t seconds
= isc_time_seconds(now
);
8131 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
8133 locktype
= isc_rwlocktype_read
;
8134 RWLOCK(&zmgr
->rwlock
, locktype
);
8135 for (i
= 0; i
< UNREACH_CHACHE_SIZE
; i
++) {
8136 if (zmgr
->unreachable
[i
].expire
>= seconds
&&
8137 isc_sockaddr_equal(&zmgr
->unreachable
[i
].remote
, remote
) &&
8138 isc_sockaddr_equal(&zmgr
->unreachable
[i
].local
, local
)) {
8139 result
= isc_rwlock_tryupgrade(&zmgr
->rwlock
);
8140 if (result
== ISC_R_SUCCESS
) {
8141 locktype
= isc_rwlocktype_write
;
8142 zmgr
->unreachable
[i
].last
= seconds
;
8147 RWUNLOCK(&zmgr
->rwlock
, locktype
);
8148 return (ISC_TF(i
< UNREACH_CHACHE_SIZE
));
8152 dns_zonemgr_unreachableadd(dns_zonemgr_t
*zmgr
, isc_sockaddr_t
*remote
,
8153 isc_sockaddr_t
*local
, isc_time_t
*now
)
8155 isc_uint32_t seconds
= isc_time_seconds(now
);
8156 isc_uint32_t last
= seconds
;
8157 unsigned int i
, slot
= UNREACH_CHACHE_SIZE
, oldest
= 0;
8159 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
8161 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
8162 for (i
= 0; i
< UNREACH_CHACHE_SIZE
; i
++) {
8163 /* Existing entry? */
8164 if (isc_sockaddr_equal(&zmgr
->unreachable
[i
].remote
, remote
) &&
8165 isc_sockaddr_equal(&zmgr
->unreachable
[i
].local
, local
))
8168 if (zmgr
->unreachable
[i
].expire
< seconds
)
8170 /* Least recently used slot? */
8171 if (zmgr
->unreachable
[i
].last
< last
) {
8172 last
= zmgr
->unreachable
[i
].last
;
8176 if (i
< UNREACH_CHACHE_SIZE
) {
8178 * Found a existing entry. Update the expire timer and
8179 * last usage timestamps.
8181 zmgr
->unreachable
[i
].expire
= seconds
+ UNREACH_HOLD_TIME
;
8182 zmgr
->unreachable
[i
].last
= seconds
;
8183 } else if (slot
!= UNREACH_CHACHE_SIZE
) {
8185 * Found a empty slot. Add a new entry to the cache.
8187 zmgr
->unreachable
[slot
].expire
= seconds
+ UNREACH_HOLD_TIME
;
8188 zmgr
->unreachable
[slot
].last
= seconds
;
8189 zmgr
->unreachable
[slot
].remote
= *remote
;
8190 zmgr
->unreachable
[slot
].local
= *local
;
8193 * Replace the least recently used entry in the cache.
8195 zmgr
->unreachable
[oldest
].expire
= seconds
+ UNREACH_HOLD_TIME
;
8196 zmgr
->unreachable
[oldest
].last
= seconds
;
8197 zmgr
->unreachable
[oldest
].remote
= *remote
;
8198 zmgr
->unreachable
[oldest
].local
= *local
;
8200 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
8204 dns_zone_forcereload(dns_zone_t
*zone
) {
8205 REQUIRE(DNS_ZONE_VALID(zone
));
8207 if (zone
->type
== dns_zone_master
)
8211 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
8213 dns_zone_refresh(zone
);
8217 dns_zone_isforced(dns_zone_t
*zone
) {
8218 REQUIRE(DNS_ZONE_VALID(zone
));
8220 return (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
));
8224 dns_zone_setstatistics(dns_zone_t
*zone
, isc_boolean_t on
) {
8226 * This function is obsoleted.
8230 return (ISC_R_NOTIMPLEMENTED
);
8234 dns_zone_getstatscounters(dns_zone_t
*zone
) {
8236 * This function is obsoleted.
8243 dns_zone_setstats(dns_zone_t
*zone
, isc_stats_t
*stats
) {
8244 REQUIRE(DNS_ZONE_VALID(zone
));
8245 REQUIRE(zone
->stats
== NULL
);
8249 isc_stats_attach(stats
, &zone
->stats
);
8254 dns_zone_setrequeststats(dns_zone_t
*zone
, isc_stats_t
*stats
) {
8255 REQUIRE(DNS_ZONE_VALID(zone
));
8258 if (zone
->requeststats_on
&& stats
== NULL
)
8259 zone
->requeststats_on
= ISC_FALSE
;
8260 else if (!zone
->requeststats_on
&& stats
!= NULL
) {
8261 if (zone
->requeststats
== NULL
) {
8262 isc_stats_attach(stats
, &zone
->requeststats
);
8263 zone
->requeststats_on
= ISC_TRUE
;
8272 dns_zone_getrequeststats(dns_zone_t
*zone
) {
8274 * We don't lock zone for efficiency reason. This is not catastrophic
8275 * because requeststats must always be valid when requeststats_on is
8277 * Some counters may be incremented while requeststats_on is becoming
8278 * false, or some cannot be incremented just after the statistics are
8279 * installed, but it shouldn't matter much in practice.
8281 if (zone
->requeststats_on
)
8282 return (zone
->requeststats
);
8288 dns_zone_dialup(dns_zone_t
*zone
) {
8290 REQUIRE(DNS_ZONE_VALID(zone
));
8292 zone_debuglog(zone
, "dns_zone_dialup", 3,
8293 "notify = %d, refresh = %d",
8294 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
),
8295 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
));
8297 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
8298 dns_zone_notify(zone
);
8299 if (zone
->type
!= dns_zone_master
&&
8300 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
8301 dns_zone_refresh(zone
);
8305 dns_zone_setdialup(dns_zone_t
*zone
, dns_dialuptype_t dialup
) {
8306 REQUIRE(DNS_ZONE_VALID(zone
));
8309 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
|
8310 DNS_ZONEFLG_DIALREFRESH
|
8311 DNS_ZONEFLG_NOREFRESH
);
8313 case dns_dialuptype_no
:
8315 case dns_dialuptype_yes
:
8316 DNS_ZONE_SETFLAG(zone
, (DNS_ZONEFLG_DIALNOTIFY
|
8317 DNS_ZONEFLG_DIALREFRESH
|
8318 DNS_ZONEFLG_NOREFRESH
));
8320 case dns_dialuptype_notify
:
8321 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
8323 case dns_dialuptype_notifypassive
:
8324 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
8325 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
8327 case dns_dialuptype_refresh
:
8328 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALREFRESH
);
8329 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
8331 case dns_dialuptype_passive
:
8332 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
8341 dns_zone_setkeydirectory(dns_zone_t
*zone
, const char *directory
) {
8342 isc_result_t result
= ISC_R_SUCCESS
;
8344 REQUIRE(DNS_ZONE_VALID(zone
));
8347 result
= dns_zone_setstring(zone
, &zone
->keydirectory
, directory
);
8354 dns_zone_getkeydirectory(dns_zone_t
*zone
) {
8355 REQUIRE(DNS_ZONE_VALID(zone
));
8357 return (zone
->keydirectory
);
8361 dns_zonemgr_getcount(dns_zonemgr_t
*zmgr
, int state
) {
8363 unsigned int count
= 0;
8365 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
8367 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
8369 case DNS_ZONESTATE_XFERRUNNING
:
8370 for (zone
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
8372 zone
= ISC_LIST_NEXT(zone
, statelink
))
8375 case DNS_ZONESTATE_XFERDEFERRED
:
8376 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
8378 zone
= ISC_LIST_NEXT(zone
, statelink
))
8381 case DNS_ZONESTATE_SOAQUERY
:
8382 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
8384 zone
= ISC_LIST_NEXT(zone
, link
))
8385 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
))
8388 case DNS_ZONESTATE_ANY
:
8389 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
8391 zone
= ISC_LIST_NEXT(zone
, link
)) {
8392 dns_view_t
*view
= zone
->view
;
8393 if (view
!= NULL
&& strcmp(view
->name
, "_bind") == 0)
8402 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
8408 dns_zone_checknames(dns_zone_t
*zone
, dns_name_t
*name
, dns_rdata_t
*rdata
) {
8409 isc_boolean_t ok
= ISC_TRUE
;
8410 isc_boolean_t fail
= ISC_FALSE
;
8411 char namebuf
[DNS_NAME_FORMATSIZE
];
8412 char namebuf2
[DNS_NAME_FORMATSIZE
];
8413 char typebuf
[DNS_RDATATYPE_FORMATSIZE
];
8414 int level
= ISC_LOG_WARNING
;
8417 REQUIRE(DNS_ZONE_VALID(zone
));
8419 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMES
))
8420 return (ISC_R_SUCCESS
);
8422 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
)) {
8423 level
= ISC_LOG_ERROR
;
8427 ok
= dns_rdata_checkowner(name
, rdata
->rdclass
, rdata
->type
, ISC_TRUE
);
8429 dns_name_format(name
, namebuf
, sizeof(namebuf
));
8430 dns_rdatatype_format(rdata
->type
, typebuf
, sizeof(typebuf
));
8431 dns_zone_log(zone
, level
, "%s/%s: %s", namebuf
, typebuf
,
8432 dns_result_totext(DNS_R_BADOWNERNAME
));
8434 return (DNS_R_BADOWNERNAME
);
8437 dns_name_init(&bad
, NULL
);
8438 ok
= dns_rdata_checknames(rdata
, name
, &bad
);
8440 dns_name_format(name
, namebuf
, sizeof(namebuf
));
8441 dns_name_format(&bad
, namebuf2
, sizeof(namebuf2
));
8442 dns_rdatatype_format(rdata
->type
, typebuf
, sizeof(typebuf
));
8443 dns_zone_log(zone
, level
, "%s/%s: %s: %s ", namebuf
, typebuf
,
8444 namebuf2
, dns_result_totext(DNS_R_BADNAME
));
8446 return (DNS_R_BADNAME
);
8449 return (ISC_R_SUCCESS
);
8453 dns_zone_setcheckmx(dns_zone_t
*zone
, dns_checkmxfunc_t checkmx
) {
8454 REQUIRE(DNS_ZONE_VALID(zone
));
8455 zone
->checkmx
= checkmx
;
8459 dns_zone_setchecksrv(dns_zone_t
*zone
, dns_checksrvfunc_t checksrv
) {
8460 REQUIRE(DNS_ZONE_VALID(zone
));
8461 zone
->checksrv
= checksrv
;
8465 dns_zone_setcheckns(dns_zone_t
*zone
, dns_checknsfunc_t checkns
) {
8466 REQUIRE(DNS_ZONE_VALID(zone
));
8467 zone
->checkns
= checkns
;
8471 dns_zone_setisself(dns_zone_t
*zone
, dns_isselffunc_t isself
, void *arg
) {
8472 REQUIRE(DNS_ZONE_VALID(zone
));
8475 zone
->isself
= isself
;
8476 zone
->isselfarg
= arg
;
8481 dns_zone_setnotifydelay(dns_zone_t
*zone
, isc_uint32_t delay
) {
8482 REQUIRE(DNS_ZONE_VALID(zone
));
8485 zone
->notifydelay
= delay
;
8490 dns_zone_getnotifydelay(dns_zone_t
*zone
) {
8491 REQUIRE(DNS_ZONE_VALID(zone
));
8493 return (zone
->notifydelay
);