2 * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and 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.333.2.23.2.65 2006/07/19 01:04:24 marka Exp $ */
23 #include <isc/mutex.h>
24 #include <isc/print.h>
25 #include <isc/random.h>
26 #include <isc/ratelimiter.h>
27 #include <isc/refcount.h>
28 #include <isc/serial.h>
29 #include <isc/string.h>
30 #include <isc/taskpool.h>
31 #include <isc/timer.h>
36 #include <dns/callbacks.h>
38 #include <dns/events.h>
39 #include <dns/journal.h>
41 #include <dns/master.h>
42 #include <dns/masterdump.h>
43 #include <dns/message.h>
46 #include <dns/rcode.h>
47 #include <dns/rdataclass.h>
48 #include <dns/rdatalist.h>
49 #include <dns/rdataset.h>
50 #include <dns/rdatastruct.h>
51 #include <dns/rdatatype.h>
52 #include <dns/request.h>
53 #include <dns/resolver.h>
54 #include <dns/result.h>
55 #include <dns/stats.h>
58 #include <dns/xfrin.h>
61 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
62 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
64 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
65 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
67 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
68 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
70 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
71 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
73 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
74 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
76 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
77 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
79 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
80 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
83 * Ensure 'a' is at least 'min' but not more than 'max'.
85 #define RANGE(a, min, max) \
86 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
91 #define DNS_DEFAULT_IDLEIN 3600 /* 1 hour */
92 #define DNS_DEFAULT_IDLEOUT 3600 /* 1 hour */
93 #define MAX_XFER_TIME (2*3600) /* Documented default is 2 hours */
95 #ifndef DNS_MAX_EXPIRE
96 #define DNS_MAX_EXPIRE 14515200 /* 24 weeks */
99 #ifndef DNS_DUMP_DELAY
100 #define DNS_DUMP_DELAY 900 /* 15 minutes */
103 typedef struct dns_notify dns_notify_t
;
104 typedef struct dns_stub dns_stub_t
;
105 typedef struct dns_load dns_load_t
;
106 typedef struct dns_forward dns_forward_t
;
107 typedef struct dns_io dns_io_t
;
108 typedef ISC_LIST(dns_io_t
) dns_iolist_t
;
110 #define DNS_ZONE_CHECKLOCK
111 #ifdef DNS_ZONE_CHECKLOCK
112 #define LOCK_ZONE(z) \
113 do { LOCK(&(z)->lock); \
114 INSIST((z)->locked == ISC_FALSE); \
115 (z)->locked = ISC_TRUE; \
117 #define UNLOCK_ZONE(z) \
118 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
119 #define LOCKED_ZONE(z) ((z)->locked)
121 #define LOCK_ZONE(z) LOCK(&(z)->lock)
122 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
123 #define LOCKED_ZONE(z) ISC_TRUE
130 #ifdef DNS_ZONE_CHECKLOCK
131 isc_boolean_t locked
;
134 isc_refcount_t erefs
;
139 ISC_LINK(dns_zone_t
) link
; /* Used by zmgr. */
145 isc_int32_t journalsize
;
146 dns_rdataclass_t rdclass
;
149 unsigned int options
;
150 unsigned int db_argc
;
152 isc_time_t expiretime
;
153 isc_time_t refreshtime
;
157 isc_uint32_t refresh
;
160 isc_uint32_t minimum
;
163 isc_uint32_t maxrefresh
;
164 isc_uint32_t minrefresh
;
165 isc_uint32_t maxretry
;
166 isc_uint32_t minretry
;
168 isc_sockaddr_t
*masters
;
169 dns_name_t
**masterkeynames
;
170 isc_boolean_t
*mastersok
;
171 unsigned int masterscnt
;
172 unsigned int curmaster
;
173 isc_sockaddr_t masteraddr
;
174 dns_notifytype_t notifytype
;
175 isc_sockaddr_t
*notify
;
176 unsigned int notifycnt
;
177 isc_sockaddr_t notifyfrom
;
179 isc_sockaddr_t notifysrc4
;
180 isc_sockaddr_t notifysrc6
;
181 isc_sockaddr_t xfrsource4
;
182 isc_sockaddr_t xfrsource6
;
183 isc_sockaddr_t altxfrsource4
;
184 isc_sockaddr_t altxfrsource6
;
185 isc_sockaddr_t sourceaddr
;
186 dns_xfrin_ctx_t
*xfr
; /* task locked */
187 dns_tsigkey_t
*tsigkey
; /* key used for xfr */
188 /* Access Control Lists */
189 dns_acl_t
*update_acl
;
190 dns_acl_t
*forward_acl
;
191 dns_acl_t
*notify_acl
;
192 dns_acl_t
*query_acl
;
194 isc_boolean_t update_disabled
;
195 dns_severity_t check_names
;
196 ISC_LIST(dns_notify_t
) notifies
;
197 dns_request_t
*request
;
202 isc_uint32_t maxxfrin
;
203 isc_uint32_t maxxfrout
;
205 isc_uint32_t idleout
;
206 isc_event_t ctlevent
;
207 dns_ssutable_t
*ssutable
;
208 isc_uint32_t sigvalidityinterval
;
211 * Zones in certain states such as "waiting for zone transfer"
212 * or "zone transfer in progress" are kept on per-state linked lists
213 * in the zone manager using the 'statelink' field. The 'statelist'
214 * field points at the list the zone is currently on. It the zone
215 * is not on any such list, statelist is NULL.
217 ISC_LINK(dns_zone_t
) statelink
;
218 dns_zonelist_t
*statelist
;
220 * Optional per-zone statistics counters (NULL if not present).
222 isc_uint64_t
*counters
;
225 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
226 #define DNS_ZONE_SETFLAG(z,f) do { \
227 INSIST(LOCKED_ZONE(z)); \
230 #define DNS_ZONE_CLRFLAG(z,f) do { \
231 INSIST(LOCKED_ZONE(z)); \
232 (z)->flags &= ~(f); \
234 /* XXX MPA these may need to go back into zone.h */
235 #define DNS_ZONEFLG_REFRESH 0x00000001U /* refresh check in progress */
236 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /* zone need consolidation */
237 #define DNS_ZONEFLG_USEVC 0x00000004U /* use tcp for refresh query */
238 #define DNS_ZONEFLG_DUMPING 0x00000008U /* a dump is in progress */
239 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /* $INCLUDE in zone file */
240 #define DNS_ZONEFLG_LOADED 0x00000020U /* database has loaded */
241 #define DNS_ZONEFLG_EXITING 0x00000040U /* zone is being destroyed */
242 #define DNS_ZONEFLG_EXPIRED 0x00000080U /* zone has expired */
243 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /* refresh check needed */
244 #define DNS_ZONEFLG_UPTODATE 0x00000200U /* zone contents are
246 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /* need to send out notify
248 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /* generate a journal diff on
250 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /* an attempt to refresh a
251 * zone with no masters
253 #define DNS_ZONEFLG_LOADING 0x00002000U /* load from disk in progress*/
254 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /* timer values have been set
255 * from SOA (if not set, we
257 * default timer values) */
258 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /* Force a zone xfer */
259 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
260 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
261 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
262 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
263 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /* IXFR failed, force AXFR */
264 #define DNS_ZONEFLG_FLUSH 0x00200000U
265 #define DNS_ZONEFLG_NOEDNS 0x00400000U
266 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
267 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
269 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
271 /* Flags for zone_load() */
272 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
277 int refs
; /* Locked by rwlock */
278 isc_taskmgr_t
* taskmgr
;
279 isc_timermgr_t
* timermgr
;
280 isc_socketmgr_t
* socketmgr
;
281 isc_taskpool_t
* zonetasks
;
283 isc_ratelimiter_t
* rl
;
287 /* Locked by rwlock. */
288 dns_zonelist_t zones
;
289 dns_zonelist_t waiting_for_xfrin
;
290 dns_zonelist_t xfrin_in_progress
;
292 /* Configuration data. */
293 isc_uint32_t transfersin
;
294 isc_uint32_t transfersperns
;
295 unsigned int serialqueryrate
;
297 /* Locked by iolock */
298 isc_uint32_t iolimit
;
299 isc_uint32_t ioactive
;
313 dns_request_t
*request
;
316 ISC_LINK(dns_notify_t
) link
;
319 #define DNS_NOTIFY_NOSOA 0x0001U
322 * dns_stub holds state while performing a 'stub' transfer.
323 * 'db' is the zone's 'db' or a new one if this is the initial
332 dns_dbversion_t
*version
;
344 dns_rdatacallbacks_t callbacks
;
348 * Hold forward state.
354 isc_buffer_t
*msgbuf
;
355 dns_request_t
*request
;
358 dns_updatecallback_t callback
;
363 * Hold IO request state.
370 ISC_LINK(dns_io_t
) link
;
374 #define SEND_BUFFER_SIZE 2048
376 static void zone_settimer(dns_zone_t
*, isc_time_t
*);
377 static void cancel_refresh(dns_zone_t
*);
378 static void zone_debuglog(dns_zone_t
*zone
, const char *, int debuglevel
,
379 const char *msg
, ...) ISC_FORMAT_PRINTF(4, 5);
380 static void notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...)
381 ISC_FORMAT_PRINTF(3, 4);
382 static void queue_xfrin(dns_zone_t
*zone
);
383 static void zone_unload(dns_zone_t
*zone
);
384 static void zone_expire(dns_zone_t
*zone
);
385 static void zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
);
386 static void zone_idetach(dns_zone_t
**zonep
);
387 static isc_result_t
zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
,
389 static isc_result_t
default_journal(dns_zone_t
*zone
);
390 static void zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
);
391 static isc_result_t
zone_postload(dns_zone_t
*zone
, dns_db_t
*db
,
392 isc_time_t loadtime
, isc_result_t result
);
393 static void zone_needdump(dns_zone_t
*zone
, unsigned int delay
);
394 static void zone_shutdown(isc_task_t
*, isc_event_t
*);
395 static void zone_loaddone(void *arg
, isc_result_t result
);
396 static isc_result_t
zone_startload(dns_db_t
*db
, dns_zone_t
*zone
,
397 isc_time_t loadtime
);
400 /* ondestroy example */
401 static void dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
);
404 static void refresh_callback(isc_task_t
*, isc_event_t
*);
405 static void stub_callback(isc_task_t
*, isc_event_t
*);
406 static void queue_soa_query(dns_zone_t
*zone
);
407 static void soa_query(isc_task_t
*, isc_event_t
*);
408 static void ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
,
410 static int message_count(dns_message_t
*msg
, dns_section_t section
,
411 dns_rdatatype_t type
);
412 static void notify_cancel(dns_zone_t
*zone
);
413 static void notify_find_address(dns_notify_t
*notify
);
414 static void notify_send(dns_notify_t
*notify
);
415 static isc_result_t
notify_createmessage(dns_zone_t
*zone
,
417 dns_message_t
**messagep
);
418 static void notify_done(isc_task_t
*task
, isc_event_t
*event
);
419 static void notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
);
420 static isc_result_t
zone_dump(dns_zone_t
*, isc_boolean_t
);
421 static void got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
);
422 static isc_result_t
zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
,
424 static void zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
);
425 static void zonemgr_free(dns_zonemgr_t
*zmgr
);
426 static isc_result_t
zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
427 isc_task_t
*task
, isc_taskaction_t action
,
428 void *arg
, dns_io_t
**iop
);
429 static void zonemgr_putio(dns_io_t
**iop
);
430 static void zonemgr_cancelio(dns_io_t
*io
);
433 zone_get_from_db(dns_db_t
*db
, dns_name_t
*origin
, unsigned int *nscount
,
434 unsigned int *soacount
, isc_uint32_t
*serial
,
435 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
436 isc_uint32_t
*expire
, isc_uint32_t
*minimum
);
438 static void zone_freedbargs(dns_zone_t
*zone
);
439 static void forward_callback(isc_task_t
*task
, isc_event_t
*event
);
440 static void zone_saveunique(dns_zone_t
*zone
, const char *path
,
441 const char *templat
);
442 static void zone_maintenance(dns_zone_t
*zone
);
443 static void zone_notify(dns_zone_t
*zone
);
444 static void dump_done(void *arg
, isc_result_t result
);
446 #define ENTER zone_debuglog(zone, me, 1, "enter")
448 static const unsigned int dbargc_default
= 1;
449 static const char *dbargv_default
[] = { "rbt" };
451 #define DNS_ZONE_JITTER_ADD(a, b, c) \
455 _j = isc_random_jitter((b), (b)/4); \
456 isc_interval_set(&_i, _j, 0); \
457 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
458 dns_zone_log(zone, ISC_LOG_WARNING, \
459 "epoch approaching: upgrade required: " \
460 "now + %s failed", #b); \
461 isc_interval_set(&_i, _j/2, 0); \
462 (void)isc_time_add((a), &_i, (c)); \
466 #define DNS_ZONE_TIME_ADD(a, b, c) \
469 isc_interval_set(&_i, (b), 0); \
470 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
471 dns_zone_log(zone, ISC_LOG_WARNING, \
472 "epoch approaching: upgrade required: " \
473 "now + %s failed", #b); \
474 isc_interval_set(&_i, (b)/2, 0); \
475 (void)isc_time_add((a), &_i, (c)); \
480 *** Public functions.
484 dns_zone_create(dns_zone_t
**zonep
, isc_mem_t
*mctx
) {
488 REQUIRE(zonep
!= NULL
&& *zonep
== NULL
);
489 REQUIRE(mctx
!= NULL
);
491 zone
= isc_mem_get(mctx
, sizeof(*zone
));
493 return (ISC_R_NOMEMORY
);
495 result
= isc_mutex_init(&zone
->lock
);
496 if (result
!= ISC_R_SUCCESS
) {
497 isc_mem_put(mctx
, zone
, sizeof(*zone
));
498 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
499 "isc_mutex_init() failed: %s",
500 isc_result_totext(result
));
501 return (ISC_R_UNEXPECTED
);
504 /* XXX MPA check that all elements are initialised */
506 #ifdef DNS_ZONE_CHECKLOCK
507 zone
->locked
= ISC_FALSE
;
509 isc_mem_attach(mctx
, &zone
->mctx
);
512 ISC_LINK_INIT(zone
, link
);
513 isc_refcount_init(&zone
->erefs
, 1); /* Implicit attach. */
515 dns_name_init(&zone
->origin
, NULL
);
516 zone
->masterfile
= NULL
;
517 zone
->keydirectory
= NULL
;
518 zone
->journalsize
= -1;
519 zone
->journal
= NULL
;
520 zone
->rdclass
= dns_rdataclass_none
;
521 zone
->type
= dns_zone_none
;
525 zone
->db_argv
= NULL
;
526 isc_time_settoepoch(&zone
->expiretime
);
527 isc_time_settoepoch(&zone
->refreshtime
);
528 isc_time_settoepoch(&zone
->dumptime
);
529 isc_time_settoepoch(&zone
->loadtime
);
531 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
532 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
535 zone
->maxrefresh
= DNS_ZONE_MAXREFRESH
;
536 zone
->minrefresh
= DNS_ZONE_MINREFRESH
;
537 zone
->maxretry
= DNS_ZONE_MAXRETRY
;
538 zone
->minretry
= DNS_ZONE_MINRETRY
;
539 zone
->masters
= NULL
;
540 zone
->masterkeynames
= NULL
;
541 zone
->mastersok
= NULL
;
542 zone
->masterscnt
= 0;
545 zone
->notifytype
= dns_notifytype_yes
;
548 zone
->update_acl
= NULL
;
549 zone
->forward_acl
= NULL
;
550 zone
->notify_acl
= NULL
;
551 zone
->query_acl
= NULL
;
552 zone
->xfr_acl
= NULL
;
553 zone
->update_disabled
= ISC_FALSE
;
554 zone
->check_names
= dns_severity_ignore
;
555 zone
->request
= NULL
;
559 zone
->writeio
= NULL
;
561 zone
->idlein
= DNS_DEFAULT_IDLEIN
;
562 zone
->idleout
= DNS_DEFAULT_IDLEOUT
;
563 ISC_LIST_INIT(zone
->notifies
);
564 isc_sockaddr_any(&zone
->notifysrc4
);
565 isc_sockaddr_any6(&zone
->notifysrc6
);
566 isc_sockaddr_any(&zone
->xfrsource4
);
567 isc_sockaddr_any6(&zone
->xfrsource6
);
568 isc_sockaddr_any(&zone
->altxfrsource4
);
569 isc_sockaddr_any6(&zone
->altxfrsource6
);
571 zone
->tsigkey
= NULL
;
572 zone
->maxxfrin
= MAX_XFER_TIME
;
573 zone
->maxxfrout
= MAX_XFER_TIME
;
574 zone
->ssutable
= NULL
;
575 zone
->sigvalidityinterval
= 30 * 24 * 3600;
577 ISC_LINK_INIT(zone
, statelink
);
578 zone
->statelist
= NULL
;
579 zone
->counters
= NULL
;
581 zone
->magic
= ZONE_MAGIC
;
583 /* Must be after magic is set. */
584 result
= dns_zone_setdbtype(zone
, dbargc_default
, dbargv_default
);
585 if (result
!= ISC_R_SUCCESS
)
588 ISC_EVENT_INIT(&zone
->ctlevent
, sizeof(zone
->ctlevent
), 0, NULL
,
589 DNS_EVENT_ZONECONTROL
, zone_shutdown
, zone
, zone
,
592 return (ISC_R_SUCCESS
);
595 DESTROYLOCK(&zone
->lock
);
596 isc_mem_putanddetach(&zone
->mctx
, zone
, sizeof(*zone
));
601 * Free a zone. Because we require that there be no more
602 * outstanding events or references, no locking is necessary.
605 zone_free(dns_zone_t
*zone
) {
606 isc_mem_t
*mctx
= NULL
;
608 REQUIRE(DNS_ZONE_VALID(zone
));
609 REQUIRE(isc_refcount_current(&zone
->erefs
) == 0);
610 REQUIRE(zone
->irefs
== 0);
611 REQUIRE(!LOCKED_ZONE(zone
));
612 REQUIRE(zone
->timer
== NULL
);
615 * Managed objects. Order is important.
617 if (zone
->request
!= NULL
)
618 dns_request_destroy(&zone
->request
); /* XXXMPA */
619 INSIST(zone
->readio
== NULL
);
620 INSIST(zone
->statelist
== NULL
);
621 INSIST(zone
->writeio
== NULL
);
623 if (zone
->task
!= NULL
)
624 isc_task_detach(&zone
->task
);
626 dns_zonemgr_releasezone(zone
->zmgr
, zone
);
628 /* Unmanaged objects */
629 if (zone
->masterfile
!= NULL
)
630 isc_mem_free(zone
->mctx
, zone
->masterfile
);
631 zone
->masterfile
= NULL
;
632 if (zone
->keydirectory
!= NULL
)
633 isc_mem_free(zone
->mctx
, zone
->keydirectory
);
634 zone
->keydirectory
= NULL
;
635 zone
->journalsize
= -1;
636 if (zone
->journal
!= NULL
)
637 isc_mem_free(zone
->mctx
, zone
->journal
);
638 zone
->journal
= NULL
;
639 if (zone
->counters
!= NULL
)
640 dns_stats_freecounters(zone
->mctx
, &zone
->counters
);
641 if (zone
->db
!= NULL
)
642 dns_db_detach(&zone
->db
);
643 zone_freedbargs(zone
);
644 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone
, NULL
, NULL
, 0)
646 RUNTIME_CHECK(dns_zone_setalsonotify(zone
, NULL
, 0)
648 zone
->check_names
= dns_severity_ignore
;
649 if (zone
->update_acl
!= NULL
)
650 dns_acl_detach(&zone
->update_acl
);
651 if (zone
->forward_acl
!= NULL
)
652 dns_acl_detach(&zone
->forward_acl
);
653 if (zone
->notify_acl
!= NULL
)
654 dns_acl_detach(&zone
->notify_acl
);
655 if (zone
->query_acl
!= NULL
)
656 dns_acl_detach(&zone
->query_acl
);
657 if (zone
->xfr_acl
!= NULL
)
658 dns_acl_detach(&zone
->xfr_acl
);
659 if (dns_name_dynamic(&zone
->origin
))
660 dns_name_free(&zone
->origin
, zone
->mctx
);
661 if (zone
->ssutable
!= NULL
)
662 dns_ssutable_detach(&zone
->ssutable
);
665 DESTROYLOCK(&zone
->lock
);
666 isc_refcount_destroy(&zone
->erefs
);
669 isc_mem_put(mctx
, zone
, sizeof(*zone
));
670 isc_mem_detach(&mctx
);
677 dns_zone_setclass(dns_zone_t
*zone
, dns_rdataclass_t rdclass
) {
679 REQUIRE(DNS_ZONE_VALID(zone
));
680 REQUIRE(rdclass
!= dns_rdataclass_none
);
686 REQUIRE(zone
->rdclass
== dns_rdataclass_none
||
687 zone
->rdclass
== rdclass
);
688 zone
->rdclass
= rdclass
;
693 dns_zone_getclass(dns_zone_t
*zone
){
694 REQUIRE(DNS_ZONE_VALID(zone
));
696 return (zone
->rdclass
);
700 dns_zone_setnotifytype(dns_zone_t
*zone
, dns_notifytype_t notifytype
) {
701 REQUIRE(DNS_ZONE_VALID(zone
));
704 zone
->notifytype
= notifytype
;
712 dns_zone_settype(dns_zone_t
*zone
, dns_zonetype_t type
) {
714 REQUIRE(DNS_ZONE_VALID(zone
));
715 REQUIRE(type
!= dns_zone_none
);
721 REQUIRE(zone
->type
== dns_zone_none
|| zone
->type
== type
);
727 zone_freedbargs(dns_zone_t
*zone
) {
730 /* Free the old database argument list. */
731 if (zone
->db_argv
!= NULL
) {
732 for (i
= 0; i
< zone
->db_argc
; i
++)
733 isc_mem_free(zone
->mctx
, zone
->db_argv
[i
]);
734 isc_mem_put(zone
->mctx
, zone
->db_argv
,
735 zone
->db_argc
* sizeof(*zone
->db_argv
));
738 zone
->db_argv
= NULL
;
742 dns_zone_setdbtype(dns_zone_t
*zone
,
743 unsigned int dbargc
, const char * const *dbargv
) {
744 isc_result_t result
= ISC_R_SUCCESS
;
748 REQUIRE(DNS_ZONE_VALID(zone
));
749 REQUIRE(dbargc
>= 1);
750 REQUIRE(dbargv
!= NULL
);
754 /* Set up a new database argument list. */
755 new = isc_mem_get(zone
->mctx
, dbargc
* sizeof(*new));
758 for (i
= 0; i
< dbargc
; i
++)
760 for (i
= 0; i
< dbargc
; i
++) {
761 new[i
] = isc_mem_strdup(zone
->mctx
, dbargv
[i
]);
766 /* Free the old list. */
767 zone_freedbargs(zone
);
769 zone
->db_argc
= dbargc
;
771 result
= ISC_R_SUCCESS
;
776 for (i
= 0; i
< dbargc
; i
++)
778 isc_mem_free(zone
->mctx
, new[i
]);
779 isc_mem_put(zone
->mctx
, new, dbargc
* sizeof(*new));
781 result
= ISC_R_NOMEMORY
;
789 dns_zone_setview(dns_zone_t
*zone
, dns_view_t
*view
) {
790 REQUIRE(DNS_ZONE_VALID(zone
));
793 if (zone
->view
!= NULL
)
794 dns_view_weakdetach(&zone
->view
);
795 dns_view_weakattach(view
, &zone
->view
);
801 dns_zone_getview(dns_zone_t
*zone
) {
802 REQUIRE(DNS_ZONE_VALID(zone
));
809 dns_zone_setorigin(dns_zone_t
*zone
, const dns_name_t
*origin
) {
812 REQUIRE(DNS_ZONE_VALID(zone
));
813 REQUIRE(origin
!= NULL
);
816 if (dns_name_dynamic(&zone
->origin
)) {
817 dns_name_free(&zone
->origin
, zone
->mctx
);
818 dns_name_init(&zone
->origin
, NULL
);
820 result
= dns_name_dup(origin
, zone
->mctx
, &zone
->origin
);
827 dns_zone_setstring(dns_zone_t
*zone
, char **field
, const char *value
) {
831 copy
= isc_mem_strdup(zone
->mctx
, value
);
833 return (ISC_R_NOMEMORY
);
839 isc_mem_free(zone
->mctx
, *field
);
842 return (ISC_R_SUCCESS
);
846 dns_zone_setfile(dns_zone_t
*zone
, const char *file
) {
847 isc_result_t result
= ISC_R_SUCCESS
;
849 REQUIRE(DNS_ZONE_VALID(zone
));
852 result
= dns_zone_setstring(zone
, &zone
->masterfile
, file
);
853 if (result
== ISC_R_SUCCESS
)
854 result
= default_journal(zone
);
861 dns_zone_getfile(dns_zone_t
*zone
) {
862 REQUIRE(DNS_ZONE_VALID(zone
));
864 return (zone
->masterfile
);
868 default_journal(dns_zone_t
*zone
) {
872 REQUIRE(DNS_ZONE_VALID(zone
));
873 REQUIRE(LOCKED_ZONE(zone
));
875 if (zone
->masterfile
!= NULL
) {
876 /* Calculate string length including '\0'. */
877 int len
= strlen(zone
->masterfile
) + sizeof(".jnl");
878 journal
= isc_mem_allocate(zone
->mctx
, len
);
880 return (ISC_R_NOMEMORY
);
881 strcpy(journal
, zone
->masterfile
);
882 strcat(journal
, ".jnl");
886 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
888 isc_mem_free(zone
->mctx
, journal
);
893 dns_zone_setjournal(dns_zone_t
*zone
, const char *journal
) {
894 isc_result_t result
= ISC_R_SUCCESS
;
896 REQUIRE(DNS_ZONE_VALID(zone
));
899 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
906 dns_zone_getjournal(dns_zone_t
*zone
) {
907 REQUIRE(DNS_ZONE_VALID(zone
));
909 return (zone
->journal
);
913 * Return true iff the zone is "dynamic", in the sense that the zone's
914 * master file (if any) is written by the server, rather than being
915 * updated manually and read by the server.
917 * This is true for slave zones, stub zones, and zones that allow
918 * dynamic updates either by having an update policy ("ssutable")
919 * or an "allow-update" ACL with a value other than exactly "{ none; }".
922 zone_isdynamic(dns_zone_t
*zone
) {
923 REQUIRE(DNS_ZONE_VALID(zone
));
925 return (ISC_TF(zone
->type
== dns_zone_slave
||
926 zone
->type
== dns_zone_stub
||
927 (!zone
->update_disabled
&& zone
->ssutable
!= NULL
) ||
928 (!zone
->update_disabled
&& zone
->update_acl
!= NULL
&&
929 ! (zone
->update_acl
->length
== 1 &&
930 zone
->update_acl
->elements
[0].negative
== ISC_TRUE
932 zone
->update_acl
->elements
[0].type
==
933 dns_aclelementtype_any
))));
938 zone_load(dns_zone_t
*zone
, unsigned int flags
) {
941 isc_time_t loadtime
, filetime
;
944 REQUIRE(DNS_ZONE_VALID(zone
));
949 INSIST(zone
->type
!= dns_zone_none
);
951 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
952 result
= ISC_R_SUCCESS
;
956 if (zone
->db
!= NULL
&& zone
->masterfile
== NULL
) {
958 * The zone has no master file configured, but it already
959 * has a database. It could be the built-in
960 * version.bind. CH zone, a zone with a persistent
961 * database being reloaded, or maybe a zone that
962 * used to have a master file but whose configuration
963 * was changed so that it no longer has one. Do nothing.
965 result
= ISC_R_SUCCESS
;
969 if (zone
->db
!= NULL
&& zone_isdynamic(zone
)) {
971 * This is a slave, stub, or dynamically updated
972 * zone being reloaded. Do nothing - the database
973 * we already have is guaranteed to be up-to-date.
975 if (zone
->type
== dns_zone_master
)
976 result
= DNS_R_DYNAMIC
;
978 result
= ISC_R_SUCCESS
;
983 * Don't do the load if the file that stores the zone is older
984 * than the last time the zone was loaded. If the zone has not
985 * been loaded yet, zone->loadtime will be the epoch.
987 if (zone
->masterfile
!= NULL
&& ! isc_time_isepoch(&zone
->loadtime
)) {
989 * The file is already loaded. If we are just doing a
990 * "rndc reconfig", we are done.
992 if ((flags
& DNS_ZONELOADFLAG_NOSTAT
) != 0) {
993 result
= ISC_R_SUCCESS
;
996 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HASINCLUDE
)) {
997 result
= isc_file_getmodtime(zone
->masterfile
,
999 if (result
== ISC_R_SUCCESS
&&
1000 isc_time_compare(&filetime
, &zone
->loadtime
) <= 0) {
1001 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1002 "skipping load: master file older "
1004 result
= DNS_R_UPTODATE
;
1010 INSIST(zone
->db_argc
>= 1);
1013 * Built in zones don't need to be reloaded.
1015 if (zone
->type
== dns_zone_master
&&
1016 strcmp(zone
->db_argv
[0], "_builtin") == 0 &&
1017 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
1018 result
= ISC_R_SUCCESS
;
1022 if ((zone
->type
== dns_zone_slave
|| zone
->type
== dns_zone_stub
) &&
1023 (strcmp(zone
->db_argv
[0], "rbt") == 0 ||
1024 strcmp(zone
->db_argv
[0], "rbt64") == 0)) {
1025 if (zone
->masterfile
== NULL
||
1026 !isc_file_exists(zone
->masterfile
)) {
1027 if (zone
->masterfile
!= NULL
)
1028 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1030 zone
->refreshtime
= now
;
1031 if (zone
->task
!= NULL
)
1032 zone_settimer(zone
, &now
);
1033 result
= ISC_R_SUCCESS
;
1038 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "starting load");
1041 * Store the current time before the zone is loaded, so that if the
1042 * file changes between the time of the load and the time that
1043 * zone->loadtime is set, then the file will still be reloaded
1044 * the next time dns_zone_load is called.
1046 TIME_NOW(&loadtime
);
1048 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
1049 &zone
->origin
, (zone
->type
== dns_zone_stub
) ?
1050 dns_dbtype_stub
: dns_dbtype_zone
,
1052 zone
->db_argc
- 1, zone
->db_argv
+ 1,
1055 if (result
!= ISC_R_SUCCESS
) {
1056 dns_zone_log(zone
, ISC_LOG_ERROR
,
1057 "loading zone: creating database: %s",
1058 isc_result_totext(result
));
1061 dns_db_settask(db
, zone
->task
);
1063 if (! dns_db_ispersistent(db
)) {
1064 if (zone
->masterfile
!= NULL
) {
1065 result
= zone_startload(db
, zone
, loadtime
);
1067 result
= DNS_R_NOMASTERFILE
;
1068 if (zone
->type
== dns_zone_master
) {
1069 dns_zone_log(zone
, ISC_LOG_ERROR
,
1071 "no master file configured");
1074 dns_zone_log(zone
, ISC_LOG_INFO
, "loading zone: "
1075 "no master file configured: continuing");
1079 if (result
== DNS_R_CONTINUE
) {
1080 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADING
);
1084 result
= zone_postload(zone
, db
, loadtime
, result
);
1094 dns_zone_load(dns_zone_t
*zone
) {
1095 return (zone_load(zone
, 0));
1099 dns_zone_loadnew(dns_zone_t
*zone
) {
1100 return (zone_load(zone
, DNS_ZONELOADFLAG_NOSTAT
));
1104 zone_gotreadhandle(isc_task_t
*task
, isc_event_t
*event
) {
1105 dns_load_t
*load
= event
->ev_arg
;
1106 isc_result_t result
= ISC_R_SUCCESS
;
1107 unsigned int options
;
1109 REQUIRE(DNS_LOAD_VALID(load
));
1111 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
1112 result
= ISC_R_CANCELED
;
1113 isc_event_free(&event
);
1114 if (result
== ISC_R_CANCELED
)
1117 options
= DNS_MASTER_ZONE
;
1118 if (load
->zone
->type
== dns_zone_slave
)
1119 options
|= DNS_MASTER_SLAVE
;
1120 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKNS
))
1121 options
|= DNS_MASTER_CHECKNS
;
1122 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_FATALNS
))
1123 options
|= DNS_MASTER_FATALNS
;
1124 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKNAMES
))
1125 options
|= DNS_MASTER_CHECKNAMES
;
1126 if (DNS_ZONE_OPTION(load
->zone
, DNS_ZONEOPT_CHECKNAMESFAIL
))
1127 options
|= DNS_MASTER_CHECKNAMESFAIL
;
1128 result
= dns_master_loadfileinc(load
->zone
->masterfile
,
1129 dns_db_origin(load
->db
),
1130 dns_db_origin(load
->db
),
1131 load
->zone
->rdclass
,
1133 &load
->callbacks
, task
,
1134 zone_loaddone
, load
,
1135 &load
->zone
->lctx
, load
->zone
->mctx
);
1136 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_CONTINUE
&&
1137 result
!= DNS_R_SEENINCLUDE
)
1142 zone_loaddone(load
, result
);
1146 zone_gotwritehandle(isc_task_t
*task
, isc_event_t
*event
) {
1147 const char me
[] = "zone_gotwritehandle";
1148 dns_zone_t
*zone
= event
->ev_arg
;
1149 isc_result_t result
= ISC_R_SUCCESS
;
1150 dns_dbversion_t
*version
= NULL
;
1152 REQUIRE(DNS_ZONE_VALID(zone
));
1153 INSIST(task
== zone
->task
);
1156 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
1157 result
= ISC_R_CANCELED
;
1158 isc_event_free(&event
);
1159 if (result
== ISC_R_CANCELED
)
1163 dns_db_currentversion(zone
->db
, &version
);
1164 result
= dns_master_dumpinc(zone
->mctx
, zone
->db
, version
,
1165 &dns_master_style_default
,
1166 zone
->masterfile
, zone
->task
,
1167 dump_done
, zone
, &zone
->dctx
);
1168 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
1170 if (result
!= DNS_R_CONTINUE
)
1175 dump_done(zone
, result
);
1179 zone_startload(dns_db_t
*db
, dns_zone_t
*zone
, isc_time_t loadtime
) {
1181 isc_result_t result
;
1182 isc_result_t tresult
;
1183 unsigned int options
;
1185 options
= DNS_MASTER_ZONE
;
1186 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MANYERRORS
))
1187 options
|= DNS_MASTER_MANYERRORS
;
1188 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNS
))
1189 options
|= DNS_MASTER_CHECKNS
;
1190 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_FATALNS
))
1191 options
|= DNS_MASTER_FATALNS
;
1192 if (zone
->type
== dns_zone_slave
)
1193 options
|= DNS_MASTER_SLAVE
;
1194 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMES
))
1195 options
|= DNS_MASTER_CHECKNAMES
;
1196 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
))
1197 options
|= DNS_MASTER_CHECKNAMESFAIL
;
1199 if (zone
->zmgr
!= NULL
&& zone
->db
!= NULL
&& zone
->task
!= NULL
) {
1200 load
= isc_mem_get(zone
->mctx
, sizeof(*load
));
1202 return (ISC_R_NOMEMORY
);
1207 load
->loadtime
= loadtime
;
1208 load
->magic
= LOAD_MAGIC
;
1210 isc_mem_attach(zone
->mctx
, &load
->mctx
);
1211 zone_iattach(zone
, &load
->zone
);
1212 dns_db_attach(db
, &load
->db
);
1213 dns_rdatacallbacks_init(&load
->callbacks
);
1214 result
= dns_db_beginload(db
, &load
->callbacks
.add
,
1215 &load
->callbacks
.add_private
);
1216 if (result
!= ISC_R_SUCCESS
)
1218 result
= zonemgr_getio(zone
->zmgr
, ISC_TRUE
, zone
->task
,
1219 zone_gotreadhandle
, load
,
1221 if (result
!= ISC_R_SUCCESS
) {
1223 * We can't report multiple errors so ignore
1224 * the result of dns_db_endload().
1226 (void)dns_db_endload(load
->db
,
1227 &load
->callbacks
.add_private
);
1230 result
= DNS_R_CONTINUE
;
1232 dns_rdatacallbacks_t callbacks
;
1234 dns_rdatacallbacks_init(&callbacks
);
1235 result
= dns_db_beginload(db
, &callbacks
.add
,
1236 &callbacks
.add_private
);
1237 if (result
!= ISC_R_SUCCESS
)
1239 result
= dns_master_loadfile(zone
->masterfile
, &zone
->origin
,
1240 &zone
->origin
, zone
->rdclass
,
1241 options
, &callbacks
, zone
->mctx
);
1242 tresult
= dns_db_endload(db
, &callbacks
.add_private
);
1243 if (result
== ISC_R_SUCCESS
)
1251 dns_db_detach(&load
->db
);
1252 zone_idetach(&load
->zone
);
1253 isc_mem_detach(&load
->mctx
);
1254 isc_mem_put(zone
->mctx
, load
, sizeof(*load
));
1259 zone_postload(dns_zone_t
*zone
, dns_db_t
*db
, isc_time_t loadtime
,
1260 isc_result_t result
)
1262 unsigned int soacount
= 0;
1263 unsigned int nscount
= 0;
1264 isc_uint32_t serial
, refresh
, retry
, expire
, minimum
;
1266 isc_boolean_t needdump
= ISC_FALSE
;
1267 isc_boolean_t hasinclude
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
1272 * Initiate zone transfer? We may need a error code that
1273 * indicates that the "permanent" form does not exist.
1274 * XXX better error feedback to log.
1276 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_SEENINCLUDE
) {
1277 if (zone
->type
== dns_zone_slave
||
1278 zone
->type
== dns_zone_stub
) {
1279 if (result
== ISC_R_FILENOTFOUND
)
1280 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1282 else if (result
!= DNS_R_NOMASTERFILE
)
1283 dns_zone_log(zone
, ISC_LOG_ERROR
,
1284 "loading master file %s: %s",
1286 dns_result_totext(result
));
1288 dns_zone_log(zone
, ISC_LOG_ERROR
,
1289 "loading master file %s: %s",
1291 dns_result_totext(result
));
1295 dns_zone_log(zone
, ISC_LOG_DEBUG(2),
1296 "number of nodes in database: %u",
1297 dns_db_nodecount(db
));
1299 if (result
== DNS_R_SEENINCLUDE
)
1300 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
1302 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
1305 * Apply update log, if any, on initial load.
1307 if (zone
->journal
!= NULL
&&
1308 ! DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOMERGE
) &&
1309 ! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
1311 result
= dns_journal_rollforward(zone
->mctx
, db
,
1313 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
&&
1314 result
!= DNS_R_UPTODATE
&& result
!= DNS_R_NOJOURNAL
&&
1315 result
!= ISC_R_RANGE
) {
1316 dns_zone_log(zone
, ISC_LOG_ERROR
,
1317 "journal rollforward failed: %s",
1318 dns_result_totext(result
));
1321 if (result
== ISC_R_NOTFOUND
|| result
== ISC_R_RANGE
) {
1322 dns_zone_log(zone
, ISC_LOG_ERROR
,
1323 "journal rollforward failed: "
1324 "journal out of sync with zone");
1327 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1328 "journal rollforward completed "
1330 dns_result_totext(result
));
1331 if (result
== ISC_R_SUCCESS
)
1332 needdump
= ISC_TRUE
;
1335 zone
->loadtime
= loadtime
;
1337 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "loaded");
1340 * Obtain ns and soa counts for top of zone.
1345 result
= zone_get_from_db(db
, &zone
->origin
, &nscount
,
1346 &soacount
, &serial
, &refresh
, &retry
,
1348 if (result
!= ISC_R_SUCCESS
) {
1349 dns_zone_log(zone
, ISC_LOG_ERROR
,
1350 "could not find NS and/or SOA records");
1354 * Master / Slave / Stub zones require both NS and SOA records at
1355 * the top of the zone.
1358 switch (zone
->type
) {
1359 case dns_zone_master
:
1360 case dns_zone_slave
:
1362 if (soacount
!= 1) {
1363 dns_zone_log(zone
, ISC_LOG_ERROR
,
1364 "has %d SOA records", soacount
);
1365 result
= DNS_R_BADZONE
;
1368 dns_zone_log(zone
, ISC_LOG_ERROR
,
1369 "has no NS records");
1370 result
= DNS_R_BADZONE
;
1372 if (result
!= ISC_R_SUCCESS
)
1374 if (zone
->db
!= NULL
) {
1376 * This is checked in zone_replacedb() for slave zones
1377 * as they don't reload from disk.
1379 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
) &&
1380 !isc_serial_gt(serial
, zone
->serial
)) {
1381 isc_uint32_t serialmin
, serialmax
;
1383 INSIST(zone
->type
== dns_zone_master
);
1385 serialmin
= (zone
->serial
+ 1) & 0xffffffffU
;
1386 serialmax
= (zone
->serial
+ 0x7fffffffU
) &
1388 dns_zone_log(zone
, ISC_LOG_ERROR
,
1389 "ixfr-from-differences: "
1390 "new serial (%u) out of range "
1391 "[%u - %u]", serial
, serialmin
,
1393 result
= DNS_R_BADZONE
;
1395 } else if (!isc_serial_ge(serial
, zone
->serial
))
1396 dns_zone_log(zone
, ISC_LOG_ERROR
,
1397 "zone serial has gone backwards");
1398 else if (serial
== zone
->serial
&& !hasinclude
)
1399 dns_zone_log(zone
, ISC_LOG_ERROR
,
1400 "zone serial unchanged");
1402 zone
->serial
= serial
;
1403 zone
->refresh
= RANGE(refresh
,
1404 zone
->minrefresh
, zone
->maxrefresh
);
1405 zone
->retry
= RANGE(retry
,
1406 zone
->minretry
, zone
->maxretry
);
1407 zone
->expire
= RANGE(expire
, zone
->refresh
+ zone
->retry
,
1409 zone
->minimum
= minimum
;
1410 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
1412 if (zone
->type
== dns_zone_slave
||
1413 zone
->type
== dns_zone_stub
) {
1417 result
= isc_file_getmodtime(zone
->journal
, &t
);
1418 if (result
!= ISC_R_SUCCESS
)
1419 result
= isc_file_getmodtime(zone
->masterfile
,
1421 if (result
== ISC_R_SUCCESS
)
1422 DNS_ZONE_TIME_ADD(&t
, zone
->expire
,
1425 DNS_ZONE_TIME_ADD(&now
, zone
->retry
,
1428 delay
= isc_random_jitter(zone
->retry
,
1429 (zone
->retry
* 3) / 4);
1430 DNS_ZONE_TIME_ADD(&now
, delay
, &zone
->refreshtime
);
1431 if (isc_time_compare(&zone
->refreshtime
,
1432 &zone
->expiretime
) >= 0)
1433 zone
->refreshtime
= now
;
1437 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
1438 "unexpected zone type %d", zone
->type
);
1439 result
= ISC_R_UNEXPECTED
;
1445 /* destroy notification example. */
1447 isc_event_t
*e
= isc_event_allocate(zone
->mctx
, NULL
,
1448 DNS_EVENT_DBDESTROYED
,
1449 dns_zonemgr_dbdestroyed
,
1451 sizeof(isc_event_t
));
1452 dns_db_ondestroy(db
, zone
->task
, &e
);
1456 if (zone
->db
!= NULL
) {
1457 result
= zone_replacedb(zone
, db
, ISC_FALSE
);
1458 if (result
!= ISC_R_SUCCESS
)
1461 dns_db_attach(db
, &zone
->db
);
1462 DNS_ZONE_SETFLAG(zone
,
1463 DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
1465 result
= ISC_R_SUCCESS
;
1467 zone_needdump(zone
, DNS_DUMP_DELAY
);
1468 if (zone
->task
!= NULL
)
1469 zone_settimer(zone
, &now
);
1471 if (! dns_db_ispersistent(db
))
1472 dns_zone_log(zone
, ISC_LOG_INFO
, "loaded serial %u%s",
1474 dns_db_issecure(db
) ? " (signed)" : "");
1479 if (zone
->type
== dns_zone_slave
||
1480 zone
->type
== dns_zone_stub
) {
1481 if (zone
->journal
!= NULL
)
1482 zone_saveunique(zone
, zone
->journal
, "jn-XXXXXXXX");
1483 if (zone
->masterfile
!= NULL
)
1484 zone_saveunique(zone
, zone
->masterfile
, "db-XXXXXXXX");
1486 /* Mark the zone for immediate refresh. */
1487 zone
->refreshtime
= now
;
1488 if (zone
->task
!= NULL
)
1489 zone_settimer(zone
, &now
);
1490 result
= ISC_R_SUCCESS
;
1495 static isc_boolean_t
1496 exit_check(dns_zone_t
*zone
) {
1498 REQUIRE(LOCKED_ZONE(zone
));
1500 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SHUTDOWN
) &&
1504 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
1506 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
1513 zone_count_ns_rr(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
1514 unsigned int *nscount
)
1516 isc_result_t result
;
1518 dns_rdataset_t rdataset
;
1520 REQUIRE(nscount
!= NULL
);
1522 dns_rdataset_init(&rdataset
);
1523 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_ns
,
1524 dns_rdatatype_none
, 0, &rdataset
, NULL
);
1525 if (result
== ISC_R_NOTFOUND
) {
1527 result
= ISC_R_SUCCESS
;
1528 goto invalidate_rdataset
;
1530 if (result
!= ISC_R_SUCCESS
)
1531 goto invalidate_rdataset
;
1534 result
= dns_rdataset_first(&rdataset
);
1535 while (result
== ISC_R_SUCCESS
) {
1537 result
= dns_rdataset_next(&rdataset
);
1539 dns_rdataset_disassociate(&rdataset
);
1542 result
= ISC_R_SUCCESS
;
1544 invalidate_rdataset
:
1545 dns_rdataset_invalidate(&rdataset
);
1551 zone_load_soa_rr(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
1552 unsigned int *soacount
,
1553 isc_uint32_t
*serial
, isc_uint32_t
*refresh
,
1554 isc_uint32_t
*retry
, isc_uint32_t
*expire
,
1555 isc_uint32_t
*minimum
)
1557 isc_result_t result
;
1559 dns_rdataset_t rdataset
;
1560 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1561 dns_rdata_soa_t soa
;
1563 dns_rdataset_init(&rdataset
);
1564 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_soa
,
1565 dns_rdatatype_none
, 0, &rdataset
, NULL
);
1566 if (result
== ISC_R_NOTFOUND
) {
1567 if (soacount
!= NULL
)
1571 if (refresh
!= NULL
)
1577 if (minimum
!= NULL
)
1579 result
= ISC_R_SUCCESS
;
1580 goto invalidate_rdataset
;
1582 if (result
!= ISC_R_SUCCESS
)
1583 goto invalidate_rdataset
;
1586 result
= dns_rdataset_first(&rdataset
);
1587 while (result
== ISC_R_SUCCESS
) {
1588 dns_rdata_init(&rdata
);
1589 dns_rdataset_current(&rdataset
, &rdata
);
1592 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
1593 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1596 result
= dns_rdataset_next(&rdataset
);
1597 dns_rdata_reset(&rdata
);
1599 dns_rdataset_disassociate(&rdataset
);
1601 if (soacount
!= NULL
)
1606 *serial
= soa
.serial
;
1607 if (refresh
!= NULL
)
1608 *refresh
= soa
.refresh
;
1612 *expire
= soa
.expire
;
1613 if (minimum
!= NULL
)
1614 *minimum
= soa
.minimum
;
1617 result
= ISC_R_SUCCESS
;
1619 invalidate_rdataset
:
1620 dns_rdataset_invalidate(&rdataset
);
1626 * zone must be locked.
1629 zone_get_from_db(dns_db_t
*db
, dns_name_t
*origin
, unsigned int *nscount
,
1630 unsigned int *soacount
, isc_uint32_t
*serial
,
1631 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
1632 isc_uint32_t
*expire
, isc_uint32_t
*minimum
)
1634 dns_dbversion_t
*version
;
1635 isc_result_t result
;
1636 isc_result_t answer
= ISC_R_SUCCESS
;
1639 REQUIRE(db
!= NULL
);
1640 REQUIRE(origin
!= NULL
);
1643 dns_db_currentversion(db
, &version
);
1646 result
= dns_db_findnode(db
, origin
, ISC_FALSE
, &node
);
1647 if (result
!= ISC_R_SUCCESS
) {
1652 if (nscount
!= NULL
) {
1653 result
= zone_count_ns_rr(db
, node
, version
, nscount
);
1654 if (result
!= ISC_R_SUCCESS
)
1658 if (soacount
!= NULL
|| serial
!= NULL
|| refresh
!= NULL
1659 || retry
!= NULL
|| expire
!= NULL
|| minimum
!= NULL
) {
1660 result
= zone_load_soa_rr(db
, node
, version
, soacount
,
1661 serial
, refresh
, retry
, expire
,
1663 if (result
!= ISC_R_SUCCESS
)
1667 dns_db_detachnode(db
, &node
);
1669 dns_db_closeversion(db
, &version
, ISC_FALSE
);
1675 dns_zone_attach(dns_zone_t
*source
, dns_zone_t
**target
) {
1676 REQUIRE(DNS_ZONE_VALID(source
));
1677 REQUIRE(target
!= NULL
&& *target
== NULL
);
1678 isc_refcount_increment(&source
->erefs
, NULL
);
1683 dns_zone_detach(dns_zone_t
**zonep
) {
1686 isc_boolean_t free_now
= ISC_FALSE
;
1688 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
1692 isc_refcount_decrement(&zone
->erefs
, &refs
);
1697 * We just detached the last external reference.
1699 if (zone
->task
!= NULL
) {
1701 * This zone is being managed. Post
1702 * its control event and let it clean
1703 * up synchronously in the context of
1706 isc_event_t
*ev
= &zone
->ctlevent
;
1707 isc_task_send(zone
->task
, &ev
);
1710 * This zone is not being managed; it has
1711 * no task and can have no outstanding
1712 * events. Free it immediately.
1715 * Unmanaged zones should not have non-null views;
1716 * we have no way of detaching from the view here
1717 * without causing deadlock because this code is called
1718 * with the view already locked.
1720 INSIST(zone
->view
== NULL
);
1721 free_now
= ISC_TRUE
;
1731 dns_zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
1732 REQUIRE(DNS_ZONE_VALID(source
));
1733 REQUIRE(target
!= NULL
&& *target
== NULL
);
1735 zone_iattach(source
, target
);
1736 UNLOCK_ZONE(source
);
1740 zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
1743 * 'source' locked by caller.
1745 REQUIRE(LOCKED_ZONE(source
));
1746 REQUIRE(DNS_ZONE_VALID(source
));
1747 REQUIRE(target
!= NULL
&& *target
== NULL
);
1748 INSIST(source
->irefs
+ isc_refcount_current(&source
->erefs
) > 0);
1750 INSIST(source
->irefs
!= 0);
1755 zone_idetach(dns_zone_t
**zonep
) {
1759 * 'zone' locked by caller.
1761 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
1763 REQUIRE(LOCKED_ZONE(*zonep
));
1766 INSIST(zone
->irefs
> 0);
1768 INSIST(zone
->irefs
+ isc_refcount_current(&zone
->erefs
) > 0);
1772 dns_zone_idetach(dns_zone_t
**zonep
) {
1774 isc_boolean_t free_needed
;
1776 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
1781 INSIST(zone
->irefs
> 0);
1783 free_needed
= exit_check(zone
);
1790 dns_zone_getmctx(dns_zone_t
*zone
) {
1791 REQUIRE(DNS_ZONE_VALID(zone
));
1793 return (zone
->mctx
);
1797 dns_zone_getmgr(dns_zone_t
*zone
) {
1798 REQUIRE(DNS_ZONE_VALID(zone
));
1800 return (zone
->zmgr
);
1804 dns_zone_setflag(dns_zone_t
*zone
, unsigned int flags
, isc_boolean_t value
) {
1805 REQUIRE(DNS_ZONE_VALID(zone
));
1809 DNS_ZONE_SETFLAG(zone
, flags
);
1811 DNS_ZONE_CLRFLAG(zone
, flags
);
1816 dns_zone_setoption(dns_zone_t
*zone
, unsigned int option
, isc_boolean_t value
)
1818 REQUIRE(DNS_ZONE_VALID(zone
));
1822 zone
->options
|= option
;
1824 zone
->options
&= ~option
;
1829 dns_zone_getoptions(dns_zone_t
*zone
) {
1831 REQUIRE(DNS_ZONE_VALID(zone
));
1833 return (zone
->options
);
1837 dns_zone_setxfrsource4(dns_zone_t
*zone
, const isc_sockaddr_t
*xfrsource
) {
1838 REQUIRE(DNS_ZONE_VALID(zone
));
1841 zone
->xfrsource4
= *xfrsource
;
1844 return (ISC_R_SUCCESS
);
1848 dns_zone_getxfrsource4(dns_zone_t
*zone
) {
1849 REQUIRE(DNS_ZONE_VALID(zone
));
1850 return (&zone
->xfrsource4
);
1854 dns_zone_setxfrsource6(dns_zone_t
*zone
, const isc_sockaddr_t
*xfrsource
) {
1855 REQUIRE(DNS_ZONE_VALID(zone
));
1858 zone
->xfrsource6
= *xfrsource
;
1861 return (ISC_R_SUCCESS
);
1865 dns_zone_getxfrsource6(dns_zone_t
*zone
) {
1866 REQUIRE(DNS_ZONE_VALID(zone
));
1867 return (&zone
->xfrsource6
);
1871 dns_zone_setaltxfrsource4(dns_zone_t
*zone
,
1872 const isc_sockaddr_t
*altxfrsource
)
1874 REQUIRE(DNS_ZONE_VALID(zone
));
1877 zone
->altxfrsource4
= *altxfrsource
;
1880 return (ISC_R_SUCCESS
);
1884 dns_zone_getaltxfrsource4(dns_zone_t
*zone
) {
1885 REQUIRE(DNS_ZONE_VALID(zone
));
1886 return (&zone
->altxfrsource4
);
1890 dns_zone_setaltxfrsource6(dns_zone_t
*zone
,
1891 const isc_sockaddr_t
*altxfrsource
)
1893 REQUIRE(DNS_ZONE_VALID(zone
));
1896 zone
->altxfrsource6
= *altxfrsource
;
1899 return (ISC_R_SUCCESS
);
1903 dns_zone_getaltxfrsource6(dns_zone_t
*zone
) {
1904 REQUIRE(DNS_ZONE_VALID(zone
));
1905 return (&zone
->altxfrsource6
);
1909 dns_zone_setnotifysrc4(dns_zone_t
*zone
, const isc_sockaddr_t
*notifysrc
) {
1910 REQUIRE(DNS_ZONE_VALID(zone
));
1913 zone
->notifysrc4
= *notifysrc
;
1916 return (ISC_R_SUCCESS
);
1920 dns_zone_getnotifysrc4(dns_zone_t
*zone
) {
1921 REQUIRE(DNS_ZONE_VALID(zone
));
1922 return (&zone
->notifysrc4
);
1926 dns_zone_setnotifysrc6(dns_zone_t
*zone
, const isc_sockaddr_t
*notifysrc
) {
1927 REQUIRE(DNS_ZONE_VALID(zone
));
1930 zone
->notifysrc6
= *notifysrc
;
1933 return (ISC_R_SUCCESS
);
1937 dns_zone_getnotifysrc6(dns_zone_t
*zone
) {
1938 REQUIRE(DNS_ZONE_VALID(zone
));
1939 return (&zone
->notifysrc6
);
1943 dns_zone_setalsonotify(dns_zone_t
*zone
, const isc_sockaddr_t
*notify
,
1946 isc_sockaddr_t
*new;
1948 REQUIRE(DNS_ZONE_VALID(zone
));
1949 REQUIRE(count
== 0 || notify
!= NULL
);
1952 if (zone
->notify
!= NULL
) {
1953 isc_mem_put(zone
->mctx
, zone
->notify
,
1954 zone
->notifycnt
* sizeof(*new));
1955 zone
->notify
= NULL
;
1956 zone
->notifycnt
= 0;
1959 new = isc_mem_get(zone
->mctx
, count
* sizeof(*new));
1962 return (ISC_R_NOMEMORY
);
1964 memcpy(new, notify
, count
* sizeof(*new));
1966 zone
->notifycnt
= count
;
1969 return (ISC_R_SUCCESS
);
1973 dns_zone_setmasters(dns_zone_t
*zone
, const isc_sockaddr_t
*masters
,
1976 isc_result_t result
;
1978 result
= dns_zone_setmasterswithkeys(zone
, masters
, NULL
, count
);
1983 dns_zone_setmasterswithkeys(dns_zone_t
*zone
,
1984 const isc_sockaddr_t
*masters
,
1985 dns_name_t
**keynames
,
1988 isc_sockaddr_t
*new;
1989 isc_result_t result
= ISC_R_SUCCESS
;
1990 dns_name_t
**newname
;
1991 isc_boolean_t
*newok
;
1994 REQUIRE(DNS_ZONE_VALID(zone
));
1995 REQUIRE(count
== 0 || masters
!= NULL
);
1996 if (keynames
!= NULL
) {
1997 REQUIRE(count
!= 0);
2001 if (zone
->masters
!= NULL
) {
2002 isc_mem_put(zone
->mctx
, zone
->masters
,
2003 zone
->masterscnt
* sizeof(*new));
2004 zone
->masters
= NULL
;
2006 if (zone
->masterkeynames
!= NULL
) {
2007 for (i
= 0; i
< zone
->masterscnt
; i
++) {
2008 if (zone
->masterkeynames
[i
] != NULL
) {
2009 dns_name_free(zone
->masterkeynames
[i
],
2011 isc_mem_put(zone
->mctx
,
2012 zone
->masterkeynames
[i
],
2013 sizeof(dns_name_t
));
2014 zone
->masterkeynames
[i
] = NULL
;
2017 isc_mem_put(zone
->mctx
, zone
->masterkeynames
,
2018 zone
->masterscnt
* sizeof(dns_name_t
*));
2019 zone
->masterkeynames
= NULL
;
2021 if (zone
->mastersok
!= NULL
) {
2022 isc_mem_put(zone
->mctx
, zone
->mastersok
,
2023 zone
->masterscnt
* sizeof(isc_boolean_t
));
2024 zone
->mastersok
= NULL
;
2026 zone
->masterscnt
= 0;
2028 * If count == 0, don't allocate any space for masters, mastersok or
2029 * keynames so internally, those pointers are NULL if count == 0
2035 * masters must countain count elements!
2037 new = isc_mem_get(zone
->mctx
, count
* sizeof(*new));
2039 result
= ISC_R_NOMEMORY
;
2042 memcpy(new, masters
, count
* sizeof(*new));
2045 * Similarly for mastersok.
2047 newok
= isc_mem_get(zone
->mctx
, count
* sizeof(*newok
));
2048 if (newok
== NULL
) {
2049 result
= ISC_R_NOMEMORY
;
2050 isc_mem_put(zone
->mctx
, new, count
* sizeof(*new));
2053 for (i
= 0; i
< count
; i
++)
2054 newok
[i
] = ISC_FALSE
;
2057 * if keynames is non-NULL, it must contain count elements!
2060 if (keynames
!= NULL
) {
2061 newname
= isc_mem_get(zone
->mctx
, count
* sizeof(*newname
));
2062 if (newname
== NULL
) {
2063 result
= ISC_R_NOMEMORY
;
2064 isc_mem_put(zone
->mctx
, new, count
* sizeof(*new));
2065 isc_mem_put(zone
->mctx
, newok
, count
* sizeof(*newok
));
2068 for (i
= 0; i
< count
; i
++)
2070 for (i
= 0; i
< count
; i
++) {
2071 if (keynames
[i
] != NULL
) {
2072 newname
[i
] = isc_mem_get(zone
->mctx
,
2073 sizeof(dns_name_t
));
2074 if (newname
[i
] == NULL
)
2076 dns_name_init(newname
[i
], NULL
);
2077 result
= dns_name_dup(keynames
[i
], zone
->mctx
,
2079 if (result
!= ISC_R_SUCCESS
) {
2081 for (i
= 0; i
< count
; i
++)
2082 if (newname
[i
] != NULL
)
2086 isc_mem_put(zone
->mctx
, new,
2087 count
* sizeof(*new));
2088 isc_mem_put(zone
->mctx
, newok
,
2089 count
* sizeof(*newok
));
2090 isc_mem_put(zone
->mctx
, newname
,
2091 count
* sizeof(*newname
));
2099 * Everything is ok so attach to the zone.
2101 zone
->masters
= new;
2102 zone
->mastersok
= newok
;
2103 zone
->masterkeynames
= newname
;
2104 zone
->masterscnt
= count
;
2105 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
2113 dns_zone_getdb(dns_zone_t
*zone
, dns_db_t
**dpb
) {
2114 isc_result_t result
= ISC_R_SUCCESS
;
2116 REQUIRE(DNS_ZONE_VALID(zone
));
2119 if (zone
->db
== NULL
)
2120 result
= DNS_R_NOTLOADED
;
2122 dns_db_attach(zone
->db
, dpb
);
2129 * Co-ordinates the starting of routine jobs.
2133 dns_zone_maintenance(dns_zone_t
*zone
) {
2134 const char me
[] = "dns_zone_maintenance";
2137 REQUIRE(DNS_ZONE_VALID(zone
));
2142 zone_settimer(zone
, &now
);
2146 static inline isc_boolean_t
2147 was_dumping(dns_zone_t
*zone
) {
2148 isc_boolean_t dumping
;
2150 REQUIRE(LOCKED_ZONE(zone
));
2152 dumping
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
);
2153 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
2155 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
2156 isc_time_settoepoch(&zone
->dumptime
);
2162 zone_maintenance(dns_zone_t
*zone
) {
2163 const char me
[] = "zone_maintenance";
2165 isc_result_t result
;
2166 isc_boolean_t dumping
;
2168 REQUIRE(DNS_ZONE_VALID(zone
));
2172 * Configuring the view of this zone may have
2173 * failed, for example because the config file
2174 * had a syntax error. In that case, the view
2175 * adb or resolver, and we had better not try
2176 * to do maintenance on it.
2178 if (zone
->view
== NULL
|| zone
->view
->adb
== NULL
)
2186 switch (zone
->type
) {
2187 case dns_zone_slave
:
2190 if (isc_time_compare(&now
, &zone
->expiretime
) >= 0 &&
2191 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
2193 zone
->refreshtime
= now
;
2204 switch (zone
->type
) {
2205 case dns_zone_slave
:
2207 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
) &&
2208 isc_time_compare(&now
, &zone
->refreshtime
) >= 0)
2209 dns_zone_refresh(zone
);
2216 * Do we need to consolidate the backing store?
2218 switch (zone
->type
) {
2219 case dns_zone_master
:
2220 case dns_zone_slave
:
2222 if (zone
->masterfile
!= NULL
&&
2223 isc_time_compare(&now
, &zone
->dumptime
) >= 0 &&
2224 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
2225 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
)) {
2226 dumping
= was_dumping(zone
);
2231 result
= zone_dump(zone
, ISC_TRUE
); /* task locked */
2232 if (result
!= ISC_R_SUCCESS
)
2233 dns_zone_log(zone
, ISC_LOG_WARNING
,
2235 dns_result_totext(result
));
2243 * Do we need to send out notify messages?
2245 switch (zone
->type
) {
2246 case dns_zone_master
:
2247 case dns_zone_slave
:
2248 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
2254 zone_settimer(zone
, &now
);
2258 dns_zone_markdirty(dns_zone_t
*zone
) {
2261 zone_needdump(zone
, DNS_DUMP_DELAY
);
2266 dns_zone_expire(dns_zone_t
*zone
) {
2267 REQUIRE(DNS_ZONE_VALID(zone
));
2275 zone_expire(dns_zone_t
*zone
) {
2277 * 'zone' locked by caller.
2280 REQUIRE(LOCKED_ZONE(zone
));
2282 dns_zone_log(zone
, ISC_LOG_WARNING
, "expired");
2284 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXPIRED
);
2285 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
2286 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
2287 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
2292 dns_zone_refresh(dns_zone_t
*zone
) {
2294 isc_uint32_t oldflags
;
2296 isc_result_t result
;
2298 REQUIRE(DNS_ZONE_VALID(zone
));
2300 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
2304 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
2305 * in progress at a time.
2309 oldflags
= zone
->flags
;
2310 if (zone
->masterscnt
== 0) {
2311 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
2312 if ((oldflags
& DNS_ZONEFLG_NOMASTERS
) == 0)
2313 dns_zone_log(zone
, ISC_LOG_ERROR
,
2314 "cannot refresh: no masters");
2317 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
2318 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
2319 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
2320 if ((oldflags
& (DNS_ZONEFLG_REFRESH
|DNS_ZONEFLG_LOADING
)) != 0)
2324 * Set the next refresh time as if refresh check has failed.
2325 * Setting this to the retry time will do that. XXXMLG
2326 * If we are successful it will be reset using zone->refresh.
2328 isc_interval_set(&i
, isc_random_jitter(zone
->retry
, zone
->retry
/ 4),
2330 result
= isc_time_nowplusinterval(&zone
->refreshtime
, &i
);
2331 if (result
|= ISC_R_SUCCESS
)
2332 dns_zone_log(zone
, ISC_LOG_WARNING
,
2333 "isc_time_nowplusinterval() failed: %s",
2334 dns_result_totext(result
));
2337 * When lacking user-specified timer values from the SOA,
2338 * do exponential backoff of the retry time up to a
2339 * maximum of six hours.
2341 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HAVETIMERS
))
2342 zone
->retry
= ISC_MIN(zone
->retry
* 2, 6 * 3600);
2344 zone
->curmaster
= 0;
2345 for (j
= 0; j
< zone
->masterscnt
; j
++)
2346 zone
->mastersok
[j
] = ISC_FALSE
;
2347 /* initiate soa query */
2348 queue_soa_query(zone
);
2354 dns_zone_flush(dns_zone_t
*zone
) {
2355 isc_result_t result
= ISC_R_SUCCESS
;
2356 isc_boolean_t dumping
;
2358 REQUIRE(DNS_ZONE_VALID(zone
));
2361 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FLUSH
);
2362 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
2363 zone
->masterfile
!= NULL
) {
2364 result
= ISC_R_ALREADYRUNNING
;
2365 dumping
= was_dumping(zone
);
2370 result
= zone_dump(zone
, ISC_FALSE
); /* Unknown task. */
2375 dns_zone_dump(dns_zone_t
*zone
) {
2376 isc_result_t result
= ISC_R_ALREADYRUNNING
;
2377 isc_boolean_t dumping
;
2379 REQUIRE(DNS_ZONE_VALID(zone
));
2382 dumping
= was_dumping(zone
);
2385 result
= zone_dump(zone
, ISC_FALSE
); /* Unknown task. */
2390 zone_needdump(dns_zone_t
*zone
, unsigned int delay
) {
2391 isc_time_t dumptime
;
2395 * 'zone' locked by caller
2398 REQUIRE(DNS_ZONE_VALID(zone
));
2399 REQUIRE(LOCKED_ZONE(zone
));
2402 * Do we have a place to dump to and are we loaded?
2404 if (zone
->masterfile
== NULL
||
2405 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) == 0)
2409 /* add some noise */
2410 DNS_ZONE_JITTER_ADD(&now
, delay
, &dumptime
);
2412 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
2413 if (isc_time_isepoch(&zone
->dumptime
) ||
2414 isc_time_compare(&zone
->dumptime
, &dumptime
) > 0)
2415 zone
->dumptime
= dumptime
;
2416 if (zone
->task
!= NULL
)
2417 zone_settimer(zone
, &now
);
2421 dump_done(void *arg
, isc_result_t result
) {
2422 const char me
[] = "dump_done";
2423 dns_zone_t
*zone
= arg
;
2425 dns_dbversion_t
*version
;
2426 isc_boolean_t again
= ISC_FALSE
;
2428 REQUIRE(DNS_ZONE_VALID(zone
));
2432 if (result
== ISC_R_SUCCESS
&& zone
->journal
!= NULL
&&
2433 zone
->journalsize
!= -1) {
2434 isc_uint32_t serial
;
2435 isc_result_t tresult
;
2438 * We don't own these, zone->dctx must stay valid.
2440 db
= dns_dumpctx_db(zone
->dctx
);
2441 version
= dns_dumpctx_version(zone
->dctx
);
2443 tresult
= dns_db_getsoaserial(db
, version
, &serial
);
2444 if (tresult
== ISC_R_SUCCESS
) {
2445 tresult
= dns_journal_compact(zone
->mctx
,
2452 case ISC_R_NOTFOUND
:
2453 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
2454 "dns_journal_compact: %s",
2455 dns_result_totext(tresult
));
2458 dns_zone_log(zone
, ISC_LOG_ERROR
,
2459 "dns_journal_compact failed: %s",
2460 dns_result_totext(tresult
));
2467 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
2468 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_CANCELED
) {
2470 * Try again in a short while.
2472 zone_needdump(zone
, DNS_DUMP_DELAY
);
2473 } else if (result
== ISC_R_SUCCESS
&&
2474 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
2475 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
2476 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
2477 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
2478 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
2479 isc_time_settoepoch(&zone
->dumptime
);
2481 } else if (result
== ISC_R_SUCCESS
)
2482 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FLUSH
);
2484 if (zone
->dctx
!= NULL
)
2485 dns_dumpctx_detach(&zone
->dctx
);
2486 zonemgr_putio(&zone
->writeio
);
2489 (void)zone_dump(zone
, ISC_FALSE
);
2490 dns_zone_idetach(&zone
);
2494 zone_dump(dns_zone_t
*zone
, isc_boolean_t compact
) {
2495 const char me
[] = "zone_dump";
2496 isc_result_t result
;
2497 dns_dbversion_t
*version
= NULL
;
2498 isc_boolean_t again
;
2499 dns_db_t
*db
= NULL
;
2500 char *masterfile
= NULL
;
2503 * 'compact' MUST only be set if we are task locked.
2506 REQUIRE(DNS_ZONE_VALID(zone
));
2511 if (zone
->db
!= NULL
)
2512 dns_db_attach(zone
->db
, &db
);
2513 if (zone
->masterfile
!= NULL
)
2514 masterfile
= isc_mem_strdup(zone
->mctx
, zone
->masterfile
);
2517 result
= DNS_R_NOTLOADED
;
2520 if (masterfile
== NULL
) {
2521 result
= DNS_R_NOMASTERFILE
;
2526 dns_zone_t
*dummy
= NULL
;
2528 zone_iattach(zone
, &dummy
);
2529 result
= zonemgr_getio(zone
->zmgr
, ISC_FALSE
, zone
->task
,
2530 zone_gotwritehandle
, zone
,
2532 if (result
!= ISC_R_SUCCESS
)
2533 zone_idetach(&dummy
);
2535 result
= DNS_R_CONTINUE
;
2538 dns_db_currentversion(db
, &version
);
2539 result
= dns_master_dump(zone
->mctx
, db
, version
,
2540 &dns_master_style_default
,
2542 dns_db_closeversion(db
, &version
, ISC_FALSE
);
2547 if (masterfile
!= NULL
)
2548 isc_mem_free(zone
->mctx
, masterfile
);
2551 if (result
== DNS_R_CONTINUE
)
2552 return (ISC_R_SUCCESS
); /* XXXMPA */
2556 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
2557 if (result
!= ISC_R_SUCCESS
) {
2559 * Try again in a short while.
2561 zone_needdump(zone
, DNS_DUMP_DELAY
);
2562 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
2563 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
2564 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
2565 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
2566 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
2567 isc_time_settoepoch(&zone
->dumptime
);
2570 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FLUSH
);
2579 dumptostream(dns_zone_t
*zone
, FILE *fd
, const dns_master_style_t
*style
) {
2580 isc_result_t result
;
2581 dns_dbversion_t
*version
= NULL
;
2582 dns_db_t
*db
= NULL
;
2584 REQUIRE(DNS_ZONE_VALID(zone
));
2587 if (zone
->db
!= NULL
)
2588 dns_db_attach(zone
->db
, &db
);
2591 return (DNS_R_NOTLOADED
);
2593 dns_db_currentversion(db
, &version
);
2594 result
= dns_master_dumptostream(zone
->mctx
, db
, version
, style
, fd
);
2595 dns_db_closeversion(db
, &version
, ISC_FALSE
);
2601 dns_zone_dumptostream(dns_zone_t
*zone
, FILE *fd
) {
2602 return dumptostream(zone
, fd
, &dns_master_style_default
);
2606 dns_zone_fulldumptostream(dns_zone_t
*zone
, FILE *fd
) {
2607 return dumptostream(zone
, fd
, &dns_master_style_full
);
2611 dns_zone_unload(dns_zone_t
*zone
) {
2612 REQUIRE(DNS_ZONE_VALID(zone
));
2620 notify_cancel(dns_zone_t
*zone
) {
2621 dns_notify_t
*notify
;
2624 * 'zone' locked by caller.
2627 REQUIRE(LOCKED_ZONE(zone
));
2629 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
2631 notify
= ISC_LIST_NEXT(notify
, link
)) {
2632 if (notify
->find
!= NULL
)
2633 dns_adb_cancelfind(notify
->find
);
2634 if (notify
->request
!= NULL
)
2635 dns_request_cancel(notify
->request
);
2640 zone_unload(dns_zone_t
*zone
) {
2643 * 'zone' locked by caller.
2646 REQUIRE(LOCKED_ZONE(zone
));
2648 dns_db_detach(&zone
->db
);
2649 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_LOADED
);
2650 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
2654 dns_zone_setminrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
2655 REQUIRE(DNS_ZONE_VALID(zone
));
2658 zone
->minrefresh
= val
;
2662 dns_zone_setmaxrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
2663 REQUIRE(DNS_ZONE_VALID(zone
));
2666 zone
->maxrefresh
= val
;
2670 dns_zone_setminretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
2671 REQUIRE(DNS_ZONE_VALID(zone
));
2674 zone
->minretry
= val
;
2678 dns_zone_setmaxretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
2679 REQUIRE(DNS_ZONE_VALID(zone
));
2682 zone
->maxretry
= val
;
2685 static isc_boolean_t
2686 notify_isqueued(dns_zone_t
*zone
, dns_name_t
*name
, isc_sockaddr_t
*addr
) {
2687 dns_notify_t
*notify
;
2689 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
2691 notify
= ISC_LIST_NEXT(notify
, link
)) {
2692 if (notify
->request
!= NULL
)
2694 if (name
!= NULL
&& dns_name_dynamic(¬ify
->ns
) &&
2695 dns_name_equal(name
, ¬ify
->ns
))
2697 if (addr
!= NULL
&& isc_sockaddr_equal(addr
, ¬ify
->dst
))
2704 notify_destroy(dns_notify_t
*notify
, isc_boolean_t locked
) {
2708 * Caller holds zone lock.
2710 REQUIRE(DNS_NOTIFY_VALID(notify
));
2712 if (notify
->zone
!= NULL
) {
2714 LOCK_ZONE(notify
->zone
);
2715 REQUIRE(LOCKED_ZONE(notify
->zone
));
2716 if (ISC_LINK_LINKED(notify
, link
))
2717 ISC_LIST_UNLINK(notify
->zone
->notifies
, notify
, link
);
2719 UNLOCK_ZONE(notify
->zone
);
2721 zone_idetach(¬ify
->zone
);
2723 dns_zone_idetach(¬ify
->zone
);
2725 if (notify
->find
!= NULL
)
2726 dns_adb_destroyfind(¬ify
->find
);
2727 if (notify
->request
!= NULL
)
2728 dns_request_destroy(¬ify
->request
);
2729 if (dns_name_dynamic(¬ify
->ns
))
2730 dns_name_free(¬ify
->ns
, notify
->mctx
);
2731 mctx
= notify
->mctx
;
2732 isc_mem_put(notify
->mctx
, notify
, sizeof(*notify
));
2733 isc_mem_detach(&mctx
);
2737 notify_create(isc_mem_t
*mctx
, unsigned int flags
, dns_notify_t
**notifyp
) {
2738 dns_notify_t
*notify
;
2740 REQUIRE(notifyp
!= NULL
&& *notifyp
== NULL
);
2742 notify
= isc_mem_get(mctx
, sizeof(*notify
));
2744 return (ISC_R_NOMEMORY
);
2746 notify
->mctx
= NULL
;
2747 isc_mem_attach(mctx
, ¬ify
->mctx
);
2748 notify
->flags
= flags
;
2749 notify
->zone
= NULL
;
2750 notify
->find
= NULL
;
2751 notify
->request
= NULL
;
2752 isc_sockaddr_any(¬ify
->dst
);
2753 dns_name_init(¬ify
->ns
, NULL
);
2754 ISC_LINK_INIT(notify
, link
);
2755 notify
->magic
= NOTIFY_MAGIC
;
2757 return (ISC_R_SUCCESS
);
2761 * XXXAG should check for DNS_ZONEFLG_EXITING
2764 process_adb_event(isc_task_t
*task
, isc_event_t
*ev
) {
2765 dns_notify_t
*notify
;
2766 isc_eventtype_t result
;
2770 notify
= ev
->ev_arg
;
2771 REQUIRE(DNS_NOTIFY_VALID(notify
));
2772 INSIST(task
== notify
->zone
->task
);
2773 result
= ev
->ev_type
;
2774 isc_event_free(&ev
);
2775 if (result
== DNS_EVENT_ADBMOREADDRESSES
) {
2776 dns_adb_destroyfind(¬ify
->find
);
2777 notify_find_address(notify
);
2780 if (result
== DNS_EVENT_ADBNOMOREADDRESSES
) {
2781 LOCK_ZONE(notify
->zone
);
2782 notify_send(notify
);
2783 UNLOCK_ZONE(notify
->zone
);
2785 notify_destroy(notify
, ISC_FALSE
);
2789 notify_find_address(dns_notify_t
*notify
) {
2790 isc_result_t result
;
2791 unsigned int options
;
2793 REQUIRE(DNS_NOTIFY_VALID(notify
));
2794 options
= DNS_ADBFIND_WANTEVENT
| DNS_ADBFIND_INET
|
2795 DNS_ADBFIND_INET6
| DNS_ADBFIND_RETURNLAME
;
2797 if (notify
->zone
->view
->adb
== NULL
)
2800 result
= dns_adb_createfind(notify
->zone
->view
->adb
,
2802 process_adb_event
, notify
,
2803 ¬ify
->ns
, dns_rootname
,
2805 notify
->zone
->view
->dstport
,
2808 /* Something failed? */
2809 if (result
!= ISC_R_SUCCESS
)
2812 /* More addresses pending? */
2813 if ((notify
->find
->options
& DNS_ADBFIND_WANTEVENT
) != 0)
2816 /* We have as many addresses as we can get. */
2817 LOCK_ZONE(notify
->zone
);
2818 notify_send(notify
);
2819 UNLOCK_ZONE(notify
->zone
);
2822 notify_destroy(notify
, ISC_FALSE
);
2827 notify_send_queue(dns_notify_t
*notify
) {
2829 isc_result_t result
;
2831 e
= isc_event_allocate(notify
->mctx
, NULL
,
2832 DNS_EVENT_NOTIFYSENDTOADDR
,
2834 notify
, sizeof(isc_event_t
));
2836 return (ISC_R_NOMEMORY
);
2838 e
->ev_sender
= NULL
;
2839 result
= isc_ratelimiter_enqueue(notify
->zone
->zmgr
->rl
,
2840 notify
->zone
->task
, &e
);
2841 if (result
!= ISC_R_SUCCESS
)
2847 notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
) {
2848 dns_notify_t
*notify
;
2849 isc_result_t result
;
2850 dns_message_t
*message
= NULL
;
2851 isc_netaddr_t dstip
;
2852 dns_tsigkey_t
*key
= NULL
;
2853 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
2857 notify
= event
->ev_arg
;
2858 REQUIRE(DNS_NOTIFY_VALID(notify
));
2862 LOCK_ZONE(notify
->zone
);
2864 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_LOADED
) == 0) {
2865 result
= ISC_R_CANCELED
;
2869 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0 ||
2870 DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_EXITING
) ||
2871 notify
->zone
->view
->requestmgr
== NULL
||
2872 notify
->zone
->db
== NULL
) {
2873 result
= ISC_R_CANCELED
;
2878 * The raw IPv4 address should also exist. Don't send to the
2881 if (isc_sockaddr_pf(¬ify
->dst
) == PF_INET6
&&
2882 IN6_IS_ADDR_V4MAPPED(¬ify
->dst
.type
.sin6
.sin6_addr
)) {
2883 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
2884 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
2885 "notify: ignoring IPv6 mapped IPV4 address: %s",
2887 result
= ISC_R_CANCELED
;
2891 result
= notify_createmessage(notify
->zone
, notify
->flags
, &message
);
2892 if (result
!= ISC_R_SUCCESS
)
2895 isc_netaddr_fromsockaddr(&dstip
, ¬ify
->dst
);
2896 (void)dns_view_getpeertsig(notify
->zone
->view
, &dstip
, &key
);
2898 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
2899 notify_log(notify
->zone
, ISC_LOG_DEBUG(3), "sending notify to %s",
2901 switch (isc_sockaddr_pf(¬ify
->dst
)) {
2903 src
= notify
->zone
->notifysrc4
;
2906 src
= notify
->zone
->notifysrc6
;
2909 result
= ISC_R_NOTIMPLEMENTED
;
2913 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_DIALNOTIFY
))
2915 result
= dns_request_createvia2(notify
->zone
->view
->requestmgr
,
2916 message
, &src
, ¬ify
->dst
, 0, key
,
2917 timeout
* 3, timeout
,
2918 notify
->zone
->task
, notify_done
,
2919 notify
, ¬ify
->request
);
2922 dns_tsigkey_detach(&key
);
2923 dns_message_destroy(&message
);
2925 UNLOCK_ZONE(notify
->zone
);
2926 if (result
!= ISC_R_SUCCESS
)
2927 notify_destroy(notify
, ISC_FALSE
);
2928 isc_event_free(&event
);
2932 notify_send(dns_notify_t
*notify
) {
2933 dns_adbaddrinfo_t
*ai
;
2935 isc_result_t result
;
2936 dns_notify_t
*new = NULL
;
2939 * Zone lock held by caller.
2941 REQUIRE(DNS_NOTIFY_VALID(notify
));
2942 REQUIRE(LOCKED_ZONE(notify
->zone
));
2944 for (ai
= ISC_LIST_HEAD(notify
->find
->list
);
2946 ai
= ISC_LIST_NEXT(ai
, publink
)) {
2948 if (notify_isqueued(notify
->zone
, NULL
, &dst
))
2951 result
= notify_create(notify
->mctx
,
2952 (notify
->flags
& DNS_NOTIFY_NOSOA
),
2954 if (result
!= ISC_R_SUCCESS
)
2956 zone_iattach(notify
->zone
, &new->zone
);
2957 ISC_LIST_APPEND(new->zone
->notifies
, new, link
);
2959 result
= notify_send_queue(new);
2960 if (result
!= ISC_R_SUCCESS
)
2967 notify_destroy(new, ISC_TRUE
);
2971 dns_zone_notify(dns_zone_t
*zone
) {
2974 REQUIRE(DNS_ZONE_VALID(zone
));
2977 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
2980 zone_settimer(zone
, &now
);
2985 zone_notify(dns_zone_t
*zone
) {
2986 dns_dbnode_t
*node
= NULL
;
2987 dns_dbversion_t
*version
= NULL
;
2988 dns_name_t
*origin
= NULL
;
2991 dns_rdata_soa_t soa
;
2992 isc_uint32_t serial
;
2993 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2994 dns_rdataset_t nsrdset
;
2995 dns_rdataset_t soardset
;
2996 isc_result_t result
;
2997 dns_notify_t
*notify
= NULL
;
3000 isc_boolean_t isqueued
;
3001 dns_notifytype_t notifytype
;
3002 unsigned int flags
= 0;
3003 isc_boolean_t loggednotify
= ISC_FALSE
;
3004 dns_db_t
*db
= NULL
;
3006 REQUIRE(DNS_ZONE_VALID(zone
));
3009 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
3010 notifytype
= zone
->notifytype
;
3013 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
3016 if (notifytype
== dns_notifytype_no
)
3020 if (zone
->db
!= NULL
)
3021 dns_db_attach(zone
->db
, &db
);
3026 origin
= &zone
->origin
;
3029 * If the zone is dialup we are done as we don't want to send
3030 * the current soa so as to force a refresh query.
3032 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
3033 flags
|= DNS_NOTIFY_NOSOA
;
3038 dns_db_currentversion(db
, &version
);
3039 result
= dns_db_findnode(db
, origin
, ISC_FALSE
, &node
);
3040 if (result
!= ISC_R_SUCCESS
)
3043 dns_rdataset_init(&soardset
);
3044 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_soa
,
3045 dns_rdatatype_none
, 0, &soardset
, NULL
);
3046 if (result
!= ISC_R_SUCCESS
)
3050 * Find serial and master server's name.
3052 dns_name_init(&master
, NULL
);
3053 result
= dns_rdataset_first(&soardset
);
3054 if (result
!= ISC_R_SUCCESS
)
3056 dns_rdataset_current(&soardset
, &rdata
);
3057 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
3058 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3059 dns_rdata_reset(&rdata
);
3060 result
= dns_name_dup(&soa
.origin
, zone
->mctx
, &master
);
3061 serial
= soa
.serial
;
3062 dns_rdataset_disassociate(&soardset
);
3063 if (result
!= ISC_R_SUCCESS
)
3067 * Enqueue notify requests for 'also-notify' servers.
3070 for (i
= 0; i
< zone
->notifycnt
; i
++) {
3071 dst
= zone
->notify
[i
];
3072 if (notify_isqueued(zone
, NULL
, &dst
))
3074 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
3075 if (result
!= ISC_R_SUCCESS
)
3077 zone_iattach(zone
, ¬ify
->zone
);
3079 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
3080 result
= notify_send_queue(notify
);
3081 if (result
!= ISC_R_SUCCESS
)
3082 notify_destroy(notify
, ISC_TRUE
);
3083 if (!loggednotify
) {
3084 notify_log(zone
, ISC_LOG_INFO
,
3085 "sending notifies (serial %u)",
3087 loggednotify
= ISC_TRUE
;
3093 if (notifytype
== dns_notifytype_explicit
)
3097 * Process NS RRset to generate notifies.
3100 dns_rdataset_init(&nsrdset
);
3101 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_ns
,
3102 dns_rdatatype_none
, 0, &nsrdset
, NULL
);
3103 if (result
!= ISC_R_SUCCESS
)
3106 result
= dns_rdataset_first(&nsrdset
);
3107 while (result
== ISC_R_SUCCESS
) {
3108 dns_rdataset_current(&nsrdset
, &rdata
);
3109 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
3110 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3111 dns_rdata_reset(&rdata
);
3113 * don't notify the master server.
3115 if (dns_name_compare(&master
, &ns
.name
) == 0) {
3116 result
= dns_rdataset_next(&nsrdset
);
3120 if (!loggednotify
) {
3121 notify_log(zone
, ISC_LOG_INFO
,
3122 "sending notifies (serial %u)",
3124 loggednotify
= ISC_TRUE
;
3128 isqueued
= notify_isqueued(zone
, &ns
.name
, NULL
);
3131 result
= dns_rdataset_next(&nsrdset
);
3134 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
3135 if (result
!= ISC_R_SUCCESS
)
3137 dns_zone_iattach(zone
, ¬ify
->zone
);
3138 result
= dns_name_dup(&ns
.name
, zone
->mctx
, ¬ify
->ns
);
3139 if (result
!= ISC_R_SUCCESS
) {
3141 notify_destroy(notify
, ISC_TRUE
);
3146 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
3148 notify_find_address(notify
);
3150 result
= dns_rdataset_next(&nsrdset
);
3152 dns_rdataset_disassociate(&nsrdset
);
3155 if (dns_name_dynamic(&master
))
3156 dns_name_free(&master
, zone
->mctx
);
3158 dns_db_detachnode(db
, &node
);
3160 dns_db_closeversion(db
, &version
, ISC_FALSE
);
3168 static inline isc_result_t
3169 save_nsrrset(dns_message_t
*message
, dns_name_t
*name
,
3170 dns_db_t
*db
, dns_dbversion_t
*version
)
3172 dns_rdataset_t
*nsrdataset
= NULL
;
3173 dns_rdataset_t
*rdataset
= NULL
;
3174 dns_dbnode_t
*node
= NULL
;
3176 isc_result_t result
;
3177 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3180 * Extract NS RRset from message.
3182 result
= dns_message_findname(message
, DNS_SECTION_ANSWER
, name
,
3183 dns_rdatatype_ns
, dns_rdatatype_none
,
3185 if (result
!= ISC_R_SUCCESS
)
3191 result
= dns_db_findnode(db
, name
, ISC_TRUE
, &node
);
3192 if (result
!= ISC_R_SUCCESS
)
3194 result
= dns_db_addrdataset(db
, node
, version
, 0,
3195 nsrdataset
, 0, NULL
);
3196 dns_db_detachnode(db
, &node
);
3197 if (result
!= ISC_R_SUCCESS
)
3200 * Add glue rdatasets.
3202 for (result
= dns_rdataset_first(nsrdataset
);
3203 result
== ISC_R_SUCCESS
;
3204 result
= dns_rdataset_next(nsrdataset
)) {
3205 dns_rdataset_current(nsrdataset
, &rdata
);
3206 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
3207 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3208 dns_rdata_reset(&rdata
);
3209 if (!dns_name_issubdomain(&ns
.name
, name
))
3212 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
3213 &ns
.name
, dns_rdatatype_aaaa
,
3214 dns_rdatatype_none
, NULL
,
3216 if (result
== ISC_R_SUCCESS
) {
3217 result
= dns_db_findnode(db
, &ns
.name
,
3219 if (result
!= ISC_R_SUCCESS
)
3221 result
= dns_db_addrdataset(db
, node
, version
, 0,
3223 dns_db_detachnode(db
, &node
);
3224 if (result
!= ISC_R_SUCCESS
)
3228 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
3229 &ns
.name
, dns_rdatatype_a
,
3230 dns_rdatatype_none
, NULL
,
3232 if (result
== ISC_R_SUCCESS
) {
3233 result
= dns_db_findnode(db
, &ns
.name
,
3235 if (result
!= ISC_R_SUCCESS
)
3237 result
= dns_db_addrdataset(db
, node
, version
, 0,
3239 dns_db_detachnode(db
, &node
);
3240 if (result
!= ISC_R_SUCCESS
)
3244 if (result
!= ISC_R_NOMORE
)
3247 return (ISC_R_SUCCESS
);
3254 stub_callback(isc_task_t
*task
, isc_event_t
*event
) {
3255 const char me
[] = "stub_callback";
3256 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
3257 dns_stub_t
*stub
= NULL
;
3258 dns_message_t
*msg
= NULL
;
3259 dns_zone_t
*zone
= NULL
;
3260 char master
[ISC_SOCKADDR_FORMATSIZE
];
3261 char source
[ISC_SOCKADDR_FORMATSIZE
];
3262 isc_uint32_t nscnt
, cnamecnt
;
3263 isc_result_t result
;
3265 isc_boolean_t exiting
= ISC_FALSE
;
3269 stub
= revent
->ev_arg
;
3270 INSIST(DNS_STUB_VALID(stub
));
3280 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
3281 zone_debuglog(zone
, me
, 1, "exiting");
3286 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
3287 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
3289 if (revent
->result
!= ISC_R_SUCCESS
) {
3290 if (revent
->result
== ISC_R_TIMEDOUT
&&
3291 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
3293 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
3295 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
3296 "refreshing stub: timeout retrying "
3297 " without EDNS master %s (source %s)",
3301 dns_zone_log(zone
, ISC_LOG_INFO
,
3302 "could not refresh stub from master %s"
3303 " (source %s): %s", master
, source
,
3304 dns_result_totext(revent
->result
));
3308 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
3309 if (result
!= ISC_R_SUCCESS
)
3312 result
= dns_request_getresponse(revent
->request
, msg
, 0);
3313 if (result
!= ISC_R_SUCCESS
)
3319 if (msg
->rcode
!= dns_rcode_noerror
) {
3323 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
3324 (void)dns_rcode_totext(msg
->rcode
, &rb
);
3326 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
) &&
3327 (msg
->rcode
== dns_rcode_servfail
||
3328 msg
->rcode
== dns_rcode_notimp
||
3329 msg
->rcode
== dns_rcode_formerr
)) {
3330 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
3331 "refreshing stub: rcode (%.*s) retrying "
3332 "without EDNS master %s (source %s)",
3333 (int)rb
.used
, rcode
, master
, source
);
3335 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
3340 dns_zone_log(zone
, ISC_LOG_INFO
,
3342 "unexpected rcode (%.*s) from %s (source %s)",
3343 (int)rb
.used
, rcode
, master
, source
);
3348 * We need complete messages.
3350 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
3351 if (dns_request_usedtcp(revent
->request
)) {
3352 dns_zone_log(zone
, ISC_LOG_INFO
,
3353 "refreshing stub: truncated TCP "
3354 "response from master %s (source %s)",
3359 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
3365 * If non-auth log and next master.
3367 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
3368 dns_zone_log(zone
, ISC_LOG_INFO
, "refreshing stub: "
3369 "non-authoritative answer from "
3370 "master %s (source %s)", master
, source
);
3377 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
3378 nscnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_ns
);
3380 if (cnamecnt
!= 0) {
3381 dns_zone_log(zone
, ISC_LOG_INFO
,
3382 "refreshing stub: unexpected CNAME response "
3383 "from master %s (source %s)", master
, source
);
3388 dns_zone_log(zone
, ISC_LOG_INFO
,
3389 "refreshing stub: no NS records in response "
3390 "from master %s (source %s)", master
, source
);
3397 result
= save_nsrrset(msg
, &zone
->origin
, stub
->db
, stub
->version
);
3398 if (result
!= ISC_R_SUCCESS
) {
3399 dns_zone_log(zone
, ISC_LOG_INFO
,
3400 "refreshing stub: unable to save NS records "
3401 "from master %s (source %s)", master
, source
);
3408 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_TRUE
);
3410 if (zone
->db
== NULL
)
3411 dns_db_attach(stub
->db
, &zone
->db
);
3413 dns_db_detach(&stub
->db
);
3415 if (zone
->masterfile
!= NULL
) {
3416 dns_zone_dump(zone
);
3417 TIME_NOW(&zone
->loadtime
);
3420 dns_message_destroy(&msg
);
3421 isc_event_free(&event
);
3423 dns_request_destroy(&zone
->request
);
3424 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
3425 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
, &zone
->refreshtime
);
3426 isc_interval_set(&i
, zone
->expire
, 0);
3427 DNS_ZONE_TIME_ADD(&now
, zone
->expire
, &zone
->expiretime
);
3428 zone_settimer(zone
, &now
);
3433 if (stub
->version
!= NULL
)
3434 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_FALSE
);
3435 if (stub
->db
!= NULL
)
3436 dns_db_detach(&stub
->db
);
3438 dns_message_destroy(&msg
);
3439 isc_event_free(&event
);
3441 dns_request_destroy(&zone
->request
);
3443 * Skip to next failed / untried master.
3447 } while (zone
->curmaster
< zone
->masterscnt
&&
3448 zone
->mastersok
[zone
->curmaster
]);
3449 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
3450 if (exiting
|| zone
->curmaster
>= zone
->masterscnt
) {
3451 isc_boolean_t done
= ISC_TRUE
;
3453 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
3454 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
3456 * Did we get a good answer from all the masters?
3458 for (j
= 0; j
< zone
->masterscnt
; j
++)
3459 if (zone
->mastersok
[j
] == ISC_FALSE
) {
3466 zone
->curmaster
= 0;
3468 * Find the next failed master.
3470 while (zone
->curmaster
< zone
->masterscnt
&&
3471 zone
->mastersok
[zone
->curmaster
])
3473 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
3475 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
3477 zone_settimer(zone
, &now
);
3482 queue_soa_query(zone
);
3488 dns_message_destroy(&msg
);
3489 isc_event_free(&event
);
3491 dns_request_destroy(&zone
->request
);
3493 ns_query(zone
, NULL
, stub
);
3498 dns_zone_idetach(&stub
->zone
);
3499 INSIST(stub
->db
== NULL
);
3500 INSIST(stub
->version
== NULL
);
3501 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
3504 INSIST(event
== NULL
);
3509 * An SOA query has finished (successfully or not).
3512 refresh_callback(isc_task_t
*task
, isc_event_t
*event
) {
3513 const char me
[] = "refresh_callback";
3514 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
3516 dns_message_t
*msg
= NULL
;
3517 isc_uint32_t soacnt
, cnamecnt
, soacount
, nscount
;
3519 char master
[ISC_SOCKADDR_FORMATSIZE
];
3520 char source
[ISC_SOCKADDR_FORMATSIZE
];
3521 dns_rdataset_t
*rdataset
= NULL
;
3522 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3523 dns_rdata_soa_t soa
;
3524 isc_result_t result
;
3525 isc_uint32_t serial
;
3528 zone
= revent
->ev_arg
;
3529 INSIST(DNS_ZONE_VALID(zone
));
3536 * if timeout log and next master;
3539 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
3540 isc_sockaddr_format(&zone
->sourceaddr
, source
, sizeof(source
));
3544 if (revent
->result
!= ISC_R_SUCCESS
) {
3545 if (revent
->result
== ISC_R_TIMEDOUT
&&
3546 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
3548 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
3550 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
3551 "refresh: timeout retrying without EDNS "
3552 "master %s (source %s)", master
, source
);
3555 if (revent
->result
== ISC_R_TIMEDOUT
&&
3556 !dns_request_usedtcp(revent
->request
)) {
3557 dns_zone_log(zone
, ISC_LOG_INFO
,
3558 "refresh: retry limit for "
3559 "master %s exceeded (source %s)",
3561 /* Try with slave with TCP. */
3562 if (zone
->type
== dns_zone_slave
) {
3564 DNS_ZONE_SETFLAG(zone
,
3565 DNS_ZONEFLG_SOABEFOREAXFR
);
3570 dns_zone_log(zone
, ISC_LOG_INFO
,
3571 "refresh: failure trying master "
3572 "%s (source %s): %s", master
, source
,
3573 dns_result_totext(revent
->result
));
3577 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
3578 if (result
!= ISC_R_SUCCESS
)
3580 result
= dns_request_getresponse(revent
->request
, msg
, 0);
3581 if (result
!= ISC_R_SUCCESS
) {
3582 dns_zone_log(zone
, ISC_LOG_INFO
,
3583 "refresh: failure trying master "
3584 "%s (source %s): %s", master
, source
,
3585 dns_result_totext(result
));
3592 if (msg
->rcode
!= dns_rcode_noerror
) {
3596 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
3597 (void)dns_rcode_totext(msg
->rcode
, &rb
);
3599 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
) &&
3600 (msg
->rcode
== dns_rcode_servfail
||
3601 msg
->rcode
== dns_rcode_notimp
||
3602 msg
->rcode
== dns_rcode_formerr
)) {
3603 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
3604 "refresh: rcode (%.*s) retrying without "
3605 "EDNS master %s (source %s)",
3606 (int)rb
.used
, rcode
, master
, source
);
3608 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
3612 dns_zone_log(zone
, ISC_LOG_INFO
,
3613 "refresh: unexpected rcode (%.*s) from "
3614 "master %s (source %s)", (int)rb
.used
, rcode
,
3617 * Perhaps AXFR/IXFR is allowed even if SOA queries arn't.
3619 if (msg
->rcode
== dns_rcode_refused
&&
3620 zone
->type
== dns_zone_slave
)
3626 * If truncated punt to zone transfer which will query again.
3628 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
3629 if (zone
->type
== dns_zone_slave
) {
3630 dns_zone_log(zone
, ISC_LOG_INFO
,
3631 "refresh: truncated UDP answer, "
3632 "initiating TCP zone xfer "
3633 "for master %s (source %s)",
3636 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
);
3640 INSIST(zone
->type
== dns_zone_stub
);
3641 if (dns_request_usedtcp(revent
->request
)) {
3642 dns_zone_log(zone
, ISC_LOG_INFO
,
3643 "refresh: truncated TCP response "
3644 "from master %s (source %s)",
3649 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
3656 * if non-auth log and next master;
3658 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
3659 dns_zone_log(zone
, ISC_LOG_INFO
,
3660 "refresh: non-authoritative answer from "
3661 "master %s (source %s)", master
, source
);
3665 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
3666 soacnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_soa
);
3667 nscount
= message_count(msg
, DNS_SECTION_AUTHORITY
, dns_rdatatype_ns
);
3668 soacount
= message_count(msg
, DNS_SECTION_AUTHORITY
,
3672 * There should not be a CNAME record at top of zone.
3674 if (cnamecnt
!= 0) {
3675 dns_zone_log(zone
, ISC_LOG_INFO
,
3676 "refresh: CNAME at top of zone "
3677 "in master %s (source %s)", master
, source
);
3682 * if referral log and next master;
3684 if (soacnt
== 0 && soacount
== 0 && nscount
!= 0) {
3685 dns_zone_log(zone
, ISC_LOG_INFO
,
3686 "refresh: referral response "
3687 "from master %s (source %s)", master
, source
);
3692 * if nodata log and next master;
3694 if (soacnt
== 0 && (nscount
== 0 || soacount
!= 0)) {
3695 dns_zone_log(zone
, ISC_LOG_INFO
,
3696 "refresh: NODATA response "
3697 "from master %s (source %s)", master
, source
);
3702 * Only one soa at top of zone.
3705 dns_zone_log(zone
, ISC_LOG_INFO
,
3706 "refresh: answer SOA count (%d) != 1 "
3707 "from master %s (source %s)",
3708 soacnt
, master
, source
);
3715 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
, &zone
->origin
,
3716 dns_rdatatype_soa
, dns_rdatatype_none
,
3718 if (result
!= ISC_R_SUCCESS
) {
3719 dns_zone_log(zone
, ISC_LOG_INFO
,
3720 "refresh: unable to get SOA record "
3721 "from master %s (source %s)", master
, source
);
3725 result
= dns_rdataset_first(rdataset
);
3726 if (result
!= ISC_R_SUCCESS
) {
3727 dns_zone_log(zone
, ISC_LOG_INFO
,
3728 "refresh: dns_rdataset_first() failed");
3732 dns_rdataset_current(rdataset
, &rdata
);
3733 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
3734 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
3736 serial
= soa
.serial
;
3738 zone_debuglog(zone
, me
, 1, "serial: new %u, old %u",
3739 serial
, zone
->serial
);
3740 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) ||
3741 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
) ||
3742 isc_serial_gt(serial
, zone
->serial
)) {
3744 isc_event_free(&event
);
3746 dns_request_destroy(&zone
->request
);
3748 if (zone
->type
== dns_zone_slave
) {
3751 INSIST(zone
->type
== dns_zone_stub
);
3752 ns_query(zone
, rdataset
, NULL
);
3755 dns_message_destroy(&msg
);
3756 } else if (isc_serial_eq(soa
.serial
, zone
->serial
)) {
3757 if (zone
->masterfile
!= NULL
) {
3758 result
= ISC_R_FAILURE
;
3759 if (zone
->journal
!= NULL
)
3760 result
= isc_file_settime(zone
->journal
, &now
);
3761 if (result
== ISC_R_SUCCESS
&&
3762 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
3763 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
3764 result
= isc_file_settime(zone
->masterfile
,
3766 } else if (result
!= ISC_R_SUCCESS
)
3767 result
= isc_file_settime(zone
->masterfile
,
3769 /* Someone removed the file from underneath us! */
3770 if (result
== ISC_R_FILENOTFOUND
) {
3772 zone_needdump(zone
, DNS_DUMP_DELAY
);
3774 } else if (result
!= ISC_R_SUCCESS
)
3775 dns_zone_log(zone
, ISC_LOG_ERROR
,
3776 "refresh: could not set file "
3777 "modification time of '%s': %s",
3779 dns_result_totext(result
));
3781 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
, &zone
->refreshtime
);
3782 DNS_ZONE_TIME_ADD(&now
, zone
->expire
, &zone
->expiretime
);
3783 zone
->mastersok
[zone
->curmaster
] = ISC_TRUE
;
3786 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MULTIMASTER
))
3787 dns_zone_log(zone
, ISC_LOG_INFO
, "serial number (%u) "
3788 "received from master %s < ours (%u)",
3789 soa
.serial
, master
, zone
->serial
);
3791 zone_debuglog(zone
, me
, 1, "ahead");
3792 zone
->mastersok
[zone
->curmaster
] = ISC_TRUE
;
3796 dns_message_destroy(&msg
);
3801 dns_message_destroy(&msg
);
3802 isc_event_free(&event
);
3804 dns_request_destroy(&zone
->request
);
3806 * Skip to next failed / untried master.
3810 } while (zone
->curmaster
< zone
->masterscnt
&&
3811 zone
->mastersok
[zone
->curmaster
]);
3812 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
3813 if (zone
->curmaster
>= zone
->masterscnt
) {
3814 isc_boolean_t done
= ISC_TRUE
;
3815 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
3816 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
3818 * Did we get a good answer from all the masters?
3820 for (j
= 0; j
< zone
->masterscnt
; j
++)
3821 if (zone
->mastersok
[j
] == ISC_FALSE
) {
3828 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
3829 zone
->curmaster
= 0;
3831 * Find the next failed master.
3833 while (zone
->curmaster
< zone
->masterscnt
&&
3834 zone
->mastersok
[zone
->curmaster
])
3838 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
3839 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
3840 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
3841 zone
->refreshtime
= now
;
3843 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
3844 zone_settimer(zone
, &now
);
3850 queue_soa_query(zone
);
3856 dns_message_destroy(&msg
);
3857 isc_event_free(&event
);
3859 dns_request_destroy(&zone
->request
);
3860 queue_soa_query(zone
);
3864 dns_zone_idetach(&zone
);
3869 queue_soa_query(dns_zone_t
*zone
) {
3870 const char me
[] = "queue_soa_query";
3872 dns_zone_t
*dummy
= NULL
;
3873 isc_result_t result
;
3879 REQUIRE(LOCKED_ZONE(zone
));
3881 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
3882 cancel_refresh(zone
);
3886 e
= isc_event_allocate(zone
->mctx
, NULL
, DNS_EVENT_ZONE
,
3887 soa_query
, zone
, sizeof(isc_event_t
));
3889 cancel_refresh(zone
);
3894 * Attach so that we won't clean up
3895 * until the event is delivered.
3897 zone_iattach(zone
, &dummy
);
3900 e
->ev_sender
= NULL
;
3901 result
= isc_ratelimiter_enqueue(zone
->zmgr
->rl
, zone
->task
, &e
);
3902 if (result
!= ISC_R_SUCCESS
) {
3903 zone_idetach(&dummy
);
3905 cancel_refresh(zone
);
3909 static inline isc_result_t
3910 create_query(dns_zone_t
*zone
, dns_rdatatype_t rdtype
,
3911 dns_message_t
**messagep
)
3913 dns_message_t
*message
= NULL
;
3914 dns_name_t
*qname
= NULL
;
3915 dns_rdataset_t
*qrdataset
= NULL
;
3916 isc_result_t result
;
3918 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
3920 if (result
!= ISC_R_SUCCESS
)
3923 message
->opcode
= dns_opcode_query
;
3924 message
->rdclass
= zone
->rdclass
;
3926 result
= dns_message_gettempname(message
, &qname
);
3927 if (result
!= ISC_R_SUCCESS
)
3930 result
= dns_message_gettemprdataset(message
, &qrdataset
);
3931 if (result
!= ISC_R_SUCCESS
)
3937 dns_name_init(qname
, NULL
);
3938 dns_name_clone(&zone
->origin
, qname
);
3939 dns_rdataset_init(qrdataset
);
3940 dns_rdataset_makequestion(qrdataset
, zone
->rdclass
, rdtype
);
3941 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
3942 dns_message_addname(message
, qname
, DNS_SECTION_QUESTION
);
3944 *messagep
= message
;
3945 return (ISC_R_SUCCESS
);
3949 dns_message_puttempname(message
, &qname
);
3950 if (qrdataset
!= NULL
)
3951 dns_message_puttemprdataset(message
, &qrdataset
);
3952 if (message
!= NULL
)
3953 dns_message_destroy(&message
);
3958 add_opt(dns_message_t
*message
) {
3959 dns_rdataset_t
*rdataset
= NULL
;
3960 dns_rdatalist_t
*rdatalist
= NULL
;
3961 dns_rdata_t
*rdata
= NULL
;
3962 isc_result_t result
;
3964 result
= dns_message_gettemprdatalist(message
, &rdatalist
);
3965 if (result
!= ISC_R_SUCCESS
)
3967 result
= dns_message_gettemprdata(message
, &rdata
);
3968 if (result
!= ISC_R_SUCCESS
)
3970 result
= dns_message_gettemprdataset(message
, &rdataset
);
3971 if (result
!= ISC_R_SUCCESS
)
3973 dns_rdataset_init(rdataset
);
3975 rdatalist
->type
= dns_rdatatype_opt
;
3976 rdatalist
->covers
= 0;
3979 * Set Maximum UDP buffer size.
3981 rdatalist
->rdclass
= SEND_BUFFER_SIZE
;
3984 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
3993 rdata
->rdclass
= rdatalist
->rdclass
;
3994 rdata
->type
= rdatalist
->type
;
3997 ISC_LIST_INIT(rdatalist
->rdata
);
3998 ISC_LIST_APPEND(rdatalist
->rdata
, rdata
, link
);
3999 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist
, rdataset
)
4002 return (dns_message_setopt(message
, rdataset
));
4005 if (rdatalist
!= NULL
)
4006 dns_message_puttemprdatalist(message
, &rdatalist
);
4007 if (rdataset
!= NULL
)
4008 dns_message_puttemprdataset(message
, &rdataset
);
4010 dns_message_puttemprdata(message
, &rdata
);
4016 soa_query(isc_task_t
*task
, isc_event_t
*event
) {
4017 const char me
[] = "soa_query";
4018 isc_result_t result
= ISC_R_FAILURE
;
4019 dns_message_t
*message
= NULL
;
4020 dns_zone_t
*zone
= event
->ev_arg
;
4021 dns_zone_t
*dummy
= NULL
;
4022 isc_netaddr_t masterip
;
4023 dns_tsigkey_t
*key
= NULL
;
4024 isc_uint32_t options
;
4025 isc_boolean_t cancel
= ISC_TRUE
;
4027 isc_boolean_t have_xfrsource
;
4029 REQUIRE(DNS_ZONE_VALID(zone
));
4036 if (((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0) ||
4037 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
) ||
4038 zone
->view
->requestmgr
== NULL
) {
4039 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
4045 * XXX Optimisation: Create message when zone is setup and reuse.
4047 result
= create_query(zone
, dns_rdatatype_soa
, &message
);
4048 if (result
!= ISC_R_SUCCESS
)
4052 INSIST(zone
->masterscnt
> 0);
4053 INSIST(zone
->curmaster
< zone
->masterscnt
);
4055 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
4057 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
4059 * First, look for a tsig key in the master statement, then
4060 * try for a server key.
4062 if ((zone
->masterkeynames
!= NULL
) &&
4063 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
4064 dns_view_t
*view
= dns_zone_getview(zone
);
4065 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
4066 result
= dns_view_gettsig(view
, keyname
, &key
);
4067 if (result
!= ISC_R_SUCCESS
) {
4068 char namebuf
[DNS_NAME_FORMATSIZE
];
4069 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
4070 dns_zone_log(zone
, ISC_LOG_ERROR
,
4071 "unable to find key: %s", namebuf
);
4075 (void)dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
4077 have_xfrsource
= ISC_FALSE
;
4078 if (zone
->view
->peers
!= NULL
) {
4079 dns_peer_t
*peer
= NULL
;
4081 result
= dns_peerlist_peerbyaddr(zone
->view
->peers
,
4083 if (result
== ISC_R_SUCCESS
) {
4084 result
= dns_peer_getsupportedns(peer
, &edns
);
4085 if (result
== ISC_R_SUCCESS
&& !edns
)
4086 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
4087 result
= dns_peer_gettransfersource(peer
,
4089 if (result
== ISC_R_SUCCESS
)
4090 have_xfrsource
= ISC_TRUE
;
4094 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
4096 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
4097 if (isc_sockaddr_equal(&zone
->altxfrsource4
,
4100 zone
->sourceaddr
= zone
->altxfrsource4
;
4101 } else if (!have_xfrsource
)
4102 zone
->sourceaddr
= zone
->xfrsource4
;
4105 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
4106 if (isc_sockaddr_equal(&zone
->altxfrsource6
,
4109 zone
->sourceaddr
= zone
->altxfrsource6
;
4110 } else if (!have_xfrsource
)
4111 zone
->sourceaddr
= zone
->xfrsource6
;
4114 result
= ISC_R_NOTIMPLEMENTED
;
4118 options
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEVC
) ?
4119 DNS_REQUESTOPT_TCP
: 0;
4121 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
4122 result
= add_opt(message
);
4123 if (result
!= ISC_R_SUCCESS
)
4124 zone_debuglog(zone
, me
, 1,
4125 "unable to add opt record: %s",
4126 dns_result_totext(result
));
4129 zone_iattach(zone
, &dummy
);
4131 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
4133 result
= dns_request_createvia2(zone
->view
->requestmgr
, message
,
4134 &zone
->sourceaddr
, &zone
->masteraddr
,
4135 options
, key
, timeout
* 3, timeout
,
4136 zone
->task
, refresh_callback
, zone
,
4138 if (result
!= ISC_R_SUCCESS
) {
4139 zone_idetach(&dummy
);
4140 zone_debuglog(zone
, me
, 1,
4141 "dns_request_createvia2() failed: %s",
4142 dns_result_totext(result
));
4149 dns_tsigkey_detach(&key
);
4150 if (result
!= ISC_R_SUCCESS
)
4151 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
4152 if (message
!= NULL
)
4153 dns_message_destroy(&message
);
4155 cancel_refresh(zone
);
4156 isc_event_free(&event
);
4158 dns_zone_idetach(&zone
);
4163 dns_tsigkey_detach(&key
);
4165 * Skip to next failed / untried master.
4169 } while (zone
->curmaster
< zone
->masterscnt
&&
4170 zone
->mastersok
[zone
->curmaster
]);
4171 if (zone
->curmaster
< zone
->masterscnt
)
4173 zone
->curmaster
= 0;
4178 ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
, dns_stub_t
*stub
) {
4179 const char me
[] = "ns_query";
4180 isc_result_t result
;
4181 dns_message_t
*message
= NULL
;
4182 isc_netaddr_t masterip
;
4183 dns_tsigkey_t
*key
= NULL
;
4184 dns_dbnode_t
*node
= NULL
;
4186 isc_boolean_t have_xfrsource
= ISC_FALSE
;
4188 REQUIRE(DNS_ZONE_VALID(zone
));
4189 REQUIRE((soardataset
!= NULL
&& stub
== NULL
) ||
4190 (soardataset
== NULL
&& stub
!= NULL
));
4191 REQUIRE(stub
== NULL
|| DNS_STUB_VALID(stub
));
4197 stub
= isc_mem_get(zone
->mctx
, sizeof(*stub
));
4200 stub
->magic
= STUB_MAGIC
;
4201 stub
->mctx
= zone
->mctx
;
4204 stub
->version
= NULL
;
4207 * Attach so that the zone won't disappear from under us.
4209 zone_iattach(zone
, &stub
->zone
);
4212 * If a db exists we will update it, otherwise we create a
4213 * new one and attach it to the zone once we have the NS
4216 if (zone
->db
!= NULL
)
4217 dns_db_attach(zone
->db
, &stub
->db
);
4219 INSIST(zone
->db_argc
>= 1);
4220 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
4221 &zone
->origin
, dns_dbtype_stub
,
4226 if (result
!= ISC_R_SUCCESS
) {
4227 dns_zone_log(zone
, ISC_LOG_ERROR
,
4231 dns_result_totext(result
));
4234 dns_db_settask(stub
->db
, zone
->task
);
4237 dns_db_newversion(stub
->db
, &stub
->version
);
4240 * Update SOA record.
4242 result
= dns_db_findnode(stub
->db
, &zone
->origin
, ISC_TRUE
,
4244 if (result
!= ISC_R_SUCCESS
) {
4245 dns_zone_log(zone
, ISC_LOG_INFO
,
4247 "dns_db_findnode() failed: %s",
4248 dns_result_totext(result
));
4252 result
= dns_db_addrdataset(stub
->db
, node
, stub
->version
, 0,
4253 soardataset
, 0, NULL
);
4254 dns_db_detachnode(stub
->db
, &node
);
4255 if (result
!= ISC_R_SUCCESS
) {
4256 dns_zone_log(zone
, ISC_LOG_INFO
,
4258 "dns_db_addrdataset() failed: %s",
4259 dns_result_totext(result
));
4265 * XXX Optimisation: Create message when zone is setup and reuse.
4267 result
= create_query(zone
, dns_rdatatype_ns
, &message
);
4269 INSIST(zone
->masterscnt
> 0);
4270 INSIST(zone
->curmaster
< zone
->masterscnt
);
4271 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
4273 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
4275 * First, look for a tsig key in the master statement, then
4276 * try for a server key.
4278 if ((zone
->masterkeynames
!= NULL
) &&
4279 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
4280 dns_view_t
*view
= dns_zone_getview(zone
);
4281 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
4282 result
= dns_view_gettsig(view
, keyname
, &key
);
4283 if (result
!= ISC_R_SUCCESS
) {
4284 char namebuf
[DNS_NAME_FORMATSIZE
];
4285 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
4286 dns_zone_log(zone
, ISC_LOG_ERROR
,
4287 "unable to find key: %s", namebuf
);
4291 (void)dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
4293 if (zone
->view
->peers
!= NULL
) {
4294 dns_peer_t
*peer
= NULL
;
4296 result
= dns_peerlist_peerbyaddr(zone
->view
->peers
,
4298 if (result
== ISC_R_SUCCESS
) {
4299 result
= dns_peer_getsupportedns(peer
, &edns
);
4300 if (result
== ISC_R_SUCCESS
&& !edns
)
4301 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOEDNS
);
4302 result
= dns_peer_gettransfersource(peer
,
4304 if (result
== ISC_R_SUCCESS
)
4305 have_xfrsource
= ISC_TRUE
;
4309 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOEDNS
)) {
4310 result
= add_opt(message
);
4311 if (result
!= ISC_R_SUCCESS
)
4312 zone_debuglog(zone
, me
, 1,
4313 "unable to add opt record: %s",
4314 dns_result_totext(result
));
4318 * Always use TCP so that we shouldn't truncate in additional section.
4320 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
4322 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
))
4323 zone
->sourceaddr
= zone
->altxfrsource4
;
4324 else if (!have_xfrsource
)
4325 zone
->sourceaddr
= zone
->xfrsource4
;
4328 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
))
4329 zone
->sourceaddr
= zone
->altxfrsource6
;
4330 else if (!have_xfrsource
)
4331 zone
->sourceaddr
= zone
->xfrsource6
;
4334 result
= ISC_R_NOTIMPLEMENTED
;
4338 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
4340 result
= dns_request_createvia2(zone
->view
->requestmgr
, message
,
4341 &zone
->sourceaddr
, &zone
->masteraddr
,
4342 DNS_REQUESTOPT_TCP
, key
, timeout
* 3,
4343 timeout
, zone
->task
, stub_callback
,
4344 stub
, &zone
->request
);
4345 if (result
!= ISC_R_SUCCESS
) {
4346 zone_debuglog(zone
, me
, 1,
4347 "dns_request_createvia() failed: %s",
4348 dns_result_totext(result
));
4351 dns_message_destroy(&message
);
4355 cancel_refresh(zone
);
4358 if (stub
->version
!= NULL
)
4359 dns_db_closeversion(stub
->db
, &stub
->version
,
4361 if (stub
->db
!= NULL
)
4362 dns_db_detach(&stub
->db
);
4363 if (stub
->zone
!= NULL
)
4364 zone_idetach(&stub
->zone
);
4365 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
4367 if (message
!= NULL
)
4368 dns_message_destroy(&message
);
4371 dns_tsigkey_detach(&key
);
4377 * Handle the control event. Note that although this event causes the zone
4378 * to shut down, it is not a shutdown event in the sense of the task library.
4381 zone_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
4382 dns_zone_t
*zone
= (dns_zone_t
*) event
->ev_arg
;
4383 isc_boolean_t free_needed
, linked
= ISC_FALSE
;
4386 REQUIRE(DNS_ZONE_VALID(zone
));
4387 INSIST(event
->ev_type
== DNS_EVENT_ZONECONTROL
);
4388 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
4389 zone_debuglog(zone
, "zone_shutdown", 3, "shutting down");
4392 * Stop things being restarted after we cancel them below.
4395 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXITING
);
4399 * If we were waiting for xfrin quota, step out of
4401 * If there's no zone manager, we can't be waiting for the
4404 if (zone
->zmgr
!= NULL
) {
4405 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
4406 if (zone
->statelist
== &zone
->zmgr
->waiting_for_xfrin
) {
4407 ISC_LIST_UNLINK(zone
->zmgr
->waiting_for_xfrin
, zone
,
4410 zone
->statelist
= NULL
;
4412 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
4416 * In task context, no locking required. See zone_xfrdone().
4418 if (zone
->xfr
!= NULL
)
4419 dns_xfrin_shutdown(zone
->xfr
);
4423 INSIST(zone
->irefs
> 0);
4426 if (zone
->request
!= NULL
) {
4427 dns_request_cancel(zone
->request
);
4430 if (zone
->readio
!= NULL
)
4431 zonemgr_cancelio(zone
->readio
);
4433 if (zone
->lctx
!= NULL
)
4434 dns_loadctx_cancel(zone
->lctx
);
4436 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) ||
4437 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
4438 if (zone
->writeio
!= NULL
)
4439 zonemgr_cancelio(zone
->writeio
);
4441 if (zone
->dctx
!= NULL
)
4442 dns_dumpctx_cancel(zone
->dctx
);
4445 notify_cancel(zone
);
4447 if (zone
->timer
!= NULL
) {
4448 isc_timer_detach(&zone
->timer
);
4449 INSIST(zone
->irefs
> 0);
4453 if (zone
->view
!= NULL
)
4454 dns_view_weakdetach(&zone
->view
);
4457 * We have now canceled everything set the flag to allow exit_check()
4458 * to succeed. We must not unlock between setting this flag and
4459 * calling exit_check().
4461 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SHUTDOWN
);
4462 free_needed
= exit_check(zone
);
4469 zone_timer(isc_task_t
*task
, isc_event_t
*event
) {
4470 const char me
[] = "zone_timer";
4471 dns_zone_t
*zone
= (dns_zone_t
*)event
->ev_arg
;
4474 REQUIRE(DNS_ZONE_VALID(zone
));
4478 zone_maintenance(zone
);
4480 isc_event_free(&event
);
4484 zone_settimer(dns_zone_t
*zone
, isc_time_t
*now
) {
4485 const char me
[] = "zone_settimer";
4487 isc_result_t result
;
4489 REQUIRE(DNS_ZONE_VALID(zone
));
4490 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
4493 isc_time_settoepoch(&next
);
4495 switch (zone
->type
) {
4496 case dns_zone_master
:
4497 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
4499 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
4500 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
4501 INSIST(!isc_time_isepoch(&zone
->dumptime
));
4502 if (isc_time_isepoch(&next
) ||
4503 isc_time_compare(&zone
->dumptime
, &next
) < 0)
4504 next
= zone
->dumptime
;
4508 case dns_zone_slave
:
4509 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
4514 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
) &&
4515 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOMASTERS
) &&
4516 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
) &&
4517 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
4518 INSIST(!isc_time_isepoch(&zone
->refreshtime
));
4519 if (isc_time_isepoch(&next
) ||
4520 isc_time_compare(&zone
->refreshtime
, &next
) < 0)
4521 next
= zone
->refreshtime
;
4523 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
4524 INSIST(!isc_time_isepoch(&zone
->expiretime
));
4525 if (isc_time_isepoch(&next
) ||
4526 isc_time_compare(&zone
->expiretime
, &next
) < 0)
4527 next
= zone
->expiretime
;
4529 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
4530 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
4531 INSIST(!isc_time_isepoch(&zone
->dumptime
));
4532 if (isc_time_isepoch(&next
) ||
4533 isc_time_compare(&zone
->dumptime
, &next
) < 0)
4534 next
= zone
->dumptime
;
4542 if (isc_time_isepoch(&next
)) {
4543 zone_debuglog(zone
, me
, 10, "settimer inactive");
4544 result
= isc_timer_reset(zone
->timer
, isc_timertype_inactive
,
4545 NULL
, NULL
, ISC_TRUE
);
4546 if (result
!= ISC_R_SUCCESS
)
4547 dns_zone_log(zone
, ISC_LOG_ERROR
,
4548 "could not deactivate zone timer: %s",
4549 isc_result_totext(result
));
4551 if (isc_time_compare(&next
, now
) <= 0)
4553 result
= isc_timer_reset(zone
->timer
, isc_timertype_once
,
4554 &next
, NULL
, ISC_TRUE
);
4555 if (result
!= ISC_R_SUCCESS
)
4556 dns_zone_log(zone
, ISC_LOG_ERROR
,
4557 "could not reset zone timer: %s",
4558 isc_result_totext(result
));
4563 cancel_refresh(dns_zone_t
*zone
) {
4564 const char me
[] = "cancel_refresh";
4568 * 'zone' locked by caller.
4571 REQUIRE(DNS_ZONE_VALID(zone
));
4572 REQUIRE(LOCKED_ZONE(zone
));
4576 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
4578 zone_settimer(zone
, &now
);
4582 notify_createmessage(dns_zone_t
*zone
, unsigned int flags
,
4583 dns_message_t
**messagep
)
4585 dns_dbnode_t
*node
= NULL
;
4586 dns_dbversion_t
*version
= NULL
;
4587 dns_message_t
*message
= NULL
;
4588 dns_rdataset_t rdataset
;
4589 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4591 dns_name_t
*tempname
= NULL
;
4592 dns_rdata_t
*temprdata
= NULL
;
4593 dns_rdatalist_t
*temprdatalist
= NULL
;
4594 dns_rdataset_t
*temprdataset
= NULL
;
4596 isc_result_t result
;
4598 isc_buffer_t
*b
= NULL
;
4600 REQUIRE(DNS_ZONE_VALID(zone
));
4601 REQUIRE(messagep
!= NULL
&& *messagep
== NULL
);
4604 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
4606 if (result
!= ISC_R_SUCCESS
)
4609 message
->opcode
= dns_opcode_notify
;
4610 message
->flags
|= DNS_MESSAGEFLAG_AA
;
4611 message
->rdclass
= zone
->rdclass
;
4613 result
= dns_message_gettempname(message
, &tempname
);
4614 if (result
!= ISC_R_SUCCESS
)
4617 result
= dns_message_gettemprdataset(message
, &temprdataset
);
4618 if (result
!= ISC_R_SUCCESS
)
4624 dns_name_init(tempname
, NULL
);
4625 dns_name_clone(&zone
->origin
, tempname
);
4626 dns_rdataset_init(temprdataset
);
4627 dns_rdataset_makequestion(temprdataset
, zone
->rdclass
,
4629 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
4630 dns_message_addname(message
, tempname
, DNS_SECTION_QUESTION
);
4632 temprdataset
= NULL
;
4634 if ((flags
& DNS_NOTIFY_NOSOA
) != 0)
4637 result
= dns_message_gettempname(message
, &tempname
);
4638 if (result
!= ISC_R_SUCCESS
)
4640 result
= dns_message_gettemprdata(message
, &temprdata
);
4641 if (result
!= ISC_R_SUCCESS
)
4643 result
= dns_message_gettemprdataset(message
, &temprdataset
);
4644 if (result
!= ISC_R_SUCCESS
)
4646 result
= dns_message_gettemprdatalist(message
, &temprdatalist
);
4647 if (result
!= ISC_R_SUCCESS
)
4650 dns_name_init(tempname
, NULL
);
4651 dns_name_clone(&zone
->origin
, tempname
);
4652 dns_db_currentversion(zone
->db
, &version
);
4653 result
= dns_db_findnode(zone
->db
, tempname
, ISC_FALSE
, &node
);
4654 if (result
!= ISC_R_SUCCESS
)
4657 dns_rdataset_init(&rdataset
);
4658 result
= dns_db_findrdataset(zone
->db
, node
, version
,
4660 dns_rdatatype_none
, 0, &rdataset
,
4662 if (result
!= ISC_R_SUCCESS
)
4664 result
= dns_rdataset_first(&rdataset
);
4665 if (result
!= ISC_R_SUCCESS
)
4667 dns_rdataset_current(&rdataset
, &rdata
);
4668 dns_rdata_toregion(&rdata
, &r
);
4669 result
= isc_buffer_allocate(zone
->mctx
, &b
, r
.length
);
4670 if (result
!= ISC_R_SUCCESS
)
4672 isc_buffer_putmem(b
, r
.base
, r
.length
);
4673 isc_buffer_usedregion(b
, &r
);
4674 dns_rdata_init(temprdata
);
4675 dns_rdata_fromregion(temprdata
, rdata
.rdclass
, rdata
.type
, &r
);
4676 dns_message_takebuffer(message
, &b
);
4677 result
= dns_rdataset_next(&rdataset
);
4678 dns_rdataset_disassociate(&rdataset
);
4679 if (result
!= ISC_R_NOMORE
)
4681 temprdatalist
->rdclass
= rdata
.rdclass
;
4682 temprdatalist
->type
= rdata
.type
;
4683 temprdatalist
->covers
= 0;
4684 temprdatalist
->ttl
= rdataset
.ttl
;
4685 ISC_LIST_INIT(temprdatalist
->rdata
);
4686 ISC_LIST_APPEND(temprdatalist
->rdata
, temprdata
, link
);
4688 dns_rdataset_init(temprdataset
);
4689 result
= dns_rdatalist_tordataset(temprdatalist
, temprdataset
);
4690 if (result
!= ISC_R_SUCCESS
)
4693 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
4694 dns_message_addname(message
, tempname
, DNS_SECTION_ANSWER
);
4695 temprdatalist
= NULL
;
4696 temprdataset
= NULL
;
4702 dns_db_detachnode(zone
->db
, &node
);
4703 if (version
!= NULL
)
4704 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
4705 if (tempname
!= NULL
)
4706 dns_message_puttempname(message
, &tempname
);
4707 if (temprdata
!= NULL
)
4708 dns_message_puttemprdata(message
, &temprdata
);
4709 if (temprdataset
!= NULL
)
4710 dns_message_puttemprdataset(message
, &temprdataset
);
4711 if (temprdatalist
!= NULL
)
4712 dns_message_puttemprdatalist(message
, &temprdatalist
);
4715 *messagep
= message
;
4716 return (ISC_R_SUCCESS
);
4719 if (tempname
!= NULL
)
4720 dns_message_puttempname(message
, &tempname
);
4721 if (temprdataset
!= NULL
)
4722 dns_message_puttemprdataset(message
, &temprdataset
);
4723 if (message
!= NULL
)
4724 dns_message_destroy(&message
);
4729 dns_zone_notifyreceive(dns_zone_t
*zone
, isc_sockaddr_t
*from
,
4733 dns_rdata_soa_t soa
;
4734 dns_rdataset_t
*rdataset
= NULL
;
4735 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4736 isc_result_t result
;
4737 char fromtext
[ISC_SOCKADDR_FORMATSIZE
];
4739 isc_netaddr_t netaddr
;
4741 REQUIRE(DNS_ZONE_VALID(zone
));
4744 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
4748 * Check that 'from' is a valid notify source, (zone->masters).
4749 * Return DNS_R_REFUSED if not.
4751 * If the notify message contains a serial number check it
4752 * against the zones serial and return if <= current serial
4754 * If a refresh check is progress, if so just record the
4755 * fact we received a NOTIFY and from where and return.
4756 * We will perform a new refresh check when the current one
4757 * completes. Return ISC_R_SUCCESS.
4759 * Otherwise initiate a refresh check using 'from' as the
4760 * first address to check. Return ISC_R_SUCCESS.
4763 isc_sockaddr_format(from
, fromtext
, sizeof(fromtext
));
4766 * We only handle NOTIFY (SOA) at the present.
4769 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0 ||
4770 dns_message_findname(msg
, DNS_SECTION_QUESTION
, &zone
->origin
,
4771 dns_rdatatype_soa
, dns_rdatatype_none
,
4772 NULL
, NULL
) != ISC_R_SUCCESS
) {
4774 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0) {
4775 dns_zone_log(zone
, ISC_LOG_NOTICE
,
4777 "question section from: %s", fromtext
);
4778 return (DNS_R_FORMERR
);
4780 dns_zone_log(zone
, ISC_LOG_NOTICE
,
4781 "NOTIFY zone does not match");
4782 return (DNS_R_NOTIMP
);
4786 * If we are a master zone just succeed.
4788 if (zone
->type
== dns_zone_master
) {
4790 return (ISC_R_SUCCESS
);
4793 isc_netaddr_fromsockaddr(&netaddr
, from
);
4794 for (i
= 0; i
< zone
->masterscnt
; i
++) {
4795 if (isc_sockaddr_eqaddr(from
, &zone
->masters
[i
]))
4797 if (zone
->view
->aclenv
.match_mapped
&&
4798 IN6_IS_ADDR_V4MAPPED(&from
->type
.sin6
.sin6_addr
) &&
4799 isc_sockaddr_pf(&zone
->masters
[i
]) == AF_INET
) {
4800 isc_netaddr_t na1
, na2
;
4801 isc_netaddr_fromv4mapped(&na1
, &netaddr
);
4802 isc_netaddr_fromsockaddr(&na2
, &zone
->masters
[i
]);
4803 if (isc_netaddr_equal(&na1
, &na2
))
4809 * Accept notify requests from non masters if they are on
4810 * 'zone->notify_acl'.
4812 if (i
>= zone
->masterscnt
&& zone
->notify_acl
!= NULL
&&
4813 dns_acl_match(&netaddr
, NULL
, zone
->notify_acl
,
4814 &zone
->view
->aclenv
,
4815 &match
, NULL
) == ISC_R_SUCCESS
&&
4818 /* Accept notify. */
4819 } else if (i
>= zone
->masterscnt
) {
4821 dns_zone_log(zone
, ISC_LOG_INFO
,
4822 "refused notify from non-master: %s", fromtext
);
4823 return (DNS_R_REFUSED
);
4827 * If the zone is loaded and there are answers check the serial
4828 * to see if we need to do a refresh. Do not worry about this
4829 * check if we are a dialup zone as we use the notify request
4830 * to trigger a refresh check.
4832 if (msg
->counts
[DNS_SECTION_ANSWER
] > 0 &&
4833 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
4834 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
)) {
4835 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
,
4838 dns_rdatatype_none
, NULL
,
4840 if (result
== ISC_R_SUCCESS
)
4841 result
= dns_rdataset_first(rdataset
);
4842 if (result
== ISC_R_SUCCESS
) {
4843 isc_uint32_t serial
= 0;
4845 dns_rdataset_current(rdataset
, &rdata
);
4846 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
4847 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
4848 serial
= soa
.serial
;
4849 if (isc_serial_le(serial
, zone
->serial
)) {
4850 dns_zone_log(zone
, ISC_LOG_INFO
,
4852 "zone is up to date",
4855 return (ISC_R_SUCCESS
);
4861 * If we got this far and there was a refresh in progress just
4862 * let it complete. Record where we got the notify from so we
4863 * can perform a refresh check when the current one completes
4865 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
)) {
4866 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
4867 zone
->notifyfrom
= *from
;
4869 dns_zone_log(zone
, ISC_LOG_INFO
,
4870 "notify from %s: refresh in progress, "
4871 "refresh check queued",
4873 return (ISC_R_SUCCESS
);
4875 zone
->notifyfrom
= *from
;
4877 dns_zone_refresh(zone
);
4878 return (ISC_R_SUCCESS
);
4882 dns_zone_setnotifyacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4884 REQUIRE(DNS_ZONE_VALID(zone
));
4887 if (zone
->notify_acl
!= NULL
)
4888 dns_acl_detach(&zone
->notify_acl
);
4889 dns_acl_attach(acl
, &zone
->notify_acl
);
4894 dns_zone_setqueryacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4896 REQUIRE(DNS_ZONE_VALID(zone
));
4899 if (zone
->query_acl
!= NULL
)
4900 dns_acl_detach(&zone
->query_acl
);
4901 dns_acl_attach(acl
, &zone
->query_acl
);
4906 dns_zone_setupdateacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4908 REQUIRE(DNS_ZONE_VALID(zone
));
4911 if (zone
->update_acl
!= NULL
)
4912 dns_acl_detach(&zone
->update_acl
);
4913 dns_acl_attach(acl
, &zone
->update_acl
);
4918 dns_zone_setforwardacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4920 REQUIRE(DNS_ZONE_VALID(zone
));
4923 if (zone
->forward_acl
!= NULL
)
4924 dns_acl_detach(&zone
->forward_acl
);
4925 dns_acl_attach(acl
, &zone
->forward_acl
);
4930 dns_zone_setxfracl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4932 REQUIRE(DNS_ZONE_VALID(zone
));
4935 if (zone
->xfr_acl
!= NULL
)
4936 dns_acl_detach(&zone
->xfr_acl
);
4937 dns_acl_attach(acl
, &zone
->xfr_acl
);
4942 dns_zone_getnotifyacl(dns_zone_t
*zone
) {
4944 REQUIRE(DNS_ZONE_VALID(zone
));
4946 return (zone
->notify_acl
);
4950 dns_zone_getqueryacl(dns_zone_t
*zone
) {
4952 REQUIRE(DNS_ZONE_VALID(zone
));
4954 return (zone
->query_acl
);
4958 dns_zone_getupdateacl(dns_zone_t
*zone
) {
4960 REQUIRE(DNS_ZONE_VALID(zone
));
4962 return (zone
->update_acl
);
4966 dns_zone_getforwardacl(dns_zone_t
*zone
) {
4968 REQUIRE(DNS_ZONE_VALID(zone
));
4970 return (zone
->forward_acl
);
4974 dns_zone_getxfracl(dns_zone_t
*zone
) {
4976 REQUIRE(DNS_ZONE_VALID(zone
));
4978 return (zone
->xfr_acl
);
4982 dns_zone_clearupdateacl(dns_zone_t
*zone
) {
4984 REQUIRE(DNS_ZONE_VALID(zone
));
4987 if (zone
->update_acl
!= NULL
)
4988 dns_acl_detach(&zone
->update_acl
);
4993 dns_zone_clearforwardacl(dns_zone_t
*zone
) {
4995 REQUIRE(DNS_ZONE_VALID(zone
));
4998 if (zone
->forward_acl
!= NULL
)
4999 dns_acl_detach(&zone
->forward_acl
);
5004 dns_zone_clearnotifyacl(dns_zone_t
*zone
) {
5006 REQUIRE(DNS_ZONE_VALID(zone
));
5009 if (zone
->notify_acl
!= NULL
)
5010 dns_acl_detach(&zone
->notify_acl
);
5015 dns_zone_clearqueryacl(dns_zone_t
*zone
) {
5017 REQUIRE(DNS_ZONE_VALID(zone
));
5020 if (zone
->query_acl
!= NULL
)
5021 dns_acl_detach(&zone
->query_acl
);
5026 dns_zone_clearxfracl(dns_zone_t
*zone
) {
5028 REQUIRE(DNS_ZONE_VALID(zone
));
5031 if (zone
->xfr_acl
!= NULL
)
5032 dns_acl_detach(&zone
->xfr_acl
);
5037 dns_zone_getupdatedisabled(dns_zone_t
*zone
) {
5038 REQUIRE(DNS_ZONE_VALID(zone
));
5039 return (zone
->update_disabled
);
5044 dns_zone_setupdatedisabled(dns_zone_t
*zone
, isc_boolean_t state
) {
5045 REQUIRE(DNS_ZONE_VALID(zone
));
5046 zone
->update_disabled
= state
;
5050 dns_zone_setchecknames(dns_zone_t
*zone
, dns_severity_t severity
) {
5052 REQUIRE(DNS_ZONE_VALID(zone
));
5054 zone
->check_names
= severity
;
5058 dns_zone_getchecknames(dns_zone_t
*zone
) {
5060 REQUIRE(DNS_ZONE_VALID(zone
));
5062 return (zone
->check_names
);
5066 dns_zone_setjournalsize(dns_zone_t
*zone
, isc_int32_t size
) {
5068 REQUIRE(DNS_ZONE_VALID(zone
));
5070 zone
->journalsize
= size
;
5074 dns_zone_getjournalsize(dns_zone_t
*zone
) {
5076 REQUIRE(DNS_ZONE_VALID(zone
));
5078 return (zone
->journalsize
);
5082 zone_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
5083 isc_result_t result
= ISC_R_FAILURE
;
5084 isc_buffer_t buffer
;
5086 REQUIRE(buf
!= NULL
);
5087 REQUIRE(length
> 1U);
5090 * Leave space for terminating '\0'.
5092 isc_buffer_init(&buffer
, buf
, length
- 1);
5093 if (dns_name_dynamic(&zone
->origin
))
5094 result
= dns_name_totext(&zone
->origin
, ISC_TRUE
, &buffer
);
5095 if (result
!= ISC_R_SUCCESS
&&
5096 isc_buffer_availablelength(&buffer
) >= (sizeof("<UNKNOWN>") - 1))
5097 isc_buffer_putstr(&buffer
, "<UNKNOWN>");
5099 if (isc_buffer_availablelength(&buffer
) > 0)
5100 isc_buffer_putstr(&buffer
, "/");
5101 (void)dns_rdataclass_totext(zone
->rdclass
, &buffer
);
5103 if (zone
->view
!= NULL
&& strcmp(zone
->view
->name
, "_bind") != 0 &&
5104 strcmp(zone
->view
->name
, "_default") != 0 &&
5105 strlen(zone
->view
->name
) < isc_buffer_availablelength(&buffer
)) {
5106 isc_buffer_putstr(&buffer
, "/");
5107 isc_buffer_putstr(&buffer
, zone
->view
->name
);
5110 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
5114 dns_zone_name(dns_zone_t
*zone
, char *buf
, size_t length
) {
5115 REQUIRE(DNS_ZONE_VALID(zone
));
5116 REQUIRE(buf
!= NULL
);
5117 zone_tostr(zone
, buf
, length
);
5121 notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
5124 char namebuf
[1024+32];
5126 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
5129 zone_tostr(zone
, namebuf
, sizeof(namebuf
));
5132 vsnprintf(message
, sizeof(message
), fmt
, ap
);
5134 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_NOTIFY
, DNS_LOGMODULE_ZONE
,
5135 level
, "zone %s: %s", namebuf
, message
);
5139 dns_zone_logc(dns_zone_t
*zone
, isc_logcategory_t
*category
,
5140 int level
, const char *fmt
, ...) {
5143 char namebuf
[1024+32];
5145 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
5148 zone_tostr(zone
, namebuf
, sizeof(namebuf
));
5151 vsnprintf(message
, sizeof(message
), fmt
, ap
);
5153 isc_log_write(dns_lctx
, category
, DNS_LOGMODULE_ZONE
,
5154 level
, "zone %s: %s", namebuf
, message
);
5158 dns_zone_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
5161 char namebuf
[1024+32];
5163 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
5166 zone_tostr(zone
, namebuf
, sizeof(namebuf
));
5169 vsnprintf(message
, sizeof(message
), fmt
, ap
);
5171 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
5172 level
, "zone %s: %s", namebuf
, message
);
5176 zone_debuglog(dns_zone_t
*zone
, const char *me
, int debuglevel
,
5177 const char *fmt
, ...)
5181 char namebuf
[1024+32];
5182 int level
= ISC_LOG_DEBUG(debuglevel
);
5184 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
5187 zone_tostr(zone
, namebuf
, sizeof(namebuf
));
5190 vsnprintf(message
, sizeof(message
), fmt
, ap
);
5192 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
5193 level
, "%s: zone %s: %s", me
, namebuf
, message
);
5197 message_count(dns_message_t
*msg
, dns_section_t section
, dns_rdatatype_t type
)
5199 isc_result_t result
;
5201 dns_rdataset_t
*curr
;
5204 result
= dns_message_firstname(msg
, section
);
5205 while (result
== ISC_R_SUCCESS
) {
5207 dns_message_currentname(msg
, section
, &name
);
5209 for (curr
= ISC_LIST_TAIL(name
->list
); curr
!= NULL
;
5210 curr
= ISC_LIST_PREV(curr
, link
)) {
5211 if (curr
->type
== type
)
5214 result
= dns_message_nextname(msg
, section
);
5221 dns_zone_setmaxxfrin(dns_zone_t
*zone
, isc_uint32_t maxxfrin
) {
5222 REQUIRE(DNS_ZONE_VALID(zone
));
5224 zone
->maxxfrin
= maxxfrin
;
5228 dns_zone_getmaxxfrin(dns_zone_t
*zone
) {
5229 REQUIRE(DNS_ZONE_VALID(zone
));
5231 return (zone
->maxxfrin
);
5235 dns_zone_setmaxxfrout(dns_zone_t
*zone
, isc_uint32_t maxxfrout
) {
5236 REQUIRE(DNS_ZONE_VALID(zone
));
5237 zone
->maxxfrout
= maxxfrout
;
5241 dns_zone_getmaxxfrout(dns_zone_t
*zone
) {
5242 REQUIRE(DNS_ZONE_VALID(zone
));
5244 return (zone
->maxxfrout
);
5247 dns_zonetype_t
dns_zone_gettype(dns_zone_t
*zone
) {
5248 REQUIRE(DNS_ZONE_VALID(zone
));
5250 return (zone
->type
);
5254 dns_zone_getorigin(dns_zone_t
*zone
) {
5255 REQUIRE(DNS_ZONE_VALID(zone
));
5257 return (&zone
->origin
);
5261 dns_zone_settask(dns_zone_t
*zone
, isc_task_t
*task
) {
5262 REQUIRE(DNS_ZONE_VALID(zone
));
5265 if (zone
->task
!= NULL
)
5266 isc_task_detach(&zone
->task
);
5267 isc_task_attach(task
, &zone
->task
);
5268 if (zone
->db
!= NULL
)
5269 dns_db_settask(zone
->db
, zone
->task
);
5274 dns_zone_gettask(dns_zone_t
*zone
, isc_task_t
**target
) {
5275 REQUIRE(DNS_ZONE_VALID(zone
));
5276 isc_task_attach(zone
->task
, target
);
5280 dns_zone_setidlein(dns_zone_t
*zone
, isc_uint32_t idlein
) {
5281 REQUIRE(DNS_ZONE_VALID(zone
));
5284 idlein
= DNS_DEFAULT_IDLEIN
;
5285 zone
->idlein
= idlein
;
5289 dns_zone_getidlein(dns_zone_t
*zone
) {
5290 REQUIRE(DNS_ZONE_VALID(zone
));
5292 return (zone
->idlein
);
5296 dns_zone_setidleout(dns_zone_t
*zone
, isc_uint32_t idleout
) {
5297 REQUIRE(DNS_ZONE_VALID(zone
));
5299 zone
->idleout
= idleout
;
5303 dns_zone_getidleout(dns_zone_t
*zone
) {
5304 REQUIRE(DNS_ZONE_VALID(zone
));
5306 return (zone
->idleout
);
5310 notify_done(isc_task_t
*task
, isc_event_t
*event
) {
5311 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
5312 dns_notify_t
*notify
;
5313 isc_result_t result
;
5314 dns_message_t
*message
= NULL
;
5317 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
5321 notify
= event
->ev_arg
;
5322 REQUIRE(DNS_NOTIFY_VALID(notify
));
5323 INSIST(task
== notify
->zone
->task
);
5325 isc_buffer_init(&buf
, rcode
, sizeof(rcode
));
5326 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
5328 result
= revent
->result
;
5329 if (result
== ISC_R_SUCCESS
)
5330 result
= dns_message_create(notify
->zone
->mctx
,
5331 DNS_MESSAGE_INTENTPARSE
, &message
);
5332 if (result
== ISC_R_SUCCESS
)
5333 result
= dns_request_getresponse(revent
->request
, message
,
5334 DNS_MESSAGEPARSE_PRESERVEORDER
);
5335 if (result
== ISC_R_SUCCESS
)
5336 result
= dns_rcode_totext(message
->rcode
, &buf
);
5337 if (result
== ISC_R_SUCCESS
)
5338 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
5339 "notify response from %s: %.*s",
5340 addrbuf
, (int)buf
.used
, rcode
);
5342 notify_log(notify
->zone
, ISC_LOG_DEBUG(2),
5343 "notify to %s failed: %s", addrbuf
,
5344 dns_result_totext(result
));
5347 * Old bind's return formerr if they see a soa record. Retry w/o
5348 * the soa if we see a formerr and had sent a SOA.
5350 isc_event_free(&event
);
5351 if (message
!= NULL
&& message
->rcode
== dns_rcode_formerr
&&
5352 (notify
->flags
& DNS_NOTIFY_NOSOA
) == 0) {
5353 notify
->flags
|= DNS_NOTIFY_NOSOA
;
5354 dns_request_destroy(¬ify
->request
);
5355 result
= notify_send_queue(notify
);
5356 if (result
!= ISC_R_SUCCESS
)
5357 notify_destroy(notify
, ISC_FALSE
);
5359 if (result
== ISC_R_TIMEDOUT
)
5360 notify_log(notify
->zone
, ISC_LOG_DEBUG(1),
5361 "notify to %s: retries exceeded", addrbuf
);
5362 notify_destroy(notify
, ISC_FALSE
);
5364 if (message
!= NULL
)
5365 dns_message_destroy(&message
);
5369 dns_zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
5370 isc_result_t result
;
5372 REQUIRE(DNS_ZONE_VALID(zone
));
5374 result
= zone_replacedb(zone
, db
, dump
);
5380 zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
5381 dns_dbversion_t
*ver
;
5382 isc_result_t result
;
5383 unsigned int soacount
= 0;
5384 unsigned int nscount
= 0;
5387 * 'zone' locked by caller.
5389 REQUIRE(DNS_ZONE_VALID(zone
));
5390 REQUIRE(LOCKED_ZONE(zone
));
5392 result
= zone_get_from_db(db
, &zone
->origin
, &nscount
, &soacount
,
5393 NULL
, NULL
, NULL
, NULL
, NULL
);
5394 if (result
== ISC_R_SUCCESS
) {
5395 if (soacount
!= 1) {
5396 dns_zone_log(zone
, ISC_LOG_ERROR
,
5397 "has %d SOA records", soacount
);
5398 result
= DNS_R_BADZONE
;
5401 dns_zone_log(zone
, ISC_LOG_ERROR
, "has no NS records");
5402 result
= DNS_R_BADZONE
;
5404 if (result
!= ISC_R_SUCCESS
)
5407 dns_zone_log(zone
, ISC_LOG_ERROR
,
5408 "retrieving SOA and NS records failed: %s",
5409 dns_result_totext(result
));
5414 dns_db_currentversion(db
, &ver
);
5417 * The initial version of a slave zone is always dumped;
5418 * subsequent versions may be journalled instead if this
5419 * is enabled in the configuration.
5421 if (zone
->db
!= NULL
&& zone
->journal
!= NULL
&&
5422 DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
) &&
5423 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
)) {
5424 isc_uint32_t serial
;
5426 dns_zone_log(zone
, ISC_LOG_DEBUG(3), "generating diffs");
5428 result
= dns_db_getsoaserial(db
, ver
, &serial
);
5429 if (result
!= ISC_R_SUCCESS
) {
5430 dns_zone_log(zone
, ISC_LOG_ERROR
,
5431 "ixfr-from-differences: unable to get "
5437 * This is checked in zone_postload() for master zones.
5439 if (zone
->type
== dns_zone_slave
&&
5440 !isc_serial_gt(serial
, zone
->serial
)) {
5441 isc_uint32_t serialmin
, serialmax
;
5442 serialmin
= (zone
->serial
+ 1) & 0xffffffffU
;
5443 serialmax
= (zone
->serial
+ 0x7fffffffU
) & 0xffffffffU
;
5444 dns_zone_log(zone
, ISC_LOG_ERROR
,
5445 "ixfr-from-differences: failed: "
5446 "new serial (%u) out of range [%u - %u]",
5447 serial
, serialmin
, serialmax
);
5448 result
= ISC_R_RANGE
;
5452 result
= dns_db_diff(zone
->mctx
, db
, ver
, zone
->db
, NULL
,
5454 if (result
!= ISC_R_SUCCESS
)
5457 zone_needdump(zone
, DNS_DUMP_DELAY
);
5458 else if (zone
->journalsize
!= -1) {
5459 result
= dns_journal_compact(zone
->mctx
, zone
->journal
,
5460 serial
, zone
->journalsize
);
5464 case ISC_R_NOTFOUND
:
5465 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
5466 "dns_journal_compact: %s",
5467 dns_result_totext(result
));
5470 dns_zone_log(zone
, ISC_LOG_ERROR
,
5471 "dns_journal_compact failed: %s",
5472 dns_result_totext(result
));
5477 if (dump
&& zone
->masterfile
!= NULL
) {
5478 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
5479 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
5480 "dumping new zone version");
5481 result
= dns_db_dump(db
, ver
, zone
->masterfile
);
5482 if (result
!= ISC_R_SUCCESS
)
5486 * Update the time the zone was updated, so
5487 * dns_zone_load can avoid loading it when
5488 * the server is reloaded. If isc_time_now
5489 * fails for some reason, all that happens is
5490 * the timestamp is not updated.
5492 TIME_NOW(&zone
->loadtime
);
5495 if (dump
&& zone
->journal
!= NULL
) {
5497 * The in-memory database just changed, and
5498 * because 'dump' is set, it didn't change by
5499 * being loaded from disk. Also, we have not
5500 * journalled diffs for this change.
5501 * Therefore, the on-disk journal is missing
5502 * the deltas for this change. Since it can
5503 * no longer be used to bring the zone
5504 * up-to-date, it is useless and should be
5507 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
5508 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
5509 "removing journal file");
5510 (void)remove(zone
->journal
);
5514 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
5516 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
5517 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
5518 "replacing zone database");
5520 if (zone
->db
!= NULL
)
5521 dns_db_detach(&zone
->db
);
5522 dns_db_attach(db
, &zone
->db
);
5523 dns_db_settask(zone
->db
, zone
->task
);
5524 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
5525 return (ISC_R_SUCCESS
);
5528 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
5533 zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
) {
5535 isc_boolean_t again
= ISC_FALSE
;
5536 unsigned int soacount
;
5537 unsigned int nscount
;
5538 isc_uint32_t serial
, refresh
, retry
, expire
, minimum
;
5539 isc_result_t xfrresult
= result
;
5540 isc_boolean_t free_needed
;
5542 REQUIRE(DNS_ZONE_VALID(zone
));
5544 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
5545 "zone transfer finished: %s", dns_result_totext(result
));
5548 INSIST((zone
->flags
& DNS_ZONEFLG_REFRESH
) != 0);
5549 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
5550 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
);
5555 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
5557 case DNS_R_UPTODATE
:
5558 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
5560 * Has the zone expired underneath us?
5562 if (zone
->db
== NULL
)
5566 * Update the zone structure's data from the actual
5571 INSIST(zone
->db
!= NULL
);
5572 result
= zone_get_from_db(zone
->db
, &zone
->origin
, &nscount
,
5573 &soacount
, &serial
, &refresh
,
5574 &retry
, &expire
, &minimum
);
5575 if (result
== ISC_R_SUCCESS
) {
5577 dns_zone_log(zone
, ISC_LOG_ERROR
,
5579 "has %d SOA record%s", soacount
,
5580 (soacount
!= 0) ? "s" : "");
5582 dns_zone_log(zone
, ISC_LOG_ERROR
,
5584 "has no NS records");
5585 if (DNS_ZONE_FLAG(zone
,
5586 DNS_ZONEFLG_HAVETIMERS
)) {
5587 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
5588 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
5590 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
5594 zone
->serial
= serial
;
5595 zone
->refresh
= RANGE(refresh
, zone
->minrefresh
,
5597 zone
->retry
= RANGE(retry
, zone
->minretry
,
5599 zone
->expire
= RANGE(expire
,
5600 zone
->refresh
+ zone
->retry
,
5602 zone
->minimum
= minimum
;
5603 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
5607 * Set our next update/expire times.
5609 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
5610 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
5611 zone
->refreshtime
= now
;
5612 DNS_ZONE_TIME_ADD(&now
, zone
->expire
,
5615 DNS_ZONE_JITTER_ADD(&now
, zone
->refresh
,
5616 &zone
->refreshtime
);
5617 DNS_ZONE_TIME_ADD(&now
, zone
->expire
,
5620 if (result
== ISC_R_SUCCESS
&& xfrresult
== ISC_R_SUCCESS
) {
5621 char buf
[DNS_NAME_FORMATSIZE
+ sizeof(": TSIG ''")];
5622 if (zone
->tsigkey
!= NULL
) {
5623 char namebuf
[DNS_NAME_FORMATSIZE
];
5624 dns_name_format(&zone
->tsigkey
->name
, namebuf
,
5626 snprintf(buf
, sizeof(buf
), ": TSIG '%s'",
5630 dns_zone_log(zone
, ISC_LOG_INFO
,
5631 "transferred serial %u%s",
5636 * This is not neccessary if we just performed a AXFR
5637 * however it is necessary for an IXFR / UPTODATE and
5638 * won't hurt with an AXFR.
5640 if (zone
->masterfile
!= NULL
|| zone
->journal
!= NULL
) {
5641 result
= ISC_R_FAILURE
;
5642 if (zone
->journal
!= NULL
)
5643 result
= isc_file_settime(zone
->journal
, &now
);
5644 if (result
!= ISC_R_SUCCESS
&&
5645 zone
->masterfile
!= NULL
)
5646 result
= isc_file_settime(zone
->masterfile
,
5648 /* Someone removed the file from underneath us! */
5649 if (result
== ISC_R_FILENOTFOUND
&&
5650 zone
->masterfile
!= NULL
)
5651 zone_needdump(zone
, DNS_DUMP_DELAY
);
5652 else if (result
!= ISC_R_SUCCESS
)
5653 dns_zone_log(zone
, ISC_LOG_ERROR
,
5654 "transfer: could not set file "
5655 "modification time of '%s': %s",
5657 dns_result_totext(result
));
5663 /* Force retry with AXFR. */
5664 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
5670 * Skip to next failed / untried master.
5674 } while (zone
->curmaster
< zone
->masterscnt
&&
5675 zone
->mastersok
[zone
->curmaster
]);
5678 if (zone
->curmaster
>= zone
->masterscnt
) {
5679 zone
->curmaster
= 0;
5680 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_USEALTXFRSRC
) &&
5681 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
)) {
5682 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
5683 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
5684 while (zone
->curmaster
< zone
->masterscnt
&&
5685 zone
->mastersok
[zone
->curmaster
])
5689 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_USEALTXFRSRC
);
5691 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
5696 zone_settimer(zone
, &now
);
5699 * If creating the transfer object failed, zone->xfr is NULL.
5700 * Otherwise, we are called as the done callback of a zone
5701 * transfer object that just entered its shutting-down
5702 * state. Since we are no longer responsible for shutting
5703 * it down, we can detach our reference.
5705 if (zone
->xfr
!= NULL
)
5706 dns_xfrin_detach(&zone
->xfr
);
5708 if (zone
->tsigkey
!= NULL
)
5709 dns_tsigkey_detach(&zone
->tsigkey
);
5712 * This transfer finishing freed up a transfer quota slot.
5713 * Let any other zones waiting for quota have it.
5715 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
5716 ISC_LIST_UNLINK(zone
->zmgr
->xfrin_in_progress
, zone
, statelink
);
5717 zone
->statelist
= NULL
;
5718 zmgr_resume_xfrs(zone
->zmgr
, ISC_FALSE
);
5719 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
5722 * Retry with a different server if necessary.
5724 if (again
&& !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
5725 queue_soa_query(zone
);
5727 INSIST(zone
->irefs
> 0);
5729 free_needed
= exit_check(zone
);
5736 zone_loaddone(void *arg
, isc_result_t result
) {
5737 static char me
[] = "zone_loaddone";
5738 dns_load_t
*load
= arg
;
5740 isc_result_t tresult
;
5742 REQUIRE(DNS_LOAD_VALID(load
));
5747 tresult
= dns_db_endload(load
->db
, &load
->callbacks
.add_private
);
5748 if (tresult
!= ISC_R_SUCCESS
&&
5749 (result
== ISC_R_SUCCESS
|| result
== DNS_R_SEENINCLUDE
))
5752 LOCK_ZONE(load
->zone
);
5753 (void)zone_postload(load
->zone
, load
->db
, load
->loadtime
, result
);
5754 zonemgr_putio(&load
->zone
->readio
);
5755 DNS_ZONE_CLRFLAG(load
->zone
, DNS_ZONEFLG_LOADING
);
5756 UNLOCK_ZONE(load
->zone
);
5759 dns_db_detach(&load
->db
);
5760 if (load
->zone
->lctx
!= NULL
)
5761 dns_loadctx_detach(&load
->zone
->lctx
);
5762 dns_zone_idetach(&load
->zone
);
5763 isc_mem_putanddetach(&load
->mctx
, load
, sizeof(*load
));
5767 dns_zone_getssutable(dns_zone_t
*zone
, dns_ssutable_t
**table
) {
5768 REQUIRE(DNS_ZONE_VALID(zone
));
5769 REQUIRE(table
!= NULL
);
5770 REQUIRE(*table
== NULL
);
5773 if (zone
->ssutable
!= NULL
)
5774 dns_ssutable_attach(zone
->ssutable
, table
);
5779 dns_zone_setssutable(dns_zone_t
*zone
, dns_ssutable_t
*table
) {
5780 REQUIRE(DNS_ZONE_VALID(zone
));
5783 if (zone
->ssutable
!= NULL
)
5784 dns_ssutable_detach(&zone
->ssutable
);
5786 dns_ssutable_attach(table
, &zone
->ssutable
);
5791 dns_zone_setsigvalidityinterval(dns_zone_t
*zone
, isc_uint32_t interval
) {
5792 REQUIRE(DNS_ZONE_VALID(zone
));
5794 zone
->sigvalidityinterval
= interval
;
5798 dns_zone_getsigvalidityinterval(dns_zone_t
*zone
) {
5799 REQUIRE(DNS_ZONE_VALID(zone
));
5801 return (zone
->sigvalidityinterval
);
5805 queue_xfrin(dns_zone_t
*zone
) {
5806 const char me
[] = "queue_xfrin";
5807 isc_result_t result
;
5808 dns_zonemgr_t
*zmgr
= zone
->zmgr
;
5812 INSIST(zone
->statelist
== NULL
);
5814 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5815 ISC_LIST_APPEND(zmgr
->waiting_for_xfrin
, zone
, statelink
);
5819 zone
->statelist
= &zmgr
->waiting_for_xfrin
;
5820 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
5821 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5823 if (result
== ISC_R_QUOTA
) {
5824 dns_zone_logc(zone
, DNS_LOGCATEGORY_XFER_IN
, ISC_LOG_INFO
,
5825 "zone transfer deferred due to quota");
5826 } else if (result
!= ISC_R_SUCCESS
) {
5827 dns_zone_logc(zone
, DNS_LOGCATEGORY_XFER_IN
, ISC_LOG_ERROR
,
5828 "starting zone transfer: %s",
5829 isc_result_totext(result
));
5834 * This event callback is called when a zone has received
5835 * any necessary zone transfer quota. This is the time
5836 * to go ahead and start the transfer.
5839 got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
) {
5840 isc_result_t result
;
5841 dns_peer_t
*peer
= NULL
;
5842 char mastertext
[256];
5843 dns_rdatatype_t xfrtype
;
5844 dns_zone_t
*zone
= event
->ev_arg
;
5845 isc_netaddr_t masterip
;
5846 isc_sockaddr_t sourceaddr
;
5847 isc_sockaddr_t masteraddr
;
5851 INSIST(task
== zone
->task
);
5853 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
5854 result
= ISC_R_CANCELED
;
5858 isc_sockaddr_format(&zone
->masteraddr
, mastertext
, sizeof(mastertext
));
5860 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
5861 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
,
5865 * Decide whether we should request IXFR or AXFR.
5867 if (zone
->db
== NULL
) {
5868 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
5869 "no database exists yet, "
5870 "requesting AXFR of "
5871 "initial version from %s", mastertext
);
5872 xfrtype
= dns_rdatatype_axfr
;
5873 } else if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
)) {
5874 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "ixfr-from-differences "
5875 "set, requesting AXFR from %s", mastertext
);
5876 xfrtype
= dns_rdatatype_axfr
;
5877 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
)) {
5878 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
5879 "forced reload, requesting AXFR of "
5880 "initial version from %s", mastertext
);
5881 xfrtype
= dns_rdatatype_axfr
;
5882 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLAG_NOIXFR
)) {
5883 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
5884 "retrying with AXFR from %s due to "
5885 "previous IXFR failure", mastertext
);
5886 xfrtype
= dns_rdatatype_axfr
;
5888 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
5891 isc_boolean_t use_ixfr
= ISC_TRUE
;
5893 dns_peer_getrequestixfr(peer
, &use_ixfr
) ==
5895 ; /* Using peer setting */
5897 use_ixfr
= zone
->view
->requestixfr
;
5899 if (use_ixfr
== ISC_FALSE
) {
5900 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
5902 "requesting AXFR from %s",
5904 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SOABEFOREAXFR
))
5905 xfrtype
= dns_rdatatype_soa
;
5907 xfrtype
= dns_rdatatype_axfr
;
5909 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
5910 "requesting IXFR from %s",
5912 xfrtype
= dns_rdatatype_ixfr
;
5917 * Determine if we should attempt to sign the request with TSIG.
5919 result
= ISC_R_NOTFOUND
;
5921 * First, look for a tsig key in the master statement, then
5922 * try for a server key.
5924 if ((zone
->masterkeynames
!= NULL
) &&
5925 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
5926 dns_view_t
*view
= dns_zone_getview(zone
);
5927 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
5928 result
= dns_view_gettsig(view
, keyname
, &zone
->tsigkey
);
5930 if (zone
->tsigkey
== NULL
)
5931 result
= dns_view_getpeertsig(zone
->view
, &masterip
,
5934 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
5935 dns_zone_log(zone
, ISC_LOG_ERROR
,
5936 "could not get TSIG key "
5937 "for zone transfer: %s",
5938 isc_result_totext(result
));
5942 masteraddr
= zone
->masteraddr
;
5943 sourceaddr
= zone
->sourceaddr
;
5945 INSIST(isc_sockaddr_pf(&masteraddr
) == isc_sockaddr_pf(&sourceaddr
));
5946 result
= dns_xfrin_create2(zone
, xfrtype
, &masteraddr
, &sourceaddr
,
5947 zone
->tsigkey
, zone
->mctx
,
5948 zone
->zmgr
->timermgr
, zone
->zmgr
->socketmgr
,
5949 zone
->task
, zone_xfrdone
, &zone
->xfr
);
5952 * Any failure in this function is handled like a failed
5953 * zone transfer. This ensures that we get removed from
5954 * zmgr->xfrin_in_progress.
5956 if (result
!= ISC_R_SUCCESS
)
5957 zone_xfrdone(zone
, result
);
5959 isc_event_free(&event
);
5963 * Update forwarding support.
5967 forward_destroy(dns_forward_t
*forward
) {
5970 if (forward
->request
!= NULL
)
5971 dns_request_destroy(&forward
->request
);
5972 if (forward
->msgbuf
!= NULL
)
5973 isc_buffer_free(&forward
->msgbuf
);
5974 if (forward
->zone
!= NULL
)
5975 dns_zone_idetach(&forward
->zone
);
5976 isc_mem_putanddetach(&forward
->mctx
, forward
, sizeof(*forward
));
5980 sendtomaster(dns_forward_t
*forward
) {
5981 isc_result_t result
;
5984 LOCK_ZONE(forward
->zone
);
5985 if (forward
->which
>= forward
->zone
->masterscnt
) {
5986 UNLOCK_ZONE(forward
->zone
);
5987 return (ISC_R_NOMORE
);
5990 forward
->addr
= forward
->zone
->masters
[forward
->which
];
5992 * Always use TCP regardless of whether the original update
5994 * XXX The timeout may but a bit small if we are far down a
5995 * transfer graph and the master has to try several masters.
5997 switch (isc_sockaddr_pf(&forward
->addr
)) {
5999 src
= forward
->zone
->xfrsource4
;
6002 src
= forward
->zone
->xfrsource6
;
6005 result
= ISC_R_NOTIMPLEMENTED
;
6008 result
= dns_request_createraw(forward
->zone
->view
->requestmgr
,
6010 &src
, &forward
->addr
,
6011 DNS_REQUESTOPT_TCP
, 15 /* XXX */,
6012 forward
->zone
->task
,
6013 forward_callback
, forward
,
6016 UNLOCK_ZONE(forward
->zone
);
6021 forward_callback(isc_task_t
*task
, isc_event_t
*event
) {
6022 const char me
[] = "forward_callback";
6023 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
6024 dns_message_t
*msg
= NULL
;
6025 char master
[ISC_SOCKADDR_FORMATSIZE
];
6026 isc_result_t result
;
6027 dns_forward_t
*forward
;
6032 forward
= revent
->ev_arg
;
6033 INSIST(DNS_FORWARD_VALID(forward
));
6034 zone
= forward
->zone
;
6035 INSIST(DNS_ZONE_VALID(zone
));
6039 isc_sockaddr_format(&forward
->addr
, master
, sizeof(master
));
6041 if (revent
->result
!= ISC_R_SUCCESS
) {
6042 dns_zone_log(zone
, ISC_LOG_INFO
,
6043 "could not forward dynamic update to %s: %s",
6044 master
, dns_result_totext(revent
->result
));
6048 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
6049 if (result
!= ISC_R_SUCCESS
)
6052 result
= dns_request_getresponse(revent
->request
, msg
,
6053 DNS_MESSAGEPARSE_PRESERVEORDER
|
6054 DNS_MESSAGEPARSE_CLONEBUFFER
);
6055 if (result
!= ISC_R_SUCCESS
)
6058 switch (msg
->rcode
) {
6060 * Pass these rcodes back to client.
6062 case dns_rcode_noerror
:
6063 case dns_rcode_yxdomain
:
6064 case dns_rcode_yxrrset
:
6065 case dns_rcode_nxrrset
:
6066 case dns_rcode_refused
:
6067 case dns_rcode_nxdomain
:
6070 /* These should not occur if the masters/zone are valid. */
6071 case dns_rcode_notzone
:
6072 case dns_rcode_notauth
: {
6076 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
6077 (void)dns_rcode_totext(msg
->rcode
, &rb
);
6078 dns_zone_log(zone
, ISC_LOG_WARNING
,
6079 "forwarding dynamic update: "
6080 "unexpected response: master %s returned: %.*s",
6081 master
, (int)rb
.used
, rcode
);
6085 /* Try another server for these rcodes. */
6086 case dns_rcode_formerr
:
6087 case dns_rcode_servfail
:
6088 case dns_rcode_notimp
:
6089 case dns_rcode_badvers
:
6095 (forward
->callback
)(forward
->callback_arg
, ISC_R_SUCCESS
, msg
);
6097 dns_request_destroy(&forward
->request
);
6098 forward_destroy(forward
);
6099 isc_event_free(&event
);
6104 dns_message_destroy(&msg
);
6105 isc_event_free(&event
);
6107 dns_request_destroy(&forward
->request
);
6108 result
= sendtomaster(forward
);
6109 if (result
!= ISC_R_SUCCESS
) {
6111 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
6112 "exhausted dynamic update forwarder list");
6113 (forward
->callback
)(forward
->callback_arg
, result
, NULL
);
6114 forward_destroy(forward
);
6119 dns_zone_forwardupdate(dns_zone_t
*zone
, dns_message_t
*msg
,
6120 dns_updatecallback_t callback
, void *callback_arg
)
6122 dns_forward_t
*forward
;
6123 isc_result_t result
;
6126 REQUIRE(DNS_ZONE_VALID(zone
));
6127 REQUIRE(msg
!= NULL
);
6128 REQUIRE(callback
!= NULL
);
6130 forward
= isc_mem_get(zone
->mctx
, sizeof(*forward
));
6131 if (forward
== NULL
)
6132 return (ISC_R_NOMEMORY
);
6134 forward
->request
= NULL
;
6135 forward
->zone
= NULL
;
6136 forward
->msgbuf
= NULL
;
6139 forward
->callback
= callback
;
6140 forward
->callback_arg
= callback_arg
;
6141 forward
->magic
= FORWARD_MAGIC
;
6143 mr
= dns_message_getrawmessage(msg
);
6145 result
= ISC_R_UNEXPECTEDEND
;
6149 result
= isc_buffer_allocate(zone
->mctx
, &forward
->msgbuf
, mr
->length
);
6150 if (result
!= ISC_R_SUCCESS
)
6152 result
= isc_buffer_copyregion(forward
->msgbuf
, mr
);
6153 if (result
!= ISC_R_SUCCESS
)
6156 isc_mem_attach(zone
->mctx
, &forward
->mctx
);
6157 dns_zone_iattach(zone
, &forward
->zone
);
6158 result
= sendtomaster(forward
);
6161 if (result
!= ISC_R_SUCCESS
) {
6162 forward_destroy(forward
);
6168 dns_zone_next(dns_zone_t
*zone
, dns_zone_t
**next
) {
6169 REQUIRE(DNS_ZONE_VALID(zone
));
6170 REQUIRE(next
!= NULL
&& *next
== NULL
);
6172 *next
= ISC_LIST_NEXT(zone
, link
);
6174 return (ISC_R_NOMORE
);
6176 return (ISC_R_SUCCESS
);
6180 dns_zone_first(dns_zonemgr_t
*zmgr
, dns_zone_t
**first
) {
6181 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6182 REQUIRE(first
!= NULL
&& *first
== NULL
);
6184 *first
= ISC_LIST_HEAD(zmgr
->zones
);
6186 return (ISC_R_NOMORE
);
6188 return (ISC_R_SUCCESS
);
6196 dns_zonemgr_create(isc_mem_t
*mctx
, isc_taskmgr_t
*taskmgr
,
6197 isc_timermgr_t
*timermgr
, isc_socketmgr_t
*socketmgr
,
6198 dns_zonemgr_t
**zmgrp
)
6200 dns_zonemgr_t
*zmgr
;
6201 isc_result_t result
;
6202 isc_interval_t interval
;
6204 zmgr
= isc_mem_get(mctx
, sizeof(*zmgr
));
6206 return (ISC_R_NOMEMORY
);
6209 isc_mem_attach(mctx
, &zmgr
->mctx
);
6210 zmgr
->taskmgr
= taskmgr
;
6211 zmgr
->timermgr
= timermgr
;
6212 zmgr
->socketmgr
= socketmgr
;
6213 zmgr
->zonetasks
= NULL
;
6216 ISC_LIST_INIT(zmgr
->zones
);
6217 ISC_LIST_INIT(zmgr
->waiting_for_xfrin
);
6218 ISC_LIST_INIT(zmgr
->xfrin_in_progress
);
6219 result
= isc_rwlock_init(&zmgr
->rwlock
, 0, 0);
6220 if (result
!= ISC_R_SUCCESS
) {
6221 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
6222 "isc_rwlock_init() failed: %s",
6223 isc_result_totext(result
));
6224 result
= ISC_R_UNEXPECTED
;
6227 zmgr
->transfersin
= 10;
6228 zmgr
->transfersperns
= 2;
6230 /* Create the zone task pool. */
6231 result
= isc_taskpool_create(taskmgr
, mctx
,
6232 8 /* XXX */, 2, &zmgr
->zonetasks
);
6233 if (result
!= ISC_R_SUCCESS
)
6236 /* Create a single task for queueing of SOA queries. */
6237 result
= isc_task_create(taskmgr
, 1, &zmgr
->task
);
6238 if (result
!= ISC_R_SUCCESS
)
6240 isc_task_setname(zmgr
->task
, "zmgr", zmgr
);
6241 result
= isc_ratelimiter_create(mctx
, timermgr
, zmgr
->task
,
6243 if (result
!= ISC_R_SUCCESS
)
6245 /* default to 20 refresh queries / notifies per second. */
6246 isc_interval_set(&interval
, 0, 1000000000/2);
6247 result
= isc_ratelimiter_setinterval(zmgr
->rl
, &interval
);
6248 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
6249 isc_ratelimiter_setpertic(zmgr
->rl
, 10);
6253 ISC_LIST_INIT(zmgr
->high
);
6254 ISC_LIST_INIT(zmgr
->low
);
6256 result
= isc_mutex_init(&zmgr
->iolock
);
6257 if (result
!= ISC_R_SUCCESS
) {
6258 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
6259 "isc_mutex_init() failed: %s",
6260 isc_result_totext(result
));
6263 zmgr
->magic
= ZONEMGR_MAGIC
;
6266 return (ISC_R_SUCCESS
);
6270 DESTROYLOCK(&zmgr
->iolock
);
6273 isc_ratelimiter_detach(&zmgr
->rl
);
6275 isc_task_detach(&zmgr
->task
);
6277 isc_taskpool_destroy(&zmgr
->zonetasks
);
6279 isc_rwlock_destroy(&zmgr
->rwlock
);
6281 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof(*zmgr
));
6282 isc_mem_detach(&mctx
);
6287 dns_zonemgr_managezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
6288 isc_result_t result
;
6290 REQUIRE(DNS_ZONE_VALID(zone
));
6291 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6293 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6295 REQUIRE(zone
->task
== NULL
);
6296 REQUIRE(zone
->timer
== NULL
);
6297 REQUIRE(zone
->zmgr
== NULL
);
6299 isc_taskpool_gettask(zmgr
->zonetasks
,
6300 dns_name_hash(dns_zone_getorigin(zone
),
6305 * Set the task name. The tag will arbitrarily point to one
6306 * of the zones sharing the task (in practice, the one
6307 * to be managed last).
6309 isc_task_setname(zone
->task
, "zone", zone
);
6311 result
= isc_timer_create(zmgr
->timermgr
, isc_timertype_inactive
,
6313 zone
->task
, zone_timer
, zone
,
6315 if (result
!= ISC_R_SUCCESS
)
6318 * The timer "holds" a iref.
6321 INSIST(zone
->irefs
!= 0);
6323 ISC_LIST_APPEND(zmgr
->zones
, zone
, link
);
6330 isc_task_detach(&zone
->task
);
6334 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6339 dns_zonemgr_releasezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
6340 isc_boolean_t free_now
= ISC_FALSE
;
6342 REQUIRE(DNS_ZONE_VALID(zone
));
6343 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6344 REQUIRE(zone
->zmgr
== zmgr
);
6346 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6349 ISC_LIST_UNLINK(zmgr
->zones
, zone
, link
);
6352 if (zmgr
->refs
== 0)
6353 free_now
= ISC_TRUE
;
6356 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6360 ENSURE(zone
->zmgr
== NULL
);
6364 dns_zonemgr_attach(dns_zonemgr_t
*source
, dns_zonemgr_t
**target
) {
6365 REQUIRE(DNS_ZONEMGR_VALID(source
));
6366 REQUIRE(target
!= NULL
&& *target
== NULL
);
6368 RWLOCK(&source
->rwlock
, isc_rwlocktype_write
);
6369 REQUIRE(source
->refs
> 0);
6371 INSIST(source
->refs
> 0);
6372 RWUNLOCK(&source
->rwlock
, isc_rwlocktype_write
);
6377 dns_zonemgr_detach(dns_zonemgr_t
**zmgrp
) {
6378 dns_zonemgr_t
*zmgr
;
6379 isc_boolean_t free_now
= ISC_FALSE
;
6381 REQUIRE(zmgrp
!= NULL
);
6383 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6385 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6387 if (zmgr
->refs
== 0)
6388 free_now
= ISC_TRUE
;
6389 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6396 dns_zonemgr_forcemaint(dns_zonemgr_t
*zmgr
) {
6399 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6401 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
6402 for (p
= ISC_LIST_HEAD(zmgr
->zones
);
6404 p
= ISC_LIST_NEXT(p
, link
))
6406 dns_zone_maintenance(p
);
6408 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
6411 * Recent configuration changes may have increased the
6412 * amount of available transfers quota. Make sure any
6413 * transfers currently blocked on quota get started if
6416 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6417 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
6418 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6419 return (ISC_R_SUCCESS
);
6423 dns_zonemgr_resumexfrs(dns_zonemgr_t
*zmgr
) {
6425 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6427 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6428 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
6429 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
6433 dns_zonemgr_shutdown(dns_zonemgr_t
*zmgr
) {
6434 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6436 isc_ratelimiter_shutdown(zmgr
->rl
);
6438 if (zmgr
->task
!= NULL
)
6439 isc_task_destroy(&zmgr
->task
);
6440 if (zmgr
->zonetasks
!= NULL
)
6441 isc_taskpool_destroy(&zmgr
->zonetasks
);
6445 zonemgr_free(dns_zonemgr_t
*zmgr
) {
6448 INSIST(zmgr
->refs
== 0);
6449 INSIST(ISC_LIST_EMPTY(zmgr
->zones
));
6453 DESTROYLOCK(&zmgr
->iolock
);
6454 isc_ratelimiter_detach(&zmgr
->rl
);
6456 isc_rwlock_destroy(&zmgr
->rwlock
);
6458 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof(*zmgr
));
6459 isc_mem_detach(&mctx
);
6463 dns_zonemgr_settransfersin(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
6464 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6466 zmgr
->transfersin
= value
;
6470 dns_zonemgr_getttransfersin(dns_zonemgr_t
*zmgr
) {
6471 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6473 return (zmgr
->transfersin
);
6477 dns_zonemgr_settransfersperns(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
6478 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6480 zmgr
->transfersperns
= value
;
6484 dns_zonemgr_getttransfersperns(dns_zonemgr_t
*zmgr
) {
6485 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6487 return (zmgr
->transfersperns
);
6491 * Try to start a new incoming zone transfer to fill a quota
6492 * slot that was just vacated.
6495 * The zone manager is locked by the caller.
6498 zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
) {
6502 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
6506 isc_result_t result
;
6507 next
= ISC_LIST_NEXT(zone
, statelink
);
6508 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
6509 if (result
== ISC_R_SUCCESS
) {
6513 * We successfully filled the slot. We're done.
6516 } else if (result
== ISC_R_QUOTA
) {
6518 * Not enough quota. This is probably the per-server
6519 * quota, because we usually get called when a unit of
6520 * global quota has just been freed. Try the next
6521 * zone, it may succeed if it uses another master.
6525 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
6526 "starting zone transfer: %s",
6527 isc_result_totext(result
));
6534 * Try to start an incoming zone transfer for 'zone', quota permitting.
6537 * The zone manager is locked by the caller.
6540 * ISC_R_SUCCESS There was enough quota and we attempted to
6541 * start a transfer. zone_xfrdone() has been or will
6543 * ISC_R_QUOTA Not enough quota.
6547 zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
6548 dns_peer_t
*peer
= NULL
;
6549 isc_netaddr_t masterip
;
6550 isc_uint32_t nxfrsin
, nxfrsperns
;
6552 isc_uint32_t maxtransfersin
, maxtransfersperns
;
6556 * Find any configured information about the server we'd
6557 * like to transfer this zone from.
6559 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
6560 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
,
6564 * Determine the total maximum number of simultaneous
6565 * transfers allowed, and the maximum for this specific
6568 maxtransfersin
= zmgr
->transfersin
;
6569 maxtransfersperns
= zmgr
->transfersperns
;
6571 (void)dns_peer_gettransfers(peer
, &maxtransfersperns
);
6574 * Count the total number of transfers that are in progress,
6575 * and the number of transfers in progress from this master.
6576 * We linearly scan a list of all transfers; if this turns
6577 * out to be too slow, we could hash on the master address.
6579 nxfrsin
= nxfrsperns
= 0;
6580 for (x
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
6582 x
= ISC_LIST_NEXT(x
, statelink
))
6585 isc_netaddr_fromsockaddr(&xip
, &x
->masteraddr
);
6587 if (isc_netaddr_equal(&xip
, &masterip
))
6591 /* Enforce quota. */
6592 if (nxfrsin
>= maxtransfersin
)
6593 return (ISC_R_QUOTA
);
6595 if (nxfrsperns
>= maxtransfersperns
)
6596 return (ISC_R_QUOTA
);
6599 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
6600 * list and send it an event to let it start the actual transfer in the
6601 * context of its own task.
6603 e
= isc_event_allocate(zmgr
->mctx
, zmgr
,
6604 DNS_EVENT_ZONESTARTXFRIN
,
6605 got_transfer_quota
, zone
,
6606 sizeof(isc_event_t
));
6608 return (ISC_R_NOMEMORY
);
6611 INSIST(zone
->statelist
== &zmgr
->waiting_for_xfrin
);
6612 ISC_LIST_UNLINK(zmgr
->waiting_for_xfrin
, zone
, statelink
);
6613 ISC_LIST_APPEND(zmgr
->xfrin_in_progress
, zone
, statelink
);
6614 zone
->statelist
= &zmgr
->xfrin_in_progress
;
6615 isc_task_send(zone
->task
, &e
);
6616 dns_zone_log(zone
, ISC_LOG_INFO
, "Transfer started.");
6619 return (ISC_R_SUCCESS
);
6623 dns_zonemgr_setiolimit(dns_zonemgr_t
*zmgr
, isc_uint32_t iolimit
) {
6625 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6626 REQUIRE(iolimit
> 0);
6628 zmgr
->iolimit
= iolimit
;
6632 dns_zonemgr_getiolimit(dns_zonemgr_t
*zmgr
) {
6634 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6636 return (zmgr
->iolimit
);
6640 * Get permission to request a file handle from the OS.
6641 * An event will be sent to action when one is available.
6642 * There are two queues available (high and low), the high
6643 * queue will be serviced before the low one.
6645 * zonemgr_putio() must be called after the event is delivered to
6650 zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
6651 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
6655 isc_boolean_t queue
;
6657 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6658 REQUIRE(iop
!= NULL
&& *iop
== NULL
);
6660 io
= isc_mem_get(zmgr
->mctx
, sizeof(*io
));
6662 return (ISC_R_NOMEMORY
);
6663 io
->event
= isc_event_allocate(zmgr
->mctx
, task
, DNS_EVENT_IOREADY
,
6664 action
, arg
, sizeof(*io
->event
));
6665 if (io
->event
== NULL
) {
6666 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
6667 return (ISC_R_NOMEMORY
);
6672 isc_task_attach(task
, &io
->task
);
6673 ISC_LINK_INIT(io
, link
);
6674 io
->magic
= IO_MAGIC
;
6676 LOCK(&zmgr
->iolock
);
6678 queue
= ISC_TF(zmgr
->ioactive
> zmgr
->iolimit
);
6681 ISC_LIST_APPEND(zmgr
->high
, io
, link
);
6683 ISC_LIST_APPEND(zmgr
->low
, io
, link
);
6685 UNLOCK(&zmgr
->iolock
);
6689 isc_task_send(io
->task
, &io
->event
);
6691 return (ISC_R_SUCCESS
);
6695 zonemgr_putio(dns_io_t
**iop
) {
6698 dns_zonemgr_t
*zmgr
;
6700 REQUIRE(iop
!= NULL
);
6702 REQUIRE(DNS_IO_VALID(io
));
6706 INSIST(!ISC_LINK_LINKED(io
, link
));
6707 INSIST(io
->event
== NULL
);
6710 isc_task_detach(&io
->task
);
6712 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
6714 LOCK(&zmgr
->iolock
);
6715 INSIST(zmgr
->ioactive
> 0);
6717 next
= HEAD(zmgr
->high
);
6719 next
= HEAD(zmgr
->low
);
6722 ISC_LIST_UNLINK(zmgr
->high
, next
, link
);
6724 ISC_LIST_UNLINK(zmgr
->low
, next
, link
);
6725 INSIST(next
->event
!= NULL
);
6727 UNLOCK(&zmgr
->iolock
);
6729 isc_task_send(next
->task
, &next
->event
);
6733 zonemgr_cancelio(dns_io_t
*io
) {
6734 isc_boolean_t send_event
= ISC_FALSE
;
6736 REQUIRE(DNS_IO_VALID(io
));
6739 * If we are queued to be run then dequeue.
6741 LOCK(&io
->zmgr
->iolock
);
6742 if (ISC_LINK_LINKED(io
, link
)) {
6744 ISC_LIST_UNLINK(io
->zmgr
->high
, io
, link
);
6746 ISC_LIST_UNLINK(io
->zmgr
->low
, io
, link
);
6748 send_event
= ISC_TRUE
;
6749 INSIST(io
->event
!= NULL
);
6751 UNLOCK(&io
->zmgr
->iolock
);
6753 io
->event
->ev_attributes
|= ISC_EVENTATTR_CANCELED
;
6754 isc_task_send(io
->task
, &io
->event
);
6759 zone_saveunique(dns_zone_t
*zone
, const char *path
, const char *templat
) {
6762 isc_result_t result
;
6764 buflen
= strlen(path
) + strlen(templat
) + 2;
6766 buf
= isc_mem_get(zone
->mctx
, buflen
);
6770 result
= isc_file_template(path
, templat
, buf
, buflen
);
6771 if (result
!= ISC_R_SUCCESS
)
6774 result
= isc_file_renameunique(path
, buf
);
6775 if (result
!= ISC_R_SUCCESS
)
6778 dns_zone_log(zone
, ISC_LOG_INFO
, "saved '%s' as '%s'",
6782 isc_mem_put(zone
->mctx
, buf
, buflen
);
6786 /* Hook for ondestroy notifcation from a database. */
6789 dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
) {
6790 dns_db_t
*db
= event
->sender
;
6793 isc_event_free(&event
);
6795 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
6796 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
6797 "database (%p) destroyed", (void*) db
);
6802 dns_zonemgr_setserialqueryrate(dns_zonemgr_t
*zmgr
, unsigned int value
) {
6803 isc_interval_t interval
;
6805 isc_uint32_t pertic
;
6806 isc_result_t result
;
6808 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6817 } else if (value
<= 10) {
6819 ns
= 1000000000 / value
;
6823 ns
= (1000000000 / value
) * 10;
6827 isc_interval_set(&interval
, s
, ns
);
6828 result
= isc_ratelimiter_setinterval(zmgr
->rl
, &interval
);
6829 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
6830 isc_ratelimiter_setpertic(zmgr
->rl
, pertic
);
6832 zmgr
->serialqueryrate
= value
;
6836 dns_zonemgr_getserialqueryrate(dns_zonemgr_t
*zmgr
) {
6837 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6839 return (zmgr
->serialqueryrate
);
6843 dns_zone_forcereload(dns_zone_t
*zone
) {
6844 REQUIRE(DNS_ZONE_VALID(zone
));
6846 if (zone
->type
== dns_zone_master
)
6850 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
6852 dns_zone_refresh(zone
);
6856 dns_zone_isforced(dns_zone_t
*zone
) {
6857 REQUIRE(DNS_ZONE_VALID(zone
));
6859 return (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
));
6863 dns_zone_setstatistics(dns_zone_t
*zone
, isc_boolean_t on
) {
6864 isc_result_t result
= ISC_R_SUCCESS
;
6868 if (zone
->counters
!= NULL
)
6870 result
= dns_stats_alloccounters(zone
->mctx
, &zone
->counters
);
6872 if (zone
->counters
== NULL
)
6874 dns_stats_freecounters(zone
->mctx
, &zone
->counters
);
6882 dns_zone_getstatscounters(dns_zone_t
*zone
) {
6883 return (zone
->counters
);
6887 dns_zone_dialup(dns_zone_t
*zone
) {
6889 REQUIRE(DNS_ZONE_VALID(zone
));
6891 zone_debuglog(zone
, "dns_zone_dialup", 3,
6892 "notify = %d, refresh = %d",
6893 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
),
6894 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
));
6896 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
6897 dns_zone_notify(zone
);
6898 if (zone
->type
!= dns_zone_master
&&
6899 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
6900 dns_zone_refresh(zone
);
6904 dns_zone_setdialup(dns_zone_t
*zone
, dns_dialuptype_t dialup
) {
6905 REQUIRE(DNS_ZONE_VALID(zone
));
6908 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
|
6909 DNS_ZONEFLG_DIALREFRESH
|
6910 DNS_ZONEFLG_NOREFRESH
);
6912 case dns_dialuptype_no
:
6914 case dns_dialuptype_yes
:
6915 DNS_ZONE_SETFLAG(zone
, (DNS_ZONEFLG_DIALNOTIFY
|
6916 DNS_ZONEFLG_DIALREFRESH
|
6917 DNS_ZONEFLG_NOREFRESH
));
6919 case dns_dialuptype_notify
:
6920 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
6922 case dns_dialuptype_notifypassive
:
6923 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
6924 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
6926 case dns_dialuptype_refresh
:
6927 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALREFRESH
);
6928 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
6930 case dns_dialuptype_passive
:
6931 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
6940 dns_zone_setkeydirectory(dns_zone_t
*zone
, const char *directory
) {
6941 isc_result_t result
= ISC_R_SUCCESS
;
6943 REQUIRE(DNS_ZONE_VALID(zone
));
6946 result
= dns_zone_setstring(zone
, &zone
->keydirectory
, directory
);
6953 dns_zone_getkeydirectory(dns_zone_t
*zone
) {
6954 REQUIRE(DNS_ZONE_VALID(zone
));
6956 return (zone
->keydirectory
);
6959 dns_zonemgr_getcount(dns_zonemgr_t
*zmgr
, int state
) {
6961 unsigned int count
= 0;
6963 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6965 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
6967 case DNS_ZONESTATE_XFERRUNNING
:
6968 for (zone
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
6970 zone
= ISC_LIST_NEXT(zone
, statelink
))
6973 case DNS_ZONESTATE_XFERDEFERRED
:
6974 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
6976 zone
= ISC_LIST_NEXT(zone
, statelink
))
6979 case DNS_ZONESTATE_SOAQUERY
:
6980 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
6982 zone
= ISC_LIST_NEXT(zone
, link
))
6983 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
))
6986 case DNS_ZONESTATE_ANY
:
6987 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
6989 zone
= ISC_LIST_NEXT(zone
, link
)) {
6990 dns_view_t
*view
= zone
->view
;
6991 if (view
!= NULL
&& strcmp(view
->name
, "_bind") == 0)
7000 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
7006 dns_zone_checknames(dns_zone_t
*zone
, dns_name_t
*name
, dns_rdata_t
*rdata
) {
7007 isc_boolean_t ok
= ISC_TRUE
;
7008 isc_boolean_t fail
= ISC_FALSE
;
7009 char namebuf
[DNS_NAME_FORMATSIZE
];
7010 char namebuf2
[DNS_NAME_FORMATSIZE
];
7011 char typebuf
[DNS_RDATATYPE_FORMATSIZE
];
7012 int level
= ISC_LOG_WARNING
;
7015 REQUIRE(DNS_ZONE_VALID(zone
));
7017 if (!DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMES
))
7018 return (ISC_R_SUCCESS
);
7020 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
)) {
7021 level
= ISC_LOG_ERROR
;
7025 ok
= dns_rdata_checkowner(name
, rdata
->rdclass
, rdata
->type
, ISC_TRUE
);
7027 dns_name_format(name
, namebuf
, sizeof(namebuf
));
7028 dns_rdatatype_format(rdata
->type
, typebuf
, sizeof(typebuf
));
7029 dns_zone_log(zone
, level
, "%s/%s: %s", namebuf
, typebuf
,
7030 dns_result_totext(DNS_R_BADOWNERNAME
));
7032 return (DNS_R_BADOWNERNAME
);
7035 dns_name_init(&bad
, NULL
);
7036 ok
= dns_rdata_checknames(rdata
, name
, &bad
);
7038 dns_name_format(name
, namebuf
, sizeof(namebuf
));
7039 dns_name_format(&bad
, namebuf2
, sizeof(namebuf2
));
7040 dns_rdatatype_format(rdata
->type
, typebuf
, sizeof(typebuf
));
7041 dns_zone_log(zone
, level
, "%s/%s: %s: %s ", namebuf
, typebuf
,
7042 namebuf2
, dns_result_totext(DNS_R_BADNAME
));
7044 return (DNS_R_BADNAME
);
7047 return (ISC_R_SUCCESS
);