2 * Copyright (C) 2004 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.33 2004/06/04 02:41:39 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/request.h>
52 #include <dns/resolver.h>
53 #include <dns/result.h>
54 #include <dns/stats.h>
57 #include <dns/xfrin.h>
60 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
61 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
63 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
64 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
66 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
67 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
69 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
70 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
72 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
73 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
75 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
76 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
78 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
79 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
82 * Ensure 'a' is at least 'min' but not more than 'max'.
84 #define RANGE(a, min, max) \
85 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
90 #define DNS_DEFAULT_IDLEIN 3600 /* 1 hour */
91 #define DNS_DEFAULT_IDLEOUT 3600 /* 1 hour */
92 #define MAX_XFER_TIME (2*3600) /* Documented default is 2 hours */
94 #ifndef DNS_MAX_EXPIRE
95 #define DNS_MAX_EXPIRE 14515200 /* 24 weeks */
98 #ifndef DNS_DUMP_DELAY
99 #define DNS_DUMP_DELAY 900 /* 15 minutes */
102 typedef struct dns_notify dns_notify_t
;
103 typedef struct dns_stub dns_stub_t
;
104 typedef struct dns_load dns_load_t
;
105 typedef struct dns_forward dns_forward_t
;
106 typedef struct dns_io dns_io_t
;
107 typedef ISC_LIST(dns_io_t
) dns_iolist_t
;
109 #define DNS_ZONE_CHECKLOCK
110 #ifdef DNS_ZONE_CHECKLOCK
111 #define LOCK_ZONE(z) \
112 do { LOCK(&(z)->lock); \
113 INSIST((z)->locked == ISC_FALSE); \
114 (z)->locked = ISC_TRUE; \
116 #define UNLOCK_ZONE(z) \
117 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
118 #define LOCKED_ZONE(z) ((z)->locked)
120 #define LOCK_ZONE(z) LOCK(&(z)->lock)
121 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
122 #define LOCKED_ZONE(z) ISC_TRUE
129 #ifdef DNS_ZONE_CHECKLOCK
130 isc_boolean_t locked
;
133 isc_refcount_t erefs
;
138 ISC_LINK(dns_zone_t
) link
; /* Used by zmgr. */
144 isc_int32_t journalsize
;
145 dns_rdataclass_t rdclass
;
148 unsigned int options
;
149 unsigned int db_argc
;
151 isc_time_t expiretime
;
152 isc_time_t refreshtime
;
156 isc_uint32_t refresh
;
159 isc_uint32_t minimum
;
161 isc_uint32_t maxrefresh
;
162 isc_uint32_t minrefresh
;
163 isc_uint32_t maxretry
;
164 isc_uint32_t minretry
;
166 isc_sockaddr_t
*masters
;
167 dns_name_t
**masterkeynames
;
168 unsigned int masterscnt
;
169 unsigned int curmaster
;
170 unsigned int refreshcnt
;
171 isc_sockaddr_t masteraddr
;
172 dns_notifytype_t notifytype
;
173 isc_sockaddr_t
*notify
;
174 unsigned int notifycnt
;
175 isc_sockaddr_t notifyfrom
;
177 isc_sockaddr_t notifysrc4
;
178 isc_sockaddr_t notifysrc6
;
179 isc_sockaddr_t xfrsource4
;
180 isc_sockaddr_t xfrsource6
;
181 dns_xfrin_ctx_t
*xfr
; /* task locked */
182 /* Access Control Lists */
183 dns_acl_t
*update_acl
;
184 dns_acl_t
*forward_acl
;
185 dns_acl_t
*notify_acl
;
186 dns_acl_t
*query_acl
;
188 dns_severity_t check_names
;
189 ISC_LIST(dns_notify_t
) notifies
;
190 dns_request_t
*request
;
193 isc_uint32_t maxxfrin
;
194 isc_uint32_t maxxfrout
;
196 isc_uint32_t idleout
;
197 isc_boolean_t diff_on_reload
;
198 isc_event_t ctlevent
;
199 dns_ssutable_t
*ssutable
;
200 isc_uint32_t sigvalidityinterval
;
203 * Zones in certain states such as "waiting for zone transfer"
204 * or "zone transfer in progress" are kept on per-state linked lists
205 * in the zone manager using the 'statelink' field. The 'statelist'
206 * field points at the list the zone is currently on. It the zone
207 * is not on any such list, statelist is NULL.
209 ISC_LINK(dns_zone_t
) statelink
;
210 dns_zonelist_t
*statelist
;
212 * Optional per-zone statistics counters (NULL if not present).
214 isc_uint64_t
*counters
;
217 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
218 #define DNS_ZONE_SETFLAG(z,f) do { \
219 INSIST(LOCKED_ZONE(z)); \
222 #define DNS_ZONE_CLRFLAG(z,f) do { \
223 INSIST(LOCKED_ZONE(z)); \
224 (z)->flags &= ~(f); \
226 /* XXX MPA these may need to go back into zone.h */
227 #define DNS_ZONEFLG_REFRESH 0x00000001U /* refresh check in progress */
228 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /* zone need consolidation */
229 #define DNS_ZONEFLG_USEVC 0x00000004U /* use tcp for refresh query */
230 #define DNS_ZONEFLG_DUMPING 0x00000008U /* a dump is in progress */
231 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /* $INCLUDE in zone file */
232 #define DNS_ZONEFLG_LOADED 0x00000020U /* database has loaded */
233 #define DNS_ZONEFLG_EXITING 0x00000040U /* zone is being destroyed */
234 #define DNS_ZONEFLG_EXPIRED 0x00000080U /* zone has expired */
235 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /* refresh check needed */
236 #define DNS_ZONEFLG_UPTODATE 0x00000200U /* zone contents are
238 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /* need to send out notify
240 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /* generate a journal diff on
242 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /* an attempt to refresh a
243 * zone with no masters
245 #define DNS_ZONEFLG_LOADING 0x00002000U /* load from disk in progress*/
246 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /* timer values have been set
247 * from SOA (if not set, we
249 * default timer values) */
250 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /* Force a zone xfer */
251 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
252 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
253 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
254 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
255 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /* IXFR failed, force AXFR */
256 #define DNS_ZONEFLG_FLUSH 0x00200000U
258 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
260 /* Flags for zone_load() */
261 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
266 int refs
; /* Locked by rwlock */
267 isc_taskmgr_t
* taskmgr
;
268 isc_timermgr_t
* timermgr
;
269 isc_socketmgr_t
* socketmgr
;
270 isc_taskpool_t
* zonetasks
;
272 isc_ratelimiter_t
* rl
;
276 /* Locked by rwlock. */
277 dns_zonelist_t zones
;
278 dns_zonelist_t waiting_for_xfrin
;
279 dns_zonelist_t xfrin_in_progress
;
281 /* Configuration data. */
282 isc_uint32_t transfersin
;
283 isc_uint32_t transfersperns
;
284 unsigned int serialqueryrate
;
286 /* Locked by iolock */
287 isc_uint32_t iolimit
;
288 isc_uint32_t ioactive
;
302 dns_request_t
*request
;
305 unsigned int attempt
;
306 ISC_LINK(dns_notify_t
) link
;
309 #define DNS_NOTIFY_NOSOA 0x0001U
312 * dns_stub holds state while performing a 'stub' transfer.
313 * 'db' is the zone's 'db' or a new one if this is the initial
322 dns_dbversion_t
*version
;
334 dns_rdatacallbacks_t callbacks
;
338 * Hold forward state.
344 isc_buffer_t
*msgbuf
;
345 dns_request_t
*request
;
348 dns_updatecallback_t callback
;
353 * Hold IO request state.
360 ISC_LINK(dns_io_t
) link
;
364 static void zone_settimer(dns_zone_t
*, isc_time_t
*);
365 static void cancel_refresh(dns_zone_t
*);
366 static void zone_debuglog(dns_zone_t
*zone
, const char *, int debuglevel
,
367 const char *msg
, ...) ISC_FORMAT_PRINTF(4, 5);
368 static void notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...)
369 ISC_FORMAT_PRINTF(3, 4);
370 static void queue_xfrin(dns_zone_t
*zone
);
371 static void zone_unload(dns_zone_t
*zone
);
372 static void zone_expire(dns_zone_t
*zone
);
373 static void zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
);
374 static void zone_idetach(dns_zone_t
**zonep
);
375 static isc_result_t
zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
,
377 static isc_result_t
default_journal(dns_zone_t
*zone
);
378 static void zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
);
379 static isc_result_t
zone_postload(dns_zone_t
*zone
, dns_db_t
*db
,
380 isc_time_t loadtime
, isc_result_t result
);
381 static void zone_needdump(dns_zone_t
*zone
, unsigned int delay
);
382 static void zone_shutdown(isc_task_t
*, isc_event_t
*);
383 static void zone_loaddone(void *arg
, isc_result_t result
);
384 static isc_result_t
zone_startload(dns_db_t
*db
, dns_zone_t
*zone
,
385 isc_time_t loadtime
);
388 /* ondestroy example */
389 static void dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
);
392 static void refresh_callback(isc_task_t
*, isc_event_t
*);
393 static void stub_callback(isc_task_t
*, isc_event_t
*);
394 static void queue_soa_query(dns_zone_t
*zone
);
395 static void soa_query(isc_task_t
*, isc_event_t
*);
396 static void ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
,
398 static int message_count(dns_message_t
*msg
, dns_section_t section
,
399 dns_rdatatype_t type
);
400 static void notify_cancel(dns_zone_t
*zone
);
401 static void notify_find_address(dns_notify_t
*notify
);
402 static void notify_send(dns_notify_t
*notify
);
403 static isc_result_t
notify_createmessage(dns_zone_t
*zone
,
405 dns_message_t
**messagep
);
406 static void notify_done(isc_task_t
*task
, isc_event_t
*event
);
407 static void notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
);
408 static isc_result_t
zone_dump(dns_zone_t
*);
409 static void got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
);
410 static isc_result_t
zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
,
412 static void zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
);
413 static void zonemgr_free(dns_zonemgr_t
*zmgr
);
414 static isc_result_t
zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
415 isc_task_t
*task
, isc_taskaction_t action
,
416 void *arg
, dns_io_t
**iop
);
417 static void zonemgr_putio(dns_io_t
**iop
);
418 static void zonemgr_cancelio(dns_io_t
*io
);
421 zone_get_from_db(dns_db_t
*db
, dns_name_t
*origin
, unsigned int *nscount
,
422 unsigned int *soacount
, isc_uint32_t
*serial
,
423 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
424 isc_uint32_t
*expire
, isc_uint32_t
*minimum
);
426 static void zone_freedbargs(dns_zone_t
*zone
);
427 static void forward_callback(isc_task_t
*task
, isc_event_t
*event
);
428 static void zone_saveunique(dns_zone_t
*zone
, const char *path
,
429 const char *templat
);
430 static void zone_maintenance(dns_zone_t
*zone
);
431 static void zone_notify(dns_zone_t
*zone
);
433 #define ENTER zone_debuglog(zone, me, 1, "enter")
435 static const unsigned int dbargc_default
= 1;
436 static const char *dbargv_default
[] = { "rbt" };
439 *** Public functions.
443 dns_zone_create(dns_zone_t
**zonep
, isc_mem_t
*mctx
) {
447 REQUIRE(zonep
!= NULL
&& *zonep
== NULL
);
448 REQUIRE(mctx
!= NULL
);
450 zone
= isc_mem_get(mctx
, sizeof *zone
);
452 return (ISC_R_NOMEMORY
);
454 result
= isc_mutex_init(&zone
->lock
);
455 if (result
!= ISC_R_SUCCESS
) {
456 isc_mem_put(mctx
, zone
, sizeof *zone
);
457 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
458 "isc_mutex_init() failed: %s",
459 isc_result_totext(result
));
460 return (ISC_R_UNEXPECTED
);
463 /* XXX MPA check that all elements are initialised */
465 #ifdef DNS_ZONE_CHECKLOCK
466 zone
->locked
= ISC_FALSE
;
468 isc_mem_attach(mctx
, &zone
->mctx
);
471 ISC_LINK_INIT(zone
, link
);
472 isc_refcount_init(&zone
->erefs
, 1); /* Implicit attach. */
474 dns_name_init(&zone
->origin
, NULL
);
475 zone
->masterfile
= NULL
;
476 zone
->journalsize
= -1;
477 zone
->journal
= NULL
;
478 zone
->rdclass
= dns_rdataclass_none
;
479 zone
->type
= dns_zone_none
;
483 zone
->db_argv
= NULL
;
484 isc_time_settoepoch(&zone
->expiretime
);
485 isc_time_settoepoch(&zone
->refreshtime
);
486 isc_time_settoepoch(&zone
->dumptime
);
487 isc_time_settoepoch(&zone
->loadtime
);
489 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
490 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
493 zone
->maxrefresh
= DNS_ZONE_MAXREFRESH
;
494 zone
->minrefresh
= DNS_ZONE_MINREFRESH
;
495 zone
->maxretry
= DNS_ZONE_MAXRETRY
;
496 zone
->minretry
= DNS_ZONE_MINRETRY
;
497 zone
->masters
= NULL
;
498 zone
->masterkeynames
= NULL
;
499 zone
->masterscnt
= 0;
501 zone
->refreshcnt
= 0;
503 zone
->notifytype
= dns_notifytype_yes
;
506 zone
->update_acl
= NULL
;
507 zone
->forward_acl
= NULL
;
508 zone
->notify_acl
= NULL
;
509 zone
->query_acl
= NULL
;
510 zone
->xfr_acl
= NULL
;
511 zone
->check_names
= dns_severity_ignore
;
512 zone
->request
= NULL
;
516 zone
->idlein
= DNS_DEFAULT_IDLEIN
;
517 zone
->idleout
= DNS_DEFAULT_IDLEOUT
;
518 ISC_LIST_INIT(zone
->notifies
);
519 isc_sockaddr_any(&zone
->notifysrc4
);
520 isc_sockaddr_any6(&zone
->notifysrc6
);
521 isc_sockaddr_any(&zone
->xfrsource4
);
522 isc_sockaddr_any6(&zone
->xfrsource6
);
524 zone
->maxxfrin
= MAX_XFER_TIME
;
525 zone
->maxxfrout
= MAX_XFER_TIME
;
526 zone
->diff_on_reload
= ISC_FALSE
;
527 zone
->ssutable
= NULL
;
528 zone
->sigvalidityinterval
= 30 * 24 * 3600;
530 ISC_LINK_INIT(zone
, statelink
);
531 zone
->statelist
= NULL
;
532 zone
->counters
= NULL
;
534 zone
->magic
= ZONE_MAGIC
;
536 /* Must be after magic is set. */
537 result
= dns_zone_setdbtype(zone
, dbargc_default
, dbargv_default
);
538 if (result
!= ISC_R_SUCCESS
)
541 ISC_EVENT_INIT(&zone
->ctlevent
, sizeof(zone
->ctlevent
), 0, NULL
,
542 DNS_EVENT_ZONECONTROL
, zone_shutdown
, zone
, zone
,
545 return (ISC_R_SUCCESS
);
548 DESTROYLOCK(&zone
->lock
);
549 return (ISC_R_NOMEMORY
);
553 * Free a zone. Because we require that there be no more
554 * outstanding events or references, no locking is necessary.
557 zone_free(dns_zone_t
*zone
) {
558 isc_mem_t
*mctx
= NULL
;
560 REQUIRE(DNS_ZONE_VALID(zone
));
561 REQUIRE(isc_refcount_current(&zone
->erefs
) == 0);
562 REQUIRE(zone
->irefs
== 0);
563 REQUIRE(!LOCKED_ZONE(zone
));
564 REQUIRE(zone
->timer
== NULL
);
567 * Managed objects. Order is important.
569 if (zone
->request
!= NULL
)
570 dns_request_destroy(&zone
->request
); /* XXXMPA */
571 INSIST(zone
->readio
== NULL
);
572 INSIST(zone
->statelist
== NULL
);
574 if (zone
->task
!= NULL
)
575 isc_task_detach(&zone
->task
);
577 dns_zonemgr_releasezone(zone
->zmgr
, zone
);
579 /* Unmanaged objects */
580 if (zone
->masterfile
!= NULL
)
581 isc_mem_free(zone
->mctx
, zone
->masterfile
);
582 zone
->masterfile
= NULL
;
583 zone
->journalsize
= -1;
584 if (zone
->journal
!= NULL
)
585 isc_mem_free(zone
->mctx
, zone
->journal
);
586 zone
->journal
= NULL
;
587 if (zone
->counters
!= NULL
)
588 dns_stats_freecounters(zone
->mctx
, &zone
->counters
);
589 if (zone
->db
!= NULL
)
590 dns_db_detach(&zone
->db
);
591 zone_freedbargs(zone
);
592 dns_zone_setmasterswithkeys(zone
, NULL
, NULL
, 0);
593 dns_zone_setalsonotify(zone
, NULL
, 0);
594 zone
->check_names
= dns_severity_ignore
;
595 if (zone
->update_acl
!= NULL
)
596 dns_acl_detach(&zone
->update_acl
);
597 if (zone
->forward_acl
!= NULL
)
598 dns_acl_detach(&zone
->forward_acl
);
599 if (zone
->notify_acl
!= NULL
)
600 dns_acl_detach(&zone
->notify_acl
);
601 if (zone
->query_acl
!= NULL
)
602 dns_acl_detach(&zone
->query_acl
);
603 if (zone
->xfr_acl
!= NULL
)
604 dns_acl_detach(&zone
->xfr_acl
);
605 if (dns_name_dynamic(&zone
->origin
))
606 dns_name_free(&zone
->origin
, zone
->mctx
);
607 if (zone
->ssutable
!= NULL
)
608 dns_ssutable_detach(&zone
->ssutable
);
611 DESTROYLOCK(&zone
->lock
);
612 isc_refcount_destroy(&zone
->erefs
);
615 isc_mem_put(mctx
, zone
, sizeof *zone
);
616 isc_mem_detach(&mctx
);
623 dns_zone_setclass(dns_zone_t
*zone
, dns_rdataclass_t rdclass
) {
625 REQUIRE(DNS_ZONE_VALID(zone
));
626 REQUIRE(rdclass
!= dns_rdataclass_none
);
632 REQUIRE(zone
->rdclass
== dns_rdataclass_none
||
633 zone
->rdclass
== rdclass
);
634 zone
->rdclass
= rdclass
;
639 dns_zone_getclass(dns_zone_t
*zone
){
640 REQUIRE(DNS_ZONE_VALID(zone
));
642 return (zone
->rdclass
);
646 dns_zone_setnotifytype(dns_zone_t
*zone
, dns_notifytype_t notifytype
) {
647 REQUIRE(DNS_ZONE_VALID(zone
));
650 zone
->notifytype
= notifytype
;
658 dns_zone_settype(dns_zone_t
*zone
, dns_zonetype_t type
) {
660 REQUIRE(DNS_ZONE_VALID(zone
));
661 REQUIRE(type
!= dns_zone_none
);
667 REQUIRE(zone
->type
== dns_zone_none
|| zone
->type
== type
);
673 zone_freedbargs(dns_zone_t
*zone
) {
676 /* Free the old database argument list. */
677 if (zone
->db_argv
!= NULL
) {
678 for (i
= 0; i
< zone
->db_argc
; i
++)
679 isc_mem_free(zone
->mctx
, zone
->db_argv
[i
]);
680 isc_mem_put(zone
->mctx
, zone
->db_argv
,
681 zone
->db_argc
* sizeof *zone
->db_argv
);
684 zone
->db_argv
= NULL
;
688 dns_zone_setdbtype(dns_zone_t
*zone
,
689 unsigned int dbargc
, const char * const *dbargv
) {
690 isc_result_t result
= ISC_R_SUCCESS
;
694 REQUIRE(DNS_ZONE_VALID(zone
));
695 REQUIRE(dbargc
>= 1);
696 REQUIRE(dbargv
!= NULL
);
700 /* Set up a new database argument list. */
701 new = isc_mem_get(zone
->mctx
, dbargc
* sizeof *new);
704 for (i
= 0; i
< dbargc
; i
++)
706 for (i
= 0; i
< dbargc
; i
++) {
707 new[i
] = isc_mem_strdup(zone
->mctx
, dbargv
[i
]);
712 /* Free the old list. */
713 zone_freedbargs(zone
);
715 zone
->db_argc
= dbargc
;
717 result
= ISC_R_SUCCESS
;
722 for (i
= 0; i
< dbargc
; i
++) {
723 if (zone
->db_argv
[i
] != NULL
)
724 isc_mem_free(zone
->mctx
, new[i
]);
725 isc_mem_put(zone
->mctx
, new,
726 dbargc
* sizeof *new);
729 result
= ISC_R_NOMEMORY
;
737 dns_zone_setview(dns_zone_t
*zone
, dns_view_t
*view
) {
738 REQUIRE(DNS_ZONE_VALID(zone
));
741 if (zone
->view
!= NULL
)
742 dns_view_weakdetach(&zone
->view
);
743 dns_view_weakattach(view
, &zone
->view
);
749 dns_zone_getview(dns_zone_t
*zone
) {
750 REQUIRE(DNS_ZONE_VALID(zone
));
757 dns_zone_setorigin(dns_zone_t
*zone
, dns_name_t
*origin
) {
760 REQUIRE(DNS_ZONE_VALID(zone
));
761 REQUIRE(origin
!= NULL
);
764 if (dns_name_dynamic(&zone
->origin
)) {
765 dns_name_free(&zone
->origin
, zone
->mctx
);
766 dns_name_init(&zone
->origin
, NULL
);
768 result
= dns_name_dup(origin
, zone
->mctx
, &zone
->origin
);
775 dns_zone_setstring(dns_zone_t
*zone
, char **field
, const char *value
) {
779 copy
= isc_mem_strdup(zone
->mctx
, value
);
781 return (ISC_R_NOMEMORY
);
787 isc_mem_free(zone
->mctx
, *field
);
790 return (ISC_R_SUCCESS
);
794 dns_zone_setfile(dns_zone_t
*zone
, const char *file
) {
795 isc_result_t result
= ISC_R_SUCCESS
;
797 REQUIRE(DNS_ZONE_VALID(zone
));
800 result
= dns_zone_setstring(zone
, &zone
->masterfile
, file
);
801 if (result
== ISC_R_SUCCESS
)
802 result
= default_journal(zone
);
809 dns_zone_getfile(dns_zone_t
*zone
) {
810 REQUIRE(DNS_ZONE_VALID(zone
));
812 return (zone
->masterfile
);
816 default_journal(dns_zone_t
*zone
) {
820 REQUIRE(DNS_ZONE_VALID(zone
));
821 REQUIRE(LOCKED_ZONE(zone
));
823 if (zone
->masterfile
!= NULL
) {
824 /* Calculate string length including '\0'. */
825 int len
= strlen(zone
->masterfile
) + sizeof ".jnl";
826 journal
= isc_mem_allocate(zone
->mctx
, len
);
828 return (ISC_R_NOMEMORY
);
829 strcpy(journal
, zone
->masterfile
);
830 strcat(journal
, ".jnl");
834 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
836 isc_mem_free(zone
->mctx
, journal
);
841 dns_zone_setjournal(dns_zone_t
*zone
, const char *journal
) {
842 isc_result_t result
= ISC_R_SUCCESS
;
844 REQUIRE(DNS_ZONE_VALID(zone
));
847 result
= dns_zone_setstring(zone
, &zone
->journal
, journal
);
854 dns_zone_getjournal(dns_zone_t
*zone
) {
855 REQUIRE(DNS_ZONE_VALID(zone
));
857 return (zone
->journal
);
861 * Return true iff the zone is "dynamic", in the sense that the zone's
862 * master file (if any) is written by the server, rather than being
863 * updated manually and read by the server.
865 * This is true for slave zones, stub zones, and zones that allow
866 * dynamic updates either by having an update policy ("ssutable")
867 * or an "allow-update" ACL with a value other than exactly "{ none; }".
870 zone_isdynamic(dns_zone_t
*zone
) {
871 REQUIRE(DNS_ZONE_VALID(zone
));
873 return (ISC_TF(zone
->type
== dns_zone_slave
||
874 zone
->type
== dns_zone_stub
||
875 zone
->ssutable
!= NULL
||
876 (zone
->update_acl
!= NULL
&&
877 ! (zone
->update_acl
->length
== 1 &&
878 zone
->update_acl
->elements
[0].negative
== ISC_TRUE
880 zone
->update_acl
->elements
[0].type
==
881 dns_aclelementtype_any
))));
886 zone_load(dns_zone_t
*zone
, unsigned int flags
) {
889 isc_time_t loadtime
, filetime
;
892 REQUIRE(DNS_ZONE_VALID(zone
));
897 INSIST(zone
->type
!= dns_zone_none
);
899 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
900 result
= ISC_R_SUCCESS
;
904 if (zone
->db
!= NULL
&& zone
->masterfile
== NULL
) {
906 * The zone has no master file configured, but it already
907 * has a database. It could be the built-in
908 * version.bind. CH zone, a zone with a persistent
909 * database being reloaded, or maybe a zone that
910 * used to have a master file but whose configuration
911 * was changed so that it no longer has one. Do nothing.
913 result
= ISC_R_SUCCESS
;
917 if (zone
->db
!= NULL
&& zone_isdynamic(zone
)) {
919 * This is a slave, stub, or dynamically updated
920 * zone being reloaded. Do nothing - the database
921 * we already have is guaranteed to be up-to-date.
923 if (zone
->type
== dns_zone_master
)
924 result
= DNS_R_DYNAMIC
;
926 result
= ISC_R_SUCCESS
;
931 * Don't do the load if the file that stores the zone is older
932 * than the last time the zone was loaded. If the zone has not
933 * been loaded yet, zone->loadtime will be the epoch.
935 if (zone
->masterfile
!= NULL
&& ! isc_time_isepoch(&zone
->loadtime
)) {
937 * The file is already loaded. If we are just doing a
938 * "rndc reconfig", we are done.
940 if ((flags
& DNS_ZONELOADFLAG_NOSTAT
) != 0) {
941 result
= ISC_R_SUCCESS
;
944 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HASINCLUDE
)) {
945 result
= isc_file_getmodtime(zone
->masterfile
,
947 if (result
== ISC_R_SUCCESS
&&
948 isc_time_compare(&filetime
, &zone
->loadtime
) < 0) {
949 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
950 "skipping load: master file older "
952 result
= ISC_R_SUCCESS
;
958 INSIST(zone
->db_argc
>= 1);
960 if ((zone
->type
== dns_zone_slave
|| zone
->type
== dns_zone_stub
) &&
961 (strcmp(zone
->db_argv
[0], "rbt") == 0 ||
962 strcmp(zone
->db_argv
[0], "rbt64") == 0)) {
963 if (zone
->masterfile
== NULL
||
964 !isc_file_exists(zone
->masterfile
)) {
965 if (zone
->masterfile
!= NULL
)
966 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
968 zone
->refreshtime
= now
;
969 if (zone
->task
!= NULL
)
970 zone_settimer(zone
, &now
);
971 result
= ISC_R_SUCCESS
;
976 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "starting load");
979 * Store the current time before the zone is loaded, so that if the
980 * file changes between the time of the load and the time that
981 * zone->loadtime is set, then the file will still be reloaded
982 * the next time dns_zone_load is called.
984 result
= isc_time_now(&loadtime
);
985 if (result
!= ISC_R_SUCCESS
)
988 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
989 &zone
->origin
, (zone
->type
== dns_zone_stub
) ?
990 dns_dbtype_stub
: dns_dbtype_zone
,
992 zone
->db_argc
- 1, zone
->db_argv
+ 1,
995 if (result
!= ISC_R_SUCCESS
) {
996 dns_zone_log(zone
, ISC_LOG_ERROR
,
997 "loading zone: creating database: %s",
998 isc_result_totext(result
));
1001 dns_db_settask(db
, zone
->task
);
1003 if (! dns_db_ispersistent(db
)) {
1004 if (zone
->masterfile
!= NULL
) {
1005 result
= zone_startload(db
, zone
, loadtime
);
1007 result
= DNS_R_NOMASTERFILE
;
1008 if (zone
->type
== dns_zone_master
) {
1009 dns_zone_log(zone
, ISC_LOG_ERROR
,
1011 "no master file configured");
1014 dns_zone_log(zone
, ISC_LOG_INFO
, "loading zone: "
1015 "no master file configured: continuing");
1019 if (result
== DNS_R_CONTINUE
) {
1020 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADING
);
1021 result
= ISC_R_SUCCESS
;
1025 result
= zone_postload(zone
, db
, loadtime
, result
);
1035 dns_zone_load(dns_zone_t
*zone
) {
1036 return (zone_load(zone
, 0));
1040 dns_zone_loadnew(dns_zone_t
*zone
) {
1041 return (zone_load(zone
, DNS_ZONELOADFLAG_NOSTAT
));
1045 zone_gotreadhandle(isc_task_t
*task
, isc_event_t
*event
) {
1046 dns_load_t
*load
= event
->ev_arg
;
1047 isc_result_t result
= ISC_R_SUCCESS
;
1048 unsigned int options
;
1050 REQUIRE(DNS_LOAD_VALID(load
));
1052 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0)
1053 result
= ISC_R_CANCELED
;
1054 isc_event_free(&event
);
1055 if (result
== ISC_R_CANCELED
)
1058 options
= DNS_MASTER_ZONE
;
1059 if (load
->zone
->type
== dns_zone_slave
)
1060 options
|= DNS_MASTER_SLAVE
;
1061 result
= dns_master_loadfileinc(load
->zone
->masterfile
,
1062 dns_db_origin(load
->db
),
1063 dns_db_origin(load
->db
),
1064 load
->zone
->rdclass
,
1066 &load
->callbacks
, task
,
1067 zone_loaddone
, load
,
1068 &load
->zone
->lctx
, load
->zone
->mctx
);
1069 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_CONTINUE
&&
1070 result
!= DNS_R_SEENINCLUDE
)
1075 zone_loaddone(load
, result
);
1079 zone_startload(dns_db_t
*db
, dns_zone_t
*zone
, isc_time_t loadtime
) {
1081 isc_result_t result
;
1082 isc_result_t tresult
;
1083 unsigned int options
;
1085 options
= DNS_MASTER_ZONE
;
1086 if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MANYERRORS
))
1087 options
|= DNS_MASTER_MANYERRORS
;
1088 if (zone
->type
== dns_zone_slave
)
1089 options
|= DNS_MASTER_SLAVE
;
1090 if (zone
->zmgr
!= NULL
&& zone
->db
!= NULL
&& zone
->task
!= NULL
) {
1091 load
= isc_mem_get(zone
->mctx
, sizeof(*load
));
1093 return (ISC_R_NOMEMORY
);
1098 load
->loadtime
= loadtime
;
1099 load
->magic
= LOAD_MAGIC
;
1101 isc_mem_attach(zone
->mctx
, &load
->mctx
);
1102 zone_iattach(zone
, &load
->zone
);
1103 dns_db_attach(db
, &load
->db
);
1104 dns_rdatacallbacks_init(&load
->callbacks
);
1105 result
= dns_db_beginload(db
, &load
->callbacks
.add
,
1106 &load
->callbacks
.add_private
);
1107 if (result
!= ISC_R_SUCCESS
)
1109 result
= zonemgr_getio(zone
->zmgr
, ISC_TRUE
, zone
->task
,
1110 zone_gotreadhandle
, load
,
1112 if (result
!= ISC_R_SUCCESS
) {
1113 tresult
= dns_db_endload(load
->db
,
1114 &load
->callbacks
.add_private
);
1115 if (result
== ISC_R_SUCCESS
)
1119 result
= DNS_R_CONTINUE
;
1120 } else if (DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_MANYERRORS
)) {
1121 dns_rdatacallbacks_t callbacks
;
1123 dns_rdatacallbacks_init(&callbacks
);
1124 result
= dns_db_beginload(db
, &callbacks
.add
,
1125 &callbacks
.add_private
);
1126 if (result
!= ISC_R_SUCCESS
)
1128 result
= dns_master_loadfile(zone
->masterfile
, &zone
->origin
,
1129 &zone
->origin
, zone
->rdclass
,
1130 options
, &callbacks
, zone
->mctx
);
1131 tresult
= dns_db_endload(db
, &callbacks
.add_private
);
1132 if (result
== ISC_R_SUCCESS
)
1135 result
= dns_db_load(db
, zone
->masterfile
);
1142 dns_db_detach(&load
->db
);
1143 zone_idetach(&load
->zone
);
1144 isc_mem_detach(&load
->mctx
);
1145 isc_mem_put(zone
->mctx
, load
, sizeof(*load
));
1150 zone_postload(dns_zone_t
*zone
, dns_db_t
*db
, isc_time_t loadtime
,
1151 isc_result_t result
)
1153 unsigned int soacount
= 0;
1154 unsigned int nscount
= 0;
1155 isc_uint32_t serial
, refresh
, retry
, expire
, minimum
;
1157 isc_boolean_t needdump
= ISC_FALSE
;
1162 * Initiate zone transfer? We may need a error code that
1163 * indicates that the "permanent" form does not exist.
1164 * XXX better error feedback to log.
1166 if (result
!= ISC_R_SUCCESS
&& result
!= DNS_R_SEENINCLUDE
) {
1167 if (zone
->type
== dns_zone_slave
||
1168 zone
->type
== dns_zone_stub
) {
1169 if (result
== ISC_R_FILENOTFOUND
)
1170 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1172 else if (result
!= DNS_R_NOMASTERFILE
)
1173 dns_zone_log(zone
, ISC_LOG_ERROR
,
1174 "loading master file %s: %s",
1176 dns_result_totext(result
));
1178 dns_zone_log(zone
, ISC_LOG_ERROR
,
1179 "loading master file %s: %s",
1181 dns_result_totext(result
));
1185 dns_zone_log(zone
, ISC_LOG_DEBUG(2),
1186 "number of nodes in database: %u",
1187 dns_db_nodecount(db
));
1188 zone
->loadtime
= loadtime
;
1190 dns_zone_log(zone
, ISC_LOG_DEBUG(1), "loaded");
1192 if (result
== DNS_R_SEENINCLUDE
)
1193 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
1195 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HASINCLUDE
);
1197 * Apply update log, if any.
1199 if (zone
->journal
!= NULL
&&
1200 ! DNS_ZONE_OPTION(zone
, DNS_ZONEOPT_NOMERGE
)) {
1201 result
= dns_journal_rollforward(zone
->mctx
, db
,
1203 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
&&
1204 result
!= DNS_R_UPTODATE
&& result
!= DNS_R_NOJOURNAL
&&
1205 result
!= ISC_R_RANGE
) {
1206 dns_zone_log(zone
, ISC_LOG_ERROR
,
1207 "journal rollforward failed: %s",
1208 dns_result_totext(result
));
1211 if (result
== ISC_R_NOTFOUND
|| result
== ISC_R_RANGE
) {
1212 dns_zone_log(zone
, ISC_LOG_ERROR
,
1213 "journal rollforward failed: "
1214 "journal out of sync with zone");
1217 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1218 "journal rollforward completed "
1220 dns_result_totext(result
));
1221 if (result
== ISC_R_SUCCESS
)
1222 needdump
= ISC_TRUE
;
1226 * Obtain ns and soa counts for top of zone.
1231 result
= zone_get_from_db(db
, &zone
->origin
, &nscount
,
1232 &soacount
, &serial
, &refresh
, &retry
,
1234 if (result
!= ISC_R_SUCCESS
) {
1235 dns_zone_log(zone
, ISC_LOG_ERROR
,
1236 "could not find NS and/or SOA records");
1240 * Master / Slave / Stub zones require both NS and SOA records at
1241 * the top of the zone.
1244 switch (zone
->type
) {
1245 case dns_zone_master
:
1246 case dns_zone_slave
:
1248 if (soacount
!= 1) {
1249 dns_zone_log(zone
, ISC_LOG_ERROR
,
1250 "has %d SOA records", soacount
);
1251 result
= DNS_R_BADZONE
;
1254 dns_zone_log(zone
, ISC_LOG_ERROR
,
1255 "has no NS records");
1256 result
= DNS_R_BADZONE
;
1258 if (result
!= ISC_R_SUCCESS
)
1260 if (zone
->db
!= NULL
) {
1261 if (!isc_serial_ge(serial
, zone
->serial
)) {
1262 dns_zone_log(zone
, ISC_LOG_ERROR
,
1263 "zone serial has gone backwards");
1266 zone
->serial
= serial
;
1267 zone
->refresh
= RANGE(refresh
,
1268 zone
->minrefresh
, zone
->maxrefresh
);
1269 zone
->retry
= RANGE(retry
,
1270 zone
->minretry
, zone
->maxretry
);
1271 zone
->expire
= RANGE(expire
, zone
->refresh
+ zone
->retry
,
1273 zone
->minimum
= minimum
;
1274 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
1276 if (zone
->type
== dns_zone_slave
||
1277 zone
->type
== dns_zone_stub
) {
1282 result
= isc_file_getmodtime(zone
->journal
, &t
);
1283 if (result
!= ISC_R_SUCCESS
)
1284 result
= isc_file_getmodtime(zone
->masterfile
,
1287 if (result
== ISC_R_SUCCESS
) {
1288 isc_interval_set(&i
, zone
->expire
, 0);
1289 isc_time_add(&t
, &i
, &zone
->expiretime
);
1291 isc_interval_set(&i
, zone
->retry
, 0);
1292 isc_time_add(&now
, &i
, &zone
->expiretime
);
1294 delay
= isc_random_jitter(zone
->retry
,
1295 (zone
->retry
* 3) / 4);
1296 isc_interval_set(&i
, delay
, 0);
1297 isc_time_add(&now
, &i
, &zone
->refreshtime
);
1298 if (isc_time_compare(&zone
->refreshtime
,
1299 &zone
->expiretime
) >= 0)
1300 zone
->refreshtime
= now
;
1304 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
1305 "unexpected zone type %d", zone
->type
);
1306 result
= ISC_R_UNEXPECTED
;
1312 /* destroy notification example. */
1314 isc_event_t
*e
= isc_event_allocate(zone
->mctx
, NULL
,
1315 DNS_EVENT_DBDESTROYED
,
1316 dns_zonemgr_dbdestroyed
,
1318 sizeof(isc_event_t
));
1319 dns_db_ondestroy(db
, zone
->task
, &e
);
1323 if (zone
->db
!= NULL
) {
1324 result
= zone_replacedb(zone
, db
, ISC_FALSE
);
1325 if (result
!= ISC_R_SUCCESS
)
1328 dns_db_attach(db
, &zone
->db
);
1329 DNS_ZONE_SETFLAG(zone
,
1330 DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
1332 result
= ISC_R_SUCCESS
;
1334 zone_needdump(zone
, DNS_DUMP_DELAY
);
1335 if (zone
->task
!= NULL
)
1336 zone_settimer(zone
, &now
);
1337 dns_zone_log(zone
, ISC_LOG_INFO
, "loaded serial %u", zone
->serial
);
1341 if (zone
->type
== dns_zone_slave
||
1342 zone
->type
== dns_zone_stub
) {
1343 if (zone
->journal
!= NULL
)
1344 zone_saveunique(zone
, zone
->journal
, "jn-XXXXXXXX");
1345 if (zone
->masterfile
!= NULL
)
1346 zone_saveunique(zone
, zone
->masterfile
, "db-XXXXXXXX");
1348 /* Mark the zone for immediate refresh. */
1349 zone
->refreshtime
= now
;
1350 if (zone
->task
!= NULL
)
1351 zone_settimer(zone
, &now
);
1352 result
= ISC_R_SUCCESS
;
1357 static isc_boolean_t
1358 exit_check(dns_zone_t
*zone
) {
1360 REQUIRE(LOCKED_ZONE(zone
));
1362 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_SHUTDOWN
) &&
1366 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
1368 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
1375 zone_count_ns_rr(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
1376 unsigned int *nscount
)
1378 isc_result_t result
;
1380 dns_rdataset_t rdataset
;
1382 REQUIRE(nscount
!= NULL
);
1384 dns_rdataset_init(&rdataset
);
1385 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_ns
,
1386 dns_rdatatype_none
, 0, &rdataset
, NULL
);
1387 if (result
== ISC_R_NOTFOUND
) {
1389 result
= ISC_R_SUCCESS
;
1390 goto invalidate_rdataset
;
1392 else if (result
!= ISC_R_SUCCESS
)
1393 goto invalidate_rdataset
;
1396 result
= dns_rdataset_first(&rdataset
);
1397 while (result
== ISC_R_SUCCESS
) {
1399 result
= dns_rdataset_next(&rdataset
);
1401 dns_rdataset_disassociate(&rdataset
);
1404 result
= ISC_R_SUCCESS
;
1406 invalidate_rdataset
:
1407 dns_rdataset_invalidate(&rdataset
);
1413 zone_load_soa_rr(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
1414 unsigned int *soacount
,
1415 isc_uint32_t
*serial
, isc_uint32_t
*refresh
,
1416 isc_uint32_t
*retry
, isc_uint32_t
*expire
,
1417 isc_uint32_t
*minimum
)
1419 isc_result_t result
;
1421 dns_rdataset_t rdataset
;
1422 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1423 dns_rdata_soa_t soa
;
1425 dns_rdataset_init(&rdataset
);
1426 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_soa
,
1427 dns_rdatatype_none
, 0, &rdataset
, NULL
);
1428 if (result
!= ISC_R_SUCCESS
)
1429 goto invalidate_rdataset
;
1432 result
= dns_rdataset_first(&rdataset
);
1433 while (result
== ISC_R_SUCCESS
) {
1434 dns_rdata_init(&rdata
);
1435 dns_rdataset_current(&rdataset
, &rdata
);
1438 dns_rdata_tostruct(&rdata
, &soa
, NULL
);
1440 result
= dns_rdataset_next(&rdataset
);
1441 dns_rdata_reset(&rdata
);
1443 dns_rdataset_disassociate(&rdataset
);
1445 if (soacount
!= NULL
)
1450 *serial
= soa
.serial
;
1451 if (refresh
!= NULL
)
1452 *refresh
= soa
.refresh
;
1456 *expire
= soa
.expire
;
1457 if (minimum
!= NULL
)
1458 *minimum
= soa
.minimum
;
1461 result
= ISC_R_SUCCESS
;
1463 invalidate_rdataset
:
1464 dns_rdataset_invalidate(&rdataset
);
1470 * zone must be locked.
1473 zone_get_from_db(dns_db_t
*db
, dns_name_t
*origin
, unsigned int *nscount
,
1474 unsigned int *soacount
, isc_uint32_t
*serial
,
1475 isc_uint32_t
*refresh
, isc_uint32_t
*retry
,
1476 isc_uint32_t
*expire
, isc_uint32_t
*minimum
)
1478 dns_dbversion_t
*version
;
1479 isc_result_t result
;
1480 isc_result_t answer
= ISC_R_SUCCESS
;
1483 REQUIRE(db
!= NULL
);
1484 REQUIRE(origin
!= NULL
);
1487 dns_db_currentversion(db
, &version
);
1490 result
= dns_db_findnode(db
, origin
, ISC_FALSE
, &node
);
1491 if (result
!= ISC_R_SUCCESS
) {
1496 if (nscount
!= NULL
) {
1497 result
= zone_count_ns_rr(db
, node
, version
, nscount
);
1498 if (result
!= ISC_R_SUCCESS
)
1502 if (soacount
!= NULL
|| serial
!= NULL
|| refresh
!= NULL
1503 || retry
!= NULL
|| expire
!= NULL
|| minimum
!= NULL
) {
1504 result
= zone_load_soa_rr(db
, node
, version
, soacount
,
1505 serial
, refresh
, retry
, expire
,
1507 if (result
!= ISC_R_SUCCESS
)
1511 dns_db_detachnode(db
, &node
);
1513 dns_db_closeversion(db
, &version
, ISC_FALSE
);
1519 dns_zone_attach(dns_zone_t
*source
, dns_zone_t
**target
) {
1520 REQUIRE(DNS_ZONE_VALID(source
));
1521 REQUIRE(target
!= NULL
&& *target
== NULL
);
1522 isc_refcount_increment(&source
->erefs
, NULL
);
1527 dns_zone_detach(dns_zone_t
**zonep
) {
1530 isc_boolean_t free_now
= ISC_FALSE
;
1532 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
1536 isc_refcount_decrement(&zone
->erefs
, &refs
);
1541 * We just detached the last external reference.
1543 if (zone
->task
!= NULL
) {
1545 * This zone is being managed. Post
1546 * its control event and let it clean
1547 * up synchronously in the context of
1550 isc_event_t
*ev
= &zone
->ctlevent
;
1551 isc_task_send(zone
->task
, &ev
);
1554 * This zone is not being managed; it has
1555 * no task and can have no outstanding
1556 * events. Free it immediately.
1559 * Unmanaged zones should not have non-null views;
1560 * we have no way of detaching from the view here
1561 * without causing deadlock because this code is called
1562 * with the view already locked.
1564 INSIST(zone
->view
== NULL
);
1565 free_now
= ISC_TRUE
;
1575 dns_zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
1576 REQUIRE(DNS_ZONE_VALID(source
));
1577 REQUIRE(target
!= NULL
&& *target
== NULL
);
1579 zone_iattach(source
, target
);
1580 UNLOCK_ZONE(source
);
1584 zone_iattach(dns_zone_t
*source
, dns_zone_t
**target
) {
1587 * 'source' locked by caller.
1589 REQUIRE(LOCKED_ZONE(source
));
1590 REQUIRE(DNS_ZONE_VALID(source
));
1591 REQUIRE(target
!= NULL
&& *target
== NULL
);
1592 INSIST(source
->irefs
+ isc_refcount_current(&source
->erefs
) > 0);
1594 INSIST(source
->irefs
!= 0);
1599 zone_idetach(dns_zone_t
**zonep
) {
1603 * 'zone' locked by caller.
1605 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
1607 REQUIRE(LOCKED_ZONE(*zonep
));
1610 INSIST(zone
->irefs
> 0);
1612 INSIST(zone
->irefs
+ isc_refcount_current(&zone
->erefs
) > 0);
1616 dns_zone_idetach(dns_zone_t
**zonep
) {
1618 isc_boolean_t free_needed
;
1620 REQUIRE(zonep
!= NULL
&& DNS_ZONE_VALID(*zonep
));
1625 INSIST(zone
->irefs
> 0);
1627 free_needed
= exit_check(zone
);
1634 dns_zone_getmctx(dns_zone_t
*zone
) {
1635 REQUIRE(DNS_ZONE_VALID(zone
));
1637 return (zone
->mctx
);
1641 dns_zone_getmgr(dns_zone_t
*zone
) {
1642 REQUIRE(DNS_ZONE_VALID(zone
));
1644 return (zone
->zmgr
);
1648 dns_zone_setflag(dns_zone_t
*zone
, unsigned int flags
, isc_boolean_t value
) {
1649 REQUIRE(DNS_ZONE_VALID(zone
));
1653 DNS_ZONE_SETFLAG(zone
, flags
);
1655 DNS_ZONE_CLRFLAG(zone
, flags
);
1660 dns_zone_setoption(dns_zone_t
*zone
, unsigned int option
, isc_boolean_t value
)
1662 REQUIRE(DNS_ZONE_VALID(zone
));
1666 zone
->options
|= option
;
1668 zone
->options
&= ~option
;
1673 dns_zone_getoptions(dns_zone_t
*zone
) {
1675 REQUIRE(DNS_ZONE_VALID(zone
));
1677 return (zone
->options
);
1681 dns_zone_setxfrsource4(dns_zone_t
*zone
, isc_sockaddr_t
*xfrsource
) {
1682 REQUIRE(DNS_ZONE_VALID(zone
));
1685 zone
->xfrsource4
= *xfrsource
;
1688 return (ISC_R_SUCCESS
);
1692 dns_zone_getxfrsource4(dns_zone_t
*zone
) {
1693 REQUIRE(DNS_ZONE_VALID(zone
));
1694 return (&zone
->xfrsource4
);
1698 dns_zone_setxfrsource6(dns_zone_t
*zone
, isc_sockaddr_t
*xfrsource
) {
1699 REQUIRE(DNS_ZONE_VALID(zone
));
1702 zone
->xfrsource6
= *xfrsource
;
1705 return (ISC_R_SUCCESS
);
1709 dns_zone_getxfrsource6(dns_zone_t
*zone
) {
1710 REQUIRE(DNS_ZONE_VALID(zone
));
1711 return (&zone
->xfrsource6
);
1715 dns_zone_setnotifysrc4(dns_zone_t
*zone
, isc_sockaddr_t
*notifysrc
) {
1716 REQUIRE(DNS_ZONE_VALID(zone
));
1719 zone
->notifysrc4
= *notifysrc
;
1722 return (ISC_R_SUCCESS
);
1726 dns_zone_getnotifysrc4(dns_zone_t
*zone
) {
1727 REQUIRE(DNS_ZONE_VALID(zone
));
1728 return (&zone
->notifysrc4
);
1732 dns_zone_setnotifysrc6(dns_zone_t
*zone
, isc_sockaddr_t
*notifysrc
) {
1733 REQUIRE(DNS_ZONE_VALID(zone
));
1736 zone
->notifysrc6
= *notifysrc
;
1739 return (ISC_R_SUCCESS
);
1743 dns_zone_getnotifysrc6(dns_zone_t
*zone
) {
1744 REQUIRE(DNS_ZONE_VALID(zone
));
1745 return (&zone
->notifysrc6
);
1749 dns_zone_setalsonotify(dns_zone_t
*zone
, isc_sockaddr_t
*notify
,
1752 isc_sockaddr_t
*new;
1754 REQUIRE(DNS_ZONE_VALID(zone
));
1755 REQUIRE(count
== 0 || notify
!= NULL
);
1758 if (zone
->notify
!= NULL
) {
1759 isc_mem_put(zone
->mctx
, zone
->notify
,
1760 zone
->notifycnt
* sizeof *new);
1761 zone
->notify
= NULL
;
1762 zone
->notifycnt
= 0;
1765 new = isc_mem_get(zone
->mctx
, count
* sizeof *new);
1768 return (ISC_R_NOMEMORY
);
1770 memcpy(new, notify
, count
* sizeof *new);
1772 zone
->notifycnt
= count
;
1775 return (ISC_R_SUCCESS
);
1779 dns_zone_setmasters(dns_zone_t
*zone
, isc_sockaddr_t
*masters
,
1782 isc_result_t result
;
1784 result
= dns_zone_setmasterswithkeys(zone
, masters
, NULL
, count
);
1789 dns_zone_setmasterswithkeys(dns_zone_t
*zone
, isc_sockaddr_t
*masters
,
1790 dns_name_t
**keynames
, isc_uint32_t count
)
1792 isc_sockaddr_t
*new;
1793 isc_result_t result
= ISC_R_SUCCESS
;
1794 dns_name_t
**newname
;
1797 REQUIRE(DNS_ZONE_VALID(zone
));
1798 REQUIRE(count
== 0 || masters
!= NULL
);
1799 if (keynames
!= NULL
) {
1800 REQUIRE(count
!= 0);
1804 if (zone
->masters
!= NULL
) {
1805 isc_mem_put(zone
->mctx
, zone
->masters
,
1806 zone
->masterscnt
* sizeof *new);
1807 zone
->masters
= NULL
;
1809 if (zone
->masterkeynames
!= NULL
) {
1810 for (i
= 0; i
< zone
->masterscnt
; i
++) {
1811 if (zone
->masterkeynames
[i
] != NULL
) {
1812 dns_name_free(zone
->masterkeynames
[i
],
1814 isc_mem_put(zone
->mctx
,
1815 zone
->masterkeynames
[i
],
1816 sizeof(dns_name_t
));
1817 zone
->masterkeynames
[i
] = NULL
;
1820 isc_mem_put(zone
->mctx
, zone
->masterkeynames
,
1821 zone
->masterscnt
* sizeof(dns_name_t
*));
1822 zone
->masterkeynames
= NULL
;
1824 zone
->masterscnt
= 0;
1826 * If count == 0, don't allocate any space for masters or keynames
1827 * so internally, those pointers are NULL if count == 0
1833 * masters must countain count elements!
1835 new = isc_mem_get(zone
->mctx
,
1836 count
* sizeof(isc_sockaddr_t
));
1838 result
= ISC_R_NOMEMORY
;
1841 memcpy(new, masters
, count
* sizeof *new);
1842 zone
->masters
= new;
1843 zone
->masterscnt
= count
;
1844 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
1847 * if keynames is non-NULL, it must contain count elements!
1849 if (keynames
!= NULL
) {
1850 newname
= isc_mem_get(zone
->mctx
,
1851 count
* sizeof(dns_name_t
*));
1852 if (newname
== NULL
) {
1853 result
= ISC_R_NOMEMORY
;
1854 isc_mem_put(zone
->mctx
, zone
->masters
,
1855 count
* sizeof *new);
1858 for (i
= 0; i
< count
; i
++)
1860 for (i
= 0; i
< count
; i
++) {
1861 if (keynames
[i
] != NULL
) {
1862 newname
[i
] = isc_mem_get(zone
->mctx
,
1863 sizeof(dns_name_t
));
1864 if (newname
[i
] == NULL
)
1866 dns_name_init(newname
[i
], NULL
);
1867 result
= dns_name_dup(keynames
[i
], zone
->mctx
,
1869 if (result
!= ISC_R_SUCCESS
) {
1871 for (i
= 0; i
< count
; i
++)
1872 if (newname
[i
] != NULL
)
1876 isc_mem_put(zone
->mctx
, zone
->masters
,
1877 count
* sizeof *new);
1878 isc_mem_put(zone
->mctx
, newname
,
1879 count
* sizeof *newname
);
1884 zone
->masterkeynames
= newname
;
1892 dns_zone_getdb(dns_zone_t
*zone
, dns_db_t
**dpb
) {
1893 isc_result_t result
= ISC_R_SUCCESS
;
1895 REQUIRE(DNS_ZONE_VALID(zone
));
1898 if (zone
->db
== NULL
)
1899 result
= DNS_R_NOTLOADED
;
1901 dns_db_attach(zone
->db
, dpb
);
1908 * Co-ordinates the starting of routine jobs.
1912 dns_zone_maintenance(dns_zone_t
*zone
) {
1913 const char me
[] = "dns_zone_maintenance";
1916 REQUIRE(DNS_ZONE_VALID(zone
));
1921 zone_settimer(zone
, &now
);
1925 static inline isc_boolean_t
1926 was_dumping(dns_zone_t
*zone
) {
1927 isc_boolean_t dumping
;
1929 REQUIRE(LOCKED_ZONE(zone
));
1931 dumping
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
);
1932 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
1934 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
1935 isc_time_settoepoch(&zone
->dumptime
);
1941 zone_maintenance(dns_zone_t
*zone
) {
1942 const char me
[] = "zone_maintenance";
1944 isc_result_t result
;
1945 isc_boolean_t dumping
;
1947 REQUIRE(DNS_ZONE_VALID(zone
));
1951 * Configuring the view of this zone may have
1952 * failed, for example because the config file
1953 * had a syntax error. In that case, the view
1954 * adb or resolver, and we had better not try
1955 * to do maintenance on it.
1957 if (zone
->view
== NULL
|| zone
->view
->adb
== NULL
)
1965 switch (zone
->type
) {
1966 case dns_zone_slave
:
1969 if (isc_time_compare(&now
, &zone
->expiretime
) >= 0 &&
1970 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
1972 zone
->refreshtime
= now
;
1983 switch (zone
->type
) {
1984 case dns_zone_slave
:
1986 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
) &&
1987 isc_time_compare(&now
, &zone
->refreshtime
) >= 0)
1988 dns_zone_refresh(zone
);
1995 * Do we need to consolidate the backing store?
1997 switch (zone
->type
) {
1998 case dns_zone_master
:
1999 case dns_zone_slave
:
2001 if (zone
->masterfile
!= NULL
&&
2002 isc_time_compare(&now
, &zone
->dumptime
) >= 0 &&
2003 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
2004 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
)) {
2005 dumping
= was_dumping(zone
);
2010 result
= zone_dump(zone
);
2011 if (result
!= ISC_R_SUCCESS
)
2012 dns_zone_log(zone
, ISC_LOG_WARNING
,
2014 dns_result_totext(result
));
2022 * Do we need to send out notify messages?
2024 switch (zone
->type
) {
2025 case dns_zone_master
:
2026 case dns_zone_slave
:
2027 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
2033 zone_settimer(zone
, &now
);
2037 dns_zone_markdirty(dns_zone_t
*zone
) {
2040 zone_needdump(zone
, DNS_DUMP_DELAY
);
2045 dns_zone_expire(dns_zone_t
*zone
) {
2046 REQUIRE(DNS_ZONE_VALID(zone
));
2054 zone_expire(dns_zone_t
*zone
) {
2056 * 'zone' locked by caller.
2059 REQUIRE(LOCKED_ZONE(zone
));
2061 dns_zone_log(zone
, ISC_LOG_WARNING
, "expired");
2063 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXPIRED
);
2064 zone
->refresh
= DNS_ZONE_DEFAULTREFRESH
;
2065 zone
->retry
= DNS_ZONE_DEFAULTRETRY
;
2066 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
2067 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
2072 dns_zone_refresh(dns_zone_t
*zone
) {
2074 isc_uint32_t oldflags
;
2076 REQUIRE(DNS_ZONE_VALID(zone
));
2078 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
2082 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
2083 * in progress at a time.
2087 oldflags
= zone
->flags
;
2088 if (zone
->masterscnt
== 0) {
2089 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOMASTERS
);
2090 if ((oldflags
& DNS_ZONEFLG_NOMASTERS
) == 0)
2091 dns_zone_log(zone
, ISC_LOG_ERROR
,
2092 "cannot refresh: no masters");
2095 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
2096 if ((oldflags
& (DNS_ZONEFLG_REFRESH
|DNS_ZONEFLG_LOADING
)) != 0)
2100 * Set the next refresh time as if refresh check has failed.
2101 * Setting this to the retry time will do that. XXXMLG
2102 * If we are successful it will be reset using zone->refresh.
2104 isc_interval_set(&i
, isc_random_jitter(zone
->retry
, zone
->retry
/ 4),
2106 isc_time_nowplusinterval(&zone
->refreshtime
, &i
);
2109 * When lacking user-specified timer values from the SOA,
2110 * do exponential backoff of the retry time up to a
2111 * maximum of six hours.
2113 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_HAVETIMERS
))
2114 zone
->retry
= ISC_MIN(zone
->retry
* 2, 6 * 3600);
2116 zone
->curmaster
= 0;
2117 zone
->refreshcnt
= 0;
2118 /* initiate soa query */
2119 queue_soa_query(zone
);
2125 dns_zone_flush(dns_zone_t
*zone
) {
2126 isc_result_t result
= ISC_R_ALREADYRUNNING
;
2127 isc_boolean_t dumping
;
2129 REQUIRE(DNS_ZONE_VALID(zone
));
2132 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FLUSH
);
2133 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
2134 zone
->masterfile
!= NULL
)
2135 dumping
= was_dumping(zone
);
2140 result
= zone_dump(zone
);
2145 dns_zone_dump(dns_zone_t
*zone
) {
2146 isc_result_t result
= ISC_R_ALREADYRUNNING
;
2147 isc_boolean_t dumping
;
2149 REQUIRE(DNS_ZONE_VALID(zone
));
2152 dumping
= was_dumping(zone
);
2155 result
= zone_dump(zone
);
2160 zone_needdump(dns_zone_t
*zone
, unsigned int delay
) {
2161 isc_time_t dumptime
;
2166 * 'zone' locked by caller
2169 REQUIRE(DNS_ZONE_VALID(zone
));
2170 REQUIRE(LOCKED_ZONE(zone
));
2173 * Do we have a place to dump to and are we loaded?
2175 if (zone
->masterfile
== NULL
||
2176 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) == 0)
2179 isc_interval_set(&i
, delay
, 0);
2181 isc_time_add(&now
, &i
, &dumptime
);
2183 /* add some noise */
2184 delay
= isc_random_jitter(delay
, delay
/4);
2186 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
2187 if (isc_time_isepoch(&zone
->dumptime
) ||
2188 isc_time_compare(&zone
->dumptime
, &dumptime
) > 0)
2189 zone
->dumptime
= dumptime
;
2190 if (zone
->task
!= NULL
)
2191 zone_settimer(zone
, &now
);
2195 zone_dump(dns_zone_t
*zone
) {
2196 isc_result_t result
;
2197 dns_dbversion_t
*version
= NULL
;
2198 isc_boolean_t again
;
2199 dns_db_t
*db
= NULL
;
2200 char *masterfile
= NULL
;
2202 REQUIRE(DNS_ZONE_VALID(zone
));
2206 if (zone
->db
!= NULL
)
2207 dns_db_attach(zone
->db
, &db
);
2208 if (zone
->masterfile
!= NULL
)
2209 masterfile
= isc_mem_strdup(zone
->mctx
, zone
->masterfile
);
2212 result
= DNS_R_NOTLOADED
;
2215 if (masterfile
== NULL
) {
2216 result
= DNS_R_NOMASTERFILE
;
2219 dns_db_currentversion(db
, &version
);
2221 result
= dns_master_dump(zone
->mctx
, db
, version
,
2222 &dns_master_style_default
, masterfile
);
2224 dns_db_closeversion(db
, &version
, ISC_FALSE
);
2228 if (masterfile
!= NULL
)
2229 isc_mem_free(zone
->mctx
, masterfile
);
2234 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DUMPING
);
2235 if (result
!= ISC_R_SUCCESS
) {
2237 * Try again in a short while.
2239 zone_needdump(zone
, DNS_DUMP_DELAY
);
2240 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FLUSH
) &&
2241 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
2242 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
2243 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDDUMP
);
2244 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DUMPING
);
2245 isc_time_settoepoch(&zone
->dumptime
);
2256 dns_zone_dumptostream(dns_zone_t
*zone
, FILE *fd
) {
2257 isc_result_t result
;
2258 dns_dbversion_t
*version
= NULL
;
2259 dns_db_t
*db
= NULL
;
2261 REQUIRE(DNS_ZONE_VALID(zone
));
2264 if (zone
->db
!= NULL
)
2265 dns_db_attach(zone
->db
, &db
);
2268 return (DNS_R_NOTLOADED
);
2270 dns_db_currentversion(db
, &version
);
2271 result
= dns_master_dumptostream(zone
->mctx
, db
, version
,
2272 &dns_master_style_default
, fd
);
2273 dns_db_closeversion(db
, &version
, ISC_FALSE
);
2279 dns_zone_unload(dns_zone_t
*zone
) {
2280 REQUIRE(DNS_ZONE_VALID(zone
));
2288 notify_cancel(dns_zone_t
*zone
) {
2289 dns_notify_t
*notify
;
2292 * 'zone' locked by caller.
2295 REQUIRE(LOCKED_ZONE(zone
));
2297 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
2299 notify
= ISC_LIST_NEXT(notify
, link
)) {
2300 if (notify
->find
!= NULL
)
2301 dns_adb_cancelfind(notify
->find
);
2302 if (notify
->request
!= NULL
)
2303 dns_request_cancel(notify
->request
);
2308 zone_unload(dns_zone_t
*zone
) {
2311 * 'zone' locked by caller.
2314 REQUIRE(LOCKED_ZONE(zone
));
2316 dns_db_detach(&zone
->db
);
2317 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_LOADED
);
2321 dns_zone_setminrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
2322 REQUIRE(DNS_ZONE_VALID(zone
));
2325 zone
->minrefresh
= val
;
2329 dns_zone_setmaxrefreshtime(dns_zone_t
*zone
, isc_uint32_t val
) {
2330 REQUIRE(DNS_ZONE_VALID(zone
));
2333 zone
->maxrefresh
= val
;
2337 dns_zone_setminretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
2338 REQUIRE(DNS_ZONE_VALID(zone
));
2341 zone
->minretry
= val
;
2345 dns_zone_setmaxretrytime(dns_zone_t
*zone
, isc_uint32_t val
) {
2346 REQUIRE(DNS_ZONE_VALID(zone
));
2349 zone
->maxretry
= val
;
2352 static isc_boolean_t
2353 notify_isqueued(dns_zone_t
*zone
, dns_name_t
*name
, isc_sockaddr_t
*addr
) {
2354 dns_notify_t
*notify
;
2356 for (notify
= ISC_LIST_HEAD(zone
->notifies
);
2358 notify
= ISC_LIST_NEXT(notify
, link
)) {
2359 if (notify
->request
!= NULL
)
2361 if (name
!= NULL
&& dns_name_dynamic(¬ify
->ns
) &&
2362 dns_name_equal(name
, ¬ify
->ns
))
2364 if (addr
!= NULL
&& isc_sockaddr_equal(addr
, ¬ify
->dst
))
2371 notify_destroy(dns_notify_t
*notify
, isc_boolean_t locked
) {
2375 * Caller holds zone lock.
2377 REQUIRE(DNS_NOTIFY_VALID(notify
));
2379 if (notify
->zone
!= NULL
) {
2381 LOCK_ZONE(notify
->zone
);
2382 REQUIRE(LOCKED_ZONE(notify
->zone
));
2383 if (ISC_LINK_LINKED(notify
, link
))
2384 ISC_LIST_UNLINK(notify
->zone
->notifies
, notify
, link
);
2386 UNLOCK_ZONE(notify
->zone
);
2388 zone_idetach(¬ify
->zone
);
2390 dns_zone_idetach(¬ify
->zone
);
2392 if (notify
->find
!= NULL
)
2393 dns_adb_destroyfind(¬ify
->find
);
2394 if (notify
->request
!= NULL
)
2395 dns_request_destroy(¬ify
->request
);
2396 if (dns_name_dynamic(¬ify
->ns
))
2397 dns_name_free(¬ify
->ns
, notify
->mctx
);
2398 mctx
= notify
->mctx
;
2399 isc_mem_put(notify
->mctx
, notify
, sizeof *notify
);
2400 isc_mem_detach(&mctx
);
2404 notify_create(isc_mem_t
*mctx
, unsigned int flags
, dns_notify_t
**notifyp
) {
2405 dns_notify_t
*notify
;
2407 REQUIRE(notifyp
!= NULL
&& *notifyp
== NULL
);
2409 notify
= isc_mem_get(mctx
, sizeof *notify
);
2411 return (ISC_R_NOMEMORY
);
2413 notify
->mctx
= NULL
;
2414 isc_mem_attach(mctx
, ¬ify
->mctx
);
2415 notify
->flags
= flags
;
2416 notify
->zone
= NULL
;
2417 notify
->find
= NULL
;
2418 notify
->request
= NULL
;
2419 isc_sockaddr_any(¬ify
->dst
);
2420 dns_name_init(¬ify
->ns
, NULL
);
2421 notify
->attempt
= 0;
2422 ISC_LINK_INIT(notify
, link
);
2423 notify
->magic
= NOTIFY_MAGIC
;
2425 return (ISC_R_SUCCESS
);
2429 * XXXAG should check for DNS_ZONEFLG_EXITING
2432 process_adb_event(isc_task_t
*task
, isc_event_t
*ev
) {
2433 dns_notify_t
*notify
;
2434 isc_eventtype_t result
;
2438 notify
= ev
->ev_arg
;
2439 REQUIRE(DNS_NOTIFY_VALID(notify
));
2440 INSIST(task
== notify
->zone
->task
);
2441 result
= ev
->ev_type
;
2442 isc_event_free(&ev
);
2443 if (result
== DNS_EVENT_ADBMOREADDRESSES
) {
2444 dns_adb_destroyfind(¬ify
->find
);
2445 notify_find_address(notify
);
2448 if (result
== DNS_EVENT_ADBNOMOREADDRESSES
) {
2449 LOCK_ZONE(notify
->zone
);
2450 notify_send(notify
);
2451 UNLOCK_ZONE(notify
->zone
);
2453 notify_destroy(notify
, ISC_FALSE
);
2457 notify_find_address(dns_notify_t
*notify
) {
2458 isc_result_t result
;
2459 unsigned int options
;
2461 REQUIRE(DNS_NOTIFY_VALID(notify
));
2462 options
= DNS_ADBFIND_WANTEVENT
| DNS_ADBFIND_INET
|
2463 DNS_ADBFIND_INET6
| DNS_ADBFIND_RETURNLAME
;
2465 if (notify
->zone
->view
->adb
== NULL
)
2468 result
= dns_adb_createfind(notify
->zone
->view
->adb
,
2470 process_adb_event
, notify
,
2471 ¬ify
->ns
, dns_rootname
,
2473 notify
->zone
->view
->dstport
,
2476 /* Something failed? */
2477 if (result
!= ISC_R_SUCCESS
)
2480 /* More addresses pending? */
2481 if ((notify
->find
->options
& DNS_ADBFIND_WANTEVENT
) != 0)
2484 /* We have as many addresses as we can get. */
2485 LOCK_ZONE(notify
->zone
);
2486 notify_send(notify
);
2487 UNLOCK_ZONE(notify
->zone
);
2490 notify_destroy(notify
, ISC_FALSE
);
2495 notify_send_queue(dns_notify_t
*notify
) {
2497 isc_result_t result
;
2499 e
= isc_event_allocate(notify
->mctx
, NULL
,
2500 DNS_EVENT_NOTIFYSENDTOADDR
,
2502 notify
, sizeof(isc_event_t
));
2504 return (ISC_R_NOMEMORY
);
2506 e
->ev_sender
= NULL
;
2507 result
= isc_ratelimiter_enqueue(notify
->zone
->zmgr
->rl
,
2508 notify
->zone
->task
, &e
);
2509 if (result
!= ISC_R_SUCCESS
)
2515 notify_send_toaddr(isc_task_t
*task
, isc_event_t
*event
) {
2516 dns_notify_t
*notify
;
2517 isc_result_t result
;
2518 dns_message_t
*message
= NULL
;
2519 isc_netaddr_t dstip
;
2520 dns_tsigkey_t
*key
= NULL
;
2521 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
2525 notify
= event
->ev_arg
;
2526 REQUIRE(DNS_NOTIFY_VALID(notify
));
2530 LOCK_ZONE(notify
->zone
);
2532 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_LOADED
) == 0) {
2533 result
= ISC_R_CANCELED
;
2537 if ((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0 ||
2538 DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_EXITING
) ||
2539 notify
->zone
->view
->requestmgr
== NULL
||
2540 notify
->zone
->db
== NULL
) {
2541 result
= ISC_R_CANCELED
;
2545 result
= notify_createmessage(notify
->zone
, notify
->flags
, &message
);
2546 if (result
!= ISC_R_SUCCESS
)
2549 isc_netaddr_fromsockaddr(&dstip
, ¬ify
->dst
);
2550 (void)dns_view_getpeertsig(notify
->zone
->view
, &dstip
, &key
);
2552 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
2553 notify_log(notify
->zone
, ISC_LOG_DEBUG(3), "sending notify to %s",
2555 switch (isc_sockaddr_pf(¬ify
->dst
)) {
2557 src
= notify
->zone
->notifysrc4
;
2560 src
= notify
->zone
->notifysrc6
;
2563 result
= ISC_R_NOTIMPLEMENTED
;
2567 if (DNS_ZONE_FLAG(notify
->zone
, DNS_ZONEFLG_DIALNOTIFY
))
2569 result
= dns_request_createvia(notify
->zone
->view
->requestmgr
, message
,
2570 &src
, ¬ify
->dst
, 0, key
, timeout
,
2572 notify_done
, notify
,
2576 dns_tsigkey_detach(&key
);
2577 dns_message_destroy(&message
);
2579 UNLOCK_ZONE(notify
->zone
);
2580 if (result
!= ISC_R_SUCCESS
)
2581 notify_destroy(notify
, ISC_FALSE
);
2582 isc_event_free(&event
);
2586 notify_send(dns_notify_t
*notify
) {
2587 dns_adbaddrinfo_t
*ai
;
2589 isc_result_t result
;
2590 dns_notify_t
*new = NULL
;
2593 * Zone lock held by caller.
2595 REQUIRE(DNS_NOTIFY_VALID(notify
));
2596 REQUIRE(LOCKED_ZONE(notify
->zone
));
2598 for (ai
= ISC_LIST_HEAD(notify
->find
->list
);
2600 ai
= ISC_LIST_NEXT(ai
, publink
)) {
2602 if (notify_isqueued(notify
->zone
, NULL
, &dst
))
2605 result
= notify_create(notify
->mctx
,
2606 (notify
->flags
& DNS_NOTIFY_NOSOA
),
2608 if (result
!= ISC_R_SUCCESS
)
2610 zone_iattach(notify
->zone
, &new->zone
);
2611 ISC_LIST_APPEND(new->zone
->notifies
, new, link
);
2613 result
= notify_send_queue(new);
2614 if (result
!= ISC_R_SUCCESS
)
2621 notify_destroy(new, ISC_TRUE
);
2625 dns_zone_notify(dns_zone_t
*zone
) {
2628 REQUIRE(DNS_ZONE_VALID(zone
));
2631 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
2634 zone_settimer(zone
, &now
);
2639 zone_notify(dns_zone_t
*zone
) {
2640 dns_dbnode_t
*node
= NULL
;
2641 dns_dbversion_t
*version
= NULL
;
2642 dns_name_t
*origin
= NULL
;
2645 dns_rdata_soa_t soa
;
2646 isc_uint32_t serial
;
2647 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2648 dns_rdataset_t nsrdset
;
2649 dns_rdataset_t soardset
;
2650 isc_result_t result
;
2651 dns_notify_t
*notify
= NULL
;
2654 isc_boolean_t isqueued
;
2655 dns_notifytype_t notifytype
;
2656 unsigned int flags
= 0;
2657 isc_boolean_t loggednotify
= ISC_FALSE
;
2659 REQUIRE(DNS_ZONE_VALID(zone
));
2662 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
2663 notifytype
= zone
->notifytype
;
2666 if (! DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
))
2669 if (notifytype
== dns_notifytype_no
)
2672 origin
= &zone
->origin
;
2675 * If the zone is dialup we are done as we don't want to send
2676 * the current soa so as to force a refresh query.
2678 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
2679 flags
|= DNS_NOTIFY_NOSOA
;
2684 dns_db_currentversion(zone
->db
, &version
);
2685 result
= dns_db_findnode(zone
->db
, origin
, ISC_FALSE
, &node
);
2686 if (result
!= ISC_R_SUCCESS
)
2689 dns_rdataset_init(&soardset
);
2690 result
= dns_db_findrdataset(zone
->db
, node
, version
,
2692 dns_rdatatype_none
, 0, &soardset
, NULL
);
2693 if (result
!= ISC_R_SUCCESS
)
2697 * Find serial and master server's name.
2699 dns_name_init(&master
, NULL
);
2700 result
= dns_rdataset_first(&soardset
);
2701 if (result
!= ISC_R_SUCCESS
)
2703 dns_rdataset_current(&soardset
, &rdata
);
2704 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
2705 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2706 dns_rdata_reset(&rdata
);
2707 result
= dns_name_dup(&soa
.origin
, zone
->mctx
, &master
);
2708 serial
= soa
.serial
;
2709 dns_rdataset_disassociate(&soardset
);
2710 if (result
!= ISC_R_SUCCESS
)
2714 * Enqueue notify requests for 'also-notify' servers.
2717 for (i
= 0; i
< zone
->notifycnt
; i
++) {
2718 dst
= zone
->notify
[i
];
2719 if (notify_isqueued(zone
, NULL
, &dst
))
2721 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
2722 if (result
!= ISC_R_SUCCESS
)
2724 zone_iattach(zone
, ¬ify
->zone
);
2726 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
2727 result
= notify_send_queue(notify
);
2728 if (result
!= ISC_R_SUCCESS
)
2729 notify_destroy(notify
, ISC_TRUE
);
2730 if (!loggednotify
) {
2731 notify_log(zone
, ISC_LOG_INFO
,
2732 "sending notifies (serial %u)",
2734 loggednotify
= ISC_TRUE
;
2740 if (notifytype
== dns_notifytype_explicit
)
2744 * Process NS RRset to generate notifies.
2747 dns_rdataset_init(&nsrdset
);
2748 result
= dns_db_findrdataset(zone
->db
, node
, version
,
2750 dns_rdatatype_none
, 0, &nsrdset
, NULL
);
2751 if (result
!= ISC_R_SUCCESS
)
2754 result
= dns_rdataset_first(&nsrdset
);
2755 while (result
== ISC_R_SUCCESS
) {
2756 dns_rdataset_current(&nsrdset
, &rdata
);
2757 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
2758 dns_rdata_reset(&rdata
);
2759 if (result
!= ISC_R_SUCCESS
)
2762 * don't notify the master server.
2764 if (dns_name_compare(&master
, &ns
.name
) == 0) {
2765 result
= dns_rdataset_next(&nsrdset
);
2769 if (!loggednotify
) {
2770 notify_log(zone
, ISC_LOG_INFO
,
2771 "sending notifies (serial %u)",
2773 loggednotify
= ISC_TRUE
;
2777 isqueued
= notify_isqueued(zone
, &ns
.name
, NULL
);
2780 result
= dns_rdataset_next(&nsrdset
);
2783 result
= notify_create(zone
->mctx
, flags
, ¬ify
);
2784 if (result
!= ISC_R_SUCCESS
)
2786 dns_zone_iattach(zone
, ¬ify
->zone
);
2787 result
= dns_name_dup(&ns
.name
, zone
->mctx
, ¬ify
->ns
);
2788 if (result
!= ISC_R_SUCCESS
) {
2790 notify_destroy(notify
, ISC_TRUE
);
2795 ISC_LIST_APPEND(zone
->notifies
, notify
, link
);
2797 notify_find_address(notify
);
2799 result
= dns_rdataset_next(&nsrdset
);
2801 dns_rdataset_disassociate(&nsrdset
);
2804 if (dns_name_dynamic(&master
))
2805 dns_name_free(&master
, zone
->mctx
);
2807 dns_db_detachnode(zone
->db
, &node
);
2809 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
2816 static inline isc_result_t
2817 save_nsrrset(dns_message_t
*message
, dns_name_t
*name
,
2818 dns_db_t
*db
, dns_dbversion_t
*version
)
2820 dns_rdataset_t
*nsrdataset
= NULL
;
2821 dns_rdataset_t
*rdataset
= NULL
;
2822 dns_dbnode_t
*node
= NULL
;
2824 isc_result_t result
;
2825 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2828 * Extract NS RRset from message.
2830 result
= dns_message_findname(message
, DNS_SECTION_ANSWER
, name
,
2831 dns_rdatatype_ns
, dns_rdatatype_none
,
2833 if (result
!= ISC_R_SUCCESS
)
2839 result
= dns_db_findnode(db
, name
, ISC_TRUE
, &node
);
2840 if (result
!= ISC_R_SUCCESS
)
2842 result
= dns_db_addrdataset(db
, node
, version
, 0,
2843 nsrdataset
, 0, NULL
);
2844 dns_db_detachnode(db
, &node
);
2845 if (result
!= ISC_R_SUCCESS
)
2848 * Add glue rdatasets.
2850 for (result
= dns_rdataset_first(nsrdataset
);
2851 result
== ISC_R_SUCCESS
;
2852 result
= dns_rdataset_next(nsrdataset
)) {
2853 dns_rdataset_current(nsrdataset
, &rdata
);
2854 result
= dns_rdata_tostruct(&rdata
, &ns
, NULL
);
2855 dns_rdata_reset(&rdata
);
2856 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2857 if (!dns_name_issubdomain(&ns
.name
, name
))
2860 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
2861 &ns
.name
, dns_rdatatype_a6
,
2862 dns_rdatatype_none
, NULL
,
2864 if (result
== ISC_R_SUCCESS
) {
2865 result
= dns_db_findnode(db
, &ns
.name
,
2867 if (result
!= ISC_R_SUCCESS
)
2869 result
= dns_db_addrdataset(db
, node
, version
, 0,
2871 dns_db_detachnode(db
, &node
);
2872 if (result
!= ISC_R_SUCCESS
)
2876 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
2877 &ns
.name
, dns_rdatatype_aaaa
,
2878 dns_rdatatype_none
, NULL
,
2880 if (result
== ISC_R_SUCCESS
) {
2881 result
= dns_db_findnode(db
, &ns
.name
,
2883 if (result
!= ISC_R_SUCCESS
)
2885 result
= dns_db_addrdataset(db
, node
, version
, 0,
2887 dns_db_detachnode(db
, &node
);
2888 if (result
!= ISC_R_SUCCESS
)
2892 result
= dns_message_findname(message
, DNS_SECTION_ADDITIONAL
,
2893 &ns
.name
, dns_rdatatype_a
,
2894 dns_rdatatype_none
, NULL
,
2896 if (result
== ISC_R_SUCCESS
) {
2897 result
= dns_db_findnode(db
, &ns
.name
,
2899 if (result
!= ISC_R_SUCCESS
)
2901 result
= dns_db_addrdataset(db
, node
, version
, 0,
2903 dns_db_detachnode(db
, &node
);
2904 if (result
!= ISC_R_SUCCESS
)
2908 if (result
!= ISC_R_NOMORE
)
2911 return (ISC_R_SUCCESS
);
2918 stub_callback(isc_task_t
*task
, isc_event_t
*event
) {
2919 const char me
[] = "stub_callback";
2920 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
2921 dns_stub_t
*stub
= NULL
;
2922 dns_message_t
*msg
= NULL
;
2923 dns_zone_t
*zone
= NULL
;
2924 char master
[ISC_SOCKADDR_FORMATSIZE
];
2925 isc_uint32_t nscnt
, cnamecnt
;
2926 isc_result_t result
;
2928 isc_boolean_t exiting
= ISC_FALSE
;
2931 stub
= revent
->ev_arg
;
2932 INSIST(DNS_STUB_VALID(stub
));
2942 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
2943 zone_debuglog(zone
, me
, 1, "exiting");
2948 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
2950 if (revent
->result
!= ISC_R_SUCCESS
) {
2951 dns_zone_log(zone
, ISC_LOG_INFO
,
2952 "could not refresh stub from master %s: %s",
2953 master
, dns_result_totext(revent
->result
));
2957 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
2958 if (result
!= ISC_R_SUCCESS
)
2961 result
= dns_request_getresponse(revent
->request
, msg
, 0);
2962 if (result
!= ISC_R_SUCCESS
)
2968 if (msg
->rcode
!= dns_rcode_noerror
) {
2972 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
2973 dns_rcode_totext(msg
->rcode
, &rb
);
2975 dns_zone_log(zone
, ISC_LOG_INFO
,
2977 "unexpected rcode (%.*s) from %s",
2978 (int)rb
.used
, rcode
, master
);
2983 * We need complete messages.
2985 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
2986 if (dns_request_usedtcp(revent
->request
)) {
2987 dns_zone_log(zone
, ISC_LOG_INFO
,
2989 "truncated TCP response from master %s",
2994 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
3000 * If non-auth log and next master.
3002 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
3003 dns_zone_log(zone
, ISC_LOG_INFO
, "refreshing stub: "
3004 "non-authoritative answer from master %s",
3012 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
3013 nscnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_ns
);
3015 if (cnamecnt
!= 0) {
3016 dns_zone_log(zone
, ISC_LOG_INFO
,
3017 "refreshing stub: unexpected CNAME response "
3018 "from master %s", master
);
3023 dns_zone_log(zone
, ISC_LOG_INFO
,
3024 "refreshing stub: no NS records in response "
3025 "from master %s", master
);
3032 result
= save_nsrrset(msg
, &zone
->origin
, stub
->db
, stub
->version
);
3033 if (result
!= ISC_R_SUCCESS
) {
3034 dns_zone_log(zone
, ISC_LOG_INFO
,
3035 "refreshing stub: unable to save NS records "
3036 "from master %s", master
);
3043 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_TRUE
);
3045 if (zone
->db
== NULL
)
3046 dns_db_attach(stub
->db
, &zone
->db
);
3048 dns_db_detach(&stub
->db
);
3050 if (zone
->masterfile
!= NULL
) {
3051 dns_zone_dump(zone
);
3052 (void)isc_time_now(&zone
->loadtime
);
3055 dns_message_destroy(&msg
);
3056 isc_event_free(&event
);
3058 dns_request_destroy(&zone
->request
);
3059 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
3060 isc_interval_set(&i
, isc_random_jitter(zone
->refresh
,
3061 zone
->refresh
/ 4), 0);
3062 isc_time_add(&now
, &i
, &zone
->refreshtime
);
3063 isc_interval_set(&i
, zone
->expire
, 0);
3064 isc_time_add(&now
, &i
, &zone
->expiretime
);
3065 zone_settimer(zone
, &now
);
3070 if (stub
->version
!= NULL
)
3071 dns_db_closeversion(stub
->db
, &stub
->version
, ISC_FALSE
);
3072 if (stub
->db
!= NULL
)
3073 dns_db_detach(&stub
->db
);
3075 dns_message_destroy(&msg
);
3076 isc_event_free(&event
);
3078 dns_request_destroy(&zone
->request
);
3080 zone
->refreshcnt
= 0;
3081 if (exiting
|| zone
->curmaster
>= zone
->masterscnt
) {
3082 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
3084 zone_settimer(zone
, &now
);
3088 queue_soa_query(zone
);
3094 dns_message_destroy(&msg
);
3095 isc_event_free(&event
);
3097 dns_request_destroy(&zone
->request
);
3099 ns_query(zone
, NULL
, stub
);
3104 dns_zone_idetach(&stub
->zone
);
3105 INSIST(stub
->db
== NULL
);
3106 INSIST(stub
->version
== NULL
);
3107 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
3110 INSIST(event
== NULL
);
3115 * An SOA query has finished (successfully or not).
3118 refresh_callback(isc_task_t
*task
, isc_event_t
*event
) {
3119 const char me
[] = "refresh_callback";
3120 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
3122 dns_message_t
*msg
= NULL
;
3123 isc_uint32_t soacnt
, cnamecnt
, soacount
, nscount
;
3125 char master
[ISC_SOCKADDR_FORMATSIZE
];
3126 dns_rdataset_t
*rdataset
;
3127 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3128 dns_rdata_soa_t soa
;
3129 isc_result_t result
;
3130 isc_uint32_t serial
;
3133 zone
= revent
->ev_arg
;
3134 INSIST(DNS_ZONE_VALID(zone
));
3141 * if timeout log and next master;
3144 isc_sockaddr_format(&zone
->masteraddr
, master
, sizeof(master
));
3148 if (revent
->result
!= ISC_R_SUCCESS
) {
3149 dns_zone_log(zone
, ISC_LOG_INFO
,
3150 "refresh: failure trying master %s: %s",
3151 master
, dns_result_totext(revent
->result
));
3152 if (revent
->result
== ISC_R_TIMEDOUT
&&
3153 !dns_request_usedtcp(revent
->request
)) {
3154 if (zone
->refreshcnt
< 3)
3156 dns_zone_log(zone
, ISC_LOG_INFO
,
3157 "refresh: retry limit for "
3158 "master %s exceeded",
3164 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
3165 if (result
!= ISC_R_SUCCESS
)
3167 result
= dns_request_getresponse(revent
->request
, msg
, 0);
3168 if (result
!= ISC_R_SUCCESS
) {
3169 dns_zone_log(zone
, ISC_LOG_INFO
,
3170 "refresh: failure trying master %s: %s",
3171 master
, dns_result_totext(result
));
3178 if (msg
->rcode
!= dns_rcode_noerror
) {
3182 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
3183 dns_rcode_totext(msg
->rcode
, &rb
);
3185 dns_zone_log(zone
, ISC_LOG_INFO
,
3186 "refresh: unexpected rcode (%.*s) from master %s",
3187 (int)rb
.used
, rcode
, master
);
3192 * If truncated punt to zone transfer which will query again.
3194 if ((msg
->flags
& DNS_MESSAGEFLAG_TC
) != 0) {
3195 if (zone
->type
== dns_zone_slave
) {
3196 dns_zone_log(zone
, ISC_LOG_INFO
,
3197 "refresh: truncated UDP answer, "
3198 "initiating TCP zone xfer "
3203 INSIST(zone
->type
== dns_zone_stub
);
3204 if (dns_request_usedtcp(revent
->request
)) {
3205 dns_zone_log(zone
, ISC_LOG_INFO
,
3206 "refresh: truncated TCP response "
3212 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_USEVC
);
3219 * if non-auth log and next master;
3221 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
3222 dns_zone_log(zone
, ISC_LOG_INFO
,
3223 "refresh: non-authoritative answer from "
3224 "master %s", master
);
3228 cnamecnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_cname
);
3229 soacnt
= message_count(msg
, DNS_SECTION_ANSWER
, dns_rdatatype_soa
);
3230 nscount
= message_count(msg
, DNS_SECTION_AUTHORITY
, dns_rdatatype_ns
);
3231 soacount
= message_count(msg
, DNS_SECTION_AUTHORITY
,
3235 * There should not be a CNAME record at top of zone.
3237 if (cnamecnt
!= 0) {
3238 dns_zone_log(zone
, ISC_LOG_INFO
,
3239 "refresh: CNAME at top of zone "
3240 "in master %s", master
);
3245 * if referral log and next master;
3247 if (soacnt
== 0 && soacount
== 0 && nscount
!= 0) {
3248 dns_zone_log(zone
, ISC_LOG_INFO
,
3249 "refresh: referral response "
3250 "from master %s", master
);
3255 * if nodata log and next master;
3257 if (soacnt
== 0 && (nscount
== 0 || soacount
!= 0)) {
3258 dns_zone_log(zone
, ISC_LOG_INFO
,
3259 "refresh: NODATA response "
3260 "from master %s", master
);
3265 * Only one soa at top of zone.
3268 dns_zone_log(zone
, ISC_LOG_INFO
,
3269 "refresh: answer SOA count (%d) != 1 "
3278 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
, &zone
->origin
,
3279 dns_rdatatype_soa
, dns_rdatatype_none
,
3281 if (result
!= ISC_R_SUCCESS
) {
3282 dns_zone_log(zone
, ISC_LOG_INFO
,
3283 "refresh: unable to get SOA record "
3284 "from master %s", master
);
3288 result
= dns_rdataset_first(rdataset
);
3289 if (result
!= ISC_R_SUCCESS
) {
3290 dns_zone_log(zone
, ISC_LOG_INFO
,
3291 "refresh: dns_rdataset_first() failed");
3295 dns_rdataset_current(rdataset
, &rdata
);
3296 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
3297 if (result
!= ISC_R_SUCCESS
) {
3298 dns_zone_log(zone
, ISC_LOG_INFO
,
3299 "refresh: dns_rdata_tostruct() failed");
3303 serial
= soa
.serial
;
3305 zone_debuglog(zone
, me
, 1, "serial: new %u, old %u",
3306 serial
, zone
->serial
);
3307 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) ||
3308 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
) ||
3309 isc_serial_gt(serial
, zone
->serial
)) {
3311 isc_event_free(&event
);
3313 dns_request_destroy(&zone
->request
);
3315 if (zone
->type
== dns_zone_slave
) {
3318 INSIST(zone
->type
== dns_zone_stub
);
3319 ns_query(zone
, rdataset
, NULL
);
3322 dns_message_destroy(&msg
);
3323 } else if (isc_serial_eq(soa
.serial
, zone
->serial
)) {
3324 if (zone
->masterfile
!= NULL
) {
3325 result
= ISC_R_FAILURE
;
3326 if (zone
->journal
!= NULL
)
3327 result
= isc_file_settime(zone
->journal
, &now
);
3328 if (result
!= ISC_R_SUCCESS
)
3329 result
= isc_file_settime(zone
->masterfile
,
3331 if (result
!= ISC_R_SUCCESS
)
3332 dns_zone_log(zone
, ISC_LOG_ERROR
,
3333 "refresh: could not set file "
3334 "modification time of '%s': %s",
3336 dns_result_totext(result
));
3338 isc_interval_set(&i
, isc_random_jitter(zone
->refresh
,
3339 zone
->refresh
/ 4), 0);
3340 isc_time_add(&now
, &i
, &zone
->refreshtime
);
3341 isc_interval_set(&i
, zone
->expire
, 0);
3342 isc_time_add(&now
, &i
, &zone
->expiretime
);
3345 zone_debuglog(zone
, me
, 1, "ahead");
3349 dns_message_destroy(&msg
);
3354 dns_message_destroy(&msg
);
3355 isc_event_free(&event
);
3357 dns_request_destroy(&zone
->request
);
3359 zone
->refreshcnt
= 0;
3360 if (zone
->curmaster
>= zone
->masterscnt
) {
3361 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
3362 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
3363 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
3364 zone
->refreshtime
= now
;
3366 zone_settimer(zone
, &now
);
3370 queue_soa_query(zone
);
3377 dns_message_destroy(&msg
);
3378 isc_event_free(&event
);
3380 dns_request_destroy(&zone
->request
);
3381 queue_soa_query(zone
);
3384 dns_zone_idetach(&zone
);
3389 queue_soa_query(dns_zone_t
*zone
) {
3390 const char me
[] = "queue_soa_query";
3392 dns_zone_t
*dummy
= NULL
;
3393 isc_result_t result
;
3399 REQUIRE(LOCKED_ZONE(zone
));
3401 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
3402 cancel_refresh(zone
);
3406 e
= isc_event_allocate(zone
->mctx
, NULL
, DNS_EVENT_ZONE
,
3407 soa_query
, zone
, sizeof(isc_event_t
));
3409 cancel_refresh(zone
);
3414 * Attach so that we won't clean up
3415 * until the event is delivered.
3417 zone_iattach(zone
, &dummy
);
3420 e
->ev_sender
= NULL
;
3421 result
= isc_ratelimiter_enqueue(zone
->zmgr
->rl
, zone
->task
, &e
);
3422 if (result
!= ISC_R_SUCCESS
) {
3423 zone_idetach(&dummy
);
3425 cancel_refresh(zone
);
3429 static inline isc_result_t
3430 create_query(dns_zone_t
*zone
, dns_rdatatype_t rdtype
,
3431 dns_message_t
**messagep
)
3433 dns_message_t
*message
= NULL
;
3434 dns_name_t
*qname
= NULL
;
3435 dns_rdataset_t
*qrdataset
= NULL
;
3436 isc_result_t result
;
3438 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
3440 if (result
!= ISC_R_SUCCESS
)
3443 message
->opcode
= dns_opcode_query
;
3444 message
->rdclass
= zone
->rdclass
;
3446 result
= dns_message_gettempname(message
, &qname
);
3447 if (result
!= ISC_R_SUCCESS
)
3450 result
= dns_message_gettemprdataset(message
, &qrdataset
);
3451 if (result
!= ISC_R_SUCCESS
)
3457 dns_name_init(qname
, NULL
);
3458 dns_name_clone(&zone
->origin
, qname
);
3459 dns_rdataset_init(qrdataset
);
3460 dns_rdataset_makequestion(qrdataset
, zone
->rdclass
, rdtype
);
3461 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
3462 dns_message_addname(message
, qname
, DNS_SECTION_QUESTION
);
3464 *messagep
= message
;
3465 return (ISC_R_SUCCESS
);
3469 dns_message_puttempname(message
, &qname
);
3470 if (qrdataset
!= NULL
)
3471 dns_message_puttemprdataset(message
, &qrdataset
);
3472 if (message
!= NULL
)
3473 dns_message_destroy(&message
);
3478 soa_query(isc_task_t
*task
, isc_event_t
*event
) {
3479 const char me
[] = "soa_query";
3480 isc_result_t result
;
3481 dns_message_t
*message
= NULL
;
3482 dns_zone_t
*zone
= event
->ev_arg
;
3483 dns_zone_t
*dummy
= NULL
;
3484 isc_netaddr_t masterip
;
3485 dns_tsigkey_t
*key
= NULL
;
3486 isc_uint32_t options
;
3488 isc_boolean_t cancel
= ISC_TRUE
;
3491 REQUIRE(DNS_ZONE_VALID(zone
));
3498 if (((event
->ev_attributes
& ISC_EVENTATTR_CANCELED
) != 0) ||
3499 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
) ||
3500 zone
->view
->requestmgr
== NULL
) {
3501 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
3507 * XXX Optimisation: Create message when zone is setup and reuse.
3509 result
= create_query(zone
, dns_rdatatype_soa
, &message
);
3510 if (result
!= ISC_R_SUCCESS
)
3513 INSIST(zone
->masterscnt
> 0);
3514 INSIST(zone
->curmaster
< zone
->masterscnt
);
3515 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
3517 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
3519 * First, look for a tsig key in the master statement, then
3520 * try for a server key.
3522 if ((zone
->masterkeynames
!= NULL
) &&
3523 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
3524 dns_view_t
*view
= dns_zone_getview(zone
);
3525 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
3526 result
= dns_view_gettsig(view
, keyname
, &key
);
3527 if (result
!= ISC_R_SUCCESS
) {
3528 char namebuf
[DNS_NAME_FORMATSIZE
];
3529 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
3530 dns_zone_log(zone
, ISC_LOG_ERROR
,
3531 "unable to find key: %s", namebuf
);
3535 (void)dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
3537 options
= DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_USEVC
) ?
3538 DNS_REQUESTOPT_TCP
: 0;
3539 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
3541 src
= zone
->xfrsource4
;
3544 src
= zone
->xfrsource6
;
3547 result
= ISC_R_NOTIMPLEMENTED
;
3550 zone_iattach(zone
, &dummy
);
3552 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
3554 result
= dns_request_createvia(zone
->view
->requestmgr
, message
,
3555 &src
, &zone
->masteraddr
, options
, key
,
3556 timeout
, zone
->task
,
3557 refresh_callback
, zone
, &zone
->request
);
3558 if (result
!= ISC_R_SUCCESS
) {
3559 zone_idetach(&dummy
);
3560 zone_debuglog(zone
, me
, 1,
3561 "dns_request_createvia() failed: %s",
3562 dns_result_totext(result
));
3569 dns_tsigkey_detach(&key
);
3570 if (message
!= NULL
)
3571 dns_message_destroy(&message
);
3573 cancel_refresh(zone
);
3574 isc_event_free(&event
);
3576 dns_zone_idetach(&zone
);
3581 ns_query(dns_zone_t
*zone
, dns_rdataset_t
*soardataset
, dns_stub_t
*stub
) {
3582 const char me
[] = "ns_query";
3583 isc_result_t result
;
3584 dns_message_t
*message
= NULL
;
3585 isc_netaddr_t masterip
;
3586 dns_tsigkey_t
*key
= NULL
;
3587 dns_dbnode_t
*node
= NULL
;
3591 REQUIRE(DNS_ZONE_VALID(zone
));
3592 REQUIRE((soardataset
!= NULL
&& stub
== NULL
) ||
3593 (soardataset
== NULL
&& stub
!= NULL
));
3594 REQUIRE(stub
== NULL
|| DNS_STUB_VALID(stub
));
3600 stub
= isc_mem_get(zone
->mctx
, sizeof *stub
);
3603 stub
->magic
= STUB_MAGIC
;
3604 stub
->mctx
= zone
->mctx
;
3607 stub
->version
= NULL
;
3610 * Attach so that the zone won't disappear from under us.
3612 zone_iattach(zone
, &stub
->zone
);
3615 * If a db exists we will update it, otherwise we create a
3616 * new one and attach it to the zone once we have the NS
3619 if (zone
->db
!= NULL
)
3620 dns_db_attach(zone
->db
, &stub
->db
);
3622 INSIST(zone
->db_argc
>= 1);
3623 result
= dns_db_create(zone
->mctx
, zone
->db_argv
[0],
3624 &zone
->origin
, dns_dbtype_stub
,
3629 if (result
!= ISC_R_SUCCESS
) {
3630 dns_zone_log(zone
, ISC_LOG_ERROR
,
3634 dns_result_totext(result
));
3637 dns_db_settask(stub
->db
, zone
->task
);
3640 dns_db_newversion(stub
->db
, &stub
->version
);
3643 * Update SOA record.
3645 result
= dns_db_findnode(stub
->db
, &zone
->origin
, ISC_TRUE
,
3647 if (result
!= ISC_R_SUCCESS
) {
3648 dns_zone_log(zone
, ISC_LOG_INFO
,
3650 "dns_db_findnode() failed: %s",
3651 dns_result_totext(result
));
3655 result
= dns_db_addrdataset(stub
->db
, node
, stub
->version
, 0,
3656 soardataset
, 0, NULL
);
3657 dns_db_detachnode(stub
->db
, &node
);
3658 if (result
!= ISC_R_SUCCESS
) {
3659 dns_zone_log(zone
, ISC_LOG_INFO
,
3661 "dns_db_addrdataset() failed: %s",
3662 dns_result_totext(result
));
3668 * XXX Optimisation: Create message when zone is setup and reuse.
3670 result
= create_query(zone
, dns_rdatatype_ns
, &message
);
3672 INSIST(zone
->masterscnt
> 0);
3673 INSIST(zone
->curmaster
< zone
->masterscnt
);
3674 zone
->masteraddr
= zone
->masters
[zone
->curmaster
];
3676 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
3678 * First, look for a tsig key in the master statement, then
3679 * try for a server key.
3681 if ((zone
->masterkeynames
!= NULL
) &&
3682 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
3683 dns_view_t
*view
= dns_zone_getview(zone
);
3684 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
3685 result
= dns_view_gettsig(view
, keyname
, &key
);
3686 if (result
!= ISC_R_SUCCESS
) {
3687 char namebuf
[DNS_NAME_FORMATSIZE
];
3688 dns_name_format(keyname
, namebuf
, sizeof(namebuf
));
3689 dns_zone_log(zone
, ISC_LOG_ERROR
,
3690 "unable to find key: %s", namebuf
);
3694 (void)dns_view_getpeertsig(zone
->view
, &masterip
, &key
);
3697 * Always use TCP so that we shouldn't truncate in additional section.
3699 switch (isc_sockaddr_pf(&zone
->masteraddr
)) {
3701 src
= zone
->xfrsource4
;
3704 src
= zone
->xfrsource6
;
3707 result
= ISC_R_NOTIMPLEMENTED
;
3711 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
3713 result
= dns_request_createvia(zone
->view
->requestmgr
, message
,
3714 &src
, &zone
->masteraddr
,
3715 DNS_REQUESTOPT_TCP
, key
, timeout
,
3716 zone
->task
, stub_callback
, stub
,
3718 if (result
!= ISC_R_SUCCESS
) {
3719 zone_debuglog(zone
, me
, 1,
3720 "dns_request_createvia() failed: %s",
3721 dns_result_totext(result
));
3724 dns_message_destroy(&message
);
3728 cancel_refresh(zone
);
3731 if (stub
->version
!= NULL
)
3732 dns_db_closeversion(stub
->db
, &stub
->version
,
3734 if (stub
->db
!= NULL
)
3735 dns_db_detach(&stub
->db
);
3736 if (stub
->zone
!= NULL
)
3737 zone_idetach(&stub
->zone
);
3738 isc_mem_put(stub
->mctx
, stub
, sizeof(*stub
));
3740 if (message
!= NULL
)
3741 dns_message_destroy(&message
);
3744 dns_tsigkey_detach(&key
);
3750 * Handle the control event. Note that although this event causes the zone
3751 * to shut down, it is not a shutdown event in the sense of the task library.
3754 zone_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
3755 dns_zone_t
*zone
= (dns_zone_t
*) event
->ev_arg
;
3756 isc_boolean_t free_needed
, linked
= ISC_FALSE
;
3759 REQUIRE(DNS_ZONE_VALID(zone
));
3760 INSIST(event
->ev_type
== DNS_EVENT_ZONECONTROL
);
3761 INSIST(isc_refcount_current(&zone
->erefs
) == 0);
3762 zone_debuglog(zone
, "zone_shutdown", 3, "shutting down");
3765 * Stop things being restarted after we cancel them below.
3768 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_EXITING
);
3772 * If we were waiting for xfrin quota, step out of
3774 * If there's no zone manager, we can't be waiting for the
3777 if (zone
->zmgr
!= NULL
) {
3778 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
3779 if (zone
->statelist
== &zone
->zmgr
->waiting_for_xfrin
) {
3780 ISC_LIST_UNLINK(zone
->zmgr
->waiting_for_xfrin
, zone
,
3783 zone
->statelist
= NULL
;
3785 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
3789 * In task context, no locking required. See zone_xfrdone().
3791 if (zone
->xfr
!= NULL
)
3792 dns_xfrin_shutdown(zone
->xfr
);
3796 INSIST(zone
->irefs
> 0);
3799 if (zone
->request
!= NULL
) {
3800 dns_request_cancel(zone
->request
);
3803 if (zone
->readio
!= NULL
)
3804 zonemgr_cancelio(zone
->readio
);
3806 if (zone
->lctx
!= NULL
)
3807 dns_loadctx_cancel(zone
->lctx
);
3809 notify_cancel(zone
);
3811 if (zone
->timer
!= NULL
) {
3812 isc_timer_detach(&zone
->timer
);
3813 INSIST(zone
->irefs
> 0);
3817 if (zone
->view
!= NULL
)
3818 dns_view_weakdetach(&zone
->view
);
3821 * We have now canceled everything set the flag to allow exit_check()
3822 * to succeed. We must not unlock between setting this flag and
3823 * calling exit_check().
3825 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_SHUTDOWN
);
3826 free_needed
= exit_check(zone
);
3833 zone_timer(isc_task_t
*task
, isc_event_t
*event
) {
3834 const char me
[] = "zone_timer";
3835 dns_zone_t
*zone
= (dns_zone_t
*)event
->ev_arg
;
3838 REQUIRE(DNS_ZONE_VALID(zone
));
3842 zone_maintenance(zone
);
3844 isc_event_free(&event
);
3848 zone_settimer(dns_zone_t
*zone
, isc_time_t
*now
) {
3849 const char me
[] = "zone_settimer";
3851 isc_result_t result
;
3853 REQUIRE(DNS_ZONE_VALID(zone
));
3854 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
3857 isc_time_settoepoch(&next
);
3859 switch (zone
->type
) {
3860 case dns_zone_master
:
3861 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
3863 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDDUMP
) &&
3864 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DUMPING
)) {
3865 INSIST(!isc_time_isepoch(&zone
->dumptime
));
3866 if (isc_time_isepoch(&next
) ||
3867 isc_time_compare(&zone
->dumptime
, &next
) < 0)
3868 next
= zone
->dumptime
;
3872 case dns_zone_slave
:
3873 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
))
3878 if (!DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
) &&
3879 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOMASTERS
) &&
3880 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
) &&
3881 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADING
)) {
3882 INSIST(!isc_time_isepoch(&zone
->refreshtime
));
3883 if (isc_time_isepoch(&next
) ||
3884 isc_time_compare(&zone
->refreshtime
, &next
) < 0)
3885 next
= zone
->refreshtime
;
3887 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
)) {
3888 INSIST(!isc_time_isepoch(&zone
->expiretime
));
3889 if (isc_time_isepoch(&next
) ||
3890 isc_time_compare(&zone
->expiretime
, &next
) < 0)
3891 next
= zone
->expiretime
;
3899 if (isc_time_isepoch(&next
)) {
3900 zone_debuglog(zone
, me
, 10, "settimer inactive");
3901 result
= isc_timer_reset(zone
->timer
, isc_timertype_inactive
,
3902 NULL
, NULL
, ISC_TRUE
);
3903 if (result
!= ISC_R_SUCCESS
)
3904 dns_zone_log(zone
, ISC_LOG_ERROR
,
3905 "could not deactivate zone timer: %s",
3906 isc_result_totext(result
));
3908 if (isc_time_compare(&next
, now
) <= 0)
3910 result
= isc_timer_reset(zone
->timer
, isc_timertype_once
,
3911 &next
, NULL
, ISC_TRUE
);
3912 if (result
!= ISC_R_SUCCESS
)
3913 dns_zone_log(zone
, ISC_LOG_ERROR
,
3914 "could not reset zone timer: %s",
3915 isc_result_totext(result
));
3920 cancel_refresh(dns_zone_t
*zone
) {
3921 const char me
[] = "cancel_refresh";
3925 * 'zone' locked by caller.
3928 REQUIRE(DNS_ZONE_VALID(zone
));
3929 REQUIRE(LOCKED_ZONE(zone
));
3933 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
3935 zone_settimer(zone
, &now
);
3939 notify_createmessage(dns_zone_t
*zone
, unsigned int flags
,
3940 dns_message_t
**messagep
)
3942 dns_dbnode_t
*node
= NULL
;
3943 dns_dbversion_t
*version
= NULL
;
3944 dns_message_t
*message
= NULL
;
3945 dns_rdataset_t rdataset
;
3946 dns_rdata_t rdata
= DNS_RDATA_INIT
;
3948 dns_name_t
*tempname
= NULL
;
3949 dns_rdata_t
*temprdata
= NULL
;
3950 dns_rdatalist_t
*temprdatalist
= NULL
;
3951 dns_rdataset_t
*temprdataset
= NULL
;
3953 isc_result_t result
;
3955 isc_buffer_t
*b
= NULL
;
3957 REQUIRE(DNS_ZONE_VALID(zone
));
3958 REQUIRE(messagep
!= NULL
&& *messagep
== NULL
);
3961 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTRENDER
,
3963 if (result
!= ISC_R_SUCCESS
)
3966 message
->opcode
= dns_opcode_notify
;
3967 message
->flags
|= DNS_MESSAGEFLAG_AA
;
3968 message
->rdclass
= zone
->rdclass
;
3970 result
= dns_message_gettempname(message
, &tempname
);
3971 if (result
!= ISC_R_SUCCESS
)
3974 result
= dns_message_gettemprdataset(message
, &temprdataset
);
3975 if (result
!= ISC_R_SUCCESS
)
3981 dns_name_init(tempname
, NULL
);
3982 dns_name_clone(&zone
->origin
, tempname
);
3983 dns_rdataset_init(temprdataset
);
3984 dns_rdataset_makequestion(temprdataset
, zone
->rdclass
,
3986 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
3987 dns_message_addname(message
, tempname
, DNS_SECTION_QUESTION
);
3989 temprdataset
= NULL
;
3991 if ((flags
& DNS_NOTIFY_NOSOA
) != 0)
3994 result
= dns_message_gettempname(message
, &tempname
);
3995 if (result
!= ISC_R_SUCCESS
)
3997 result
= dns_message_gettemprdata(message
, &temprdata
);
3998 if (result
!= ISC_R_SUCCESS
)
4000 result
= dns_message_gettemprdataset(message
, &temprdataset
);
4001 if (result
!= ISC_R_SUCCESS
)
4003 result
= dns_message_gettemprdatalist(message
, &temprdatalist
);
4004 if (result
!= ISC_R_SUCCESS
)
4007 dns_name_init(tempname
, NULL
);
4008 dns_name_clone(&zone
->origin
, tempname
);
4009 dns_db_currentversion(zone
->db
, &version
);
4010 result
= dns_db_findnode(zone
->db
, tempname
, ISC_FALSE
, &node
);
4011 if (result
!= ISC_R_SUCCESS
)
4014 dns_rdataset_init(&rdataset
);
4015 result
= dns_db_findrdataset(zone
->db
, node
, version
,
4017 dns_rdatatype_none
, 0, &rdataset
,
4019 if (result
!= ISC_R_SUCCESS
)
4021 result
= dns_rdataset_first(&rdataset
);
4022 if (result
!= ISC_R_SUCCESS
)
4024 dns_rdataset_current(&rdataset
, &rdata
);
4025 dns_rdata_toregion(&rdata
, &r
);
4026 result
= isc_buffer_allocate(zone
->mctx
, &b
, r
.length
);
4027 if (result
!= ISC_R_SUCCESS
)
4029 isc_buffer_putmem(b
, r
.base
, r
.length
);
4030 isc_buffer_usedregion(b
, &r
);
4031 dns_rdata_init(temprdata
);
4032 dns_rdata_fromregion(temprdata
, rdata
.rdclass
, rdata
.type
, &r
);
4033 dns_message_takebuffer(message
, &b
);
4034 result
= dns_rdataset_next(&rdataset
);
4035 dns_rdataset_disassociate(&rdataset
);
4036 if (result
!= ISC_R_NOMORE
)
4038 temprdatalist
->rdclass
= rdata
.rdclass
;
4039 temprdatalist
->type
= rdata
.type
;
4040 temprdatalist
->covers
= 0;
4041 temprdatalist
->ttl
= rdataset
.ttl
;
4042 ISC_LIST_INIT(temprdatalist
->rdata
);
4043 ISC_LIST_APPEND(temprdatalist
->rdata
, temprdata
, link
);
4045 dns_rdataset_init(temprdataset
);
4046 result
= dns_rdatalist_tordataset(temprdatalist
, temprdataset
);
4047 if (result
!= ISC_R_SUCCESS
)
4050 ISC_LIST_APPEND(tempname
->list
, temprdataset
, link
);
4051 dns_message_addname(message
, tempname
, DNS_SECTION_ANSWER
);
4052 temprdatalist
= NULL
;
4053 temprdataset
= NULL
;
4059 dns_db_detachnode(zone
->db
, &node
);
4060 if (version
!= NULL
)
4061 dns_db_closeversion(zone
->db
, &version
, ISC_FALSE
);
4062 if (tempname
!= NULL
)
4063 dns_message_puttempname(message
, &tempname
);
4064 if (temprdata
!= NULL
)
4065 dns_message_puttemprdata(message
, &temprdata
);
4066 if (temprdataset
!= NULL
)
4067 dns_message_puttemprdataset(message
, &temprdataset
);
4068 if (temprdatalist
!= NULL
)
4069 dns_message_puttemprdatalist(message
, &temprdatalist
);
4072 *messagep
= message
;
4073 return (ISC_R_SUCCESS
);
4076 if (tempname
!= NULL
)
4077 dns_message_puttempname(message
, &tempname
);
4078 if (temprdataset
!= NULL
)
4079 dns_message_puttemprdataset(message
, &temprdataset
);
4080 if (message
!= NULL
)
4081 dns_message_destroy(&message
);
4086 dns_zone_notifyreceive(dns_zone_t
*zone
, isc_sockaddr_t
*from
,
4090 dns_rdata_soa_t soa
;
4091 dns_rdataset_t
*rdataset
= NULL
;
4092 dns_rdata_t rdata
= DNS_RDATA_INIT
;
4093 isc_result_t result
;
4094 char fromtext
[ISC_SOCKADDR_FORMATSIZE
];
4096 isc_netaddr_t netaddr
;
4098 REQUIRE(DNS_ZONE_VALID(zone
));
4101 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
4105 * Check that 'from' is a valid notify source, (zone->masters).
4106 * Return DNS_R_REFUSED if not.
4108 * If the notify message contains a serial number check it
4109 * against the zones serial and return if <= current serial
4111 * If a refresh check is progress, if so just record the
4112 * fact we received a NOTIFY and from where and return.
4113 * We will perform a new refresh check when the current one
4114 * completes. Return ISC_R_SUCCESS.
4116 * Otherwise initiate a refresh check using 'from' as the
4117 * first address to check. Return ISC_R_SUCCESS.
4120 isc_sockaddr_format(from
, fromtext
, sizeof(fromtext
));
4123 * We only handle NOTIFY (SOA) at the present.
4126 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0 ||
4127 dns_message_findname(msg
, DNS_SECTION_QUESTION
, &zone
->origin
,
4128 dns_rdatatype_soa
, dns_rdatatype_none
,
4129 NULL
, NULL
) != ISC_R_SUCCESS
) {
4131 if (msg
->counts
[DNS_SECTION_QUESTION
] == 0) {
4132 dns_zone_log(zone
, ISC_LOG_NOTICE
,
4134 "question section from: %s", fromtext
);
4135 return (DNS_R_FORMERR
);
4137 dns_zone_log(zone
, ISC_LOG_NOTICE
,
4138 "NOTIFY zone does not match");
4139 return (DNS_R_NOTIMP
);
4143 * If we are a master zone just succeed.
4145 if (zone
->type
== dns_zone_master
) {
4147 return (ISC_R_SUCCESS
);
4150 isc_netaddr_fromsockaddr(&netaddr
, from
);
4151 for (i
= 0; i
< zone
->masterscnt
; i
++) {
4152 if (isc_sockaddr_eqaddr(from
, &zone
->masters
[i
]))
4154 if (zone
->view
->aclenv
.match_mapped
&&
4155 IN6_IS_ADDR_V4MAPPED(&from
->type
.sin6
.sin6_addr
) &&
4156 isc_sockaddr_pf(&zone
->masters
[i
]) == AF_INET
) {
4157 isc_netaddr_t na1
, na2
;
4158 isc_netaddr_fromv4mapped(&na1
, &netaddr
);
4159 isc_netaddr_fromsockaddr(&na2
, &zone
->masters
[i
]);
4160 if (isc_netaddr_equal(&na1
, &na2
))
4166 * Accept notify requests from non masters if they are on
4167 * 'zone->notify_acl'.
4169 if (i
>= zone
->masterscnt
&& zone
->notify_acl
!= NULL
&&
4170 dns_acl_match(&netaddr
, NULL
, zone
->notify_acl
,
4171 &zone
->view
->aclenv
,
4172 &match
, NULL
) == ISC_R_SUCCESS
&&
4175 /* Accept notify. */
4176 } else if (i
>= zone
->masterscnt
) {
4178 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
4179 "refused notify from non-master: %s", fromtext
);
4180 return (DNS_R_REFUSED
);
4184 * If the zone is loaded and there are answers check the serial
4185 * to see if we need to do a refresh. Do not worry about this
4186 * check if we are a dialup zone as we use the notify request
4187 * to trigger a refresh check.
4189 if (msg
->counts
[DNS_SECTION_ANSWER
] > 0 &&
4190 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_LOADED
) &&
4191 !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NOREFRESH
)) {
4192 result
= dns_message_findname(msg
, DNS_SECTION_ANSWER
,
4195 dns_rdatatype_none
, NULL
,
4197 if (result
== ISC_R_SUCCESS
)
4198 result
= dns_rdataset_first(rdataset
);
4199 if (result
== ISC_R_SUCCESS
) {
4200 isc_uint32_t serial
= 0;
4202 dns_rdataset_current(rdataset
, &rdata
);
4203 result
= dns_rdata_tostruct(&rdata
, &soa
, NULL
);
4204 if (result
== ISC_R_SUCCESS
) {
4205 serial
= soa
.serial
;
4206 if (isc_serial_le(serial
, zone
->serial
)) {
4207 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
4209 "zone is up to date",
4212 return (ISC_R_SUCCESS
);
4219 * If we got this far and there was a refresh in progress just
4220 * let it complete. Record where we got the notify from so we
4221 * can perform a refresh check when the current one completes
4223 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
)) {
4224 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
4225 zone
->notifyfrom
= *from
;
4227 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
4228 "notify from %s: refresh in progress, "
4229 "refresh check queued",
4231 return (ISC_R_SUCCESS
);
4233 zone
->notifyfrom
= *from
;
4235 dns_zone_refresh(zone
);
4236 return (ISC_R_SUCCESS
);
4240 dns_zone_setnotifyacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4242 REQUIRE(DNS_ZONE_VALID(zone
));
4245 if (zone
->notify_acl
!= NULL
)
4246 dns_acl_detach(&zone
->notify_acl
);
4247 dns_acl_attach(acl
, &zone
->notify_acl
);
4252 dns_zone_setqueryacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4254 REQUIRE(DNS_ZONE_VALID(zone
));
4257 if (zone
->query_acl
!= NULL
)
4258 dns_acl_detach(&zone
->query_acl
);
4259 dns_acl_attach(acl
, &zone
->query_acl
);
4264 dns_zone_setupdateacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4266 REQUIRE(DNS_ZONE_VALID(zone
));
4269 if (zone
->update_acl
!= NULL
)
4270 dns_acl_detach(&zone
->update_acl
);
4271 dns_acl_attach(acl
, &zone
->update_acl
);
4276 dns_zone_setforwardacl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4278 REQUIRE(DNS_ZONE_VALID(zone
));
4281 if (zone
->forward_acl
!= NULL
)
4282 dns_acl_detach(&zone
->forward_acl
);
4283 dns_acl_attach(acl
, &zone
->forward_acl
);
4288 dns_zone_setxfracl(dns_zone_t
*zone
, dns_acl_t
*acl
) {
4290 REQUIRE(DNS_ZONE_VALID(zone
));
4293 if (zone
->xfr_acl
!= NULL
)
4294 dns_acl_detach(&zone
->xfr_acl
);
4295 dns_acl_attach(acl
, &zone
->xfr_acl
);
4300 dns_zone_getnotifyacl(dns_zone_t
*zone
) {
4302 REQUIRE(DNS_ZONE_VALID(zone
));
4304 return (zone
->notify_acl
);
4308 dns_zone_getqueryacl(dns_zone_t
*zone
) {
4310 REQUIRE(DNS_ZONE_VALID(zone
));
4312 return (zone
->query_acl
);
4316 dns_zone_getupdateacl(dns_zone_t
*zone
) {
4318 REQUIRE(DNS_ZONE_VALID(zone
));
4320 return (zone
->update_acl
);
4324 dns_zone_getforwardacl(dns_zone_t
*zone
) {
4326 REQUIRE(DNS_ZONE_VALID(zone
));
4328 return (zone
->forward_acl
);
4332 dns_zone_getxfracl(dns_zone_t
*zone
) {
4334 REQUIRE(DNS_ZONE_VALID(zone
));
4336 return (zone
->xfr_acl
);
4340 dns_zone_clearupdateacl(dns_zone_t
*zone
) {
4342 REQUIRE(DNS_ZONE_VALID(zone
));
4345 if (zone
->update_acl
!= NULL
)
4346 dns_acl_detach(&zone
->update_acl
);
4351 dns_zone_clearforwardacl(dns_zone_t
*zone
) {
4353 REQUIRE(DNS_ZONE_VALID(zone
));
4356 if (zone
->forward_acl
!= NULL
)
4357 dns_acl_detach(&zone
->forward_acl
);
4362 dns_zone_clearnotifyacl(dns_zone_t
*zone
) {
4364 REQUIRE(DNS_ZONE_VALID(zone
));
4367 if (zone
->notify_acl
!= NULL
)
4368 dns_acl_detach(&zone
->notify_acl
);
4373 dns_zone_clearqueryacl(dns_zone_t
*zone
) {
4375 REQUIRE(DNS_ZONE_VALID(zone
));
4378 if (zone
->query_acl
!= NULL
)
4379 dns_acl_detach(&zone
->query_acl
);
4384 dns_zone_clearxfracl(dns_zone_t
*zone
) {
4386 REQUIRE(DNS_ZONE_VALID(zone
));
4389 if (zone
->xfr_acl
!= NULL
)
4390 dns_acl_detach(&zone
->xfr_acl
);
4395 dns_zone_setchecknames(dns_zone_t
*zone
, dns_severity_t severity
) {
4397 REQUIRE(DNS_ZONE_VALID(zone
));
4399 zone
->check_names
= severity
;
4403 dns_zone_getchecknames(dns_zone_t
*zone
) {
4405 REQUIRE(DNS_ZONE_VALID(zone
));
4407 return (zone
->check_names
);
4411 dns_zone_setjournalsize(dns_zone_t
*zone
, isc_int32_t size
) {
4413 REQUIRE(DNS_ZONE_VALID(zone
));
4415 zone
->journalsize
= size
;
4419 dns_zone_getjournalsize(dns_zone_t
*zone
) {
4421 REQUIRE(DNS_ZONE_VALID(zone
));
4423 return (zone
->journalsize
);
4427 zone_tostr(dns_zone_t
*zone
, char *buf
, size_t length
) {
4428 isc_result_t result
= ISC_R_FAILURE
;
4429 isc_buffer_t buffer
;
4431 REQUIRE(buf
!= NULL
);
4432 REQUIRE(length
> 1U);
4435 * Leave space for terminating '\0'.
4437 isc_buffer_init(&buffer
, buf
, length
- 1);
4438 if (dns_name_dynamic(&zone
->origin
))
4439 result
= dns_name_totext(&zone
->origin
, ISC_TRUE
, &buffer
);
4440 if (result
!= ISC_R_SUCCESS
)
4441 isc_buffer_putstr(&buffer
, "<UNKNOWN>");
4443 isc_buffer_putstr(&buffer
, "/");
4444 (void)dns_rdataclass_totext(zone
->rdclass
, &buffer
);
4445 buf
[isc_buffer_usedlength(&buffer
)] = '\0';
4449 notify_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
4452 char namebuf
[1024+32];
4454 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
4457 zone_tostr(zone
, namebuf
, sizeof(namebuf
));
4460 vsnprintf(message
, sizeof message
, fmt
, ap
);
4462 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_NOTIFY
, DNS_LOGMODULE_ZONE
,
4463 level
, "zone %s: %s", namebuf
, message
);
4467 dns_zone_log(dns_zone_t
*zone
, int level
, const char *fmt
, ...) {
4470 char namebuf
[1024+32];
4472 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
4475 zone_tostr(zone
, namebuf
, sizeof(namebuf
));
4478 vsnprintf(message
, sizeof message
, fmt
, ap
);
4480 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
4481 level
, "zone %s: %s", namebuf
, message
);
4485 zone_debuglog(dns_zone_t
*zone
, const char *me
, int debuglevel
,
4486 const char *fmt
, ...)
4490 char namebuf
[1024+32];
4491 int level
= ISC_LOG_DEBUG(debuglevel
);
4493 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
4496 zone_tostr(zone
, namebuf
, sizeof(namebuf
));
4499 vsnprintf(message
, sizeof message
, fmt
, ap
);
4501 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
, DNS_LOGMODULE_ZONE
,
4502 level
, "%s: zone %s: %s", me
, namebuf
, message
);
4506 message_count(dns_message_t
*msg
, dns_section_t section
, dns_rdatatype_t type
)
4508 isc_result_t result
;
4510 dns_rdataset_t
*curr
;
4513 result
= dns_message_firstname(msg
, section
);
4514 while (result
== ISC_R_SUCCESS
) {
4516 dns_message_currentname(msg
, section
, &name
);
4518 for (curr
= ISC_LIST_TAIL(name
->list
); curr
!= NULL
;
4519 curr
= ISC_LIST_PREV(curr
, link
)) {
4520 if (curr
->type
== type
)
4523 result
= dns_message_nextname(msg
, section
);
4530 dns_zone_setmaxxfrin(dns_zone_t
*zone
, isc_uint32_t maxxfrin
) {
4531 REQUIRE(DNS_ZONE_VALID(zone
));
4533 zone
->maxxfrin
= maxxfrin
;
4537 dns_zone_getmaxxfrin(dns_zone_t
*zone
) {
4538 REQUIRE(DNS_ZONE_VALID(zone
));
4540 return (zone
->maxxfrin
);
4544 dns_zone_setmaxxfrout(dns_zone_t
*zone
, isc_uint32_t maxxfrout
) {
4545 REQUIRE(DNS_ZONE_VALID(zone
));
4546 zone
->maxxfrout
= maxxfrout
;
4550 dns_zone_getmaxxfrout(dns_zone_t
*zone
) {
4551 REQUIRE(DNS_ZONE_VALID(zone
));
4553 return (zone
->maxxfrout
);
4556 dns_zonetype_t
dns_zone_gettype(dns_zone_t
*zone
) {
4557 REQUIRE(DNS_ZONE_VALID(zone
));
4559 return (zone
->type
);
4563 dns_zone_getorigin(dns_zone_t
*zone
) {
4564 REQUIRE(DNS_ZONE_VALID(zone
));
4566 return (&zone
->origin
);
4570 dns_zone_settask(dns_zone_t
*zone
, isc_task_t
*task
) {
4571 REQUIRE(DNS_ZONE_VALID(zone
));
4574 if (zone
->task
!= NULL
)
4575 isc_task_detach(&zone
->task
);
4576 isc_task_attach(task
, &zone
->task
);
4577 if (zone
->db
!= NULL
)
4578 dns_db_settask(zone
->db
, zone
->task
);
4583 dns_zone_gettask(dns_zone_t
*zone
, isc_task_t
**target
) {
4584 REQUIRE(DNS_ZONE_VALID(zone
));
4585 isc_task_attach(zone
->task
, target
);
4589 dns_zone_setidlein(dns_zone_t
*zone
, isc_uint32_t idlein
) {
4590 REQUIRE(DNS_ZONE_VALID(zone
));
4593 idlein
= DNS_DEFAULT_IDLEIN
;
4594 zone
->idlein
= idlein
;
4598 dns_zone_getidlein(dns_zone_t
*zone
) {
4599 REQUIRE(DNS_ZONE_VALID(zone
));
4601 return (zone
->idlein
);
4605 dns_zone_setidleout(dns_zone_t
*zone
, isc_uint32_t idleout
) {
4606 REQUIRE(DNS_ZONE_VALID(zone
));
4608 zone
->idleout
= idleout
;
4612 dns_zone_getidleout(dns_zone_t
*zone
) {
4613 REQUIRE(DNS_ZONE_VALID(zone
));
4615 return (zone
->idleout
);
4619 notify_done(isc_task_t
*task
, isc_event_t
*event
) {
4620 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
4621 dns_notify_t
*notify
;
4622 isc_result_t result
;
4623 dns_message_t
*message
= NULL
;
4626 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
4630 notify
= event
->ev_arg
;
4631 REQUIRE(DNS_NOTIFY_VALID(notify
));
4632 INSIST(task
== notify
->zone
->task
);
4634 isc_buffer_init(&buf
, rcode
, sizeof(rcode
));
4635 isc_sockaddr_format(¬ify
->dst
, addrbuf
, sizeof(addrbuf
));
4637 result
= revent
->result
;
4638 if (result
== ISC_R_SUCCESS
)
4639 result
= dns_message_create(notify
->zone
->mctx
,
4640 DNS_MESSAGE_INTENTPARSE
, &message
);
4641 if (result
== ISC_R_SUCCESS
)
4642 result
= dns_request_getresponse(revent
->request
, message
,
4643 DNS_MESSAGEPARSE_PRESERVEORDER
);
4644 if (result
== ISC_R_SUCCESS
)
4645 result
= dns_rcode_totext(message
->rcode
, &buf
);
4646 if (result
== ISC_R_SUCCESS
)
4647 notify_log(notify
->zone
, ISC_LOG_DEBUG(3),
4648 "notify response from %s: %.*s",
4649 addrbuf
, (int)buf
.used
, rcode
);
4651 notify_log(notify
->zone
, ISC_LOG_DEBUG(1),
4652 "notify to %s failed: %s", addrbuf
,
4653 dns_result_totext(result
));
4656 * Old bind's return formerr if they see a soa record. Retry w/o
4657 * the soa if we see a formerr and had sent a SOA.
4659 isc_event_free(&event
);
4660 if ((result
== ISC_R_TIMEDOUT
||
4661 (message
!= NULL
&& message
->rcode
== dns_rcode_formerr
&&
4662 (notify
->flags
& DNS_NOTIFY_NOSOA
) == 0)) &&
4663 notify
->attempt
< 3) {
4664 notify
->flags
|= DNS_NOTIFY_NOSOA
;
4666 dns_request_destroy(¬ify
->request
);
4667 result
= notify_send_queue(notify
);
4668 if (result
!= ISC_R_SUCCESS
)
4669 notify_destroy(notify
, ISC_FALSE
);
4671 if (result
== ISC_R_TIMEDOUT
)
4672 notify_log(notify
->zone
, ISC_LOG_DEBUG(1),
4673 "notify to %s: retries exceeded", addrbuf
);
4674 notify_destroy(notify
, ISC_FALSE
);
4676 if (message
!= NULL
)
4677 dns_message_destroy(&message
);
4681 dns_zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
4682 isc_result_t result
;
4684 REQUIRE(DNS_ZONE_VALID(zone
));
4686 result
= zone_replacedb(zone
, db
, dump
);
4692 zone_replacedb(dns_zone_t
*zone
, dns_db_t
*db
, isc_boolean_t dump
) {
4693 dns_dbversion_t
*ver
;
4694 isc_result_t result
;
4697 * 'zone' locked by caller.
4699 REQUIRE(DNS_ZONE_VALID(zone
));
4700 REQUIRE(LOCKED_ZONE(zone
));
4703 dns_db_currentversion(db
, &ver
);
4706 * The initial version of a slave zone is always dumped;
4707 * subsequent versions may be journalled instead if this
4708 * is enabled in the configuration.
4710 if (zone
->db
!= NULL
&& zone
->journal
!= NULL
&&
4711 zone
->diff_on_reload
) {
4712 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
4713 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
4714 "generating diffs");
4715 result
= dns_db_diff(zone
->mctx
, db
, ver
,
4716 zone
->db
, NULL
/* XXX */,
4718 if (result
!= ISC_R_SUCCESS
)
4721 if (dump
&& zone
->masterfile
!= NULL
) {
4722 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
4723 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
4724 "dumping new zone version");
4725 result
= dns_db_dump(db
, ver
, zone
->masterfile
);
4726 if (result
!= ISC_R_SUCCESS
)
4730 * Update the time the zone was updated, so
4731 * dns_zone_load can avoid loading it when
4732 * the server is reloaded. If isc_time_now
4733 * fails for some reason, all that happens is
4734 * the timestamp is not updated.
4736 (void)isc_time_now(&zone
->loadtime
);
4739 if (dump
&& zone
->journal
!= NULL
) {
4741 * The in-memory database just changed, and
4742 * because 'dump' is set, it didn't change by
4743 * being loaded from disk. Also, we have not
4744 * journalled diffs for this change.
4745 * Therefore, the on-disk journal is missing
4746 * the deltas for this change. Since it can
4747 * no longer be used to bring the zone
4748 * up-to-date, it is useless and should be
4751 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
4752 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
4753 "removing journal file");
4754 (void)remove(zone
->journal
);
4758 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
4760 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
4761 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
4762 "replacing zone database");
4764 if (zone
->db
!= NULL
)
4765 dns_db_detach(&zone
->db
);
4766 dns_db_attach(db
, &zone
->db
);
4767 dns_db_settask(zone
->db
, zone
->task
);
4768 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_LOADED
|DNS_ZONEFLG_NEEDNOTIFY
);
4769 return (ISC_R_SUCCESS
);
4772 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
4777 zone_xfrdone(dns_zone_t
*zone
, isc_result_t result
) {
4780 isc_boolean_t again
= ISC_FALSE
;
4781 unsigned int soacount
;
4782 unsigned int nscount
;
4783 isc_uint32_t serial
, refresh
, retry
, expire
, minimum
;
4784 isc_result_t xfrresult
= result
;
4785 isc_boolean_t free_needed
;
4787 REQUIRE(DNS_ZONE_VALID(zone
));
4789 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
4790 "zone transfer finished: %s", dns_result_totext(result
));
4793 INSIST((zone
->flags
& DNS_ZONEFLG_REFRESH
) != 0);
4794 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_REFRESH
);
4799 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NEEDNOTIFY
);
4801 case DNS_R_UPTODATE
:
4802 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
4804 * Has the zone expired underneath us?
4806 if (zone
->db
== NULL
)
4810 * Update the zone structure's data from the actual
4815 INSIST(zone
->db
!= NULL
);
4816 result
= zone_get_from_db(zone
->db
, &zone
->origin
, &nscount
,
4817 &soacount
, &serial
, &refresh
,
4818 &retry
, &expire
, &minimum
);
4819 if (result
== ISC_R_SUCCESS
) {
4821 dns_zone_log(zone
, ISC_LOG_ERROR
,
4823 "has %d SOA record%s", soacount
,
4824 (soacount
!= 0) ? "s" : "");
4826 dns_zone_log(zone
, ISC_LOG_ERROR
,
4828 "has no NS records");
4829 zone
->serial
= serial
;
4830 zone
->refresh
= RANGE(refresh
, zone
->minrefresh
,
4832 zone
->retry
= RANGE(retry
, zone
->minretry
,
4834 zone
->expire
= RANGE(expire
,
4835 zone
->refresh
+ zone
->retry
,
4837 zone
->minimum
= minimum
;
4838 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_HAVETIMERS
);
4842 * Set our next update/expire times.
4844 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
)) {
4845 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_NEEDREFRESH
);
4846 zone
->refreshtime
= now
;
4847 isc_interval_set(&i
, zone
->expire
, 0);
4848 isc_time_add(&now
, &i
, &zone
->expiretime
);
4850 isc_interval_set(&i
, isc_random_jitter(zone
->refresh
,
4851 zone
->refresh
/ 4), 0);
4852 isc_time_add(&now
, &i
, &zone
->refreshtime
);
4853 isc_interval_set(&i
, zone
->expire
, 0);
4854 isc_time_add(&now
, &i
, &zone
->expiretime
);
4856 if (result
== ISC_R_SUCCESS
&& xfrresult
== ISC_R_SUCCESS
)
4857 dns_zone_log(zone
, ISC_LOG_INFO
,
4858 "transferred serial %u", zone
->serial
);
4861 * This is not neccessary if we just performed a AXFR
4862 * however it is necessary for an IXFR / UPTODATE and
4863 * won't hurt with an AXFR.
4865 if (zone
->masterfile
!= NULL
|| zone
->journal
!= NULL
) {
4866 result
= ISC_R_FAILURE
;
4867 if (zone
->journal
!= NULL
)
4868 result
= isc_file_settime(zone
->journal
, &now
);
4869 if (result
!= ISC_R_SUCCESS
&&
4870 zone
->masterfile
!= NULL
)
4871 result
= isc_file_settime(zone
->masterfile
,
4873 /* Someone removed the file from underneath us! */
4874 if (result
== ISC_R_FILENOTFOUND
&&
4875 zone
->masterfile
!= NULL
)
4876 zone_needdump(zone
, DNS_DUMP_DELAY
);
4877 else if (result
!= ISC_R_SUCCESS
)
4878 dns_zone_log(zone
, ISC_LOG_ERROR
,
4879 "transfer: could not set file "
4880 "modification time of '%s': %s",
4882 dns_result_totext(result
));
4888 /* Force retry with AXFR. */
4889 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
4895 if (zone
->curmaster
>= zone
->masterscnt
)
4896 zone
->curmaster
= 0;
4898 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_REFRESH
);
4903 zone_settimer(zone
, &now
);
4906 * If creating the transfer object failed, zone->xfr is NULL.
4907 * Otherwise, we are called as the done callback of a zone
4908 * transfer object that just entered its shutting-down
4909 * state. Since we are no longer responsible for shutting
4910 * it down, we can detach our reference.
4912 if (zone
->xfr
!= NULL
)
4913 dns_xfrin_detach(&zone
->xfr
);
4916 * This transfer finishing freed up a transfer quota slot.
4917 * Let any other zones waiting for quota have it.
4919 RWLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
4920 ISC_LIST_UNLINK(zone
->zmgr
->xfrin_in_progress
, zone
, statelink
);
4921 zone
->statelist
= NULL
;
4922 zmgr_resume_xfrs(zone
->zmgr
, ISC_FALSE
);
4923 RWUNLOCK(&zone
->zmgr
->rwlock
, isc_rwlocktype_write
);
4926 * Retry with a different server if necessary.
4928 if (again
&& !DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
))
4929 queue_soa_query(zone
);
4931 INSIST(zone
->irefs
> 0);
4933 free_needed
= exit_check(zone
);
4940 zone_loaddone(void *arg
, isc_result_t result
) {
4941 static char me
[] = "zone_loaddone";
4942 dns_load_t
*load
= arg
;
4944 isc_result_t tresult
;
4946 REQUIRE(DNS_LOAD_VALID(load
));
4951 tresult
= dns_db_endload(load
->db
, &load
->callbacks
.add_private
);
4952 if (tresult
!= ISC_R_SUCCESS
&&
4953 (result
== ISC_R_SUCCESS
|| result
== DNS_R_SEENINCLUDE
))
4956 LOCK_ZONE(load
->zone
);
4957 (void)zone_postload(load
->zone
, load
->db
, load
->loadtime
, result
);
4958 zonemgr_putio(&load
->zone
->readio
);
4959 DNS_ZONE_CLRFLAG(load
->zone
, DNS_ZONEFLG_LOADING
);
4960 UNLOCK_ZONE(load
->zone
);
4963 dns_db_detach(&load
->db
);
4964 if (load
->zone
->lctx
!= NULL
)
4965 dns_loadctx_detach(&load
->zone
->lctx
);
4966 dns_zone_idetach(&load
->zone
);
4967 isc_mem_putanddetach(&load
->mctx
, load
, sizeof (*load
));
4971 dns_zone_getssutable(dns_zone_t
*zone
, dns_ssutable_t
**table
) {
4972 REQUIRE(DNS_ZONE_VALID(zone
));
4973 REQUIRE(table
!= NULL
);
4974 REQUIRE(*table
== NULL
);
4977 if (zone
->ssutable
!= NULL
)
4978 dns_ssutable_attach(zone
->ssutable
, table
);
4983 dns_zone_setssutable(dns_zone_t
*zone
, dns_ssutable_t
*table
) {
4984 REQUIRE(DNS_ZONE_VALID(zone
));
4987 if (zone
->ssutable
!= NULL
)
4988 dns_ssutable_detach(&zone
->ssutable
);
4990 dns_ssutable_attach(table
, &zone
->ssutable
);
4995 dns_zone_setsigvalidityinterval(dns_zone_t
*zone
, isc_uint32_t interval
) {
4996 REQUIRE(DNS_ZONE_VALID(zone
));
4998 zone
->sigvalidityinterval
= interval
;
5002 dns_zone_getsigvalidityinterval(dns_zone_t
*zone
) {
5003 REQUIRE(DNS_ZONE_VALID(zone
));
5005 return (zone
->sigvalidityinterval
);
5009 queue_xfrin(dns_zone_t
*zone
) {
5010 const char me
[] = "queue_xfrin";
5011 isc_result_t result
;
5012 dns_zonemgr_t
*zmgr
= zone
->zmgr
;
5016 INSIST(zone
->statelist
== NULL
);
5018 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5019 ISC_LIST_APPEND(zmgr
->waiting_for_xfrin
, zone
, statelink
);
5023 zone
->statelist
= &zmgr
->waiting_for_xfrin
;
5024 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
5025 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5027 if (result
== ISC_R_QUOTA
) {
5028 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
5029 "zone transfer deferred due to quota");
5030 } else if (result
!= ISC_R_SUCCESS
) {
5031 dns_zone_log(zone
, ISC_LOG_ERROR
,
5032 "starting zone transfer: %s",
5033 isc_result_totext(result
));
5038 * This event callback is called when a zone has received
5039 * any necessary zone transfer quota. This is the time
5040 * to go ahead and start the transfer.
5043 got_transfer_quota(isc_task_t
*task
, isc_event_t
*event
) {
5044 isc_result_t result
;
5045 dns_peer_t
*peer
= NULL
;
5046 dns_tsigkey_t
*tsigkey
= NULL
;
5047 char mastertext
[256];
5048 dns_rdatatype_t xfrtype
;
5049 dns_zone_t
*zone
= event
->ev_arg
;
5050 isc_netaddr_t masterip
;
5054 INSIST(task
== zone
->task
);
5056 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_EXITING
)) {
5057 result
= ISC_R_CANCELED
;
5061 isc_sockaddr_format(&zone
->masteraddr
, mastertext
, sizeof(mastertext
));
5063 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
5064 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
,
5068 * Decide whether we should request IXFR or AXFR.
5070 if (zone
->db
== NULL
) {
5071 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
5072 "no database exists yet, "
5073 "requesting AXFR of "
5074 "initial version from %s", mastertext
);
5075 xfrtype
= dns_rdatatype_axfr
;
5076 } else if (dns_zone_isforced(zone
)) {
5077 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
5078 "forced reload, requesting AXFR of "
5079 "initial version from %s", mastertext
);
5080 xfrtype
= dns_rdatatype_axfr
;
5081 } else if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLAG_NOIXFR
)) {
5082 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
5083 "retrying with AXFR from %s due to "
5084 "previous IXFR failure", mastertext
);
5085 xfrtype
= dns_rdatatype_axfr
;
5087 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLAG_NOIXFR
);
5090 isc_boolean_t use_ixfr
= ISC_TRUE
;
5092 dns_peer_getrequestixfr(peer
, &use_ixfr
) ==
5094 ; /* Using peer setting */
5096 use_ixfr
= zone
->view
->requestixfr
;
5098 if (use_ixfr
== ISC_FALSE
) {
5099 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
5101 "requesting AXFR from %s",
5103 xfrtype
= dns_rdatatype_axfr
;
5105 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
5106 "requesting IXFR from %s",
5108 xfrtype
= dns_rdatatype_ixfr
;
5113 * Determine if we should attempt to sign the request with TSIG.
5115 result
= ISC_R_NOTFOUND
;
5117 * First, look for a tsig key in the master statement, then
5118 * try for a server key.
5120 if ((zone
->masterkeynames
!= NULL
) &&
5121 (zone
->masterkeynames
[zone
->curmaster
] != NULL
)) {
5122 dns_view_t
*view
= dns_zone_getview(zone
);
5123 dns_name_t
*keyname
= zone
->masterkeynames
[zone
->curmaster
];
5124 result
= dns_view_gettsig(view
, keyname
, &tsigkey
);
5126 if (tsigkey
== NULL
)
5127 result
= dns_view_getpeertsig(zone
->view
, &masterip
, &tsigkey
);
5129 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
) {
5130 dns_zone_log(zone
, ISC_LOG_ERROR
,
5131 "could not get TSIG key "
5132 "for zone transfer: %s",
5133 isc_result_totext(result
));
5136 result
= dns_xfrin_create(zone
, xfrtype
, &zone
->masteraddr
,
5137 tsigkey
, zone
->mctx
,
5138 zone
->zmgr
->timermgr
, zone
->zmgr
->socketmgr
,
5139 zone
->task
, zone_xfrdone
, &zone
->xfr
);
5142 * Any failure in this function is handled like a failed
5143 * zone transfer. This ensures that we get removed from
5144 * zmgr->xfrin_in_progress.
5146 if (result
!= ISC_R_SUCCESS
)
5147 zone_xfrdone(zone
, result
);
5149 if (tsigkey
!= NULL
)
5150 dns_tsigkey_detach(&tsigkey
);
5152 isc_event_free(&event
);
5156 * Update forwarding support.
5160 forward_destroy(dns_forward_t
*forward
) {
5163 if (forward
->request
!= NULL
)
5164 dns_request_destroy(&forward
->request
);
5165 if (forward
->msgbuf
!= NULL
)
5166 isc_buffer_free(&forward
->msgbuf
);
5167 if (forward
->zone
!= NULL
)
5168 dns_zone_idetach(&forward
->zone
);
5169 isc_mem_putanddetach(&forward
->mctx
, forward
, sizeof (*forward
));
5173 sendtomaster(dns_forward_t
*forward
) {
5174 isc_result_t result
;
5177 LOCK_ZONE(forward
->zone
);
5178 if (forward
->which
>= forward
->zone
->masterscnt
) {
5179 UNLOCK_ZONE(forward
->zone
);
5180 return (ISC_R_NOMORE
);
5183 forward
->addr
= forward
->zone
->masters
[forward
->which
];
5185 * Always use TCP regardless of whether the original update
5187 * XXX The timeout may but a bit small if we are far down a
5188 * transfer graph and the master has to try several masters.
5190 switch (isc_sockaddr_pf(&forward
->addr
)) {
5192 src
= forward
->zone
->xfrsource4
;
5195 src
= forward
->zone
->xfrsource6
;
5198 result
= ISC_R_NOTIMPLEMENTED
;
5201 result
= dns_request_createraw(forward
->zone
->view
->requestmgr
,
5203 &src
, &forward
->addr
,
5204 DNS_REQUESTOPT_TCP
, 15 /* XXX */,
5205 forward
->zone
->task
,
5206 forward_callback
, forward
,
5209 UNLOCK_ZONE(forward
->zone
);
5214 forward_callback(isc_task_t
*task
, isc_event_t
*event
) {
5215 const char me
[] = "forward_callback";
5216 dns_requestevent_t
*revent
= (dns_requestevent_t
*)event
;
5217 dns_message_t
*msg
= NULL
;
5218 char master
[ISC_SOCKADDR_FORMATSIZE
];
5219 isc_result_t result
;
5220 dns_forward_t
*forward
;
5225 forward
= revent
->ev_arg
;
5226 INSIST(DNS_FORWARD_VALID(forward
));
5227 zone
= forward
->zone
;
5228 INSIST(DNS_ZONE_VALID(zone
));
5232 isc_sockaddr_format(&forward
->addr
, master
, sizeof(master
));
5234 if (revent
->result
!= ISC_R_SUCCESS
) {
5235 dns_zone_log(zone
, ISC_LOG_INFO
,
5236 "could not forward dynamic update to %s: %s",
5237 master
, dns_result_totext(revent
->result
));
5241 result
= dns_message_create(zone
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
);
5242 if (result
!= ISC_R_SUCCESS
)
5245 result
= dns_request_getresponse(revent
->request
, msg
,
5246 DNS_MESSAGEPARSE_PRESERVEORDER
|
5247 DNS_MESSAGEPARSE_CLONEBUFFER
);
5248 if (result
!= ISC_R_SUCCESS
)
5251 switch (msg
->rcode
) {
5253 * Pass these rcodes back to client.
5255 case dns_rcode_noerror
:
5256 case dns_rcode_yxdomain
:
5257 case dns_rcode_yxrrset
:
5258 case dns_rcode_nxrrset
:
5259 case dns_rcode_refused
:
5260 case dns_rcode_nxdomain
:
5263 /* These should not occur if the masters/zone are valid. */
5264 case dns_rcode_notzone
:
5265 case dns_rcode_notauth
: {
5269 isc_buffer_init(&rb
, rcode
, sizeof(rcode
));
5270 dns_rcode_totext(msg
->rcode
, &rb
);
5271 dns_zone_log(zone
, ISC_LOG_WARNING
,
5272 "forwarding dynamic update: "
5273 "unexpected response: master %s returned: %.*s",
5274 master
, (int)rb
.used
, rcode
);
5278 /* Try another server for these rcodes. */
5279 case dns_rcode_formerr
:
5280 case dns_rcode_servfail
:
5281 case dns_rcode_notimp
:
5282 case dns_rcode_badvers
:
5288 (forward
->callback
)(forward
->callback_arg
, ISC_R_SUCCESS
, msg
);
5290 dns_request_destroy(&forward
->request
);
5291 forward_destroy(forward
);
5292 isc_event_free(&event
);
5297 dns_message_destroy(&msg
);
5298 isc_event_free(&event
);
5300 dns_request_destroy(&forward
->request
);
5301 result
= sendtomaster(forward
);
5302 if (result
!= ISC_R_SUCCESS
) {
5304 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
5305 "exhausted dynamic update forwarder list");
5306 (forward
->callback
)(forward
->callback_arg
, result
, NULL
);
5307 forward_destroy(forward
);
5312 dns_zone_forwardupdate(dns_zone_t
*zone
, dns_message_t
*msg
,
5313 dns_updatecallback_t callback
, void *callback_arg
)
5315 dns_forward_t
*forward
;
5316 isc_result_t result
;
5319 REQUIRE(DNS_ZONE_VALID(zone
));
5320 REQUIRE(msg
!= NULL
);
5321 REQUIRE(callback
!= NULL
);
5323 forward
= isc_mem_get(zone
->mctx
, sizeof(*forward
));
5324 if (forward
== NULL
)
5325 return (ISC_R_NOMEMORY
);
5327 forward
->request
= NULL
;
5328 forward
->zone
= NULL
;
5329 forward
->msgbuf
= NULL
;
5332 forward
->callback
= callback
;
5333 forward
->callback_arg
= callback_arg
;
5334 forward
->magic
= FORWARD_MAGIC
;
5336 mr
= dns_message_getrawmessage(msg
);
5338 result
= ISC_R_UNEXPECTEDEND
;
5342 result
= isc_buffer_allocate(zone
->mctx
, &forward
->msgbuf
, mr
->length
);
5343 if (result
!= ISC_R_SUCCESS
)
5345 result
= isc_buffer_copyregion(forward
->msgbuf
, mr
);
5346 if (result
!= ISC_R_SUCCESS
)
5349 isc_mem_attach(zone
->mctx
, &forward
->mctx
);
5350 dns_zone_iattach(zone
, &forward
->zone
);
5351 result
= sendtomaster(forward
);
5354 if (result
!= ISC_R_SUCCESS
) {
5355 forward_destroy(forward
);
5361 dns_zone_next(dns_zone_t
*zone
, dns_zone_t
**next
) {
5362 REQUIRE(DNS_ZONE_VALID(zone
));
5363 REQUIRE(next
!= NULL
&& *next
== NULL
);
5365 *next
= ISC_LIST_NEXT(zone
, link
);
5367 return (ISC_R_NOMORE
);
5369 return (ISC_R_SUCCESS
);
5373 dns_zone_first(dns_zonemgr_t
*zmgr
, dns_zone_t
**first
) {
5374 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5375 REQUIRE(first
!= NULL
&& *first
== NULL
);
5377 *first
= ISC_LIST_HEAD(zmgr
->zones
);
5379 return (ISC_R_NOMORE
);
5381 return (ISC_R_SUCCESS
);
5389 dns_zonemgr_create(isc_mem_t
*mctx
, isc_taskmgr_t
*taskmgr
,
5390 isc_timermgr_t
*timermgr
, isc_socketmgr_t
*socketmgr
,
5391 dns_zonemgr_t
**zmgrp
)
5393 dns_zonemgr_t
*zmgr
;
5394 isc_result_t result
;
5395 isc_interval_t interval
;
5397 zmgr
= isc_mem_get(mctx
, sizeof *zmgr
);
5399 return (ISC_R_NOMEMORY
);
5402 isc_mem_attach(mctx
, &zmgr
->mctx
);
5403 zmgr
->taskmgr
= taskmgr
;
5404 zmgr
->timermgr
= timermgr
;
5405 zmgr
->socketmgr
= socketmgr
;
5406 zmgr
->zonetasks
= NULL
;
5409 ISC_LIST_INIT(zmgr
->zones
);
5410 ISC_LIST_INIT(zmgr
->waiting_for_xfrin
);
5411 ISC_LIST_INIT(zmgr
->xfrin_in_progress
);
5412 result
= isc_rwlock_init(&zmgr
->rwlock
, 0, 0);
5413 if (result
!= ISC_R_SUCCESS
) {
5414 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
5415 "isc_rwlock_init() failed: %s",
5416 isc_result_totext(result
));
5417 result
= ISC_R_UNEXPECTED
;
5420 zmgr
->transfersin
= 10;
5421 zmgr
->transfersperns
= 2;
5423 /* Create the zone task pool. */
5424 result
= isc_taskpool_create(taskmgr
, mctx
,
5425 8 /* XXX */, 2, &zmgr
->zonetasks
);
5426 if (result
!= ISC_R_SUCCESS
)
5429 /* Create a single task for queueing of SOA queries. */
5430 result
= isc_task_create(taskmgr
, 1, &zmgr
->task
);
5431 if (result
!= ISC_R_SUCCESS
)
5433 isc_task_setname(zmgr
->task
, "zmgr", zmgr
);
5434 result
= isc_ratelimiter_create(mctx
, timermgr
, zmgr
->task
,
5436 if (result
!= ISC_R_SUCCESS
)
5438 /* default to 20 refresh queries / notifies per second. */
5439 isc_interval_set(&interval
, 0, 1000000000/2);
5440 result
= isc_ratelimiter_setinterval(zmgr
->rl
, &interval
);
5441 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
5442 isc_ratelimiter_setpertic(zmgr
->rl
, 10);
5446 ISC_LIST_INIT(zmgr
->high
);
5447 ISC_LIST_INIT(zmgr
->low
);
5449 result
= isc_mutex_init(&zmgr
->iolock
);
5450 if (result
!= ISC_R_SUCCESS
) {
5451 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
5452 "isc_mutex_init() failed: %s",
5453 isc_result_totext(result
));
5456 zmgr
->magic
= ZONEMGR_MAGIC
;
5459 return (ISC_R_SUCCESS
);
5463 DESTROYLOCK(&zmgr
->iolock
);
5466 isc_ratelimiter_detach(&zmgr
->rl
);
5468 isc_task_detach(&zmgr
->task
);
5470 isc_taskpool_destroy(&zmgr
->zonetasks
);
5472 isc_rwlock_destroy(&zmgr
->rwlock
);
5474 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof *zmgr
);
5475 isc_mem_detach(&mctx
);
5480 dns_zonemgr_managezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
5481 isc_result_t result
;
5483 REQUIRE(DNS_ZONE_VALID(zone
));
5484 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5486 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5488 REQUIRE(zone
->task
== NULL
);
5489 REQUIRE(zone
->timer
== NULL
);
5490 REQUIRE(zone
->zmgr
== NULL
);
5492 isc_taskpool_gettask(zmgr
->zonetasks
,
5493 dns_name_hash(dns_zone_getorigin(zone
),
5498 * Set the task name. The tag will arbitrarily point to one
5499 * of the zones sharing the task (in practice, the one
5500 * to be managed last).
5502 isc_task_setname(zone
->task
, "zone", zone
);
5504 result
= isc_timer_create(zmgr
->timermgr
, isc_timertype_inactive
,
5506 zone
->task
, zone_timer
, zone
,
5508 if (result
!= ISC_R_SUCCESS
)
5511 * The timer "holds" a iref.
5514 INSIST(zone
->irefs
!= 0);
5516 ISC_LIST_APPEND(zmgr
->zones
, zone
, link
);
5523 isc_task_detach(&zone
->task
);
5527 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5532 dns_zonemgr_releasezone(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
5533 isc_boolean_t free_now
= ISC_FALSE
;
5535 REQUIRE(DNS_ZONE_VALID(zone
));
5536 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5537 REQUIRE(zone
->zmgr
== zmgr
);
5539 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5542 ISC_LIST_UNLINK(zmgr
->zones
, zone
, link
);
5545 if (zmgr
->refs
== 0)
5546 free_now
= ISC_TRUE
;
5549 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5553 ENSURE(zone
->zmgr
== NULL
);
5557 dns_zonemgr_attach(dns_zonemgr_t
*source
, dns_zonemgr_t
**target
) {
5558 REQUIRE(DNS_ZONEMGR_VALID(source
));
5559 REQUIRE(target
!= NULL
&& *target
== NULL
);
5561 RWLOCK(&source
->rwlock
, isc_rwlocktype_write
);
5562 REQUIRE(source
->refs
> 0);
5564 INSIST(source
->refs
> 0);
5565 RWUNLOCK(&source
->rwlock
, isc_rwlocktype_write
);
5570 dns_zonemgr_detach(dns_zonemgr_t
**zmgrp
) {
5571 dns_zonemgr_t
*zmgr
;
5572 isc_boolean_t free_now
= ISC_FALSE
;
5574 REQUIRE(zmgrp
!= NULL
);
5576 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5578 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5580 if (zmgr
->refs
== 0)
5581 free_now
= ISC_TRUE
;
5582 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5589 dns_zonemgr_forcemaint(dns_zonemgr_t
*zmgr
) {
5592 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5594 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
5595 for (p
= ISC_LIST_HEAD(zmgr
->zones
);
5597 p
= ISC_LIST_NEXT(p
, link
))
5599 dns_zone_maintenance(p
);
5601 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
5604 * Recent configuration changes may have increased the
5605 * amount of available transfers quota. Make sure any
5606 * transfers currently blocked on quota get started if
5609 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5610 zmgr_resume_xfrs(zmgr
, ISC_TRUE
);
5611 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_write
);
5612 return (ISC_R_SUCCESS
);
5616 dns_zonemgr_shutdown(dns_zonemgr_t
*zmgr
) {
5617 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5619 isc_ratelimiter_shutdown(zmgr
->rl
);
5621 if (zmgr
->task
!= NULL
)
5622 isc_task_destroy(&zmgr
->task
);
5623 if (zmgr
->zonetasks
!= NULL
)
5624 isc_taskpool_destroy(&zmgr
->zonetasks
);
5628 zonemgr_free(dns_zonemgr_t
*zmgr
) {
5631 INSIST(zmgr
->refs
== 0);
5632 INSIST(ISC_LIST_EMPTY(zmgr
->zones
));
5636 DESTROYLOCK(&zmgr
->iolock
);
5637 isc_ratelimiter_detach(&zmgr
->rl
);
5639 isc_rwlock_destroy(&zmgr
->rwlock
);
5641 isc_mem_put(zmgr
->mctx
, zmgr
, sizeof *zmgr
);
5642 isc_mem_detach(&mctx
);
5646 dns_zonemgr_settransfersin(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
5647 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5649 zmgr
->transfersin
= value
;
5653 dns_zonemgr_getttransfersin(dns_zonemgr_t
*zmgr
) {
5654 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5656 return (zmgr
->transfersin
);
5660 dns_zonemgr_settransfersperns(dns_zonemgr_t
*zmgr
, isc_uint32_t value
) {
5661 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5663 zmgr
->transfersperns
= value
;
5667 dns_zonemgr_getttransfersperns(dns_zonemgr_t
*zmgr
) {
5668 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5670 return (zmgr
->transfersperns
);
5674 * Try to start a new incoming zone transfer to fill a quota
5675 * slot that was just vacated.
5678 * The zone manager is locked by the caller.
5681 zmgr_resume_xfrs(dns_zonemgr_t
*zmgr
, isc_boolean_t multi
) {
5685 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
5689 isc_result_t result
;
5690 next
= ISC_LIST_NEXT(zone
, statelink
);
5691 result
= zmgr_start_xfrin_ifquota(zmgr
, zone
);
5692 if (result
== ISC_R_SUCCESS
) {
5696 * We successfully filled the slot. We're done.
5699 } else if (result
== ISC_R_QUOTA
) {
5701 * Not enough quota. This is probably the per-server
5702 * quota, because we usually get called when a unit of
5703 * global quota has just been freed. Try the next
5704 * zone, it may succeed if it uses another master.
5708 dns_zone_log(zone
, ISC_LOG_DEBUG(3),
5709 "starting zone transfer: %s",
5710 isc_result_totext(result
));
5717 * Try to start an incoming zone transfer for 'zone', quota permitting.
5720 * The zone manager is locked by the caller.
5723 * ISC_R_SUCCESS There was enough quota and we attempted to
5724 * start a transfer. zone_xfrdone() has been or will
5726 * ISC_R_QUOTA Not enough quota.
5730 zmgr_start_xfrin_ifquota(dns_zonemgr_t
*zmgr
, dns_zone_t
*zone
) {
5731 dns_peer_t
*peer
= NULL
;
5732 isc_netaddr_t masterip
;
5733 isc_uint32_t nxfrsin
, nxfrsperns
;
5735 isc_uint32_t maxtransfersin
, maxtransfersperns
;
5739 * Find any configured information about the server we'd
5740 * like to transfer this zone from.
5742 isc_netaddr_fromsockaddr(&masterip
, &zone
->masteraddr
);
5743 (void)dns_peerlist_peerbyaddr(zone
->view
->peers
,
5747 * Determine the total maximum number of simultaneous
5748 * transfers allowed, and the maximum for this specific
5751 maxtransfersin
= zmgr
->transfersin
;
5752 maxtransfersperns
= zmgr
->transfersperns
;
5754 (void)dns_peer_gettransfers(peer
, &maxtransfersperns
);
5757 * Count the total number of transfers that are in progress,
5758 * and the number of transfers in progress from this master.
5759 * We linearly scan a list of all transfers; if this turns
5760 * out to be too slow, we could hash on the master address.
5762 nxfrsin
= nxfrsperns
= 0;
5763 for (x
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
5765 x
= ISC_LIST_NEXT(x
, statelink
))
5768 isc_netaddr_fromsockaddr(&xip
, &x
->masteraddr
);
5770 if (isc_netaddr_equal(&xip
, &masterip
))
5774 /* Enforce quota. */
5775 if (nxfrsin
>= maxtransfersin
)
5776 return (ISC_R_QUOTA
);
5778 if (nxfrsperns
>= maxtransfersperns
)
5779 return (ISC_R_QUOTA
);
5782 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
5783 * list and send it an event to let it start the actual transfer in the
5784 * context of its own task.
5786 e
= isc_event_allocate(zmgr
->mctx
, zmgr
,
5787 DNS_EVENT_ZONESTARTXFRIN
,
5788 got_transfer_quota
, zone
,
5789 sizeof(isc_event_t
));
5791 return (ISC_R_NOMEMORY
);
5794 INSIST(zone
->statelist
== &zmgr
->waiting_for_xfrin
);
5795 ISC_LIST_UNLINK(zmgr
->waiting_for_xfrin
, zone
, statelink
);
5796 ISC_LIST_APPEND(zmgr
->xfrin_in_progress
, zone
, statelink
);
5797 zone
->statelist
= &zmgr
->xfrin_in_progress
;
5798 isc_task_send(zone
->task
, &e
);
5801 return (ISC_R_SUCCESS
);
5805 dns_zonemgr_setiolimit(dns_zonemgr_t
*zmgr
, isc_uint32_t iolimit
) {
5807 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5808 REQUIRE(iolimit
> 0);
5810 zmgr
->iolimit
= iolimit
;
5814 dns_zonemgr_getiolimit(dns_zonemgr_t
*zmgr
) {
5816 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5818 return (zmgr
->iolimit
);
5822 * Get permission to request a file handle from the OS.
5823 * An event will be sent to action when one is available.
5824 * There are two queues available (high and low), the high
5825 * queue will be serviced before the low one.
5827 * zonemgr_putio() must be called after the event is delivered to
5832 zonemgr_getio(dns_zonemgr_t
*zmgr
, isc_boolean_t high
,
5833 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
5837 isc_boolean_t queue
;
5839 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5840 REQUIRE(iop
!= NULL
&& *iop
== NULL
);
5842 io
= isc_mem_get(zmgr
->mctx
, sizeof(*io
));
5844 return (ISC_R_NOMEMORY
);
5845 io
->event
= isc_event_allocate(zmgr
->mctx
, task
, DNS_EVENT_IOREADY
,
5846 action
, arg
, sizeof(*io
->event
));
5847 if (io
->event
== NULL
) {
5848 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
5849 return (ISC_R_NOMEMORY
);
5854 isc_task_attach(task
, &io
->task
);
5855 ISC_LINK_INIT(io
, link
);
5856 io
->magic
= IO_MAGIC
;
5858 LOCK(&zmgr
->iolock
);
5860 queue
= ISC_TF(zmgr
->ioactive
> zmgr
->iolimit
);
5863 ISC_LIST_APPEND(zmgr
->high
, io
, link
);
5865 ISC_LIST_APPEND(zmgr
->low
, io
, link
);
5867 UNLOCK(&zmgr
->iolock
);
5871 isc_task_send(io
->task
, &io
->event
);
5873 return (ISC_R_SUCCESS
);
5877 zonemgr_putio(dns_io_t
**iop
) {
5880 dns_zonemgr_t
*zmgr
;
5882 REQUIRE(iop
!= NULL
);
5884 REQUIRE(DNS_IO_VALID(io
));
5888 INSIST(!ISC_LINK_LINKED(io
, link
));
5889 INSIST(io
->event
== NULL
);
5892 isc_task_detach(&io
->task
);
5894 isc_mem_put(zmgr
->mctx
, io
, sizeof(*io
));
5896 LOCK(&zmgr
->iolock
);
5897 INSIST(zmgr
->ioactive
> 0);
5899 next
= HEAD(zmgr
->high
);
5901 next
= HEAD(zmgr
->low
);
5904 ISC_LIST_UNLINK(zmgr
->high
, next
, link
);
5906 ISC_LIST_UNLINK(zmgr
->low
, next
, link
);
5907 INSIST(next
->event
!= NULL
);
5909 UNLOCK(&zmgr
->iolock
);
5911 isc_task_send(next
->task
, &next
->event
);
5915 zonemgr_cancelio(dns_io_t
*io
) {
5916 isc_boolean_t send_event
= ISC_FALSE
;
5918 REQUIRE(DNS_IO_VALID(io
));
5921 * If we are queued to be run then dequeue.
5923 LOCK(&io
->zmgr
->iolock
);
5924 if (ISC_LINK_LINKED(io
, link
)) {
5926 ISC_LIST_UNLINK(io
->zmgr
->high
, io
, link
);
5928 ISC_LIST_UNLINK(io
->zmgr
->low
, io
, link
);
5930 send_event
= ISC_TRUE
;
5931 INSIST(io
->event
!= NULL
);
5933 UNLOCK(&io
->zmgr
->iolock
);
5935 io
->event
->ev_attributes
|= ISC_EVENTATTR_CANCELED
;
5936 isc_task_send(io
->task
, &io
->event
);
5941 zone_saveunique(dns_zone_t
*zone
, const char *path
, const char *templat
) {
5944 isc_result_t result
;
5946 buflen
= strlen(path
) + strlen(templat
) + 2;
5948 buf
= isc_mem_get(zone
->mctx
, buflen
);
5952 result
= isc_file_template(path
, templat
, buf
, buflen
);
5953 if (result
!= ISC_R_SUCCESS
)
5956 result
= isc_file_renameunique(path
, buf
);
5957 if (result
!= ISC_R_SUCCESS
)
5960 dns_zone_log(zone
, ISC_LOG_INFO
, "saved '%s' as '%s'",
5964 isc_mem_put(zone
->mctx
, buf
, buflen
);
5968 /* Hook for ondestroy notifcation from a database. */
5971 dns_zonemgr_dbdestroyed(isc_task_t
*task
, isc_event_t
*event
) {
5972 dns_db_t
*db
= event
->sender
;
5975 isc_event_free(&event
);
5977 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_GENERAL
,
5978 DNS_LOGMODULE_ZONE
, ISC_LOG_DEBUG(3),
5979 "database (%p) destroyed", (void*) db
);
5984 dns_zonemgr_setserialqueryrate(dns_zonemgr_t
*zmgr
, unsigned int value
) {
5985 isc_interval_t interval
;
5987 isc_uint32_t pertic
;
5988 isc_result_t result
;
5990 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
5999 } else if (value
<= 10) {
6001 ns
= 1000000000 / value
;
6005 ns
= (1000000000 / value
) * 10;
6009 isc_interval_set(&interval
, s
, ns
);
6010 result
= isc_ratelimiter_setinterval(zmgr
->rl
, &interval
);
6011 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
6012 isc_ratelimiter_setpertic(zmgr
->rl
, pertic
);
6014 zmgr
->serialqueryrate
= value
;
6018 dns_zonemgr_getserialqueryrate(dns_zonemgr_t
*zmgr
) {
6019 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6021 return (zmgr
->serialqueryrate
);
6025 dns_zone_forcereload(dns_zone_t
*zone
) {
6026 REQUIRE(DNS_ZONE_VALID(zone
));
6029 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_FORCEXFER
);
6031 dns_zone_refresh(zone
);
6035 dns_zone_isforced(dns_zone_t
*zone
) {
6036 REQUIRE(DNS_ZONE_VALID(zone
));
6038 return (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_FORCEXFER
));
6042 dns_zone_setstatistics(dns_zone_t
*zone
, isc_boolean_t on
) {
6043 isc_result_t result
= ISC_R_SUCCESS
;
6047 if (zone
->counters
!= NULL
)
6049 result
= dns_stats_alloccounters(zone
->mctx
, &zone
->counters
);
6051 if (zone
->counters
== NULL
)
6053 dns_stats_freecounters(zone
->mctx
, &zone
->counters
);
6061 dns_zone_getstatscounters(dns_zone_t
*zone
) {
6062 return (zone
->counters
);
6066 dns_zone_dialup(dns_zone_t
*zone
) {
6068 REQUIRE(DNS_ZONE_VALID(zone
));
6070 zone_debuglog(zone
, "dns_zone_dialup", 3,
6071 "notify = %d, refresh = %d",
6072 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
),
6073 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
));
6075 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
))
6076 dns_zone_notify(zone
);
6077 if (zone
->type
!= dns_zone_master
&&
6078 DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_DIALREFRESH
))
6079 dns_zone_refresh(zone
);
6083 dns_zone_setdialup(dns_zone_t
*zone
, dns_dialuptype_t dialup
) {
6084 REQUIRE(DNS_ZONE_VALID(zone
));
6087 DNS_ZONE_CLRFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
|
6088 DNS_ZONEFLG_DIALREFRESH
|
6089 DNS_ZONEFLG_NOREFRESH
);
6091 case dns_dialuptype_no
:
6093 case dns_dialuptype_yes
:
6094 DNS_ZONE_SETFLAG(zone
, (DNS_ZONEFLG_DIALNOTIFY
|
6095 DNS_ZONEFLG_DIALREFRESH
|
6096 DNS_ZONEFLG_NOREFRESH
));
6098 case dns_dialuptype_notify
:
6099 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
6101 case dns_dialuptype_notifypassive
:
6102 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALNOTIFY
);
6103 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
6105 case dns_dialuptype_refresh
:
6106 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_DIALREFRESH
);
6107 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
6109 case dns_dialuptype_passive
:
6110 DNS_ZONE_SETFLAG(zone
, DNS_ZONEFLG_NOREFRESH
);
6119 dns_zonemgr_getcount(dns_zonemgr_t
*zmgr
, int state
) {
6121 unsigned int count
= 0;
6123 REQUIRE(DNS_ZONEMGR_VALID(zmgr
));
6125 RWLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);
6127 case DNS_ZONESTATE_XFERRUNNING
:
6128 for (zone
= ISC_LIST_HEAD(zmgr
->xfrin_in_progress
);
6130 zone
= ISC_LIST_NEXT(zone
, statelink
))
6133 case DNS_ZONESTATE_XFERDEFERRED
:
6134 for (zone
= ISC_LIST_HEAD(zmgr
->waiting_for_xfrin
);
6136 zone
= ISC_LIST_NEXT(zone
, statelink
))
6139 case DNS_ZONESTATE_SOAQUERY
:
6140 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
6142 zone
= ISC_LIST_NEXT(zone
, link
))
6143 if (DNS_ZONE_FLAG(zone
, DNS_ZONEFLG_REFRESH
))
6146 case DNS_ZONESTATE_ANY
:
6147 for (zone
= ISC_LIST_HEAD(zmgr
->zones
);
6149 zone
= ISC_LIST_NEXT(zone
, link
))
6156 RWUNLOCK(&zmgr
->rwlock
, isc_rwlocktype_read
);