2 * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: zone.c,v 1.410.18.55 2008/10/24 01:43:17 tbox Exp $ */
25 #include <isc/mutex.h>
26 #include <isc/print.h>
27 #include <isc/random.h>
28 #include <isc/ratelimiter.h>
29 #include <isc/refcount.h>
30 #include <isc/rwlock.h>
31 #include <isc/serial.h>
32 #include <isc/string.h>
33 #include <isc/taskpool.h>
34 #include <isc/timer.h>
37 #include <dns/acache.h>
40 #include <dns/callbacks.h>
42 #include <dns/dbiterator.h>
43 #include <dns/events.h>
44 #include <dns/journal.h>
46 #include <dns/master.h>
47 #include <dns/masterdump.h>
48 #include <dns/message.h>
51 #include <dns/rcode.h>
52 #include <dns/rdataclass.h>
53 #include <dns/rdatalist.h>
54 #include <dns/rdataset.h>
55 #include <dns/rdatastruct.h>
56 #include <dns/rdatatype.h>
57 #include <dns/request.h>
58 #include <dns/resolver.h>
59 #include <dns/result.h>
60 #include <dns/stats.h>
63 #include <dns/xfrin.h>
66 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
67 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
69 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
70 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
72 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
73 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
75 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
76 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
78 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
79 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
81 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
82 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
84 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
85 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
88 * Ensure 'a' is at least 'min' but not more than 'max'.
90 #define RANGE(a, min, max) \
91 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
96 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
97 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
98 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
100 #ifndef DNS_MAX_EXPIRE
101 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
104 #ifndef DNS_DUMP_DELAY
105 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
108 typedef struct dns_notify dns_notify_t;
109 typedef struct dns_stub dns_stub_t;
110 typedef struct dns_load dns_load_t;
111 typedef struct dns_forward dns_forward_t;
112 typedef struct dns_io dns_io_t;
113 typedef ISC_LIST(dns_io_t) dns_iolist_t;
115 #define DNS_ZONE_CHECKLOCK
116 #ifdef DNS_ZONE_CHECKLOCK
117 #define LOCK_ZONE(z) \
118 do { LOCK(&(z)->lock); \
119 INSIST((z)->locked == ISC_FALSE); \
120 (z)->locked = ISC_TRUE; \
122 #define UNLOCK_ZONE(z) \
123 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
124 #define LOCKED_ZONE(z) ((z)->locked)
126 #define LOCK_ZONE(z) LOCK(&(z)->lock)
127 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
128 #define LOCKED_ZONE(z) ISC_TRUE
131 #ifdef ISC_RWLOCK_USEATOMIC
132 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
133 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
134 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
135 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
137 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
138 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
139 #define ZONEDB_LOCK(l, t) LOCK(l)
140 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
147 #ifdef DNS_ZONE_CHECKLOCK
148 isc_boolean_t locked;
151 isc_refcount_t erefs;
153 #ifdef ISC_RWLOCK_USEATOMIC
158 dns_db_t *db; /* Locked by dblock */
162 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
167 dns_masterformat_t masterformat;
169 isc_int32_t journalsize;
170 dns_rdataclass_t rdclass;
173 unsigned int options;
174 unsigned int db_argc;
176 isc_time_t expiretime;
177 isc_time_t refreshtime;
180 isc_time_t notifytime;
182 isc_uint32_t refresh;
185 isc_uint32_t minimum;
188 isc_uint32_t maxrefresh;
189 isc_uint32_t minrefresh;
190 isc_uint32_t maxretry;
191 isc_uint32_t minretry;
193 isc_sockaddr_t *masters;
194 dns_name_t **masterkeynames;
195 isc_boolean_t *mastersok;
196 unsigned int masterscnt;
197 unsigned int curmaster;
198 isc_sockaddr_t masteraddr;
199 dns_notifytype_t notifytype;
200 isc_sockaddr_t *notify;
201 unsigned int notifycnt;
202 isc_sockaddr_t notifyfrom;
204 isc_sockaddr_t notifysrc4;
205 isc_sockaddr_t notifysrc6;
206 isc_sockaddr_t xfrsource4;
207 isc_sockaddr_t xfrsource6;
208 isc_sockaddr_t altxfrsource4;
209 isc_sockaddr_t altxfrsource6;
210 isc_sockaddr_t sourceaddr;
211 dns_xfrin_ctx_t *xfr; /* task locked */
212 dns_tsigkey_t *tsigkey; /* key used for xfr */
213 /* Access Control Lists */
214 dns_acl_t *update_acl;
215 dns_acl_t *forward_acl;
216 dns_acl_t *notify_acl;
217 dns_acl_t *query_acl;
219 isc_boolean_t update_disabled;
220 isc_boolean_t zero_no_soa_ttl;
221 dns_severity_t check_names;
222 ISC_LIST(dns_notify_t) notifies;
223 dns_request_t *request;
228 isc_uint32_t maxxfrin;
229 isc_uint32_t maxxfrout;
231 isc_uint32_t idleout;
232 isc_event_t ctlevent;
233 dns_ssutable_t *ssutable;
234 isc_uint32_t sigvalidityinterval;
236 dns_acache_t *acache;
237 dns_checkmxfunc_t checkmx;
238 dns_checksrvfunc_t checksrv;
239 dns_checknsfunc_t checkns;
241 * Zones in certain states such as "waiting for zone transfer"
242 * or "zone transfer in progress" are kept on per-state linked lists
243 * in the zone manager using the 'statelink' field. The 'statelist'
244 * field points at the list the zone is currently on. It the zone
245 * is not on any such list, statelist is NULL.
247 ISC_LINK(dns_zone_t) statelink;
248 dns_zonelist_t *statelist;
250 * Optional per-zone statistics counters (NULL if not present).
252 isc_uint64_t *counters;
253 isc_uint32_t notifydelay;
254 dns_isselffunc_t isself;
258 * Serial number for deferred journal compaction.
260 isc_uint32_t compact_serial;
263 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
264 #define DNS_ZONE_SETFLAG(z,f) do { \
265 INSIST(LOCKED_ZONE(z)); \
268 #define DNS_ZONE_CLRFLAG(z,f) do { \
269 INSIST(LOCKED_ZONE(z)); \
270 (z)->flags &= ~(f); \
272 /* XXX MPA these may need to go back into zone.h */
273 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
274 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
275 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
276 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
277 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
278 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
279 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
280 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
281 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
282 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
284 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
286 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
288 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
289 * zone with no masters
291 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
292 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
293 * from SOA (if not set, we
295 * default timer values) */
296 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
297 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
298 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
299 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
300 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
301 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
302 #define DNS_ZONEFLG_FLUSH 0x00200000U
303 #define DNS_ZONEFLG_NOEDNS 0x00400000U
304 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
305 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
306 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
308 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
310 /* Flags for zone_load() */
311 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
316 int refs; /* Locked by rwlock */
317 isc_taskmgr_t * taskmgr;
318 isc_timermgr_t * timermgr;
319 isc_socketmgr_t * socketmgr;
320 isc_taskpool_t * zonetasks;
322 isc_ratelimiter_t * rl;
326 /* Locked by rwlock. */
327 dns_zonelist_t zones;
328 dns_zonelist_t waiting_for_xfrin;
329 dns_zonelist_t xfrin_in_progress;
331 /* Configuration data. */
332 isc_uint32_t transfersin;
333 isc_uint32_t transfersperns;
334 unsigned int serialqueryrate;
336 /* Locked by iolock */
337 isc_uint32_t iolimit;
338 isc_uint32_t ioactive;
352 dns_request_t *request;
355 ISC_LINK(dns_notify_t) link;
358 #define DNS_NOTIFY_NOSOA 0x0001U
361 * dns_stub holds state while performing a 'stub' transfer.
362 * 'db' is the zone's 'db' or a new one if this is the initial
371 dns_dbversion_t *version;
383 dns_rdatacallbacks_t callbacks;
387 * Hold forward state.
393 isc_buffer_t *msgbuf;
394 dns_request_t *request;
397 dns_updatecallback_t callback;
402 * Hold IO request state.
409 ISC_LINK(dns_io_t) link;
413 #define SEND_BUFFER_SIZE 2048
415 static void zone_settimer(dns_zone_t *, isc_time_t *);
416 static void cancel_refresh(dns_zone_t *);
417 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
418 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
419 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
420 ISC_FORMAT_PRINTF(3, 4);
421 static void queue_xfrin(dns_zone_t *zone);
422 static void zone_unload(dns_zone_t *zone);
423 static void zone_expire(dns_zone_t *zone);
424 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
425 static void zone_idetach(dns_zone_t **zonep);
426 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
428 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
429 static inline void zone_detachdb(dns_zone_t *zone);
430 static isc_result_t default_journal(dns_zone_t *zone);
431 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
432 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
433 isc_time_t loadtime, isc_result_t result);
434 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
435 static void zone_shutdown(isc_task_t *, isc_event_t *);
436 static void zone_loaddone(void *arg, isc_result_t result);
437 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
438 isc_time_t loadtime);
441 /* ondestroy example */
442 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
445 static void refresh_callback(isc_task_t *, isc_event_t *);
446 static void stub_callback(isc_task_t *, isc_event_t *);
447 static void queue_soa_query(dns_zone_t *zone);
448 static void soa_query(isc_task_t *, isc_event_t *);
449 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
451 static int message_count(dns_message_t *msg, dns_section_t section,
452 dns_rdatatype_t type);
453 static void notify_cancel(dns_zone_t *zone);
454 static void notify_find_address(dns_notify_t *notify);
455 static void notify_send(dns_notify_t *notify);
456 static isc_result_t notify_createmessage(dns_zone_t *zone,
458 dns_message_t **messagep);
459 static void notify_done(isc_task_t *task, isc_event_t *event);
460 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
461 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
462 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
463 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
465 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
466 static void zonemgr_free(dns_zonemgr_t *zmgr);
467 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
468 isc_task_t *task, isc_taskaction_t action,
469 void *arg, dns_io_t **iop);
470 static void zonemgr_putio(dns_io_t **iop);
471 static void zonemgr_cancelio(dns_io_t *io);
474 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
475 unsigned int *soacount, isc_uint32_t *serial,
476 isc_uint32_t *refresh, isc_uint32_t *retry,
477 isc_uint32_t *expire, isc_uint32_t *minimum,
478 unsigned int *errors);
480 static void zone_freedbargs(dns_zone_t *zone);
481 static void forward_callback(isc_task_t *task, isc_event_t *event);
482 static void zone_saveunique(dns_zone_t *zone, const char *path,
483 const char *templat);
484 static void zone_maintenance(dns_zone_t *zone);
485 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
486 static void dump_done(void *arg, isc_result_t result);
488 #define ENTER zone_debuglog(zone, me, 1, "enter")
490 static const unsigned int dbargc_default = 1;
491 static const char *dbargv_default[] = { "rbt" };
493 #define DNS_ZONE_JITTER_ADD(a, b, c) \
497 _j = isc_random_jitter((b), (b)/4); \
498 isc_interval_set(&_i, _j, 0); \
499 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
500 dns_zone_log(zone, ISC_LOG_WARNING, \
501 "epoch approaching: upgrade required: " \
502 "now + %s failed", #b); \
503 isc_interval_set(&_i, _j/2, 0); \
504 (void)isc_time_add((a), &_i, (c)); \
508 #define DNS_ZONE_TIME_ADD(a, b, c) \
511 isc_interval_set(&_i, (b), 0); \
512 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
513 dns_zone_log(zone, ISC_LOG_WARNING, \
514 "epoch approaching: upgrade required: " \
515 "now + %s failed", #b); \
516 isc_interval_set(&_i, (b)/2, 0); \
517 (void)isc_time_add((a), &_i, (c)); \
522 *** Public functions.
526 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
531 REQUIRE(zonep != NULL && *zonep == NULL);
532 REQUIRE(mctx != NULL);
535 zone = isc_mem_get(mctx, sizeof(*zone));
537 return (ISC_R_NOMEMORY);
540 isc_mem_attach(mctx, &zone->mctx);
542 result = isc_mutex_init(&zone->lock);
543 if (result != ISC_R_SUCCESS)
546 result = ZONEDB_INITLOCK(&zone->dblock);
547 if (result != ISC_R_SUCCESS)
550 /* XXX MPA check that all elements are initialised */
551 #ifdef DNS_ZONE_CHECKLOCK
552 zone->locked = ISC_FALSE;
556 ISC_LINK_INIT(zone, link);
557 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
558 if (result != ISC_R_SUCCESS)
561 dns_name_init(&zone->origin, NULL);
562 zone->masterfile = NULL;
563 zone->masterformat = dns_masterformat_none;
564 zone->keydirectory = NULL;
565 zone->journalsize = -1;
566 zone->journal = NULL;
567 zone->rdclass = dns_rdataclass_none;
568 zone->type = dns_zone_none;
572 zone->db_argv = NULL;
573 isc_time_settoepoch(&zone->expiretime);
574 isc_time_settoepoch(&zone->refreshtime);
575 isc_time_settoepoch(&zone->dumptime);
576 isc_time_settoepoch(&zone->loadtime);
577 zone->notifytime = now;
579 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
580 zone->retry = DNS_ZONE_DEFAULTRETRY;
583 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
584 zone->minrefresh = DNS_ZONE_MINREFRESH;
585 zone->maxretry = DNS_ZONE_MAXRETRY;
586 zone->minretry = DNS_ZONE_MINRETRY;
587 zone->masters = NULL;
588 zone->masterkeynames = NULL;
589 zone->mastersok = NULL;
590 zone->masterscnt = 0;
593 zone->notifytype = dns_notifytype_yes;
596 zone->update_acl = NULL;
597 zone->forward_acl = NULL;
598 zone->notify_acl = NULL;
599 zone->query_acl = NULL;
600 zone->xfr_acl = NULL;
601 zone->update_disabled = ISC_FALSE;
602 zone->zero_no_soa_ttl = ISC_TRUE;
603 zone->check_names = dns_severity_ignore;
604 zone->request = NULL;
608 zone->writeio = NULL;
610 zone->idlein = DNS_DEFAULT_IDLEIN;
611 zone->idleout = DNS_DEFAULT_IDLEOUT;
612 ISC_LIST_INIT(zone->notifies);
613 isc_sockaddr_any(&zone->notifysrc4);
614 isc_sockaddr_any6(&zone->notifysrc6);
615 isc_sockaddr_any(&zone->xfrsource4);
616 isc_sockaddr_any6(&zone->xfrsource6);
617 isc_sockaddr_any(&zone->altxfrsource4);
618 isc_sockaddr_any6(&zone->altxfrsource6);
620 zone->tsigkey = NULL;
621 zone->maxxfrin = MAX_XFER_TIME;
622 zone->maxxfrout = MAX_XFER_TIME;
623 zone->ssutable = NULL;
624 zone->sigvalidityinterval = 30 * 24 * 3600;
627 zone->checkmx = NULL;
628 zone->checksrv = NULL;
629 zone->checkns = NULL;
630 ISC_LINK_INIT(zone, statelink);
631 zone->statelist = NULL;
632 zone->counters = NULL;
633 zone->notifydelay = 5;
635 zone->isselfarg = NULL;
637 zone->magic = ZONE_MAGIC;
639 /* Must be after magic is set. */
640 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
641 if (result != ISC_R_SUCCESS)
644 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
645 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
648 return (ISC_R_SUCCESS);
651 isc_refcount_decrement(&zone->erefs, NULL);
652 isc_refcount_destroy(&zone->erefs);
655 ZONEDB_DESTROYLOCK(&zone->dblock);
658 DESTROYLOCK(&zone->lock);
661 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
666 * Free a zone. Because we require that there be no more
667 * outstanding events or references, no locking is necessary.
670 zone_free(dns_zone_t *zone) {
671 isc_mem_t *mctx = NULL;
673 REQUIRE(DNS_ZONE_VALID(zone));
674 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
675 REQUIRE(zone->irefs == 0);
676 REQUIRE(!LOCKED_ZONE(zone));
677 REQUIRE(zone->timer == NULL);
680 * Managed objects. Order is important.
682 if (zone->request != NULL)
683 dns_request_destroy(&zone->request); /* XXXMPA */
684 INSIST(zone->readio == NULL);
685 INSIST(zone->statelist == NULL);
686 INSIST(zone->writeio == NULL);
688 if (zone->task != NULL)
689 isc_task_detach(&zone->task);
691 dns_zonemgr_releasezone(zone->zmgr, zone);
693 /* Unmanaged objects */
694 if (zone->masterfile != NULL)
695 isc_mem_free(zone->mctx, zone->masterfile);
696 zone->masterfile = NULL;
697 if (zone->keydirectory != NULL)
698 isc_mem_free(zone->mctx, zone->keydirectory);
699 zone->keydirectory = NULL;
700 zone->journalsize = -1;
701 if (zone->journal != NULL)
702 isc_mem_free(zone->mctx, zone->journal);
703 zone->journal = NULL;
704 if (zone->counters != NULL)
705 dns_stats_freecounters(zone->mctx, &zone->counters);
706 if (zone->db != NULL)
708 if (zone->acache != NULL)
709 dns_acache_detach(&zone->acache);
710 zone_freedbargs(zone);
711 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
713 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
715 zone->check_names = dns_severity_ignore;
716 if (zone->update_acl != NULL)
717 dns_acl_detach(&zone->update_acl);
718 if (zone->forward_acl != NULL)
719 dns_acl_detach(&zone->forward_acl);
720 if (zone->notify_acl != NULL)
721 dns_acl_detach(&zone->notify_acl);
722 if (zone->query_acl != NULL)
723 dns_acl_detach(&zone->query_acl);
724 if (zone->xfr_acl != NULL)
725 dns_acl_detach(&zone->xfr_acl);
726 if (dns_name_dynamic(&zone->origin))
727 dns_name_free(&zone->origin, zone->mctx);
728 if (zone->ssutable != NULL)
729 dns_ssutable_detach(&zone->ssutable);
732 ZONEDB_DESTROYLOCK(&zone->dblock);
733 DESTROYLOCK(&zone->lock);
734 isc_refcount_destroy(&zone->erefs);
737 isc_mem_put(mctx, zone, sizeof(*zone));
738 isc_mem_detach(&mctx);
745 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
747 REQUIRE(DNS_ZONE_VALID(zone));
748 REQUIRE(rdclass != dns_rdataclass_none);
754 REQUIRE(zone->rdclass == dns_rdataclass_none ||
755 zone->rdclass == rdclass);
756 zone->rdclass = rdclass;
761 dns_zone_getclass(dns_zone_t *zone){
762 REQUIRE(DNS_ZONE_VALID(zone));
764 return (zone->rdclass);
768 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
769 REQUIRE(DNS_ZONE_VALID(zone));
772 zone->notifytype = notifytype;
780 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
782 REQUIRE(DNS_ZONE_VALID(zone));
783 REQUIRE(type != dns_zone_none);
789 REQUIRE(zone->type == dns_zone_none || zone->type == type);
795 zone_freedbargs(dns_zone_t *zone) {
798 /* Free the old database argument list. */
799 if (zone->db_argv != NULL) {
800 for (i = 0; i < zone->db_argc; i++)
801 isc_mem_free(zone->mctx, zone->db_argv[i]);
802 isc_mem_put(zone->mctx, zone->db_argv,
803 zone->db_argc * sizeof(*zone->db_argv));
806 zone->db_argv = NULL;
810 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
813 isc_result_t result = ISC_R_SUCCESS;
817 REQUIRE(DNS_ZONE_VALID(zone));
818 REQUIRE(argv != NULL && *argv == NULL);
821 size = (zone->db_argc + 1) * sizeof(char *);
822 for (i = 0; i < zone->db_argc; i++)
823 size += strlen(zone->db_argv[i]) + 1;
824 mem = isc_mem_allocate(mctx, size);
828 tmp2 += (zone->db_argc + 1) * sizeof(char *);
829 for (i = 0; i < zone->db_argc; i++) {
831 strcpy(tmp2, zone->db_argv[i]);
832 tmp2 += strlen(tmp2) + 1;
836 result = ISC_R_NOMEMORY;
843 dns_zone_setdbtype(dns_zone_t *zone,
844 unsigned int dbargc, const char * const *dbargv) {
845 isc_result_t result = ISC_R_SUCCESS;
849 REQUIRE(DNS_ZONE_VALID(zone));
850 REQUIRE(dbargc >= 1);
851 REQUIRE(dbargv != NULL);
855 /* Set up a new database argument list. */
856 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
859 for (i = 0; i < dbargc; i++)
861 for (i = 0; i < dbargc; i++) {
862 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
867 /* Free the old list. */
868 zone_freedbargs(zone);
870 zone->db_argc = dbargc;
872 result = ISC_R_SUCCESS;
877 for (i = 0; i < dbargc; i++)
879 isc_mem_free(zone->mctx, new[i]);
880 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
882 result = ISC_R_NOMEMORY;
890 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
891 REQUIRE(DNS_ZONE_VALID(zone));
894 if (zone->view != NULL)
895 dns_view_weakdetach(&zone->view);
896 dns_view_weakattach(view, &zone->view);
902 dns_zone_getview(dns_zone_t *zone) {
903 REQUIRE(DNS_ZONE_VALID(zone));
910 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
913 REQUIRE(DNS_ZONE_VALID(zone));
914 REQUIRE(origin != NULL);
917 if (dns_name_dynamic(&zone->origin)) {
918 dns_name_free(&zone->origin, zone->mctx);
919 dns_name_init(&zone->origin, NULL);
921 result = dns_name_dup(origin, zone->mctx, &zone->origin);
927 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
928 REQUIRE(DNS_ZONE_VALID(zone));
929 REQUIRE(acache != NULL);
932 if (zone->acache != NULL)
933 dns_acache_detach(&zone->acache);
934 dns_acache_attach(acache, &zone->acache);
935 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
936 if (zone->db != NULL) {
940 * If the zone reuses an existing DB, the DB needs to be
941 * set in the acache explicitly. We can safely ignore the
942 * case where the DB is already set. If other error happens,
943 * the acache will not work effectively.
945 result = dns_acache_setdb(acache, zone->db);
946 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
947 UNEXPECTED_ERROR(__FILE__, __LINE__,
948 "dns_acache_setdb() failed: %s",
949 isc_result_totext(result));
952 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
957 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
961 copy = isc_mem_strdup(zone->mctx, value);
963 return (ISC_R_NOMEMORY);
969 isc_mem_free(zone->mctx, *field);
972 return (ISC_R_SUCCESS);
976 dns_zone_setfile(dns_zone_t *zone, const char *file) {
977 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
981 dns_zone_setfile2(dns_zone_t *zone, const char *file,
982 dns_masterformat_t format) {
983 isc_result_t result = ISC_R_SUCCESS;
985 REQUIRE(DNS_ZONE_VALID(zone));
988 result = dns_zone_setstring(zone, &zone->masterfile, file);
989 if (result == ISC_R_SUCCESS) {
990 zone->masterformat = format;
991 result = default_journal(zone);
999 dns_zone_getfile(dns_zone_t *zone) {
1000 REQUIRE(DNS_ZONE_VALID(zone));
1002 return (zone->masterfile);
1006 default_journal(dns_zone_t *zone) {
1007 isc_result_t result;
1010 REQUIRE(DNS_ZONE_VALID(zone));
1011 REQUIRE(LOCKED_ZONE(zone));
1013 if (zone->masterfile != NULL) {
1014 /* Calculate string length including '\0'. */
1015 int len = strlen(zone->masterfile) + sizeof(".jnl");
1016 journal = isc_mem_allocate(zone->mctx, len);
1017 if (journal == NULL)
1018 return (ISC_R_NOMEMORY);
1019 strcpy(journal, zone->masterfile);
1020 strcat(journal, ".jnl");
1024 result = dns_zone_setstring(zone, &zone->journal, journal);
1025 if (journal != NULL)
1026 isc_mem_free(zone->mctx, journal);
1031 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1032 isc_result_t result = ISC_R_SUCCESS;
1034 REQUIRE(DNS_ZONE_VALID(zone));
1037 result = dns_zone_setstring(zone, &zone->journal, journal);
1044 dns_zone_getjournal(dns_zone_t *zone) {
1045 REQUIRE(DNS_ZONE_VALID(zone));
1047 return (zone->journal);
1051 * Return true iff the zone is "dynamic", in the sense that the zone's
1052 * master file (if any) is written by the server, rather than being
1053 * updated manually and read by the server.
1055 * This is true for slave zones, stub zones, and zones that allow
1056 * dynamic updates either by having an update policy ("ssutable")
1057 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1059 static isc_boolean_t
1060 zone_isdynamic(dns_zone_t *zone) {
1061 REQUIRE(DNS_ZONE_VALID(zone));
1063 return (ISC_TF(zone->type == dns_zone_slave ||
1064 zone->type == dns_zone_stub ||
1065 (!zone->update_disabled && zone->ssutable != NULL) ||
1066 (!zone->update_disabled && zone->update_acl != NULL &&
1067 ! (zone->update_acl->length == 1 &&
1068 zone->update_acl->elements[0].negative == ISC_TRUE
1070 zone->update_acl->elements[0].type ==
1071 dns_aclelementtype_any))));
1076 zone_load(dns_zone_t *zone, unsigned int flags) {
1077 isc_result_t result;
1079 isc_time_t loadtime, filetime;
1080 dns_db_t *db = NULL;
1082 REQUIRE(DNS_ZONE_VALID(zone));
1087 INSIST(zone->type != dns_zone_none);
1089 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1090 result = ISC_R_SUCCESS;
1094 if (zone->db != NULL && zone->masterfile == NULL) {
1096 * The zone has no master file configured, but it already
1097 * has a database. It could be the built-in
1098 * version.bind. CH zone, a zone with a persistent
1099 * database being reloaded, or maybe a zone that
1100 * used to have a master file but whose configuration
1101 * was changed so that it no longer has one. Do nothing.
1103 result = ISC_R_SUCCESS;
1107 if (zone->db != NULL && zone_isdynamic(zone)) {
1109 * This is a slave, stub, or dynamically updated
1110 * zone being reloaded. Do nothing - the database
1111 * we already have is guaranteed to be up-to-date.
1113 if (zone->type == dns_zone_master)
1114 result = DNS_R_DYNAMIC;
1116 result = ISC_R_SUCCESS;
1122 * Store the current time before the zone is loaded, so that if the
1123 * file changes between the time of the load and the time that
1124 * zone->loadtime is set, then the file will still be reloaded
1125 * the next time dns_zone_load is called.
1127 TIME_NOW(&loadtime);
1130 * Don't do the load if the file that stores the zone is older
1131 * than the last time the zone was loaded. If the zone has not
1132 * been loaded yet, zone->loadtime will be the epoch.
1134 if (zone->masterfile != NULL) {
1136 * The file is already loaded. If we are just doing a
1137 * "rndc reconfig", we are done.
1139 if (!isc_time_isepoch(&zone->loadtime) &&
1140 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1141 result = ISC_R_SUCCESS;
1145 result = isc_file_getmodtime(zone->masterfile, &filetime);
1146 if (result == ISC_R_SUCCESS) {
1147 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1148 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1149 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1150 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1151 "skipping load: master file "
1152 "older than last load");
1153 result = DNS_R_UPTODATE;
1156 loadtime = filetime;
1160 INSIST(zone->db_argc >= 1);
1163 * Built in zones don't need to be reloaded.
1165 if (zone->type == dns_zone_master &&
1166 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1167 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1168 result = ISC_R_SUCCESS;
1172 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1173 (strcmp(zone->db_argv[0], "rbt") == 0 ||
1174 strcmp(zone->db_argv[0], "rbt64") == 0)) {
1175 if (zone->masterfile == NULL ||
1176 !isc_file_exists(zone->masterfile)) {
1177 if (zone->masterfile != NULL) {
1178 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1181 zone->refreshtime = now;
1182 if (zone->task != NULL)
1183 zone_settimer(zone, &now);
1184 result = ISC_R_SUCCESS;
1189 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1191 result = dns_db_create(zone->mctx, zone->db_argv[0],
1192 &zone->origin, (zone->type == dns_zone_stub) ?
1193 dns_dbtype_stub : dns_dbtype_zone,
1195 zone->db_argc - 1, zone->db_argv + 1,
1198 if (result != ISC_R_SUCCESS) {
1199 dns_zone_log(zone, ISC_LOG_ERROR,
1200 "loading zone: creating database: %s",
1201 isc_result_totext(result));
1204 dns_db_settask(db, zone->task);
1206 if (! dns_db_ispersistent(db)) {
1207 if (zone->masterfile != NULL) {
1208 result = zone_startload(db, zone, loadtime);
1210 result = DNS_R_NOMASTERFILE;
1211 if (zone->type == dns_zone_master) {
1212 dns_zone_log(zone, ISC_LOG_ERROR,
1214 "no master file configured");
1217 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1218 "no master file configured: continuing");
1222 if (result == DNS_R_CONTINUE) {
1223 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1227 result = zone_postload(zone, db, loadtime, result);
1237 dns_zone_load(dns_zone_t *zone) {
1238 return (zone_load(zone, 0));
1242 dns_zone_loadnew(dns_zone_t *zone) {
1243 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1247 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1248 dns_load_t *load = event->ev_arg;
1249 isc_result_t result = ISC_R_SUCCESS;
1250 unsigned int options;
1252 REQUIRE(DNS_LOAD_VALID(load));
1254 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1255 result = ISC_R_CANCELED;
1256 isc_event_free(&event);
1257 if (result == ISC_R_CANCELED)
1260 options = DNS_MASTER_ZONE;
1261 if (load->zone->type == dns_zone_slave)
1262 options |= DNS_MASTER_SLAVE;
1263 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNS))
1264 options |= DNS_MASTER_CHECKNS;
1265 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_FATALNS))
1266 options |= DNS_MASTER_FATALNS;
1267 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMES))
1268 options |= DNS_MASTER_CHECKNAMES;
1269 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1270 options |= DNS_MASTER_CHECKNAMESFAIL;
1271 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMX))
1272 options |= DNS_MASTER_CHECKMX;
1273 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMXFAIL))
1274 options |= DNS_MASTER_CHECKMXFAIL;
1275 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKWILDCARD))
1276 options |= DNS_MASTER_CHECKWILDCARD;
1277 result = dns_master_loadfileinc2(load->zone->masterfile,
1278 dns_db_origin(load->db),
1279 dns_db_origin(load->db),
1280 load->zone->rdclass,
1282 &load->callbacks, task,
1283 zone_loaddone, load,
1284 &load->zone->lctx, load->zone->mctx,
1285 load->zone->masterformat);
1286 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1287 result != DNS_R_SEENINCLUDE)
1292 zone_loaddone(load, result);
1296 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1297 const char me[] = "zone_gotwritehandle";
1298 dns_zone_t *zone = event->ev_arg;
1299 isc_result_t result = ISC_R_SUCCESS;
1300 dns_dbversion_t *version = NULL;
1302 REQUIRE(DNS_ZONE_VALID(zone));
1303 INSIST(task == zone->task);
1306 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1307 result = ISC_R_CANCELED;
1308 isc_event_free(&event);
1309 if (result == ISC_R_CANCELED)
1313 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1314 dns_db_currentversion(zone->db, &version);
1315 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1316 &dns_master_style_default,
1317 zone->masterfile, zone->task, dump_done,
1318 zone, &zone->dctx, zone->masterformat);
1319 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1320 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1322 if (result != DNS_R_CONTINUE)
1327 dump_done(zone, result);
1331 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1333 isc_result_t result;
1334 isc_result_t tresult;
1335 unsigned int options;
1337 options = DNS_MASTER_ZONE;
1338 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1339 options |= DNS_MASTER_MANYERRORS;
1340 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1341 options |= DNS_MASTER_CHECKNS;
1342 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1343 options |= DNS_MASTER_FATALNS;
1344 if (zone->type == dns_zone_slave)
1345 options |= DNS_MASTER_SLAVE;
1346 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1347 options |= DNS_MASTER_CHECKNAMES;
1348 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1349 options |= DNS_MASTER_CHECKNAMESFAIL;
1350 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1351 options |= DNS_MASTER_CHECKMX;
1352 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1353 options |= DNS_MASTER_CHECKMXFAIL;
1354 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1355 options |= DNS_MASTER_CHECKWILDCARD;
1357 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1358 load = isc_mem_get(zone->mctx, sizeof(*load));
1360 return (ISC_R_NOMEMORY);
1365 load->loadtime = loadtime;
1366 load->magic = LOAD_MAGIC;
1368 isc_mem_attach(zone->mctx, &load->mctx);
1369 zone_iattach(zone, &load->zone);
1370 dns_db_attach(db, &load->db);
1371 dns_rdatacallbacks_init(&load->callbacks);
1372 result = dns_db_beginload(db, &load->callbacks.add,
1373 &load->callbacks.add_private);
1374 if (result != ISC_R_SUCCESS)
1376 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1377 zone_gotreadhandle, load,
1379 if (result != ISC_R_SUCCESS) {
1381 * We can't report multiple errors so ignore
1382 * the result of dns_db_endload().
1384 (void)dns_db_endload(load->db,
1385 &load->callbacks.add_private);
1388 result = DNS_R_CONTINUE;
1390 dns_rdatacallbacks_t callbacks;
1392 dns_rdatacallbacks_init(&callbacks);
1393 result = dns_db_beginload(db, &callbacks.add,
1394 &callbacks.add_private);
1395 if (result != ISC_R_SUCCESS)
1397 result = dns_master_loadfile2(zone->masterfile, &zone->origin,
1398 &zone->origin, zone->rdclass,
1399 options, &callbacks, zone->mctx,
1400 zone->masterformat);
1401 tresult = dns_db_endload(db, &callbacks.add_private);
1402 if (result == ISC_R_SUCCESS)
1410 dns_db_detach(&load->db);
1411 zone_idetach(&load->zone);
1412 isc_mem_detach(&load->mctx);
1413 isc_mem_put(zone->mctx, load, sizeof(*load));
1417 static isc_boolean_t
1418 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1421 isc_result_t result;
1422 char ownerbuf[DNS_NAME_FORMATSIZE];
1423 char namebuf[DNS_NAME_FORMATSIZE];
1424 char altbuf[DNS_NAME_FORMATSIZE];
1425 dns_fixedname_t fixed;
1426 dns_name_t *foundname;
1432 if (!dns_name_issubdomain(name, &zone->origin)) {
1433 if (zone->checkmx != NULL)
1434 return ((zone->checkmx)(zone, name, owner));
1438 if (zone->type == dns_zone_master)
1439 level = ISC_LOG_ERROR;
1441 level = ISC_LOG_WARNING;
1443 dns_fixedname_init(&fixed);
1444 foundname = dns_fixedname_name(&fixed);
1446 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1447 0, 0, NULL, foundname, NULL, NULL);
1448 if (result == ISC_R_SUCCESS)
1451 if (result == DNS_R_NXRRSET) {
1452 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1453 0, 0, NULL, foundname, NULL, NULL);
1454 if (result == ISC_R_SUCCESS)
1458 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1459 dns_name_format(name, namebuf, sizeof namebuf);
1460 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1461 result == DNS_R_EMPTYNAME) {
1462 dns_zone_log(zone, level,
1463 "%s/MX '%s' has no address records (A or AAAA)",
1465 /* XXX950 make fatal for 9.5.0. */
1469 if (result == DNS_R_CNAME) {
1470 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1471 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1472 level = ISC_LOG_WARNING;
1473 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1474 dns_zone_log(zone, level,
1475 "%s/MX '%s' is a CNAME (illegal)",
1477 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1480 if (result == DNS_R_DNAME) {
1481 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1482 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1483 level = ISC_LOG_WARNING;
1484 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1485 dns_name_format(foundname, altbuf, sizeof altbuf);
1486 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1487 " '%s' (illegal)", ownerbuf, namebuf,
1490 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1493 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1494 return ((zone->checkmx)(zone, name, owner));
1499 static isc_boolean_t
1500 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1503 isc_result_t result;
1504 char ownerbuf[DNS_NAME_FORMATSIZE];
1505 char namebuf[DNS_NAME_FORMATSIZE];
1506 char altbuf[DNS_NAME_FORMATSIZE];
1507 dns_fixedname_t fixed;
1508 dns_name_t *foundname;
1512 * "." means the services does not exist.
1514 if (dns_name_equal(name, dns_rootname))
1520 if (!dns_name_issubdomain(name, &zone->origin)) {
1521 if (zone->checksrv != NULL)
1522 return ((zone->checksrv)(zone, name, owner));
1526 if (zone->type == dns_zone_master)
1527 level = ISC_LOG_ERROR;
1529 level = ISC_LOG_WARNING;
1531 dns_fixedname_init(&fixed);
1532 foundname = dns_fixedname_name(&fixed);
1534 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1535 0, 0, NULL, foundname, NULL, NULL);
1536 if (result == ISC_R_SUCCESS)
1539 if (result == DNS_R_NXRRSET) {
1540 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1541 0, 0, NULL, foundname, NULL, NULL);
1542 if (result == ISC_R_SUCCESS)
1546 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1547 dns_name_format(name, namebuf, sizeof namebuf);
1548 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1549 result == DNS_R_EMPTYNAME) {
1550 dns_zone_log(zone, level,
1551 "%s/SRV '%s' has no address records (A or AAAA)",
1553 /* XXX950 make fatal for 9.5.0. */
1557 if (result == DNS_R_CNAME) {
1558 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1559 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1560 level = ISC_LOG_WARNING;
1561 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1562 dns_zone_log(zone, level,
1563 "%s/SRV '%s' is a CNAME (illegal)",
1565 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1568 if (result == DNS_R_DNAME) {
1569 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1570 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1571 level = ISC_LOG_WARNING;
1572 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1573 dns_name_format(foundname, altbuf, sizeof altbuf);
1574 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1575 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1578 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1581 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1582 return ((zone->checksrv)(zone, name, owner));
1587 static isc_boolean_t
1588 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1591 isc_boolean_t answer = ISC_TRUE;
1592 isc_result_t result, tresult;
1593 char ownerbuf[DNS_NAME_FORMATSIZE];
1594 char namebuf[DNS_NAME_FORMATSIZE];
1595 char altbuf[DNS_NAME_FORMATSIZE];
1596 dns_fixedname_t fixed;
1597 dns_name_t *foundname;
1599 dns_rdataset_t aaaa;
1605 if (!dns_name_issubdomain(name, &zone->origin)) {
1606 if (zone->checkns != NULL)
1607 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1611 if (zone->type == dns_zone_master)
1612 level = ISC_LOG_ERROR;
1614 level = ISC_LOG_WARNING;
1616 dns_fixedname_init(&fixed);
1617 foundname = dns_fixedname_name(&fixed);
1618 dns_rdataset_init(&a);
1619 dns_rdataset_init(&aaaa);
1621 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1622 DNS_DBFIND_GLUEOK, 0, NULL,
1623 foundname, &a, NULL);
1625 if (result == ISC_R_SUCCESS) {
1626 dns_rdataset_disassociate(&a);
1628 } else if (result == DNS_R_DELEGATION)
1629 dns_rdataset_disassociate(&a);
1631 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1632 result == DNS_R_GLUE) {
1633 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1634 DNS_DBFIND_GLUEOK, 0, NULL,
1635 foundname, &aaaa, NULL);
1636 if (tresult == ISC_R_SUCCESS) {
1637 dns_rdataset_disassociate(&aaaa);
1640 if (tresult == DNS_R_DELEGATION)
1641 dns_rdataset_disassociate(&aaaa);
1642 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1644 * Check glue against child zone.
1646 if (zone->checkns != NULL)
1647 answer = (zone->checkns)(zone, name, owner,
1649 if (dns_rdataset_isassociated(&a))
1650 dns_rdataset_disassociate(&a);
1651 if (dns_rdataset_isassociated(&aaaa))
1652 dns_rdataset_disassociate(&aaaa);
1658 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1659 dns_name_format(name, namebuf, sizeof namebuf);
1660 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1661 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
1663 isc_boolean_t required = ISC_FALSE;
1664 if (dns_name_issubdomain(name, owner)) {
1665 what = "REQUIRED GLUE ";
1666 required = ISC_TRUE;
1667 } else if (result == DNS_R_DELEGATION)
1668 what = "SIBLING GLUE ";
1672 if (result != DNS_R_DELEGATION || required ||
1673 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
1674 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
1675 "address records (A or AAAA)",
1676 ownerbuf, namebuf, what);
1678 * Log missing address record.
1680 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
1681 (void)(zone->checkns)(zone, name, owner,
1683 /* XXX950 make fatal for 9.5.0. */
1684 /* answer = ISC_FALSE; */
1686 } else if (result == DNS_R_CNAME) {
1687 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
1689 /* XXX950 make fatal for 9.5.0. */
1690 /* answer = ISC_FALSE; */
1691 } else if (result == DNS_R_DNAME) {
1692 dns_name_format(foundname, altbuf, sizeof altbuf);
1693 dns_zone_log(zone, level,
1694 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1695 ownerbuf, namebuf, altbuf);
1696 /* XXX950 make fatal for 9.5.0. */
1697 /* answer = ISC_FALSE; */
1700 if (dns_rdataset_isassociated(&a))
1701 dns_rdataset_disassociate(&a);
1702 if (dns_rdataset_isassociated(&aaaa))
1703 dns_rdataset_disassociate(&aaaa);
1707 static isc_boolean_t
1708 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
1709 dns_dbiterator_t *dbiterator = NULL;
1710 dns_dbnode_t *node = NULL;
1711 dns_rdataset_t rdataset;
1712 dns_fixedname_t fixed;
1713 dns_fixedname_t fixedbottom;
1716 dns_rdata_in_srv_t srv;
1720 isc_result_t result;
1721 isc_boolean_t ok = ISC_TRUE;
1723 dns_fixedname_init(&fixed);
1724 name = dns_fixedname_name(&fixed);
1725 dns_fixedname_init(&fixedbottom);
1726 bottom = dns_fixedname_name(&fixedbottom);
1727 dns_rdataset_init(&rdataset);
1728 dns_rdata_init(&rdata);
1730 result = dns_db_createiterator(db, ISC_FALSE, &dbiterator);
1731 if (result != ISC_R_SUCCESS)
1734 result = dns_dbiterator_first(dbiterator);
1735 while (result == ISC_R_SUCCESS) {
1736 result = dns_dbiterator_current(dbiterator, &node, name);
1737 if (result != ISC_R_SUCCESS)
1741 * Is this name visible in the zone?
1743 if (!dns_name_issubdomain(name, &zone->origin) ||
1744 (dns_name_countlabels(bottom) > 0 &&
1745 dns_name_issubdomain(name, bottom)))
1749 * Don't check the NS records at the origin.
1751 if (dns_name_equal(name, &zone->origin))
1754 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
1755 0, 0, &rdataset, NULL);
1756 if (result != ISC_R_SUCCESS)
1759 * Remember bottom of zone.
1761 dns_name_copy(name, bottom, NULL);
1763 result = dns_rdataset_first(&rdataset);
1764 while (result == ISC_R_SUCCESS) {
1765 dns_rdataset_current(&rdataset, &rdata);
1766 result = dns_rdata_tostruct(&rdata, &ns, NULL);
1767 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1768 if (!zone_check_glue(zone, db, &ns.name, name))
1770 dns_rdata_reset(&rdata);
1771 result = dns_rdataset_next(&rdataset);
1773 dns_rdataset_disassociate(&rdataset);
1776 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
1777 0, 0, &rdataset, NULL);
1778 if (result != ISC_R_SUCCESS)
1780 result = dns_rdataset_first(&rdataset);
1781 while (result == ISC_R_SUCCESS) {
1782 dns_rdataset_current(&rdataset, &rdata);
1783 result = dns_rdata_tostruct(&rdata, &mx, NULL);
1784 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1785 if (!zone_check_mx(zone, db, &mx.mx, name))
1787 dns_rdata_reset(&rdata);
1788 result = dns_rdataset_next(&rdataset);
1790 dns_rdataset_disassociate(&rdataset);
1793 if (zone->rdclass != dns_rdataclass_in)
1795 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
1796 0, 0, &rdataset, NULL);
1797 if (result != ISC_R_SUCCESS)
1799 result = dns_rdataset_first(&rdataset);
1800 while (result == ISC_R_SUCCESS) {
1801 dns_rdataset_current(&rdataset, &rdata);
1802 result = dns_rdata_tostruct(&rdata, &srv, NULL);
1803 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1804 if (!zone_check_srv(zone, db, &srv.target, name))
1806 dns_rdata_reset(&rdata);
1807 result = dns_rdataset_next(&rdataset);
1809 dns_rdataset_disassociate(&rdataset);
1812 dns_db_detachnode(db, &node);
1813 result = dns_dbiterator_next(dbiterator);
1818 dns_db_detachnode(db, &node);
1819 dns_dbiterator_destroy(&dbiterator);
1825 * OpenSSL verification of RSA keys with exponent 3 is known to be
1826 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
1827 * if they are in use.
1830 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
1831 dns_dbnode_t *node = NULL;
1832 dns_dbversion_t *version = NULL;
1833 dns_rdata_dnskey_t dnskey;
1834 dns_rdata_t rdata = DNS_RDATA_INIT;
1835 dns_rdataset_t rdataset;
1836 isc_result_t result;
1837 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
1838 const char *algorithm;
1840 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
1841 if (result != ISC_R_SUCCESS)
1844 dns_db_currentversion(db, &version);
1845 dns_rdataset_init(&rdataset);
1846 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1847 dns_rdatatype_none, 0, &rdataset, NULL);
1848 if (result != ISC_R_SUCCESS)
1851 for (result = dns_rdataset_first(&rdataset);
1852 result == ISC_R_SUCCESS;
1853 result = dns_rdataset_next(&rdataset))
1855 dns_rdataset_current(&rdataset, &rdata);
1856 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
1857 INSIST(result == ISC_R_SUCCESS);
1859 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
1860 dnskey.algorithm == DST_ALG_RSAMD5) &&
1861 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
1862 dnskey.data[1] == 3)
1864 if (dnskey.algorithm == DST_ALG_RSASHA1) {
1866 foundrsa = ISC_TRUE;
1867 algorithm = "RSASHA1";
1870 foundmd5 = ISC_TRUE;
1871 algorithm = "RSAMD5";
1874 dns_zone_log(zone, ISC_LOG_WARNING,
1875 "weak %s (%u) key found "
1876 "(exponent=3)", algorithm,
1878 if (foundrsa && foundmd5)
1881 dns_rdata_reset(&rdata);
1883 dns_rdataset_disassociate(&rdataset);
1887 dns_db_detachnode(db, &node);
1888 if (version != NULL)
1889 dns_db_closeversion(db, &version, ISC_FALSE);
1894 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
1895 isc_result_t result)
1897 unsigned int soacount = 0;
1898 unsigned int nscount = 0;
1899 unsigned int errors = 0;
1900 isc_uint32_t serial, refresh, retry, expire, minimum;
1902 isc_boolean_t needdump = ISC_FALSE;
1903 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1908 * Initiate zone transfer? We may need a error code that
1909 * indicates that the "permanent" form does not exist.
1910 * XXX better error feedback to log.
1912 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
1913 if (zone->type == dns_zone_slave ||
1914 zone->type == dns_zone_stub) {
1915 if (result == ISC_R_FILENOTFOUND)
1916 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1918 else if (result != DNS_R_NOMASTERFILE)
1919 dns_zone_log(zone, ISC_LOG_ERROR,
1920 "loading from master file %s "
1923 dns_result_totext(result));
1925 dns_zone_log(zone, ISC_LOG_ERROR,
1926 "loading from master file %s failed: %s",
1928 dns_result_totext(result));
1932 dns_zone_log(zone, ISC_LOG_DEBUG(2),
1933 "number of nodes in database: %u",
1934 dns_db_nodecount(db));
1936 if (result == DNS_R_SEENINCLUDE)
1937 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1939 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1942 * Apply update log, if any, on initial load.
1944 if (zone->journal != NULL &&
1945 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
1946 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
1948 result = dns_journal_rollforward(zone->mctx, db,
1950 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
1951 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
1952 result != ISC_R_RANGE) {
1953 dns_zone_log(zone, ISC_LOG_ERROR,
1954 "journal rollforward failed: %s",
1955 dns_result_totext(result));
1958 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
1959 dns_zone_log(zone, ISC_LOG_ERROR,
1960 "journal rollforward failed: "
1961 "journal out of sync with zone");
1964 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1965 "journal rollforward completed "
1967 dns_result_totext(result));
1968 if (result == ISC_R_SUCCESS)
1969 needdump = ISC_TRUE;
1972 zone->loadtime = loadtime;
1974 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded");
1977 * Obtain ns, soa and cname counts for top of zone.
1980 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
1981 &refresh, &retry, &expire, &minimum,
1983 if (result != ISC_R_SUCCESS) {
1984 dns_zone_log(zone, ISC_LOG_ERROR,
1985 "could not find NS and/or SOA records");
1989 * Master / Slave / Stub zones require both NS and SOA records at
1990 * the top of the zone.
1993 switch (zone->type) {
1994 case dns_zone_master:
1995 case dns_zone_slave:
1997 if (soacount != 1) {
1998 dns_zone_log(zone, ISC_LOG_ERROR,
1999 "has %d SOA records", soacount);
2000 result = DNS_R_BADZONE;
2003 dns_zone_log(zone, ISC_LOG_ERROR,
2004 "has no NS records");
2005 result = DNS_R_BADZONE;
2007 if (result != ISC_R_SUCCESS)
2009 if (zone->type == dns_zone_master && errors != 0) {
2010 result = DNS_R_BADZONE;
2013 if (zone->type == dns_zone_master &&
2014 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
2015 !integrity_checks(zone, db)) {
2016 result = DNS_R_BADZONE;
2020 if (zone->db != NULL) {
2022 * This is checked in zone_replacedb() for slave zones
2023 * as they don't reload from disk.
2025 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
2026 !isc_serial_gt(serial, zone->serial)) {
2027 isc_uint32_t serialmin, serialmax;
2029 INSIST(zone->type == dns_zone_master);
2031 serialmin = (zone->serial + 1) & 0xffffffffU;
2032 serialmax = (zone->serial + 0x7fffffffU) &
2034 dns_zone_log(zone, ISC_LOG_ERROR,
2035 "ixfr-from-differences: "
2036 "new serial (%u) out of range "
2037 "[%u - %u]", serial, serialmin,
2039 result = DNS_R_BADZONE;
2041 } else if (!isc_serial_ge(serial, zone->serial))
2042 dns_zone_log(zone, ISC_LOG_ERROR,
2043 "zone serial has gone backwards");
2044 else if (serial == zone->serial && !hasinclude)
2045 dns_zone_log(zone, ISC_LOG_ERROR,
2046 "zone serial unchanged. "
2047 "zone may fail to transfer "
2050 zone->serial = serial;
2051 zone->refresh = RANGE(refresh,
2052 zone->minrefresh, zone->maxrefresh);
2053 zone->retry = RANGE(retry,
2054 zone->minretry, zone->maxretry);
2055 zone->expire = RANGE(expire, zone->refresh + zone->retry,
2057 zone->minimum = minimum;
2058 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
2060 if (zone->type == dns_zone_slave ||
2061 zone->type == dns_zone_stub) {
2065 result = isc_file_getmodtime(zone->journal, &t);
2066 if (result != ISC_R_SUCCESS)
2067 result = isc_file_getmodtime(zone->masterfile,
2069 if (result == ISC_R_SUCCESS)
2070 DNS_ZONE_TIME_ADD(&t, zone->expire,
2073 DNS_ZONE_TIME_ADD(&now, zone->retry,
2076 delay = isc_random_jitter(zone->retry,
2077 (zone->retry * 3) / 4);
2078 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
2079 if (isc_time_compare(&zone->refreshtime,
2080 &zone->expiretime) >= 0)
2081 zone->refreshtime = now;
2085 UNEXPECTED_ERROR(__FILE__, __LINE__,
2086 "unexpected zone type %d", zone->type);
2087 result = ISC_R_UNEXPECTED;
2092 * Check for weak DNSKEY's.
2094 if (zone->type == dns_zone_master)
2095 zone_check_dnskeys(zone, db);
2098 /* destroy notification example. */
2100 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
2101 DNS_EVENT_DBDESTROYED,
2102 dns_zonemgr_dbdestroyed,
2104 sizeof(isc_event_t));
2105 dns_db_ondestroy(db, zone->task, &e);
2109 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2110 if (zone->db != NULL) {
2111 result = zone_replacedb(zone, db, ISC_FALSE);
2112 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2113 if (result != ISC_R_SUCCESS)
2116 zone_attachdb(zone, db);
2117 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2118 DNS_ZONE_SETFLAG(zone,
2119 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
2121 result = ISC_R_SUCCESS;
2123 zone_needdump(zone, DNS_DUMP_DELAY);
2124 if (zone->task != NULL)
2125 zone_settimer(zone, &now);
2127 if (! dns_db_ispersistent(db))
2128 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s",
2130 dns_db_issecure(db) ? " (signed)" : "");
2135 if (zone->type == dns_zone_slave ||
2136 zone->type == dns_zone_stub) {
2137 if (zone->journal != NULL)
2138 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
2139 if (zone->masterfile != NULL)
2140 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
2142 /* Mark the zone for immediate refresh. */
2143 zone->refreshtime = now;
2144 if (zone->task != NULL)
2145 zone_settimer(zone, &now);
2146 result = ISC_R_SUCCESS;
2151 static isc_boolean_t
2152 exit_check(dns_zone_t *zone) {
2154 REQUIRE(LOCKED_ZONE(zone));
2156 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
2160 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2162 INSIST(isc_refcount_current(&zone->erefs) == 0);
2168 static isc_boolean_t
2169 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
2170 isc_result_t result;
2171 char namebuf[DNS_NAME_FORMATSIZE];
2172 char altbuf[DNS_NAME_FORMATSIZE];
2173 dns_fixedname_t fixed;
2174 dns_name_t *foundname;
2177 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
2180 if (zone->type == dns_zone_master)
2181 level = ISC_LOG_ERROR;
2183 level = ISC_LOG_WARNING;
2185 dns_fixedname_init(&fixed);
2186 foundname = dns_fixedname_name(&fixed);
2188 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2189 0, 0, NULL, foundname, NULL, NULL);
2190 if (result == ISC_R_SUCCESS)
2193 if (result == DNS_R_NXRRSET) {
2194 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2195 0, 0, NULL, foundname, NULL, NULL);
2196 if (result == ISC_R_SUCCESS)
2200 dns_name_format(name, namebuf, sizeof namebuf);
2201 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2202 result == DNS_R_EMPTYNAME) {
2203 dns_zone_log(zone, level,
2204 "NS '%s' has no address records (A or AAAA)",
2206 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2210 if (result == DNS_R_CNAME) {
2211 dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
2213 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2217 if (result == DNS_R_DNAME) {
2218 dns_name_format(foundname, altbuf, sizeof altbuf);
2219 dns_zone_log(zone, level,
2220 "NS '%s' is below a DNAME '%s' (illegal)",
2222 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2230 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
2231 dns_dbversion_t *version, unsigned int *nscount,
2232 unsigned int *errors)
2234 isc_result_t result;
2235 unsigned int count = 0;
2236 unsigned int ecount = 0;
2237 dns_rdataset_t rdataset;
2241 dns_rdataset_init(&rdataset);
2242 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
2243 dns_rdatatype_none, 0, &rdataset, NULL);
2244 if (result == ISC_R_NOTFOUND)
2246 if (result != ISC_R_SUCCESS)
2247 goto invalidate_rdataset;
2249 result = dns_rdataset_first(&rdataset);
2250 while (result == ISC_R_SUCCESS) {
2251 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
2252 (zone->type == dns_zone_master ||
2253 zone->type == dns_zone_slave)) {
2254 dns_rdata_init(&rdata);
2255 dns_rdataset_current(&rdataset, &rdata);
2256 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2257 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2258 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
2259 !zone_check_ns(zone, db, &ns.name))
2263 result = dns_rdataset_next(&rdataset);
2265 dns_rdataset_disassociate(&rdataset);
2268 if (nscount != NULL)
2273 result = ISC_R_SUCCESS;
2275 invalidate_rdataset:
2276 dns_rdataset_invalidate(&rdataset);
2282 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
2283 unsigned int *soacount,
2284 isc_uint32_t *serial, isc_uint32_t *refresh,
2285 isc_uint32_t *retry, isc_uint32_t *expire,
2286 isc_uint32_t *minimum)
2288 isc_result_t result;
2290 dns_rdataset_t rdataset;
2291 dns_rdata_t rdata = DNS_RDATA_INIT;
2292 dns_rdata_soa_t soa;
2294 dns_rdataset_init(&rdataset);
2295 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
2296 dns_rdatatype_none, 0, &rdataset, NULL);
2297 if (result == ISC_R_NOTFOUND) {
2298 if (soacount != NULL)
2302 if (refresh != NULL)
2308 if (minimum != NULL)
2310 result = ISC_R_SUCCESS;
2311 goto invalidate_rdataset;
2313 if (result != ISC_R_SUCCESS)
2314 goto invalidate_rdataset;
2317 result = dns_rdataset_first(&rdataset);
2318 while (result == ISC_R_SUCCESS) {
2319 dns_rdata_init(&rdata);
2320 dns_rdataset_current(&rdataset, &rdata);
2323 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2324 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2327 result = dns_rdataset_next(&rdataset);
2328 dns_rdata_reset(&rdata);
2330 dns_rdataset_disassociate(&rdataset);
2332 if (soacount != NULL)
2337 *serial = soa.serial;
2338 if (refresh != NULL)
2339 *refresh = soa.refresh;
2343 *expire = soa.expire;
2344 if (minimum != NULL)
2345 *minimum = soa.minimum;
2348 result = ISC_R_SUCCESS;
2350 invalidate_rdataset:
2351 dns_rdataset_invalidate(&rdataset);
2357 * zone must be locked.
2360 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
2361 unsigned int *soacount, isc_uint32_t *serial,
2362 isc_uint32_t *refresh, isc_uint32_t *retry,
2363 isc_uint32_t *expire, isc_uint32_t *minimum,
2364 unsigned int *errors)
2366 dns_dbversion_t *version;
2367 isc_result_t result;
2368 isc_result_t answer = ISC_R_SUCCESS;
2371 REQUIRE(db != NULL);
2372 REQUIRE(zone != NULL);
2375 dns_db_currentversion(db, &version);
2378 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2379 if (result != ISC_R_SUCCESS) {
2384 if (nscount != NULL || errors != NULL) {
2385 result = zone_count_ns_rr(zone, db, node, version,
2387 if (result != ISC_R_SUCCESS)
2391 if (soacount != NULL || serial != NULL || refresh != NULL
2392 || retry != NULL || expire != NULL || minimum != NULL) {
2393 result = zone_load_soa_rr(db, node, version, soacount,
2394 serial, refresh, retry, expire,
2396 if (result != ISC_R_SUCCESS)
2400 dns_db_detachnode(db, &node);
2402 dns_db_closeversion(db, &version, ISC_FALSE);
2408 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
2409 REQUIRE(DNS_ZONE_VALID(source));
2410 REQUIRE(target != NULL && *target == NULL);
2411 isc_refcount_increment(&source->erefs, NULL);
2416 dns_zone_detach(dns_zone_t **zonep) {
2419 isc_boolean_t free_now = ISC_FALSE;
2421 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2425 isc_refcount_decrement(&zone->erefs, &refs);
2430 * We just detached the last external reference.
2432 if (zone->task != NULL) {
2434 * This zone is being managed. Post
2435 * its control event and let it clean
2436 * up synchronously in the context of
2439 isc_event_t *ev = &zone->ctlevent;
2440 isc_task_send(zone->task, &ev);
2443 * This zone is not being managed; it has
2444 * no task and can have no outstanding
2445 * events. Free it immediately.
2448 * Unmanaged zones should not have non-null views;
2449 * we have no way of detaching from the view here
2450 * without causing deadlock because this code is called
2451 * with the view already locked.
2453 INSIST(zone->view == NULL);
2454 free_now = ISC_TRUE;
2464 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
2465 REQUIRE(DNS_ZONE_VALID(source));
2466 REQUIRE(target != NULL && *target == NULL);
2468 zone_iattach(source, target);
2469 UNLOCK_ZONE(source);
2473 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
2476 * 'source' locked by caller.
2478 REQUIRE(LOCKED_ZONE(source));
2479 REQUIRE(DNS_ZONE_VALID(source));
2480 REQUIRE(target != NULL && *target == NULL);
2481 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
2483 INSIST(source->irefs != 0);
2488 zone_idetach(dns_zone_t **zonep) {
2492 * 'zone' locked by caller.
2494 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2496 REQUIRE(LOCKED_ZONE(*zonep));
2499 INSIST(zone->irefs > 0);
2501 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
2505 dns_zone_idetach(dns_zone_t **zonep) {
2507 isc_boolean_t free_needed;
2509 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2514 INSIST(zone->irefs > 0);
2516 free_needed = exit_check(zone);
2523 dns_zone_getmctx(dns_zone_t *zone) {
2524 REQUIRE(DNS_ZONE_VALID(zone));
2526 return (zone->mctx);
2530 dns_zone_getmgr(dns_zone_t *zone) {
2531 REQUIRE(DNS_ZONE_VALID(zone));
2533 return (zone->zmgr);
2537 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
2538 REQUIRE(DNS_ZONE_VALID(zone));
2542 DNS_ZONE_SETFLAG(zone, flags);
2544 DNS_ZONE_CLRFLAG(zone, flags);
2549 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
2551 REQUIRE(DNS_ZONE_VALID(zone));
2555 zone->options |= option;
2557 zone->options &= ~option;
2562 dns_zone_getoptions(dns_zone_t *zone) {
2564 REQUIRE(DNS_ZONE_VALID(zone));
2566 return (zone->options);
2570 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
2571 REQUIRE(DNS_ZONE_VALID(zone));
2574 zone->xfrsource4 = *xfrsource;
2577 return (ISC_R_SUCCESS);
2581 dns_zone_getxfrsource4(dns_zone_t *zone) {
2582 REQUIRE(DNS_ZONE_VALID(zone));
2583 return (&zone->xfrsource4);
2587 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
2588 REQUIRE(DNS_ZONE_VALID(zone));
2591 zone->xfrsource6 = *xfrsource;
2594 return (ISC_R_SUCCESS);
2598 dns_zone_getxfrsource6(dns_zone_t *zone) {
2599 REQUIRE(DNS_ZONE_VALID(zone));
2600 return (&zone->xfrsource6);
2604 dns_zone_setaltxfrsource4(dns_zone_t *zone,
2605 const isc_sockaddr_t *altxfrsource)
2607 REQUIRE(DNS_ZONE_VALID(zone));
2610 zone->altxfrsource4 = *altxfrsource;
2613 return (ISC_R_SUCCESS);
2617 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
2618 REQUIRE(DNS_ZONE_VALID(zone));
2619 return (&zone->altxfrsource4);
2623 dns_zone_setaltxfrsource6(dns_zone_t *zone,
2624 const isc_sockaddr_t *altxfrsource)
2626 REQUIRE(DNS_ZONE_VALID(zone));
2629 zone->altxfrsource6 = *altxfrsource;
2632 return (ISC_R_SUCCESS);
2636 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
2637 REQUIRE(DNS_ZONE_VALID(zone));
2638 return (&zone->altxfrsource6);
2642 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
2643 REQUIRE(DNS_ZONE_VALID(zone));
2646 zone->notifysrc4 = *notifysrc;
2649 return (ISC_R_SUCCESS);
2653 dns_zone_getnotifysrc4(dns_zone_t *zone) {
2654 REQUIRE(DNS_ZONE_VALID(zone));
2655 return (&zone->notifysrc4);
2659 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
2660 REQUIRE(DNS_ZONE_VALID(zone));
2663 zone->notifysrc6 = *notifysrc;
2666 return (ISC_R_SUCCESS);
2670 dns_zone_getnotifysrc6(dns_zone_t *zone) {
2671 REQUIRE(DNS_ZONE_VALID(zone));
2672 return (&zone->notifysrc6);
2676 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
2679 isc_sockaddr_t *new;
2681 REQUIRE(DNS_ZONE_VALID(zone));
2682 REQUIRE(count == 0 || notify != NULL);
2685 if (zone->notify != NULL) {
2686 isc_mem_put(zone->mctx, zone->notify,
2687 zone->notifycnt * sizeof(*new));
2688 zone->notify = NULL;
2689 zone->notifycnt = 0;
2692 new = isc_mem_get(zone->mctx, count * sizeof(*new));
2695 return (ISC_R_NOMEMORY);
2697 memcpy(new, notify, count * sizeof(*new));
2699 zone->notifycnt = count;
2702 return (ISC_R_SUCCESS);
2706 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
2709 isc_result_t result;
2711 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
2715 static isc_boolean_t
2716 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
2721 for (i = 0; i < count; i++)
2722 if (!isc_sockaddr_equal(&old[i], &new[i]))
2727 static isc_boolean_t
2728 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
2731 if (old == NULL && new == NULL)
2733 if (old == NULL || new == NULL)
2736 for (i = 0; i < count; i++) {
2737 if (old[i] == NULL && new[i] == NULL)
2739 if (old[i] == NULL || new[i] == NULL ||
2740 !dns_name_equal(old[i], new[i]))
2747 dns_zone_setmasterswithkeys(dns_zone_t *zone,
2748 const isc_sockaddr_t *masters,
2749 dns_name_t **keynames,
2752 isc_sockaddr_t *new;
2753 isc_result_t result = ISC_R_SUCCESS;
2754 dns_name_t **newname;
2755 isc_boolean_t *newok;
2758 REQUIRE(DNS_ZONE_VALID(zone));
2759 REQUIRE(count == 0 || masters != NULL);
2760 if (keynames != NULL) {
2761 REQUIRE(count != 0);
2766 * The refresh code assumes that 'masters' wouldn't change under it.
2767 * If it will change then kill off any current refresh in progress
2768 * and update the masters info. If it won't change then we can just
2771 if (count != zone->masterscnt ||
2772 !same_masters(zone->masters, masters, count) ||
2773 !same_keynames(zone->masterkeynames, keynames, count)) {
2774 if (zone->request != NULL)
2775 dns_request_cancel(zone->request);
2778 if (zone->masters != NULL) {
2779 isc_mem_put(zone->mctx, zone->masters,
2780 zone->masterscnt * sizeof(*new));
2781 zone->masters = NULL;
2783 if (zone->masterkeynames != NULL) {
2784 for (i = 0; i < zone->masterscnt; i++) {
2785 if (zone->masterkeynames[i] != NULL) {
2786 dns_name_free(zone->masterkeynames[i],
2788 isc_mem_put(zone->mctx,
2789 zone->masterkeynames[i],
2790 sizeof(dns_name_t));
2791 zone->masterkeynames[i] = NULL;
2794 isc_mem_put(zone->mctx, zone->masterkeynames,
2795 zone->masterscnt * sizeof(dns_name_t *));
2796 zone->masterkeynames = NULL;
2798 if (zone->mastersok != NULL) {
2799 isc_mem_put(zone->mctx, zone->mastersok,
2800 zone->masterscnt * sizeof(isc_boolean_t));
2801 zone->mastersok = NULL;
2803 zone->masterscnt = 0;
2805 * If count == 0, don't allocate any space for masters, mastersok or
2806 * keynames so internally, those pointers are NULL if count == 0
2812 * masters must countain count elements!
2814 new = isc_mem_get(zone->mctx, count * sizeof(*new));
2816 result = ISC_R_NOMEMORY;
2819 memcpy(new, masters, count * sizeof(*new));
2822 * Similarly for mastersok.
2824 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
2825 if (newok == NULL) {
2826 result = ISC_R_NOMEMORY;
2827 isc_mem_put(zone->mctx, new, count * sizeof(*new));
2830 for (i = 0; i < count; i++)
2831 newok[i] = ISC_FALSE;
2834 * if keynames is non-NULL, it must contain count elements!
2837 if (keynames != NULL) {
2838 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
2839 if (newname == NULL) {
2840 result = ISC_R_NOMEMORY;
2841 isc_mem_put(zone->mctx, new, count * sizeof(*new));
2842 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
2845 for (i = 0; i < count; i++)
2847 for (i = 0; i < count; i++) {
2848 if (keynames[i] != NULL) {
2849 newname[i] = isc_mem_get(zone->mctx,
2850 sizeof(dns_name_t));
2851 if (newname[i] == NULL)
2853 dns_name_init(newname[i], NULL);
2854 result = dns_name_dup(keynames[i], zone->mctx,
2856 if (result != ISC_R_SUCCESS) {
2858 for (i = 0; i < count; i++)
2859 if (newname[i] != NULL)
2863 isc_mem_put(zone->mctx, new,
2864 count * sizeof(*new));
2865 isc_mem_put(zone->mctx, newok,
2866 count * sizeof(*newok));
2867 isc_mem_put(zone->mctx, newname,
2868 count * sizeof(*newname));
2876 * Everything is ok so attach to the zone.
2878 zone->masters = new;
2879 zone->mastersok = newok;
2880 zone->masterkeynames = newname;
2881 zone->masterscnt = count;
2882 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
2890 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
2891 isc_result_t result = ISC_R_SUCCESS;
2893 REQUIRE(DNS_ZONE_VALID(zone));
2895 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2896 if (zone->db == NULL)
2897 result = DNS_R_NOTLOADED;
2899 dns_db_attach(zone->db, dpb);
2900 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2906 * Co-ordinates the starting of routine jobs.
2910 dns_zone_maintenance(dns_zone_t *zone) {
2911 const char me[] = "dns_zone_maintenance";
2914 REQUIRE(DNS_ZONE_VALID(zone));
2919 zone_settimer(zone, &now);
2923 static inline isc_boolean_t
2924 was_dumping(dns_zone_t *zone) {
2925 isc_boolean_t dumping;
2927 REQUIRE(LOCKED_ZONE(zone));
2929 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
2930 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
2932 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
2933 isc_time_settoepoch(&zone->dumptime);
2939 zone_maintenance(dns_zone_t *zone) {
2940 const char me[] = "zone_maintenance";
2942 isc_result_t result;
2943 isc_boolean_t dumping;
2945 REQUIRE(DNS_ZONE_VALID(zone));
2949 * Configuring the view of this zone may have
2950 * failed, for example because the config file
2951 * had a syntax error. In that case, the view
2952 * adb or resolver, and we had better not try
2953 * to do maintenance on it.
2955 if (zone->view == NULL || zone->view->adb == NULL)
2963 switch (zone->type) {
2964 case dns_zone_slave:
2967 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
2968 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
2970 zone->refreshtime = now;
2981 switch (zone->type) {
2982 case dns_zone_slave:
2984 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
2985 isc_time_compare(&now, &zone->refreshtime) >= 0)
2986 dns_zone_refresh(zone);
2993 * Do we need to consolidate the backing store?
2995 switch (zone->type) {
2996 case dns_zone_master:
2997 case dns_zone_slave:
2999 if (zone->masterfile != NULL &&
3000 isc_time_compare(&now, &zone->dumptime) >= 0 &&
3001 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
3002 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
3003 dumping = was_dumping(zone);
3008 result = zone_dump(zone, ISC_TRUE); /* task locked */
3009 if (result != ISC_R_SUCCESS)
3010 dns_zone_log(zone, ISC_LOG_WARNING,
3012 dns_result_totext(result));
3020 * Do we need to send out notify messages?
3022 switch (zone->type) {
3023 case dns_zone_master:
3024 case dns_zone_slave:
3025 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
3026 isc_time_compare(&now, &zone->notifytime) >= 0)
3027 zone_notify(zone, &now);
3032 zone_settimer(zone, &now);
3036 dns_zone_markdirty(dns_zone_t *zone) {
3039 zone_needdump(zone, DNS_DUMP_DELAY);
3044 dns_zone_expire(dns_zone_t *zone) {
3045 REQUIRE(DNS_ZONE_VALID(zone));
3053 zone_expire(dns_zone_t *zone) {
3055 * 'zone' locked by caller.
3058 REQUIRE(LOCKED_ZONE(zone));
3060 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
3062 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
3063 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
3064 zone->retry = DNS_ZONE_DEFAULTRETRY;
3065 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
3070 dns_zone_refresh(dns_zone_t *zone) {
3072 isc_uint32_t oldflags;
3074 isc_result_t result;
3076 REQUIRE(DNS_ZONE_VALID(zone));
3078 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
3082 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
3083 * in progress at a time.
3087 oldflags = zone->flags;
3088 if (zone->masterscnt == 0) {
3089 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
3090 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
3091 dns_zone_log(zone, ISC_LOG_ERROR,
3092 "cannot refresh: no masters");
3095 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
3096 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
3097 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
3098 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
3102 * Set the next refresh time as if refresh check has failed.
3103 * Setting this to the retry time will do that. XXXMLG
3104 * If we are successful it will be reset using zone->refresh.
3106 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
3108 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
3109 if (result |= ISC_R_SUCCESS)
3110 dns_zone_log(zone, ISC_LOG_WARNING,
3111 "isc_time_nowplusinterval() failed: %s",
3112 dns_result_totext(result));
3115 * When lacking user-specified timer values from the SOA,
3116 * do exponential backoff of the retry time up to a
3117 * maximum of six hours.
3119 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
3120 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
3122 zone->curmaster = 0;
3123 for (j = 0; j < zone->masterscnt; j++)
3124 zone->mastersok[j] = ISC_FALSE;
3125 /* initiate soa query */
3126 queue_soa_query(zone);
3132 dns_zone_flush(dns_zone_t *zone) {
3133 isc_result_t result = ISC_R_SUCCESS;
3134 isc_boolean_t dumping;
3136 REQUIRE(DNS_ZONE_VALID(zone));
3139 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
3140 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3141 zone->masterfile != NULL) {
3142 result = ISC_R_ALREADYRUNNING;
3143 dumping = was_dumping(zone);
3148 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
3153 dns_zone_dump(dns_zone_t *zone) {
3154 isc_result_t result = ISC_R_ALREADYRUNNING;
3155 isc_boolean_t dumping;
3157 REQUIRE(DNS_ZONE_VALID(zone));
3160 dumping = was_dumping(zone);
3163 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
3168 zone_needdump(dns_zone_t *zone, unsigned int delay) {
3169 isc_time_t dumptime;
3173 * 'zone' locked by caller
3176 REQUIRE(DNS_ZONE_VALID(zone));
3177 REQUIRE(LOCKED_ZONE(zone));
3180 * Do we have a place to dump to and are we loaded?
3182 if (zone->masterfile == NULL ||
3183 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
3187 /* add some noise */
3188 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
3190 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3191 if (isc_time_isepoch(&zone->dumptime) ||
3192 isc_time_compare(&zone->dumptime, &dumptime) > 0)
3193 zone->dumptime = dumptime;
3194 if (zone->task != NULL)
3195 zone_settimer(zone, &now);
3199 dump_done(void *arg, isc_result_t result) {
3200 const char me[] = "dump_done";
3201 dns_zone_t *zone = arg;
3203 dns_dbversion_t *version;
3204 isc_boolean_t again = ISC_FALSE;
3205 isc_boolean_t compact = ISC_FALSE;
3206 isc_uint32_t serial;
3207 isc_result_t tresult;
3209 REQUIRE(DNS_ZONE_VALID(zone));
3213 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
3214 zone->journalsize != -1) {
3217 * We don't own these, zone->dctx must stay valid.
3219 db = dns_dumpctx_db(zone->dctx);
3220 version = dns_dumpctx_version(zone->dctx);
3222 tresult = dns_db_getsoaserial(db, version, &serial);
3224 * Note: we are task locked here so we can test
3227 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
3228 tresult = dns_journal_compact(zone->mctx,
3235 case ISC_R_NOTFOUND:
3236 dns_zone_log(zone, ISC_LOG_DEBUG(3),
3237 "dns_journal_compact: %s",
3238 dns_result_totext(tresult));
3241 dns_zone_log(zone, ISC_LOG_ERROR,
3242 "dns_journal_compact failed: %s",
3243 dns_result_totext(tresult));
3246 } else if (tresult == ISC_R_SUCCESS) {
3248 zone->compact_serial = serial;
3253 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
3255 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
3256 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
3258 * Try again in a short while.
3260 zone_needdump(zone, DNS_DUMP_DELAY);
3261 } else if (result == ISC_R_SUCCESS &&
3262 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
3263 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3264 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3265 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3266 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3267 isc_time_settoepoch(&zone->dumptime);
3269 } else if (result == ISC_R_SUCCESS)
3270 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
3272 if (zone->dctx != NULL)
3273 dns_dumpctx_detach(&zone->dctx);
3274 zonemgr_putio(&zone->writeio);
3277 (void)zone_dump(zone, ISC_FALSE);
3278 dns_zone_idetach(&zone);
3282 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
3283 const char me[] = "zone_dump";
3284 isc_result_t result;
3285 dns_dbversion_t *version = NULL;
3286 isc_boolean_t again;
3287 dns_db_t *db = NULL;
3288 char *masterfile = NULL;
3289 dns_masterformat_t masterformat = dns_masterformat_none;
3292 * 'compact' MUST only be set if we are task locked.
3295 REQUIRE(DNS_ZONE_VALID(zone));
3299 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3300 if (zone->db != NULL)
3301 dns_db_attach(zone->db, &db);
3302 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3304 if (zone->masterfile != NULL) {
3305 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
3306 masterformat = zone->masterformat;
3310 result = DNS_R_NOTLOADED;
3313 if (masterfile == NULL) {
3314 result = DNS_R_NOMASTERFILE;
3319 dns_zone_t *dummy = NULL;
3321 zone_iattach(zone, &dummy);
3322 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
3323 zone_gotwritehandle, zone,
3325 if (result != ISC_R_SUCCESS)
3326 zone_idetach(&dummy);
3328 result = DNS_R_CONTINUE;
3331 dns_db_currentversion(db, &version);
3332 result = dns_master_dump2(zone->mctx, db, version,
3333 &dns_master_style_default,
3334 masterfile, masterformat);
3335 dns_db_closeversion(db, &version, ISC_FALSE);
3340 if (masterfile != NULL)
3341 isc_mem_free(zone->mctx, masterfile);
3344 if (result == DNS_R_CONTINUE)
3345 return (ISC_R_SUCCESS); /* XXXMPA */
3349 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
3350 if (result != ISC_R_SUCCESS) {
3352 * Try again in a short while.
3354 zone_needdump(zone, DNS_DUMP_DELAY);
3355 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
3356 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3357 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3358 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3359 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3360 isc_time_settoepoch(&zone->dumptime);
3363 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
3372 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
3373 dns_masterformat_t format)
3375 isc_result_t result;
3376 dns_dbversion_t *version = NULL;
3377 dns_db_t *db = NULL;
3379 REQUIRE(DNS_ZONE_VALID(zone));
3381 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3382 if (zone->db != NULL)
3383 dns_db_attach(zone->db, &db);
3384 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3386 return (DNS_R_NOTLOADED);
3388 dns_db_currentversion(db, &version);
3389 result = dns_master_dumptostream2(zone->mctx, db, version, style,
3391 dns_db_closeversion(db, &version, ISC_FALSE);
3397 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
3398 const dns_master_style_t *style) {
3399 return dumptostream(zone, fd, style, format);
3403 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
3404 return dumptostream(zone, fd, &dns_master_style_default,
3405 dns_masterformat_text);
3409 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
3410 return dumptostream(zone, fd, &dns_master_style_full,
3411 dns_masterformat_text);
3415 dns_zone_unload(dns_zone_t *zone) {
3416 REQUIRE(DNS_ZONE_VALID(zone));
3424 notify_cancel(dns_zone_t *zone) {
3425 dns_notify_t *notify;
3428 * 'zone' locked by caller.
3431 REQUIRE(LOCKED_ZONE(zone));
3433 for (notify = ISC_LIST_HEAD(zone->notifies);
3435 notify = ISC_LIST_NEXT(notify, link)) {
3436 if (notify->find != NULL)
3437 dns_adb_cancelfind(notify->find);
3438 if (notify->request != NULL)
3439 dns_request_cancel(notify->request);
3444 zone_unload(dns_zone_t *zone) {
3447 * 'zone' locked by caller.
3450 REQUIRE(LOCKED_ZONE(zone));
3452 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
3453 zone_detachdb(zone);
3454 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3455 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
3456 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3460 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
3461 REQUIRE(DNS_ZONE_VALID(zone));
3464 zone->minrefresh = val;
3468 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
3469 REQUIRE(DNS_ZONE_VALID(zone));
3472 zone->maxrefresh = val;
3476 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
3477 REQUIRE(DNS_ZONE_VALID(zone));
3480 zone->minretry = val;
3484 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
3485 REQUIRE(DNS_ZONE_VALID(zone));
3488 zone->maxretry = val;
3491 static isc_boolean_t
3492 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
3493 dns_notify_t *notify;
3495 for (notify = ISC_LIST_HEAD(zone->notifies);
3497 notify = ISC_LIST_NEXT(notify, link)) {
3498 if (notify->request != NULL)
3500 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
3501 dns_name_equal(name, ¬ify->ns))
3503 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
3509 static isc_boolean_t
3510 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
3511 dns_tsigkey_t *key = NULL;
3514 isc_boolean_t isself;
3515 isc_netaddr_t dstaddr;
3517 if (zone->view == NULL || zone->isself == NULL)
3520 switch (isc_sockaddr_pf(dst)) {
3522 src = zone->notifysrc4;
3523 isc_sockaddr_any(&any);
3526 src = zone->notifysrc6;
3527 isc_sockaddr_any6(&any);
3534 * When sending from any the kernel will assign a source address
3535 * that matches the destination address.
3537 if (isc_sockaddr_eqaddr(&any, &src))
3540 isc_netaddr_fromsockaddr(&dstaddr, dst);
3541 (void)dns_view_getpeertsig(zone->view, &dstaddr, &key);
3542 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
3545 dns_tsigkey_detach(&key);
3550 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
3554 * Caller holds zone lock.
3556 REQUIRE(DNS_NOTIFY_VALID(notify));
3558 if (notify->zone != NULL) {
3560 LOCK_ZONE(notify->zone);
3561 REQUIRE(LOCKED_ZONE(notify->zone));
3562 if (ISC_LINK_LINKED(notify, link))
3563 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
3565 UNLOCK_ZONE(notify->zone);
3567 zone_idetach(¬ify->zone);
3569 dns_zone_idetach(¬ify->zone);
3571 if (notify->find != NULL)
3572 dns_adb_destroyfind(¬ify->find);
3573 if (notify->request != NULL)
3574 dns_request_destroy(¬ify->request);
3575 if (dns_name_dynamic(¬ify->ns))
3576 dns_name_free(¬ify->ns, notify->mctx);
3577 mctx = notify->mctx;
3578 isc_mem_put(notify->mctx, notify, sizeof(*notify));
3579 isc_mem_detach(&mctx);
3583 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
3584 dns_notify_t *notify;
3586 REQUIRE(notifyp != NULL && *notifyp == NULL);
3588 notify = isc_mem_get(mctx, sizeof(*notify));
3590 return (ISC_R_NOMEMORY);
3592 notify->mctx = NULL;
3593 isc_mem_attach(mctx, ¬ify->mctx);
3594 notify->flags = flags;
3595 notify->zone = NULL;
3596 notify->find = NULL;
3597 notify->request = NULL;
3598 isc_sockaddr_any(¬ify->dst);
3599 dns_name_init(¬ify->ns, NULL);
3600 ISC_LINK_INIT(notify, link);
3601 notify->magic = NOTIFY_MAGIC;
3603 return (ISC_R_SUCCESS);
3607 * XXXAG should check for DNS_ZONEFLG_EXITING
3610 process_adb_event(isc_task_t *task, isc_event_t *ev) {
3611 dns_notify_t *notify;
3612 isc_eventtype_t result;
3616 notify = ev->ev_arg;
3617 REQUIRE(DNS_NOTIFY_VALID(notify));
3618 INSIST(task == notify->zone->task);
3619 result = ev->ev_type;
3620 isc_event_free(&ev);
3621 if (result == DNS_EVENT_ADBMOREADDRESSES) {
3622 dns_adb_destroyfind(¬ify->find);
3623 notify_find_address(notify);
3626 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
3627 LOCK_ZONE(notify->zone);
3628 notify_send(notify);
3629 UNLOCK_ZONE(notify->zone);
3631 notify_destroy(notify, ISC_FALSE);
3635 notify_find_address(dns_notify_t *notify) {
3636 isc_result_t result;
3637 unsigned int options;
3639 REQUIRE(DNS_NOTIFY_VALID(notify));
3640 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
3641 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
3643 if (notify->zone->view->adb == NULL)
3646 result = dns_adb_createfind(notify->zone->view->adb,
3648 process_adb_event, notify,
3649 ¬ify->ns, dns_rootname, 0,
3651 notify->zone->view->dstport,
3654 /* Something failed? */
3655 if (result != ISC_R_SUCCESS)
3658 /* More addresses pending? */
3659 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
3662 /* We have as many addresses as we can get. */
3663 LOCK_ZONE(notify->zone);
3664 notify_send(notify);
3665 UNLOCK_ZONE(notify->zone);
3668 notify_destroy(notify, ISC_FALSE);
3673 notify_send_queue(dns_notify_t *notify) {
3675 isc_result_t result;
3677 e = isc_event_allocate(notify->mctx, NULL,
3678 DNS_EVENT_NOTIFYSENDTOADDR,
3680 notify, sizeof(isc_event_t));
3682 return (ISC_R_NOMEMORY);
3684 e->ev_sender = NULL;
3685 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
3686 notify->zone->task, &e);
3687 if (result != ISC_R_SUCCESS)
3693 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
3694 dns_notify_t *notify;
3695 isc_result_t result;
3696 dns_message_t *message = NULL;
3697 isc_netaddr_t dstip;
3698 dns_tsigkey_t *key = NULL;
3699 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
3702 isc_boolean_t have_notifysource = ISC_FALSE;
3704 notify = event->ev_arg;
3705 REQUIRE(DNS_NOTIFY_VALID(notify));
3709 LOCK_ZONE(notify->zone);
3711 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
3712 result = ISC_R_CANCELED;
3716 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
3717 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
3718 notify->zone->view->requestmgr == NULL ||
3719 notify->zone->db == NULL) {
3720 result = ISC_R_CANCELED;
3725 * The raw IPv4 address should also exist. Don't send to the
3728 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
3729 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
3730 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
3731 notify_log(notify->zone, ISC_LOG_DEBUG(3),
3732 "notify: ignoring IPv6 mapped IPV4 address: %s",
3734 result = ISC_R_CANCELED;
3738 result = notify_createmessage(notify->zone, notify->flags, &message);
3739 if (result != ISC_R_SUCCESS)
3742 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
3743 (void)dns_view_getpeertsig(notify->zone->view, &dstip, &key);
3745 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
3746 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
3748 if (notify->zone->view->peers != NULL) {
3749 dns_peer_t *peer = NULL;
3750 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
3752 if (result == ISC_R_SUCCESS) {
3753 result = dns_peer_getnotifysource(peer, &src);
3754 if (result == ISC_R_SUCCESS)
3755 have_notifysource = ISC_TRUE;
3758 switch (isc_sockaddr_pf(¬ify->dst)) {
3760 if (!have_notifysource)
3761 src = notify->zone->notifysrc4;
3764 if (!have_notifysource)
3765 src = notify->zone->notifysrc6;
3768 result = ISC_R_NOTIMPLEMENTED;
3772 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
3774 result = dns_request_createvia2(notify->zone->view->requestmgr,
3775 message, &src, ¬ify->dst, 0, key,
3776 timeout * 3, timeout,
3777 notify->zone->task, notify_done,
3778 notify, ¬ify->request);
3781 dns_tsigkey_detach(&key);
3782 dns_message_destroy(&message);
3784 UNLOCK_ZONE(notify->zone);
3785 if (result != ISC_R_SUCCESS)
3786 notify_destroy(notify, ISC_FALSE);
3787 isc_event_free(&event);
3791 notify_send(dns_notify_t *notify) {
3792 dns_adbaddrinfo_t *ai;
3794 isc_result_t result;
3795 dns_notify_t *new = NULL;
3798 * Zone lock held by caller.
3800 REQUIRE(DNS_NOTIFY_VALID(notify));
3801 REQUIRE(LOCKED_ZONE(notify->zone));
3803 for (ai = ISC_LIST_HEAD(notify->find->list);
3805 ai = ISC_LIST_NEXT(ai, publink)) {
3807 if (notify_isqueued(notify->zone, NULL, &dst))
3809 if (notify_isself(notify->zone, &dst))
3812 result = notify_create(notify->mctx,
3813 (notify->flags & DNS_NOTIFY_NOSOA),
3815 if (result != ISC_R_SUCCESS)
3817 zone_iattach(notify->zone, &new->zone);
3818 ISC_LIST_APPEND(new->zone->notifies, new, link);
3820 result = notify_send_queue(new);
3821 if (result != ISC_R_SUCCESS)
3828 notify_destroy(new, ISC_TRUE);
3832 dns_zone_notify(dns_zone_t *zone) {
3835 REQUIRE(DNS_ZONE_VALID(zone));
3838 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
3841 zone_settimer(zone, &now);
3846 zone_notify(dns_zone_t *zone, isc_time_t *now) {
3847 dns_dbnode_t *node = NULL;
3848 dns_db_t *zonedb = NULL;
3849 dns_dbversion_t *version = NULL;
3850 dns_name_t *origin = NULL;
3853 dns_rdata_soa_t soa;
3854 isc_uint32_t serial;
3855 dns_rdata_t rdata = DNS_RDATA_INIT;
3856 dns_rdataset_t nsrdset;
3857 dns_rdataset_t soardset;
3858 isc_result_t result;
3859 dns_notify_t *notify = NULL;
3862 isc_boolean_t isqueued;
3863 dns_notifytype_t notifytype;
3864 unsigned int flags = 0;
3865 isc_boolean_t loggednotify = ISC_FALSE;
3867 REQUIRE(DNS_ZONE_VALID(zone));
3870 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
3871 notifytype = zone->notifytype;
3872 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
3875 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
3878 if (notifytype == dns_notifytype_no)
3881 if (notifytype == dns_notifytype_masteronly &&
3882 zone->type != dns_zone_master)
3885 origin = &zone->origin;
3888 * If the zone is dialup we are done as we don't want to send
3889 * the current soa so as to force a refresh query.
3891 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
3892 flags |= DNS_NOTIFY_NOSOA;
3897 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3898 if (zone->db != NULL)
3899 dns_db_attach(zone->db, &zonedb);
3900 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3903 dns_db_currentversion(zonedb, &version);
3904 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
3905 if (result != ISC_R_SUCCESS)
3908 dns_rdataset_init(&soardset);
3909 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
3910 dns_rdatatype_none, 0, &soardset, NULL);
3911 if (result != ISC_R_SUCCESS)
3915 * Find serial and master server's name.
3917 dns_name_init(&master, NULL);
3918 result = dns_rdataset_first(&soardset);
3919 if (result != ISC_R_SUCCESS)
3921 dns_rdataset_current(&soardset, &rdata);
3922 result = dns_rdata_tostruct(&rdata, &soa, NULL);
3923 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3924 dns_rdata_reset(&rdata);
3925 result = dns_name_dup(&soa.origin, zone->mctx, &master);
3926 serial = soa.serial;
3927 dns_rdataset_disassociate(&soardset);
3928 if (result != ISC_R_SUCCESS)
3932 * Enqueue notify requests for 'also-notify' servers.
3935 for (i = 0; i < zone->notifycnt; i++) {
3936 dst = zone->notify[i];
3937 if (notify_isqueued(zone, NULL, &dst))
3939 result = notify_create(zone->mctx, flags, ¬ify);
3940 if (result != ISC_R_SUCCESS)
3942 zone_iattach(zone, ¬ify->zone);
3944 ISC_LIST_APPEND(zone->notifies, notify, link);
3945 result = notify_send_queue(notify);
3946 if (result != ISC_R_SUCCESS)
3947 notify_destroy(notify, ISC_TRUE);
3948 if (!loggednotify) {
3949 notify_log(zone, ISC_LOG_INFO,
3950 "sending notifies (serial %u)",
3952 loggednotify = ISC_TRUE;
3958 if (notifytype == dns_notifytype_explicit)
3962 * Process NS RRset to generate notifies.
3965 dns_rdataset_init(&nsrdset);
3966 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
3967 dns_rdatatype_none, 0, &nsrdset, NULL);
3968 if (result != ISC_R_SUCCESS)
3971 result = dns_rdataset_first(&nsrdset);
3972 while (result == ISC_R_SUCCESS) {
3973 dns_rdataset_current(&nsrdset, &rdata);
3974 result = dns_rdata_tostruct(&rdata, &ns, NULL);
3975 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3976 dns_rdata_reset(&rdata);
3978 * don't notify the master server.
3980 if (dns_name_compare(&master, &ns.name) == 0) {
3981 result = dns_rdataset_next(&nsrdset);
3985 if (!loggednotify) {
3986 notify_log(zone, ISC_LOG_INFO,
3987 "sending notifies (serial %u)",
3989 loggednotify = ISC_TRUE;
3993 isqueued = notify_isqueued(zone, &ns.name, NULL);
3996 result = dns_rdataset_next(&nsrdset);
3999 result = notify_create(zone->mctx, flags, ¬ify);
4000 if (result != ISC_R_SUCCESS)
4002 dns_zone_iattach(zone, ¬ify->zone);
4003 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
4004 if (result != ISC_R_SUCCESS) {
4006 notify_destroy(notify, ISC_TRUE);
4011 ISC_LIST_APPEND(zone->notifies, notify, link);
4013 notify_find_address(notify);
4015 result = dns_rdataset_next(&nsrdset);
4017 dns_rdataset_disassociate(&nsrdset);
4020 if (dns_name_dynamic(&master))
4021 dns_name_free(&master, zone->mctx);
4023 dns_db_detachnode(zonedb, &node);
4025 dns_db_closeversion(zonedb, &version, ISC_FALSE);
4026 dns_db_detach(&zonedb);
4033 static inline isc_result_t
4034 save_nsrrset(dns_message_t *message, dns_name_t *name,
4035 dns_db_t *db, dns_dbversion_t *version)
4037 dns_rdataset_t *nsrdataset = NULL;
4038 dns_rdataset_t *rdataset = NULL;
4039 dns_dbnode_t *node = NULL;
4041 isc_result_t result;
4042 dns_rdata_t rdata = DNS_RDATA_INIT;
4045 * Extract NS RRset from message.
4047 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
4048 dns_rdatatype_ns, dns_rdatatype_none,
4050 if (result != ISC_R_SUCCESS)
4056 result = dns_db_findnode(db, name, ISC_TRUE, &node);
4057 if (result != ISC_R_SUCCESS)
4059 result = dns_db_addrdataset(db, node, version, 0,
4060 nsrdataset, 0, NULL);
4061 dns_db_detachnode(db, &node);
4062 if (result != ISC_R_SUCCESS)
4065 * Add glue rdatasets.
4067 for (result = dns_rdataset_first(nsrdataset);
4068 result == ISC_R_SUCCESS;
4069 result = dns_rdataset_next(nsrdataset)) {
4070 dns_rdataset_current(nsrdataset, &rdata);
4071 result = dns_rdata_tostruct(&rdata, &ns, NULL);
4072 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4073 dns_rdata_reset(&rdata);
4074 if (!dns_name_issubdomain(&ns.name, name))
4077 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
4078 &ns.name, dns_rdatatype_aaaa,
4079 dns_rdatatype_none, NULL,
4081 if (result == ISC_R_SUCCESS) {
4082 result = dns_db_findnode(db, &ns.name,
4084 if (result != ISC_R_SUCCESS)
4086 result = dns_db_addrdataset(db, node, version, 0,
4088 dns_db_detachnode(db, &node);
4089 if (result != ISC_R_SUCCESS)
4093 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
4094 &ns.name, dns_rdatatype_a,
4095 dns_rdatatype_none, NULL,
4097 if (result == ISC_R_SUCCESS) {
4098 result = dns_db_findnode(db, &ns.name,
4100 if (result != ISC_R_SUCCESS)
4102 result = dns_db_addrdataset(db, node, version, 0,
4104 dns_db_detachnode(db, &node);
4105 if (result != ISC_R_SUCCESS)
4109 if (result != ISC_R_NOMORE)
4112 return (ISC_R_SUCCESS);
4119 stub_callback(isc_task_t *task, isc_event_t *event) {
4120 const char me[] = "stub_callback";
4121 dns_requestevent_t *revent = (dns_requestevent_t *)event;
4122 dns_stub_t *stub = NULL;
4123 dns_message_t *msg = NULL;
4124 dns_zone_t *zone = NULL;
4125 char master[ISC_SOCKADDR_FORMATSIZE];
4126 char source[ISC_SOCKADDR_FORMATSIZE];
4127 isc_uint32_t nscnt, cnamecnt;
4128 isc_result_t result;
4130 isc_boolean_t exiting = ISC_FALSE;
4134 stub = revent->ev_arg;
4135 INSIST(DNS_STUB_VALID(stub));
4145 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
4146 zone_debuglog(zone, me, 1, "exiting");
4151 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
4152 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
4154 if (revent->result != ISC_R_SUCCESS) {
4155 if (revent->result == ISC_R_TIMEDOUT &&
4156 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4158 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4160 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4161 "refreshing stub: timeout retrying "
4162 " without EDNS master %s (source %s)",
4166 dns_zone_log(zone, ISC_LOG_INFO,
4167 "could not refresh stub from master %s"
4168 " (source %s): %s", master, source,
4169 dns_result_totext(revent->result));
4173 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
4174 if (result != ISC_R_SUCCESS)
4177 result = dns_request_getresponse(revent->request, msg, 0);
4178 if (result != ISC_R_SUCCESS)
4184 if (msg->rcode != dns_rcode_noerror) {
4188 isc_buffer_init(&rb, rcode, sizeof(rcode));
4189 (void)dns_rcode_totext(msg->rcode, &rb);
4191 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
4192 (msg->rcode == dns_rcode_servfail ||
4193 msg->rcode == dns_rcode_notimp ||
4194 msg->rcode == dns_rcode_formerr)) {
4195 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4196 "refreshing stub: rcode (%.*s) retrying "
4197 "without EDNS master %s (source %s)",
4198 (int)rb.used, rcode, master, source);
4200 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4205 dns_zone_log(zone, ISC_LOG_INFO,
4207 "unexpected rcode (%.*s) from %s (source %s)",
4208 (int)rb.used, rcode, master, source);
4213 * We need complete messages.
4215 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
4216 if (dns_request_usedtcp(revent->request)) {
4217 dns_zone_log(zone, ISC_LOG_INFO,
4218 "refreshing stub: truncated TCP "
4219 "response from master %s (source %s)",
4224 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
4230 * If non-auth log and next master.
4232 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
4233 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
4234 "non-authoritative answer from "
4235 "master %s (source %s)", master, source);
4242 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
4243 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
4245 if (cnamecnt != 0) {
4246 dns_zone_log(zone, ISC_LOG_INFO,
4247 "refreshing stub: unexpected CNAME response "
4248 "from master %s (source %s)", master, source);
4253 dns_zone_log(zone, ISC_LOG_INFO,
4254 "refreshing stub: no NS records in response "
4255 "from master %s (source %s)", master, source);
4262 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
4263 if (result != ISC_R_SUCCESS) {
4264 dns_zone_log(zone, ISC_LOG_INFO,
4265 "refreshing stub: unable to save NS records "
4266 "from master %s (source %s)", master, source);
4273 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
4274 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4275 if (zone->db == NULL)
4276 zone_attachdb(zone, stub->db);
4277 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4278 dns_db_detach(&stub->db);
4280 if (zone->masterfile != NULL) {
4281 dns_zone_dump(zone);
4282 TIME_NOW(&zone->loadtime);
4285 dns_message_destroy(&msg);
4286 isc_event_free(&event);
4288 dns_request_destroy(&zone->request);
4289 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4290 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
4291 isc_interval_set(&i, zone->expire, 0);
4292 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
4293 zone_settimer(zone, &now);
4298 if (stub->version != NULL)
4299 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
4300 if (stub->db != NULL)
4301 dns_db_detach(&stub->db);
4303 dns_message_destroy(&msg);
4304 isc_event_free(&event);
4306 dns_request_destroy(&zone->request);
4308 * Skip to next failed / untried master.
4312 } while (zone->curmaster < zone->masterscnt &&
4313 zone->mastersok[zone->curmaster]);
4314 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
4315 if (exiting || zone->curmaster >= zone->masterscnt) {
4316 isc_boolean_t done = ISC_TRUE;
4318 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
4319 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4321 * Did we get a good answer from all the masters?
4323 for (j = 0; j < zone->masterscnt; j++)
4324 if (zone->mastersok[j] == ISC_FALSE) {
4331 zone->curmaster = 0;
4333 * Find the next failed master.
4335 while (zone->curmaster < zone->masterscnt &&
4336 zone->mastersok[zone->curmaster])
4338 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4340 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4342 zone_settimer(zone, &now);
4347 queue_soa_query(zone);
4353 dns_message_destroy(&msg);
4354 isc_event_free(&event);
4356 dns_request_destroy(&zone->request);
4358 ns_query(zone, NULL, stub);
4363 dns_zone_idetach(&stub->zone);
4364 INSIST(stub->db == NULL);
4365 INSIST(stub->version == NULL);
4366 isc_mem_put(stub->mctx, stub, sizeof(*stub));
4369 INSIST(event == NULL);
4374 * An SOA query has finished (successfully or not).
4377 refresh_callback(isc_task_t *task, isc_event_t *event) {
4378 const char me[] = "refresh_callback";
4379 dns_requestevent_t *revent = (dns_requestevent_t *)event;
4381 dns_message_t *msg = NULL;
4382 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
4384 char master[ISC_SOCKADDR_FORMATSIZE];
4385 char source[ISC_SOCKADDR_FORMATSIZE];
4386 dns_rdataset_t *rdataset = NULL;
4387 dns_rdata_t rdata = DNS_RDATA_INIT;
4388 dns_rdata_soa_t soa;
4389 isc_result_t result;
4390 isc_uint32_t serial;
4393 zone = revent->ev_arg;
4394 INSIST(DNS_ZONE_VALID(zone));
4401 * if timeout log and next master;
4404 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
4405 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
4409 if (revent->result != ISC_R_SUCCESS) {
4410 if (revent->result == ISC_R_TIMEDOUT &&
4411 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4413 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4415 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4416 "refresh: timeout retrying without EDNS "
4417 "master %s (source %s)", master, source);
4420 if (revent->result == ISC_R_TIMEDOUT &&
4421 !dns_request_usedtcp(revent->request)) {
4422 dns_zone_log(zone, ISC_LOG_INFO,
4423 "refresh: retry limit for "
4424 "master %s exceeded (source %s)",
4426 /* Try with slave with TCP. */
4427 if (zone->type == dns_zone_slave) {
4429 DNS_ZONE_SETFLAG(zone,
4430 DNS_ZONEFLG_SOABEFOREAXFR);
4435 dns_zone_log(zone, ISC_LOG_INFO,
4436 "refresh: failure trying master "
4437 "%s (source %s): %s", master, source,
4438 dns_result_totext(revent->result));
4442 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
4443 if (result != ISC_R_SUCCESS)
4445 result = dns_request_getresponse(revent->request, msg, 0);
4446 if (result != ISC_R_SUCCESS) {
4447 dns_zone_log(zone, ISC_LOG_INFO,
4448 "refresh: failure trying master "
4449 "%s (source %s): %s", master, source,
4450 dns_result_totext(result));
4457 if (msg->rcode != dns_rcode_noerror) {
4461 isc_buffer_init(&rb, rcode, sizeof(rcode));
4462 (void)dns_rcode_totext(msg->rcode, &rb);
4464 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
4465 (msg->rcode == dns_rcode_servfail ||
4466 msg->rcode == dns_rcode_notimp ||
4467 msg->rcode == dns_rcode_formerr)) {
4468 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4469 "refresh: rcode (%.*s) retrying without "
4470 "EDNS master %s (source %s)",
4471 (int)rb.used, rcode, master, source);
4473 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4477 dns_zone_log(zone, ISC_LOG_INFO,
4478 "refresh: unexpected rcode (%.*s) from "
4479 "master %s (source %s)", (int)rb.used, rcode,
4482 * Perhaps AXFR/IXFR is allowed even if SOA queries arn't.
4484 if (msg->rcode == dns_rcode_refused &&
4485 zone->type == dns_zone_slave)
4491 * If truncated punt to zone transfer which will query again.
4493 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
4494 if (zone->type == dns_zone_slave) {
4495 dns_zone_log(zone, ISC_LOG_INFO,
4496 "refresh: truncated UDP answer, "
4497 "initiating TCP zone xfer "
4498 "for master %s (source %s)",
4501 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
4505 INSIST(zone->type == dns_zone_stub);
4506 if (dns_request_usedtcp(revent->request)) {
4507 dns_zone_log(zone, ISC_LOG_INFO,
4508 "refresh: truncated TCP response "
4509 "from master %s (source %s)",
4514 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
4521 * if non-auth log and next master;
4523 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
4524 dns_zone_log(zone, ISC_LOG_INFO,
4525 "refresh: non-authoritative answer from "
4526 "master %s (source %s)", master, source);
4530 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
4531 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
4532 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
4533 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
4537 * There should not be a CNAME record at top of zone.
4539 if (cnamecnt != 0) {
4540 dns_zone_log(zone, ISC_LOG_INFO,
4541 "refresh: CNAME at top of zone "
4542 "in master %s (source %s)", master, source);
4547 * if referral log and next master;
4549 if (soacnt == 0 && soacount == 0 && nscount != 0) {
4550 dns_zone_log(zone, ISC_LOG_INFO,
4551 "refresh: referral response "
4552 "from master %s (source %s)", master, source);
4557 * if nodata log and next master;
4559 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
4560 dns_zone_log(zone, ISC_LOG_INFO,
4561 "refresh: NODATA response "
4562 "from master %s (source %s)", master, source);
4567 * Only one soa at top of zone.
4570 dns_zone_log(zone, ISC_LOG_INFO,
4571 "refresh: answer SOA count (%d) != 1 "
4572 "from master %s (source %s)",
4573 soacnt, master, source);
4580 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
4581 dns_rdatatype_soa, dns_rdatatype_none,
4583 if (result != ISC_R_SUCCESS) {
4584 dns_zone_log(zone, ISC_LOG_INFO,
4585 "refresh: unable to get SOA record "
4586 "from master %s (source %s)", master, source);
4590 result = dns_rdataset_first(rdataset);
4591 if (result != ISC_R_SUCCESS) {
4592 dns_zone_log(zone, ISC_LOG_INFO,
4593 "refresh: dns_rdataset_first() failed");
4597 dns_rdataset_current(rdataset, &rdata);
4598 result = dns_rdata_tostruct(&rdata, &soa, NULL);
4599 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4601 serial = soa.serial;
4603 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
4604 serial, zone->serial);
4605 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
4606 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
4607 isc_serial_gt(serial, zone->serial)) {
4609 isc_event_free(&event);
4611 dns_request_destroy(&zone->request);
4613 if (zone->type == dns_zone_slave) {
4616 INSIST(zone->type == dns_zone_stub);
4617 ns_query(zone, rdataset, NULL);
4620 dns_message_destroy(&msg);
4621 } else if (isc_serial_eq(soa.serial, zone->serial)) {
4622 if (zone->masterfile != NULL) {
4623 result = ISC_R_FAILURE;
4624 if (zone->journal != NULL)
4625 result = isc_file_settime(zone->journal, &now);
4626 if (result == ISC_R_SUCCESS &&
4627 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
4628 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
4629 result = isc_file_settime(zone->masterfile,
4631 } else if (result != ISC_R_SUCCESS)
4632 result = isc_file_settime(zone->masterfile,
4634 /* Someone removed the file from underneath us! */
4635 if (result == ISC_R_FILENOTFOUND) {
4637 zone_needdump(zone, DNS_DUMP_DELAY);
4639 } else if (result != ISC_R_SUCCESS)
4640 dns_zone_log(zone, ISC_LOG_ERROR,
4641 "refresh: could not set file "
4642 "modification time of '%s': %s",
4644 dns_result_totext(result));
4646 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
4647 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
4648 zone->mastersok[zone->curmaster] = ISC_TRUE;
4651 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
4652 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
4653 "received from master %s < ours (%u)",
4654 soa.serial, master, zone->serial);
4656 zone_debuglog(zone, me, 1, "ahead");
4657 zone->mastersok[zone->curmaster] = ISC_TRUE;
4661 dns_message_destroy(&msg);
4666 dns_message_destroy(&msg);
4667 isc_event_free(&event);
4669 dns_request_destroy(&zone->request);
4671 * Skip to next failed / untried master.
4675 } while (zone->curmaster < zone->masterscnt &&
4676 zone->mastersok[zone->curmaster]);
4677 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
4678 if (zone->curmaster >= zone->masterscnt) {
4679 isc_boolean_t done = ISC_TRUE;
4680 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
4681 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4683 * Did we get a good answer from all the masters?
4685 for (j = 0; j < zone->masterscnt; j++)
4686 if (zone->mastersok[j] == ISC_FALSE) {
4693 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4694 zone->curmaster = 0;
4696 * Find the next failed master.
4698 while (zone->curmaster < zone->masterscnt &&
4699 zone->mastersok[zone->curmaster])
4703 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4704 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
4705 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
4706 zone->refreshtime = now;
4708 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4709 zone_settimer(zone, &now);
4715 queue_soa_query(zone);
4721 dns_message_destroy(&msg);
4722 isc_event_free(&event);
4724 dns_request_destroy(&zone->request);
4725 queue_soa_query(zone);
4729 dns_zone_idetach(&zone);
4734 queue_soa_query(dns_zone_t *zone) {
4735 const char me[] = "queue_soa_query";
4737 dns_zone_t *dummy = NULL;
4738 isc_result_t result;
4744 REQUIRE(LOCKED_ZONE(zone));
4746 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
4747 cancel_refresh(zone);
4751 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
4752 soa_query, zone, sizeof(isc_event_t));
4754 cancel_refresh(zone);
4759 * Attach so that we won't clean up
4760 * until the event is delivered.
4762 zone_iattach(zone, &dummy);
4765 e->ev_sender = NULL;
4766 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
4767 if (result != ISC_R_SUCCESS) {
4768 zone_idetach(&dummy);
4770 cancel_refresh(zone);
4774 static inline isc_result_t
4775 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
4776 dns_message_t **messagep)
4778 dns_message_t *message = NULL;
4779 dns_name_t *qname = NULL;
4780 dns_rdataset_t *qrdataset = NULL;
4781 isc_result_t result;
4783 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
4785 if (result != ISC_R_SUCCESS)
4788 message->opcode = dns_opcode_query;
4789 message->rdclass = zone->rdclass;
4791 result = dns_message_gettempname(message, &qname);
4792 if (result != ISC_R_SUCCESS)
4795 result = dns_message_gettemprdataset(message, &qrdataset);
4796 if (result != ISC_R_SUCCESS)
4802 dns_name_init(qname, NULL);
4803 dns_name_clone(&zone->origin, qname);
4804 dns_rdataset_init(qrdataset);
4805 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
4806 ISC_LIST_APPEND(qname->list, qrdataset, link);
4807 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
4809 *messagep = message;
4810 return (ISC_R_SUCCESS);
4814 dns_message_puttempname(message, &qname);
4815 if (qrdataset != NULL)
4816 dns_message_puttemprdataset(message, &qrdataset);
4817 if (message != NULL)
4818 dns_message_destroy(&message);
4823 add_opt(dns_message_t *message, isc_uint16_t udpsize) {
4824 dns_rdataset_t *rdataset = NULL;
4825 dns_rdatalist_t *rdatalist = NULL;
4826 dns_rdata_t *rdata = NULL;
4827 isc_result_t result;
4829 result = dns_message_gettemprdatalist(message, &rdatalist);
4830 if (result != ISC_R_SUCCESS)
4832 result = dns_message_gettemprdata(message, &rdata);
4833 if (result != ISC_R_SUCCESS)
4835 result = dns_message_gettemprdataset(message, &rdataset);
4836 if (result != ISC_R_SUCCESS)
4838 dns_rdataset_init(rdataset);
4840 rdatalist->type = dns_rdatatype_opt;
4841 rdatalist->covers = 0;
4844 * Set Maximum UDP buffer size.
4846 rdatalist->rdclass = udpsize;
4849 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
4858 rdata->rdclass = rdatalist->rdclass;
4859 rdata->type = rdatalist->type;
4862 ISC_LIST_INIT(rdatalist->rdata);
4863 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
4864 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
4867 return (dns_message_setopt(message, rdataset));
4870 if (rdatalist != NULL)
4871 dns_message_puttemprdatalist(message, &rdatalist);
4872 if (rdataset != NULL)
4873 dns_message_puttemprdataset(message, &rdataset);
4875 dns_message_puttemprdata(message, &rdata);
4881 soa_query(isc_task_t *task, isc_event_t *event) {
4882 const char me[] = "soa_query";
4883 isc_result_t result = ISC_R_FAILURE;
4884 dns_message_t *message = NULL;
4885 dns_zone_t *zone = event->ev_arg;
4886 dns_zone_t *dummy = NULL;
4887 isc_netaddr_t masterip;
4888 dns_tsigkey_t *key = NULL;
4889 isc_uint32_t options;
4890 isc_boolean_t cancel = ISC_TRUE;
4892 isc_boolean_t have_xfrsource;
4893 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
4895 REQUIRE(DNS_ZONE_VALID(zone));
4902 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
4903 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
4904 zone->view->requestmgr == NULL) {
4905 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
4911 * XXX Optimisation: Create message when zone is setup and reuse.
4913 result = create_query(zone, dns_rdatatype_soa, &message);
4914 if (result != ISC_R_SUCCESS)
4918 INSIST(zone->masterscnt > 0);
4919 INSIST(zone->curmaster < zone->masterscnt);
4921 zone->masteraddr = zone->masters[zone->curmaster];
4923 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
4925 * First, look for a tsig key in the master statement, then
4926 * try for a server key.
4928 if ((zone->masterkeynames != NULL) &&
4929 (zone->masterkeynames[zone->curmaster] != NULL)) {
4930 dns_view_t *view = dns_zone_getview(zone);
4931 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
4932 result = dns_view_gettsig(view, keyname, &key);
4933 if (result != ISC_R_SUCCESS) {
4934 char namebuf[DNS_NAME_FORMATSIZE];
4935 dns_name_format(keyname, namebuf, sizeof(namebuf));
4936 dns_zone_log(zone, ISC_LOG_ERROR,
4937 "unable to find key: %s", namebuf);
4941 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
4943 have_xfrsource = ISC_FALSE;
4944 if (zone->view->peers != NULL) {
4945 dns_peer_t *peer = NULL;
4947 result = dns_peerlist_peerbyaddr(zone->view->peers,
4949 if (result == ISC_R_SUCCESS) {
4950 result = dns_peer_getsupportedns(peer, &edns);
4951 if (result == ISC_R_SUCCESS && !edns)
4952 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4953 result = dns_peer_gettransfersource(peer,
4955 if (result == ISC_R_SUCCESS)
4956 have_xfrsource = ISC_TRUE;
4957 if (zone->view->resolver != NULL)
4959 dns_resolver_getudpsize(zone->view->resolver);
4960 (void)dns_peer_getudpsize(peer, &udpsize);
4964 switch (isc_sockaddr_pf(&zone->masteraddr)) {
4966 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4967 if (isc_sockaddr_equal(&zone->altxfrsource4,
4970 zone->sourceaddr = zone->altxfrsource4;
4971 } else if (!have_xfrsource)
4972 zone->sourceaddr = zone->xfrsource4;
4975 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4976 if (isc_sockaddr_equal(&zone->altxfrsource6,
4979 zone->sourceaddr = zone->altxfrsource6;
4980 } else if (!have_xfrsource)
4981 zone->sourceaddr = zone->xfrsource6;
4984 result = ISC_R_NOTIMPLEMENTED;
4988 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
4989 DNS_REQUESTOPT_TCP : 0;
4991 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4992 result = add_opt(message, udpsize);
4993 if (result != ISC_R_SUCCESS)
4994 zone_debuglog(zone, me, 1,
4995 "unable to add opt record: %s",
4996 dns_result_totext(result));
4999 zone_iattach(zone, &dummy);
5001 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
5003 result = dns_request_createvia2(zone->view->requestmgr, message,
5004 &zone->sourceaddr, &zone->masteraddr,
5005 options, key, timeout * 3, timeout,
5006 zone->task, refresh_callback, zone,
5008 if (result != ISC_R_SUCCESS) {
5009 zone_idetach(&dummy);
5010 zone_debuglog(zone, me, 1,
5011 "dns_request_createvia2() failed: %s",
5012 dns_result_totext(result));
5019 dns_tsigkey_detach(&key);
5020 if (result != ISC_R_SUCCESS)
5021 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
5022 if (message != NULL)
5023 dns_message_destroy(&message);
5025 cancel_refresh(zone);
5026 isc_event_free(&event);
5028 dns_zone_idetach(&zone);
5033 dns_tsigkey_detach(&key);
5035 * Skip to next failed / untried master.
5039 } while (zone->curmaster < zone->masterscnt &&
5040 zone->mastersok[zone->curmaster]);
5041 if (zone->curmaster < zone->masterscnt)
5043 zone->curmaster = 0;
5048 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
5049 const char me[] = "ns_query";
5050 isc_result_t result;
5051 dns_message_t *message = NULL;
5052 isc_netaddr_t masterip;
5053 dns_tsigkey_t *key = NULL;
5054 dns_dbnode_t *node = NULL;
5056 isc_boolean_t have_xfrsource = ISC_FALSE;
5057 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
5059 REQUIRE(DNS_ZONE_VALID(zone));
5060 REQUIRE((soardataset != NULL && stub == NULL) ||
5061 (soardataset == NULL && stub != NULL));
5062 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
5068 stub = isc_mem_get(zone->mctx, sizeof(*stub));
5071 stub->magic = STUB_MAGIC;
5072 stub->mctx = zone->mctx;
5075 stub->version = NULL;
5078 * Attach so that the zone won't disappear from under us.
5080 zone_iattach(zone, &stub->zone);
5083 * If a db exists we will update it, otherwise we create a
5084 * new one and attach it to the zone once we have the NS
5087 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5088 if (zone->db != NULL) {
5089 dns_db_attach(zone->db, &stub->db);
5090 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5092 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5094 INSIST(zone->db_argc >= 1);
5095 result = dns_db_create(zone->mctx, zone->db_argv[0],
5096 &zone->origin, dns_dbtype_stub,
5101 if (result != ISC_R_SUCCESS) {
5102 dns_zone_log(zone, ISC_LOG_ERROR,
5106 dns_result_totext(result));
5109 dns_db_settask(stub->db, zone->task);
5112 dns_db_newversion(stub->db, &stub->version);
5115 * Update SOA record.
5117 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
5119 if (result != ISC_R_SUCCESS) {
5120 dns_zone_log(zone, ISC_LOG_INFO,
5122 "dns_db_findnode() failed: %s",
5123 dns_result_totext(result));
5127 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
5128 soardataset, 0, NULL);
5129 dns_db_detachnode(stub->db, &node);
5130 if (result != ISC_R_SUCCESS) {
5131 dns_zone_log(zone, ISC_LOG_INFO,
5133 "dns_db_addrdataset() failed: %s",
5134 dns_result_totext(result));
5140 * XXX Optimisation: Create message when zone is setup and reuse.
5142 result = create_query(zone, dns_rdatatype_ns, &message);
5144 INSIST(zone->masterscnt > 0);
5145 INSIST(zone->curmaster < zone->masterscnt);
5146 zone->masteraddr = zone->masters[zone->curmaster];
5148 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
5150 * First, look for a tsig key in the master statement, then
5151 * try for a server key.
5153 if ((zone->masterkeynames != NULL) &&
5154 (zone->masterkeynames[zone->curmaster] != NULL)) {
5155 dns_view_t *view = dns_zone_getview(zone);
5156 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
5157 result = dns_view_gettsig(view, keyname, &key);
5158 if (result != ISC_R_SUCCESS) {
5159 char namebuf[DNS_NAME_FORMATSIZE];
5160 dns_name_format(keyname, namebuf, sizeof(namebuf));
5161 dns_zone_log(zone, ISC_LOG_ERROR,
5162 "unable to find key: %s", namebuf);
5166 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
5168 if (zone->view->peers != NULL) {
5169 dns_peer_t *peer = NULL;
5171 result = dns_peerlist_peerbyaddr(zone->view->peers,
5173 if (result == ISC_R_SUCCESS) {
5174 result = dns_peer_getsupportedns(peer, &edns);
5175 if (result == ISC_R_SUCCESS && !edns)
5176 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
5177 result = dns_peer_gettransfersource(peer,
5179 if (result == ISC_R_SUCCESS)
5180 have_xfrsource = ISC_TRUE;
5181 if (zone->view->resolver != NULL)
5183 dns_resolver_getudpsize(zone->view->resolver);
5184 (void)dns_peer_getudpsize(peer, &udpsize);
5188 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
5189 result = add_opt(message, udpsize);
5190 if (result != ISC_R_SUCCESS)
5191 zone_debuglog(zone, me, 1,
5192 "unable to add opt record: %s",
5193 dns_result_totext(result));
5197 * Always use TCP so that we shouldn't truncate in additional section.
5199 switch (isc_sockaddr_pf(&zone->masteraddr)) {
5201 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
5202 zone->sourceaddr = zone->altxfrsource4;
5203 else if (!have_xfrsource)
5204 zone->sourceaddr = zone->xfrsource4;
5207 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
5208 zone->sourceaddr = zone->altxfrsource6;
5209 else if (!have_xfrsource)
5210 zone->sourceaddr = zone->xfrsource6;
5213 result = ISC_R_NOTIMPLEMENTED;
5217 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
5219 result = dns_request_createvia2(zone->view->requestmgr, message,
5220 &zone->sourceaddr, &zone->masteraddr,
5221 DNS_REQUESTOPT_TCP, key, timeout * 3,
5222 timeout, zone->task, stub_callback,
5223 stub, &zone->request);
5224 if (result != ISC_R_SUCCESS) {
5225 zone_debuglog(zone, me, 1,
5226 "dns_request_createvia() failed: %s",
5227 dns_result_totext(result));
5230 dns_message_destroy(&message);
5234 cancel_refresh(zone);
5237 if (stub->version != NULL)
5238 dns_db_closeversion(stub->db, &stub->version,
5240 if (stub->db != NULL)
5241 dns_db_detach(&stub->db);
5242 if (stub->zone != NULL)
5243 zone_idetach(&stub->zone);
5244 isc_mem_put(stub->mctx, stub, sizeof(*stub));
5246 if (message != NULL)
5247 dns_message_destroy(&message);
5250 dns_tsigkey_detach(&key);
5256 * Handle the control event. Note that although this event causes the zone
5257 * to shut down, it is not a shutdown event in the sense of the task library.
5260 zone_shutdown(isc_task_t *task, isc_event_t *event) {
5261 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
5262 isc_boolean_t free_needed, linked = ISC_FALSE;
5265 REQUIRE(DNS_ZONE_VALID(zone));
5266 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
5267 INSIST(isc_refcount_current(&zone->erefs) == 0);
5268 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
5271 * Stop things being restarted after we cancel them below.
5274 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
5278 * If we were waiting for xfrin quota, step out of
5280 * If there's no zone manager, we can't be waiting for the
5283 if (zone->zmgr != NULL) {
5284 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
5285 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
5286 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
5289 zone->statelist = NULL;
5291 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
5295 * In task context, no locking required. See zone_xfrdone().
5297 if (zone->xfr != NULL)
5298 dns_xfrin_shutdown(zone->xfr);
5302 INSIST(zone->irefs > 0);
5305 if (zone->request != NULL) {
5306 dns_request_cancel(zone->request);
5309 if (zone->readio != NULL)
5310 zonemgr_cancelio(zone->readio);
5312 if (zone->lctx != NULL)
5313 dns_loadctx_cancel(zone->lctx);
5315 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
5316 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5317 if (zone->writeio != NULL)
5318 zonemgr_cancelio(zone->writeio);
5320 if (zone->dctx != NULL)
5321 dns_dumpctx_cancel(zone->dctx);
5324 notify_cancel(zone);
5326 if (zone->timer != NULL) {
5327 isc_timer_detach(&zone->timer);
5328 INSIST(zone->irefs > 0);
5332 if (zone->view != NULL)
5333 dns_view_weakdetach(&zone->view);
5336 * We have now canceled everything set the flag to allow exit_check()
5337 * to succeed. We must not unlock between setting this flag and
5338 * calling exit_check().
5340 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
5341 free_needed = exit_check(zone);
5348 zone_timer(isc_task_t *task, isc_event_t *event) {
5349 const char me[] = "zone_timer";
5350 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
5353 REQUIRE(DNS_ZONE_VALID(zone));
5357 zone_maintenance(zone);
5359 isc_event_free(&event);
5363 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
5364 const char me[] = "zone_settimer";
5366 isc_result_t result;
5368 REQUIRE(DNS_ZONE_VALID(zone));
5369 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
5372 isc_time_settoepoch(&next);
5374 switch (zone->type) {
5375 case dns_zone_master:
5376 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
5377 next = zone->notifytime;
5378 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
5379 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5380 INSIST(!isc_time_isepoch(&zone->dumptime));
5381 if (isc_time_isepoch(&next) ||
5382 isc_time_compare(&zone->dumptime, &next) < 0)
5383 next = zone->dumptime;
5387 case dns_zone_slave:
5388 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
5389 next = zone->notifytime;
5393 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
5394 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
5395 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
5396 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
5397 INSIST(!isc_time_isepoch(&zone->refreshtime));
5398 if (isc_time_isepoch(&next) ||
5399 isc_time_compare(&zone->refreshtime, &next) < 0)
5400 next = zone->refreshtime;
5402 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
5403 INSIST(!isc_time_isepoch(&zone->expiretime));
5404 if (isc_time_isepoch(&next) ||
5405 isc_time_compare(&zone->expiretime, &next) < 0)
5406 next = zone->expiretime;
5408 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
5409 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5410 INSIST(!isc_time_isepoch(&zone->dumptime));
5411 if (isc_time_isepoch(&next) ||
5412 isc_time_compare(&zone->dumptime, &next) < 0)
5413 next = zone->dumptime;
5421 if (isc_time_isepoch(&next)) {
5422 zone_debuglog(zone, me, 10, "settimer inactive");
5423 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
5424 NULL, NULL, ISC_TRUE);
5425 if (result != ISC_R_SUCCESS)
5426 dns_zone_log(zone, ISC_LOG_ERROR,
5427 "could not deactivate zone timer: %s",
5428 isc_result_totext(result));
5430 if (isc_time_compare(&next, now) <= 0)
5432 result = isc_timer_reset(zone->timer, isc_timertype_once,
5433 &next, NULL, ISC_TRUE);
5434 if (result != ISC_R_SUCCESS)
5435 dns_zone_log(zone, ISC_LOG_ERROR,
5436 "could not reset zone timer: %s",
5437 isc_result_totext(result));
5442 cancel_refresh(dns_zone_t *zone) {
5443 const char me[] = "cancel_refresh";
5447 * 'zone' locked by caller.
5450 REQUIRE(DNS_ZONE_VALID(zone));
5451 REQUIRE(LOCKED_ZONE(zone));
5455 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
5457 zone_settimer(zone, &now);
5461 notify_createmessage(dns_zone_t *zone, unsigned int flags,
5462 dns_message_t **messagep)
5464 dns_db_t *zonedb = NULL;
5465 dns_dbnode_t *node = NULL;
5466 dns_dbversion_t *version = NULL;
5467 dns_message_t *message = NULL;
5468 dns_rdataset_t rdataset;
5469 dns_rdata_t rdata = DNS_RDATA_INIT;
5471 dns_name_t *tempname = NULL;
5472 dns_rdata_t *temprdata = NULL;
5473 dns_rdatalist_t *temprdatalist = NULL;
5474 dns_rdataset_t *temprdataset = NULL;
5476 isc_result_t result;
5478 isc_buffer_t *b = NULL;
5480 REQUIRE(DNS_ZONE_VALID(zone));
5481 REQUIRE(messagep != NULL && *messagep == NULL);
5483 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
5485 if (result != ISC_R_SUCCESS)
5488 message->opcode = dns_opcode_notify;
5489 message->flags |= DNS_MESSAGEFLAG_AA;
5490 message->rdclass = zone->rdclass;
5492 result = dns_message_gettempname(message, &tempname);
5493 if (result != ISC_R_SUCCESS)
5496 result = dns_message_gettemprdataset(message, &temprdataset);
5497 if (result != ISC_R_SUCCESS)
5503 dns_name_init(tempname, NULL);
5504 dns_name_clone(&zone->origin, tempname);
5505 dns_rdataset_init(temprdataset);
5506 dns_rdataset_makequestion(temprdataset, zone->rdclass,
5508 ISC_LIST_APPEND(tempname->list, temprdataset, link);
5509 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
5511 temprdataset = NULL;
5513 if ((flags & DNS_NOTIFY_NOSOA) != 0)
5516 result = dns_message_gettempname(message, &tempname);
5517 if (result != ISC_R_SUCCESS)
5519 result = dns_message_gettemprdata(message, &temprdata);
5520 if (result != ISC_R_SUCCESS)
5522 result = dns_message_gettemprdataset(message, &temprdataset);
5523 if (result != ISC_R_SUCCESS)
5525 result = dns_message_gettemprdatalist(message, &temprdatalist);
5526 if (result != ISC_R_SUCCESS)
5529 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5530 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
5531 dns_db_attach(zone->db, &zonedb);
5532 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5534 dns_name_init(tempname, NULL);
5535 dns_name_clone(&zone->origin, tempname);
5536 dns_db_currentversion(zonedb, &version);
5537 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
5538 if (result != ISC_R_SUCCESS)
5541 dns_rdataset_init(&rdataset);
5542 result = dns_db_findrdataset(zonedb, node, version,
5544 dns_rdatatype_none, 0, &rdataset,
5546 if (result != ISC_R_SUCCESS)
5548 result = dns_rdataset_first(&rdataset);
5549 if (result != ISC_R_SUCCESS)
5551 dns_rdataset_current(&rdataset, &rdata);
5552 dns_rdata_toregion(&rdata, &r);
5553 result = isc_buffer_allocate(zone->mctx, &b, r.length);
5554 if (result != ISC_R_SUCCESS)
5556 isc_buffer_putmem(b, r.base, r.length);
5557 isc_buffer_usedregion(b, &r);
5558 dns_rdata_init(temprdata);
5559 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
5560 dns_message_takebuffer(message, &b);
5561 result = dns_rdataset_next(&rdataset);
5562 dns_rdataset_disassociate(&rdataset);
5563 if (result != ISC_R_NOMORE)
5565 temprdatalist->rdclass = rdata.rdclass;
5566 temprdatalist->type = rdata.type;
5567 temprdatalist->covers = 0;
5568 temprdatalist->ttl = rdataset.ttl;
5569 ISC_LIST_INIT(temprdatalist->rdata);
5570 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
5572 dns_rdataset_init(temprdataset);
5573 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
5574 if (result != ISC_R_SUCCESS)
5577 ISC_LIST_APPEND(tempname->list, temprdataset, link);
5578 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
5579 temprdatalist = NULL;
5580 temprdataset = NULL;
5586 dns_db_detachnode(zonedb, &node);
5587 if (version != NULL)
5588 dns_db_closeversion(zonedb, &version, ISC_FALSE);
5590 dns_db_detach(&zonedb);
5591 if (tempname != NULL)
5592 dns_message_puttempname(message, &tempname);
5593 if (temprdata != NULL)
5594 dns_message_puttemprdata(message, &temprdata);
5595 if (temprdataset != NULL)
5596 dns_message_puttemprdataset(message, &temprdataset);
5597 if (temprdatalist != NULL)
5598 dns_message_puttemprdatalist(message, &temprdatalist);
5601 *messagep = message;
5602 return (ISC_R_SUCCESS);
5605 if (tempname != NULL)
5606 dns_message_puttempname(message, &tempname);
5607 if (temprdataset != NULL)
5608 dns_message_puttemprdataset(message, &temprdataset);
5609 dns_message_destroy(&message);
5614 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
5618 dns_rdata_soa_t soa;
5619 dns_rdataset_t *rdataset = NULL;
5620 dns_rdata_t rdata = DNS_RDATA_INIT;
5621 isc_result_t result;
5622 char fromtext[ISC_SOCKADDR_FORMATSIZE];
5624 isc_netaddr_t netaddr;
5626 REQUIRE(DNS_ZONE_VALID(zone));
5629 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
5633 * Check that 'from' is a valid notify source, (zone->masters).
5634 * Return DNS_R_REFUSED if not.
5636 * If the notify message contains a serial number check it
5637 * against the zones serial and return if <= current serial
5639 * If a refresh check is progress, if so just record the
5640 * fact we received a NOTIFY and from where and return.
5641 * We will perform a new refresh check when the current one
5642 * completes. Return ISC_R_SUCCESS.
5644 * Otherwise initiate a refresh check using 'from' as the
5645 * first address to check. Return ISC_R_SUCCESS.
5648 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
5651 * We only handle NOTIFY (SOA) at the present.
5654 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
5655 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
5656 dns_rdatatype_soa, dns_rdatatype_none,
5657 NULL, NULL) != ISC_R_SUCCESS) {
5659 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
5660 dns_zone_log(zone, ISC_LOG_NOTICE,
5662 "question section from: %s", fromtext);
5663 return (DNS_R_FORMERR);
5665 dns_zone_log(zone, ISC_LOG_NOTICE,
5666 "NOTIFY zone does not match");
5667 return (DNS_R_NOTIMP);
5671 * If we are a master zone just succeed.
5673 if (zone->type == dns_zone_master) {
5675 return (ISC_R_SUCCESS);
5678 isc_netaddr_fromsockaddr(&netaddr, from);
5679 for (i = 0; i < zone->masterscnt; i++) {
5680 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
5682 if (zone->view->aclenv.match_mapped &&
5683 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
5684 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
5685 isc_netaddr_t na1, na2;
5686 isc_netaddr_fromv4mapped(&na1, &netaddr);
5687 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
5688 if (isc_netaddr_equal(&na1, &na2))
5694 * Accept notify requests from non masters if they are on
5695 * 'zone->notify_acl'.
5697 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
5698 dns_acl_match(&netaddr, NULL, zone->notify_acl,
5699 &zone->view->aclenv,
5700 &match, NULL) == ISC_R_SUCCESS &&
5703 /* Accept notify. */
5704 } else if (i >= zone->masterscnt) {
5706 dns_zone_log(zone, ISC_LOG_INFO,
5707 "refused notify from non-master: %s", fromtext);
5708 return (DNS_R_REFUSED);
5712 * If the zone is loaded and there are answers check the serial
5713 * to see if we need to do a refresh. Do not worry about this
5714 * check if we are a dialup zone as we use the notify request
5715 * to trigger a refresh check.
5717 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
5718 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
5719 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
5720 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
5723 dns_rdatatype_none, NULL,
5725 if (result == ISC_R_SUCCESS)
5726 result = dns_rdataset_first(rdataset);
5727 if (result == ISC_R_SUCCESS) {
5728 isc_uint32_t serial = 0;
5730 dns_rdataset_current(rdataset, &rdata);
5731 result = dns_rdata_tostruct(&rdata, &soa, NULL);
5732 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5733 serial = soa.serial;
5734 if (isc_serial_le(serial, zone->serial)) {
5735 dns_zone_log(zone, ISC_LOG_INFO,
5737 "zone is up to date",
5740 return (ISC_R_SUCCESS);
5746 * If we got this far and there was a refresh in progress just
5747 * let it complete. Record where we got the notify from so we
5748 * can perform a refresh check when the current one completes
5750 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
5751 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
5752 zone->notifyfrom = *from;
5754 dns_zone_log(zone, ISC_LOG_INFO,
5755 "notify from %s: refresh in progress, "
5756 "refresh check queued",
5758 return (ISC_R_SUCCESS);
5760 zone->notifyfrom = *from;
5762 dns_zone_refresh(zone);
5763 return (ISC_R_SUCCESS);
5767 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
5769 REQUIRE(DNS_ZONE_VALID(zone));
5772 if (zone->notify_acl != NULL)
5773 dns_acl_detach(&zone->notify_acl);
5774 dns_acl_attach(acl, &zone->notify_acl);
5779 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
5781 REQUIRE(DNS_ZONE_VALID(zone));
5784 if (zone->query_acl != NULL)
5785 dns_acl_detach(&zone->query_acl);
5786 dns_acl_attach(acl, &zone->query_acl);
5791 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
5793 REQUIRE(DNS_ZONE_VALID(zone));
5796 if (zone->update_acl != NULL)
5797 dns_acl_detach(&zone->update_acl);
5798 dns_acl_attach(acl, &zone->update_acl);
5803 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
5805 REQUIRE(DNS_ZONE_VALID(zone));
5808 if (zone->forward_acl != NULL)
5809 dns_acl_detach(&zone->forward_acl);
5810 dns_acl_attach(acl, &zone->forward_acl);
5815 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
5817 REQUIRE(DNS_ZONE_VALID(zone));
5820 if (zone->xfr_acl != NULL)
5821 dns_acl_detach(&zone->xfr_acl);
5822 dns_acl_attach(acl, &zone->xfr_acl);
5827 dns_zone_getnotifyacl(dns_zone_t *zone) {
5829 REQUIRE(DNS_ZONE_VALID(zone));
5831 return (zone->notify_acl);
5835 dns_zone_getqueryacl(dns_zone_t *zone) {
5837 REQUIRE(DNS_ZONE_VALID(zone));
5839 return (zone->query_acl);
5843 dns_zone_getupdateacl(dns_zone_t *zone) {
5845 REQUIRE(DNS_ZONE_VALID(zone));
5847 return (zone->update_acl);
5851 dns_zone_getforwardacl(dns_zone_t *zone) {
5853 REQUIRE(DNS_ZONE_VALID(zone));
5855 return (zone->forward_acl);
5859 dns_zone_getxfracl(dns_zone_t *zone) {
5861 REQUIRE(DNS_ZONE_VALID(zone));
5863 return (zone->xfr_acl);
5867 dns_zone_clearupdateacl(dns_zone_t *zone) {
5869 REQUIRE(DNS_ZONE_VALID(zone));
5872 if (zone->update_acl != NULL)
5873 dns_acl_detach(&zone->update_acl);
5878 dns_zone_clearforwardacl(dns_zone_t *zone) {
5880 REQUIRE(DNS_ZONE_VALID(zone));
5883 if (zone->forward_acl != NULL)
5884 dns_acl_detach(&zone->forward_acl);
5889 dns_zone_clearnotifyacl(dns_zone_t *zone) {
5891 REQUIRE(DNS_ZONE_VALID(zone));
5894 if (zone->notify_acl != NULL)
5895 dns_acl_detach(&zone->notify_acl);
5900 dns_zone_clearqueryacl(dns_zone_t *zone) {
5902 REQUIRE(DNS_ZONE_VALID(zone));
5905 if (zone->query_acl != NULL)
5906 dns_acl_detach(&zone->query_acl);
5911 dns_zone_clearxfracl(dns_zone_t *zone) {
5913 REQUIRE(DNS_ZONE_VALID(zone));
5916 if (zone->xfr_acl != NULL)
5917 dns_acl_detach(&zone->xfr_acl);
5922 dns_zone_getupdatedisabled(dns_zone_t *zone) {
5923 REQUIRE(DNS_ZONE_VALID(zone));
5924 return (zone->update_disabled);
5929 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
5930 REQUIRE(DNS_ZONE_VALID(zone));
5931 zone->update_disabled = state;
5935 dns_zone_getzeronosoattl(dns_zone_t *zone) {
5936 REQUIRE(DNS_ZONE_VALID(zone));
5937 return (zone->zero_no_soa_ttl);
5942 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
5943 REQUIRE(DNS_ZONE_VALID(zone));
5944 zone->zero_no_soa_ttl = state;
5948 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
5950 REQUIRE(DNS_ZONE_VALID(zone));
5952 zone->check_names = severity;
5956 dns_zone_getchecknames(dns_zone_t *zone) {
5958 REQUIRE(DNS_ZONE_VALID(zone));
5960 return (zone->check_names);
5964 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
5966 REQUIRE(DNS_ZONE_VALID(zone));
5968 zone->journalsize = size;
5972 dns_zone_getjournalsize(dns_zone_t *zone) {
5974 REQUIRE(DNS_ZONE_VALID(zone));
5976 return (zone->journalsize);
5980 zone_tostr(dns_zone_t *zone, char *buf, size_t length) {
5981 isc_result_t result = ISC_R_FAILURE;
5982 isc_buffer_t buffer;
5984 REQUIRE(buf != NULL);
5985 REQUIRE(length > 1U);
5988 * Leave space for terminating '\0'.
5990 isc_buffer_init(&buffer, buf, length - 1);
5991 if (dns_name_dynamic(&zone->origin))
5992 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
5993 if (result != ISC_R_SUCCESS &&
5994 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
5995 isc_buffer_putstr(&buffer, "<UNKNOWN>");
5997 if (isc_buffer_availablelength(&buffer) > 0)
5998 isc_buffer_putstr(&buffer, "/");
5999 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
6001 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
6002 strcmp(zone->view->name, "_default") != 0 &&
6003 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
6004 isc_buffer_putstr(&buffer, "/");
6005 isc_buffer_putstr(&buffer, zone->view->name);
6008 buf[isc_buffer_usedlength(&buffer)] = '\0';
6012 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
6013 REQUIRE(DNS_ZONE_VALID(zone));
6014 REQUIRE(buf != NULL);
6015 zone_tostr(zone, buf, length);
6019 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
6022 char namebuf[1024+32];
6024 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6027 zone_tostr(zone, namebuf, sizeof(namebuf));
6030 vsnprintf(message, sizeof(message), fmt, ap);
6032 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
6033 level, "zone %s: %s", namebuf, message);
6037 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
6038 int level, const char *fmt, ...) {
6041 char namebuf[1024+32];
6043 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6046 zone_tostr(zone, namebuf, sizeof(namebuf));
6049 vsnprintf(message, sizeof(message), fmt, ap);
6051 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
6052 level, "zone %s: %s", namebuf, message);
6056 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
6059 char namebuf[1024+32];
6061 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6064 zone_tostr(zone, namebuf, sizeof(namebuf));
6067 vsnprintf(message, sizeof(message), fmt, ap);
6069 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
6070 level, "zone %s: %s", namebuf, message);
6074 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
6075 const char *fmt, ...)
6079 char namebuf[1024+32];
6080 int level = ISC_LOG_DEBUG(debuglevel);
6082 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6085 zone_tostr(zone, namebuf, sizeof(namebuf));
6088 vsnprintf(message, sizeof(message), fmt, ap);
6090 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
6091 level, "%s: zone %s: %s", me, namebuf, message);
6095 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
6097 isc_result_t result;
6099 dns_rdataset_t *curr;
6102 result = dns_message_firstname(msg, section);
6103 while (result == ISC_R_SUCCESS) {
6105 dns_message_currentname(msg, section, &name);
6107 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
6108 curr = ISC_LIST_PREV(curr, link)) {
6109 if (curr->type == type)
6112 result = dns_message_nextname(msg, section);
6119 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
6120 REQUIRE(DNS_ZONE_VALID(zone));
6122 zone->maxxfrin = maxxfrin;
6126 dns_zone_getmaxxfrin(dns_zone_t *zone) {
6127 REQUIRE(DNS_ZONE_VALID(zone));
6129 return (zone->maxxfrin);
6133 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
6134 REQUIRE(DNS_ZONE_VALID(zone));
6135 zone->maxxfrout = maxxfrout;
6139 dns_zone_getmaxxfrout(dns_zone_t *zone) {
6140 REQUIRE(DNS_ZONE_VALID(zone));
6142 return (zone->maxxfrout);
6146 dns_zone_gettype(dns_zone_t *zone) {
6147 REQUIRE(DNS_ZONE_VALID(zone));
6149 return (zone->type);
6153 dns_zone_getorigin(dns_zone_t *zone) {
6154 REQUIRE(DNS_ZONE_VALID(zone));
6156 return (&zone->origin);
6160 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
6161 REQUIRE(DNS_ZONE_VALID(zone));
6164 if (zone->task != NULL)
6165 isc_task_detach(&zone->task);
6166 isc_task_attach(task, &zone->task);
6167 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6168 if (zone->db != NULL)
6169 dns_db_settask(zone->db, zone->task);
6170 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6175 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
6176 REQUIRE(DNS_ZONE_VALID(zone));
6177 isc_task_attach(zone->task, target);
6181 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
6182 REQUIRE(DNS_ZONE_VALID(zone));
6185 idlein = DNS_DEFAULT_IDLEIN;
6186 zone->idlein = idlein;
6190 dns_zone_getidlein(dns_zone_t *zone) {
6191 REQUIRE(DNS_ZONE_VALID(zone));
6193 return (zone->idlein);
6197 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
6198 REQUIRE(DNS_ZONE_VALID(zone));
6200 zone->idleout = idleout;
6204 dns_zone_getidleout(dns_zone_t *zone) {
6205 REQUIRE(DNS_ZONE_VALID(zone));
6207 return (zone->idleout);
6211 notify_done(isc_task_t *task, isc_event_t *event) {
6212 dns_requestevent_t *revent = (dns_requestevent_t *)event;
6213 dns_notify_t *notify;
6214 isc_result_t result;
6215 dns_message_t *message = NULL;
6218 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6222 notify = event->ev_arg;
6223 REQUIRE(DNS_NOTIFY_VALID(notify));
6224 INSIST(task == notify->zone->task);
6226 isc_buffer_init(&buf, rcode, sizeof(rcode));
6227 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6229 result = revent->result;
6230 if (result == ISC_R_SUCCESS)
6231 result = dns_message_create(notify->zone->mctx,
6232 DNS_MESSAGE_INTENTPARSE, &message);
6233 if (result == ISC_R_SUCCESS)
6234 result = dns_request_getresponse(revent->request, message,
6235 DNS_MESSAGEPARSE_PRESERVEORDER);
6236 if (result == ISC_R_SUCCESS)
6237 result = dns_rcode_totext(message->rcode, &buf);
6238 if (result == ISC_R_SUCCESS)
6239 notify_log(notify->zone, ISC_LOG_DEBUG(3),
6240 "notify response from %s: %.*s",
6241 addrbuf, (int)buf.used, rcode);
6243 notify_log(notify->zone, ISC_LOG_DEBUG(2),
6244 "notify to %s failed: %s", addrbuf,
6245 dns_result_totext(result));
6248 * Old bind's return formerr if they see a soa record. Retry w/o
6249 * the soa if we see a formerr and had sent a SOA.
6251 isc_event_free(&event);
6252 if (message != NULL && message->rcode == dns_rcode_formerr &&
6253 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
6254 notify->flags |= DNS_NOTIFY_NOSOA;
6255 dns_request_destroy(¬ify->request);
6256 result = notify_send_queue(notify);
6257 if (result != ISC_R_SUCCESS)
6258 notify_destroy(notify, ISC_FALSE);
6260 if (result == ISC_R_TIMEDOUT)
6261 notify_log(notify->zone, ISC_LOG_DEBUG(1),
6262 "notify to %s: retries exceeded", addrbuf);
6263 notify_destroy(notify, ISC_FALSE);
6265 if (message != NULL)
6266 dns_message_destroy(&message);
6270 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
6271 isc_result_t result;
6273 REQUIRE(DNS_ZONE_VALID(zone));
6275 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6276 result = zone_replacedb(zone, db, dump);
6277 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6283 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
6284 dns_dbversion_t *ver;
6285 isc_result_t result;
6286 unsigned int soacount = 0;
6287 unsigned int nscount = 0;
6290 * 'zone' and 'zonedb' locked by caller.
6292 REQUIRE(DNS_ZONE_VALID(zone));
6293 REQUIRE(LOCKED_ZONE(zone));
6295 result = zone_get_from_db(zone, db, &nscount, &soacount,
6296 NULL, NULL, NULL, NULL, NULL, NULL);
6297 if (result == ISC_R_SUCCESS) {
6298 if (soacount != 1) {
6299 dns_zone_log(zone, ISC_LOG_ERROR,
6300 "has %d SOA records", soacount);
6301 result = DNS_R_BADZONE;
6304 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
6305 result = DNS_R_BADZONE;
6307 if (result != ISC_R_SUCCESS)
6310 dns_zone_log(zone, ISC_LOG_ERROR,
6311 "retrieving SOA and NS records failed: %s",
6312 dns_result_totext(result));
6317 dns_db_currentversion(db, &ver);
6320 * The initial version of a slave zone is always dumped;
6321 * subsequent versions may be journalled instead if this
6322 * is enabled in the configuration.
6324 if (zone->db != NULL && zone->journal != NULL &&
6325 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
6326 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
6327 isc_uint32_t serial;
6329 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
6331 result = dns_db_getsoaserial(db, ver, &serial);
6332 if (result != ISC_R_SUCCESS) {
6333 dns_zone_log(zone, ISC_LOG_ERROR,
6334 "ixfr-from-differences: unable to get "
6340 * This is checked in zone_postload() for master zones.
6342 if (zone->type == dns_zone_slave &&
6343 !isc_serial_gt(serial, zone->serial)) {
6344 isc_uint32_t serialmin, serialmax;
6345 serialmin = (zone->serial + 1) & 0xffffffffU;
6346 serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU;
6347 dns_zone_log(zone, ISC_LOG_ERROR,
6348 "ixfr-from-differences: failed: "
6349 "new serial (%u) out of range [%u - %u]",
6350 serial, serialmin, serialmax);
6351 result = ISC_R_RANGE;
6355 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
6357 if (result != ISC_R_SUCCESS)
6360 zone_needdump(zone, DNS_DUMP_DELAY);
6361 else if (zone->journalsize != -1) {
6362 result = dns_journal_compact(zone->mctx, zone->journal,
6363 serial, zone->journalsize);
6367 case ISC_R_NOTFOUND:
6368 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6369 "dns_journal_compact: %s",
6370 dns_result_totext(result));
6373 dns_zone_log(zone, ISC_LOG_ERROR,
6374 "dns_journal_compact failed: %s",
6375 dns_result_totext(result));
6380 if (dump && zone->masterfile != NULL) {
6381 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6382 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6383 "dumping new zone version");
6384 result = dns_db_dump2(db, ver, zone->masterfile,
6385 zone->masterformat);
6386 if (result != ISC_R_SUCCESS)
6390 * Update the time the zone was updated, so
6391 * dns_zone_load can avoid loading it when
6392 * the server is reloaded. If isc_time_now
6393 * fails for some reason, all that happens is
6394 * the timestamp is not updated.
6396 TIME_NOW(&zone->loadtime);
6399 if (dump && zone->journal != NULL) {
6401 * The in-memory database just changed, and
6402 * because 'dump' is set, it didn't change by
6403 * being loaded from disk. Also, we have not
6404 * journalled diffs for this change.
6405 * Therefore, the on-disk journal is missing
6406 * the deltas for this change. Since it can
6407 * no longer be used to bring the zone
6408 * up-to-date, it is useless and should be
6411 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6412 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6413 "removing journal file");
6414 (void)remove(zone->journal);
6418 dns_db_closeversion(db, &ver, ISC_FALSE);
6420 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6421 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6422 "replacing zone database");
6424 if (zone->db != NULL)
6425 zone_detachdb(zone);
6426 zone_attachdb(zone, db);
6427 dns_db_settask(zone->db, zone->task);
6428 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
6429 return (ISC_R_SUCCESS);
6432 dns_db_closeversion(db, &ver, ISC_FALSE);
6436 /* The caller must hold the dblock as a writer. */
6438 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
6439 REQUIRE(zone->db == NULL && db != NULL);
6441 dns_db_attach(db, &zone->db);
6442 if (zone->acache != NULL) {
6443 isc_result_t result;
6444 result = dns_acache_setdb(zone->acache, db);
6445 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
6446 UNEXPECTED_ERROR(__FILE__, __LINE__,
6447 "dns_acache_setdb() failed: %s",
6448 isc_result_totext(result));
6453 /* The caller must hold the dblock as a writer. */
6455 zone_detachdb(dns_zone_t *zone) {
6456 REQUIRE(zone->db != NULL);
6458 if (zone->acache != NULL)
6459 (void)dns_acache_putdb(zone->acache, zone->db);
6460 dns_db_detach(&zone->db);
6464 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
6466 isc_boolean_t again = ISC_FALSE;
6467 unsigned int soacount;
6468 unsigned int nscount;
6469 isc_uint32_t serial, refresh, retry, expire, minimum;
6470 isc_result_t xfrresult = result;
6471 isc_boolean_t free_needed;
6473 REQUIRE(DNS_ZONE_VALID(zone));
6475 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6476 "zone transfer finished: %s", dns_result_totext(result));
6479 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
6480 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
6481 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
6486 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6488 case DNS_R_UPTODATE:
6489 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
6491 * Has the zone expired underneath us?
6493 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6494 if (zone->db == NULL) {
6495 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6500 * Update the zone structure's data from the actual
6505 INSIST(zone->db != NULL);
6506 result = zone_get_from_db(zone, zone->db, &nscount,
6507 &soacount, &serial, &refresh,
6508 &retry, &expire, &minimum, NULL);
6509 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6510 if (result == ISC_R_SUCCESS) {
6512 dns_zone_log(zone, ISC_LOG_ERROR,
6514 "has %d SOA record%s", soacount,
6515 (soacount != 0) ? "s" : "");
6517 dns_zone_log(zone, ISC_LOG_ERROR,
6519 "has no NS records");
6520 if (DNS_ZONE_FLAG(zone,
6521 DNS_ZONEFLG_HAVETIMERS)) {
6522 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
6523 zone->retry = DNS_ZONE_DEFAULTRETRY;
6525 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6529 zone->serial = serial;
6530 zone->refresh = RANGE(refresh, zone->minrefresh,
6532 zone->retry = RANGE(retry, zone->minretry,
6534 zone->expire = RANGE(expire,
6535 zone->refresh + zone->retry,
6537 zone->minimum = minimum;
6538 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6542 * Set our next update/expire times.
6544 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
6545 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
6546 zone->refreshtime = now;
6547 DNS_ZONE_TIME_ADD(&now, zone->expire,
6550 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
6551 &zone->refreshtime);
6552 DNS_ZONE_TIME_ADD(&now, zone->expire,
6555 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
6556 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
6557 if (zone->tsigkey != NULL) {
6558 char namebuf[DNS_NAME_FORMATSIZE];
6559 dns_name_format(&zone->tsigkey->name, namebuf,
6561 snprintf(buf, sizeof(buf), ": TSIG '%s'",
6565 dns_zone_log(zone, ISC_LOG_INFO,
6566 "transferred serial %u%s",
6571 * This is not neccessary if we just performed a AXFR
6572 * however it is necessary for an IXFR / UPTODATE and
6573 * won't hurt with an AXFR.
6575 if (zone->masterfile != NULL || zone->journal != NULL) {
6576 result = ISC_R_FAILURE;
6577 if (zone->journal != NULL)
6578 result = isc_file_settime(zone->journal, &now);
6579 if (result != ISC_R_SUCCESS &&
6580 zone->masterfile != NULL)
6581 result = isc_file_settime(zone->masterfile,
6583 /* Someone removed the file from underneath us! */
6584 if (result == ISC_R_FILENOTFOUND &&
6585 zone->masterfile != NULL)
6586 zone_needdump(zone, DNS_DUMP_DELAY);
6587 else if (result != ISC_R_SUCCESS)
6588 dns_zone_log(zone, ISC_LOG_ERROR,
6589 "transfer: could not set file "
6590 "modification time of '%s': %s",
6592 dns_result_totext(result));
6598 /* Force retry with AXFR. */
6599 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
6605 * Skip to next failed / untried master.
6609 } while (zone->curmaster < zone->masterscnt &&
6610 zone->mastersok[zone->curmaster]);
6613 if (zone->curmaster >= zone->masterscnt) {
6614 zone->curmaster = 0;
6615 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
6616 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
6617 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6618 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6619 while (zone->curmaster < zone->masterscnt &&
6620 zone->mastersok[zone->curmaster])
6624 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6626 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6631 zone_settimer(zone, &now);
6634 * If creating the transfer object failed, zone->xfr is NULL.
6635 * Otherwise, we are called as the done callback of a zone
6636 * transfer object that just entered its shutting-down
6637 * state. Since we are no longer responsible for shutting
6638 * it down, we can detach our reference.
6640 if (zone->xfr != NULL)
6641 dns_xfrin_detach(&zone->xfr);
6643 if (zone->tsigkey != NULL)
6644 dns_tsigkey_detach(&zone->tsigkey);
6647 * Handle any deferred journal compaction.
6649 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
6650 result = dns_journal_compact(zone->mctx, zone->journal,
6651 zone->compact_serial,
6656 case ISC_R_NOTFOUND:
6657 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6658 "dns_journal_compact: %s",
6659 dns_result_totext(result));
6662 dns_zone_log(zone, ISC_LOG_ERROR,
6663 "dns_journal_compact failed: %s",
6664 dns_result_totext(result));
6667 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
6671 * This transfer finishing freed up a transfer quota slot.
6672 * Let any other zones waiting for quota have it.
6674 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
6675 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
6676 zone->statelist = NULL;
6677 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
6678 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
6681 * Retry with a different server if necessary.
6683 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
6684 queue_soa_query(zone);
6686 INSIST(zone->irefs > 0);
6688 free_needed = exit_check(zone);
6695 zone_loaddone(void *arg, isc_result_t result) {
6696 static char me[] = "zone_loaddone";
6697 dns_load_t *load = arg;
6699 isc_result_t tresult;
6701 REQUIRE(DNS_LOAD_VALID(load));
6706 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
6707 if (tresult != ISC_R_SUCCESS &&
6708 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
6711 LOCK_ZONE(load->zone);
6712 (void)zone_postload(load->zone, load->db, load->loadtime, result);
6713 zonemgr_putio(&load->zone->readio);
6714 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
6715 UNLOCK_ZONE(load->zone);
6718 dns_db_detach(&load->db);
6719 if (load->zone->lctx != NULL)
6720 dns_loadctx_detach(&load->zone->lctx);
6721 dns_zone_idetach(&load->zone);
6722 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
6726 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
6727 REQUIRE(DNS_ZONE_VALID(zone));
6728 REQUIRE(table != NULL);
6729 REQUIRE(*table == NULL);
6732 if (zone->ssutable != NULL)
6733 dns_ssutable_attach(zone->ssutable, table);
6738 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
6739 REQUIRE(DNS_ZONE_VALID(zone));
6742 if (zone->ssutable != NULL)
6743 dns_ssutable_detach(&zone->ssutable);
6745 dns_ssutable_attach(table, &zone->ssutable);
6750 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
6751 REQUIRE(DNS_ZONE_VALID(zone));
6753 zone->sigvalidityinterval = interval;
6757 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
6758 REQUIRE(DNS_ZONE_VALID(zone));
6760 return (zone->sigvalidityinterval);
6764 queue_xfrin(dns_zone_t *zone) {
6765 const char me[] = "queue_xfrin";
6766 isc_result_t result;
6767 dns_zonemgr_t *zmgr = zone->zmgr;
6771 INSIST(zone->statelist == NULL);
6773 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
6774 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
6778 zone->statelist = &zmgr->waiting_for_xfrin;
6779 result = zmgr_start_xfrin_ifquota(zmgr, zone);
6780 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
6782 if (result == ISC_R_QUOTA) {
6783 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
6784 "zone transfer deferred due to quota");
6785 } else if (result != ISC_R_SUCCESS) {
6786 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
6787 "starting zone transfer: %s",
6788 isc_result_totext(result));
6793 * This event callback is called when a zone has received
6794 * any necessary zone transfer quota. This is the time
6795 * to go ahead and start the transfer.
6798 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
6799 isc_result_t result;
6800 dns_peer_t *peer = NULL;
6801 char mastertext[256];
6802 dns_rdatatype_t xfrtype;
6803 dns_zone_t *zone = event->ev_arg;
6804 isc_netaddr_t masterip;
6805 isc_sockaddr_t sourceaddr;
6806 isc_sockaddr_t masteraddr;
6810 INSIST(task == zone->task);
6812 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
6813 result = ISC_R_CANCELED;
6817 isc_sockaddr_format(&zone->masteraddr, mastertext, sizeof(mastertext));
6819 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
6820 (void)dns_peerlist_peerbyaddr(zone->view->peers,
6824 * Decide whether we should request IXFR or AXFR.
6826 if (zone->db == NULL) {
6827 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6828 "no database exists yet, "
6829 "requesting AXFR of "
6830 "initial version from %s", mastertext);
6831 xfrtype = dns_rdatatype_axfr;
6832 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
6833 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
6834 "set, requesting AXFR from %s", mastertext);
6835 xfrtype = dns_rdatatype_axfr;
6836 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
6837 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6838 "forced reload, requesting AXFR of "
6839 "initial version from %s", mastertext);
6840 xfrtype = dns_rdatatype_axfr;
6841 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
6842 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6843 "retrying with AXFR from %s due to "
6844 "previous IXFR failure", mastertext);
6845 xfrtype = dns_rdatatype_axfr;
6847 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
6850 isc_boolean_t use_ixfr = ISC_TRUE;
6852 dns_peer_getrequestixfr(peer, &use_ixfr) ==
6854 ; /* Using peer setting */
6856 use_ixfr = zone->view->requestixfr;
6858 if (use_ixfr == ISC_FALSE) {
6859 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6861 "requesting AXFR from %s",
6863 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
6864 xfrtype = dns_rdatatype_soa;
6866 xfrtype = dns_rdatatype_axfr;
6868 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6869 "requesting IXFR from %s",
6871 xfrtype = dns_rdatatype_ixfr;
6876 * Determine if we should attempt to sign the request with TSIG.
6878 result = ISC_R_NOTFOUND;
6880 * First, look for a tsig key in the master statement, then
6881 * try for a server key.
6883 if ((zone->masterkeynames != NULL) &&
6884 (zone->masterkeynames[zone->curmaster] != NULL)) {
6885 dns_view_t *view = dns_zone_getview(zone);
6886 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
6887 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
6889 if (zone->tsigkey == NULL)
6890 result = dns_view_getpeertsig(zone->view, &masterip,
6893 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6894 dns_zone_log(zone, ISC_LOG_ERROR,
6895 "could not get TSIG key "
6896 "for zone transfer: %s",
6897 isc_result_totext(result));
6901 masteraddr = zone->masteraddr;
6902 sourceaddr = zone->sourceaddr;
6904 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
6905 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
6906 zone->tsigkey, zone->mctx,
6907 zone->zmgr->timermgr, zone->zmgr->socketmgr,
6908 zone->task, zone_xfrdone, &zone->xfr);
6911 * Any failure in this function is handled like a failed
6912 * zone transfer. This ensures that we get removed from
6913 * zmgr->xfrin_in_progress.
6915 if (result != ISC_R_SUCCESS)
6916 zone_xfrdone(zone, result);
6918 isc_event_free(&event);
6922 * Update forwarding support.
6926 forward_destroy(dns_forward_t *forward) {
6929 if (forward->request != NULL)
6930 dns_request_destroy(&forward->request);
6931 if (forward->msgbuf != NULL)
6932 isc_buffer_free(&forward->msgbuf);
6933 if (forward->zone != NULL)
6934 dns_zone_idetach(&forward->zone);
6935 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
6939 sendtomaster(dns_forward_t *forward) {
6940 isc_result_t result;
6943 LOCK_ZONE(forward->zone);
6944 if (forward->which >= forward->zone->masterscnt) {
6945 UNLOCK_ZONE(forward->zone);
6946 return (ISC_R_NOMORE);
6949 forward->addr = forward->zone->masters[forward->which];
6951 * Always use TCP regardless of whether the original update
6953 * XXX The timeout may but a bit small if we are far down a
6954 * transfer graph and the master has to try several masters.
6956 switch (isc_sockaddr_pf(&forward->addr)) {
6958 src = forward->zone->xfrsource4;
6961 src = forward->zone->xfrsource6;
6964 result = ISC_R_NOTIMPLEMENTED;
6967 result = dns_request_createraw(forward->zone->view->requestmgr,
6969 &src, &forward->addr,
6970 DNS_REQUESTOPT_TCP, 15 /* XXX */,
6971 forward->zone->task,
6972 forward_callback, forward,
6975 UNLOCK_ZONE(forward->zone);
6980 forward_callback(isc_task_t *task, isc_event_t *event) {
6981 const char me[] = "forward_callback";
6982 dns_requestevent_t *revent = (dns_requestevent_t *)event;
6983 dns_message_t *msg = NULL;
6984 char master[ISC_SOCKADDR_FORMATSIZE];
6985 isc_result_t result;
6986 dns_forward_t *forward;
6991 forward = revent->ev_arg;
6992 INSIST(DNS_FORWARD_VALID(forward));
6993 zone = forward->zone;
6994 INSIST(DNS_ZONE_VALID(zone));
6998 isc_sockaddr_format(&forward->addr, master, sizeof(master));
7000 if (revent->result != ISC_R_SUCCESS) {
7001 dns_zone_log(zone, ISC_LOG_INFO,
7002 "could not forward dynamic update to %s: %s",
7003 master, dns_result_totext(revent->result));
7007 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7008 if (result != ISC_R_SUCCESS)
7011 result = dns_request_getresponse(revent->request, msg,
7012 DNS_MESSAGEPARSE_PRESERVEORDER |
7013 DNS_MESSAGEPARSE_CLONEBUFFER);
7014 if (result != ISC_R_SUCCESS)
7017 switch (msg->rcode) {
7019 * Pass these rcodes back to client.
7021 case dns_rcode_noerror:
7022 case dns_rcode_yxdomain:
7023 case dns_rcode_yxrrset:
7024 case dns_rcode_nxrrset:
7025 case dns_rcode_refused:
7026 case dns_rcode_nxdomain:
7029 /* These should not occur if the masters/zone are valid. */
7030 case dns_rcode_notzone:
7031 case dns_rcode_notauth: {
7035 isc_buffer_init(&rb, rcode, sizeof(rcode));
7036 (void)dns_rcode_totext(msg->rcode, &rb);
7037 dns_zone_log(zone, ISC_LOG_WARNING,
7038 "forwarding dynamic update: "
7039 "unexpected response: master %s returned: %.*s",
7040 master, (int)rb.used, rcode);
7044 /* Try another server for these rcodes. */
7045 case dns_rcode_formerr:
7046 case dns_rcode_servfail:
7047 case dns_rcode_notimp:
7048 case dns_rcode_badvers:
7054 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
7056 dns_request_destroy(&forward->request);
7057 forward_destroy(forward);
7058 isc_event_free(&event);
7063 dns_message_destroy(&msg);
7064 isc_event_free(&event);
7066 dns_request_destroy(&forward->request);
7067 result = sendtomaster(forward);
7068 if (result != ISC_R_SUCCESS) {
7070 dns_zone_log(zone, ISC_LOG_DEBUG(3),
7071 "exhausted dynamic update forwarder list");
7072 (forward->callback)(forward->callback_arg, result, NULL);
7073 forward_destroy(forward);
7078 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
7079 dns_updatecallback_t callback, void *callback_arg)
7081 dns_forward_t *forward;
7082 isc_result_t result;
7085 REQUIRE(DNS_ZONE_VALID(zone));
7086 REQUIRE(msg != NULL);
7087 REQUIRE(callback != NULL);
7089 forward = isc_mem_get(zone->mctx, sizeof(*forward));
7090 if (forward == NULL)
7091 return (ISC_R_NOMEMORY);
7093 forward->request = NULL;
7094 forward->zone = NULL;
7095 forward->msgbuf = NULL;
7098 forward->callback = callback;
7099 forward->callback_arg = callback_arg;
7100 forward->magic = FORWARD_MAGIC;
7102 mr = dns_message_getrawmessage(msg);
7104 result = ISC_R_UNEXPECTEDEND;
7108 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
7109 if (result != ISC_R_SUCCESS)
7111 result = isc_buffer_copyregion(forward->msgbuf, mr);
7112 if (result != ISC_R_SUCCESS)
7115 isc_mem_attach(zone->mctx, &forward->mctx);
7116 dns_zone_iattach(zone, &forward->zone);
7117 result = sendtomaster(forward);
7120 if (result != ISC_R_SUCCESS) {
7121 forward_destroy(forward);
7127 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
7128 REQUIRE(DNS_ZONE_VALID(zone));
7129 REQUIRE(next != NULL && *next == NULL);
7131 *next = ISC_LIST_NEXT(zone, link);
7133 return (ISC_R_NOMORE);
7135 return (ISC_R_SUCCESS);
7139 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
7140 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7141 REQUIRE(first != NULL && *first == NULL);
7143 *first = ISC_LIST_HEAD(zmgr->zones);
7145 return (ISC_R_NOMORE);
7147 return (ISC_R_SUCCESS);
7155 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
7156 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
7157 dns_zonemgr_t **zmgrp)
7159 dns_zonemgr_t *zmgr;
7160 isc_result_t result;
7161 isc_interval_t interval;
7163 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
7165 return (ISC_R_NOMEMORY);
7168 isc_mem_attach(mctx, &zmgr->mctx);
7169 zmgr->taskmgr = taskmgr;
7170 zmgr->timermgr = timermgr;
7171 zmgr->socketmgr = socketmgr;
7172 zmgr->zonetasks = NULL;
7175 ISC_LIST_INIT(zmgr->zones);
7176 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
7177 ISC_LIST_INIT(zmgr->xfrin_in_progress);
7178 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
7179 if (result != ISC_R_SUCCESS)
7182 zmgr->transfersin = 10;
7183 zmgr->transfersperns = 2;
7185 /* Create the zone task pool. */
7186 result = isc_taskpool_create(taskmgr, mctx,
7187 8 /* XXX */, 2, &zmgr->zonetasks);
7188 if (result != ISC_R_SUCCESS)
7191 /* Create a single task for queueing of SOA queries. */
7192 result = isc_task_create(taskmgr, 1, &zmgr->task);
7193 if (result != ISC_R_SUCCESS)
7195 isc_task_setname(zmgr->task, "zmgr", zmgr);
7196 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
7198 if (result != ISC_R_SUCCESS)
7200 /* default to 20 refresh queries / notifies per second. */
7201 isc_interval_set(&interval, 0, 1000000000/2);
7202 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
7203 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7204 isc_ratelimiter_setpertic(zmgr->rl, 10);
7208 ISC_LIST_INIT(zmgr->high);
7209 ISC_LIST_INIT(zmgr->low);
7211 result = isc_mutex_init(&zmgr->iolock);
7212 if (result != ISC_R_SUCCESS)
7215 zmgr->magic = ZONEMGR_MAGIC;
7218 return (ISC_R_SUCCESS);
7222 DESTROYLOCK(&zmgr->iolock);
7225 isc_ratelimiter_detach(&zmgr->rl);
7227 isc_task_detach(&zmgr->task);
7229 isc_taskpool_destroy(&zmgr->zonetasks);
7231 isc_rwlock_destroy(&zmgr->rwlock);
7233 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
7234 isc_mem_detach(&mctx);
7239 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7240 isc_result_t result;
7242 REQUIRE(DNS_ZONE_VALID(zone));
7243 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7245 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7247 REQUIRE(zone->task == NULL);
7248 REQUIRE(zone->timer == NULL);
7249 REQUIRE(zone->zmgr == NULL);
7251 isc_taskpool_gettask(zmgr->zonetasks,
7252 dns_name_hash(dns_zone_getorigin(zone),
7257 * Set the task name. The tag will arbitrarily point to one
7258 * of the zones sharing the task (in practice, the one
7259 * to be managed last).
7261 isc_task_setname(zone->task, "zone", zone);
7263 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
7265 zone->task, zone_timer, zone,
7267 if (result != ISC_R_SUCCESS)
7270 * The timer "holds" a iref.
7273 INSIST(zone->irefs != 0);
7275 ISC_LIST_APPEND(zmgr->zones, zone, link);
7282 isc_task_detach(&zone->task);
7286 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7291 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7292 isc_boolean_t free_now = ISC_FALSE;
7294 REQUIRE(DNS_ZONE_VALID(zone));
7295 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7296 REQUIRE(zone->zmgr == zmgr);
7298 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7301 ISC_LIST_UNLINK(zmgr->zones, zone, link);
7304 if (zmgr->refs == 0)
7305 free_now = ISC_TRUE;
7308 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7312 ENSURE(zone->zmgr == NULL);
7316 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
7317 REQUIRE(DNS_ZONEMGR_VALID(source));
7318 REQUIRE(target != NULL && *target == NULL);
7320 RWLOCK(&source->rwlock, isc_rwlocktype_write);
7321 REQUIRE(source->refs > 0);
7323 INSIST(source->refs > 0);
7324 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
7329 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
7330 dns_zonemgr_t *zmgr;
7331 isc_boolean_t free_now = ISC_FALSE;
7333 REQUIRE(zmgrp != NULL);
7335 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7337 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7339 if (zmgr->refs == 0)
7340 free_now = ISC_TRUE;
7341 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7348 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
7351 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7353 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7354 for (p = ISC_LIST_HEAD(zmgr->zones);
7356 p = ISC_LIST_NEXT(p, link))
7358 dns_zone_maintenance(p);
7360 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7363 * Recent configuration changes may have increased the
7364 * amount of available transfers quota. Make sure any
7365 * transfers currently blocked on quota get started if
7368 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7369 zmgr_resume_xfrs(zmgr, ISC_TRUE);
7370 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7371 return (ISC_R_SUCCESS);
7375 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
7377 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7379 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7380 zmgr_resume_xfrs(zmgr, ISC_TRUE);
7381 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7385 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
7386 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7388 isc_ratelimiter_shutdown(zmgr->rl);
7390 if (zmgr->task != NULL)
7391 isc_task_destroy(&zmgr->task);
7392 if (zmgr->zonetasks != NULL)
7393 isc_taskpool_destroy(&zmgr->zonetasks);
7397 zonemgr_free(dns_zonemgr_t *zmgr) {
7400 INSIST(zmgr->refs == 0);
7401 INSIST(ISC_LIST_EMPTY(zmgr->zones));
7405 DESTROYLOCK(&zmgr->iolock);
7406 isc_ratelimiter_detach(&zmgr->rl);
7408 isc_rwlock_destroy(&zmgr->rwlock);
7410 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
7411 isc_mem_detach(&mctx);
7415 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
7416 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7418 zmgr->transfersin = value;
7422 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
7423 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7425 return (zmgr->transfersin);
7429 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
7430 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7432 zmgr->transfersperns = value;
7436 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
7437 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7439 return (zmgr->transfersperns);
7443 * Try to start a new incoming zone transfer to fill a quota
7444 * slot that was just vacated.
7447 * The zone manager is locked by the caller.
7450 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
7454 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
7458 isc_result_t result;
7459 next = ISC_LIST_NEXT(zone, statelink);
7460 result = zmgr_start_xfrin_ifquota(zmgr, zone);
7461 if (result == ISC_R_SUCCESS) {
7465 * We successfully filled the slot. We're done.
7468 } else if (result == ISC_R_QUOTA) {
7470 * Not enough quota. This is probably the per-server
7471 * quota, because we usually get called when a unit of
7472 * global quota has just been freed. Try the next
7473 * zone, it may succeed if it uses another master.
7477 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7478 "starting zone transfer: %s",
7479 isc_result_totext(result));
7486 * Try to start an incoming zone transfer for 'zone', quota permitting.
7489 * The zone manager is locked by the caller.
7492 * ISC_R_SUCCESS There was enough quota and we attempted to
7493 * start a transfer. zone_xfrdone() has been or will
7495 * ISC_R_QUOTA Not enough quota.
7499 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7500 dns_peer_t *peer = NULL;
7501 isc_netaddr_t masterip;
7502 isc_uint32_t nxfrsin, nxfrsperns;
7504 isc_uint32_t maxtransfersin, maxtransfersperns;
7508 * Find any configured information about the server we'd
7509 * like to transfer this zone from.
7511 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
7512 (void)dns_peerlist_peerbyaddr(zone->view->peers,
7516 * Determine the total maximum number of simultaneous
7517 * transfers allowed, and the maximum for this specific
7520 maxtransfersin = zmgr->transfersin;
7521 maxtransfersperns = zmgr->transfersperns;
7523 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
7526 * Count the total number of transfers that are in progress,
7527 * and the number of transfers in progress from this master.
7528 * We linearly scan a list of all transfers; if this turns
7529 * out to be too slow, we could hash on the master address.
7531 nxfrsin = nxfrsperns = 0;
7532 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
7534 x = ISC_LIST_NEXT(x, statelink))
7537 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
7539 if (isc_netaddr_equal(&xip, &masterip))
7543 /* Enforce quota. */
7544 if (nxfrsin >= maxtransfersin)
7545 return (ISC_R_QUOTA);
7547 if (nxfrsperns >= maxtransfersperns)
7548 return (ISC_R_QUOTA);
7551 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
7552 * list and send it an event to let it start the actual transfer in the
7553 * context of its own task.
7555 e = isc_event_allocate(zmgr->mctx, zmgr,
7556 DNS_EVENT_ZONESTARTXFRIN,
7557 got_transfer_quota, zone,
7558 sizeof(isc_event_t));
7560 return (ISC_R_NOMEMORY);
7563 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
7564 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
7565 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
7566 zone->statelist = &zmgr->xfrin_in_progress;
7567 isc_task_send(zone->task, &e);
7568 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
7571 return (ISC_R_SUCCESS);
7575 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
7577 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7578 REQUIRE(iolimit > 0);
7580 zmgr->iolimit = iolimit;
7584 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
7586 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7588 return (zmgr->iolimit);
7592 * Get permission to request a file handle from the OS.
7593 * An event will be sent to action when one is available.
7594 * There are two queues available (high and low), the high
7595 * queue will be serviced before the low one.
7597 * zonemgr_putio() must be called after the event is delivered to
7602 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
7603 isc_task_t *task, isc_taskaction_t action, void *arg,
7607 isc_boolean_t queue;
7609 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7610 REQUIRE(iop != NULL && *iop == NULL);
7612 io = isc_mem_get(zmgr->mctx, sizeof(*io));
7614 return (ISC_R_NOMEMORY);
7615 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
7616 action, arg, sizeof(*io->event));
7617 if (io->event == NULL) {
7618 isc_mem_put(zmgr->mctx, io, sizeof(*io));
7619 return (ISC_R_NOMEMORY);
7624 isc_task_attach(task, &io->task);
7625 ISC_LINK_INIT(io, link);
7626 io->magic = IO_MAGIC;
7628 LOCK(&zmgr->iolock);
7630 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
7633 ISC_LIST_APPEND(zmgr->high, io, link);
7635 ISC_LIST_APPEND(zmgr->low, io, link);
7637 UNLOCK(&zmgr->iolock);
7641 isc_task_send(io->task, &io->event);
7643 return (ISC_R_SUCCESS);
7647 zonemgr_putio(dns_io_t **iop) {
7650 dns_zonemgr_t *zmgr;
7652 REQUIRE(iop != NULL);
7654 REQUIRE(DNS_IO_VALID(io));
7658 INSIST(!ISC_LINK_LINKED(io, link));
7659 INSIST(io->event == NULL);
7662 isc_task_detach(&io->task);
7664 isc_mem_put(zmgr->mctx, io, sizeof(*io));
7666 LOCK(&zmgr->iolock);
7667 INSIST(zmgr->ioactive > 0);
7669 next = HEAD(zmgr->high);
7671 next = HEAD(zmgr->low);
7674 ISC_LIST_UNLINK(zmgr->high, next, link);
7676 ISC_LIST_UNLINK(zmgr->low, next, link);
7677 INSIST(next->event != NULL);
7679 UNLOCK(&zmgr->iolock);
7681 isc_task_send(next->task, &next->event);
7685 zonemgr_cancelio(dns_io_t *io) {
7686 isc_boolean_t send_event = ISC_FALSE;
7688 REQUIRE(DNS_IO_VALID(io));
7691 * If we are queued to be run then dequeue.
7693 LOCK(&io->zmgr->iolock);
7694 if (ISC_LINK_LINKED(io, link)) {
7696 ISC_LIST_UNLINK(io->zmgr->high, io, link);
7698 ISC_LIST_UNLINK(io->zmgr->low, io, link);
7700 send_event = ISC_TRUE;
7701 INSIST(io->event != NULL);
7703 UNLOCK(&io->zmgr->iolock);
7705 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
7706 isc_task_send(io->task, &io->event);
7711 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
7714 isc_result_t result;
7716 buflen = strlen(path) + strlen(templat) + 2;
7718 buf = isc_mem_get(zone->mctx, buflen);
7722 result = isc_file_template(path, templat, buf, buflen);
7723 if (result != ISC_R_SUCCESS)
7726 result = isc_file_renameunique(path, buf);
7727 if (result != ISC_R_SUCCESS)
7730 dns_zone_log(zone, ISC_LOG_WARNING, "saved '%s' as '%s'",
7734 isc_mem_put(zone->mctx, buf, buflen);
7738 /* Hook for ondestroy notifcation from a database. */
7741 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
7742 dns_db_t *db = event->sender;
7745 isc_event_free(&event);
7747 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
7748 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
7749 "database (%p) destroyed", (void*) db);
7754 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
7755 isc_interval_t interval;
7757 isc_uint32_t pertic;
7758 isc_result_t result;
7760 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7769 } else if (value <= 10) {
7771 ns = 1000000000 / value;
7775 ns = (1000000000 / value) * 10;
7779 isc_interval_set(&interval, s, ns);
7780 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
7781 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7782 isc_ratelimiter_setpertic(zmgr->rl, pertic);
7784 zmgr->serialqueryrate = value;
7788 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
7789 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7791 return (zmgr->serialqueryrate);
7795 dns_zone_forcereload(dns_zone_t *zone) {
7796 REQUIRE(DNS_ZONE_VALID(zone));
7798 if (zone->type == dns_zone_master)
7802 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
7804 dns_zone_refresh(zone);
7808 dns_zone_isforced(dns_zone_t *zone) {
7809 REQUIRE(DNS_ZONE_VALID(zone));
7811 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
7815 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
7816 isc_result_t result = ISC_R_SUCCESS;
7820 if (zone->counters != NULL)
7822 result = dns_stats_alloccounters(zone->mctx, &zone->counters);
7824 if (zone->counters == NULL)
7826 dns_stats_freecounters(zone->mctx, &zone->counters);
7834 dns_zone_getstatscounters(dns_zone_t *zone) {
7835 return (zone->counters);
7839 dns_zone_dialup(dns_zone_t *zone) {
7841 REQUIRE(DNS_ZONE_VALID(zone));
7843 zone_debuglog(zone, "dns_zone_dialup", 3,
7844 "notify = %d, refresh = %d",
7845 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
7846 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
7848 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
7849 dns_zone_notify(zone);
7850 if (zone->type != dns_zone_master &&
7851 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
7852 dns_zone_refresh(zone);
7856 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
7857 REQUIRE(DNS_ZONE_VALID(zone));
7860 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
7861 DNS_ZONEFLG_DIALREFRESH |
7862 DNS_ZONEFLG_NOREFRESH);
7864 case dns_dialuptype_no:
7866 case dns_dialuptype_yes:
7867 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
7868 DNS_ZONEFLG_DIALREFRESH |
7869 DNS_ZONEFLG_NOREFRESH));
7871 case dns_dialuptype_notify:
7872 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
7874 case dns_dialuptype_notifypassive:
7875 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
7876 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7878 case dns_dialuptype_refresh:
7879 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
7880 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7882 case dns_dialuptype_passive:
7883 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7892 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
7893 isc_result_t result = ISC_R_SUCCESS;
7895 REQUIRE(DNS_ZONE_VALID(zone));
7898 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
7905 dns_zone_getkeydirectory(dns_zone_t *zone) {
7906 REQUIRE(DNS_ZONE_VALID(zone));
7908 return (zone->keydirectory);
7912 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
7914 unsigned int count = 0;
7916 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7918 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7920 case DNS_ZONESTATE_XFERRUNNING:
7921 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
7923 zone = ISC_LIST_NEXT(zone, statelink))
7926 case DNS_ZONESTATE_XFERDEFERRED:
7927 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
7929 zone = ISC_LIST_NEXT(zone, statelink))
7932 case DNS_ZONESTATE_SOAQUERY:
7933 for (zone = ISC_LIST_HEAD(zmgr->zones);
7935 zone = ISC_LIST_NEXT(zone, link))
7936 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
7939 case DNS_ZONESTATE_ANY:
7940 for (zone = ISC_LIST_HEAD(zmgr->zones);
7942 zone = ISC_LIST_NEXT(zone, link)) {
7943 dns_view_t *view = zone->view;
7944 if (view != NULL && strcmp(view->name, "_bind") == 0)
7953 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7959 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
7960 isc_boolean_t ok = ISC_TRUE;
7961 isc_boolean_t fail = ISC_FALSE;
7962 char namebuf[DNS_NAME_FORMATSIZE];
7963 char namebuf2[DNS_NAME_FORMATSIZE];
7964 char typebuf[DNS_RDATATYPE_FORMATSIZE];
7965 int level = ISC_LOG_WARNING;
7968 REQUIRE(DNS_ZONE_VALID(zone));
7970 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
7971 return (ISC_R_SUCCESS);
7973 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
7974 level = ISC_LOG_ERROR;
7978 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
7980 dns_name_format(name, namebuf, sizeof(namebuf));
7981 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
7982 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
7983 dns_result_totext(DNS_R_BADOWNERNAME));
7985 return (DNS_R_BADOWNERNAME);
7988 dns_name_init(&bad, NULL);
7989 ok = dns_rdata_checknames(rdata, name, &bad);
7991 dns_name_format(name, namebuf, sizeof(namebuf));
7992 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
7993 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
7994 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
7995 namebuf2, dns_result_totext(DNS_R_BADNAME));
7997 return (DNS_R_BADNAME);
8000 return (ISC_R_SUCCESS);
8004 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
8005 REQUIRE(DNS_ZONE_VALID(zone));
8006 zone->checkmx = checkmx;
8010 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
8011 REQUIRE(DNS_ZONE_VALID(zone));
8012 zone->checksrv = checksrv;
8016 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
8017 REQUIRE(DNS_ZONE_VALID(zone));
8018 zone->checkns = checkns;
8022 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
8023 REQUIRE(DNS_ZONE_VALID(zone));
8026 zone->isself = isself;
8027 zone->isselfarg = arg;
8032 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
8033 REQUIRE(DNS_ZONE_VALID(zone));
8036 zone->notifydelay = delay;
8041 dns_zone_getnotifydelay(dns_zone_t *zone) {
8042 REQUIRE(DNS_ZONE_VALID(zone));
8044 return (zone->notifydelay);