2 * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: zone.c,v 1.410.18.47 2006/12/07 06:21:16 marka 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 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
259 #define DNS_ZONE_SETFLAG(z,f) do { \
260 INSIST(LOCKED_ZONE(z)); \
263 #define DNS_ZONE_CLRFLAG(z,f) do { \
264 INSIST(LOCKED_ZONE(z)); \
265 (z)->flags &= ~(f); \
267 /* XXX MPA these may need to go back into zone.h */
268 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
269 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
270 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
271 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
272 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
273 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
274 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
275 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
276 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
277 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
279 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
281 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
283 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
284 * zone with no masters
286 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
287 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
288 * from SOA (if not set, we
290 * default timer values) */
291 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
292 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
293 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
294 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
295 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
296 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
297 #define DNS_ZONEFLG_FLUSH 0x00200000U
298 #define DNS_ZONEFLG_NOEDNS 0x00400000U
299 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
300 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
302 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
304 /* Flags for zone_load() */
305 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
310 int refs; /* Locked by rwlock */
311 isc_taskmgr_t * taskmgr;
312 isc_timermgr_t * timermgr;
313 isc_socketmgr_t * socketmgr;
314 isc_taskpool_t * zonetasks;
316 isc_ratelimiter_t * rl;
320 /* Locked by rwlock. */
321 dns_zonelist_t zones;
322 dns_zonelist_t waiting_for_xfrin;
323 dns_zonelist_t xfrin_in_progress;
325 /* Configuration data. */
326 isc_uint32_t transfersin;
327 isc_uint32_t transfersperns;
328 unsigned int serialqueryrate;
330 /* Locked by iolock */
331 isc_uint32_t iolimit;
332 isc_uint32_t ioactive;
346 dns_request_t *request;
349 ISC_LINK(dns_notify_t) link;
352 #define DNS_NOTIFY_NOSOA 0x0001U
355 * dns_stub holds state while performing a 'stub' transfer.
356 * 'db' is the zone's 'db' or a new one if this is the initial
365 dns_dbversion_t *version;
377 dns_rdatacallbacks_t callbacks;
381 * Hold forward state.
387 isc_buffer_t *msgbuf;
388 dns_request_t *request;
391 dns_updatecallback_t callback;
396 * Hold IO request state.
403 ISC_LINK(dns_io_t) link;
407 #define SEND_BUFFER_SIZE 2048
409 static void zone_settimer(dns_zone_t *, isc_time_t *);
410 static void cancel_refresh(dns_zone_t *);
411 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
412 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
413 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
414 ISC_FORMAT_PRINTF(3, 4);
415 static void queue_xfrin(dns_zone_t *zone);
416 static void zone_unload(dns_zone_t *zone);
417 static void zone_expire(dns_zone_t *zone);
418 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
419 static void zone_idetach(dns_zone_t **zonep);
420 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
422 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
423 static inline void zone_detachdb(dns_zone_t *zone);
424 static isc_result_t default_journal(dns_zone_t *zone);
425 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
426 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
427 isc_time_t loadtime, isc_result_t result);
428 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
429 static void zone_shutdown(isc_task_t *, isc_event_t *);
430 static void zone_loaddone(void *arg, isc_result_t result);
431 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
432 isc_time_t loadtime);
435 /* ondestroy example */
436 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
439 static void refresh_callback(isc_task_t *, isc_event_t *);
440 static void stub_callback(isc_task_t *, isc_event_t *);
441 static void queue_soa_query(dns_zone_t *zone);
442 static void soa_query(isc_task_t *, isc_event_t *);
443 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
445 static int message_count(dns_message_t *msg, dns_section_t section,
446 dns_rdatatype_t type);
447 static void notify_cancel(dns_zone_t *zone);
448 static void notify_find_address(dns_notify_t *notify);
449 static void notify_send(dns_notify_t *notify);
450 static isc_result_t notify_createmessage(dns_zone_t *zone,
452 dns_message_t **messagep);
453 static void notify_done(isc_task_t *task, isc_event_t *event);
454 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
455 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
456 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
457 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
459 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
460 static void zonemgr_free(dns_zonemgr_t *zmgr);
461 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
462 isc_task_t *task, isc_taskaction_t action,
463 void *arg, dns_io_t **iop);
464 static void zonemgr_putio(dns_io_t **iop);
465 static void zonemgr_cancelio(dns_io_t *io);
468 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
469 unsigned int *soacount, isc_uint32_t *serial,
470 isc_uint32_t *refresh, isc_uint32_t *retry,
471 isc_uint32_t *expire, isc_uint32_t *minimum,
472 unsigned int *errors);
474 static void zone_freedbargs(dns_zone_t *zone);
475 static void forward_callback(isc_task_t *task, isc_event_t *event);
476 static void zone_saveunique(dns_zone_t *zone, const char *path,
477 const char *templat);
478 static void zone_maintenance(dns_zone_t *zone);
479 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
480 static void dump_done(void *arg, isc_result_t result);
482 #define ENTER zone_debuglog(zone, me, 1, "enter")
484 static const unsigned int dbargc_default = 1;
485 static const char *dbargv_default[] = { "rbt" };
487 #define DNS_ZONE_JITTER_ADD(a, b, c) \
491 _j = isc_random_jitter((b), (b)/4); \
492 isc_interval_set(&_i, _j, 0); \
493 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
494 dns_zone_log(zone, ISC_LOG_WARNING, \
495 "epoch approaching: upgrade required: " \
496 "now + %s failed", #b); \
497 isc_interval_set(&_i, _j/2, 0); \
498 (void)isc_time_add((a), &_i, (c)); \
502 #define DNS_ZONE_TIME_ADD(a, b, c) \
505 isc_interval_set(&_i, (b), 0); \
506 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
507 dns_zone_log(zone, ISC_LOG_WARNING, \
508 "epoch approaching: upgrade required: " \
509 "now + %s failed", #b); \
510 isc_interval_set(&_i, (b)/2, 0); \
511 (void)isc_time_add((a), &_i, (c)); \
516 *** Public functions.
520 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
525 REQUIRE(zonep != NULL && *zonep == NULL);
526 REQUIRE(mctx != NULL);
529 zone = isc_mem_get(mctx, sizeof(*zone));
531 return (ISC_R_NOMEMORY);
534 isc_mem_attach(mctx, &zone->mctx);
536 result = isc_mutex_init(&zone->lock);
537 if (result != ISC_R_SUCCESS)
540 result = ZONEDB_INITLOCK(&zone->dblock);
541 if (result != ISC_R_SUCCESS)
544 /* XXX MPA check that all elements are initialised */
545 #ifdef DNS_ZONE_CHECKLOCK
546 zone->locked = ISC_FALSE;
550 ISC_LINK_INIT(zone, link);
551 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
552 if (result != ISC_R_SUCCESS)
555 dns_name_init(&zone->origin, NULL);
556 zone->masterfile = NULL;
557 zone->masterformat = dns_masterformat_none;
558 zone->keydirectory = NULL;
559 zone->journalsize = -1;
560 zone->journal = NULL;
561 zone->rdclass = dns_rdataclass_none;
562 zone->type = dns_zone_none;
566 zone->db_argv = NULL;
567 isc_time_settoepoch(&zone->expiretime);
568 isc_time_settoepoch(&zone->refreshtime);
569 isc_time_settoepoch(&zone->dumptime);
570 isc_time_settoepoch(&zone->loadtime);
571 zone->notifytime = now;
573 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
574 zone->retry = DNS_ZONE_DEFAULTRETRY;
577 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
578 zone->minrefresh = DNS_ZONE_MINREFRESH;
579 zone->maxretry = DNS_ZONE_MAXRETRY;
580 zone->minretry = DNS_ZONE_MINRETRY;
581 zone->masters = NULL;
582 zone->masterkeynames = NULL;
583 zone->mastersok = NULL;
584 zone->masterscnt = 0;
587 zone->notifytype = dns_notifytype_yes;
590 zone->update_acl = NULL;
591 zone->forward_acl = NULL;
592 zone->notify_acl = NULL;
593 zone->query_acl = NULL;
594 zone->xfr_acl = NULL;
595 zone->update_disabled = ISC_FALSE;
596 zone->zero_no_soa_ttl = ISC_TRUE;
597 zone->check_names = dns_severity_ignore;
598 zone->request = NULL;
602 zone->writeio = NULL;
604 zone->idlein = DNS_DEFAULT_IDLEIN;
605 zone->idleout = DNS_DEFAULT_IDLEOUT;
606 ISC_LIST_INIT(zone->notifies);
607 isc_sockaddr_any(&zone->notifysrc4);
608 isc_sockaddr_any6(&zone->notifysrc6);
609 isc_sockaddr_any(&zone->xfrsource4);
610 isc_sockaddr_any6(&zone->xfrsource6);
611 isc_sockaddr_any(&zone->altxfrsource4);
612 isc_sockaddr_any6(&zone->altxfrsource6);
614 zone->tsigkey = NULL;
615 zone->maxxfrin = MAX_XFER_TIME;
616 zone->maxxfrout = MAX_XFER_TIME;
617 zone->ssutable = NULL;
618 zone->sigvalidityinterval = 30 * 24 * 3600;
621 zone->checkmx = NULL;
622 zone->checksrv = NULL;
623 zone->checkns = NULL;
624 ISC_LINK_INIT(zone, statelink);
625 zone->statelist = NULL;
626 zone->counters = NULL;
627 zone->notifydelay = 5;
629 zone->isselfarg = NULL;
631 zone->magic = ZONE_MAGIC;
633 /* Must be after magic is set. */
634 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
635 if (result != ISC_R_SUCCESS)
638 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
639 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
642 return (ISC_R_SUCCESS);
645 isc_refcount_decrement(&zone->erefs, NULL);
646 isc_refcount_destroy(&zone->erefs);
649 ZONEDB_DESTROYLOCK(&zone->dblock);
652 DESTROYLOCK(&zone->lock);
655 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
660 * Free a zone. Because we require that there be no more
661 * outstanding events or references, no locking is necessary.
664 zone_free(dns_zone_t *zone) {
665 isc_mem_t *mctx = NULL;
667 REQUIRE(DNS_ZONE_VALID(zone));
668 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
669 REQUIRE(zone->irefs == 0);
670 REQUIRE(!LOCKED_ZONE(zone));
671 REQUIRE(zone->timer == NULL);
674 * Managed objects. Order is important.
676 if (zone->request != NULL)
677 dns_request_destroy(&zone->request); /* XXXMPA */
678 INSIST(zone->readio == NULL);
679 INSIST(zone->statelist == NULL);
680 INSIST(zone->writeio == NULL);
682 if (zone->task != NULL)
683 isc_task_detach(&zone->task);
685 dns_zonemgr_releasezone(zone->zmgr, zone);
687 /* Unmanaged objects */
688 if (zone->masterfile != NULL)
689 isc_mem_free(zone->mctx, zone->masterfile);
690 zone->masterfile = NULL;
691 if (zone->keydirectory != NULL)
692 isc_mem_free(zone->mctx, zone->keydirectory);
693 zone->keydirectory = NULL;
694 zone->journalsize = -1;
695 if (zone->journal != NULL)
696 isc_mem_free(zone->mctx, zone->journal);
697 zone->journal = NULL;
698 if (zone->counters != NULL)
699 dns_stats_freecounters(zone->mctx, &zone->counters);
700 if (zone->db != NULL)
702 if (zone->acache != NULL)
703 dns_acache_detach(&zone->acache);
704 zone_freedbargs(zone);
705 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
707 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
709 zone->check_names = dns_severity_ignore;
710 if (zone->update_acl != NULL)
711 dns_acl_detach(&zone->update_acl);
712 if (zone->forward_acl != NULL)
713 dns_acl_detach(&zone->forward_acl);
714 if (zone->notify_acl != NULL)
715 dns_acl_detach(&zone->notify_acl);
716 if (zone->query_acl != NULL)
717 dns_acl_detach(&zone->query_acl);
718 if (zone->xfr_acl != NULL)
719 dns_acl_detach(&zone->xfr_acl);
720 if (dns_name_dynamic(&zone->origin))
721 dns_name_free(&zone->origin, zone->mctx);
722 if (zone->ssutable != NULL)
723 dns_ssutable_detach(&zone->ssutable);
726 ZONEDB_DESTROYLOCK(&zone->dblock);
727 DESTROYLOCK(&zone->lock);
728 isc_refcount_destroy(&zone->erefs);
731 isc_mem_put(mctx, zone, sizeof(*zone));
732 isc_mem_detach(&mctx);
739 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
741 REQUIRE(DNS_ZONE_VALID(zone));
742 REQUIRE(rdclass != dns_rdataclass_none);
748 REQUIRE(zone->rdclass == dns_rdataclass_none ||
749 zone->rdclass == rdclass);
750 zone->rdclass = rdclass;
755 dns_zone_getclass(dns_zone_t *zone){
756 REQUIRE(DNS_ZONE_VALID(zone));
758 return (zone->rdclass);
762 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
763 REQUIRE(DNS_ZONE_VALID(zone));
766 zone->notifytype = notifytype;
774 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
776 REQUIRE(DNS_ZONE_VALID(zone));
777 REQUIRE(type != dns_zone_none);
783 REQUIRE(zone->type == dns_zone_none || zone->type == type);
789 zone_freedbargs(dns_zone_t *zone) {
792 /* Free the old database argument list. */
793 if (zone->db_argv != NULL) {
794 for (i = 0; i < zone->db_argc; i++)
795 isc_mem_free(zone->mctx, zone->db_argv[i]);
796 isc_mem_put(zone->mctx, zone->db_argv,
797 zone->db_argc * sizeof(*zone->db_argv));
800 zone->db_argv = NULL;
804 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
807 isc_result_t result = ISC_R_SUCCESS;
811 REQUIRE(DNS_ZONE_VALID(zone));
812 REQUIRE(argv != NULL && *argv == NULL);
815 size = (zone->db_argc + 1) * sizeof(char *);
816 for (i = 0; i < zone->db_argc; i++)
817 size += strlen(zone->db_argv[i]) + 1;
818 mem = isc_mem_allocate(mctx, size);
822 tmp2 += (zone->db_argc + 1) * sizeof(char *);
823 for (i = 0; i < zone->db_argc; i++) {
825 strcpy(tmp2, zone->db_argv[i]);
826 tmp2 += strlen(tmp2) + 1;
830 result = ISC_R_NOMEMORY;
837 dns_zone_setdbtype(dns_zone_t *zone,
838 unsigned int dbargc, const char * const *dbargv) {
839 isc_result_t result = ISC_R_SUCCESS;
843 REQUIRE(DNS_ZONE_VALID(zone));
844 REQUIRE(dbargc >= 1);
845 REQUIRE(dbargv != NULL);
849 /* Set up a new database argument list. */
850 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
853 for (i = 0; i < dbargc; i++)
855 for (i = 0; i < dbargc; i++) {
856 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
861 /* Free the old list. */
862 zone_freedbargs(zone);
864 zone->db_argc = dbargc;
866 result = ISC_R_SUCCESS;
871 for (i = 0; i < dbargc; i++)
873 isc_mem_free(zone->mctx, new[i]);
874 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
876 result = ISC_R_NOMEMORY;
884 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
885 REQUIRE(DNS_ZONE_VALID(zone));
888 if (zone->view != NULL)
889 dns_view_weakdetach(&zone->view);
890 dns_view_weakattach(view, &zone->view);
896 dns_zone_getview(dns_zone_t *zone) {
897 REQUIRE(DNS_ZONE_VALID(zone));
904 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
907 REQUIRE(DNS_ZONE_VALID(zone));
908 REQUIRE(origin != NULL);
911 if (dns_name_dynamic(&zone->origin)) {
912 dns_name_free(&zone->origin, zone->mctx);
913 dns_name_init(&zone->origin, NULL);
915 result = dns_name_dup(origin, zone->mctx, &zone->origin);
921 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
922 REQUIRE(DNS_ZONE_VALID(zone));
923 REQUIRE(acache != NULL);
926 if (zone->acache != NULL)
927 dns_acache_detach(&zone->acache);
928 dns_acache_attach(acache, &zone->acache);
929 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
930 if (zone->db != NULL) {
934 * If the zone reuses an existing DB, the DB needs to be
935 * set in the acache explicitly. We can safely ignore the
936 * case where the DB is already set. If other error happens,
937 * the acache will not work effectively.
939 result = dns_acache_setdb(acache, zone->db);
940 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
941 UNEXPECTED_ERROR(__FILE__, __LINE__,
942 "dns_acache_setdb() failed: %s",
943 isc_result_totext(result));
946 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
951 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
955 copy = isc_mem_strdup(zone->mctx, value);
957 return (ISC_R_NOMEMORY);
963 isc_mem_free(zone->mctx, *field);
966 return (ISC_R_SUCCESS);
970 dns_zone_setfile(dns_zone_t *zone, const char *file) {
971 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
975 dns_zone_setfile2(dns_zone_t *zone, const char *file,
976 dns_masterformat_t format) {
977 isc_result_t result = ISC_R_SUCCESS;
979 REQUIRE(DNS_ZONE_VALID(zone));
982 result = dns_zone_setstring(zone, &zone->masterfile, file);
983 if (result == ISC_R_SUCCESS) {
984 zone->masterformat = format;
985 result = default_journal(zone);
993 dns_zone_getfile(dns_zone_t *zone) {
994 REQUIRE(DNS_ZONE_VALID(zone));
996 return (zone->masterfile);
1000 default_journal(dns_zone_t *zone) {
1001 isc_result_t result;
1004 REQUIRE(DNS_ZONE_VALID(zone));
1005 REQUIRE(LOCKED_ZONE(zone));
1007 if (zone->masterfile != NULL) {
1008 /* Calculate string length including '\0'. */
1009 int len = strlen(zone->masterfile) + sizeof(".jnl");
1010 journal = isc_mem_allocate(zone->mctx, len);
1011 if (journal == NULL)
1012 return (ISC_R_NOMEMORY);
1013 strcpy(journal, zone->masterfile);
1014 strcat(journal, ".jnl");
1018 result = dns_zone_setstring(zone, &zone->journal, journal);
1019 if (journal != NULL)
1020 isc_mem_free(zone->mctx, journal);
1025 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1026 isc_result_t result = ISC_R_SUCCESS;
1028 REQUIRE(DNS_ZONE_VALID(zone));
1031 result = dns_zone_setstring(zone, &zone->journal, journal);
1038 dns_zone_getjournal(dns_zone_t *zone) {
1039 REQUIRE(DNS_ZONE_VALID(zone));
1041 return (zone->journal);
1045 * Return true iff the zone is "dynamic", in the sense that the zone's
1046 * master file (if any) is written by the server, rather than being
1047 * updated manually and read by the server.
1049 * This is true for slave zones, stub zones, and zones that allow
1050 * dynamic updates either by having an update policy ("ssutable")
1051 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1053 static isc_boolean_t
1054 zone_isdynamic(dns_zone_t *zone) {
1055 REQUIRE(DNS_ZONE_VALID(zone));
1057 return (ISC_TF(zone->type == dns_zone_slave ||
1058 zone->type == dns_zone_stub ||
1059 (!zone->update_disabled && zone->ssutable != NULL) ||
1060 (!zone->update_disabled && zone->update_acl != NULL &&
1061 ! (zone->update_acl->length == 1 &&
1062 zone->update_acl->elements[0].negative == ISC_TRUE
1064 zone->update_acl->elements[0].type ==
1065 dns_aclelementtype_any))));
1070 zone_load(dns_zone_t *zone, unsigned int flags) {
1071 isc_result_t result;
1073 isc_time_t loadtime, filetime;
1074 dns_db_t *db = NULL;
1076 REQUIRE(DNS_ZONE_VALID(zone));
1081 INSIST(zone->type != dns_zone_none);
1083 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1084 result = ISC_R_SUCCESS;
1088 if (zone->db != NULL && zone->masterfile == NULL) {
1090 * The zone has no master file configured, but it already
1091 * has a database. It could be the built-in
1092 * version.bind. CH zone, a zone with a persistent
1093 * database being reloaded, or maybe a zone that
1094 * used to have a master file but whose configuration
1095 * was changed so that it no longer has one. Do nothing.
1097 result = ISC_R_SUCCESS;
1101 if (zone->db != NULL && zone_isdynamic(zone)) {
1103 * This is a slave, stub, or dynamically updated
1104 * zone being reloaded. Do nothing - the database
1105 * we already have is guaranteed to be up-to-date.
1107 if (zone->type == dns_zone_master)
1108 result = DNS_R_DYNAMIC;
1110 result = ISC_R_SUCCESS;
1116 * Store the current time before the zone is loaded, so that if the
1117 * file changes between the time of the load and the time that
1118 * zone->loadtime is set, then the file will still be reloaded
1119 * the next time dns_zone_load is called.
1121 TIME_NOW(&loadtime);
1124 * Don't do the load if the file that stores the zone is older
1125 * than the last time the zone was loaded. If the zone has not
1126 * been loaded yet, zone->loadtime will be the epoch.
1128 if (zone->masterfile != NULL) {
1130 * The file is already loaded. If we are just doing a
1131 * "rndc reconfig", we are done.
1133 if (!isc_time_isepoch(&zone->loadtime) &&
1134 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1135 result = ISC_R_SUCCESS;
1139 result = isc_file_getmodtime(zone->masterfile, &filetime);
1140 if (result == ISC_R_SUCCESS) {
1141 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1142 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1143 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1144 "skipping load: master file "
1145 "older than last load");
1146 result = DNS_R_UPTODATE;
1149 loadtime = filetime;
1153 INSIST(zone->db_argc >= 1);
1156 * Built in zones don't need to be reloaded.
1158 if (zone->type == dns_zone_master &&
1159 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1160 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1161 result = ISC_R_SUCCESS;
1165 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1166 (strcmp(zone->db_argv[0], "rbt") == 0 ||
1167 strcmp(zone->db_argv[0], "rbt64") == 0)) {
1168 if (zone->masterfile == NULL ||
1169 !isc_file_exists(zone->masterfile)) {
1170 if (zone->masterfile != NULL) {
1171 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1174 zone->refreshtime = now;
1175 if (zone->task != NULL)
1176 zone_settimer(zone, &now);
1177 result = ISC_R_SUCCESS;
1182 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1184 result = dns_db_create(zone->mctx, zone->db_argv[0],
1185 &zone->origin, (zone->type == dns_zone_stub) ?
1186 dns_dbtype_stub : dns_dbtype_zone,
1188 zone->db_argc - 1, zone->db_argv + 1,
1191 if (result != ISC_R_SUCCESS) {
1192 dns_zone_log(zone, ISC_LOG_ERROR,
1193 "loading zone: creating database: %s",
1194 isc_result_totext(result));
1197 dns_db_settask(db, zone->task);
1199 if (! dns_db_ispersistent(db)) {
1200 if (zone->masterfile != NULL) {
1201 result = zone_startload(db, zone, loadtime);
1203 result = DNS_R_NOMASTERFILE;
1204 if (zone->type == dns_zone_master) {
1205 dns_zone_log(zone, ISC_LOG_ERROR,
1207 "no master file configured");
1210 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1211 "no master file configured: continuing");
1215 if (result == DNS_R_CONTINUE) {
1216 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1220 result = zone_postload(zone, db, loadtime, result);
1230 dns_zone_load(dns_zone_t *zone) {
1231 return (zone_load(zone, 0));
1235 dns_zone_loadnew(dns_zone_t *zone) {
1236 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1240 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1241 dns_load_t *load = event->ev_arg;
1242 isc_result_t result = ISC_R_SUCCESS;
1243 unsigned int options;
1245 REQUIRE(DNS_LOAD_VALID(load));
1247 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1248 result = ISC_R_CANCELED;
1249 isc_event_free(&event);
1250 if (result == ISC_R_CANCELED)
1253 options = DNS_MASTER_ZONE;
1254 if (load->zone->type == dns_zone_slave)
1255 options |= DNS_MASTER_SLAVE;
1256 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNS))
1257 options |= DNS_MASTER_CHECKNS;
1258 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_FATALNS))
1259 options |= DNS_MASTER_FATALNS;
1260 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMES))
1261 options |= DNS_MASTER_CHECKNAMES;
1262 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1263 options |= DNS_MASTER_CHECKNAMESFAIL;
1264 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMX))
1265 options |= DNS_MASTER_CHECKMX;
1266 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMXFAIL))
1267 options |= DNS_MASTER_CHECKMXFAIL;
1268 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKWILDCARD))
1269 options |= DNS_MASTER_CHECKWILDCARD;
1270 result = dns_master_loadfileinc2(load->zone->masterfile,
1271 dns_db_origin(load->db),
1272 dns_db_origin(load->db),
1273 load->zone->rdclass,
1275 &load->callbacks, task,
1276 zone_loaddone, load,
1277 &load->zone->lctx, load->zone->mctx,
1278 load->zone->masterformat);
1279 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1280 result != DNS_R_SEENINCLUDE)
1285 zone_loaddone(load, result);
1289 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1290 const char me[] = "zone_gotwritehandle";
1291 dns_zone_t *zone = event->ev_arg;
1292 isc_result_t result = ISC_R_SUCCESS;
1293 dns_dbversion_t *version = NULL;
1295 REQUIRE(DNS_ZONE_VALID(zone));
1296 INSIST(task == zone->task);
1299 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1300 result = ISC_R_CANCELED;
1301 isc_event_free(&event);
1302 if (result == ISC_R_CANCELED)
1306 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1307 dns_db_currentversion(zone->db, &version);
1308 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1309 &dns_master_style_default,
1310 zone->masterfile, zone->task, dump_done,
1311 zone, &zone->dctx, zone->masterformat);
1312 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1313 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1315 if (result != DNS_R_CONTINUE)
1320 dump_done(zone, result);
1324 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1326 isc_result_t result;
1327 isc_result_t tresult;
1328 unsigned int options;
1330 options = DNS_MASTER_ZONE;
1331 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1332 options |= DNS_MASTER_MANYERRORS;
1333 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1334 options |= DNS_MASTER_CHECKNS;
1335 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1336 options |= DNS_MASTER_FATALNS;
1337 if (zone->type == dns_zone_slave)
1338 options |= DNS_MASTER_SLAVE;
1339 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1340 options |= DNS_MASTER_CHECKNAMES;
1341 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1342 options |= DNS_MASTER_CHECKNAMESFAIL;
1343 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1344 options |= DNS_MASTER_CHECKMX;
1345 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1346 options |= DNS_MASTER_CHECKMXFAIL;
1347 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1348 options |= DNS_MASTER_CHECKWILDCARD;
1350 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1351 load = isc_mem_get(zone->mctx, sizeof(*load));
1353 return (ISC_R_NOMEMORY);
1358 load->loadtime = loadtime;
1359 load->magic = LOAD_MAGIC;
1361 isc_mem_attach(zone->mctx, &load->mctx);
1362 zone_iattach(zone, &load->zone);
1363 dns_db_attach(db, &load->db);
1364 dns_rdatacallbacks_init(&load->callbacks);
1365 result = dns_db_beginload(db, &load->callbacks.add,
1366 &load->callbacks.add_private);
1367 if (result != ISC_R_SUCCESS)
1369 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1370 zone_gotreadhandle, load,
1372 if (result != ISC_R_SUCCESS) {
1374 * We can't report multiple errors so ignore
1375 * the result of dns_db_endload().
1377 (void)dns_db_endload(load->db,
1378 &load->callbacks.add_private);
1381 result = DNS_R_CONTINUE;
1383 dns_rdatacallbacks_t callbacks;
1385 dns_rdatacallbacks_init(&callbacks);
1386 result = dns_db_beginload(db, &callbacks.add,
1387 &callbacks.add_private);
1388 if (result != ISC_R_SUCCESS)
1390 result = dns_master_loadfile2(zone->masterfile, &zone->origin,
1391 &zone->origin, zone->rdclass,
1392 options, &callbacks, zone->mctx,
1393 zone->masterformat);
1394 tresult = dns_db_endload(db, &callbacks.add_private);
1395 if (result == ISC_R_SUCCESS)
1403 dns_db_detach(&load->db);
1404 zone_idetach(&load->zone);
1405 isc_mem_detach(&load->mctx);
1406 isc_mem_put(zone->mctx, load, sizeof(*load));
1410 static isc_boolean_t
1411 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1414 isc_result_t result;
1415 char ownerbuf[DNS_NAME_FORMATSIZE];
1416 char namebuf[DNS_NAME_FORMATSIZE];
1417 char altbuf[DNS_NAME_FORMATSIZE];
1418 dns_fixedname_t fixed;
1419 dns_name_t *foundname;
1425 if (!dns_name_issubdomain(name, &zone->origin)) {
1426 if (zone->checkmx != NULL)
1427 return ((zone->checkmx)(zone, name, owner));
1431 if (zone->type == dns_zone_master)
1432 level = ISC_LOG_ERROR;
1434 level = ISC_LOG_WARNING;
1436 dns_fixedname_init(&fixed);
1437 foundname = dns_fixedname_name(&fixed);
1439 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1440 0, 0, NULL, foundname, NULL, NULL);
1441 if (result == ISC_R_SUCCESS)
1444 if (result == DNS_R_NXRRSET) {
1445 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1446 0, 0, NULL, foundname, NULL, NULL);
1447 if (result == ISC_R_SUCCESS)
1451 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1452 dns_name_format(name, namebuf, sizeof namebuf);
1453 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1454 result == DNS_R_EMPTYNAME) {
1455 dns_zone_log(zone, level,
1456 "%s/MX '%s' has no address records (A or AAAA)",
1458 /* XXX950 make fatal for 9.5.0. */
1462 if (result == DNS_R_CNAME) {
1463 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1464 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1465 level = ISC_LOG_WARNING;
1466 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1467 dns_zone_log(zone, level,
1468 "%s/MX '%s' is a CNAME (illegal)",
1470 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1473 if (result == DNS_R_DNAME) {
1474 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1475 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1476 level = ISC_LOG_WARNING;
1477 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1478 dns_name_format(foundname, altbuf, sizeof altbuf);
1479 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1480 " '%s' (illegal)", ownerbuf, namebuf,
1483 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1486 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1487 return ((zone->checkmx)(zone, name, owner));
1492 static isc_boolean_t
1493 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1496 isc_result_t result;
1497 char ownerbuf[DNS_NAME_FORMATSIZE];
1498 char namebuf[DNS_NAME_FORMATSIZE];
1499 char altbuf[DNS_NAME_FORMATSIZE];
1500 dns_fixedname_t fixed;
1501 dns_name_t *foundname;
1505 * "." means the services does not exist.
1507 if (dns_name_equal(name, dns_rootname))
1513 if (!dns_name_issubdomain(name, &zone->origin)) {
1514 if (zone->checksrv != NULL)
1515 return ((zone->checksrv)(zone, name, owner));
1519 if (zone->type == dns_zone_master)
1520 level = ISC_LOG_ERROR;
1522 level = ISC_LOG_WARNING;
1524 dns_fixedname_init(&fixed);
1525 foundname = dns_fixedname_name(&fixed);
1527 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1528 0, 0, NULL, foundname, NULL, NULL);
1529 if (result == ISC_R_SUCCESS)
1532 if (result == DNS_R_NXRRSET) {
1533 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1534 0, 0, NULL, foundname, NULL, NULL);
1535 if (result == ISC_R_SUCCESS)
1539 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1540 dns_name_format(name, namebuf, sizeof namebuf);
1541 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1542 result == DNS_R_EMPTYNAME) {
1543 dns_zone_log(zone, level,
1544 "%s/SRV '%s' has no address records (A or AAAA)",
1546 /* XXX950 make fatal for 9.5.0. */
1550 if (result == DNS_R_CNAME) {
1551 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1552 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1553 level = ISC_LOG_WARNING;
1554 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1555 dns_zone_log(zone, level,
1556 "%s/SRV '%s' is a CNAME (illegal)",
1558 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1561 if (result == DNS_R_DNAME) {
1562 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1563 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1564 level = ISC_LOG_WARNING;
1565 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1566 dns_name_format(foundname, altbuf, sizeof altbuf);
1567 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1568 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1571 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1574 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1575 return ((zone->checksrv)(zone, name, owner));
1580 static isc_boolean_t
1581 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1584 isc_boolean_t answer = ISC_TRUE;
1585 isc_result_t result, tresult;
1586 char ownerbuf[DNS_NAME_FORMATSIZE];
1587 char namebuf[DNS_NAME_FORMATSIZE];
1588 char altbuf[DNS_NAME_FORMATSIZE];
1589 dns_fixedname_t fixed;
1590 dns_name_t *foundname;
1592 dns_rdataset_t aaaa;
1598 if (!dns_name_issubdomain(name, &zone->origin)) {
1599 if (zone->checkns != NULL)
1600 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1604 if (zone->type == dns_zone_master)
1605 level = ISC_LOG_ERROR;
1607 level = ISC_LOG_WARNING;
1609 dns_fixedname_init(&fixed);
1610 foundname = dns_fixedname_name(&fixed);
1611 dns_rdataset_init(&a);
1612 dns_rdataset_init(&aaaa);
1614 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1615 DNS_DBFIND_GLUEOK, 0, NULL,
1616 foundname, &a, NULL);
1618 if (result == ISC_R_SUCCESS) {
1619 dns_rdataset_disassociate(&a);
1621 } else if (result == DNS_R_DELEGATION)
1622 dns_rdataset_disassociate(&a);
1624 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1625 result == DNS_R_GLUE) {
1626 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1627 DNS_DBFIND_GLUEOK, 0, NULL,
1628 foundname, &aaaa, NULL);
1629 if (tresult == ISC_R_SUCCESS) {
1630 dns_rdataset_disassociate(&aaaa);
1633 if (tresult == DNS_R_DELEGATION)
1634 dns_rdataset_disassociate(&aaaa);
1635 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1637 * Check glue against child zone.
1639 if (zone->checkns != NULL)
1640 answer = (zone->checkns)(zone, name, owner,
1642 if (dns_rdataset_isassociated(&a))
1643 dns_rdataset_disassociate(&a);
1644 if (dns_rdataset_isassociated(&aaaa))
1645 dns_rdataset_disassociate(&aaaa);
1651 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1652 dns_name_format(name, namebuf, sizeof namebuf);
1653 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1654 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
1656 if (dns_name_issubdomain(name, owner))
1657 what = "REQUIRED GLUE ";
1658 else if (result == DNS_R_DELEGATION)
1659 what = "SIBLING GLUE ";
1663 if (result != DNS_R_DELEGATION ||
1664 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
1665 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
1666 "address records (A or AAAA)",
1667 ownerbuf, namebuf, what);
1669 * Log missing address record.
1671 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
1672 (void)(zone->checkns)(zone, name, owner,
1674 /* XXX950 make fatal for 9.5.0. */
1675 /* answer = ISC_FALSE; */
1677 } else if (result == DNS_R_CNAME) {
1678 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
1680 /* XXX950 make fatal for 9.5.0. */
1681 /* answer = ISC_FALSE; */
1682 } else if (result == DNS_R_DNAME) {
1683 dns_name_format(foundname, altbuf, sizeof altbuf);
1684 dns_zone_log(zone, level,
1685 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1686 ownerbuf, namebuf, altbuf);
1687 /* XXX950 make fatal for 9.5.0. */
1688 /* answer = ISC_FALSE; */
1691 if (dns_rdataset_isassociated(&a))
1692 dns_rdataset_disassociate(&a);
1693 if (dns_rdataset_isassociated(&aaaa))
1694 dns_rdataset_disassociate(&aaaa);
1698 static isc_boolean_t
1699 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
1700 dns_dbiterator_t *dbiterator = NULL;
1701 dns_dbnode_t *node = NULL;
1702 dns_rdataset_t rdataset;
1703 dns_fixedname_t fixed;
1704 dns_fixedname_t fixedbottom;
1707 dns_rdata_in_srv_t srv;
1711 isc_result_t result;
1712 isc_boolean_t ok = ISC_TRUE;
1714 dns_fixedname_init(&fixed);
1715 name = dns_fixedname_name(&fixed);
1716 dns_fixedname_init(&fixedbottom);
1717 bottom = dns_fixedname_name(&fixedbottom);
1718 dns_rdataset_init(&rdataset);
1719 dns_rdata_init(&rdata);
1721 result = dns_db_createiterator(db, ISC_FALSE, &dbiterator);
1722 if (result != ISC_R_SUCCESS)
1725 result = dns_dbiterator_first(dbiterator);
1726 while (result == ISC_R_SUCCESS) {
1727 result = dns_dbiterator_current(dbiterator, &node, name);
1728 if (result != ISC_R_SUCCESS)
1732 * Is this name visible in the zone?
1734 if (!dns_name_issubdomain(name, &zone->origin) ||
1735 (dns_name_countlabels(bottom) > 0 &&
1736 dns_name_issubdomain(name, bottom)))
1740 * Don't check the NS records at the origin.
1742 if (dns_name_equal(name, &zone->origin))
1745 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
1746 0, 0, &rdataset, NULL);
1747 if (result != ISC_R_SUCCESS)
1750 * Remember bottom of zone.
1752 dns_name_copy(name, bottom, NULL);
1754 result = dns_rdataset_first(&rdataset);
1755 while (result == ISC_R_SUCCESS) {
1756 dns_rdataset_current(&rdataset, &rdata);
1757 result = dns_rdata_tostruct(&rdata, &ns, NULL);
1758 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1759 if (!zone_check_glue(zone, db, &ns.name, name))
1761 dns_rdata_reset(&rdata);
1762 result = dns_rdataset_next(&rdataset);
1764 dns_rdataset_disassociate(&rdataset);
1767 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
1768 0, 0, &rdataset, NULL);
1769 if (result != ISC_R_SUCCESS)
1771 result = dns_rdataset_first(&rdataset);
1772 while (result == ISC_R_SUCCESS) {
1773 dns_rdataset_current(&rdataset, &rdata);
1774 result = dns_rdata_tostruct(&rdata, &mx, NULL);
1775 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1776 if (!zone_check_mx(zone, db, &mx.mx, name))
1778 dns_rdata_reset(&rdata);
1779 result = dns_rdataset_next(&rdataset);
1781 dns_rdataset_disassociate(&rdataset);
1784 if (zone->rdclass != dns_rdataclass_in)
1786 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
1787 0, 0, &rdataset, NULL);
1788 if (result != ISC_R_SUCCESS)
1790 result = dns_rdataset_first(&rdataset);
1791 while (result == ISC_R_SUCCESS) {
1792 dns_rdataset_current(&rdataset, &rdata);
1793 result = dns_rdata_tostruct(&rdata, &srv, NULL);
1794 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1795 if (!zone_check_srv(zone, db, &srv.target, name))
1797 dns_rdata_reset(&rdata);
1798 result = dns_rdataset_next(&rdataset);
1800 dns_rdataset_disassociate(&rdataset);
1803 dns_db_detachnode(db, &node);
1804 result = dns_dbiterator_next(dbiterator);
1809 dns_db_detachnode(db, &node);
1810 dns_dbiterator_destroy(&dbiterator);
1816 * OpenSSL verification of RSA keys with exponent 3 is known to be
1817 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
1818 * if they are in use.
1821 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
1822 dns_dbnode_t *node = NULL;
1823 dns_dbversion_t *version = NULL;
1824 dns_rdata_dnskey_t dnskey;
1825 dns_rdata_t rdata = DNS_RDATA_INIT;
1826 dns_rdataset_t rdataset;
1827 isc_result_t result;
1828 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
1829 const char *algorithm;
1831 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
1832 if (result != ISC_R_SUCCESS)
1835 dns_db_currentversion(db, &version);
1836 dns_rdataset_init(&rdataset);
1837 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1838 dns_rdatatype_none, 0, &rdataset, NULL);
1839 if (result != ISC_R_SUCCESS)
1842 for (result = dns_rdataset_first(&rdataset);
1843 result == ISC_R_SUCCESS;
1844 result = dns_rdataset_next(&rdataset))
1846 dns_rdataset_current(&rdataset, &rdata);
1847 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
1848 INSIST(result == ISC_R_SUCCESS);
1850 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
1851 dnskey.algorithm == DST_ALG_RSAMD5) &&
1852 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
1853 dnskey.data[1] == 3)
1855 if (dnskey.algorithm == DST_ALG_RSASHA1) {
1857 foundrsa = ISC_TRUE;
1858 algorithm = "RSASHA1";
1861 foundmd5 = ISC_TRUE;
1862 algorithm = "RSAMD5";
1865 dns_zone_log(zone, ISC_LOG_WARNING,
1866 "weak %s (%u) key found "
1867 "(exponent=3)", algorithm,
1869 if (foundrsa && foundmd5)
1872 dns_rdata_reset(&rdata);
1874 dns_rdataset_disassociate(&rdataset);
1878 dns_db_detachnode(db, &node);
1879 if (version != NULL)
1880 dns_db_closeversion(db, &version, ISC_FALSE);
1885 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
1886 isc_result_t result)
1888 unsigned int soacount = 0;
1889 unsigned int nscount = 0;
1890 unsigned int errors = 0;
1891 isc_uint32_t serial, refresh, retry, expire, minimum;
1893 isc_boolean_t needdump = ISC_FALSE;
1894 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1899 * Initiate zone transfer? We may need a error code that
1900 * indicates that the "permanent" form does not exist.
1901 * XXX better error feedback to log.
1903 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
1904 if (zone->type == dns_zone_slave ||
1905 zone->type == dns_zone_stub) {
1906 if (result == ISC_R_FILENOTFOUND)
1907 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1909 else if (result != DNS_R_NOMASTERFILE)
1910 dns_zone_log(zone, ISC_LOG_ERROR,
1911 "loading from master file %s "
1914 dns_result_totext(result));
1916 dns_zone_log(zone, ISC_LOG_ERROR,
1917 "loading from master file %s failed: %s",
1919 dns_result_totext(result));
1923 dns_zone_log(zone, ISC_LOG_DEBUG(2),
1924 "number of nodes in database: %u",
1925 dns_db_nodecount(db));
1927 if (result == DNS_R_SEENINCLUDE)
1928 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1930 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1933 * Apply update log, if any, on initial load.
1935 if (zone->journal != NULL &&
1936 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
1937 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
1939 result = dns_journal_rollforward(zone->mctx, db,
1941 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
1942 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
1943 result != ISC_R_RANGE) {
1944 dns_zone_log(zone, ISC_LOG_ERROR,
1945 "journal rollforward failed: %s",
1946 dns_result_totext(result));
1949 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
1950 dns_zone_log(zone, ISC_LOG_ERROR,
1951 "journal rollforward failed: "
1952 "journal out of sync with zone");
1955 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1956 "journal rollforward completed "
1958 dns_result_totext(result));
1959 if (result == ISC_R_SUCCESS)
1960 needdump = ISC_TRUE;
1963 zone->loadtime = loadtime;
1965 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded");
1968 * Obtain ns, soa and cname counts for top of zone.
1971 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
1972 &refresh, &retry, &expire, &minimum,
1974 if (result != ISC_R_SUCCESS) {
1975 dns_zone_log(zone, ISC_LOG_ERROR,
1976 "could not find NS and/or SOA records");
1980 * Master / Slave / Stub zones require both NS and SOA records at
1981 * the top of the zone.
1984 switch (zone->type) {
1985 case dns_zone_master:
1986 case dns_zone_slave:
1988 if (soacount != 1) {
1989 dns_zone_log(zone, ISC_LOG_ERROR,
1990 "has %d SOA records", soacount);
1991 result = DNS_R_BADZONE;
1994 dns_zone_log(zone, ISC_LOG_ERROR,
1995 "has no NS records");
1996 result = DNS_R_BADZONE;
1998 if (result != ISC_R_SUCCESS)
2000 if (zone->type == dns_zone_master && errors != 0) {
2001 result = DNS_R_BADZONE;
2004 if (zone->type == dns_zone_master &&
2005 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
2006 !integrity_checks(zone, db)) {
2007 result = DNS_R_BADZONE;
2011 if (zone->db != NULL) {
2013 * This is checked in zone_replacedb() for slave zones
2014 * as they don't reload from disk.
2016 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
2017 !isc_serial_gt(serial, zone->serial)) {
2018 isc_uint32_t serialmin, serialmax;
2020 INSIST(zone->type == dns_zone_master);
2022 serialmin = (zone->serial + 1) & 0xffffffffU;
2023 serialmax = (zone->serial + 0x7fffffffU) &
2025 dns_zone_log(zone, ISC_LOG_ERROR,
2026 "ixfr-from-differences: "
2027 "new serial (%u) out of range "
2028 "[%u - %u]", serial, serialmin,
2030 result = DNS_R_BADZONE;
2032 } else if (!isc_serial_ge(serial, zone->serial))
2033 dns_zone_log(zone, ISC_LOG_ERROR,
2034 "zone serial has gone backwards");
2035 else if (serial == zone->serial && !hasinclude)
2036 dns_zone_log(zone, ISC_LOG_ERROR,
2037 "zone serial unchanged. "
2038 "zone may fail to transfer "
2041 zone->serial = serial;
2042 zone->refresh = RANGE(refresh,
2043 zone->minrefresh, zone->maxrefresh);
2044 zone->retry = RANGE(retry,
2045 zone->minretry, zone->maxretry);
2046 zone->expire = RANGE(expire, zone->refresh + zone->retry,
2048 zone->minimum = minimum;
2049 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
2051 if (zone->type == dns_zone_slave ||
2052 zone->type == dns_zone_stub) {
2056 result = isc_file_getmodtime(zone->journal, &t);
2057 if (result != ISC_R_SUCCESS)
2058 result = isc_file_getmodtime(zone->masterfile,
2060 if (result == ISC_R_SUCCESS)
2061 DNS_ZONE_TIME_ADD(&t, zone->expire,
2064 DNS_ZONE_TIME_ADD(&now, zone->retry,
2067 delay = isc_random_jitter(zone->retry,
2068 (zone->retry * 3) / 4);
2069 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
2070 if (isc_time_compare(&zone->refreshtime,
2071 &zone->expiretime) >= 0)
2072 zone->refreshtime = now;
2076 UNEXPECTED_ERROR(__FILE__, __LINE__,
2077 "unexpected zone type %d", zone->type);
2078 result = ISC_R_UNEXPECTED;
2083 * Check for weak DNSKEY's.
2085 if (zone->type == dns_zone_master)
2086 zone_check_dnskeys(zone, db);
2089 /* destroy notification example. */
2091 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
2092 DNS_EVENT_DBDESTROYED,
2093 dns_zonemgr_dbdestroyed,
2095 sizeof(isc_event_t));
2096 dns_db_ondestroy(db, zone->task, &e);
2100 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2101 if (zone->db != NULL) {
2102 result = zone_replacedb(zone, db, ISC_FALSE);
2103 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2104 if (result != ISC_R_SUCCESS)
2107 zone_attachdb(zone, db);
2108 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2109 DNS_ZONE_SETFLAG(zone,
2110 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
2112 result = ISC_R_SUCCESS;
2114 zone_needdump(zone, DNS_DUMP_DELAY);
2115 if (zone->task != NULL)
2116 zone_settimer(zone, &now);
2118 if (! dns_db_ispersistent(db))
2119 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s",
2121 dns_db_issecure(db) ? " (signed)" : "");
2126 if (zone->type == dns_zone_slave ||
2127 zone->type == dns_zone_stub) {
2128 if (zone->journal != NULL)
2129 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
2130 if (zone->masterfile != NULL)
2131 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
2133 /* Mark the zone for immediate refresh. */
2134 zone->refreshtime = now;
2135 if (zone->task != NULL)
2136 zone_settimer(zone, &now);
2137 result = ISC_R_SUCCESS;
2142 static isc_boolean_t
2143 exit_check(dns_zone_t *zone) {
2145 REQUIRE(LOCKED_ZONE(zone));
2147 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
2151 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2153 INSIST(isc_refcount_current(&zone->erefs) == 0);
2159 static isc_boolean_t
2160 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
2161 isc_result_t result;
2162 char namebuf[DNS_NAME_FORMATSIZE];
2163 char altbuf[DNS_NAME_FORMATSIZE];
2164 dns_fixedname_t fixed;
2165 dns_name_t *foundname;
2168 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
2171 if (zone->type == dns_zone_master)
2172 level = ISC_LOG_ERROR;
2174 level = ISC_LOG_WARNING;
2176 dns_fixedname_init(&fixed);
2177 foundname = dns_fixedname_name(&fixed);
2179 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2180 0, 0, NULL, foundname, NULL, NULL);
2181 if (result == ISC_R_SUCCESS)
2184 if (result == DNS_R_NXRRSET) {
2185 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2186 0, 0, NULL, foundname, NULL, NULL);
2187 if (result == ISC_R_SUCCESS)
2191 dns_name_format(name, namebuf, sizeof namebuf);
2192 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2193 result == DNS_R_EMPTYNAME) {
2194 dns_zone_log(zone, level,
2195 "NS '%s' has no address records (A or AAAA)",
2197 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2201 if (result == DNS_R_CNAME) {
2202 dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
2204 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2208 if (result == DNS_R_DNAME) {
2209 dns_name_format(foundname, altbuf, sizeof altbuf);
2210 dns_zone_log(zone, level,
2211 "NS '%s' is below a DNAME '%s' (illegal)",
2213 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2221 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
2222 dns_dbversion_t *version, unsigned int *nscount,
2223 unsigned int *errors)
2225 isc_result_t result;
2226 unsigned int count = 0;
2227 unsigned int ecount = 0;
2228 dns_rdataset_t rdataset;
2232 dns_rdataset_init(&rdataset);
2233 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
2234 dns_rdatatype_none, 0, &rdataset, NULL);
2235 if (result == ISC_R_NOTFOUND)
2237 if (result != ISC_R_SUCCESS)
2238 goto invalidate_rdataset;
2240 result = dns_rdataset_first(&rdataset);
2241 while (result == ISC_R_SUCCESS) {
2242 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
2243 (zone->type == dns_zone_master ||
2244 zone->type == dns_zone_slave)) {
2245 dns_rdata_init(&rdata);
2246 dns_rdataset_current(&rdataset, &rdata);
2247 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2248 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2249 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
2250 !zone_check_ns(zone, db, &ns.name))
2254 result = dns_rdataset_next(&rdataset);
2256 dns_rdataset_disassociate(&rdataset);
2259 if (nscount != NULL)
2264 result = ISC_R_SUCCESS;
2266 invalidate_rdataset:
2267 dns_rdataset_invalidate(&rdataset);
2273 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
2274 unsigned int *soacount,
2275 isc_uint32_t *serial, isc_uint32_t *refresh,
2276 isc_uint32_t *retry, isc_uint32_t *expire,
2277 isc_uint32_t *minimum)
2279 isc_result_t result;
2281 dns_rdataset_t rdataset;
2282 dns_rdata_t rdata = DNS_RDATA_INIT;
2283 dns_rdata_soa_t soa;
2285 dns_rdataset_init(&rdataset);
2286 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
2287 dns_rdatatype_none, 0, &rdataset, NULL);
2288 if (result == ISC_R_NOTFOUND) {
2289 if (soacount != NULL)
2293 if (refresh != NULL)
2299 if (minimum != NULL)
2301 result = ISC_R_SUCCESS;
2302 goto invalidate_rdataset;
2304 if (result != ISC_R_SUCCESS)
2305 goto invalidate_rdataset;
2308 result = dns_rdataset_first(&rdataset);
2309 while (result == ISC_R_SUCCESS) {
2310 dns_rdata_init(&rdata);
2311 dns_rdataset_current(&rdataset, &rdata);
2314 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2315 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2318 result = dns_rdataset_next(&rdataset);
2319 dns_rdata_reset(&rdata);
2321 dns_rdataset_disassociate(&rdataset);
2323 if (soacount != NULL)
2328 *serial = soa.serial;
2329 if (refresh != NULL)
2330 *refresh = soa.refresh;
2334 *expire = soa.expire;
2335 if (minimum != NULL)
2336 *minimum = soa.minimum;
2339 result = ISC_R_SUCCESS;
2341 invalidate_rdataset:
2342 dns_rdataset_invalidate(&rdataset);
2348 * zone must be locked.
2351 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
2352 unsigned int *soacount, isc_uint32_t *serial,
2353 isc_uint32_t *refresh, isc_uint32_t *retry,
2354 isc_uint32_t *expire, isc_uint32_t *minimum,
2355 unsigned int *errors)
2357 dns_dbversion_t *version;
2358 isc_result_t result;
2359 isc_result_t answer = ISC_R_SUCCESS;
2362 REQUIRE(db != NULL);
2363 REQUIRE(zone != NULL);
2366 dns_db_currentversion(db, &version);
2369 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2370 if (result != ISC_R_SUCCESS) {
2375 if (nscount != NULL || errors != NULL) {
2376 result = zone_count_ns_rr(zone, db, node, version,
2378 if (result != ISC_R_SUCCESS)
2382 if (soacount != NULL || serial != NULL || refresh != NULL
2383 || retry != NULL || expire != NULL || minimum != NULL) {
2384 result = zone_load_soa_rr(db, node, version, soacount,
2385 serial, refresh, retry, expire,
2387 if (result != ISC_R_SUCCESS)
2391 dns_db_detachnode(db, &node);
2393 dns_db_closeversion(db, &version, ISC_FALSE);
2399 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
2400 REQUIRE(DNS_ZONE_VALID(source));
2401 REQUIRE(target != NULL && *target == NULL);
2402 isc_refcount_increment(&source->erefs, NULL);
2407 dns_zone_detach(dns_zone_t **zonep) {
2410 isc_boolean_t free_now = ISC_FALSE;
2412 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2416 isc_refcount_decrement(&zone->erefs, &refs);
2421 * We just detached the last external reference.
2423 if (zone->task != NULL) {
2425 * This zone is being managed. Post
2426 * its control event and let it clean
2427 * up synchronously in the context of
2430 isc_event_t *ev = &zone->ctlevent;
2431 isc_task_send(zone->task, &ev);
2434 * This zone is not being managed; it has
2435 * no task and can have no outstanding
2436 * events. Free it immediately.
2439 * Unmanaged zones should not have non-null views;
2440 * we have no way of detaching from the view here
2441 * without causing deadlock because this code is called
2442 * with the view already locked.
2444 INSIST(zone->view == NULL);
2445 free_now = ISC_TRUE;
2455 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
2456 REQUIRE(DNS_ZONE_VALID(source));
2457 REQUIRE(target != NULL && *target == NULL);
2459 zone_iattach(source, target);
2460 UNLOCK_ZONE(source);
2464 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
2467 * 'source' locked by caller.
2469 REQUIRE(LOCKED_ZONE(source));
2470 REQUIRE(DNS_ZONE_VALID(source));
2471 REQUIRE(target != NULL && *target == NULL);
2472 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
2474 INSIST(source->irefs != 0);
2479 zone_idetach(dns_zone_t **zonep) {
2483 * 'zone' locked by caller.
2485 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2487 REQUIRE(LOCKED_ZONE(*zonep));
2490 INSIST(zone->irefs > 0);
2492 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
2496 dns_zone_idetach(dns_zone_t **zonep) {
2498 isc_boolean_t free_needed;
2500 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2505 INSIST(zone->irefs > 0);
2507 free_needed = exit_check(zone);
2514 dns_zone_getmctx(dns_zone_t *zone) {
2515 REQUIRE(DNS_ZONE_VALID(zone));
2517 return (zone->mctx);
2521 dns_zone_getmgr(dns_zone_t *zone) {
2522 REQUIRE(DNS_ZONE_VALID(zone));
2524 return (zone->zmgr);
2528 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
2529 REQUIRE(DNS_ZONE_VALID(zone));
2533 DNS_ZONE_SETFLAG(zone, flags);
2535 DNS_ZONE_CLRFLAG(zone, flags);
2540 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
2542 REQUIRE(DNS_ZONE_VALID(zone));
2546 zone->options |= option;
2548 zone->options &= ~option;
2553 dns_zone_getoptions(dns_zone_t *zone) {
2555 REQUIRE(DNS_ZONE_VALID(zone));
2557 return (zone->options);
2561 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
2562 REQUIRE(DNS_ZONE_VALID(zone));
2565 zone->xfrsource4 = *xfrsource;
2568 return (ISC_R_SUCCESS);
2572 dns_zone_getxfrsource4(dns_zone_t *zone) {
2573 REQUIRE(DNS_ZONE_VALID(zone));
2574 return (&zone->xfrsource4);
2578 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
2579 REQUIRE(DNS_ZONE_VALID(zone));
2582 zone->xfrsource6 = *xfrsource;
2585 return (ISC_R_SUCCESS);
2589 dns_zone_getxfrsource6(dns_zone_t *zone) {
2590 REQUIRE(DNS_ZONE_VALID(zone));
2591 return (&zone->xfrsource6);
2595 dns_zone_setaltxfrsource4(dns_zone_t *zone,
2596 const isc_sockaddr_t *altxfrsource)
2598 REQUIRE(DNS_ZONE_VALID(zone));
2601 zone->altxfrsource4 = *altxfrsource;
2604 return (ISC_R_SUCCESS);
2608 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
2609 REQUIRE(DNS_ZONE_VALID(zone));
2610 return (&zone->altxfrsource4);
2614 dns_zone_setaltxfrsource6(dns_zone_t *zone,
2615 const isc_sockaddr_t *altxfrsource)
2617 REQUIRE(DNS_ZONE_VALID(zone));
2620 zone->altxfrsource6 = *altxfrsource;
2623 return (ISC_R_SUCCESS);
2627 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
2628 REQUIRE(DNS_ZONE_VALID(zone));
2629 return (&zone->altxfrsource6);
2633 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
2634 REQUIRE(DNS_ZONE_VALID(zone));
2637 zone->notifysrc4 = *notifysrc;
2640 return (ISC_R_SUCCESS);
2644 dns_zone_getnotifysrc4(dns_zone_t *zone) {
2645 REQUIRE(DNS_ZONE_VALID(zone));
2646 return (&zone->notifysrc4);
2650 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
2651 REQUIRE(DNS_ZONE_VALID(zone));
2654 zone->notifysrc6 = *notifysrc;
2657 return (ISC_R_SUCCESS);
2661 dns_zone_getnotifysrc6(dns_zone_t *zone) {
2662 REQUIRE(DNS_ZONE_VALID(zone));
2663 return (&zone->notifysrc6);
2667 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
2670 isc_sockaddr_t *new;
2672 REQUIRE(DNS_ZONE_VALID(zone));
2673 REQUIRE(count == 0 || notify != NULL);
2676 if (zone->notify != NULL) {
2677 isc_mem_put(zone->mctx, zone->notify,
2678 zone->notifycnt * sizeof(*new));
2679 zone->notify = NULL;
2680 zone->notifycnt = 0;
2683 new = isc_mem_get(zone->mctx, count * sizeof(*new));
2686 return (ISC_R_NOMEMORY);
2688 memcpy(new, notify, count * sizeof(*new));
2690 zone->notifycnt = count;
2693 return (ISC_R_SUCCESS);
2697 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
2700 isc_result_t result;
2702 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
2706 static isc_boolean_t
2707 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
2712 for (i = 0; i < count; i++)
2713 if (!isc_sockaddr_equal(&old[i], &new[i]))
2718 static isc_boolean_t
2719 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
2722 if (old == NULL && new == NULL)
2724 if (old == NULL || new == NULL)
2727 for (i = 0; i < count; i++) {
2728 if (old[i] == NULL && new[i] == NULL)
2730 if (old[i] == NULL || new[i] == NULL ||
2731 !dns_name_equal(old[i], new[i]))
2738 dns_zone_setmasterswithkeys(dns_zone_t *zone,
2739 const isc_sockaddr_t *masters,
2740 dns_name_t **keynames,
2743 isc_sockaddr_t *new;
2744 isc_result_t result = ISC_R_SUCCESS;
2745 dns_name_t **newname;
2746 isc_boolean_t *newok;
2749 REQUIRE(DNS_ZONE_VALID(zone));
2750 REQUIRE(count == 0 || masters != NULL);
2751 if (keynames != NULL) {
2752 REQUIRE(count != 0);
2757 * The refresh code assumes that 'masters' wouldn't change under it.
2758 * If it will change then kill off any current refresh in progress
2759 * and update the masters info. If it won't change then we can just
2762 if (count != zone->masterscnt ||
2763 !same_masters(zone->masters, masters, count) ||
2764 !same_keynames(zone->masterkeynames, keynames, count)) {
2765 if (zone->request != NULL)
2766 dns_request_cancel(zone->request);
2769 if (zone->masters != NULL) {
2770 isc_mem_put(zone->mctx, zone->masters,
2771 zone->masterscnt * sizeof(*new));
2772 zone->masters = NULL;
2774 if (zone->masterkeynames != NULL) {
2775 for (i = 0; i < zone->masterscnt; i++) {
2776 if (zone->masterkeynames[i] != NULL) {
2777 dns_name_free(zone->masterkeynames[i],
2779 isc_mem_put(zone->mctx,
2780 zone->masterkeynames[i],
2781 sizeof(dns_name_t));
2782 zone->masterkeynames[i] = NULL;
2785 isc_mem_put(zone->mctx, zone->masterkeynames,
2786 zone->masterscnt * sizeof(dns_name_t *));
2787 zone->masterkeynames = NULL;
2789 if (zone->mastersok != NULL) {
2790 isc_mem_put(zone->mctx, zone->mastersok,
2791 zone->masterscnt * sizeof(isc_boolean_t));
2792 zone->mastersok = NULL;
2794 zone->masterscnt = 0;
2796 * If count == 0, don't allocate any space for masters, mastersok or
2797 * keynames so internally, those pointers are NULL if count == 0
2803 * masters must countain count elements!
2805 new = isc_mem_get(zone->mctx, count * sizeof(*new));
2807 result = ISC_R_NOMEMORY;
2810 memcpy(new, masters, count * sizeof(*new));
2813 * Similarly for mastersok.
2815 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
2816 if (newok == NULL) {
2817 result = ISC_R_NOMEMORY;
2818 isc_mem_put(zone->mctx, new, count * sizeof(*new));
2821 for (i = 0; i < count; i++)
2822 newok[i] = ISC_FALSE;
2825 * if keynames is non-NULL, it must contain count elements!
2828 if (keynames != NULL) {
2829 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
2830 if (newname == NULL) {
2831 result = ISC_R_NOMEMORY;
2832 isc_mem_put(zone->mctx, new, count * sizeof(*new));
2833 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
2836 for (i = 0; i < count; i++)
2838 for (i = 0; i < count; i++) {
2839 if (keynames[i] != NULL) {
2840 newname[i] = isc_mem_get(zone->mctx,
2841 sizeof(dns_name_t));
2842 if (newname[i] == NULL)
2844 dns_name_init(newname[i], NULL);
2845 result = dns_name_dup(keynames[i], zone->mctx,
2847 if (result != ISC_R_SUCCESS) {
2849 for (i = 0; i < count; i++)
2850 if (newname[i] != NULL)
2854 isc_mem_put(zone->mctx, new,
2855 count * sizeof(*new));
2856 isc_mem_put(zone->mctx, newok,
2857 count * sizeof(*newok));
2858 isc_mem_put(zone->mctx, newname,
2859 count * sizeof(*newname));
2867 * Everything is ok so attach to the zone.
2869 zone->masters = new;
2870 zone->mastersok = newok;
2871 zone->masterkeynames = newname;
2872 zone->masterscnt = count;
2873 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
2881 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
2882 isc_result_t result = ISC_R_SUCCESS;
2884 REQUIRE(DNS_ZONE_VALID(zone));
2886 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2887 if (zone->db == NULL)
2888 result = DNS_R_NOTLOADED;
2890 dns_db_attach(zone->db, dpb);
2891 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2897 * Co-ordinates the starting of routine jobs.
2901 dns_zone_maintenance(dns_zone_t *zone) {
2902 const char me[] = "dns_zone_maintenance";
2905 REQUIRE(DNS_ZONE_VALID(zone));
2910 zone_settimer(zone, &now);
2914 static inline isc_boolean_t
2915 was_dumping(dns_zone_t *zone) {
2916 isc_boolean_t dumping;
2918 REQUIRE(LOCKED_ZONE(zone));
2920 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
2921 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
2923 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
2924 isc_time_settoepoch(&zone->dumptime);
2930 zone_maintenance(dns_zone_t *zone) {
2931 const char me[] = "zone_maintenance";
2933 isc_result_t result;
2934 isc_boolean_t dumping;
2936 REQUIRE(DNS_ZONE_VALID(zone));
2940 * Configuring the view of this zone may have
2941 * failed, for example because the config file
2942 * had a syntax error. In that case, the view
2943 * adb or resolver, and we had better not try
2944 * to do maintenance on it.
2946 if (zone->view == NULL || zone->view->adb == NULL)
2954 switch (zone->type) {
2955 case dns_zone_slave:
2958 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
2959 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
2961 zone->refreshtime = now;
2972 switch (zone->type) {
2973 case dns_zone_slave:
2975 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
2976 isc_time_compare(&now, &zone->refreshtime) >= 0)
2977 dns_zone_refresh(zone);
2984 * Do we need to consolidate the backing store?
2986 switch (zone->type) {
2987 case dns_zone_master:
2988 case dns_zone_slave:
2990 if (zone->masterfile != NULL &&
2991 isc_time_compare(&now, &zone->dumptime) >= 0 &&
2992 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
2993 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
2994 dumping = was_dumping(zone);
2999 result = zone_dump(zone, ISC_TRUE); /* task locked */
3000 if (result != ISC_R_SUCCESS)
3001 dns_zone_log(zone, ISC_LOG_WARNING,
3003 dns_result_totext(result));
3011 * Do we need to send out notify messages?
3013 switch (zone->type) {
3014 case dns_zone_master:
3015 case dns_zone_slave:
3016 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
3017 isc_time_compare(&now, &zone->notifytime) >= 0)
3018 zone_notify(zone, &now);
3023 zone_settimer(zone, &now);
3027 dns_zone_markdirty(dns_zone_t *zone) {
3030 zone_needdump(zone, DNS_DUMP_DELAY);
3035 dns_zone_expire(dns_zone_t *zone) {
3036 REQUIRE(DNS_ZONE_VALID(zone));
3044 zone_expire(dns_zone_t *zone) {
3046 * 'zone' locked by caller.
3049 REQUIRE(LOCKED_ZONE(zone));
3051 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
3053 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
3054 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
3055 zone->retry = DNS_ZONE_DEFAULTRETRY;
3056 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
3061 dns_zone_refresh(dns_zone_t *zone) {
3063 isc_uint32_t oldflags;
3065 isc_result_t result;
3067 REQUIRE(DNS_ZONE_VALID(zone));
3069 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
3073 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
3074 * in progress at a time.
3078 oldflags = zone->flags;
3079 if (zone->masterscnt == 0) {
3080 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
3081 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
3082 dns_zone_log(zone, ISC_LOG_ERROR,
3083 "cannot refresh: no masters");
3086 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
3087 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
3088 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
3089 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
3093 * Set the next refresh time as if refresh check has failed.
3094 * Setting this to the retry time will do that. XXXMLG
3095 * If we are successful it will be reset using zone->refresh.
3097 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
3099 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
3100 if (result |= ISC_R_SUCCESS)
3101 dns_zone_log(zone, ISC_LOG_WARNING,
3102 "isc_time_nowplusinterval() failed: %s",
3103 dns_result_totext(result));
3106 * When lacking user-specified timer values from the SOA,
3107 * do exponential backoff of the retry time up to a
3108 * maximum of six hours.
3110 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
3111 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
3113 zone->curmaster = 0;
3114 for (j = 0; j < zone->masterscnt; j++)
3115 zone->mastersok[j] = ISC_FALSE;
3116 /* initiate soa query */
3117 queue_soa_query(zone);
3123 dns_zone_flush(dns_zone_t *zone) {
3124 isc_result_t result = ISC_R_SUCCESS;
3125 isc_boolean_t dumping;
3127 REQUIRE(DNS_ZONE_VALID(zone));
3130 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
3131 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3132 zone->masterfile != NULL) {
3133 result = ISC_R_ALREADYRUNNING;
3134 dumping = was_dumping(zone);
3139 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
3144 dns_zone_dump(dns_zone_t *zone) {
3145 isc_result_t result = ISC_R_ALREADYRUNNING;
3146 isc_boolean_t dumping;
3148 REQUIRE(DNS_ZONE_VALID(zone));
3151 dumping = was_dumping(zone);
3154 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
3159 zone_needdump(dns_zone_t *zone, unsigned int delay) {
3160 isc_time_t dumptime;
3164 * 'zone' locked by caller
3167 REQUIRE(DNS_ZONE_VALID(zone));
3168 REQUIRE(LOCKED_ZONE(zone));
3171 * Do we have a place to dump to and are we loaded?
3173 if (zone->masterfile == NULL ||
3174 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
3178 /* add some noise */
3179 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
3181 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3182 if (isc_time_isepoch(&zone->dumptime) ||
3183 isc_time_compare(&zone->dumptime, &dumptime) > 0)
3184 zone->dumptime = dumptime;
3185 if (zone->task != NULL)
3186 zone_settimer(zone, &now);
3190 dump_done(void *arg, isc_result_t result) {
3191 const char me[] = "dump_done";
3192 dns_zone_t *zone = arg;
3194 dns_dbversion_t *version;
3195 isc_boolean_t again = ISC_FALSE;
3197 REQUIRE(DNS_ZONE_VALID(zone));
3201 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
3202 zone->journalsize != -1) {
3203 isc_uint32_t serial;
3204 isc_result_t tresult;
3207 * We don't own these, zone->dctx must stay valid.
3209 db = dns_dumpctx_db(zone->dctx);
3210 version = dns_dumpctx_version(zone->dctx);
3212 tresult = dns_db_getsoaserial(db, version, &serial);
3213 if (tresult == ISC_R_SUCCESS) {
3214 tresult = dns_journal_compact(zone->mctx,
3221 case ISC_R_NOTFOUND:
3222 dns_zone_log(zone, ISC_LOG_DEBUG(3),
3223 "dns_journal_compact: %s",
3224 dns_result_totext(tresult));
3227 dns_zone_log(zone, ISC_LOG_ERROR,
3228 "dns_journal_compact failed: %s",
3229 dns_result_totext(tresult));
3236 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
3237 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
3239 * Try again in a short while.
3241 zone_needdump(zone, DNS_DUMP_DELAY);
3242 } else if (result == ISC_R_SUCCESS &&
3243 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
3244 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3245 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3246 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3247 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3248 isc_time_settoepoch(&zone->dumptime);
3250 } else if (result == ISC_R_SUCCESS)
3251 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
3253 if (zone->dctx != NULL)
3254 dns_dumpctx_detach(&zone->dctx);
3255 zonemgr_putio(&zone->writeio);
3258 (void)zone_dump(zone, ISC_FALSE);
3259 dns_zone_idetach(&zone);
3263 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
3264 const char me[] = "zone_dump";
3265 isc_result_t result;
3266 dns_dbversion_t *version = NULL;
3267 isc_boolean_t again;
3268 dns_db_t *db = NULL;
3269 char *masterfile = NULL;
3270 dns_masterformat_t masterformat = dns_masterformat_none;
3273 * 'compact' MUST only be set if we are task locked.
3276 REQUIRE(DNS_ZONE_VALID(zone));
3280 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3281 if (zone->db != NULL)
3282 dns_db_attach(zone->db, &db);
3283 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3285 if (zone->masterfile != NULL) {
3286 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
3287 masterformat = zone->masterformat;
3291 result = DNS_R_NOTLOADED;
3294 if (masterfile == NULL) {
3295 result = DNS_R_NOMASTERFILE;
3300 dns_zone_t *dummy = NULL;
3302 zone_iattach(zone, &dummy);
3303 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
3304 zone_gotwritehandle, zone,
3306 if (result != ISC_R_SUCCESS)
3307 zone_idetach(&dummy);
3309 result = DNS_R_CONTINUE;
3312 dns_db_currentversion(db, &version);
3313 result = dns_master_dump2(zone->mctx, db, version,
3314 &dns_master_style_default,
3315 masterfile, masterformat);
3316 dns_db_closeversion(db, &version, ISC_FALSE);
3321 if (masterfile != NULL)
3322 isc_mem_free(zone->mctx, masterfile);
3325 if (result == DNS_R_CONTINUE)
3326 return (ISC_R_SUCCESS); /* XXXMPA */
3330 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
3331 if (result != ISC_R_SUCCESS) {
3333 * Try again in a short while.
3335 zone_needdump(zone, DNS_DUMP_DELAY);
3336 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
3337 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3338 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3339 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3340 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3341 isc_time_settoepoch(&zone->dumptime);
3344 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
3353 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
3354 dns_masterformat_t format)
3356 isc_result_t result;
3357 dns_dbversion_t *version = NULL;
3358 dns_db_t *db = NULL;
3360 REQUIRE(DNS_ZONE_VALID(zone));
3362 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3363 if (zone->db != NULL)
3364 dns_db_attach(zone->db, &db);
3365 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3367 return (DNS_R_NOTLOADED);
3369 dns_db_currentversion(db, &version);
3370 result = dns_master_dumptostream2(zone->mctx, db, version, style,
3372 dns_db_closeversion(db, &version, ISC_FALSE);
3378 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
3379 const dns_master_style_t *style) {
3380 return dumptostream(zone, fd, style, format);
3384 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
3385 return dumptostream(zone, fd, &dns_master_style_default,
3386 dns_masterformat_text);
3390 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
3391 return dumptostream(zone, fd, &dns_master_style_full,
3392 dns_masterformat_text);
3396 dns_zone_unload(dns_zone_t *zone) {
3397 REQUIRE(DNS_ZONE_VALID(zone));
3405 notify_cancel(dns_zone_t *zone) {
3406 dns_notify_t *notify;
3409 * 'zone' locked by caller.
3412 REQUIRE(LOCKED_ZONE(zone));
3414 for (notify = ISC_LIST_HEAD(zone->notifies);
3416 notify = ISC_LIST_NEXT(notify, link)) {
3417 if (notify->find != NULL)
3418 dns_adb_cancelfind(notify->find);
3419 if (notify->request != NULL)
3420 dns_request_cancel(notify->request);
3425 zone_unload(dns_zone_t *zone) {
3428 * 'zone' locked by caller.
3431 REQUIRE(LOCKED_ZONE(zone));
3433 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
3434 zone_detachdb(zone);
3435 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3436 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
3437 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3441 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
3442 REQUIRE(DNS_ZONE_VALID(zone));
3445 zone->minrefresh = val;
3449 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
3450 REQUIRE(DNS_ZONE_VALID(zone));
3453 zone->maxrefresh = val;
3457 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
3458 REQUIRE(DNS_ZONE_VALID(zone));
3461 zone->minretry = val;
3465 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
3466 REQUIRE(DNS_ZONE_VALID(zone));
3469 zone->maxretry = val;
3472 static isc_boolean_t
3473 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
3474 dns_notify_t *notify;
3476 for (notify = ISC_LIST_HEAD(zone->notifies);
3478 notify = ISC_LIST_NEXT(notify, link)) {
3479 if (notify->request != NULL)
3481 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
3482 dns_name_equal(name, ¬ify->ns))
3484 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
3490 static isc_boolean_t
3491 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
3492 dns_tsigkey_t *key = NULL;
3495 isc_boolean_t isself;
3496 isc_netaddr_t dstaddr;
3498 if (zone->view == NULL || zone->isself == NULL)
3501 switch (isc_sockaddr_pf(dst)) {
3503 src = zone->notifysrc4;
3504 isc_sockaddr_any(&any);
3507 src = zone->notifysrc6;
3508 isc_sockaddr_any6(&any);
3515 * When sending from any the kernel will assign a source address
3516 * that matches the destination address.
3518 if (isc_sockaddr_eqaddr(&any, &src))
3521 isc_netaddr_fromsockaddr(&dstaddr, dst);
3522 (void)dns_view_getpeertsig(zone->view, &dstaddr, &key);
3523 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
3526 dns_tsigkey_detach(&key);
3531 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
3535 * Caller holds zone lock.
3537 REQUIRE(DNS_NOTIFY_VALID(notify));
3539 if (notify->zone != NULL) {
3541 LOCK_ZONE(notify->zone);
3542 REQUIRE(LOCKED_ZONE(notify->zone));
3543 if (ISC_LINK_LINKED(notify, link))
3544 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
3546 UNLOCK_ZONE(notify->zone);
3548 zone_idetach(¬ify->zone);
3550 dns_zone_idetach(¬ify->zone);
3552 if (notify->find != NULL)
3553 dns_adb_destroyfind(¬ify->find);
3554 if (notify->request != NULL)
3555 dns_request_destroy(¬ify->request);
3556 if (dns_name_dynamic(¬ify->ns))
3557 dns_name_free(¬ify->ns, notify->mctx);
3558 mctx = notify->mctx;
3559 isc_mem_put(notify->mctx, notify, sizeof(*notify));
3560 isc_mem_detach(&mctx);
3564 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
3565 dns_notify_t *notify;
3567 REQUIRE(notifyp != NULL && *notifyp == NULL);
3569 notify = isc_mem_get(mctx, sizeof(*notify));
3571 return (ISC_R_NOMEMORY);
3573 notify->mctx = NULL;
3574 isc_mem_attach(mctx, ¬ify->mctx);
3575 notify->flags = flags;
3576 notify->zone = NULL;
3577 notify->find = NULL;
3578 notify->request = NULL;
3579 isc_sockaddr_any(¬ify->dst);
3580 dns_name_init(¬ify->ns, NULL);
3581 ISC_LINK_INIT(notify, link);
3582 notify->magic = NOTIFY_MAGIC;
3584 return (ISC_R_SUCCESS);
3588 * XXXAG should check for DNS_ZONEFLG_EXITING
3591 process_adb_event(isc_task_t *task, isc_event_t *ev) {
3592 dns_notify_t *notify;
3593 isc_eventtype_t result;
3597 notify = ev->ev_arg;
3598 REQUIRE(DNS_NOTIFY_VALID(notify));
3599 INSIST(task == notify->zone->task);
3600 result = ev->ev_type;
3601 isc_event_free(&ev);
3602 if (result == DNS_EVENT_ADBMOREADDRESSES) {
3603 dns_adb_destroyfind(¬ify->find);
3604 notify_find_address(notify);
3607 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
3608 LOCK_ZONE(notify->zone);
3609 notify_send(notify);
3610 UNLOCK_ZONE(notify->zone);
3612 notify_destroy(notify, ISC_FALSE);
3616 notify_find_address(dns_notify_t *notify) {
3617 isc_result_t result;
3618 unsigned int options;
3620 REQUIRE(DNS_NOTIFY_VALID(notify));
3621 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
3622 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
3624 if (notify->zone->view->adb == NULL)
3627 result = dns_adb_createfind(notify->zone->view->adb,
3629 process_adb_event, notify,
3630 ¬ify->ns, dns_rootname, 0,
3632 notify->zone->view->dstport,
3635 /* Something failed? */
3636 if (result != ISC_R_SUCCESS)
3639 /* More addresses pending? */
3640 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
3643 /* We have as many addresses as we can get. */
3644 LOCK_ZONE(notify->zone);
3645 notify_send(notify);
3646 UNLOCK_ZONE(notify->zone);
3649 notify_destroy(notify, ISC_FALSE);
3654 notify_send_queue(dns_notify_t *notify) {
3656 isc_result_t result;
3658 e = isc_event_allocate(notify->mctx, NULL,
3659 DNS_EVENT_NOTIFYSENDTOADDR,
3661 notify, sizeof(isc_event_t));
3663 return (ISC_R_NOMEMORY);
3665 e->ev_sender = NULL;
3666 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
3667 notify->zone->task, &e);
3668 if (result != ISC_R_SUCCESS)
3674 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
3675 dns_notify_t *notify;
3676 isc_result_t result;
3677 dns_message_t *message = NULL;
3678 isc_netaddr_t dstip;
3679 dns_tsigkey_t *key = NULL;
3680 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
3683 isc_boolean_t have_notifysource = ISC_FALSE;
3685 notify = event->ev_arg;
3686 REQUIRE(DNS_NOTIFY_VALID(notify));
3690 LOCK_ZONE(notify->zone);
3692 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
3693 result = ISC_R_CANCELED;
3697 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
3698 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
3699 notify->zone->view->requestmgr == NULL ||
3700 notify->zone->db == NULL) {
3701 result = ISC_R_CANCELED;
3706 * The raw IPv4 address should also exist. Don't send to the
3709 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
3710 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
3711 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
3712 notify_log(notify->zone, ISC_LOG_DEBUG(3),
3713 "notify: ignoring IPv6 mapped IPV4 address: %s",
3715 result = ISC_R_CANCELED;
3719 result = notify_createmessage(notify->zone, notify->flags, &message);
3720 if (result != ISC_R_SUCCESS)
3723 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
3724 (void)dns_view_getpeertsig(notify->zone->view, &dstip, &key);
3726 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
3727 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
3729 if (notify->zone->view->peers != NULL) {
3730 dns_peer_t *peer = NULL;
3731 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
3733 if (result == ISC_R_SUCCESS) {
3734 result = dns_peer_getnotifysource(peer, &src);
3735 if (result == ISC_R_SUCCESS)
3736 have_notifysource = ISC_TRUE;
3739 switch (isc_sockaddr_pf(¬ify->dst)) {
3741 if (!have_notifysource)
3742 src = notify->zone->notifysrc4;
3745 if (!have_notifysource)
3746 src = notify->zone->notifysrc6;
3749 result = ISC_R_NOTIMPLEMENTED;
3753 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
3755 result = dns_request_createvia2(notify->zone->view->requestmgr,
3756 message, &src, ¬ify->dst, 0, key,
3757 timeout * 3, timeout,
3758 notify->zone->task, notify_done,
3759 notify, ¬ify->request);
3762 dns_tsigkey_detach(&key);
3763 dns_message_destroy(&message);
3765 UNLOCK_ZONE(notify->zone);
3766 if (result != ISC_R_SUCCESS)
3767 notify_destroy(notify, ISC_FALSE);
3768 isc_event_free(&event);
3772 notify_send(dns_notify_t *notify) {
3773 dns_adbaddrinfo_t *ai;
3775 isc_result_t result;
3776 dns_notify_t *new = NULL;
3779 * Zone lock held by caller.
3781 REQUIRE(DNS_NOTIFY_VALID(notify));
3782 REQUIRE(LOCKED_ZONE(notify->zone));
3784 for (ai = ISC_LIST_HEAD(notify->find->list);
3786 ai = ISC_LIST_NEXT(ai, publink)) {
3788 if (notify_isqueued(notify->zone, NULL, &dst))
3790 if (notify_isself(notify->zone, &dst))
3793 result = notify_create(notify->mctx,
3794 (notify->flags & DNS_NOTIFY_NOSOA),
3796 if (result != ISC_R_SUCCESS)
3798 zone_iattach(notify->zone, &new->zone);
3799 ISC_LIST_APPEND(new->zone->notifies, new, link);
3801 result = notify_send_queue(new);
3802 if (result != ISC_R_SUCCESS)
3809 notify_destroy(new, ISC_TRUE);
3813 dns_zone_notify(dns_zone_t *zone) {
3816 REQUIRE(DNS_ZONE_VALID(zone));
3819 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
3822 zone_settimer(zone, &now);
3827 zone_notify(dns_zone_t *zone, isc_time_t *now) {
3828 dns_dbnode_t *node = NULL;
3829 dns_db_t *zonedb = NULL;
3830 dns_dbversion_t *version = NULL;
3831 dns_name_t *origin = NULL;
3834 dns_rdata_soa_t soa;
3835 isc_uint32_t serial;
3836 dns_rdata_t rdata = DNS_RDATA_INIT;
3837 dns_rdataset_t nsrdset;
3838 dns_rdataset_t soardset;
3839 isc_result_t result;
3840 dns_notify_t *notify = NULL;
3843 isc_boolean_t isqueued;
3844 dns_notifytype_t notifytype;
3845 unsigned int flags = 0;
3846 isc_boolean_t loggednotify = ISC_FALSE;
3848 REQUIRE(DNS_ZONE_VALID(zone));
3851 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
3852 notifytype = zone->notifytype;
3853 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
3856 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
3859 if (notifytype == dns_notifytype_no)
3862 if (notifytype == dns_notifytype_masteronly &&
3863 zone->type != dns_zone_master)
3866 origin = &zone->origin;
3869 * If the zone is dialup we are done as we don't want to send
3870 * the current soa so as to force a refresh query.
3872 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
3873 flags |= DNS_NOTIFY_NOSOA;
3878 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3879 if (zone->db != NULL)
3880 dns_db_attach(zone->db, &zonedb);
3881 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3884 dns_db_currentversion(zonedb, &version);
3885 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
3886 if (result != ISC_R_SUCCESS)
3889 dns_rdataset_init(&soardset);
3890 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
3891 dns_rdatatype_none, 0, &soardset, NULL);
3892 if (result != ISC_R_SUCCESS)
3896 * Find serial and master server's name.
3898 dns_name_init(&master, NULL);
3899 result = dns_rdataset_first(&soardset);
3900 if (result != ISC_R_SUCCESS)
3902 dns_rdataset_current(&soardset, &rdata);
3903 result = dns_rdata_tostruct(&rdata, &soa, NULL);
3904 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3905 dns_rdata_reset(&rdata);
3906 result = dns_name_dup(&soa.origin, zone->mctx, &master);
3907 serial = soa.serial;
3908 dns_rdataset_disassociate(&soardset);
3909 if (result != ISC_R_SUCCESS)
3913 * Enqueue notify requests for 'also-notify' servers.
3916 for (i = 0; i < zone->notifycnt; i++) {
3917 dst = zone->notify[i];
3918 if (notify_isqueued(zone, NULL, &dst))
3920 result = notify_create(zone->mctx, flags, ¬ify);
3921 if (result != ISC_R_SUCCESS)
3923 zone_iattach(zone, ¬ify->zone);
3925 ISC_LIST_APPEND(zone->notifies, notify, link);
3926 result = notify_send_queue(notify);
3927 if (result != ISC_R_SUCCESS)
3928 notify_destroy(notify, ISC_TRUE);
3929 if (!loggednotify) {
3930 notify_log(zone, ISC_LOG_INFO,
3931 "sending notifies (serial %u)",
3933 loggednotify = ISC_TRUE;
3939 if (notifytype == dns_notifytype_explicit)
3943 * Process NS RRset to generate notifies.
3946 dns_rdataset_init(&nsrdset);
3947 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
3948 dns_rdatatype_none, 0, &nsrdset, NULL);
3949 if (result != ISC_R_SUCCESS)
3952 result = dns_rdataset_first(&nsrdset);
3953 while (result == ISC_R_SUCCESS) {
3954 dns_rdataset_current(&nsrdset, &rdata);
3955 result = dns_rdata_tostruct(&rdata, &ns, NULL);
3956 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3957 dns_rdata_reset(&rdata);
3959 * don't notify the master server.
3961 if (dns_name_compare(&master, &ns.name) == 0) {
3962 result = dns_rdataset_next(&nsrdset);
3966 if (!loggednotify) {
3967 notify_log(zone, ISC_LOG_INFO,
3968 "sending notifies (serial %u)",
3970 loggednotify = ISC_TRUE;
3974 isqueued = notify_isqueued(zone, &ns.name, NULL);
3977 result = dns_rdataset_next(&nsrdset);
3980 result = notify_create(zone->mctx, flags, ¬ify);
3981 if (result != ISC_R_SUCCESS)
3983 dns_zone_iattach(zone, ¬ify->zone);
3984 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
3985 if (result != ISC_R_SUCCESS) {
3987 notify_destroy(notify, ISC_TRUE);
3992 ISC_LIST_APPEND(zone->notifies, notify, link);
3994 notify_find_address(notify);
3996 result = dns_rdataset_next(&nsrdset);
3998 dns_rdataset_disassociate(&nsrdset);
4001 if (dns_name_dynamic(&master))
4002 dns_name_free(&master, zone->mctx);
4004 dns_db_detachnode(zonedb, &node);
4006 dns_db_closeversion(zonedb, &version, ISC_FALSE);
4007 dns_db_detach(&zonedb);
4014 static inline isc_result_t
4015 save_nsrrset(dns_message_t *message, dns_name_t *name,
4016 dns_db_t *db, dns_dbversion_t *version)
4018 dns_rdataset_t *nsrdataset = NULL;
4019 dns_rdataset_t *rdataset = NULL;
4020 dns_dbnode_t *node = NULL;
4022 isc_result_t result;
4023 dns_rdata_t rdata = DNS_RDATA_INIT;
4026 * Extract NS RRset from message.
4028 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
4029 dns_rdatatype_ns, dns_rdatatype_none,
4031 if (result != ISC_R_SUCCESS)
4037 result = dns_db_findnode(db, name, ISC_TRUE, &node);
4038 if (result != ISC_R_SUCCESS)
4040 result = dns_db_addrdataset(db, node, version, 0,
4041 nsrdataset, 0, NULL);
4042 dns_db_detachnode(db, &node);
4043 if (result != ISC_R_SUCCESS)
4046 * Add glue rdatasets.
4048 for (result = dns_rdataset_first(nsrdataset);
4049 result == ISC_R_SUCCESS;
4050 result = dns_rdataset_next(nsrdataset)) {
4051 dns_rdataset_current(nsrdataset, &rdata);
4052 result = dns_rdata_tostruct(&rdata, &ns, NULL);
4053 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4054 dns_rdata_reset(&rdata);
4055 if (!dns_name_issubdomain(&ns.name, name))
4058 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
4059 &ns.name, dns_rdatatype_aaaa,
4060 dns_rdatatype_none, NULL,
4062 if (result == ISC_R_SUCCESS) {
4063 result = dns_db_findnode(db, &ns.name,
4065 if (result != ISC_R_SUCCESS)
4067 result = dns_db_addrdataset(db, node, version, 0,
4069 dns_db_detachnode(db, &node);
4070 if (result != ISC_R_SUCCESS)
4074 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
4075 &ns.name, dns_rdatatype_a,
4076 dns_rdatatype_none, NULL,
4078 if (result == ISC_R_SUCCESS) {
4079 result = dns_db_findnode(db, &ns.name,
4081 if (result != ISC_R_SUCCESS)
4083 result = dns_db_addrdataset(db, node, version, 0,
4085 dns_db_detachnode(db, &node);
4086 if (result != ISC_R_SUCCESS)
4090 if (result != ISC_R_NOMORE)
4093 return (ISC_R_SUCCESS);
4100 stub_callback(isc_task_t *task, isc_event_t *event) {
4101 const char me[] = "stub_callback";
4102 dns_requestevent_t *revent = (dns_requestevent_t *)event;
4103 dns_stub_t *stub = NULL;
4104 dns_message_t *msg = NULL;
4105 dns_zone_t *zone = NULL;
4106 char master[ISC_SOCKADDR_FORMATSIZE];
4107 char source[ISC_SOCKADDR_FORMATSIZE];
4108 isc_uint32_t nscnt, cnamecnt;
4109 isc_result_t result;
4111 isc_boolean_t exiting = ISC_FALSE;
4115 stub = revent->ev_arg;
4116 INSIST(DNS_STUB_VALID(stub));
4126 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
4127 zone_debuglog(zone, me, 1, "exiting");
4132 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
4133 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
4135 if (revent->result != ISC_R_SUCCESS) {
4136 if (revent->result == ISC_R_TIMEDOUT &&
4137 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4139 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4141 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4142 "refreshing stub: timeout retrying "
4143 " without EDNS master %s (source %s)",
4147 dns_zone_log(zone, ISC_LOG_INFO,
4148 "could not refresh stub from master %s"
4149 " (source %s): %s", master, source,
4150 dns_result_totext(revent->result));
4154 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
4155 if (result != ISC_R_SUCCESS)
4158 result = dns_request_getresponse(revent->request, msg, 0);
4159 if (result != ISC_R_SUCCESS)
4165 if (msg->rcode != dns_rcode_noerror) {
4169 isc_buffer_init(&rb, rcode, sizeof(rcode));
4170 (void)dns_rcode_totext(msg->rcode, &rb);
4172 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
4173 (msg->rcode == dns_rcode_servfail ||
4174 msg->rcode == dns_rcode_notimp ||
4175 msg->rcode == dns_rcode_formerr)) {
4176 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4177 "refreshing stub: rcode (%.*s) retrying "
4178 "without EDNS master %s (source %s)",
4179 (int)rb.used, rcode, master, source);
4181 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4186 dns_zone_log(zone, ISC_LOG_INFO,
4188 "unexpected rcode (%.*s) from %s (source %s)",
4189 (int)rb.used, rcode, master, source);
4194 * We need complete messages.
4196 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
4197 if (dns_request_usedtcp(revent->request)) {
4198 dns_zone_log(zone, ISC_LOG_INFO,
4199 "refreshing stub: truncated TCP "
4200 "response from master %s (source %s)",
4205 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
4211 * If non-auth log and next master.
4213 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
4214 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
4215 "non-authoritative answer from "
4216 "master %s (source %s)", master, source);
4223 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
4224 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
4226 if (cnamecnt != 0) {
4227 dns_zone_log(zone, ISC_LOG_INFO,
4228 "refreshing stub: unexpected CNAME response "
4229 "from master %s (source %s)", master, source);
4234 dns_zone_log(zone, ISC_LOG_INFO,
4235 "refreshing stub: no NS records in response "
4236 "from master %s (source %s)", master, source);
4243 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
4244 if (result != ISC_R_SUCCESS) {
4245 dns_zone_log(zone, ISC_LOG_INFO,
4246 "refreshing stub: unable to save NS records "
4247 "from master %s (source %s)", master, source);
4254 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
4255 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4256 if (zone->db == NULL)
4257 zone_attachdb(zone, stub->db);
4258 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4259 dns_db_detach(&stub->db);
4261 if (zone->masterfile != NULL) {
4262 dns_zone_dump(zone);
4263 TIME_NOW(&zone->loadtime);
4266 dns_message_destroy(&msg);
4267 isc_event_free(&event);
4269 dns_request_destroy(&zone->request);
4270 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4271 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
4272 isc_interval_set(&i, zone->expire, 0);
4273 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
4274 zone_settimer(zone, &now);
4279 if (stub->version != NULL)
4280 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
4281 if (stub->db != NULL)
4282 dns_db_detach(&stub->db);
4284 dns_message_destroy(&msg);
4285 isc_event_free(&event);
4287 dns_request_destroy(&zone->request);
4289 * Skip to next failed / untried master.
4293 } while (zone->curmaster < zone->masterscnt &&
4294 zone->mastersok[zone->curmaster]);
4295 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
4296 if (exiting || zone->curmaster >= zone->masterscnt) {
4297 isc_boolean_t done = ISC_TRUE;
4299 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
4300 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4302 * Did we get a good answer from all the masters?
4304 for (j = 0; j < zone->masterscnt; j++)
4305 if (zone->mastersok[j] == ISC_FALSE) {
4312 zone->curmaster = 0;
4314 * Find the next failed master.
4316 while (zone->curmaster < zone->masterscnt &&
4317 zone->mastersok[zone->curmaster])
4319 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4321 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4323 zone_settimer(zone, &now);
4328 queue_soa_query(zone);
4334 dns_message_destroy(&msg);
4335 isc_event_free(&event);
4337 dns_request_destroy(&zone->request);
4339 ns_query(zone, NULL, stub);
4344 dns_zone_idetach(&stub->zone);
4345 INSIST(stub->db == NULL);
4346 INSIST(stub->version == NULL);
4347 isc_mem_put(stub->mctx, stub, sizeof(*stub));
4350 INSIST(event == NULL);
4355 * An SOA query has finished (successfully or not).
4358 refresh_callback(isc_task_t *task, isc_event_t *event) {
4359 const char me[] = "refresh_callback";
4360 dns_requestevent_t *revent = (dns_requestevent_t *)event;
4362 dns_message_t *msg = NULL;
4363 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
4365 char master[ISC_SOCKADDR_FORMATSIZE];
4366 char source[ISC_SOCKADDR_FORMATSIZE];
4367 dns_rdataset_t *rdataset = NULL;
4368 dns_rdata_t rdata = DNS_RDATA_INIT;
4369 dns_rdata_soa_t soa;
4370 isc_result_t result;
4371 isc_uint32_t serial;
4374 zone = revent->ev_arg;
4375 INSIST(DNS_ZONE_VALID(zone));
4382 * if timeout log and next master;
4385 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
4386 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
4390 if (revent->result != ISC_R_SUCCESS) {
4391 if (revent->result == ISC_R_TIMEDOUT &&
4392 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4394 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4396 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4397 "refresh: timeout retrying without EDNS "
4398 "master %s (source %s)", master, source);
4401 if (revent->result == ISC_R_TIMEDOUT &&
4402 !dns_request_usedtcp(revent->request)) {
4403 dns_zone_log(zone, ISC_LOG_INFO,
4404 "refresh: retry limit for "
4405 "master %s exceeded (source %s)",
4407 /* Try with slave with TCP. */
4408 if (zone->type == dns_zone_slave) {
4410 DNS_ZONE_SETFLAG(zone,
4411 DNS_ZONEFLG_SOABEFOREAXFR);
4416 dns_zone_log(zone, ISC_LOG_INFO,
4417 "refresh: failure trying master "
4418 "%s (source %s): %s", master, source,
4419 dns_result_totext(revent->result));
4423 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
4424 if (result != ISC_R_SUCCESS)
4426 result = dns_request_getresponse(revent->request, msg, 0);
4427 if (result != ISC_R_SUCCESS) {
4428 dns_zone_log(zone, ISC_LOG_INFO,
4429 "refresh: failure trying master "
4430 "%s (source %s): %s", master, source,
4431 dns_result_totext(result));
4438 if (msg->rcode != dns_rcode_noerror) {
4442 isc_buffer_init(&rb, rcode, sizeof(rcode));
4443 (void)dns_rcode_totext(msg->rcode, &rb);
4445 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
4446 (msg->rcode == dns_rcode_servfail ||
4447 msg->rcode == dns_rcode_notimp ||
4448 msg->rcode == dns_rcode_formerr)) {
4449 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4450 "refresh: rcode (%.*s) retrying without "
4451 "EDNS master %s (source %s)",
4452 (int)rb.used, rcode, master, source);
4454 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4458 dns_zone_log(zone, ISC_LOG_INFO,
4459 "refresh: unexpected rcode (%.*s) from "
4460 "master %s (source %s)", (int)rb.used, rcode,
4463 * Perhaps AXFR/IXFR is allowed even if SOA queries arn't.
4465 if (msg->rcode == dns_rcode_refused &&
4466 zone->type == dns_zone_slave)
4472 * If truncated punt to zone transfer which will query again.
4474 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
4475 if (zone->type == dns_zone_slave) {
4476 dns_zone_log(zone, ISC_LOG_INFO,
4477 "refresh: truncated UDP answer, "
4478 "initiating TCP zone xfer "
4479 "for master %s (source %s)",
4482 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
4486 INSIST(zone->type == dns_zone_stub);
4487 if (dns_request_usedtcp(revent->request)) {
4488 dns_zone_log(zone, ISC_LOG_INFO,
4489 "refresh: truncated TCP response "
4490 "from master %s (source %s)",
4495 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
4502 * if non-auth log and next master;
4504 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
4505 dns_zone_log(zone, ISC_LOG_INFO,
4506 "refresh: non-authoritative answer from "
4507 "master %s (source %s)", master, source);
4511 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
4512 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
4513 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
4514 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
4518 * There should not be a CNAME record at top of zone.
4520 if (cnamecnt != 0) {
4521 dns_zone_log(zone, ISC_LOG_INFO,
4522 "refresh: CNAME at top of zone "
4523 "in master %s (source %s)", master, source);
4528 * if referral log and next master;
4530 if (soacnt == 0 && soacount == 0 && nscount != 0) {
4531 dns_zone_log(zone, ISC_LOG_INFO,
4532 "refresh: referral response "
4533 "from master %s (source %s)", master, source);
4538 * if nodata log and next master;
4540 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
4541 dns_zone_log(zone, ISC_LOG_INFO,
4542 "refresh: NODATA response "
4543 "from master %s (source %s)", master, source);
4548 * Only one soa at top of zone.
4551 dns_zone_log(zone, ISC_LOG_INFO,
4552 "refresh: answer SOA count (%d) != 1 "
4553 "from master %s (source %s)",
4554 soacnt, master, source);
4561 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
4562 dns_rdatatype_soa, dns_rdatatype_none,
4564 if (result != ISC_R_SUCCESS) {
4565 dns_zone_log(zone, ISC_LOG_INFO,
4566 "refresh: unable to get SOA record "
4567 "from master %s (source %s)", master, source);
4571 result = dns_rdataset_first(rdataset);
4572 if (result != ISC_R_SUCCESS) {
4573 dns_zone_log(zone, ISC_LOG_INFO,
4574 "refresh: dns_rdataset_first() failed");
4578 dns_rdataset_current(rdataset, &rdata);
4579 result = dns_rdata_tostruct(&rdata, &soa, NULL);
4580 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4582 serial = soa.serial;
4584 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
4585 serial, zone->serial);
4586 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
4587 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
4588 isc_serial_gt(serial, zone->serial)) {
4590 isc_event_free(&event);
4592 dns_request_destroy(&zone->request);
4594 if (zone->type == dns_zone_slave) {
4597 INSIST(zone->type == dns_zone_stub);
4598 ns_query(zone, rdataset, NULL);
4601 dns_message_destroy(&msg);
4602 } else if (isc_serial_eq(soa.serial, zone->serial)) {
4603 if (zone->masterfile != NULL) {
4604 result = ISC_R_FAILURE;
4605 if (zone->journal != NULL)
4606 result = isc_file_settime(zone->journal, &now);
4607 if (result == ISC_R_SUCCESS &&
4608 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
4609 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
4610 result = isc_file_settime(zone->masterfile,
4612 } else if (result != ISC_R_SUCCESS)
4613 result = isc_file_settime(zone->masterfile,
4615 /* Someone removed the file from underneath us! */
4616 if (result == ISC_R_FILENOTFOUND) {
4618 zone_needdump(zone, DNS_DUMP_DELAY);
4620 } else if (result != ISC_R_SUCCESS)
4621 dns_zone_log(zone, ISC_LOG_ERROR,
4622 "refresh: could not set file "
4623 "modification time of '%s': %s",
4625 dns_result_totext(result));
4627 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
4628 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
4629 zone->mastersok[zone->curmaster] = ISC_TRUE;
4632 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
4633 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
4634 "received from master %s < ours (%u)",
4635 soa.serial, master, zone->serial);
4637 zone_debuglog(zone, me, 1, "ahead");
4638 zone->mastersok[zone->curmaster] = ISC_TRUE;
4642 dns_message_destroy(&msg);
4647 dns_message_destroy(&msg);
4648 isc_event_free(&event);
4650 dns_request_destroy(&zone->request);
4652 * Skip to next failed / untried master.
4656 } while (zone->curmaster < zone->masterscnt &&
4657 zone->mastersok[zone->curmaster]);
4658 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
4659 if (zone->curmaster >= zone->masterscnt) {
4660 isc_boolean_t done = ISC_TRUE;
4661 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
4662 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4664 * Did we get a good answer from all the masters?
4666 for (j = 0; j < zone->masterscnt; j++)
4667 if (zone->mastersok[j] == ISC_FALSE) {
4674 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4675 zone->curmaster = 0;
4677 * Find the next failed master.
4679 while (zone->curmaster < zone->masterscnt &&
4680 zone->mastersok[zone->curmaster])
4684 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4685 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
4686 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
4687 zone->refreshtime = now;
4689 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4690 zone_settimer(zone, &now);
4696 queue_soa_query(zone);
4702 dns_message_destroy(&msg);
4703 isc_event_free(&event);
4705 dns_request_destroy(&zone->request);
4706 queue_soa_query(zone);
4710 dns_zone_idetach(&zone);
4715 queue_soa_query(dns_zone_t *zone) {
4716 const char me[] = "queue_soa_query";
4718 dns_zone_t *dummy = NULL;
4719 isc_result_t result;
4725 REQUIRE(LOCKED_ZONE(zone));
4727 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
4728 cancel_refresh(zone);
4732 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
4733 soa_query, zone, sizeof(isc_event_t));
4735 cancel_refresh(zone);
4740 * Attach so that we won't clean up
4741 * until the event is delivered.
4743 zone_iattach(zone, &dummy);
4746 e->ev_sender = NULL;
4747 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
4748 if (result != ISC_R_SUCCESS) {
4749 zone_idetach(&dummy);
4751 cancel_refresh(zone);
4755 static inline isc_result_t
4756 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
4757 dns_message_t **messagep)
4759 dns_message_t *message = NULL;
4760 dns_name_t *qname = NULL;
4761 dns_rdataset_t *qrdataset = NULL;
4762 isc_result_t result;
4764 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
4766 if (result != ISC_R_SUCCESS)
4769 message->opcode = dns_opcode_query;
4770 message->rdclass = zone->rdclass;
4772 result = dns_message_gettempname(message, &qname);
4773 if (result != ISC_R_SUCCESS)
4776 result = dns_message_gettemprdataset(message, &qrdataset);
4777 if (result != ISC_R_SUCCESS)
4783 dns_name_init(qname, NULL);
4784 dns_name_clone(&zone->origin, qname);
4785 dns_rdataset_init(qrdataset);
4786 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
4787 ISC_LIST_APPEND(qname->list, qrdataset, link);
4788 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
4790 *messagep = message;
4791 return (ISC_R_SUCCESS);
4795 dns_message_puttempname(message, &qname);
4796 if (qrdataset != NULL)
4797 dns_message_puttemprdataset(message, &qrdataset);
4798 if (message != NULL)
4799 dns_message_destroy(&message);
4804 add_opt(dns_message_t *message, isc_uint16_t udpsize) {
4805 dns_rdataset_t *rdataset = NULL;
4806 dns_rdatalist_t *rdatalist = NULL;
4807 dns_rdata_t *rdata = NULL;
4808 isc_result_t result;
4810 result = dns_message_gettemprdatalist(message, &rdatalist);
4811 if (result != ISC_R_SUCCESS)
4813 result = dns_message_gettemprdata(message, &rdata);
4814 if (result != ISC_R_SUCCESS)
4816 result = dns_message_gettemprdataset(message, &rdataset);
4817 if (result != ISC_R_SUCCESS)
4819 dns_rdataset_init(rdataset);
4821 rdatalist->type = dns_rdatatype_opt;
4822 rdatalist->covers = 0;
4825 * Set Maximum UDP buffer size.
4827 rdatalist->rdclass = udpsize;
4830 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
4839 rdata->rdclass = rdatalist->rdclass;
4840 rdata->type = rdatalist->type;
4843 ISC_LIST_INIT(rdatalist->rdata);
4844 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
4845 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
4848 return (dns_message_setopt(message, rdataset));
4851 if (rdatalist != NULL)
4852 dns_message_puttemprdatalist(message, &rdatalist);
4853 if (rdataset != NULL)
4854 dns_message_puttemprdataset(message, &rdataset);
4856 dns_message_puttemprdata(message, &rdata);
4862 soa_query(isc_task_t *task, isc_event_t *event) {
4863 const char me[] = "soa_query";
4864 isc_result_t result = ISC_R_FAILURE;
4865 dns_message_t *message = NULL;
4866 dns_zone_t *zone = event->ev_arg;
4867 dns_zone_t *dummy = NULL;
4868 isc_netaddr_t masterip;
4869 dns_tsigkey_t *key = NULL;
4870 isc_uint32_t options;
4871 isc_boolean_t cancel = ISC_TRUE;
4873 isc_boolean_t have_xfrsource;
4874 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
4876 REQUIRE(DNS_ZONE_VALID(zone));
4883 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
4884 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
4885 zone->view->requestmgr == NULL) {
4886 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
4892 * XXX Optimisation: Create message when zone is setup and reuse.
4894 result = create_query(zone, dns_rdatatype_soa, &message);
4895 if (result != ISC_R_SUCCESS)
4899 INSIST(zone->masterscnt > 0);
4900 INSIST(zone->curmaster < zone->masterscnt);
4902 zone->masteraddr = zone->masters[zone->curmaster];
4904 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
4906 * First, look for a tsig key in the master statement, then
4907 * try for a server key.
4909 if ((zone->masterkeynames != NULL) &&
4910 (zone->masterkeynames[zone->curmaster] != NULL)) {
4911 dns_view_t *view = dns_zone_getview(zone);
4912 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
4913 result = dns_view_gettsig(view, keyname, &key);
4914 if (result != ISC_R_SUCCESS) {
4915 char namebuf[DNS_NAME_FORMATSIZE];
4916 dns_name_format(keyname, namebuf, sizeof(namebuf));
4917 dns_zone_log(zone, ISC_LOG_ERROR,
4918 "unable to find key: %s", namebuf);
4922 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
4924 have_xfrsource = ISC_FALSE;
4925 if (zone->view->peers != NULL) {
4926 dns_peer_t *peer = NULL;
4928 result = dns_peerlist_peerbyaddr(zone->view->peers,
4930 if (result == ISC_R_SUCCESS) {
4931 result = dns_peer_getsupportedns(peer, &edns);
4932 if (result == ISC_R_SUCCESS && !edns)
4933 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4934 result = dns_peer_gettransfersource(peer,
4936 if (result == ISC_R_SUCCESS)
4937 have_xfrsource = ISC_TRUE;
4938 if (zone->view->resolver != NULL)
4940 dns_resolver_getudpsize(zone->view->resolver);
4941 (void)dns_peer_getudpsize(peer, &udpsize);
4945 switch (isc_sockaddr_pf(&zone->masteraddr)) {
4947 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4948 if (isc_sockaddr_equal(&zone->altxfrsource4,
4951 zone->sourceaddr = zone->altxfrsource4;
4952 } else if (!have_xfrsource)
4953 zone->sourceaddr = zone->xfrsource4;
4956 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4957 if (isc_sockaddr_equal(&zone->altxfrsource6,
4960 zone->sourceaddr = zone->altxfrsource6;
4961 } else if (!have_xfrsource)
4962 zone->sourceaddr = zone->xfrsource6;
4965 result = ISC_R_NOTIMPLEMENTED;
4969 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
4970 DNS_REQUESTOPT_TCP : 0;
4972 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4973 result = add_opt(message, udpsize);
4974 if (result != ISC_R_SUCCESS)
4975 zone_debuglog(zone, me, 1,
4976 "unable to add opt record: %s",
4977 dns_result_totext(result));
4980 zone_iattach(zone, &dummy);
4982 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
4984 result = dns_request_createvia2(zone->view->requestmgr, message,
4985 &zone->sourceaddr, &zone->masteraddr,
4986 options, key, timeout * 3, timeout,
4987 zone->task, refresh_callback, zone,
4989 if (result != ISC_R_SUCCESS) {
4990 zone_idetach(&dummy);
4991 zone_debuglog(zone, me, 1,
4992 "dns_request_createvia2() failed: %s",
4993 dns_result_totext(result));
5000 dns_tsigkey_detach(&key);
5001 if (result != ISC_R_SUCCESS)
5002 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
5003 if (message != NULL)
5004 dns_message_destroy(&message);
5006 cancel_refresh(zone);
5007 isc_event_free(&event);
5009 dns_zone_idetach(&zone);
5014 dns_tsigkey_detach(&key);
5016 * Skip to next failed / untried master.
5020 } while (zone->curmaster < zone->masterscnt &&
5021 zone->mastersok[zone->curmaster]);
5022 if (zone->curmaster < zone->masterscnt)
5024 zone->curmaster = 0;
5029 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
5030 const char me[] = "ns_query";
5031 isc_result_t result;
5032 dns_message_t *message = NULL;
5033 isc_netaddr_t masterip;
5034 dns_tsigkey_t *key = NULL;
5035 dns_dbnode_t *node = NULL;
5037 isc_boolean_t have_xfrsource = ISC_FALSE;
5038 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
5040 REQUIRE(DNS_ZONE_VALID(zone));
5041 REQUIRE((soardataset != NULL && stub == NULL) ||
5042 (soardataset == NULL && stub != NULL));
5043 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
5049 stub = isc_mem_get(zone->mctx, sizeof(*stub));
5052 stub->magic = STUB_MAGIC;
5053 stub->mctx = zone->mctx;
5056 stub->version = NULL;
5059 * Attach so that the zone won't disappear from under us.
5061 zone_iattach(zone, &stub->zone);
5064 * If a db exists we will update it, otherwise we create a
5065 * new one and attach it to the zone once we have the NS
5068 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5069 if (zone->db != NULL) {
5070 dns_db_attach(zone->db, &stub->db);
5071 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5073 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5075 INSIST(zone->db_argc >= 1);
5076 result = dns_db_create(zone->mctx, zone->db_argv[0],
5077 &zone->origin, dns_dbtype_stub,
5082 if (result != ISC_R_SUCCESS) {
5083 dns_zone_log(zone, ISC_LOG_ERROR,
5087 dns_result_totext(result));
5090 dns_db_settask(stub->db, zone->task);
5093 dns_db_newversion(stub->db, &stub->version);
5096 * Update SOA record.
5098 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
5100 if (result != ISC_R_SUCCESS) {
5101 dns_zone_log(zone, ISC_LOG_INFO,
5103 "dns_db_findnode() failed: %s",
5104 dns_result_totext(result));
5108 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
5109 soardataset, 0, NULL);
5110 dns_db_detachnode(stub->db, &node);
5111 if (result != ISC_R_SUCCESS) {
5112 dns_zone_log(zone, ISC_LOG_INFO,
5114 "dns_db_addrdataset() failed: %s",
5115 dns_result_totext(result));
5121 * XXX Optimisation: Create message when zone is setup and reuse.
5123 result = create_query(zone, dns_rdatatype_ns, &message);
5125 INSIST(zone->masterscnt > 0);
5126 INSIST(zone->curmaster < zone->masterscnt);
5127 zone->masteraddr = zone->masters[zone->curmaster];
5129 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
5131 * First, look for a tsig key in the master statement, then
5132 * try for a server key.
5134 if ((zone->masterkeynames != NULL) &&
5135 (zone->masterkeynames[zone->curmaster] != NULL)) {
5136 dns_view_t *view = dns_zone_getview(zone);
5137 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
5138 result = dns_view_gettsig(view, keyname, &key);
5139 if (result != ISC_R_SUCCESS) {
5140 char namebuf[DNS_NAME_FORMATSIZE];
5141 dns_name_format(keyname, namebuf, sizeof(namebuf));
5142 dns_zone_log(zone, ISC_LOG_ERROR,
5143 "unable to find key: %s", namebuf);
5147 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
5149 if (zone->view->peers != NULL) {
5150 dns_peer_t *peer = NULL;
5152 result = dns_peerlist_peerbyaddr(zone->view->peers,
5154 if (result == ISC_R_SUCCESS) {
5155 result = dns_peer_getsupportedns(peer, &edns);
5156 if (result == ISC_R_SUCCESS && !edns)
5157 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
5158 result = dns_peer_gettransfersource(peer,
5160 if (result == ISC_R_SUCCESS)
5161 have_xfrsource = ISC_TRUE;
5162 if (zone->view->resolver != NULL)
5164 dns_resolver_getudpsize(zone->view->resolver);
5165 (void)dns_peer_getudpsize(peer, &udpsize);
5169 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
5170 result = add_opt(message, udpsize);
5171 if (result != ISC_R_SUCCESS)
5172 zone_debuglog(zone, me, 1,
5173 "unable to add opt record: %s",
5174 dns_result_totext(result));
5178 * Always use TCP so that we shouldn't truncate in additional section.
5180 switch (isc_sockaddr_pf(&zone->masteraddr)) {
5182 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
5183 zone->sourceaddr = zone->altxfrsource4;
5184 else if (!have_xfrsource)
5185 zone->sourceaddr = zone->xfrsource4;
5188 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
5189 zone->sourceaddr = zone->altxfrsource6;
5190 else if (!have_xfrsource)
5191 zone->sourceaddr = zone->xfrsource6;
5194 result = ISC_R_NOTIMPLEMENTED;
5198 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
5200 result = dns_request_createvia2(zone->view->requestmgr, message,
5201 &zone->sourceaddr, &zone->masteraddr,
5202 DNS_REQUESTOPT_TCP, key, timeout * 3,
5203 timeout, zone->task, stub_callback,
5204 stub, &zone->request);
5205 if (result != ISC_R_SUCCESS) {
5206 zone_debuglog(zone, me, 1,
5207 "dns_request_createvia() failed: %s",
5208 dns_result_totext(result));
5211 dns_message_destroy(&message);
5215 cancel_refresh(zone);
5218 if (stub->version != NULL)
5219 dns_db_closeversion(stub->db, &stub->version,
5221 if (stub->db != NULL)
5222 dns_db_detach(&stub->db);
5223 if (stub->zone != NULL)
5224 zone_idetach(&stub->zone);
5225 isc_mem_put(stub->mctx, stub, sizeof(*stub));
5227 if (message != NULL)
5228 dns_message_destroy(&message);
5231 dns_tsigkey_detach(&key);
5237 * Handle the control event. Note that although this event causes the zone
5238 * to shut down, it is not a shutdown event in the sense of the task library.
5241 zone_shutdown(isc_task_t *task, isc_event_t *event) {
5242 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
5243 isc_boolean_t free_needed, linked = ISC_FALSE;
5246 REQUIRE(DNS_ZONE_VALID(zone));
5247 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
5248 INSIST(isc_refcount_current(&zone->erefs) == 0);
5249 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
5252 * Stop things being restarted after we cancel them below.
5255 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
5259 * If we were waiting for xfrin quota, step out of
5261 * If there's no zone manager, we can't be waiting for the
5264 if (zone->zmgr != NULL) {
5265 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
5266 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
5267 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
5270 zone->statelist = NULL;
5272 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
5276 * In task context, no locking required. See zone_xfrdone().
5278 if (zone->xfr != NULL)
5279 dns_xfrin_shutdown(zone->xfr);
5283 INSIST(zone->irefs > 0);
5286 if (zone->request != NULL) {
5287 dns_request_cancel(zone->request);
5290 if (zone->readio != NULL)
5291 zonemgr_cancelio(zone->readio);
5293 if (zone->lctx != NULL)
5294 dns_loadctx_cancel(zone->lctx);
5296 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
5297 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5298 if (zone->writeio != NULL)
5299 zonemgr_cancelio(zone->writeio);
5301 if (zone->dctx != NULL)
5302 dns_dumpctx_cancel(zone->dctx);
5305 notify_cancel(zone);
5307 if (zone->timer != NULL) {
5308 isc_timer_detach(&zone->timer);
5309 INSIST(zone->irefs > 0);
5313 if (zone->view != NULL)
5314 dns_view_weakdetach(&zone->view);
5317 * We have now canceled everything set the flag to allow exit_check()
5318 * to succeed. We must not unlock between setting this flag and
5319 * calling exit_check().
5321 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
5322 free_needed = exit_check(zone);
5329 zone_timer(isc_task_t *task, isc_event_t *event) {
5330 const char me[] = "zone_timer";
5331 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
5334 REQUIRE(DNS_ZONE_VALID(zone));
5338 zone_maintenance(zone);
5340 isc_event_free(&event);
5344 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
5345 const char me[] = "zone_settimer";
5347 isc_result_t result;
5349 REQUIRE(DNS_ZONE_VALID(zone));
5350 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
5353 isc_time_settoepoch(&next);
5355 switch (zone->type) {
5356 case dns_zone_master:
5357 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
5358 next = zone->notifytime;
5359 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
5360 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5361 INSIST(!isc_time_isepoch(&zone->dumptime));
5362 if (isc_time_isepoch(&next) ||
5363 isc_time_compare(&zone->dumptime, &next) < 0)
5364 next = zone->dumptime;
5368 case dns_zone_slave:
5369 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
5370 next = zone->notifytime;
5374 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
5375 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
5376 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
5377 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
5378 INSIST(!isc_time_isepoch(&zone->refreshtime));
5379 if (isc_time_isepoch(&next) ||
5380 isc_time_compare(&zone->refreshtime, &next) < 0)
5381 next = zone->refreshtime;
5383 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
5384 INSIST(!isc_time_isepoch(&zone->expiretime));
5385 if (isc_time_isepoch(&next) ||
5386 isc_time_compare(&zone->expiretime, &next) < 0)
5387 next = zone->expiretime;
5389 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
5390 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5391 INSIST(!isc_time_isepoch(&zone->dumptime));
5392 if (isc_time_isepoch(&next) ||
5393 isc_time_compare(&zone->dumptime, &next) < 0)
5394 next = zone->dumptime;
5402 if (isc_time_isepoch(&next)) {
5403 zone_debuglog(zone, me, 10, "settimer inactive");
5404 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
5405 NULL, NULL, ISC_TRUE);
5406 if (result != ISC_R_SUCCESS)
5407 dns_zone_log(zone, ISC_LOG_ERROR,
5408 "could not deactivate zone timer: %s",
5409 isc_result_totext(result));
5411 if (isc_time_compare(&next, now) <= 0)
5413 result = isc_timer_reset(zone->timer, isc_timertype_once,
5414 &next, NULL, ISC_TRUE);
5415 if (result != ISC_R_SUCCESS)
5416 dns_zone_log(zone, ISC_LOG_ERROR,
5417 "could not reset zone timer: %s",
5418 isc_result_totext(result));
5423 cancel_refresh(dns_zone_t *zone) {
5424 const char me[] = "cancel_refresh";
5428 * 'zone' locked by caller.
5431 REQUIRE(DNS_ZONE_VALID(zone));
5432 REQUIRE(LOCKED_ZONE(zone));
5436 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
5438 zone_settimer(zone, &now);
5442 notify_createmessage(dns_zone_t *zone, unsigned int flags,
5443 dns_message_t **messagep)
5445 dns_db_t *zonedb = NULL;
5446 dns_dbnode_t *node = NULL;
5447 dns_dbversion_t *version = NULL;
5448 dns_message_t *message = NULL;
5449 dns_rdataset_t rdataset;
5450 dns_rdata_t rdata = DNS_RDATA_INIT;
5452 dns_name_t *tempname = NULL;
5453 dns_rdata_t *temprdata = NULL;
5454 dns_rdatalist_t *temprdatalist = NULL;
5455 dns_rdataset_t *temprdataset = NULL;
5457 isc_result_t result;
5459 isc_buffer_t *b = NULL;
5461 REQUIRE(DNS_ZONE_VALID(zone));
5462 REQUIRE(messagep != NULL && *messagep == NULL);
5465 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
5467 if (result != ISC_R_SUCCESS)
5470 message->opcode = dns_opcode_notify;
5471 message->flags |= DNS_MESSAGEFLAG_AA;
5472 message->rdclass = zone->rdclass;
5474 result = dns_message_gettempname(message, &tempname);
5475 if (result != ISC_R_SUCCESS)
5478 result = dns_message_gettemprdataset(message, &temprdataset);
5479 if (result != ISC_R_SUCCESS)
5485 dns_name_init(tempname, NULL);
5486 dns_name_clone(&zone->origin, tempname);
5487 dns_rdataset_init(temprdataset);
5488 dns_rdataset_makequestion(temprdataset, zone->rdclass,
5490 ISC_LIST_APPEND(tempname->list, temprdataset, link);
5491 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
5493 temprdataset = NULL;
5495 if ((flags & DNS_NOTIFY_NOSOA) != 0)
5498 result = dns_message_gettempname(message, &tempname);
5499 if (result != ISC_R_SUCCESS)
5501 result = dns_message_gettemprdata(message, &temprdata);
5502 if (result != ISC_R_SUCCESS)
5504 result = dns_message_gettemprdataset(message, &temprdataset);
5505 if (result != ISC_R_SUCCESS)
5507 result = dns_message_gettemprdatalist(message, &temprdatalist);
5508 if (result != ISC_R_SUCCESS)
5511 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5512 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
5513 dns_db_attach(zone->db, &zonedb);
5514 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5516 dns_name_init(tempname, NULL);
5517 dns_name_clone(&zone->origin, tempname);
5518 dns_db_currentversion(zonedb, &version);
5519 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
5520 if (result != ISC_R_SUCCESS)
5523 dns_rdataset_init(&rdataset);
5524 result = dns_db_findrdataset(zonedb, node, version,
5526 dns_rdatatype_none, 0, &rdataset,
5528 if (result != ISC_R_SUCCESS)
5530 result = dns_rdataset_first(&rdataset);
5531 if (result != ISC_R_SUCCESS)
5533 dns_rdataset_current(&rdataset, &rdata);
5534 dns_rdata_toregion(&rdata, &r);
5535 result = isc_buffer_allocate(zone->mctx, &b, r.length);
5536 if (result != ISC_R_SUCCESS)
5538 isc_buffer_putmem(b, r.base, r.length);
5539 isc_buffer_usedregion(b, &r);
5540 dns_rdata_init(temprdata);
5541 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
5542 dns_message_takebuffer(message, &b);
5543 result = dns_rdataset_next(&rdataset);
5544 dns_rdataset_disassociate(&rdataset);
5545 if (result != ISC_R_NOMORE)
5547 temprdatalist->rdclass = rdata.rdclass;
5548 temprdatalist->type = rdata.type;
5549 temprdatalist->covers = 0;
5550 temprdatalist->ttl = rdataset.ttl;
5551 ISC_LIST_INIT(temprdatalist->rdata);
5552 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
5554 dns_rdataset_init(temprdataset);
5555 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
5556 if (result != ISC_R_SUCCESS)
5559 ISC_LIST_APPEND(tempname->list, temprdataset, link);
5560 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
5561 temprdatalist = NULL;
5562 temprdataset = NULL;
5568 dns_db_detachnode(zonedb, &node);
5569 if (version != NULL)
5570 dns_db_closeversion(zonedb, &version, ISC_FALSE);
5572 dns_db_detach(&zonedb);
5573 if (tempname != NULL)
5574 dns_message_puttempname(message, &tempname);
5575 if (temprdata != NULL)
5576 dns_message_puttemprdata(message, &temprdata);
5577 if (temprdataset != NULL)
5578 dns_message_puttemprdataset(message, &temprdataset);
5579 if (temprdatalist != NULL)
5580 dns_message_puttemprdatalist(message, &temprdatalist);
5583 *messagep = message;
5584 return (ISC_R_SUCCESS);
5587 if (tempname != NULL)
5588 dns_message_puttempname(message, &tempname);
5589 if (temprdataset != NULL)
5590 dns_message_puttemprdataset(message, &temprdataset);
5591 if (message != NULL)
5592 dns_message_destroy(&message);
5597 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
5601 dns_rdata_soa_t soa;
5602 dns_rdataset_t *rdataset = NULL;
5603 dns_rdata_t rdata = DNS_RDATA_INIT;
5604 isc_result_t result;
5605 char fromtext[ISC_SOCKADDR_FORMATSIZE];
5607 isc_netaddr_t netaddr;
5609 REQUIRE(DNS_ZONE_VALID(zone));
5612 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
5616 * Check that 'from' is a valid notify source, (zone->masters).
5617 * Return DNS_R_REFUSED if not.
5619 * If the notify message contains a serial number check it
5620 * against the zones serial and return if <= current serial
5622 * If a refresh check is progress, if so just record the
5623 * fact we received a NOTIFY and from where and return.
5624 * We will perform a new refresh check when the current one
5625 * completes. Return ISC_R_SUCCESS.
5627 * Otherwise initiate a refresh check using 'from' as the
5628 * first address to check. Return ISC_R_SUCCESS.
5631 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
5634 * We only handle NOTIFY (SOA) at the present.
5637 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
5638 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
5639 dns_rdatatype_soa, dns_rdatatype_none,
5640 NULL, NULL) != ISC_R_SUCCESS) {
5642 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
5643 dns_zone_log(zone, ISC_LOG_NOTICE,
5645 "question section from: %s", fromtext);
5646 return (DNS_R_FORMERR);
5648 dns_zone_log(zone, ISC_LOG_NOTICE,
5649 "NOTIFY zone does not match");
5650 return (DNS_R_NOTIMP);
5654 * If we are a master zone just succeed.
5656 if (zone->type == dns_zone_master) {
5658 return (ISC_R_SUCCESS);
5661 isc_netaddr_fromsockaddr(&netaddr, from);
5662 for (i = 0; i < zone->masterscnt; i++) {
5663 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
5665 if (zone->view->aclenv.match_mapped &&
5666 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
5667 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
5668 isc_netaddr_t na1, na2;
5669 isc_netaddr_fromv4mapped(&na1, &netaddr);
5670 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
5671 if (isc_netaddr_equal(&na1, &na2))
5677 * Accept notify requests from non masters if they are on
5678 * 'zone->notify_acl'.
5680 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
5681 dns_acl_match(&netaddr, NULL, zone->notify_acl,
5682 &zone->view->aclenv,
5683 &match, NULL) == ISC_R_SUCCESS &&
5686 /* Accept notify. */
5687 } else if (i >= zone->masterscnt) {
5689 dns_zone_log(zone, ISC_LOG_INFO,
5690 "refused notify from non-master: %s", fromtext);
5691 return (DNS_R_REFUSED);
5695 * If the zone is loaded and there are answers check the serial
5696 * to see if we need to do a refresh. Do not worry about this
5697 * check if we are a dialup zone as we use the notify request
5698 * to trigger a refresh check.
5700 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
5701 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
5702 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
5703 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
5706 dns_rdatatype_none, NULL,
5708 if (result == ISC_R_SUCCESS)
5709 result = dns_rdataset_first(rdataset);
5710 if (result == ISC_R_SUCCESS) {
5711 isc_uint32_t serial = 0;
5713 dns_rdataset_current(rdataset, &rdata);
5714 result = dns_rdata_tostruct(&rdata, &soa, NULL);
5715 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5716 serial = soa.serial;
5717 if (isc_serial_le(serial, zone->serial)) {
5718 dns_zone_log(zone, ISC_LOG_INFO,
5720 "zone is up to date",
5723 return (ISC_R_SUCCESS);
5729 * If we got this far and there was a refresh in progress just
5730 * let it complete. Record where we got the notify from so we
5731 * can perform a refresh check when the current one completes
5733 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
5734 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
5735 zone->notifyfrom = *from;
5737 dns_zone_log(zone, ISC_LOG_INFO,
5738 "notify from %s: refresh in progress, "
5739 "refresh check queued",
5741 return (ISC_R_SUCCESS);
5743 zone->notifyfrom = *from;
5745 dns_zone_refresh(zone);
5746 return (ISC_R_SUCCESS);
5750 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
5752 REQUIRE(DNS_ZONE_VALID(zone));
5755 if (zone->notify_acl != NULL)
5756 dns_acl_detach(&zone->notify_acl);
5757 dns_acl_attach(acl, &zone->notify_acl);
5762 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
5764 REQUIRE(DNS_ZONE_VALID(zone));
5767 if (zone->query_acl != NULL)
5768 dns_acl_detach(&zone->query_acl);
5769 dns_acl_attach(acl, &zone->query_acl);
5774 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
5776 REQUIRE(DNS_ZONE_VALID(zone));
5779 if (zone->update_acl != NULL)
5780 dns_acl_detach(&zone->update_acl);
5781 dns_acl_attach(acl, &zone->update_acl);
5786 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
5788 REQUIRE(DNS_ZONE_VALID(zone));
5791 if (zone->forward_acl != NULL)
5792 dns_acl_detach(&zone->forward_acl);
5793 dns_acl_attach(acl, &zone->forward_acl);
5798 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
5800 REQUIRE(DNS_ZONE_VALID(zone));
5803 if (zone->xfr_acl != NULL)
5804 dns_acl_detach(&zone->xfr_acl);
5805 dns_acl_attach(acl, &zone->xfr_acl);
5810 dns_zone_getnotifyacl(dns_zone_t *zone) {
5812 REQUIRE(DNS_ZONE_VALID(zone));
5814 return (zone->notify_acl);
5818 dns_zone_getqueryacl(dns_zone_t *zone) {
5820 REQUIRE(DNS_ZONE_VALID(zone));
5822 return (zone->query_acl);
5826 dns_zone_getupdateacl(dns_zone_t *zone) {
5828 REQUIRE(DNS_ZONE_VALID(zone));
5830 return (zone->update_acl);
5834 dns_zone_getforwardacl(dns_zone_t *zone) {
5836 REQUIRE(DNS_ZONE_VALID(zone));
5838 return (zone->forward_acl);
5842 dns_zone_getxfracl(dns_zone_t *zone) {
5844 REQUIRE(DNS_ZONE_VALID(zone));
5846 return (zone->xfr_acl);
5850 dns_zone_clearupdateacl(dns_zone_t *zone) {
5852 REQUIRE(DNS_ZONE_VALID(zone));
5855 if (zone->update_acl != NULL)
5856 dns_acl_detach(&zone->update_acl);
5861 dns_zone_clearforwardacl(dns_zone_t *zone) {
5863 REQUIRE(DNS_ZONE_VALID(zone));
5866 if (zone->forward_acl != NULL)
5867 dns_acl_detach(&zone->forward_acl);
5872 dns_zone_clearnotifyacl(dns_zone_t *zone) {
5874 REQUIRE(DNS_ZONE_VALID(zone));
5877 if (zone->notify_acl != NULL)
5878 dns_acl_detach(&zone->notify_acl);
5883 dns_zone_clearqueryacl(dns_zone_t *zone) {
5885 REQUIRE(DNS_ZONE_VALID(zone));
5888 if (zone->query_acl != NULL)
5889 dns_acl_detach(&zone->query_acl);
5894 dns_zone_clearxfracl(dns_zone_t *zone) {
5896 REQUIRE(DNS_ZONE_VALID(zone));
5899 if (zone->xfr_acl != NULL)
5900 dns_acl_detach(&zone->xfr_acl);
5905 dns_zone_getupdatedisabled(dns_zone_t *zone) {
5906 REQUIRE(DNS_ZONE_VALID(zone));
5907 return (zone->update_disabled);
5912 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
5913 REQUIRE(DNS_ZONE_VALID(zone));
5914 zone->update_disabled = state;
5918 dns_zone_getzeronosoattl(dns_zone_t *zone) {
5919 REQUIRE(DNS_ZONE_VALID(zone));
5920 return (zone->zero_no_soa_ttl);
5925 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
5926 REQUIRE(DNS_ZONE_VALID(zone));
5927 zone->zero_no_soa_ttl = state;
5931 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
5933 REQUIRE(DNS_ZONE_VALID(zone));
5935 zone->check_names = severity;
5939 dns_zone_getchecknames(dns_zone_t *zone) {
5941 REQUIRE(DNS_ZONE_VALID(zone));
5943 return (zone->check_names);
5947 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
5949 REQUIRE(DNS_ZONE_VALID(zone));
5951 zone->journalsize = size;
5955 dns_zone_getjournalsize(dns_zone_t *zone) {
5957 REQUIRE(DNS_ZONE_VALID(zone));
5959 return (zone->journalsize);
5963 zone_tostr(dns_zone_t *zone, char *buf, size_t length) {
5964 isc_result_t result = ISC_R_FAILURE;
5965 isc_buffer_t buffer;
5967 REQUIRE(buf != NULL);
5968 REQUIRE(length > 1U);
5971 * Leave space for terminating '\0'.
5973 isc_buffer_init(&buffer, buf, length - 1);
5974 if (dns_name_dynamic(&zone->origin))
5975 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
5976 if (result != ISC_R_SUCCESS &&
5977 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
5978 isc_buffer_putstr(&buffer, "<UNKNOWN>");
5980 if (isc_buffer_availablelength(&buffer) > 0)
5981 isc_buffer_putstr(&buffer, "/");
5982 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
5984 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
5985 strcmp(zone->view->name, "_default") != 0 &&
5986 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
5987 isc_buffer_putstr(&buffer, "/");
5988 isc_buffer_putstr(&buffer, zone->view->name);
5991 buf[isc_buffer_usedlength(&buffer)] = '\0';
5995 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
5996 REQUIRE(DNS_ZONE_VALID(zone));
5997 REQUIRE(buf != NULL);
5998 zone_tostr(zone, buf, length);
6002 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
6005 char namebuf[1024+32];
6007 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6010 zone_tostr(zone, namebuf, sizeof(namebuf));
6013 vsnprintf(message, sizeof(message), fmt, ap);
6015 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
6016 level, "zone %s: %s", namebuf, message);
6020 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
6021 int level, const char *fmt, ...) {
6024 char namebuf[1024+32];
6026 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6029 zone_tostr(zone, namebuf, sizeof(namebuf));
6032 vsnprintf(message, sizeof(message), fmt, ap);
6034 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
6035 level, "zone %s: %s", namebuf, message);
6039 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
6042 char namebuf[1024+32];
6044 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6047 zone_tostr(zone, namebuf, sizeof(namebuf));
6050 vsnprintf(message, sizeof(message), fmt, ap);
6052 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
6053 level, "zone %s: %s", namebuf, message);
6057 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
6058 const char *fmt, ...)
6062 char namebuf[1024+32];
6063 int level = ISC_LOG_DEBUG(debuglevel);
6065 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6068 zone_tostr(zone, namebuf, sizeof(namebuf));
6071 vsnprintf(message, sizeof(message), fmt, ap);
6073 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
6074 level, "%s: zone %s: %s", me, namebuf, message);
6078 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
6080 isc_result_t result;
6082 dns_rdataset_t *curr;
6085 result = dns_message_firstname(msg, section);
6086 while (result == ISC_R_SUCCESS) {
6088 dns_message_currentname(msg, section, &name);
6090 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
6091 curr = ISC_LIST_PREV(curr, link)) {
6092 if (curr->type == type)
6095 result = dns_message_nextname(msg, section);
6102 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
6103 REQUIRE(DNS_ZONE_VALID(zone));
6105 zone->maxxfrin = maxxfrin;
6109 dns_zone_getmaxxfrin(dns_zone_t *zone) {
6110 REQUIRE(DNS_ZONE_VALID(zone));
6112 return (zone->maxxfrin);
6116 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
6117 REQUIRE(DNS_ZONE_VALID(zone));
6118 zone->maxxfrout = maxxfrout;
6122 dns_zone_getmaxxfrout(dns_zone_t *zone) {
6123 REQUIRE(DNS_ZONE_VALID(zone));
6125 return (zone->maxxfrout);
6129 dns_zone_gettype(dns_zone_t *zone) {
6130 REQUIRE(DNS_ZONE_VALID(zone));
6132 return (zone->type);
6136 dns_zone_getorigin(dns_zone_t *zone) {
6137 REQUIRE(DNS_ZONE_VALID(zone));
6139 return (&zone->origin);
6143 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
6144 REQUIRE(DNS_ZONE_VALID(zone));
6147 if (zone->task != NULL)
6148 isc_task_detach(&zone->task);
6149 isc_task_attach(task, &zone->task);
6150 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6151 if (zone->db != NULL)
6152 dns_db_settask(zone->db, zone->task);
6153 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6158 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
6159 REQUIRE(DNS_ZONE_VALID(zone));
6160 isc_task_attach(zone->task, target);
6164 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
6165 REQUIRE(DNS_ZONE_VALID(zone));
6168 idlein = DNS_DEFAULT_IDLEIN;
6169 zone->idlein = idlein;
6173 dns_zone_getidlein(dns_zone_t *zone) {
6174 REQUIRE(DNS_ZONE_VALID(zone));
6176 return (zone->idlein);
6180 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
6181 REQUIRE(DNS_ZONE_VALID(zone));
6183 zone->idleout = idleout;
6187 dns_zone_getidleout(dns_zone_t *zone) {
6188 REQUIRE(DNS_ZONE_VALID(zone));
6190 return (zone->idleout);
6194 notify_done(isc_task_t *task, isc_event_t *event) {
6195 dns_requestevent_t *revent = (dns_requestevent_t *)event;
6196 dns_notify_t *notify;
6197 isc_result_t result;
6198 dns_message_t *message = NULL;
6201 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6205 notify = event->ev_arg;
6206 REQUIRE(DNS_NOTIFY_VALID(notify));
6207 INSIST(task == notify->zone->task);
6209 isc_buffer_init(&buf, rcode, sizeof(rcode));
6210 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6212 result = revent->result;
6213 if (result == ISC_R_SUCCESS)
6214 result = dns_message_create(notify->zone->mctx,
6215 DNS_MESSAGE_INTENTPARSE, &message);
6216 if (result == ISC_R_SUCCESS)
6217 result = dns_request_getresponse(revent->request, message,
6218 DNS_MESSAGEPARSE_PRESERVEORDER);
6219 if (result == ISC_R_SUCCESS)
6220 result = dns_rcode_totext(message->rcode, &buf);
6221 if (result == ISC_R_SUCCESS)
6222 notify_log(notify->zone, ISC_LOG_DEBUG(3),
6223 "notify response from %s: %.*s",
6224 addrbuf, (int)buf.used, rcode);
6226 notify_log(notify->zone, ISC_LOG_DEBUG(2),
6227 "notify to %s failed: %s", addrbuf,
6228 dns_result_totext(result));
6231 * Old bind's return formerr if they see a soa record. Retry w/o
6232 * the soa if we see a formerr and had sent a SOA.
6234 isc_event_free(&event);
6235 if (message != NULL && message->rcode == dns_rcode_formerr &&
6236 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
6237 notify->flags |= DNS_NOTIFY_NOSOA;
6238 dns_request_destroy(¬ify->request);
6239 result = notify_send_queue(notify);
6240 if (result != ISC_R_SUCCESS)
6241 notify_destroy(notify, ISC_FALSE);
6243 if (result == ISC_R_TIMEDOUT)
6244 notify_log(notify->zone, ISC_LOG_DEBUG(1),
6245 "notify to %s: retries exceeded", addrbuf);
6246 notify_destroy(notify, ISC_FALSE);
6248 if (message != NULL)
6249 dns_message_destroy(&message);
6253 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
6254 isc_result_t result;
6256 REQUIRE(DNS_ZONE_VALID(zone));
6258 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6259 result = zone_replacedb(zone, db, dump);
6260 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6266 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
6267 dns_dbversion_t *ver;
6268 isc_result_t result;
6269 unsigned int soacount = 0;
6270 unsigned int nscount = 0;
6273 * 'zone' and 'zonedb' locked by caller.
6275 REQUIRE(DNS_ZONE_VALID(zone));
6276 REQUIRE(LOCKED_ZONE(zone));
6278 result = zone_get_from_db(zone, db, &nscount, &soacount,
6279 NULL, NULL, NULL, NULL, NULL, NULL);
6280 if (result == ISC_R_SUCCESS) {
6281 if (soacount != 1) {
6282 dns_zone_log(zone, ISC_LOG_ERROR,
6283 "has %d SOA records", soacount);
6284 result = DNS_R_BADZONE;
6287 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
6288 result = DNS_R_BADZONE;
6290 if (result != ISC_R_SUCCESS)
6293 dns_zone_log(zone, ISC_LOG_ERROR,
6294 "retrieving SOA and NS records failed: %s",
6295 dns_result_totext(result));
6300 dns_db_currentversion(db, &ver);
6303 * The initial version of a slave zone is always dumped;
6304 * subsequent versions may be journalled instead if this
6305 * is enabled in the configuration.
6307 if (zone->db != NULL && zone->journal != NULL &&
6308 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
6309 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
6310 isc_uint32_t serial;
6312 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
6314 result = dns_db_getsoaserial(db, ver, &serial);
6315 if (result != ISC_R_SUCCESS) {
6316 dns_zone_log(zone, ISC_LOG_ERROR,
6317 "ixfr-from-differences: unable to get "
6323 * This is checked in zone_postload() for master zones.
6325 if (zone->type == dns_zone_slave &&
6326 !isc_serial_gt(serial, zone->serial)) {
6327 isc_uint32_t serialmin, serialmax;
6328 serialmin = (zone->serial + 1) & 0xffffffffU;
6329 serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU;
6330 dns_zone_log(zone, ISC_LOG_ERROR,
6331 "ixfr-from-differences: failed: "
6332 "new serial (%u) out of range [%u - %u]",
6333 serial, serialmin, serialmax);
6334 result = ISC_R_RANGE;
6338 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
6340 if (result != ISC_R_SUCCESS)
6343 zone_needdump(zone, DNS_DUMP_DELAY);
6344 else if (zone->journalsize != -1) {
6345 result = dns_journal_compact(zone->mctx, zone->journal,
6346 serial, zone->journalsize);
6350 case ISC_R_NOTFOUND:
6351 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6352 "dns_journal_compact: %s",
6353 dns_result_totext(result));
6356 dns_zone_log(zone, ISC_LOG_ERROR,
6357 "dns_journal_compact failed: %s",
6358 dns_result_totext(result));
6363 if (dump && zone->masterfile != NULL) {
6364 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6365 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6366 "dumping new zone version");
6367 result = dns_db_dump2(db, ver, zone->masterfile,
6368 zone->masterformat);
6369 if (result != ISC_R_SUCCESS)
6373 * Update the time the zone was updated, so
6374 * dns_zone_load can avoid loading it when
6375 * the server is reloaded. If isc_time_now
6376 * fails for some reason, all that happens is
6377 * the timestamp is not updated.
6379 TIME_NOW(&zone->loadtime);
6382 if (dump && zone->journal != NULL) {
6384 * The in-memory database just changed, and
6385 * because 'dump' is set, it didn't change by
6386 * being loaded from disk. Also, we have not
6387 * journalled diffs for this change.
6388 * Therefore, the on-disk journal is missing
6389 * the deltas for this change. Since it can
6390 * no longer be used to bring the zone
6391 * up-to-date, it is useless and should be
6394 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6395 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6396 "removing journal file");
6397 (void)remove(zone->journal);
6401 dns_db_closeversion(db, &ver, ISC_FALSE);
6403 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6404 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6405 "replacing zone database");
6407 if (zone->db != NULL)
6408 zone_detachdb(zone);
6409 zone_attachdb(zone, db);
6410 dns_db_settask(zone->db, zone->task);
6411 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
6412 return (ISC_R_SUCCESS);
6415 dns_db_closeversion(db, &ver, ISC_FALSE);
6419 /* The caller must hold the dblock as a writer. */
6421 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
6422 REQUIRE(zone->db == NULL && db != NULL);
6424 dns_db_attach(db, &zone->db);
6425 if (zone->acache != NULL) {
6426 isc_result_t result;
6427 result = dns_acache_setdb(zone->acache, db);
6428 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
6429 UNEXPECTED_ERROR(__FILE__, __LINE__,
6430 "dns_acache_setdb() failed: %s",
6431 isc_result_totext(result));
6436 /* The caller must hold the dblock as a writer. */
6438 zone_detachdb(dns_zone_t *zone) {
6439 REQUIRE(zone->db != NULL);
6441 if (zone->acache != NULL)
6442 (void)dns_acache_putdb(zone->acache, zone->db);
6443 dns_db_detach(&zone->db);
6447 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
6449 isc_boolean_t again = ISC_FALSE;
6450 unsigned int soacount;
6451 unsigned int nscount;
6452 isc_uint32_t serial, refresh, retry, expire, minimum;
6453 isc_result_t xfrresult = result;
6454 isc_boolean_t free_needed;
6456 REQUIRE(DNS_ZONE_VALID(zone));
6458 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6459 "zone transfer finished: %s", dns_result_totext(result));
6462 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
6463 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
6464 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
6469 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6471 case DNS_R_UPTODATE:
6472 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
6474 * Has the zone expired underneath us?
6476 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6477 if (zone->db == NULL) {
6478 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6483 * Update the zone structure's data from the actual
6488 INSIST(zone->db != NULL);
6489 result = zone_get_from_db(zone, zone->db, &nscount,
6490 &soacount, &serial, &refresh,
6491 &retry, &expire, &minimum, NULL);
6492 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6493 if (result == ISC_R_SUCCESS) {
6495 dns_zone_log(zone, ISC_LOG_ERROR,
6497 "has %d SOA record%s", soacount,
6498 (soacount != 0) ? "s" : "");
6500 dns_zone_log(zone, ISC_LOG_ERROR,
6502 "has no NS records");
6503 if (DNS_ZONE_FLAG(zone,
6504 DNS_ZONEFLG_HAVETIMERS)) {
6505 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
6506 zone->retry = DNS_ZONE_DEFAULTRETRY;
6508 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6512 zone->serial = serial;
6513 zone->refresh = RANGE(refresh, zone->minrefresh,
6515 zone->retry = RANGE(retry, zone->minretry,
6517 zone->expire = RANGE(expire,
6518 zone->refresh + zone->retry,
6520 zone->minimum = minimum;
6521 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6525 * Set our next update/expire times.
6527 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
6528 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
6529 zone->refreshtime = now;
6530 DNS_ZONE_TIME_ADD(&now, zone->expire,
6533 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
6534 &zone->refreshtime);
6535 DNS_ZONE_TIME_ADD(&now, zone->expire,
6538 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
6539 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
6540 if (zone->tsigkey != NULL) {
6541 char namebuf[DNS_NAME_FORMATSIZE];
6542 dns_name_format(&zone->tsigkey->name, namebuf,
6544 snprintf(buf, sizeof(buf), ": TSIG '%s'",
6548 dns_zone_log(zone, ISC_LOG_INFO,
6549 "transferred serial %u%s",
6554 * This is not neccessary if we just performed a AXFR
6555 * however it is necessary for an IXFR / UPTODATE and
6556 * won't hurt with an AXFR.
6558 if (zone->masterfile != NULL || zone->journal != NULL) {
6559 result = ISC_R_FAILURE;
6560 if (zone->journal != NULL)
6561 result = isc_file_settime(zone->journal, &now);
6562 if (result != ISC_R_SUCCESS &&
6563 zone->masterfile != NULL)
6564 result = isc_file_settime(zone->masterfile,
6566 /* Someone removed the file from underneath us! */
6567 if (result == ISC_R_FILENOTFOUND &&
6568 zone->masterfile != NULL)
6569 zone_needdump(zone, DNS_DUMP_DELAY);
6570 else if (result != ISC_R_SUCCESS)
6571 dns_zone_log(zone, ISC_LOG_ERROR,
6572 "transfer: could not set file "
6573 "modification time of '%s': %s",
6575 dns_result_totext(result));
6581 /* Force retry with AXFR. */
6582 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
6588 * Skip to next failed / untried master.
6592 } while (zone->curmaster < zone->masterscnt &&
6593 zone->mastersok[zone->curmaster]);
6596 if (zone->curmaster >= zone->masterscnt) {
6597 zone->curmaster = 0;
6598 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
6599 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
6600 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6601 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6602 while (zone->curmaster < zone->masterscnt &&
6603 zone->mastersok[zone->curmaster])
6607 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6609 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6614 zone_settimer(zone, &now);
6617 * If creating the transfer object failed, zone->xfr is NULL.
6618 * Otherwise, we are called as the done callback of a zone
6619 * transfer object that just entered its shutting-down
6620 * state. Since we are no longer responsible for shutting
6621 * it down, we can detach our reference.
6623 if (zone->xfr != NULL)
6624 dns_xfrin_detach(&zone->xfr);
6626 if (zone->tsigkey != NULL)
6627 dns_tsigkey_detach(&zone->tsigkey);
6630 * This transfer finishing freed up a transfer quota slot.
6631 * Let any other zones waiting for quota have it.
6633 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
6634 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
6635 zone->statelist = NULL;
6636 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
6637 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
6640 * Retry with a different server if necessary.
6642 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
6643 queue_soa_query(zone);
6645 INSIST(zone->irefs > 0);
6647 free_needed = exit_check(zone);
6654 zone_loaddone(void *arg, isc_result_t result) {
6655 static char me[] = "zone_loaddone";
6656 dns_load_t *load = arg;
6658 isc_result_t tresult;
6660 REQUIRE(DNS_LOAD_VALID(load));
6665 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
6666 if (tresult != ISC_R_SUCCESS &&
6667 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
6670 LOCK_ZONE(load->zone);
6671 (void)zone_postload(load->zone, load->db, load->loadtime, result);
6672 zonemgr_putio(&load->zone->readio);
6673 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
6674 UNLOCK_ZONE(load->zone);
6677 dns_db_detach(&load->db);
6678 if (load->zone->lctx != NULL)
6679 dns_loadctx_detach(&load->zone->lctx);
6680 dns_zone_idetach(&load->zone);
6681 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
6685 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
6686 REQUIRE(DNS_ZONE_VALID(zone));
6687 REQUIRE(table != NULL);
6688 REQUIRE(*table == NULL);
6691 if (zone->ssutable != NULL)
6692 dns_ssutable_attach(zone->ssutable, table);
6697 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
6698 REQUIRE(DNS_ZONE_VALID(zone));
6701 if (zone->ssutable != NULL)
6702 dns_ssutable_detach(&zone->ssutable);
6704 dns_ssutable_attach(table, &zone->ssutable);
6709 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
6710 REQUIRE(DNS_ZONE_VALID(zone));
6712 zone->sigvalidityinterval = interval;
6716 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
6717 REQUIRE(DNS_ZONE_VALID(zone));
6719 return (zone->sigvalidityinterval);
6723 queue_xfrin(dns_zone_t *zone) {
6724 const char me[] = "queue_xfrin";
6725 isc_result_t result;
6726 dns_zonemgr_t *zmgr = zone->zmgr;
6730 INSIST(zone->statelist == NULL);
6732 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
6733 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
6737 zone->statelist = &zmgr->waiting_for_xfrin;
6738 result = zmgr_start_xfrin_ifquota(zmgr, zone);
6739 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
6741 if (result == ISC_R_QUOTA) {
6742 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
6743 "zone transfer deferred due to quota");
6744 } else if (result != ISC_R_SUCCESS) {
6745 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
6746 "starting zone transfer: %s",
6747 isc_result_totext(result));
6752 * This event callback is called when a zone has received
6753 * any necessary zone transfer quota. This is the time
6754 * to go ahead and start the transfer.
6757 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
6758 isc_result_t result;
6759 dns_peer_t *peer = NULL;
6760 char mastertext[256];
6761 dns_rdatatype_t xfrtype;
6762 dns_zone_t *zone = event->ev_arg;
6763 isc_netaddr_t masterip;
6764 isc_sockaddr_t sourceaddr;
6765 isc_sockaddr_t masteraddr;
6769 INSIST(task == zone->task);
6771 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
6772 result = ISC_R_CANCELED;
6776 isc_sockaddr_format(&zone->masteraddr, mastertext, sizeof(mastertext));
6778 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
6779 (void)dns_peerlist_peerbyaddr(zone->view->peers,
6783 * Decide whether we should request IXFR or AXFR.
6785 if (zone->db == NULL) {
6786 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6787 "no database exists yet, "
6788 "requesting AXFR of "
6789 "initial version from %s", mastertext);
6790 xfrtype = dns_rdatatype_axfr;
6791 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
6792 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
6793 "set, requesting AXFR from %s", mastertext);
6794 xfrtype = dns_rdatatype_axfr;
6795 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
6796 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6797 "forced reload, requesting AXFR of "
6798 "initial version from %s", mastertext);
6799 xfrtype = dns_rdatatype_axfr;
6800 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
6801 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6802 "retrying with AXFR from %s due to "
6803 "previous IXFR failure", mastertext);
6804 xfrtype = dns_rdatatype_axfr;
6806 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
6809 isc_boolean_t use_ixfr = ISC_TRUE;
6811 dns_peer_getrequestixfr(peer, &use_ixfr) ==
6813 ; /* Using peer setting */
6815 use_ixfr = zone->view->requestixfr;
6817 if (use_ixfr == ISC_FALSE) {
6818 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6820 "requesting AXFR from %s",
6822 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
6823 xfrtype = dns_rdatatype_soa;
6825 xfrtype = dns_rdatatype_axfr;
6827 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6828 "requesting IXFR from %s",
6830 xfrtype = dns_rdatatype_ixfr;
6835 * Determine if we should attempt to sign the request with TSIG.
6837 result = ISC_R_NOTFOUND;
6839 * First, look for a tsig key in the master statement, then
6840 * try for a server key.
6842 if ((zone->masterkeynames != NULL) &&
6843 (zone->masterkeynames[zone->curmaster] != NULL)) {
6844 dns_view_t *view = dns_zone_getview(zone);
6845 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
6846 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
6848 if (zone->tsigkey == NULL)
6849 result = dns_view_getpeertsig(zone->view, &masterip,
6852 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6853 dns_zone_log(zone, ISC_LOG_ERROR,
6854 "could not get TSIG key "
6855 "for zone transfer: %s",
6856 isc_result_totext(result));
6860 masteraddr = zone->masteraddr;
6861 sourceaddr = zone->sourceaddr;
6863 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
6864 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
6865 zone->tsigkey, zone->mctx,
6866 zone->zmgr->timermgr, zone->zmgr->socketmgr,
6867 zone->task, zone_xfrdone, &zone->xfr);
6870 * Any failure in this function is handled like a failed
6871 * zone transfer. This ensures that we get removed from
6872 * zmgr->xfrin_in_progress.
6874 if (result != ISC_R_SUCCESS)
6875 zone_xfrdone(zone, result);
6877 isc_event_free(&event);
6881 * Update forwarding support.
6885 forward_destroy(dns_forward_t *forward) {
6888 if (forward->request != NULL)
6889 dns_request_destroy(&forward->request);
6890 if (forward->msgbuf != NULL)
6891 isc_buffer_free(&forward->msgbuf);
6892 if (forward->zone != NULL)
6893 dns_zone_idetach(&forward->zone);
6894 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
6898 sendtomaster(dns_forward_t *forward) {
6899 isc_result_t result;
6902 LOCK_ZONE(forward->zone);
6903 if (forward->which >= forward->zone->masterscnt) {
6904 UNLOCK_ZONE(forward->zone);
6905 return (ISC_R_NOMORE);
6908 forward->addr = forward->zone->masters[forward->which];
6910 * Always use TCP regardless of whether the original update
6912 * XXX The timeout may but a bit small if we are far down a
6913 * transfer graph and the master has to try several masters.
6915 switch (isc_sockaddr_pf(&forward->addr)) {
6917 src = forward->zone->xfrsource4;
6920 src = forward->zone->xfrsource6;
6923 result = ISC_R_NOTIMPLEMENTED;
6926 result = dns_request_createraw(forward->zone->view->requestmgr,
6928 &src, &forward->addr,
6929 DNS_REQUESTOPT_TCP, 15 /* XXX */,
6930 forward->zone->task,
6931 forward_callback, forward,
6934 UNLOCK_ZONE(forward->zone);
6939 forward_callback(isc_task_t *task, isc_event_t *event) {
6940 const char me[] = "forward_callback";
6941 dns_requestevent_t *revent = (dns_requestevent_t *)event;
6942 dns_message_t *msg = NULL;
6943 char master[ISC_SOCKADDR_FORMATSIZE];
6944 isc_result_t result;
6945 dns_forward_t *forward;
6950 forward = revent->ev_arg;
6951 INSIST(DNS_FORWARD_VALID(forward));
6952 zone = forward->zone;
6953 INSIST(DNS_ZONE_VALID(zone));
6957 isc_sockaddr_format(&forward->addr, master, sizeof(master));
6959 if (revent->result != ISC_R_SUCCESS) {
6960 dns_zone_log(zone, ISC_LOG_INFO,
6961 "could not forward dynamic update to %s: %s",
6962 master, dns_result_totext(revent->result));
6966 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
6967 if (result != ISC_R_SUCCESS)
6970 result = dns_request_getresponse(revent->request, msg,
6971 DNS_MESSAGEPARSE_PRESERVEORDER |
6972 DNS_MESSAGEPARSE_CLONEBUFFER);
6973 if (result != ISC_R_SUCCESS)
6976 switch (msg->rcode) {
6978 * Pass these rcodes back to client.
6980 case dns_rcode_noerror:
6981 case dns_rcode_yxdomain:
6982 case dns_rcode_yxrrset:
6983 case dns_rcode_nxrrset:
6984 case dns_rcode_refused:
6985 case dns_rcode_nxdomain:
6988 /* These should not occur if the masters/zone are valid. */
6989 case dns_rcode_notzone:
6990 case dns_rcode_notauth: {
6994 isc_buffer_init(&rb, rcode, sizeof(rcode));
6995 (void)dns_rcode_totext(msg->rcode, &rb);
6996 dns_zone_log(zone, ISC_LOG_WARNING,
6997 "forwarding dynamic update: "
6998 "unexpected response: master %s returned: %.*s",
6999 master, (int)rb.used, rcode);
7003 /* Try another server for these rcodes. */
7004 case dns_rcode_formerr:
7005 case dns_rcode_servfail:
7006 case dns_rcode_notimp:
7007 case dns_rcode_badvers:
7013 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
7015 dns_request_destroy(&forward->request);
7016 forward_destroy(forward);
7017 isc_event_free(&event);
7022 dns_message_destroy(&msg);
7023 isc_event_free(&event);
7025 dns_request_destroy(&forward->request);
7026 result = sendtomaster(forward);
7027 if (result != ISC_R_SUCCESS) {
7029 dns_zone_log(zone, ISC_LOG_DEBUG(3),
7030 "exhausted dynamic update forwarder list");
7031 (forward->callback)(forward->callback_arg, result, NULL);
7032 forward_destroy(forward);
7037 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
7038 dns_updatecallback_t callback, void *callback_arg)
7040 dns_forward_t *forward;
7041 isc_result_t result;
7044 REQUIRE(DNS_ZONE_VALID(zone));
7045 REQUIRE(msg != NULL);
7046 REQUIRE(callback != NULL);
7048 forward = isc_mem_get(zone->mctx, sizeof(*forward));
7049 if (forward == NULL)
7050 return (ISC_R_NOMEMORY);
7052 forward->request = NULL;
7053 forward->zone = NULL;
7054 forward->msgbuf = NULL;
7057 forward->callback = callback;
7058 forward->callback_arg = callback_arg;
7059 forward->magic = FORWARD_MAGIC;
7061 mr = dns_message_getrawmessage(msg);
7063 result = ISC_R_UNEXPECTEDEND;
7067 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
7068 if (result != ISC_R_SUCCESS)
7070 result = isc_buffer_copyregion(forward->msgbuf, mr);
7071 if (result != ISC_R_SUCCESS)
7074 isc_mem_attach(zone->mctx, &forward->mctx);
7075 dns_zone_iattach(zone, &forward->zone);
7076 result = sendtomaster(forward);
7079 if (result != ISC_R_SUCCESS) {
7080 forward_destroy(forward);
7086 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
7087 REQUIRE(DNS_ZONE_VALID(zone));
7088 REQUIRE(next != NULL && *next == NULL);
7090 *next = ISC_LIST_NEXT(zone, link);
7092 return (ISC_R_NOMORE);
7094 return (ISC_R_SUCCESS);
7098 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
7099 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7100 REQUIRE(first != NULL && *first == NULL);
7102 *first = ISC_LIST_HEAD(zmgr->zones);
7104 return (ISC_R_NOMORE);
7106 return (ISC_R_SUCCESS);
7114 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
7115 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
7116 dns_zonemgr_t **zmgrp)
7118 dns_zonemgr_t *zmgr;
7119 isc_result_t result;
7120 isc_interval_t interval;
7122 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
7124 return (ISC_R_NOMEMORY);
7127 isc_mem_attach(mctx, &zmgr->mctx);
7128 zmgr->taskmgr = taskmgr;
7129 zmgr->timermgr = timermgr;
7130 zmgr->socketmgr = socketmgr;
7131 zmgr->zonetasks = NULL;
7134 ISC_LIST_INIT(zmgr->zones);
7135 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
7136 ISC_LIST_INIT(zmgr->xfrin_in_progress);
7137 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
7138 if (result != ISC_R_SUCCESS)
7141 zmgr->transfersin = 10;
7142 zmgr->transfersperns = 2;
7144 /* Create the zone task pool. */
7145 result = isc_taskpool_create(taskmgr, mctx,
7146 8 /* XXX */, 2, &zmgr->zonetasks);
7147 if (result != ISC_R_SUCCESS)
7150 /* Create a single task for queueing of SOA queries. */
7151 result = isc_task_create(taskmgr, 1, &zmgr->task);
7152 if (result != ISC_R_SUCCESS)
7154 isc_task_setname(zmgr->task, "zmgr", zmgr);
7155 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
7157 if (result != ISC_R_SUCCESS)
7159 /* default to 20 refresh queries / notifies per second. */
7160 isc_interval_set(&interval, 0, 1000000000/2);
7161 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
7162 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7163 isc_ratelimiter_setpertic(zmgr->rl, 10);
7167 ISC_LIST_INIT(zmgr->high);
7168 ISC_LIST_INIT(zmgr->low);
7170 result = isc_mutex_init(&zmgr->iolock);
7171 if (result != ISC_R_SUCCESS)
7174 zmgr->magic = ZONEMGR_MAGIC;
7177 return (ISC_R_SUCCESS);
7181 DESTROYLOCK(&zmgr->iolock);
7184 isc_ratelimiter_detach(&zmgr->rl);
7186 isc_task_detach(&zmgr->task);
7188 isc_taskpool_destroy(&zmgr->zonetasks);
7190 isc_rwlock_destroy(&zmgr->rwlock);
7192 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
7193 isc_mem_detach(&mctx);
7198 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7199 isc_result_t result;
7201 REQUIRE(DNS_ZONE_VALID(zone));
7202 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7204 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7206 REQUIRE(zone->task == NULL);
7207 REQUIRE(zone->timer == NULL);
7208 REQUIRE(zone->zmgr == NULL);
7210 isc_taskpool_gettask(zmgr->zonetasks,
7211 dns_name_hash(dns_zone_getorigin(zone),
7216 * Set the task name. The tag will arbitrarily point to one
7217 * of the zones sharing the task (in practice, the one
7218 * to be managed last).
7220 isc_task_setname(zone->task, "zone", zone);
7222 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
7224 zone->task, zone_timer, zone,
7226 if (result != ISC_R_SUCCESS)
7229 * The timer "holds" a iref.
7232 INSIST(zone->irefs != 0);
7234 ISC_LIST_APPEND(zmgr->zones, zone, link);
7241 isc_task_detach(&zone->task);
7245 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7250 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7251 isc_boolean_t free_now = ISC_FALSE;
7253 REQUIRE(DNS_ZONE_VALID(zone));
7254 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7255 REQUIRE(zone->zmgr == zmgr);
7257 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7260 ISC_LIST_UNLINK(zmgr->zones, zone, link);
7263 if (zmgr->refs == 0)
7264 free_now = ISC_TRUE;
7267 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7271 ENSURE(zone->zmgr == NULL);
7275 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
7276 REQUIRE(DNS_ZONEMGR_VALID(source));
7277 REQUIRE(target != NULL && *target == NULL);
7279 RWLOCK(&source->rwlock, isc_rwlocktype_write);
7280 REQUIRE(source->refs > 0);
7282 INSIST(source->refs > 0);
7283 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
7288 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
7289 dns_zonemgr_t *zmgr;
7290 isc_boolean_t free_now = ISC_FALSE;
7292 REQUIRE(zmgrp != NULL);
7294 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7296 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7298 if (zmgr->refs == 0)
7299 free_now = ISC_TRUE;
7300 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7307 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
7310 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7312 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7313 for (p = ISC_LIST_HEAD(zmgr->zones);
7315 p = ISC_LIST_NEXT(p, link))
7317 dns_zone_maintenance(p);
7319 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7322 * Recent configuration changes may have increased the
7323 * amount of available transfers quota. Make sure any
7324 * transfers currently blocked on quota get started if
7327 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7328 zmgr_resume_xfrs(zmgr, ISC_TRUE);
7329 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7330 return (ISC_R_SUCCESS);
7334 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
7336 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7338 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7339 zmgr_resume_xfrs(zmgr, ISC_TRUE);
7340 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7344 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
7345 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7347 isc_ratelimiter_shutdown(zmgr->rl);
7349 if (zmgr->task != NULL)
7350 isc_task_destroy(&zmgr->task);
7351 if (zmgr->zonetasks != NULL)
7352 isc_taskpool_destroy(&zmgr->zonetasks);
7356 zonemgr_free(dns_zonemgr_t *zmgr) {
7359 INSIST(zmgr->refs == 0);
7360 INSIST(ISC_LIST_EMPTY(zmgr->zones));
7364 DESTROYLOCK(&zmgr->iolock);
7365 isc_ratelimiter_detach(&zmgr->rl);
7367 isc_rwlock_destroy(&zmgr->rwlock);
7369 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
7370 isc_mem_detach(&mctx);
7374 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
7375 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7377 zmgr->transfersin = value;
7381 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
7382 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7384 return (zmgr->transfersin);
7388 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
7389 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7391 zmgr->transfersperns = value;
7395 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
7396 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7398 return (zmgr->transfersperns);
7402 * Try to start a new incoming zone transfer to fill a quota
7403 * slot that was just vacated.
7406 * The zone manager is locked by the caller.
7409 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
7413 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
7417 isc_result_t result;
7418 next = ISC_LIST_NEXT(zone, statelink);
7419 result = zmgr_start_xfrin_ifquota(zmgr, zone);
7420 if (result == ISC_R_SUCCESS) {
7424 * We successfully filled the slot. We're done.
7427 } else if (result == ISC_R_QUOTA) {
7429 * Not enough quota. This is probably the per-server
7430 * quota, because we usually get called when a unit of
7431 * global quota has just been freed. Try the next
7432 * zone, it may succeed if it uses another master.
7436 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7437 "starting zone transfer: %s",
7438 isc_result_totext(result));
7445 * Try to start an incoming zone transfer for 'zone', quota permitting.
7448 * The zone manager is locked by the caller.
7451 * ISC_R_SUCCESS There was enough quota and we attempted to
7452 * start a transfer. zone_xfrdone() has been or will
7454 * ISC_R_QUOTA Not enough quota.
7458 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7459 dns_peer_t *peer = NULL;
7460 isc_netaddr_t masterip;
7461 isc_uint32_t nxfrsin, nxfrsperns;
7463 isc_uint32_t maxtransfersin, maxtransfersperns;
7467 * Find any configured information about the server we'd
7468 * like to transfer this zone from.
7470 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
7471 (void)dns_peerlist_peerbyaddr(zone->view->peers,
7475 * Determine the total maximum number of simultaneous
7476 * transfers allowed, and the maximum for this specific
7479 maxtransfersin = zmgr->transfersin;
7480 maxtransfersperns = zmgr->transfersperns;
7482 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
7485 * Count the total number of transfers that are in progress,
7486 * and the number of transfers in progress from this master.
7487 * We linearly scan a list of all transfers; if this turns
7488 * out to be too slow, we could hash on the master address.
7490 nxfrsin = nxfrsperns = 0;
7491 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
7493 x = ISC_LIST_NEXT(x, statelink))
7496 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
7498 if (isc_netaddr_equal(&xip, &masterip))
7502 /* Enforce quota. */
7503 if (nxfrsin >= maxtransfersin)
7504 return (ISC_R_QUOTA);
7506 if (nxfrsperns >= maxtransfersperns)
7507 return (ISC_R_QUOTA);
7510 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
7511 * list and send it an event to let it start the actual transfer in the
7512 * context of its own task.
7514 e = isc_event_allocate(zmgr->mctx, zmgr,
7515 DNS_EVENT_ZONESTARTXFRIN,
7516 got_transfer_quota, zone,
7517 sizeof(isc_event_t));
7519 return (ISC_R_NOMEMORY);
7522 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
7523 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
7524 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
7525 zone->statelist = &zmgr->xfrin_in_progress;
7526 isc_task_send(zone->task, &e);
7527 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
7530 return (ISC_R_SUCCESS);
7534 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
7536 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7537 REQUIRE(iolimit > 0);
7539 zmgr->iolimit = iolimit;
7543 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
7545 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7547 return (zmgr->iolimit);
7551 * Get permission to request a file handle from the OS.
7552 * An event will be sent to action when one is available.
7553 * There are two queues available (high and low), the high
7554 * queue will be serviced before the low one.
7556 * zonemgr_putio() must be called after the event is delivered to
7561 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
7562 isc_task_t *task, isc_taskaction_t action, void *arg,
7566 isc_boolean_t queue;
7568 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7569 REQUIRE(iop != NULL && *iop == NULL);
7571 io = isc_mem_get(zmgr->mctx, sizeof(*io));
7573 return (ISC_R_NOMEMORY);
7574 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
7575 action, arg, sizeof(*io->event));
7576 if (io->event == NULL) {
7577 isc_mem_put(zmgr->mctx, io, sizeof(*io));
7578 return (ISC_R_NOMEMORY);
7583 isc_task_attach(task, &io->task);
7584 ISC_LINK_INIT(io, link);
7585 io->magic = IO_MAGIC;
7587 LOCK(&zmgr->iolock);
7589 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
7592 ISC_LIST_APPEND(zmgr->high, io, link);
7594 ISC_LIST_APPEND(zmgr->low, io, link);
7596 UNLOCK(&zmgr->iolock);
7600 isc_task_send(io->task, &io->event);
7602 return (ISC_R_SUCCESS);
7606 zonemgr_putio(dns_io_t **iop) {
7609 dns_zonemgr_t *zmgr;
7611 REQUIRE(iop != NULL);
7613 REQUIRE(DNS_IO_VALID(io));
7617 INSIST(!ISC_LINK_LINKED(io, link));
7618 INSIST(io->event == NULL);
7621 isc_task_detach(&io->task);
7623 isc_mem_put(zmgr->mctx, io, sizeof(*io));
7625 LOCK(&zmgr->iolock);
7626 INSIST(zmgr->ioactive > 0);
7628 next = HEAD(zmgr->high);
7630 next = HEAD(zmgr->low);
7633 ISC_LIST_UNLINK(zmgr->high, next, link);
7635 ISC_LIST_UNLINK(zmgr->low, next, link);
7636 INSIST(next->event != NULL);
7638 UNLOCK(&zmgr->iolock);
7640 isc_task_send(next->task, &next->event);
7644 zonemgr_cancelio(dns_io_t *io) {
7645 isc_boolean_t send_event = ISC_FALSE;
7647 REQUIRE(DNS_IO_VALID(io));
7650 * If we are queued to be run then dequeue.
7652 LOCK(&io->zmgr->iolock);
7653 if (ISC_LINK_LINKED(io, link)) {
7655 ISC_LIST_UNLINK(io->zmgr->high, io, link);
7657 ISC_LIST_UNLINK(io->zmgr->low, io, link);
7659 send_event = ISC_TRUE;
7660 INSIST(io->event != NULL);
7662 UNLOCK(&io->zmgr->iolock);
7664 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
7665 isc_task_send(io->task, &io->event);
7670 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
7673 isc_result_t result;
7675 buflen = strlen(path) + strlen(templat) + 2;
7677 buf = isc_mem_get(zone->mctx, buflen);
7681 result = isc_file_template(path, templat, buf, buflen);
7682 if (result != ISC_R_SUCCESS)
7685 result = isc_file_renameunique(path, buf);
7686 if (result != ISC_R_SUCCESS)
7689 dns_zone_log(zone, ISC_LOG_INFO, "saved '%s' as '%s'",
7693 isc_mem_put(zone->mctx, buf, buflen);
7697 /* Hook for ondestroy notifcation from a database. */
7700 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
7701 dns_db_t *db = event->sender;
7704 isc_event_free(&event);
7706 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
7707 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
7708 "database (%p) destroyed", (void*) db);
7713 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
7714 isc_interval_t interval;
7716 isc_uint32_t pertic;
7717 isc_result_t result;
7719 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7728 } else if (value <= 10) {
7730 ns = 1000000000 / value;
7734 ns = (1000000000 / value) * 10;
7738 isc_interval_set(&interval, s, ns);
7739 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
7740 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7741 isc_ratelimiter_setpertic(zmgr->rl, pertic);
7743 zmgr->serialqueryrate = value;
7747 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
7748 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7750 return (zmgr->serialqueryrate);
7754 dns_zone_forcereload(dns_zone_t *zone) {
7755 REQUIRE(DNS_ZONE_VALID(zone));
7757 if (zone->type == dns_zone_master)
7761 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
7763 dns_zone_refresh(zone);
7767 dns_zone_isforced(dns_zone_t *zone) {
7768 REQUIRE(DNS_ZONE_VALID(zone));
7770 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
7774 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
7775 isc_result_t result = ISC_R_SUCCESS;
7779 if (zone->counters != NULL)
7781 result = dns_stats_alloccounters(zone->mctx, &zone->counters);
7783 if (zone->counters == NULL)
7785 dns_stats_freecounters(zone->mctx, &zone->counters);
7793 dns_zone_getstatscounters(dns_zone_t *zone) {
7794 return (zone->counters);
7798 dns_zone_dialup(dns_zone_t *zone) {
7800 REQUIRE(DNS_ZONE_VALID(zone));
7802 zone_debuglog(zone, "dns_zone_dialup", 3,
7803 "notify = %d, refresh = %d",
7804 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
7805 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
7807 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
7808 dns_zone_notify(zone);
7809 if (zone->type != dns_zone_master &&
7810 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
7811 dns_zone_refresh(zone);
7815 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
7816 REQUIRE(DNS_ZONE_VALID(zone));
7819 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
7820 DNS_ZONEFLG_DIALREFRESH |
7821 DNS_ZONEFLG_NOREFRESH);
7823 case dns_dialuptype_no:
7825 case dns_dialuptype_yes:
7826 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
7827 DNS_ZONEFLG_DIALREFRESH |
7828 DNS_ZONEFLG_NOREFRESH));
7830 case dns_dialuptype_notify:
7831 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
7833 case dns_dialuptype_notifypassive:
7834 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
7835 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7837 case dns_dialuptype_refresh:
7838 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
7839 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7841 case dns_dialuptype_passive:
7842 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7851 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
7852 isc_result_t result = ISC_R_SUCCESS;
7854 REQUIRE(DNS_ZONE_VALID(zone));
7857 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
7864 dns_zone_getkeydirectory(dns_zone_t *zone) {
7865 REQUIRE(DNS_ZONE_VALID(zone));
7867 return (zone->keydirectory);
7871 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
7873 unsigned int count = 0;
7875 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7877 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7879 case DNS_ZONESTATE_XFERRUNNING:
7880 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
7882 zone = ISC_LIST_NEXT(zone, statelink))
7885 case DNS_ZONESTATE_XFERDEFERRED:
7886 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
7888 zone = ISC_LIST_NEXT(zone, statelink))
7891 case DNS_ZONESTATE_SOAQUERY:
7892 for (zone = ISC_LIST_HEAD(zmgr->zones);
7894 zone = ISC_LIST_NEXT(zone, link))
7895 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
7898 case DNS_ZONESTATE_ANY:
7899 for (zone = ISC_LIST_HEAD(zmgr->zones);
7901 zone = ISC_LIST_NEXT(zone, link)) {
7902 dns_view_t *view = zone->view;
7903 if (view != NULL && strcmp(view->name, "_bind") == 0)
7912 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7918 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
7919 isc_boolean_t ok = ISC_TRUE;
7920 isc_boolean_t fail = ISC_FALSE;
7921 char namebuf[DNS_NAME_FORMATSIZE];
7922 char namebuf2[DNS_NAME_FORMATSIZE];
7923 char typebuf[DNS_RDATATYPE_FORMATSIZE];
7924 int level = ISC_LOG_WARNING;
7927 REQUIRE(DNS_ZONE_VALID(zone));
7929 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
7930 return (ISC_R_SUCCESS);
7932 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
7933 level = ISC_LOG_ERROR;
7937 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
7939 dns_name_format(name, namebuf, sizeof(namebuf));
7940 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
7941 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
7942 dns_result_totext(DNS_R_BADOWNERNAME));
7944 return (DNS_R_BADOWNERNAME);
7947 dns_name_init(&bad, NULL);
7948 ok = dns_rdata_checknames(rdata, name, &bad);
7950 dns_name_format(name, namebuf, sizeof(namebuf));
7951 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
7952 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
7953 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
7954 namebuf2, dns_result_totext(DNS_R_BADNAME));
7956 return (DNS_R_BADNAME);
7959 return (ISC_R_SUCCESS);
7963 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
7964 REQUIRE(DNS_ZONE_VALID(zone));
7965 zone->checkmx = checkmx;
7969 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
7970 REQUIRE(DNS_ZONE_VALID(zone));
7971 zone->checksrv = checksrv;
7975 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
7976 REQUIRE(DNS_ZONE_VALID(zone));
7977 zone->checkns = checkns;
7981 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
7982 REQUIRE(DNS_ZONE_VALID(zone));
7985 zone->isself = isself;
7986 zone->isselfarg = arg;
7991 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
7992 REQUIRE(DNS_ZONE_VALID(zone));
7995 zone->notifydelay = delay;
8000 dns_zone_getnotifydelay(dns_zone_t *zone) {
8001 REQUIRE(DNS_ZONE_VALID(zone));
8003 return (zone->notifydelay);