2 * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: zone.c,v 1.410.18.52 2007/08/30 05:15:03 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 * Serial number for deferred journal compaction.
260 isc_uint32_t compact_serial;
263 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
264 #define DNS_ZONE_SETFLAG(z,f) do { \
265 INSIST(LOCKED_ZONE(z)); \
268 #define DNS_ZONE_CLRFLAG(z,f) do { \
269 INSIST(LOCKED_ZONE(z)); \
270 (z)->flags &= ~(f); \
272 /* XXX MPA these may need to go back into zone.h */
273 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
274 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
275 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
276 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
277 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
278 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
279 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
280 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
281 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
282 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
284 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
286 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
288 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
289 * zone with no masters
291 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
292 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
293 * from SOA (if not set, we
295 * default timer values) */
296 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
297 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
298 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
299 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
300 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
301 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
302 #define DNS_ZONEFLG_FLUSH 0x00200000U
303 #define DNS_ZONEFLG_NOEDNS 0x00400000U
304 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
305 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
306 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
308 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
310 /* Flags for zone_load() */
311 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
316 int refs; /* Locked by rwlock */
317 isc_taskmgr_t * taskmgr;
318 isc_timermgr_t * timermgr;
319 isc_socketmgr_t * socketmgr;
320 isc_taskpool_t * zonetasks;
322 isc_ratelimiter_t * rl;
326 /* Locked by rwlock. */
327 dns_zonelist_t zones;
328 dns_zonelist_t waiting_for_xfrin;
329 dns_zonelist_t xfrin_in_progress;
331 /* Configuration data. */
332 isc_uint32_t transfersin;
333 isc_uint32_t transfersperns;
334 unsigned int serialqueryrate;
336 /* Locked by iolock */
337 isc_uint32_t iolimit;
338 isc_uint32_t ioactive;
352 dns_request_t *request;
355 ISC_LINK(dns_notify_t) link;
358 #define DNS_NOTIFY_NOSOA 0x0001U
361 * dns_stub holds state while performing a 'stub' transfer.
362 * 'db' is the zone's 'db' or a new one if this is the initial
371 dns_dbversion_t *version;
383 dns_rdatacallbacks_t callbacks;
387 * Hold forward state.
393 isc_buffer_t *msgbuf;
394 dns_request_t *request;
397 dns_updatecallback_t callback;
402 * Hold IO request state.
409 ISC_LINK(dns_io_t) link;
413 #define SEND_BUFFER_SIZE 2048
415 static void zone_settimer(dns_zone_t *, isc_time_t *);
416 static void cancel_refresh(dns_zone_t *);
417 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
418 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
419 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
420 ISC_FORMAT_PRINTF(3, 4);
421 static void queue_xfrin(dns_zone_t *zone);
422 static void zone_unload(dns_zone_t *zone);
423 static void zone_expire(dns_zone_t *zone);
424 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
425 static void zone_idetach(dns_zone_t **zonep);
426 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
428 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
429 static inline void zone_detachdb(dns_zone_t *zone);
430 static isc_result_t default_journal(dns_zone_t *zone);
431 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
432 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
433 isc_time_t loadtime, isc_result_t result);
434 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
435 static void zone_shutdown(isc_task_t *, isc_event_t *);
436 static void zone_loaddone(void *arg, isc_result_t result);
437 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
438 isc_time_t loadtime);
441 /* ondestroy example */
442 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
445 static void refresh_callback(isc_task_t *, isc_event_t *);
446 static void stub_callback(isc_task_t *, isc_event_t *);
447 static void queue_soa_query(dns_zone_t *zone);
448 static void soa_query(isc_task_t *, isc_event_t *);
449 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
451 static int message_count(dns_message_t *msg, dns_section_t section,
452 dns_rdatatype_t type);
453 static void notify_cancel(dns_zone_t *zone);
454 static void notify_find_address(dns_notify_t *notify);
455 static void notify_send(dns_notify_t *notify);
456 static isc_result_t notify_createmessage(dns_zone_t *zone,
458 dns_message_t **messagep);
459 static void notify_done(isc_task_t *task, isc_event_t *event);
460 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
461 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
462 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
463 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
465 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
466 static void zonemgr_free(dns_zonemgr_t *zmgr);
467 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
468 isc_task_t *task, isc_taskaction_t action,
469 void *arg, dns_io_t **iop);
470 static void zonemgr_putio(dns_io_t **iop);
471 static void zonemgr_cancelio(dns_io_t *io);
474 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
475 unsigned int *soacount, isc_uint32_t *serial,
476 isc_uint32_t *refresh, isc_uint32_t *retry,
477 isc_uint32_t *expire, isc_uint32_t *minimum,
478 unsigned int *errors);
480 static void zone_freedbargs(dns_zone_t *zone);
481 static void forward_callback(isc_task_t *task, isc_event_t *event);
482 static void zone_saveunique(dns_zone_t *zone, const char *path,
483 const char *templat);
484 static void zone_maintenance(dns_zone_t *zone);
485 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
486 static void dump_done(void *arg, isc_result_t result);
488 #define ENTER zone_debuglog(zone, me, 1, "enter")
490 static const unsigned int dbargc_default = 1;
491 static const char *dbargv_default[] = { "rbt" };
493 #define DNS_ZONE_JITTER_ADD(a, b, c) \
497 _j = isc_random_jitter((b), (b)/4); \
498 isc_interval_set(&_i, _j, 0); \
499 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
500 dns_zone_log(zone, ISC_LOG_WARNING, \
501 "epoch approaching: upgrade required: " \
502 "now + %s failed", #b); \
503 isc_interval_set(&_i, _j/2, 0); \
504 (void)isc_time_add((a), &_i, (c)); \
508 #define DNS_ZONE_TIME_ADD(a, b, c) \
511 isc_interval_set(&_i, (b), 0); \
512 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
513 dns_zone_log(zone, ISC_LOG_WARNING, \
514 "epoch approaching: upgrade required: " \
515 "now + %s failed", #b); \
516 isc_interval_set(&_i, (b)/2, 0); \
517 (void)isc_time_add((a), &_i, (c)); \
522 *** Public functions.
526 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
531 REQUIRE(zonep != NULL && *zonep == NULL);
532 REQUIRE(mctx != NULL);
535 zone = isc_mem_get(mctx, sizeof(*zone));
537 return (ISC_R_NOMEMORY);
540 isc_mem_attach(mctx, &zone->mctx);
542 result = isc_mutex_init(&zone->lock);
543 if (result != ISC_R_SUCCESS)
546 result = ZONEDB_INITLOCK(&zone->dblock);
547 if (result != ISC_R_SUCCESS)
550 /* XXX MPA check that all elements are initialised */
551 #ifdef DNS_ZONE_CHECKLOCK
552 zone->locked = ISC_FALSE;
556 ISC_LINK_INIT(zone, link);
557 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
558 if (result != ISC_R_SUCCESS)
561 dns_name_init(&zone->origin, NULL);
562 zone->masterfile = NULL;
563 zone->masterformat = dns_masterformat_none;
564 zone->keydirectory = NULL;
565 zone->journalsize = -1;
566 zone->journal = NULL;
567 zone->rdclass = dns_rdataclass_none;
568 zone->type = dns_zone_none;
572 zone->db_argv = NULL;
573 isc_time_settoepoch(&zone->expiretime);
574 isc_time_settoepoch(&zone->refreshtime);
575 isc_time_settoepoch(&zone->dumptime);
576 isc_time_settoepoch(&zone->loadtime);
577 zone->notifytime = now;
579 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
580 zone->retry = DNS_ZONE_DEFAULTRETRY;
583 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
584 zone->minrefresh = DNS_ZONE_MINREFRESH;
585 zone->maxretry = DNS_ZONE_MAXRETRY;
586 zone->minretry = DNS_ZONE_MINRETRY;
587 zone->masters = NULL;
588 zone->masterkeynames = NULL;
589 zone->mastersok = NULL;
590 zone->masterscnt = 0;
593 zone->notifytype = dns_notifytype_yes;
596 zone->update_acl = NULL;
597 zone->forward_acl = NULL;
598 zone->notify_acl = NULL;
599 zone->query_acl = NULL;
600 zone->xfr_acl = NULL;
601 zone->update_disabled = ISC_FALSE;
602 zone->zero_no_soa_ttl = ISC_TRUE;
603 zone->check_names = dns_severity_ignore;
604 zone->request = NULL;
608 zone->writeio = NULL;
610 zone->idlein = DNS_DEFAULT_IDLEIN;
611 zone->idleout = DNS_DEFAULT_IDLEOUT;
612 ISC_LIST_INIT(zone->notifies);
613 isc_sockaddr_any(&zone->notifysrc4);
614 isc_sockaddr_any6(&zone->notifysrc6);
615 isc_sockaddr_any(&zone->xfrsource4);
616 isc_sockaddr_any6(&zone->xfrsource6);
617 isc_sockaddr_any(&zone->altxfrsource4);
618 isc_sockaddr_any6(&zone->altxfrsource6);
620 zone->tsigkey = NULL;
621 zone->maxxfrin = MAX_XFER_TIME;
622 zone->maxxfrout = MAX_XFER_TIME;
623 zone->ssutable = NULL;
624 zone->sigvalidityinterval = 30 * 24 * 3600;
627 zone->checkmx = NULL;
628 zone->checksrv = NULL;
629 zone->checkns = NULL;
630 ISC_LINK_INIT(zone, statelink);
631 zone->statelist = NULL;
632 zone->counters = NULL;
633 zone->notifydelay = 5;
635 zone->isselfarg = NULL;
637 zone->magic = ZONE_MAGIC;
639 /* Must be after magic is set. */
640 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
641 if (result != ISC_R_SUCCESS)
644 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
645 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
648 return (ISC_R_SUCCESS);
651 isc_refcount_decrement(&zone->erefs, NULL);
652 isc_refcount_destroy(&zone->erefs);
655 ZONEDB_DESTROYLOCK(&zone->dblock);
658 DESTROYLOCK(&zone->lock);
661 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
666 * Free a zone. Because we require that there be no more
667 * outstanding events or references, no locking is necessary.
670 zone_free(dns_zone_t *zone) {
671 isc_mem_t *mctx = NULL;
673 REQUIRE(DNS_ZONE_VALID(zone));
674 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
675 REQUIRE(zone->irefs == 0);
676 REQUIRE(!LOCKED_ZONE(zone));
677 REQUIRE(zone->timer == NULL);
680 * Managed objects. Order is important.
682 if (zone->request != NULL)
683 dns_request_destroy(&zone->request); /* XXXMPA */
684 INSIST(zone->readio == NULL);
685 INSIST(zone->statelist == NULL);
686 INSIST(zone->writeio == NULL);
688 if (zone->task != NULL)
689 isc_task_detach(&zone->task);
691 dns_zonemgr_releasezone(zone->zmgr, zone);
693 /* Unmanaged objects */
694 if (zone->masterfile != NULL)
695 isc_mem_free(zone->mctx, zone->masterfile);
696 zone->masterfile = NULL;
697 if (zone->keydirectory != NULL)
698 isc_mem_free(zone->mctx, zone->keydirectory);
699 zone->keydirectory = NULL;
700 zone->journalsize = -1;
701 if (zone->journal != NULL)
702 isc_mem_free(zone->mctx, zone->journal);
703 zone->journal = NULL;
704 if (zone->counters != NULL)
705 dns_stats_freecounters(zone->mctx, &zone->counters);
706 if (zone->db != NULL)
708 if (zone->acache != NULL)
709 dns_acache_detach(&zone->acache);
710 zone_freedbargs(zone);
711 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
713 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
715 zone->check_names = dns_severity_ignore;
716 if (zone->update_acl != NULL)
717 dns_acl_detach(&zone->update_acl);
718 if (zone->forward_acl != NULL)
719 dns_acl_detach(&zone->forward_acl);
720 if (zone->notify_acl != NULL)
721 dns_acl_detach(&zone->notify_acl);
722 if (zone->query_acl != NULL)
723 dns_acl_detach(&zone->query_acl);
724 if (zone->xfr_acl != NULL)
725 dns_acl_detach(&zone->xfr_acl);
726 if (dns_name_dynamic(&zone->origin))
727 dns_name_free(&zone->origin, zone->mctx);
728 if (zone->ssutable != NULL)
729 dns_ssutable_detach(&zone->ssutable);
732 ZONEDB_DESTROYLOCK(&zone->dblock);
733 DESTROYLOCK(&zone->lock);
734 isc_refcount_destroy(&zone->erefs);
737 isc_mem_put(mctx, zone, sizeof(*zone));
738 isc_mem_detach(&mctx);
745 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
747 REQUIRE(DNS_ZONE_VALID(zone));
748 REQUIRE(rdclass != dns_rdataclass_none);
754 REQUIRE(zone->rdclass == dns_rdataclass_none ||
755 zone->rdclass == rdclass);
756 zone->rdclass = rdclass;
761 dns_zone_getclass(dns_zone_t *zone){
762 REQUIRE(DNS_ZONE_VALID(zone));
764 return (zone->rdclass);
768 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
769 REQUIRE(DNS_ZONE_VALID(zone));
772 zone->notifytype = notifytype;
780 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
782 REQUIRE(DNS_ZONE_VALID(zone));
783 REQUIRE(type != dns_zone_none);
789 REQUIRE(zone->type == dns_zone_none || zone->type == type);
795 zone_freedbargs(dns_zone_t *zone) {
798 /* Free the old database argument list. */
799 if (zone->db_argv != NULL) {
800 for (i = 0; i < zone->db_argc; i++)
801 isc_mem_free(zone->mctx, zone->db_argv[i]);
802 isc_mem_put(zone->mctx, zone->db_argv,
803 zone->db_argc * sizeof(*zone->db_argv));
806 zone->db_argv = NULL;
810 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
813 isc_result_t result = ISC_R_SUCCESS;
817 REQUIRE(DNS_ZONE_VALID(zone));
818 REQUIRE(argv != NULL && *argv == NULL);
821 size = (zone->db_argc + 1) * sizeof(char *);
822 for (i = 0; i < zone->db_argc; i++)
823 size += strlen(zone->db_argv[i]) + 1;
824 mem = isc_mem_allocate(mctx, size);
828 tmp2 += (zone->db_argc + 1) * sizeof(char *);
829 for (i = 0; i < zone->db_argc; i++) {
831 strcpy(tmp2, zone->db_argv[i]);
832 tmp2 += strlen(tmp2) + 1;
836 result = ISC_R_NOMEMORY;
843 dns_zone_setdbtype(dns_zone_t *zone,
844 unsigned int dbargc, const char * const *dbargv) {
845 isc_result_t result = ISC_R_SUCCESS;
849 REQUIRE(DNS_ZONE_VALID(zone));
850 REQUIRE(dbargc >= 1);
851 REQUIRE(dbargv != NULL);
855 /* Set up a new database argument list. */
856 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
859 for (i = 0; i < dbargc; i++)
861 for (i = 0; i < dbargc; i++) {
862 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
867 /* Free the old list. */
868 zone_freedbargs(zone);
870 zone->db_argc = dbargc;
872 result = ISC_R_SUCCESS;
877 for (i = 0; i < dbargc; i++)
879 isc_mem_free(zone->mctx, new[i]);
880 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
882 result = ISC_R_NOMEMORY;
890 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
891 REQUIRE(DNS_ZONE_VALID(zone));
894 if (zone->view != NULL)
895 dns_view_weakdetach(&zone->view);
896 dns_view_weakattach(view, &zone->view);
902 dns_zone_getview(dns_zone_t *zone) {
903 REQUIRE(DNS_ZONE_VALID(zone));
910 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
913 REQUIRE(DNS_ZONE_VALID(zone));
914 REQUIRE(origin != NULL);
917 if (dns_name_dynamic(&zone->origin)) {
918 dns_name_free(&zone->origin, zone->mctx);
919 dns_name_init(&zone->origin, NULL);
921 result = dns_name_dup(origin, zone->mctx, &zone->origin);
927 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
928 REQUIRE(DNS_ZONE_VALID(zone));
929 REQUIRE(acache != NULL);
932 if (zone->acache != NULL)
933 dns_acache_detach(&zone->acache);
934 dns_acache_attach(acache, &zone->acache);
935 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
936 if (zone->db != NULL) {
940 * If the zone reuses an existing DB, the DB needs to be
941 * set in the acache explicitly. We can safely ignore the
942 * case where the DB is already set. If other error happens,
943 * the acache will not work effectively.
945 result = dns_acache_setdb(acache, zone->db);
946 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
947 UNEXPECTED_ERROR(__FILE__, __LINE__,
948 "dns_acache_setdb() failed: %s",
949 isc_result_totext(result));
952 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
957 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
961 copy = isc_mem_strdup(zone->mctx, value);
963 return (ISC_R_NOMEMORY);
969 isc_mem_free(zone->mctx, *field);
972 return (ISC_R_SUCCESS);
976 dns_zone_setfile(dns_zone_t *zone, const char *file) {
977 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
981 dns_zone_setfile2(dns_zone_t *zone, const char *file,
982 dns_masterformat_t format) {
983 isc_result_t result = ISC_R_SUCCESS;
985 REQUIRE(DNS_ZONE_VALID(zone));
988 result = dns_zone_setstring(zone, &zone->masterfile, file);
989 if (result == ISC_R_SUCCESS) {
990 zone->masterformat = format;
991 result = default_journal(zone);
999 dns_zone_getfile(dns_zone_t *zone) {
1000 REQUIRE(DNS_ZONE_VALID(zone));
1002 return (zone->masterfile);
1006 default_journal(dns_zone_t *zone) {
1007 isc_result_t result;
1010 REQUIRE(DNS_ZONE_VALID(zone));
1011 REQUIRE(LOCKED_ZONE(zone));
1013 if (zone->masterfile != NULL) {
1014 /* Calculate string length including '\0'. */
1015 int len = strlen(zone->masterfile) + sizeof(".jnl");
1016 journal = isc_mem_allocate(zone->mctx, len);
1017 if (journal == NULL)
1018 return (ISC_R_NOMEMORY);
1019 strcpy(journal, zone->masterfile);
1020 strcat(journal, ".jnl");
1024 result = dns_zone_setstring(zone, &zone->journal, journal);
1025 if (journal != NULL)
1026 isc_mem_free(zone->mctx, journal);
1031 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1032 isc_result_t result = ISC_R_SUCCESS;
1034 REQUIRE(DNS_ZONE_VALID(zone));
1037 result = dns_zone_setstring(zone, &zone->journal, journal);
1044 dns_zone_getjournal(dns_zone_t *zone) {
1045 REQUIRE(DNS_ZONE_VALID(zone));
1047 return (zone->journal);
1051 * Return true iff the zone is "dynamic", in the sense that the zone's
1052 * master file (if any) is written by the server, rather than being
1053 * updated manually and read by the server.
1055 * This is true for slave zones, stub zones, and zones that allow
1056 * dynamic updates either by having an update policy ("ssutable")
1057 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1059 static isc_boolean_t
1060 zone_isdynamic(dns_zone_t *zone) {
1061 REQUIRE(DNS_ZONE_VALID(zone));
1063 return (ISC_TF(zone->type == dns_zone_slave ||
1064 zone->type == dns_zone_stub ||
1065 (!zone->update_disabled && zone->ssutable != NULL) ||
1066 (!zone->update_disabled && zone->update_acl != NULL &&
1067 ! (zone->update_acl->length == 1 &&
1068 zone->update_acl->elements[0].negative == ISC_TRUE
1070 zone->update_acl->elements[0].type ==
1071 dns_aclelementtype_any))));
1076 zone_load(dns_zone_t *zone, unsigned int flags) {
1077 isc_result_t result;
1079 isc_time_t loadtime, filetime;
1080 dns_db_t *db = NULL;
1082 REQUIRE(DNS_ZONE_VALID(zone));
1087 INSIST(zone->type != dns_zone_none);
1089 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1090 result = ISC_R_SUCCESS;
1094 if (zone->db != NULL && zone->masterfile == NULL) {
1096 * The zone has no master file configured, but it already
1097 * has a database. It could be the built-in
1098 * version.bind. CH zone, a zone with a persistent
1099 * database being reloaded, or maybe a zone that
1100 * used to have a master file but whose configuration
1101 * was changed so that it no longer has one. Do nothing.
1103 result = ISC_R_SUCCESS;
1107 if (zone->db != NULL && zone_isdynamic(zone)) {
1109 * This is a slave, stub, or dynamically updated
1110 * zone being reloaded. Do nothing - the database
1111 * we already have is guaranteed to be up-to-date.
1113 if (zone->type == dns_zone_master)
1114 result = DNS_R_DYNAMIC;
1116 result = ISC_R_SUCCESS;
1122 * Store the current time before the zone is loaded, so that if the
1123 * file changes between the time of the load and the time that
1124 * zone->loadtime is set, then the file will still be reloaded
1125 * the next time dns_zone_load is called.
1127 TIME_NOW(&loadtime);
1130 * Don't do the load if the file that stores the zone is older
1131 * than the last time the zone was loaded. If the zone has not
1132 * been loaded yet, zone->loadtime will be the epoch.
1134 if (zone->masterfile != NULL) {
1136 * The file is already loaded. If we are just doing a
1137 * "rndc reconfig", we are done.
1139 if (!isc_time_isepoch(&zone->loadtime) &&
1140 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1141 result = ISC_R_SUCCESS;
1145 result = isc_file_getmodtime(zone->masterfile, &filetime);
1146 if (result == ISC_R_SUCCESS) {
1147 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1148 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1149 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1150 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1151 "skipping load: master file "
1152 "older than last load");
1153 result = DNS_R_UPTODATE;
1156 loadtime = filetime;
1160 INSIST(zone->db_argc >= 1);
1163 * Built in zones don't need to be reloaded.
1165 if (zone->type == dns_zone_master &&
1166 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1167 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1168 result = ISC_R_SUCCESS;
1172 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1173 (strcmp(zone->db_argv[0], "rbt") == 0 ||
1174 strcmp(zone->db_argv[0], "rbt64") == 0)) {
1175 if (zone->masterfile == NULL ||
1176 !isc_file_exists(zone->masterfile)) {
1177 if (zone->masterfile != NULL) {
1178 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1181 zone->refreshtime = now;
1182 if (zone->task != NULL)
1183 zone_settimer(zone, &now);
1184 result = ISC_R_SUCCESS;
1189 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1191 result = dns_db_create(zone->mctx, zone->db_argv[0],
1192 &zone->origin, (zone->type == dns_zone_stub) ?
1193 dns_dbtype_stub : dns_dbtype_zone,
1195 zone->db_argc - 1, zone->db_argv + 1,
1198 if (result != ISC_R_SUCCESS) {
1199 dns_zone_log(zone, ISC_LOG_ERROR,
1200 "loading zone: creating database: %s",
1201 isc_result_totext(result));
1204 dns_db_settask(db, zone->task);
1206 if (! dns_db_ispersistent(db)) {
1207 if (zone->masterfile != NULL) {
1208 result = zone_startload(db, zone, loadtime);
1210 result = DNS_R_NOMASTERFILE;
1211 if (zone->type == dns_zone_master) {
1212 dns_zone_log(zone, ISC_LOG_ERROR,
1214 "no master file configured");
1217 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1218 "no master file configured: continuing");
1222 if (result == DNS_R_CONTINUE) {
1223 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1227 result = zone_postload(zone, db, loadtime, result);
1237 dns_zone_load(dns_zone_t *zone) {
1238 return (zone_load(zone, 0));
1242 dns_zone_loadnew(dns_zone_t *zone) {
1243 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1247 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1248 dns_load_t *load = event->ev_arg;
1249 isc_result_t result = ISC_R_SUCCESS;
1250 unsigned int options;
1252 REQUIRE(DNS_LOAD_VALID(load));
1254 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1255 result = ISC_R_CANCELED;
1256 isc_event_free(&event);
1257 if (result == ISC_R_CANCELED)
1260 options = DNS_MASTER_ZONE;
1261 if (load->zone->type == dns_zone_slave)
1262 options |= DNS_MASTER_SLAVE;
1263 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNS))
1264 options |= DNS_MASTER_CHECKNS;
1265 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_FATALNS))
1266 options |= DNS_MASTER_FATALNS;
1267 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMES))
1268 options |= DNS_MASTER_CHECKNAMES;
1269 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1270 options |= DNS_MASTER_CHECKNAMESFAIL;
1271 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMX))
1272 options |= DNS_MASTER_CHECKMX;
1273 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMXFAIL))
1274 options |= DNS_MASTER_CHECKMXFAIL;
1275 if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKWILDCARD))
1276 options |= DNS_MASTER_CHECKWILDCARD;
1277 result = dns_master_loadfileinc2(load->zone->masterfile,
1278 dns_db_origin(load->db),
1279 dns_db_origin(load->db),
1280 load->zone->rdclass,
1282 &load->callbacks, task,
1283 zone_loaddone, load,
1284 &load->zone->lctx, load->zone->mctx,
1285 load->zone->masterformat);
1286 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1287 result != DNS_R_SEENINCLUDE)
1292 zone_loaddone(load, result);
1296 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1297 const char me[] = "zone_gotwritehandle";
1298 dns_zone_t *zone = event->ev_arg;
1299 isc_result_t result = ISC_R_SUCCESS;
1300 dns_dbversion_t *version = NULL;
1302 REQUIRE(DNS_ZONE_VALID(zone));
1303 INSIST(task == zone->task);
1306 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1307 result = ISC_R_CANCELED;
1308 isc_event_free(&event);
1309 if (result == ISC_R_CANCELED)
1313 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1314 dns_db_currentversion(zone->db, &version);
1315 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1316 &dns_master_style_default,
1317 zone->masterfile, zone->task, dump_done,
1318 zone, &zone->dctx, zone->masterformat);
1319 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1320 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1322 if (result != DNS_R_CONTINUE)
1327 dump_done(zone, result);
1331 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1333 isc_result_t result;
1334 isc_result_t tresult;
1335 unsigned int options;
1337 options = DNS_MASTER_ZONE;
1338 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1339 options |= DNS_MASTER_MANYERRORS;
1340 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1341 options |= DNS_MASTER_CHECKNS;
1342 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1343 options |= DNS_MASTER_FATALNS;
1344 if (zone->type == dns_zone_slave)
1345 options |= DNS_MASTER_SLAVE;
1346 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1347 options |= DNS_MASTER_CHECKNAMES;
1348 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1349 options |= DNS_MASTER_CHECKNAMESFAIL;
1350 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1351 options |= DNS_MASTER_CHECKMX;
1352 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1353 options |= DNS_MASTER_CHECKMXFAIL;
1354 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1355 options |= DNS_MASTER_CHECKWILDCARD;
1357 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1358 load = isc_mem_get(zone->mctx, sizeof(*load));
1360 return (ISC_R_NOMEMORY);
1365 load->loadtime = loadtime;
1366 load->magic = LOAD_MAGIC;
1368 isc_mem_attach(zone->mctx, &load->mctx);
1369 zone_iattach(zone, &load->zone);
1370 dns_db_attach(db, &load->db);
1371 dns_rdatacallbacks_init(&load->callbacks);
1372 result = dns_db_beginload(db, &load->callbacks.add,
1373 &load->callbacks.add_private);
1374 if (result != ISC_R_SUCCESS)
1376 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1377 zone_gotreadhandle, load,
1379 if (result != ISC_R_SUCCESS) {
1381 * We can't report multiple errors so ignore
1382 * the result of dns_db_endload().
1384 (void)dns_db_endload(load->db,
1385 &load->callbacks.add_private);
1388 result = DNS_R_CONTINUE;
1390 dns_rdatacallbacks_t callbacks;
1392 dns_rdatacallbacks_init(&callbacks);
1393 result = dns_db_beginload(db, &callbacks.add,
1394 &callbacks.add_private);
1395 if (result != ISC_R_SUCCESS)
1397 result = dns_master_loadfile2(zone->masterfile, &zone->origin,
1398 &zone->origin, zone->rdclass,
1399 options, &callbacks, zone->mctx,
1400 zone->masterformat);
1401 tresult = dns_db_endload(db, &callbacks.add_private);
1402 if (result == ISC_R_SUCCESS)
1410 dns_db_detach(&load->db);
1411 zone_idetach(&load->zone);
1412 isc_mem_detach(&load->mctx);
1413 isc_mem_put(zone->mctx, load, sizeof(*load));
1417 static isc_boolean_t
1418 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1421 isc_result_t result;
1422 char ownerbuf[DNS_NAME_FORMATSIZE];
1423 char namebuf[DNS_NAME_FORMATSIZE];
1424 char altbuf[DNS_NAME_FORMATSIZE];
1425 dns_fixedname_t fixed;
1426 dns_name_t *foundname;
1432 if (!dns_name_issubdomain(name, &zone->origin)) {
1433 if (zone->checkmx != NULL)
1434 return ((zone->checkmx)(zone, name, owner));
1438 if (zone->type == dns_zone_master)
1439 level = ISC_LOG_ERROR;
1441 level = ISC_LOG_WARNING;
1443 dns_fixedname_init(&fixed);
1444 foundname = dns_fixedname_name(&fixed);
1446 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1447 0, 0, NULL, foundname, NULL, NULL);
1448 if (result == ISC_R_SUCCESS)
1451 if (result == DNS_R_NXRRSET) {
1452 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1453 0, 0, NULL, foundname, NULL, NULL);
1454 if (result == ISC_R_SUCCESS)
1458 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1459 dns_name_format(name, namebuf, sizeof namebuf);
1460 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1461 result == DNS_R_EMPTYNAME) {
1462 dns_zone_log(zone, level,
1463 "%s/MX '%s' has no address records (A or AAAA)",
1465 /* XXX950 make fatal for 9.5.0. */
1469 if (result == DNS_R_CNAME) {
1470 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1471 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1472 level = ISC_LOG_WARNING;
1473 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1474 dns_zone_log(zone, level,
1475 "%s/MX '%s' is a CNAME (illegal)",
1477 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1480 if (result == DNS_R_DNAME) {
1481 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1482 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1483 level = ISC_LOG_WARNING;
1484 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1485 dns_name_format(foundname, altbuf, sizeof altbuf);
1486 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1487 " '%s' (illegal)", ownerbuf, namebuf,
1490 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1493 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1494 return ((zone->checkmx)(zone, name, owner));
1499 static isc_boolean_t
1500 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1503 isc_result_t result;
1504 char ownerbuf[DNS_NAME_FORMATSIZE];
1505 char namebuf[DNS_NAME_FORMATSIZE];
1506 char altbuf[DNS_NAME_FORMATSIZE];
1507 dns_fixedname_t fixed;
1508 dns_name_t *foundname;
1512 * "." means the services does not exist.
1514 if (dns_name_equal(name, dns_rootname))
1520 if (!dns_name_issubdomain(name, &zone->origin)) {
1521 if (zone->checksrv != NULL)
1522 return ((zone->checksrv)(zone, name, owner));
1526 if (zone->type == dns_zone_master)
1527 level = ISC_LOG_ERROR;
1529 level = ISC_LOG_WARNING;
1531 dns_fixedname_init(&fixed);
1532 foundname = dns_fixedname_name(&fixed);
1534 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1535 0, 0, NULL, foundname, NULL, NULL);
1536 if (result == ISC_R_SUCCESS)
1539 if (result == DNS_R_NXRRSET) {
1540 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1541 0, 0, NULL, foundname, NULL, NULL);
1542 if (result == ISC_R_SUCCESS)
1546 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1547 dns_name_format(name, namebuf, sizeof namebuf);
1548 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1549 result == DNS_R_EMPTYNAME) {
1550 dns_zone_log(zone, level,
1551 "%s/SRV '%s' has no address records (A or AAAA)",
1553 /* XXX950 make fatal for 9.5.0. */
1557 if (result == DNS_R_CNAME) {
1558 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1559 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1560 level = ISC_LOG_WARNING;
1561 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1562 dns_zone_log(zone, level,
1563 "%s/SRV '%s' is a CNAME (illegal)",
1565 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1568 if (result == DNS_R_DNAME) {
1569 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1570 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1571 level = ISC_LOG_WARNING;
1572 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1573 dns_name_format(foundname, altbuf, sizeof altbuf);
1574 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1575 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1578 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1581 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1582 return ((zone->checksrv)(zone, name, owner));
1587 static isc_boolean_t
1588 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1591 isc_boolean_t answer = ISC_TRUE;
1592 isc_result_t result, tresult;
1593 char ownerbuf[DNS_NAME_FORMATSIZE];
1594 char namebuf[DNS_NAME_FORMATSIZE];
1595 char altbuf[DNS_NAME_FORMATSIZE];
1596 dns_fixedname_t fixed;
1597 dns_name_t *foundname;
1599 dns_rdataset_t aaaa;
1605 if (!dns_name_issubdomain(name, &zone->origin)) {
1606 if (zone->checkns != NULL)
1607 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1611 if (zone->type == dns_zone_master)
1612 level = ISC_LOG_ERROR;
1614 level = ISC_LOG_WARNING;
1616 dns_fixedname_init(&fixed);
1617 foundname = dns_fixedname_name(&fixed);
1618 dns_rdataset_init(&a);
1619 dns_rdataset_init(&aaaa);
1621 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1622 DNS_DBFIND_GLUEOK, 0, NULL,
1623 foundname, &a, NULL);
1625 if (result == ISC_R_SUCCESS) {
1626 dns_rdataset_disassociate(&a);
1628 } else if (result == DNS_R_DELEGATION)
1629 dns_rdataset_disassociate(&a);
1631 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1632 result == DNS_R_GLUE) {
1633 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1634 DNS_DBFIND_GLUEOK, 0, NULL,
1635 foundname, &aaaa, NULL);
1636 if (tresult == ISC_R_SUCCESS) {
1637 dns_rdataset_disassociate(&aaaa);
1640 if (tresult == DNS_R_DELEGATION)
1641 dns_rdataset_disassociate(&aaaa);
1642 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1644 * Check glue against child zone.
1646 if (zone->checkns != NULL)
1647 answer = (zone->checkns)(zone, name, owner,
1649 if (dns_rdataset_isassociated(&a))
1650 dns_rdataset_disassociate(&a);
1651 if (dns_rdataset_isassociated(&aaaa))
1652 dns_rdataset_disassociate(&aaaa);
1658 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1659 dns_name_format(name, namebuf, sizeof namebuf);
1660 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1661 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
1663 if (dns_name_issubdomain(name, owner))
1664 what = "REQUIRED GLUE ";
1665 else if (result == DNS_R_DELEGATION)
1666 what = "SIBLING GLUE ";
1670 if (result != DNS_R_DELEGATION ||
1671 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
1672 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
1673 "address records (A or AAAA)",
1674 ownerbuf, namebuf, what);
1676 * Log missing address record.
1678 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
1679 (void)(zone->checkns)(zone, name, owner,
1681 /* XXX950 make fatal for 9.5.0. */
1682 /* answer = ISC_FALSE; */
1684 } else if (result == DNS_R_CNAME) {
1685 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
1687 /* XXX950 make fatal for 9.5.0. */
1688 /* answer = ISC_FALSE; */
1689 } else if (result == DNS_R_DNAME) {
1690 dns_name_format(foundname, altbuf, sizeof altbuf);
1691 dns_zone_log(zone, level,
1692 "%s/NS '%s' is below a DNAME '%s' (illegal)",
1693 ownerbuf, namebuf, altbuf);
1694 /* XXX950 make fatal for 9.5.0. */
1695 /* answer = ISC_FALSE; */
1698 if (dns_rdataset_isassociated(&a))
1699 dns_rdataset_disassociate(&a);
1700 if (dns_rdataset_isassociated(&aaaa))
1701 dns_rdataset_disassociate(&aaaa);
1705 static isc_boolean_t
1706 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
1707 dns_dbiterator_t *dbiterator = NULL;
1708 dns_dbnode_t *node = NULL;
1709 dns_rdataset_t rdataset;
1710 dns_fixedname_t fixed;
1711 dns_fixedname_t fixedbottom;
1714 dns_rdata_in_srv_t srv;
1718 isc_result_t result;
1719 isc_boolean_t ok = ISC_TRUE;
1721 dns_fixedname_init(&fixed);
1722 name = dns_fixedname_name(&fixed);
1723 dns_fixedname_init(&fixedbottom);
1724 bottom = dns_fixedname_name(&fixedbottom);
1725 dns_rdataset_init(&rdataset);
1726 dns_rdata_init(&rdata);
1728 result = dns_db_createiterator(db, ISC_FALSE, &dbiterator);
1729 if (result != ISC_R_SUCCESS)
1732 result = dns_dbiterator_first(dbiterator);
1733 while (result == ISC_R_SUCCESS) {
1734 result = dns_dbiterator_current(dbiterator, &node, name);
1735 if (result != ISC_R_SUCCESS)
1739 * Is this name visible in the zone?
1741 if (!dns_name_issubdomain(name, &zone->origin) ||
1742 (dns_name_countlabels(bottom) > 0 &&
1743 dns_name_issubdomain(name, bottom)))
1747 * Don't check the NS records at the origin.
1749 if (dns_name_equal(name, &zone->origin))
1752 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
1753 0, 0, &rdataset, NULL);
1754 if (result != ISC_R_SUCCESS)
1757 * Remember bottom of zone.
1759 dns_name_copy(name, bottom, NULL);
1761 result = dns_rdataset_first(&rdataset);
1762 while (result == ISC_R_SUCCESS) {
1763 dns_rdataset_current(&rdataset, &rdata);
1764 result = dns_rdata_tostruct(&rdata, &ns, NULL);
1765 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1766 if (!zone_check_glue(zone, db, &ns.name, name))
1768 dns_rdata_reset(&rdata);
1769 result = dns_rdataset_next(&rdataset);
1771 dns_rdataset_disassociate(&rdataset);
1774 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
1775 0, 0, &rdataset, NULL);
1776 if (result != ISC_R_SUCCESS)
1778 result = dns_rdataset_first(&rdataset);
1779 while (result == ISC_R_SUCCESS) {
1780 dns_rdataset_current(&rdataset, &rdata);
1781 result = dns_rdata_tostruct(&rdata, &mx, NULL);
1782 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1783 if (!zone_check_mx(zone, db, &mx.mx, name))
1785 dns_rdata_reset(&rdata);
1786 result = dns_rdataset_next(&rdataset);
1788 dns_rdataset_disassociate(&rdataset);
1791 if (zone->rdclass != dns_rdataclass_in)
1793 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
1794 0, 0, &rdataset, NULL);
1795 if (result != ISC_R_SUCCESS)
1797 result = dns_rdataset_first(&rdataset);
1798 while (result == ISC_R_SUCCESS) {
1799 dns_rdataset_current(&rdataset, &rdata);
1800 result = dns_rdata_tostruct(&rdata, &srv, NULL);
1801 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1802 if (!zone_check_srv(zone, db, &srv.target, name))
1804 dns_rdata_reset(&rdata);
1805 result = dns_rdataset_next(&rdataset);
1807 dns_rdataset_disassociate(&rdataset);
1810 dns_db_detachnode(db, &node);
1811 result = dns_dbiterator_next(dbiterator);
1816 dns_db_detachnode(db, &node);
1817 dns_dbiterator_destroy(&dbiterator);
1823 * OpenSSL verification of RSA keys with exponent 3 is known to be
1824 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
1825 * if they are in use.
1828 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
1829 dns_dbnode_t *node = NULL;
1830 dns_dbversion_t *version = NULL;
1831 dns_rdata_dnskey_t dnskey;
1832 dns_rdata_t rdata = DNS_RDATA_INIT;
1833 dns_rdataset_t rdataset;
1834 isc_result_t result;
1835 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
1836 const char *algorithm;
1838 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
1839 if (result != ISC_R_SUCCESS)
1842 dns_db_currentversion(db, &version);
1843 dns_rdataset_init(&rdataset);
1844 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1845 dns_rdatatype_none, 0, &rdataset, NULL);
1846 if (result != ISC_R_SUCCESS)
1849 for (result = dns_rdataset_first(&rdataset);
1850 result == ISC_R_SUCCESS;
1851 result = dns_rdataset_next(&rdataset))
1853 dns_rdataset_current(&rdataset, &rdata);
1854 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
1855 INSIST(result == ISC_R_SUCCESS);
1857 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
1858 dnskey.algorithm == DST_ALG_RSAMD5) &&
1859 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
1860 dnskey.data[1] == 3)
1862 if (dnskey.algorithm == DST_ALG_RSASHA1) {
1864 foundrsa = ISC_TRUE;
1865 algorithm = "RSASHA1";
1868 foundmd5 = ISC_TRUE;
1869 algorithm = "RSAMD5";
1872 dns_zone_log(zone, ISC_LOG_WARNING,
1873 "weak %s (%u) key found "
1874 "(exponent=3)", algorithm,
1876 if (foundrsa && foundmd5)
1879 dns_rdata_reset(&rdata);
1881 dns_rdataset_disassociate(&rdataset);
1885 dns_db_detachnode(db, &node);
1886 if (version != NULL)
1887 dns_db_closeversion(db, &version, ISC_FALSE);
1892 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
1893 isc_result_t result)
1895 unsigned int soacount = 0;
1896 unsigned int nscount = 0;
1897 unsigned int errors = 0;
1898 isc_uint32_t serial, refresh, retry, expire, minimum;
1900 isc_boolean_t needdump = ISC_FALSE;
1901 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1906 * Initiate zone transfer? We may need a error code that
1907 * indicates that the "permanent" form does not exist.
1908 * XXX better error feedback to log.
1910 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
1911 if (zone->type == dns_zone_slave ||
1912 zone->type == dns_zone_stub) {
1913 if (result == ISC_R_FILENOTFOUND)
1914 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1916 else if (result != DNS_R_NOMASTERFILE)
1917 dns_zone_log(zone, ISC_LOG_ERROR,
1918 "loading from master file %s "
1921 dns_result_totext(result));
1923 dns_zone_log(zone, ISC_LOG_ERROR,
1924 "loading from master file %s failed: %s",
1926 dns_result_totext(result));
1930 dns_zone_log(zone, ISC_LOG_DEBUG(2),
1931 "number of nodes in database: %u",
1932 dns_db_nodecount(db));
1934 if (result == DNS_R_SEENINCLUDE)
1935 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1937 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
1940 * Apply update log, if any, on initial load.
1942 if (zone->journal != NULL &&
1943 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
1944 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
1946 result = dns_journal_rollforward(zone->mctx, db,
1948 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
1949 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
1950 result != ISC_R_RANGE) {
1951 dns_zone_log(zone, ISC_LOG_ERROR,
1952 "journal rollforward failed: %s",
1953 dns_result_totext(result));
1956 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
1957 dns_zone_log(zone, ISC_LOG_ERROR,
1958 "journal rollforward failed: "
1959 "journal out of sync with zone");
1962 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1963 "journal rollforward completed "
1965 dns_result_totext(result));
1966 if (result == ISC_R_SUCCESS)
1967 needdump = ISC_TRUE;
1970 zone->loadtime = loadtime;
1972 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded");
1975 * Obtain ns, soa and cname counts for top of zone.
1978 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
1979 &refresh, &retry, &expire, &minimum,
1981 if (result != ISC_R_SUCCESS) {
1982 dns_zone_log(zone, ISC_LOG_ERROR,
1983 "could not find NS and/or SOA records");
1987 * Master / Slave / Stub zones require both NS and SOA records at
1988 * the top of the zone.
1991 switch (zone->type) {
1992 case dns_zone_master:
1993 case dns_zone_slave:
1995 if (soacount != 1) {
1996 dns_zone_log(zone, ISC_LOG_ERROR,
1997 "has %d SOA records", soacount);
1998 result = DNS_R_BADZONE;
2001 dns_zone_log(zone, ISC_LOG_ERROR,
2002 "has no NS records");
2003 result = DNS_R_BADZONE;
2005 if (result != ISC_R_SUCCESS)
2007 if (zone->type == dns_zone_master && errors != 0) {
2008 result = DNS_R_BADZONE;
2011 if (zone->type == dns_zone_master &&
2012 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
2013 !integrity_checks(zone, db)) {
2014 result = DNS_R_BADZONE;
2018 if (zone->db != NULL) {
2020 * This is checked in zone_replacedb() for slave zones
2021 * as they don't reload from disk.
2023 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
2024 !isc_serial_gt(serial, zone->serial)) {
2025 isc_uint32_t serialmin, serialmax;
2027 INSIST(zone->type == dns_zone_master);
2029 serialmin = (zone->serial + 1) & 0xffffffffU;
2030 serialmax = (zone->serial + 0x7fffffffU) &
2032 dns_zone_log(zone, ISC_LOG_ERROR,
2033 "ixfr-from-differences: "
2034 "new serial (%u) out of range "
2035 "[%u - %u]", serial, serialmin,
2037 result = DNS_R_BADZONE;
2039 } else if (!isc_serial_ge(serial, zone->serial))
2040 dns_zone_log(zone, ISC_LOG_ERROR,
2041 "zone serial has gone backwards");
2042 else if (serial == zone->serial && !hasinclude)
2043 dns_zone_log(zone, ISC_LOG_ERROR,
2044 "zone serial unchanged. "
2045 "zone may fail to transfer "
2048 zone->serial = serial;
2049 zone->refresh = RANGE(refresh,
2050 zone->minrefresh, zone->maxrefresh);
2051 zone->retry = RANGE(retry,
2052 zone->minretry, zone->maxretry);
2053 zone->expire = RANGE(expire, zone->refresh + zone->retry,
2055 zone->minimum = minimum;
2056 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
2058 if (zone->type == dns_zone_slave ||
2059 zone->type == dns_zone_stub) {
2063 result = isc_file_getmodtime(zone->journal, &t);
2064 if (result != ISC_R_SUCCESS)
2065 result = isc_file_getmodtime(zone->masterfile,
2067 if (result == ISC_R_SUCCESS)
2068 DNS_ZONE_TIME_ADD(&t, zone->expire,
2071 DNS_ZONE_TIME_ADD(&now, zone->retry,
2074 delay = isc_random_jitter(zone->retry,
2075 (zone->retry * 3) / 4);
2076 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
2077 if (isc_time_compare(&zone->refreshtime,
2078 &zone->expiretime) >= 0)
2079 zone->refreshtime = now;
2083 UNEXPECTED_ERROR(__FILE__, __LINE__,
2084 "unexpected zone type %d", zone->type);
2085 result = ISC_R_UNEXPECTED;
2090 * Check for weak DNSKEY's.
2092 if (zone->type == dns_zone_master)
2093 zone_check_dnskeys(zone, db);
2096 /* destroy notification example. */
2098 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
2099 DNS_EVENT_DBDESTROYED,
2100 dns_zonemgr_dbdestroyed,
2102 sizeof(isc_event_t));
2103 dns_db_ondestroy(db, zone->task, &e);
2107 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2108 if (zone->db != NULL) {
2109 result = zone_replacedb(zone, db, ISC_FALSE);
2110 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2111 if (result != ISC_R_SUCCESS)
2114 zone_attachdb(zone, db);
2115 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2116 DNS_ZONE_SETFLAG(zone,
2117 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
2119 result = ISC_R_SUCCESS;
2121 zone_needdump(zone, DNS_DUMP_DELAY);
2122 if (zone->task != NULL)
2123 zone_settimer(zone, &now);
2125 if (! dns_db_ispersistent(db))
2126 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s",
2128 dns_db_issecure(db) ? " (signed)" : "");
2133 if (zone->type == dns_zone_slave ||
2134 zone->type == dns_zone_stub) {
2135 if (zone->journal != NULL)
2136 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
2137 if (zone->masterfile != NULL)
2138 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
2140 /* Mark the zone for immediate refresh. */
2141 zone->refreshtime = now;
2142 if (zone->task != NULL)
2143 zone_settimer(zone, &now);
2144 result = ISC_R_SUCCESS;
2149 static isc_boolean_t
2150 exit_check(dns_zone_t *zone) {
2152 REQUIRE(LOCKED_ZONE(zone));
2154 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
2158 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
2160 INSIST(isc_refcount_current(&zone->erefs) == 0);
2166 static isc_boolean_t
2167 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
2168 isc_result_t result;
2169 char namebuf[DNS_NAME_FORMATSIZE];
2170 char altbuf[DNS_NAME_FORMATSIZE];
2171 dns_fixedname_t fixed;
2172 dns_name_t *foundname;
2175 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
2178 if (zone->type == dns_zone_master)
2179 level = ISC_LOG_ERROR;
2181 level = ISC_LOG_WARNING;
2183 dns_fixedname_init(&fixed);
2184 foundname = dns_fixedname_name(&fixed);
2186 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2187 0, 0, NULL, foundname, NULL, NULL);
2188 if (result == ISC_R_SUCCESS)
2191 if (result == DNS_R_NXRRSET) {
2192 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2193 0, 0, NULL, foundname, NULL, NULL);
2194 if (result == ISC_R_SUCCESS)
2198 dns_name_format(name, namebuf, sizeof namebuf);
2199 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2200 result == DNS_R_EMPTYNAME) {
2201 dns_zone_log(zone, level,
2202 "NS '%s' has no address records (A or AAAA)",
2204 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2208 if (result == DNS_R_CNAME) {
2209 dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
2211 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2215 if (result == DNS_R_DNAME) {
2216 dns_name_format(foundname, altbuf, sizeof altbuf);
2217 dns_zone_log(zone, level,
2218 "NS '%s' is below a DNAME '%s' (illegal)",
2220 /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
2228 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
2229 dns_dbversion_t *version, unsigned int *nscount,
2230 unsigned int *errors)
2232 isc_result_t result;
2233 unsigned int count = 0;
2234 unsigned int ecount = 0;
2235 dns_rdataset_t rdataset;
2239 dns_rdataset_init(&rdataset);
2240 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
2241 dns_rdatatype_none, 0, &rdataset, NULL);
2242 if (result == ISC_R_NOTFOUND)
2244 if (result != ISC_R_SUCCESS)
2245 goto invalidate_rdataset;
2247 result = dns_rdataset_first(&rdataset);
2248 while (result == ISC_R_SUCCESS) {
2249 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
2250 (zone->type == dns_zone_master ||
2251 zone->type == dns_zone_slave)) {
2252 dns_rdata_init(&rdata);
2253 dns_rdataset_current(&rdataset, &rdata);
2254 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2255 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2256 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
2257 !zone_check_ns(zone, db, &ns.name))
2261 result = dns_rdataset_next(&rdataset);
2263 dns_rdataset_disassociate(&rdataset);
2266 if (nscount != NULL)
2271 result = ISC_R_SUCCESS;
2273 invalidate_rdataset:
2274 dns_rdataset_invalidate(&rdataset);
2280 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
2281 unsigned int *soacount,
2282 isc_uint32_t *serial, isc_uint32_t *refresh,
2283 isc_uint32_t *retry, isc_uint32_t *expire,
2284 isc_uint32_t *minimum)
2286 isc_result_t result;
2288 dns_rdataset_t rdataset;
2289 dns_rdata_t rdata = DNS_RDATA_INIT;
2290 dns_rdata_soa_t soa;
2292 dns_rdataset_init(&rdataset);
2293 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
2294 dns_rdatatype_none, 0, &rdataset, NULL);
2295 if (result == ISC_R_NOTFOUND) {
2296 if (soacount != NULL)
2300 if (refresh != NULL)
2306 if (minimum != NULL)
2308 result = ISC_R_SUCCESS;
2309 goto invalidate_rdataset;
2311 if (result != ISC_R_SUCCESS)
2312 goto invalidate_rdataset;
2315 result = dns_rdataset_first(&rdataset);
2316 while (result == ISC_R_SUCCESS) {
2317 dns_rdata_init(&rdata);
2318 dns_rdataset_current(&rdataset, &rdata);
2321 result = dns_rdata_tostruct(&rdata, &soa, NULL);
2322 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2325 result = dns_rdataset_next(&rdataset);
2326 dns_rdata_reset(&rdata);
2328 dns_rdataset_disassociate(&rdataset);
2330 if (soacount != NULL)
2335 *serial = soa.serial;
2336 if (refresh != NULL)
2337 *refresh = soa.refresh;
2341 *expire = soa.expire;
2342 if (minimum != NULL)
2343 *minimum = soa.minimum;
2346 result = ISC_R_SUCCESS;
2348 invalidate_rdataset:
2349 dns_rdataset_invalidate(&rdataset);
2355 * zone must be locked.
2358 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
2359 unsigned int *soacount, isc_uint32_t *serial,
2360 isc_uint32_t *refresh, isc_uint32_t *retry,
2361 isc_uint32_t *expire, isc_uint32_t *minimum,
2362 unsigned int *errors)
2364 dns_dbversion_t *version;
2365 isc_result_t result;
2366 isc_result_t answer = ISC_R_SUCCESS;
2369 REQUIRE(db != NULL);
2370 REQUIRE(zone != NULL);
2373 dns_db_currentversion(db, &version);
2376 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2377 if (result != ISC_R_SUCCESS) {
2382 if (nscount != NULL || errors != NULL) {
2383 result = zone_count_ns_rr(zone, db, node, version,
2385 if (result != ISC_R_SUCCESS)
2389 if (soacount != NULL || serial != NULL || refresh != NULL
2390 || retry != NULL || expire != NULL || minimum != NULL) {
2391 result = zone_load_soa_rr(db, node, version, soacount,
2392 serial, refresh, retry, expire,
2394 if (result != ISC_R_SUCCESS)
2398 dns_db_detachnode(db, &node);
2400 dns_db_closeversion(db, &version, ISC_FALSE);
2406 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
2407 REQUIRE(DNS_ZONE_VALID(source));
2408 REQUIRE(target != NULL && *target == NULL);
2409 isc_refcount_increment(&source->erefs, NULL);
2414 dns_zone_detach(dns_zone_t **zonep) {
2417 isc_boolean_t free_now = ISC_FALSE;
2419 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2423 isc_refcount_decrement(&zone->erefs, &refs);
2428 * We just detached the last external reference.
2430 if (zone->task != NULL) {
2432 * This zone is being managed. Post
2433 * its control event and let it clean
2434 * up synchronously in the context of
2437 isc_event_t *ev = &zone->ctlevent;
2438 isc_task_send(zone->task, &ev);
2441 * This zone is not being managed; it has
2442 * no task and can have no outstanding
2443 * events. Free it immediately.
2446 * Unmanaged zones should not have non-null views;
2447 * we have no way of detaching from the view here
2448 * without causing deadlock because this code is called
2449 * with the view already locked.
2451 INSIST(zone->view == NULL);
2452 free_now = ISC_TRUE;
2462 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
2463 REQUIRE(DNS_ZONE_VALID(source));
2464 REQUIRE(target != NULL && *target == NULL);
2466 zone_iattach(source, target);
2467 UNLOCK_ZONE(source);
2471 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
2474 * 'source' locked by caller.
2476 REQUIRE(LOCKED_ZONE(source));
2477 REQUIRE(DNS_ZONE_VALID(source));
2478 REQUIRE(target != NULL && *target == NULL);
2479 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
2481 INSIST(source->irefs != 0);
2486 zone_idetach(dns_zone_t **zonep) {
2490 * 'zone' locked by caller.
2492 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2494 REQUIRE(LOCKED_ZONE(*zonep));
2497 INSIST(zone->irefs > 0);
2499 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
2503 dns_zone_idetach(dns_zone_t **zonep) {
2505 isc_boolean_t free_needed;
2507 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
2512 INSIST(zone->irefs > 0);
2514 free_needed = exit_check(zone);
2521 dns_zone_getmctx(dns_zone_t *zone) {
2522 REQUIRE(DNS_ZONE_VALID(zone));
2524 return (zone->mctx);
2528 dns_zone_getmgr(dns_zone_t *zone) {
2529 REQUIRE(DNS_ZONE_VALID(zone));
2531 return (zone->zmgr);
2535 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
2536 REQUIRE(DNS_ZONE_VALID(zone));
2540 DNS_ZONE_SETFLAG(zone, flags);
2542 DNS_ZONE_CLRFLAG(zone, flags);
2547 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
2549 REQUIRE(DNS_ZONE_VALID(zone));
2553 zone->options |= option;
2555 zone->options &= ~option;
2560 dns_zone_getoptions(dns_zone_t *zone) {
2562 REQUIRE(DNS_ZONE_VALID(zone));
2564 return (zone->options);
2568 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
2569 REQUIRE(DNS_ZONE_VALID(zone));
2572 zone->xfrsource4 = *xfrsource;
2575 return (ISC_R_SUCCESS);
2579 dns_zone_getxfrsource4(dns_zone_t *zone) {
2580 REQUIRE(DNS_ZONE_VALID(zone));
2581 return (&zone->xfrsource4);
2585 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
2586 REQUIRE(DNS_ZONE_VALID(zone));
2589 zone->xfrsource6 = *xfrsource;
2592 return (ISC_R_SUCCESS);
2596 dns_zone_getxfrsource6(dns_zone_t *zone) {
2597 REQUIRE(DNS_ZONE_VALID(zone));
2598 return (&zone->xfrsource6);
2602 dns_zone_setaltxfrsource4(dns_zone_t *zone,
2603 const isc_sockaddr_t *altxfrsource)
2605 REQUIRE(DNS_ZONE_VALID(zone));
2608 zone->altxfrsource4 = *altxfrsource;
2611 return (ISC_R_SUCCESS);
2615 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
2616 REQUIRE(DNS_ZONE_VALID(zone));
2617 return (&zone->altxfrsource4);
2621 dns_zone_setaltxfrsource6(dns_zone_t *zone,
2622 const isc_sockaddr_t *altxfrsource)
2624 REQUIRE(DNS_ZONE_VALID(zone));
2627 zone->altxfrsource6 = *altxfrsource;
2630 return (ISC_R_SUCCESS);
2634 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
2635 REQUIRE(DNS_ZONE_VALID(zone));
2636 return (&zone->altxfrsource6);
2640 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
2641 REQUIRE(DNS_ZONE_VALID(zone));
2644 zone->notifysrc4 = *notifysrc;
2647 return (ISC_R_SUCCESS);
2651 dns_zone_getnotifysrc4(dns_zone_t *zone) {
2652 REQUIRE(DNS_ZONE_VALID(zone));
2653 return (&zone->notifysrc4);
2657 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
2658 REQUIRE(DNS_ZONE_VALID(zone));
2661 zone->notifysrc6 = *notifysrc;
2664 return (ISC_R_SUCCESS);
2668 dns_zone_getnotifysrc6(dns_zone_t *zone) {
2669 REQUIRE(DNS_ZONE_VALID(zone));
2670 return (&zone->notifysrc6);
2674 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
2677 isc_sockaddr_t *new;
2679 REQUIRE(DNS_ZONE_VALID(zone));
2680 REQUIRE(count == 0 || notify != NULL);
2683 if (zone->notify != NULL) {
2684 isc_mem_put(zone->mctx, zone->notify,
2685 zone->notifycnt * sizeof(*new));
2686 zone->notify = NULL;
2687 zone->notifycnt = 0;
2690 new = isc_mem_get(zone->mctx, count * sizeof(*new));
2693 return (ISC_R_NOMEMORY);
2695 memcpy(new, notify, count * sizeof(*new));
2697 zone->notifycnt = count;
2700 return (ISC_R_SUCCESS);
2704 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
2707 isc_result_t result;
2709 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
2713 static isc_boolean_t
2714 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
2719 for (i = 0; i < count; i++)
2720 if (!isc_sockaddr_equal(&old[i], &new[i]))
2725 static isc_boolean_t
2726 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
2729 if (old == NULL && new == NULL)
2731 if (old == NULL || new == NULL)
2734 for (i = 0; i < count; i++) {
2735 if (old[i] == NULL && new[i] == NULL)
2737 if (old[i] == NULL || new[i] == NULL ||
2738 !dns_name_equal(old[i], new[i]))
2745 dns_zone_setmasterswithkeys(dns_zone_t *zone,
2746 const isc_sockaddr_t *masters,
2747 dns_name_t **keynames,
2750 isc_sockaddr_t *new;
2751 isc_result_t result = ISC_R_SUCCESS;
2752 dns_name_t **newname;
2753 isc_boolean_t *newok;
2756 REQUIRE(DNS_ZONE_VALID(zone));
2757 REQUIRE(count == 0 || masters != NULL);
2758 if (keynames != NULL) {
2759 REQUIRE(count != 0);
2764 * The refresh code assumes that 'masters' wouldn't change under it.
2765 * If it will change then kill off any current refresh in progress
2766 * and update the masters info. If it won't change then we can just
2769 if (count != zone->masterscnt ||
2770 !same_masters(zone->masters, masters, count) ||
2771 !same_keynames(zone->masterkeynames, keynames, count)) {
2772 if (zone->request != NULL)
2773 dns_request_cancel(zone->request);
2776 if (zone->masters != NULL) {
2777 isc_mem_put(zone->mctx, zone->masters,
2778 zone->masterscnt * sizeof(*new));
2779 zone->masters = NULL;
2781 if (zone->masterkeynames != NULL) {
2782 for (i = 0; i < zone->masterscnt; i++) {
2783 if (zone->masterkeynames[i] != NULL) {
2784 dns_name_free(zone->masterkeynames[i],
2786 isc_mem_put(zone->mctx,
2787 zone->masterkeynames[i],
2788 sizeof(dns_name_t));
2789 zone->masterkeynames[i] = NULL;
2792 isc_mem_put(zone->mctx, zone->masterkeynames,
2793 zone->masterscnt * sizeof(dns_name_t *));
2794 zone->masterkeynames = NULL;
2796 if (zone->mastersok != NULL) {
2797 isc_mem_put(zone->mctx, zone->mastersok,
2798 zone->masterscnt * sizeof(isc_boolean_t));
2799 zone->mastersok = NULL;
2801 zone->masterscnt = 0;
2803 * If count == 0, don't allocate any space for masters, mastersok or
2804 * keynames so internally, those pointers are NULL if count == 0
2810 * masters must countain count elements!
2812 new = isc_mem_get(zone->mctx, count * sizeof(*new));
2814 result = ISC_R_NOMEMORY;
2817 memcpy(new, masters, count * sizeof(*new));
2820 * Similarly for mastersok.
2822 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
2823 if (newok == NULL) {
2824 result = ISC_R_NOMEMORY;
2825 isc_mem_put(zone->mctx, new, count * sizeof(*new));
2828 for (i = 0; i < count; i++)
2829 newok[i] = ISC_FALSE;
2832 * if keynames is non-NULL, it must contain count elements!
2835 if (keynames != NULL) {
2836 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
2837 if (newname == NULL) {
2838 result = ISC_R_NOMEMORY;
2839 isc_mem_put(zone->mctx, new, count * sizeof(*new));
2840 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
2843 for (i = 0; i < count; i++)
2845 for (i = 0; i < count; i++) {
2846 if (keynames[i] != NULL) {
2847 newname[i] = isc_mem_get(zone->mctx,
2848 sizeof(dns_name_t));
2849 if (newname[i] == NULL)
2851 dns_name_init(newname[i], NULL);
2852 result = dns_name_dup(keynames[i], zone->mctx,
2854 if (result != ISC_R_SUCCESS) {
2856 for (i = 0; i < count; i++)
2857 if (newname[i] != NULL)
2861 isc_mem_put(zone->mctx, new,
2862 count * sizeof(*new));
2863 isc_mem_put(zone->mctx, newok,
2864 count * sizeof(*newok));
2865 isc_mem_put(zone->mctx, newname,
2866 count * sizeof(*newname));
2874 * Everything is ok so attach to the zone.
2876 zone->masters = new;
2877 zone->mastersok = newok;
2878 zone->masterkeynames = newname;
2879 zone->masterscnt = count;
2880 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
2888 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
2889 isc_result_t result = ISC_R_SUCCESS;
2891 REQUIRE(DNS_ZONE_VALID(zone));
2893 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2894 if (zone->db == NULL)
2895 result = DNS_R_NOTLOADED;
2897 dns_db_attach(zone->db, dpb);
2898 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2904 * Co-ordinates the starting of routine jobs.
2908 dns_zone_maintenance(dns_zone_t *zone) {
2909 const char me[] = "dns_zone_maintenance";
2912 REQUIRE(DNS_ZONE_VALID(zone));
2917 zone_settimer(zone, &now);
2921 static inline isc_boolean_t
2922 was_dumping(dns_zone_t *zone) {
2923 isc_boolean_t dumping;
2925 REQUIRE(LOCKED_ZONE(zone));
2927 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
2928 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
2930 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
2931 isc_time_settoepoch(&zone->dumptime);
2937 zone_maintenance(dns_zone_t *zone) {
2938 const char me[] = "zone_maintenance";
2940 isc_result_t result;
2941 isc_boolean_t dumping;
2943 REQUIRE(DNS_ZONE_VALID(zone));
2947 * Configuring the view of this zone may have
2948 * failed, for example because the config file
2949 * had a syntax error. In that case, the view
2950 * adb or resolver, and we had better not try
2951 * to do maintenance on it.
2953 if (zone->view == NULL || zone->view->adb == NULL)
2961 switch (zone->type) {
2962 case dns_zone_slave:
2965 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
2966 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
2968 zone->refreshtime = now;
2979 switch (zone->type) {
2980 case dns_zone_slave:
2982 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
2983 isc_time_compare(&now, &zone->refreshtime) >= 0)
2984 dns_zone_refresh(zone);
2991 * Do we need to consolidate the backing store?
2993 switch (zone->type) {
2994 case dns_zone_master:
2995 case dns_zone_slave:
2997 if (zone->masterfile != NULL &&
2998 isc_time_compare(&now, &zone->dumptime) >= 0 &&
2999 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
3000 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
3001 dumping = was_dumping(zone);
3006 result = zone_dump(zone, ISC_TRUE); /* task locked */
3007 if (result != ISC_R_SUCCESS)
3008 dns_zone_log(zone, ISC_LOG_WARNING,
3010 dns_result_totext(result));
3018 * Do we need to send out notify messages?
3020 switch (zone->type) {
3021 case dns_zone_master:
3022 case dns_zone_slave:
3023 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
3024 isc_time_compare(&now, &zone->notifytime) >= 0)
3025 zone_notify(zone, &now);
3030 zone_settimer(zone, &now);
3034 dns_zone_markdirty(dns_zone_t *zone) {
3037 zone_needdump(zone, DNS_DUMP_DELAY);
3042 dns_zone_expire(dns_zone_t *zone) {
3043 REQUIRE(DNS_ZONE_VALID(zone));
3051 zone_expire(dns_zone_t *zone) {
3053 * 'zone' locked by caller.
3056 REQUIRE(LOCKED_ZONE(zone));
3058 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
3060 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
3061 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
3062 zone->retry = DNS_ZONE_DEFAULTRETRY;
3063 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
3068 dns_zone_refresh(dns_zone_t *zone) {
3070 isc_uint32_t oldflags;
3072 isc_result_t result;
3074 REQUIRE(DNS_ZONE_VALID(zone));
3076 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
3080 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
3081 * in progress at a time.
3085 oldflags = zone->flags;
3086 if (zone->masterscnt == 0) {
3087 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
3088 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
3089 dns_zone_log(zone, ISC_LOG_ERROR,
3090 "cannot refresh: no masters");
3093 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
3094 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
3095 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
3096 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
3100 * Set the next refresh time as if refresh check has failed.
3101 * Setting this to the retry time will do that. XXXMLG
3102 * If we are successful it will be reset using zone->refresh.
3104 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
3106 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
3107 if (result |= ISC_R_SUCCESS)
3108 dns_zone_log(zone, ISC_LOG_WARNING,
3109 "isc_time_nowplusinterval() failed: %s",
3110 dns_result_totext(result));
3113 * When lacking user-specified timer values from the SOA,
3114 * do exponential backoff of the retry time up to a
3115 * maximum of six hours.
3117 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
3118 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
3120 zone->curmaster = 0;
3121 for (j = 0; j < zone->masterscnt; j++)
3122 zone->mastersok[j] = ISC_FALSE;
3123 /* initiate soa query */
3124 queue_soa_query(zone);
3130 dns_zone_flush(dns_zone_t *zone) {
3131 isc_result_t result = ISC_R_SUCCESS;
3132 isc_boolean_t dumping;
3134 REQUIRE(DNS_ZONE_VALID(zone));
3137 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
3138 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3139 zone->masterfile != NULL) {
3140 result = ISC_R_ALREADYRUNNING;
3141 dumping = was_dumping(zone);
3146 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
3151 dns_zone_dump(dns_zone_t *zone) {
3152 isc_result_t result = ISC_R_ALREADYRUNNING;
3153 isc_boolean_t dumping;
3155 REQUIRE(DNS_ZONE_VALID(zone));
3158 dumping = was_dumping(zone);
3161 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
3166 zone_needdump(dns_zone_t *zone, unsigned int delay) {
3167 isc_time_t dumptime;
3171 * 'zone' locked by caller
3174 REQUIRE(DNS_ZONE_VALID(zone));
3175 REQUIRE(LOCKED_ZONE(zone));
3178 * Do we have a place to dump to and are we loaded?
3180 if (zone->masterfile == NULL ||
3181 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
3185 /* add some noise */
3186 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
3188 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3189 if (isc_time_isepoch(&zone->dumptime) ||
3190 isc_time_compare(&zone->dumptime, &dumptime) > 0)
3191 zone->dumptime = dumptime;
3192 if (zone->task != NULL)
3193 zone_settimer(zone, &now);
3197 dump_done(void *arg, isc_result_t result) {
3198 const char me[] = "dump_done";
3199 dns_zone_t *zone = arg;
3201 dns_dbversion_t *version;
3202 isc_boolean_t again = ISC_FALSE;
3203 isc_boolean_t compact = ISC_FALSE;
3204 isc_uint32_t serial;
3205 isc_result_t tresult;
3207 REQUIRE(DNS_ZONE_VALID(zone));
3211 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
3212 zone->journalsize != -1) {
3215 * We don't own these, zone->dctx must stay valid.
3217 db = dns_dumpctx_db(zone->dctx);
3218 version = dns_dumpctx_version(zone->dctx);
3220 tresult = dns_db_getsoaserial(db, version, &serial);
3222 * Note: we are task locked here so we can test
3225 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
3226 tresult = dns_journal_compact(zone->mctx,
3233 case ISC_R_NOTFOUND:
3234 dns_zone_log(zone, ISC_LOG_DEBUG(3),
3235 "dns_journal_compact: %s",
3236 dns_result_totext(tresult));
3239 dns_zone_log(zone, ISC_LOG_ERROR,
3240 "dns_journal_compact failed: %s",
3241 dns_result_totext(tresult));
3244 } else if (tresult == ISC_R_SUCCESS) {
3246 zone->compact_serial = serial;
3251 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
3253 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
3254 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
3256 * Try again in a short while.
3258 zone_needdump(zone, DNS_DUMP_DELAY);
3259 } else if (result == ISC_R_SUCCESS &&
3260 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
3261 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3262 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3263 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3264 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3265 isc_time_settoepoch(&zone->dumptime);
3267 } else if (result == ISC_R_SUCCESS)
3268 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
3270 if (zone->dctx != NULL)
3271 dns_dumpctx_detach(&zone->dctx);
3272 zonemgr_putio(&zone->writeio);
3275 (void)zone_dump(zone, ISC_FALSE);
3276 dns_zone_idetach(&zone);
3280 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
3281 const char me[] = "zone_dump";
3282 isc_result_t result;
3283 dns_dbversion_t *version = NULL;
3284 isc_boolean_t again;
3285 dns_db_t *db = NULL;
3286 char *masterfile = NULL;
3287 dns_masterformat_t masterformat = dns_masterformat_none;
3290 * 'compact' MUST only be set if we are task locked.
3293 REQUIRE(DNS_ZONE_VALID(zone));
3297 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3298 if (zone->db != NULL)
3299 dns_db_attach(zone->db, &db);
3300 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3302 if (zone->masterfile != NULL) {
3303 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
3304 masterformat = zone->masterformat;
3308 result = DNS_R_NOTLOADED;
3311 if (masterfile == NULL) {
3312 result = DNS_R_NOMASTERFILE;
3317 dns_zone_t *dummy = NULL;
3319 zone_iattach(zone, &dummy);
3320 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
3321 zone_gotwritehandle, zone,
3323 if (result != ISC_R_SUCCESS)
3324 zone_idetach(&dummy);
3326 result = DNS_R_CONTINUE;
3329 dns_db_currentversion(db, &version);
3330 result = dns_master_dump2(zone->mctx, db, version,
3331 &dns_master_style_default,
3332 masterfile, masterformat);
3333 dns_db_closeversion(db, &version, ISC_FALSE);
3338 if (masterfile != NULL)
3339 isc_mem_free(zone->mctx, masterfile);
3342 if (result == DNS_R_CONTINUE)
3343 return (ISC_R_SUCCESS); /* XXXMPA */
3347 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
3348 if (result != ISC_R_SUCCESS) {
3350 * Try again in a short while.
3352 zone_needdump(zone, DNS_DUMP_DELAY);
3353 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
3354 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
3355 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3356 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3357 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
3358 isc_time_settoepoch(&zone->dumptime);
3361 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
3370 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
3371 dns_masterformat_t format)
3373 isc_result_t result;
3374 dns_dbversion_t *version = NULL;
3375 dns_db_t *db = NULL;
3377 REQUIRE(DNS_ZONE_VALID(zone));
3379 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3380 if (zone->db != NULL)
3381 dns_db_attach(zone->db, &db);
3382 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3384 return (DNS_R_NOTLOADED);
3386 dns_db_currentversion(db, &version);
3387 result = dns_master_dumptostream2(zone->mctx, db, version, style,
3389 dns_db_closeversion(db, &version, ISC_FALSE);
3395 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
3396 const dns_master_style_t *style) {
3397 return dumptostream(zone, fd, style, format);
3401 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
3402 return dumptostream(zone, fd, &dns_master_style_default,
3403 dns_masterformat_text);
3407 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
3408 return dumptostream(zone, fd, &dns_master_style_full,
3409 dns_masterformat_text);
3413 dns_zone_unload(dns_zone_t *zone) {
3414 REQUIRE(DNS_ZONE_VALID(zone));
3422 notify_cancel(dns_zone_t *zone) {
3423 dns_notify_t *notify;
3426 * 'zone' locked by caller.
3429 REQUIRE(LOCKED_ZONE(zone));
3431 for (notify = ISC_LIST_HEAD(zone->notifies);
3433 notify = ISC_LIST_NEXT(notify, link)) {
3434 if (notify->find != NULL)
3435 dns_adb_cancelfind(notify->find);
3436 if (notify->request != NULL)
3437 dns_request_cancel(notify->request);
3442 zone_unload(dns_zone_t *zone) {
3445 * 'zone' locked by caller.
3448 REQUIRE(LOCKED_ZONE(zone));
3450 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
3451 zone_detachdb(zone);
3452 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3453 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
3454 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
3458 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
3459 REQUIRE(DNS_ZONE_VALID(zone));
3462 zone->minrefresh = val;
3466 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
3467 REQUIRE(DNS_ZONE_VALID(zone));
3470 zone->maxrefresh = val;
3474 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
3475 REQUIRE(DNS_ZONE_VALID(zone));
3478 zone->minretry = val;
3482 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
3483 REQUIRE(DNS_ZONE_VALID(zone));
3486 zone->maxretry = val;
3489 static isc_boolean_t
3490 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
3491 dns_notify_t *notify;
3493 for (notify = ISC_LIST_HEAD(zone->notifies);
3495 notify = ISC_LIST_NEXT(notify, link)) {
3496 if (notify->request != NULL)
3498 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
3499 dns_name_equal(name, ¬ify->ns))
3501 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
3507 static isc_boolean_t
3508 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
3509 dns_tsigkey_t *key = NULL;
3512 isc_boolean_t isself;
3513 isc_netaddr_t dstaddr;
3515 if (zone->view == NULL || zone->isself == NULL)
3518 switch (isc_sockaddr_pf(dst)) {
3520 src = zone->notifysrc4;
3521 isc_sockaddr_any(&any);
3524 src = zone->notifysrc6;
3525 isc_sockaddr_any6(&any);
3532 * When sending from any the kernel will assign a source address
3533 * that matches the destination address.
3535 if (isc_sockaddr_eqaddr(&any, &src))
3538 isc_netaddr_fromsockaddr(&dstaddr, dst);
3539 (void)dns_view_getpeertsig(zone->view, &dstaddr, &key);
3540 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
3543 dns_tsigkey_detach(&key);
3548 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
3552 * Caller holds zone lock.
3554 REQUIRE(DNS_NOTIFY_VALID(notify));
3556 if (notify->zone != NULL) {
3558 LOCK_ZONE(notify->zone);
3559 REQUIRE(LOCKED_ZONE(notify->zone));
3560 if (ISC_LINK_LINKED(notify, link))
3561 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
3563 UNLOCK_ZONE(notify->zone);
3565 zone_idetach(¬ify->zone);
3567 dns_zone_idetach(¬ify->zone);
3569 if (notify->find != NULL)
3570 dns_adb_destroyfind(¬ify->find);
3571 if (notify->request != NULL)
3572 dns_request_destroy(¬ify->request);
3573 if (dns_name_dynamic(¬ify->ns))
3574 dns_name_free(¬ify->ns, notify->mctx);
3575 mctx = notify->mctx;
3576 isc_mem_put(notify->mctx, notify, sizeof(*notify));
3577 isc_mem_detach(&mctx);
3581 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
3582 dns_notify_t *notify;
3584 REQUIRE(notifyp != NULL && *notifyp == NULL);
3586 notify = isc_mem_get(mctx, sizeof(*notify));
3588 return (ISC_R_NOMEMORY);
3590 notify->mctx = NULL;
3591 isc_mem_attach(mctx, ¬ify->mctx);
3592 notify->flags = flags;
3593 notify->zone = NULL;
3594 notify->find = NULL;
3595 notify->request = NULL;
3596 isc_sockaddr_any(¬ify->dst);
3597 dns_name_init(¬ify->ns, NULL);
3598 ISC_LINK_INIT(notify, link);
3599 notify->magic = NOTIFY_MAGIC;
3601 return (ISC_R_SUCCESS);
3605 * XXXAG should check for DNS_ZONEFLG_EXITING
3608 process_adb_event(isc_task_t *task, isc_event_t *ev) {
3609 dns_notify_t *notify;
3610 isc_eventtype_t result;
3614 notify = ev->ev_arg;
3615 REQUIRE(DNS_NOTIFY_VALID(notify));
3616 INSIST(task == notify->zone->task);
3617 result = ev->ev_type;
3618 isc_event_free(&ev);
3619 if (result == DNS_EVENT_ADBMOREADDRESSES) {
3620 dns_adb_destroyfind(¬ify->find);
3621 notify_find_address(notify);
3624 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
3625 LOCK_ZONE(notify->zone);
3626 notify_send(notify);
3627 UNLOCK_ZONE(notify->zone);
3629 notify_destroy(notify, ISC_FALSE);
3633 notify_find_address(dns_notify_t *notify) {
3634 isc_result_t result;
3635 unsigned int options;
3637 REQUIRE(DNS_NOTIFY_VALID(notify));
3638 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
3639 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
3641 if (notify->zone->view->adb == NULL)
3644 result = dns_adb_createfind(notify->zone->view->adb,
3646 process_adb_event, notify,
3647 ¬ify->ns, dns_rootname, 0,
3649 notify->zone->view->dstport,
3652 /* Something failed? */
3653 if (result != ISC_R_SUCCESS)
3656 /* More addresses pending? */
3657 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
3660 /* We have as many addresses as we can get. */
3661 LOCK_ZONE(notify->zone);
3662 notify_send(notify);
3663 UNLOCK_ZONE(notify->zone);
3666 notify_destroy(notify, ISC_FALSE);
3671 notify_send_queue(dns_notify_t *notify) {
3673 isc_result_t result;
3675 e = isc_event_allocate(notify->mctx, NULL,
3676 DNS_EVENT_NOTIFYSENDTOADDR,
3678 notify, sizeof(isc_event_t));
3680 return (ISC_R_NOMEMORY);
3682 e->ev_sender = NULL;
3683 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
3684 notify->zone->task, &e);
3685 if (result != ISC_R_SUCCESS)
3691 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
3692 dns_notify_t *notify;
3693 isc_result_t result;
3694 dns_message_t *message = NULL;
3695 isc_netaddr_t dstip;
3696 dns_tsigkey_t *key = NULL;
3697 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
3700 isc_boolean_t have_notifysource = ISC_FALSE;
3702 notify = event->ev_arg;
3703 REQUIRE(DNS_NOTIFY_VALID(notify));
3707 LOCK_ZONE(notify->zone);
3709 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
3710 result = ISC_R_CANCELED;
3714 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
3715 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
3716 notify->zone->view->requestmgr == NULL ||
3717 notify->zone->db == NULL) {
3718 result = ISC_R_CANCELED;
3723 * The raw IPv4 address should also exist. Don't send to the
3726 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
3727 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
3728 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
3729 notify_log(notify->zone, ISC_LOG_DEBUG(3),
3730 "notify: ignoring IPv6 mapped IPV4 address: %s",
3732 result = ISC_R_CANCELED;
3736 result = notify_createmessage(notify->zone, notify->flags, &message);
3737 if (result != ISC_R_SUCCESS)
3740 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
3741 (void)dns_view_getpeertsig(notify->zone->view, &dstip, &key);
3743 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
3744 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
3746 if (notify->zone->view->peers != NULL) {
3747 dns_peer_t *peer = NULL;
3748 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
3750 if (result == ISC_R_SUCCESS) {
3751 result = dns_peer_getnotifysource(peer, &src);
3752 if (result == ISC_R_SUCCESS)
3753 have_notifysource = ISC_TRUE;
3756 switch (isc_sockaddr_pf(¬ify->dst)) {
3758 if (!have_notifysource)
3759 src = notify->zone->notifysrc4;
3762 if (!have_notifysource)
3763 src = notify->zone->notifysrc6;
3766 result = ISC_R_NOTIMPLEMENTED;
3770 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
3772 result = dns_request_createvia2(notify->zone->view->requestmgr,
3773 message, &src, ¬ify->dst, 0, key,
3774 timeout * 3, timeout,
3775 notify->zone->task, notify_done,
3776 notify, ¬ify->request);
3779 dns_tsigkey_detach(&key);
3780 dns_message_destroy(&message);
3782 UNLOCK_ZONE(notify->zone);
3783 if (result != ISC_R_SUCCESS)
3784 notify_destroy(notify, ISC_FALSE);
3785 isc_event_free(&event);
3789 notify_send(dns_notify_t *notify) {
3790 dns_adbaddrinfo_t *ai;
3792 isc_result_t result;
3793 dns_notify_t *new = NULL;
3796 * Zone lock held by caller.
3798 REQUIRE(DNS_NOTIFY_VALID(notify));
3799 REQUIRE(LOCKED_ZONE(notify->zone));
3801 for (ai = ISC_LIST_HEAD(notify->find->list);
3803 ai = ISC_LIST_NEXT(ai, publink)) {
3805 if (notify_isqueued(notify->zone, NULL, &dst))
3807 if (notify_isself(notify->zone, &dst))
3810 result = notify_create(notify->mctx,
3811 (notify->flags & DNS_NOTIFY_NOSOA),
3813 if (result != ISC_R_SUCCESS)
3815 zone_iattach(notify->zone, &new->zone);
3816 ISC_LIST_APPEND(new->zone->notifies, new, link);
3818 result = notify_send_queue(new);
3819 if (result != ISC_R_SUCCESS)
3826 notify_destroy(new, ISC_TRUE);
3830 dns_zone_notify(dns_zone_t *zone) {
3833 REQUIRE(DNS_ZONE_VALID(zone));
3836 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
3839 zone_settimer(zone, &now);
3844 zone_notify(dns_zone_t *zone, isc_time_t *now) {
3845 dns_dbnode_t *node = NULL;
3846 dns_db_t *zonedb = NULL;
3847 dns_dbversion_t *version = NULL;
3848 dns_name_t *origin = NULL;
3851 dns_rdata_soa_t soa;
3852 isc_uint32_t serial;
3853 dns_rdata_t rdata = DNS_RDATA_INIT;
3854 dns_rdataset_t nsrdset;
3855 dns_rdataset_t soardset;
3856 isc_result_t result;
3857 dns_notify_t *notify = NULL;
3860 isc_boolean_t isqueued;
3861 dns_notifytype_t notifytype;
3862 unsigned int flags = 0;
3863 isc_boolean_t loggednotify = ISC_FALSE;
3865 REQUIRE(DNS_ZONE_VALID(zone));
3868 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
3869 notifytype = zone->notifytype;
3870 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
3873 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
3876 if (notifytype == dns_notifytype_no)
3879 if (notifytype == dns_notifytype_masteronly &&
3880 zone->type != dns_zone_master)
3883 origin = &zone->origin;
3886 * If the zone is dialup we are done as we don't want to send
3887 * the current soa so as to force a refresh query.
3889 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
3890 flags |= DNS_NOTIFY_NOSOA;
3895 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3896 if (zone->db != NULL)
3897 dns_db_attach(zone->db, &zonedb);
3898 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3901 dns_db_currentversion(zonedb, &version);
3902 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
3903 if (result != ISC_R_SUCCESS)
3906 dns_rdataset_init(&soardset);
3907 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
3908 dns_rdatatype_none, 0, &soardset, NULL);
3909 if (result != ISC_R_SUCCESS)
3913 * Find serial and master server's name.
3915 dns_name_init(&master, NULL);
3916 result = dns_rdataset_first(&soardset);
3917 if (result != ISC_R_SUCCESS)
3919 dns_rdataset_current(&soardset, &rdata);
3920 result = dns_rdata_tostruct(&rdata, &soa, NULL);
3921 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3922 dns_rdata_reset(&rdata);
3923 result = dns_name_dup(&soa.origin, zone->mctx, &master);
3924 serial = soa.serial;
3925 dns_rdataset_disassociate(&soardset);
3926 if (result != ISC_R_SUCCESS)
3930 * Enqueue notify requests for 'also-notify' servers.
3933 for (i = 0; i < zone->notifycnt; i++) {
3934 dst = zone->notify[i];
3935 if (notify_isqueued(zone, NULL, &dst))
3937 result = notify_create(zone->mctx, flags, ¬ify);
3938 if (result != ISC_R_SUCCESS)
3940 zone_iattach(zone, ¬ify->zone);
3942 ISC_LIST_APPEND(zone->notifies, notify, link);
3943 result = notify_send_queue(notify);
3944 if (result != ISC_R_SUCCESS)
3945 notify_destroy(notify, ISC_TRUE);
3946 if (!loggednotify) {
3947 notify_log(zone, ISC_LOG_INFO,
3948 "sending notifies (serial %u)",
3950 loggednotify = ISC_TRUE;
3956 if (notifytype == dns_notifytype_explicit)
3960 * Process NS RRset to generate notifies.
3963 dns_rdataset_init(&nsrdset);
3964 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
3965 dns_rdatatype_none, 0, &nsrdset, NULL);
3966 if (result != ISC_R_SUCCESS)
3969 result = dns_rdataset_first(&nsrdset);
3970 while (result == ISC_R_SUCCESS) {
3971 dns_rdataset_current(&nsrdset, &rdata);
3972 result = dns_rdata_tostruct(&rdata, &ns, NULL);
3973 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3974 dns_rdata_reset(&rdata);
3976 * don't notify the master server.
3978 if (dns_name_compare(&master, &ns.name) == 0) {
3979 result = dns_rdataset_next(&nsrdset);
3983 if (!loggednotify) {
3984 notify_log(zone, ISC_LOG_INFO,
3985 "sending notifies (serial %u)",
3987 loggednotify = ISC_TRUE;
3991 isqueued = notify_isqueued(zone, &ns.name, NULL);
3994 result = dns_rdataset_next(&nsrdset);
3997 result = notify_create(zone->mctx, flags, ¬ify);
3998 if (result != ISC_R_SUCCESS)
4000 dns_zone_iattach(zone, ¬ify->zone);
4001 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
4002 if (result != ISC_R_SUCCESS) {
4004 notify_destroy(notify, ISC_TRUE);
4009 ISC_LIST_APPEND(zone->notifies, notify, link);
4011 notify_find_address(notify);
4013 result = dns_rdataset_next(&nsrdset);
4015 dns_rdataset_disassociate(&nsrdset);
4018 if (dns_name_dynamic(&master))
4019 dns_name_free(&master, zone->mctx);
4021 dns_db_detachnode(zonedb, &node);
4023 dns_db_closeversion(zonedb, &version, ISC_FALSE);
4024 dns_db_detach(&zonedb);
4031 static inline isc_result_t
4032 save_nsrrset(dns_message_t *message, dns_name_t *name,
4033 dns_db_t *db, dns_dbversion_t *version)
4035 dns_rdataset_t *nsrdataset = NULL;
4036 dns_rdataset_t *rdataset = NULL;
4037 dns_dbnode_t *node = NULL;
4039 isc_result_t result;
4040 dns_rdata_t rdata = DNS_RDATA_INIT;
4043 * Extract NS RRset from message.
4045 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
4046 dns_rdatatype_ns, dns_rdatatype_none,
4048 if (result != ISC_R_SUCCESS)
4054 result = dns_db_findnode(db, name, ISC_TRUE, &node);
4055 if (result != ISC_R_SUCCESS)
4057 result = dns_db_addrdataset(db, node, version, 0,
4058 nsrdataset, 0, NULL);
4059 dns_db_detachnode(db, &node);
4060 if (result != ISC_R_SUCCESS)
4063 * Add glue rdatasets.
4065 for (result = dns_rdataset_first(nsrdataset);
4066 result == ISC_R_SUCCESS;
4067 result = dns_rdataset_next(nsrdataset)) {
4068 dns_rdataset_current(nsrdataset, &rdata);
4069 result = dns_rdata_tostruct(&rdata, &ns, NULL);
4070 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4071 dns_rdata_reset(&rdata);
4072 if (!dns_name_issubdomain(&ns.name, name))
4075 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
4076 &ns.name, dns_rdatatype_aaaa,
4077 dns_rdatatype_none, NULL,
4079 if (result == ISC_R_SUCCESS) {
4080 result = dns_db_findnode(db, &ns.name,
4082 if (result != ISC_R_SUCCESS)
4084 result = dns_db_addrdataset(db, node, version, 0,
4086 dns_db_detachnode(db, &node);
4087 if (result != ISC_R_SUCCESS)
4091 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
4092 &ns.name, dns_rdatatype_a,
4093 dns_rdatatype_none, NULL,
4095 if (result == ISC_R_SUCCESS) {
4096 result = dns_db_findnode(db, &ns.name,
4098 if (result != ISC_R_SUCCESS)
4100 result = dns_db_addrdataset(db, node, version, 0,
4102 dns_db_detachnode(db, &node);
4103 if (result != ISC_R_SUCCESS)
4107 if (result != ISC_R_NOMORE)
4110 return (ISC_R_SUCCESS);
4117 stub_callback(isc_task_t *task, isc_event_t *event) {
4118 const char me[] = "stub_callback";
4119 dns_requestevent_t *revent = (dns_requestevent_t *)event;
4120 dns_stub_t *stub = NULL;
4121 dns_message_t *msg = NULL;
4122 dns_zone_t *zone = NULL;
4123 char master[ISC_SOCKADDR_FORMATSIZE];
4124 char source[ISC_SOCKADDR_FORMATSIZE];
4125 isc_uint32_t nscnt, cnamecnt;
4126 isc_result_t result;
4128 isc_boolean_t exiting = ISC_FALSE;
4132 stub = revent->ev_arg;
4133 INSIST(DNS_STUB_VALID(stub));
4143 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
4144 zone_debuglog(zone, me, 1, "exiting");
4149 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
4150 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
4152 if (revent->result != ISC_R_SUCCESS) {
4153 if (revent->result == ISC_R_TIMEDOUT &&
4154 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4156 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4158 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4159 "refreshing stub: timeout retrying "
4160 " without EDNS master %s (source %s)",
4164 dns_zone_log(zone, ISC_LOG_INFO,
4165 "could not refresh stub from master %s"
4166 " (source %s): %s", master, source,
4167 dns_result_totext(revent->result));
4171 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
4172 if (result != ISC_R_SUCCESS)
4175 result = dns_request_getresponse(revent->request, msg, 0);
4176 if (result != ISC_R_SUCCESS)
4182 if (msg->rcode != dns_rcode_noerror) {
4186 isc_buffer_init(&rb, rcode, sizeof(rcode));
4187 (void)dns_rcode_totext(msg->rcode, &rb);
4189 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
4190 (msg->rcode == dns_rcode_servfail ||
4191 msg->rcode == dns_rcode_notimp ||
4192 msg->rcode == dns_rcode_formerr)) {
4193 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4194 "refreshing stub: rcode (%.*s) retrying "
4195 "without EDNS master %s (source %s)",
4196 (int)rb.used, rcode, master, source);
4198 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4203 dns_zone_log(zone, ISC_LOG_INFO,
4205 "unexpected rcode (%.*s) from %s (source %s)",
4206 (int)rb.used, rcode, master, source);
4211 * We need complete messages.
4213 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
4214 if (dns_request_usedtcp(revent->request)) {
4215 dns_zone_log(zone, ISC_LOG_INFO,
4216 "refreshing stub: truncated TCP "
4217 "response from master %s (source %s)",
4222 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
4228 * If non-auth log and next master.
4230 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
4231 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
4232 "non-authoritative answer from "
4233 "master %s (source %s)", master, source);
4240 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
4241 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
4243 if (cnamecnt != 0) {
4244 dns_zone_log(zone, ISC_LOG_INFO,
4245 "refreshing stub: unexpected CNAME response "
4246 "from master %s (source %s)", master, source);
4251 dns_zone_log(zone, ISC_LOG_INFO,
4252 "refreshing stub: no NS records in response "
4253 "from master %s (source %s)", master, source);
4260 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
4261 if (result != ISC_R_SUCCESS) {
4262 dns_zone_log(zone, ISC_LOG_INFO,
4263 "refreshing stub: unable to save NS records "
4264 "from master %s (source %s)", master, source);
4271 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
4272 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4273 if (zone->db == NULL)
4274 zone_attachdb(zone, stub->db);
4275 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4276 dns_db_detach(&stub->db);
4278 if (zone->masterfile != NULL) {
4279 dns_zone_dump(zone);
4280 TIME_NOW(&zone->loadtime);
4283 dns_message_destroy(&msg);
4284 isc_event_free(&event);
4286 dns_request_destroy(&zone->request);
4287 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4288 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
4289 isc_interval_set(&i, zone->expire, 0);
4290 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
4291 zone_settimer(zone, &now);
4296 if (stub->version != NULL)
4297 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
4298 if (stub->db != NULL)
4299 dns_db_detach(&stub->db);
4301 dns_message_destroy(&msg);
4302 isc_event_free(&event);
4304 dns_request_destroy(&zone->request);
4306 * Skip to next failed / untried master.
4310 } while (zone->curmaster < zone->masterscnt &&
4311 zone->mastersok[zone->curmaster]);
4312 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
4313 if (exiting || zone->curmaster >= zone->masterscnt) {
4314 isc_boolean_t done = ISC_TRUE;
4316 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
4317 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4319 * Did we get a good answer from all the masters?
4321 for (j = 0; j < zone->masterscnt; j++)
4322 if (zone->mastersok[j] == ISC_FALSE) {
4329 zone->curmaster = 0;
4331 * Find the next failed master.
4333 while (zone->curmaster < zone->masterscnt &&
4334 zone->mastersok[zone->curmaster])
4336 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4338 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4340 zone_settimer(zone, &now);
4345 queue_soa_query(zone);
4351 dns_message_destroy(&msg);
4352 isc_event_free(&event);
4354 dns_request_destroy(&zone->request);
4356 ns_query(zone, NULL, stub);
4361 dns_zone_idetach(&stub->zone);
4362 INSIST(stub->db == NULL);
4363 INSIST(stub->version == NULL);
4364 isc_mem_put(stub->mctx, stub, sizeof(*stub));
4367 INSIST(event == NULL);
4372 * An SOA query has finished (successfully or not).
4375 refresh_callback(isc_task_t *task, isc_event_t *event) {
4376 const char me[] = "refresh_callback";
4377 dns_requestevent_t *revent = (dns_requestevent_t *)event;
4379 dns_message_t *msg = NULL;
4380 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
4382 char master[ISC_SOCKADDR_FORMATSIZE];
4383 char source[ISC_SOCKADDR_FORMATSIZE];
4384 dns_rdataset_t *rdataset = NULL;
4385 dns_rdata_t rdata = DNS_RDATA_INIT;
4386 dns_rdata_soa_t soa;
4387 isc_result_t result;
4388 isc_uint32_t serial;
4391 zone = revent->ev_arg;
4392 INSIST(DNS_ZONE_VALID(zone));
4399 * if timeout log and next master;
4402 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
4403 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
4407 if (revent->result != ISC_R_SUCCESS) {
4408 if (revent->result == ISC_R_TIMEDOUT &&
4409 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4411 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4413 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4414 "refresh: timeout retrying without EDNS "
4415 "master %s (source %s)", master, source);
4418 if (revent->result == ISC_R_TIMEDOUT &&
4419 !dns_request_usedtcp(revent->request)) {
4420 dns_zone_log(zone, ISC_LOG_INFO,
4421 "refresh: retry limit for "
4422 "master %s exceeded (source %s)",
4424 /* Try with slave with TCP. */
4425 if (zone->type == dns_zone_slave) {
4427 DNS_ZONE_SETFLAG(zone,
4428 DNS_ZONEFLG_SOABEFOREAXFR);
4433 dns_zone_log(zone, ISC_LOG_INFO,
4434 "refresh: failure trying master "
4435 "%s (source %s): %s", master, source,
4436 dns_result_totext(revent->result));
4440 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
4441 if (result != ISC_R_SUCCESS)
4443 result = dns_request_getresponse(revent->request, msg, 0);
4444 if (result != ISC_R_SUCCESS) {
4445 dns_zone_log(zone, ISC_LOG_INFO,
4446 "refresh: failure trying master "
4447 "%s (source %s): %s", master, source,
4448 dns_result_totext(result));
4455 if (msg->rcode != dns_rcode_noerror) {
4459 isc_buffer_init(&rb, rcode, sizeof(rcode));
4460 (void)dns_rcode_totext(msg->rcode, &rb);
4462 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
4463 (msg->rcode == dns_rcode_servfail ||
4464 msg->rcode == dns_rcode_notimp ||
4465 msg->rcode == dns_rcode_formerr)) {
4466 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4467 "refresh: rcode (%.*s) retrying without "
4468 "EDNS master %s (source %s)",
4469 (int)rb.used, rcode, master, source);
4471 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4475 dns_zone_log(zone, ISC_LOG_INFO,
4476 "refresh: unexpected rcode (%.*s) from "
4477 "master %s (source %s)", (int)rb.used, rcode,
4480 * Perhaps AXFR/IXFR is allowed even if SOA queries arn't.
4482 if (msg->rcode == dns_rcode_refused &&
4483 zone->type == dns_zone_slave)
4489 * If truncated punt to zone transfer which will query again.
4491 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
4492 if (zone->type == dns_zone_slave) {
4493 dns_zone_log(zone, ISC_LOG_INFO,
4494 "refresh: truncated UDP answer, "
4495 "initiating TCP zone xfer "
4496 "for master %s (source %s)",
4499 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
4503 INSIST(zone->type == dns_zone_stub);
4504 if (dns_request_usedtcp(revent->request)) {
4505 dns_zone_log(zone, ISC_LOG_INFO,
4506 "refresh: truncated TCP response "
4507 "from master %s (source %s)",
4512 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
4519 * if non-auth log and next master;
4521 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
4522 dns_zone_log(zone, ISC_LOG_INFO,
4523 "refresh: non-authoritative answer from "
4524 "master %s (source %s)", master, source);
4528 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
4529 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
4530 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
4531 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
4535 * There should not be a CNAME record at top of zone.
4537 if (cnamecnt != 0) {
4538 dns_zone_log(zone, ISC_LOG_INFO,
4539 "refresh: CNAME at top of zone "
4540 "in master %s (source %s)", master, source);
4545 * if referral log and next master;
4547 if (soacnt == 0 && soacount == 0 && nscount != 0) {
4548 dns_zone_log(zone, ISC_LOG_INFO,
4549 "refresh: referral response "
4550 "from master %s (source %s)", master, source);
4555 * if nodata log and next master;
4557 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
4558 dns_zone_log(zone, ISC_LOG_INFO,
4559 "refresh: NODATA response "
4560 "from master %s (source %s)", master, source);
4565 * Only one soa at top of zone.
4568 dns_zone_log(zone, ISC_LOG_INFO,
4569 "refresh: answer SOA count (%d) != 1 "
4570 "from master %s (source %s)",
4571 soacnt, master, source);
4578 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
4579 dns_rdatatype_soa, dns_rdatatype_none,
4581 if (result != ISC_R_SUCCESS) {
4582 dns_zone_log(zone, ISC_LOG_INFO,
4583 "refresh: unable to get SOA record "
4584 "from master %s (source %s)", master, source);
4588 result = dns_rdataset_first(rdataset);
4589 if (result != ISC_R_SUCCESS) {
4590 dns_zone_log(zone, ISC_LOG_INFO,
4591 "refresh: dns_rdataset_first() failed");
4595 dns_rdataset_current(rdataset, &rdata);
4596 result = dns_rdata_tostruct(&rdata, &soa, NULL);
4597 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4599 serial = soa.serial;
4601 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
4602 serial, zone->serial);
4603 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
4604 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
4605 isc_serial_gt(serial, zone->serial)) {
4607 isc_event_free(&event);
4609 dns_request_destroy(&zone->request);
4611 if (zone->type == dns_zone_slave) {
4614 INSIST(zone->type == dns_zone_stub);
4615 ns_query(zone, rdataset, NULL);
4618 dns_message_destroy(&msg);
4619 } else if (isc_serial_eq(soa.serial, zone->serial)) {
4620 if (zone->masterfile != NULL) {
4621 result = ISC_R_FAILURE;
4622 if (zone->journal != NULL)
4623 result = isc_file_settime(zone->journal, &now);
4624 if (result == ISC_R_SUCCESS &&
4625 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
4626 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
4627 result = isc_file_settime(zone->masterfile,
4629 } else if (result != ISC_R_SUCCESS)
4630 result = isc_file_settime(zone->masterfile,
4632 /* Someone removed the file from underneath us! */
4633 if (result == ISC_R_FILENOTFOUND) {
4635 zone_needdump(zone, DNS_DUMP_DELAY);
4637 } else if (result != ISC_R_SUCCESS)
4638 dns_zone_log(zone, ISC_LOG_ERROR,
4639 "refresh: could not set file "
4640 "modification time of '%s': %s",
4642 dns_result_totext(result));
4644 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
4645 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
4646 zone->mastersok[zone->curmaster] = ISC_TRUE;
4649 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
4650 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
4651 "received from master %s < ours (%u)",
4652 soa.serial, master, zone->serial);
4654 zone_debuglog(zone, me, 1, "ahead");
4655 zone->mastersok[zone->curmaster] = ISC_TRUE;
4659 dns_message_destroy(&msg);
4664 dns_message_destroy(&msg);
4665 isc_event_free(&event);
4667 dns_request_destroy(&zone->request);
4669 * Skip to next failed / untried master.
4673 } while (zone->curmaster < zone->masterscnt &&
4674 zone->mastersok[zone->curmaster]);
4675 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
4676 if (zone->curmaster >= zone->masterscnt) {
4677 isc_boolean_t done = ISC_TRUE;
4678 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
4679 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4681 * Did we get a good answer from all the masters?
4683 for (j = 0; j < zone->masterscnt; j++)
4684 if (zone->mastersok[j] == ISC_FALSE) {
4691 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4692 zone->curmaster = 0;
4694 * Find the next failed master.
4696 while (zone->curmaster < zone->masterscnt &&
4697 zone->mastersok[zone->curmaster])
4701 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
4702 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
4703 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
4704 zone->refreshtime = now;
4706 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
4707 zone_settimer(zone, &now);
4713 queue_soa_query(zone);
4719 dns_message_destroy(&msg);
4720 isc_event_free(&event);
4722 dns_request_destroy(&zone->request);
4723 queue_soa_query(zone);
4727 dns_zone_idetach(&zone);
4732 queue_soa_query(dns_zone_t *zone) {
4733 const char me[] = "queue_soa_query";
4735 dns_zone_t *dummy = NULL;
4736 isc_result_t result;
4742 REQUIRE(LOCKED_ZONE(zone));
4744 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
4745 cancel_refresh(zone);
4749 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
4750 soa_query, zone, sizeof(isc_event_t));
4752 cancel_refresh(zone);
4757 * Attach so that we won't clean up
4758 * until the event is delivered.
4760 zone_iattach(zone, &dummy);
4763 e->ev_sender = NULL;
4764 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
4765 if (result != ISC_R_SUCCESS) {
4766 zone_idetach(&dummy);
4768 cancel_refresh(zone);
4772 static inline isc_result_t
4773 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
4774 dns_message_t **messagep)
4776 dns_message_t *message = NULL;
4777 dns_name_t *qname = NULL;
4778 dns_rdataset_t *qrdataset = NULL;
4779 isc_result_t result;
4781 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
4783 if (result != ISC_R_SUCCESS)
4786 message->opcode = dns_opcode_query;
4787 message->rdclass = zone->rdclass;
4789 result = dns_message_gettempname(message, &qname);
4790 if (result != ISC_R_SUCCESS)
4793 result = dns_message_gettemprdataset(message, &qrdataset);
4794 if (result != ISC_R_SUCCESS)
4800 dns_name_init(qname, NULL);
4801 dns_name_clone(&zone->origin, qname);
4802 dns_rdataset_init(qrdataset);
4803 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
4804 ISC_LIST_APPEND(qname->list, qrdataset, link);
4805 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
4807 *messagep = message;
4808 return (ISC_R_SUCCESS);
4812 dns_message_puttempname(message, &qname);
4813 if (qrdataset != NULL)
4814 dns_message_puttemprdataset(message, &qrdataset);
4815 if (message != NULL)
4816 dns_message_destroy(&message);
4821 add_opt(dns_message_t *message, isc_uint16_t udpsize) {
4822 dns_rdataset_t *rdataset = NULL;
4823 dns_rdatalist_t *rdatalist = NULL;
4824 dns_rdata_t *rdata = NULL;
4825 isc_result_t result;
4827 result = dns_message_gettemprdatalist(message, &rdatalist);
4828 if (result != ISC_R_SUCCESS)
4830 result = dns_message_gettemprdata(message, &rdata);
4831 if (result != ISC_R_SUCCESS)
4833 result = dns_message_gettemprdataset(message, &rdataset);
4834 if (result != ISC_R_SUCCESS)
4836 dns_rdataset_init(rdataset);
4838 rdatalist->type = dns_rdatatype_opt;
4839 rdatalist->covers = 0;
4842 * Set Maximum UDP buffer size.
4844 rdatalist->rdclass = udpsize;
4847 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
4856 rdata->rdclass = rdatalist->rdclass;
4857 rdata->type = rdatalist->type;
4860 ISC_LIST_INIT(rdatalist->rdata);
4861 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
4862 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
4865 return (dns_message_setopt(message, rdataset));
4868 if (rdatalist != NULL)
4869 dns_message_puttemprdatalist(message, &rdatalist);
4870 if (rdataset != NULL)
4871 dns_message_puttemprdataset(message, &rdataset);
4873 dns_message_puttemprdata(message, &rdata);
4879 soa_query(isc_task_t *task, isc_event_t *event) {
4880 const char me[] = "soa_query";
4881 isc_result_t result = ISC_R_FAILURE;
4882 dns_message_t *message = NULL;
4883 dns_zone_t *zone = event->ev_arg;
4884 dns_zone_t *dummy = NULL;
4885 isc_netaddr_t masterip;
4886 dns_tsigkey_t *key = NULL;
4887 isc_uint32_t options;
4888 isc_boolean_t cancel = ISC_TRUE;
4890 isc_boolean_t have_xfrsource;
4891 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
4893 REQUIRE(DNS_ZONE_VALID(zone));
4900 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
4901 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
4902 zone->view->requestmgr == NULL) {
4903 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
4909 * XXX Optimisation: Create message when zone is setup and reuse.
4911 result = create_query(zone, dns_rdatatype_soa, &message);
4912 if (result != ISC_R_SUCCESS)
4916 INSIST(zone->masterscnt > 0);
4917 INSIST(zone->curmaster < zone->masterscnt);
4919 zone->masteraddr = zone->masters[zone->curmaster];
4921 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
4923 * First, look for a tsig key in the master statement, then
4924 * try for a server key.
4926 if ((zone->masterkeynames != NULL) &&
4927 (zone->masterkeynames[zone->curmaster] != NULL)) {
4928 dns_view_t *view = dns_zone_getview(zone);
4929 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
4930 result = dns_view_gettsig(view, keyname, &key);
4931 if (result != ISC_R_SUCCESS) {
4932 char namebuf[DNS_NAME_FORMATSIZE];
4933 dns_name_format(keyname, namebuf, sizeof(namebuf));
4934 dns_zone_log(zone, ISC_LOG_ERROR,
4935 "unable to find key: %s", namebuf);
4939 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
4941 have_xfrsource = ISC_FALSE;
4942 if (zone->view->peers != NULL) {
4943 dns_peer_t *peer = NULL;
4945 result = dns_peerlist_peerbyaddr(zone->view->peers,
4947 if (result == ISC_R_SUCCESS) {
4948 result = dns_peer_getsupportedns(peer, &edns);
4949 if (result == ISC_R_SUCCESS && !edns)
4950 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
4951 result = dns_peer_gettransfersource(peer,
4953 if (result == ISC_R_SUCCESS)
4954 have_xfrsource = ISC_TRUE;
4955 if (zone->view->resolver != NULL)
4957 dns_resolver_getudpsize(zone->view->resolver);
4958 (void)dns_peer_getudpsize(peer, &udpsize);
4962 switch (isc_sockaddr_pf(&zone->masteraddr)) {
4964 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4965 if (isc_sockaddr_equal(&zone->altxfrsource4,
4968 zone->sourceaddr = zone->altxfrsource4;
4969 } else if (!have_xfrsource)
4970 zone->sourceaddr = zone->xfrsource4;
4973 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
4974 if (isc_sockaddr_equal(&zone->altxfrsource6,
4977 zone->sourceaddr = zone->altxfrsource6;
4978 } else if (!have_xfrsource)
4979 zone->sourceaddr = zone->xfrsource6;
4982 result = ISC_R_NOTIMPLEMENTED;
4986 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
4987 DNS_REQUESTOPT_TCP : 0;
4989 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
4990 result = add_opt(message, udpsize);
4991 if (result != ISC_R_SUCCESS)
4992 zone_debuglog(zone, me, 1,
4993 "unable to add opt record: %s",
4994 dns_result_totext(result));
4997 zone_iattach(zone, &dummy);
4999 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
5001 result = dns_request_createvia2(zone->view->requestmgr, message,
5002 &zone->sourceaddr, &zone->masteraddr,
5003 options, key, timeout * 3, timeout,
5004 zone->task, refresh_callback, zone,
5006 if (result != ISC_R_SUCCESS) {
5007 zone_idetach(&dummy);
5008 zone_debuglog(zone, me, 1,
5009 "dns_request_createvia2() failed: %s",
5010 dns_result_totext(result));
5017 dns_tsigkey_detach(&key);
5018 if (result != ISC_R_SUCCESS)
5019 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
5020 if (message != NULL)
5021 dns_message_destroy(&message);
5023 cancel_refresh(zone);
5024 isc_event_free(&event);
5026 dns_zone_idetach(&zone);
5031 dns_tsigkey_detach(&key);
5033 * Skip to next failed / untried master.
5037 } while (zone->curmaster < zone->masterscnt &&
5038 zone->mastersok[zone->curmaster]);
5039 if (zone->curmaster < zone->masterscnt)
5041 zone->curmaster = 0;
5046 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
5047 const char me[] = "ns_query";
5048 isc_result_t result;
5049 dns_message_t *message = NULL;
5050 isc_netaddr_t masterip;
5051 dns_tsigkey_t *key = NULL;
5052 dns_dbnode_t *node = NULL;
5054 isc_boolean_t have_xfrsource = ISC_FALSE;
5055 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
5057 REQUIRE(DNS_ZONE_VALID(zone));
5058 REQUIRE((soardataset != NULL && stub == NULL) ||
5059 (soardataset == NULL && stub != NULL));
5060 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
5066 stub = isc_mem_get(zone->mctx, sizeof(*stub));
5069 stub->magic = STUB_MAGIC;
5070 stub->mctx = zone->mctx;
5073 stub->version = NULL;
5076 * Attach so that the zone won't disappear from under us.
5078 zone_iattach(zone, &stub->zone);
5081 * If a db exists we will update it, otherwise we create a
5082 * new one and attach it to the zone once we have the NS
5085 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5086 if (zone->db != NULL) {
5087 dns_db_attach(zone->db, &stub->db);
5088 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5090 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5092 INSIST(zone->db_argc >= 1);
5093 result = dns_db_create(zone->mctx, zone->db_argv[0],
5094 &zone->origin, dns_dbtype_stub,
5099 if (result != ISC_R_SUCCESS) {
5100 dns_zone_log(zone, ISC_LOG_ERROR,
5104 dns_result_totext(result));
5107 dns_db_settask(stub->db, zone->task);
5110 dns_db_newversion(stub->db, &stub->version);
5113 * Update SOA record.
5115 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
5117 if (result != ISC_R_SUCCESS) {
5118 dns_zone_log(zone, ISC_LOG_INFO,
5120 "dns_db_findnode() failed: %s",
5121 dns_result_totext(result));
5125 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
5126 soardataset, 0, NULL);
5127 dns_db_detachnode(stub->db, &node);
5128 if (result != ISC_R_SUCCESS) {
5129 dns_zone_log(zone, ISC_LOG_INFO,
5131 "dns_db_addrdataset() failed: %s",
5132 dns_result_totext(result));
5138 * XXX Optimisation: Create message when zone is setup and reuse.
5140 result = create_query(zone, dns_rdatatype_ns, &message);
5142 INSIST(zone->masterscnt > 0);
5143 INSIST(zone->curmaster < zone->masterscnt);
5144 zone->masteraddr = zone->masters[zone->curmaster];
5146 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
5148 * First, look for a tsig key in the master statement, then
5149 * try for a server key.
5151 if ((zone->masterkeynames != NULL) &&
5152 (zone->masterkeynames[zone->curmaster] != NULL)) {
5153 dns_view_t *view = dns_zone_getview(zone);
5154 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
5155 result = dns_view_gettsig(view, keyname, &key);
5156 if (result != ISC_R_SUCCESS) {
5157 char namebuf[DNS_NAME_FORMATSIZE];
5158 dns_name_format(keyname, namebuf, sizeof(namebuf));
5159 dns_zone_log(zone, ISC_LOG_ERROR,
5160 "unable to find key: %s", namebuf);
5164 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
5166 if (zone->view->peers != NULL) {
5167 dns_peer_t *peer = NULL;
5169 result = dns_peerlist_peerbyaddr(zone->view->peers,
5171 if (result == ISC_R_SUCCESS) {
5172 result = dns_peer_getsupportedns(peer, &edns);
5173 if (result == ISC_R_SUCCESS && !edns)
5174 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
5175 result = dns_peer_gettransfersource(peer,
5177 if (result == ISC_R_SUCCESS)
5178 have_xfrsource = ISC_TRUE;
5179 if (zone->view->resolver != NULL)
5181 dns_resolver_getudpsize(zone->view->resolver);
5182 (void)dns_peer_getudpsize(peer, &udpsize);
5186 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
5187 result = add_opt(message, udpsize);
5188 if (result != ISC_R_SUCCESS)
5189 zone_debuglog(zone, me, 1,
5190 "unable to add opt record: %s",
5191 dns_result_totext(result));
5195 * Always use TCP so that we shouldn't truncate in additional section.
5197 switch (isc_sockaddr_pf(&zone->masteraddr)) {
5199 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
5200 zone->sourceaddr = zone->altxfrsource4;
5201 else if (!have_xfrsource)
5202 zone->sourceaddr = zone->xfrsource4;
5205 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
5206 zone->sourceaddr = zone->altxfrsource6;
5207 else if (!have_xfrsource)
5208 zone->sourceaddr = zone->xfrsource6;
5211 result = ISC_R_NOTIMPLEMENTED;
5215 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
5217 result = dns_request_createvia2(zone->view->requestmgr, message,
5218 &zone->sourceaddr, &zone->masteraddr,
5219 DNS_REQUESTOPT_TCP, key, timeout * 3,
5220 timeout, zone->task, stub_callback,
5221 stub, &zone->request);
5222 if (result != ISC_R_SUCCESS) {
5223 zone_debuglog(zone, me, 1,
5224 "dns_request_createvia() failed: %s",
5225 dns_result_totext(result));
5228 dns_message_destroy(&message);
5232 cancel_refresh(zone);
5235 if (stub->version != NULL)
5236 dns_db_closeversion(stub->db, &stub->version,
5238 if (stub->db != NULL)
5239 dns_db_detach(&stub->db);
5240 if (stub->zone != NULL)
5241 zone_idetach(&stub->zone);
5242 isc_mem_put(stub->mctx, stub, sizeof(*stub));
5244 if (message != NULL)
5245 dns_message_destroy(&message);
5248 dns_tsigkey_detach(&key);
5254 * Handle the control event. Note that although this event causes the zone
5255 * to shut down, it is not a shutdown event in the sense of the task library.
5258 zone_shutdown(isc_task_t *task, isc_event_t *event) {
5259 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
5260 isc_boolean_t free_needed, linked = ISC_FALSE;
5263 REQUIRE(DNS_ZONE_VALID(zone));
5264 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
5265 INSIST(isc_refcount_current(&zone->erefs) == 0);
5266 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
5269 * Stop things being restarted after we cancel them below.
5272 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
5276 * If we were waiting for xfrin quota, step out of
5278 * If there's no zone manager, we can't be waiting for the
5281 if (zone->zmgr != NULL) {
5282 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
5283 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
5284 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
5287 zone->statelist = NULL;
5289 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
5293 * In task context, no locking required. See zone_xfrdone().
5295 if (zone->xfr != NULL)
5296 dns_xfrin_shutdown(zone->xfr);
5300 INSIST(zone->irefs > 0);
5303 if (zone->request != NULL) {
5304 dns_request_cancel(zone->request);
5307 if (zone->readio != NULL)
5308 zonemgr_cancelio(zone->readio);
5310 if (zone->lctx != NULL)
5311 dns_loadctx_cancel(zone->lctx);
5313 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
5314 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5315 if (zone->writeio != NULL)
5316 zonemgr_cancelio(zone->writeio);
5318 if (zone->dctx != NULL)
5319 dns_dumpctx_cancel(zone->dctx);
5322 notify_cancel(zone);
5324 if (zone->timer != NULL) {
5325 isc_timer_detach(&zone->timer);
5326 INSIST(zone->irefs > 0);
5330 if (zone->view != NULL)
5331 dns_view_weakdetach(&zone->view);
5334 * We have now canceled everything set the flag to allow exit_check()
5335 * to succeed. We must not unlock between setting this flag and
5336 * calling exit_check().
5338 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
5339 free_needed = exit_check(zone);
5346 zone_timer(isc_task_t *task, isc_event_t *event) {
5347 const char me[] = "zone_timer";
5348 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
5351 REQUIRE(DNS_ZONE_VALID(zone));
5355 zone_maintenance(zone);
5357 isc_event_free(&event);
5361 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
5362 const char me[] = "zone_settimer";
5364 isc_result_t result;
5366 REQUIRE(DNS_ZONE_VALID(zone));
5367 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
5370 isc_time_settoepoch(&next);
5372 switch (zone->type) {
5373 case dns_zone_master:
5374 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
5375 next = zone->notifytime;
5376 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
5377 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5378 INSIST(!isc_time_isepoch(&zone->dumptime));
5379 if (isc_time_isepoch(&next) ||
5380 isc_time_compare(&zone->dumptime, &next) < 0)
5381 next = zone->dumptime;
5385 case dns_zone_slave:
5386 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
5387 next = zone->notifytime;
5391 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
5392 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
5393 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
5394 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
5395 INSIST(!isc_time_isepoch(&zone->refreshtime));
5396 if (isc_time_isepoch(&next) ||
5397 isc_time_compare(&zone->refreshtime, &next) < 0)
5398 next = zone->refreshtime;
5400 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
5401 INSIST(!isc_time_isepoch(&zone->expiretime));
5402 if (isc_time_isepoch(&next) ||
5403 isc_time_compare(&zone->expiretime, &next) < 0)
5404 next = zone->expiretime;
5406 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
5407 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
5408 INSIST(!isc_time_isepoch(&zone->dumptime));
5409 if (isc_time_isepoch(&next) ||
5410 isc_time_compare(&zone->dumptime, &next) < 0)
5411 next = zone->dumptime;
5419 if (isc_time_isepoch(&next)) {
5420 zone_debuglog(zone, me, 10, "settimer inactive");
5421 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
5422 NULL, NULL, ISC_TRUE);
5423 if (result != ISC_R_SUCCESS)
5424 dns_zone_log(zone, ISC_LOG_ERROR,
5425 "could not deactivate zone timer: %s",
5426 isc_result_totext(result));
5428 if (isc_time_compare(&next, now) <= 0)
5430 result = isc_timer_reset(zone->timer, isc_timertype_once,
5431 &next, NULL, ISC_TRUE);
5432 if (result != ISC_R_SUCCESS)
5433 dns_zone_log(zone, ISC_LOG_ERROR,
5434 "could not reset zone timer: %s",
5435 isc_result_totext(result));
5440 cancel_refresh(dns_zone_t *zone) {
5441 const char me[] = "cancel_refresh";
5445 * 'zone' locked by caller.
5448 REQUIRE(DNS_ZONE_VALID(zone));
5449 REQUIRE(LOCKED_ZONE(zone));
5453 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
5455 zone_settimer(zone, &now);
5459 notify_createmessage(dns_zone_t *zone, unsigned int flags,
5460 dns_message_t **messagep)
5462 dns_db_t *zonedb = NULL;
5463 dns_dbnode_t *node = NULL;
5464 dns_dbversion_t *version = NULL;
5465 dns_message_t *message = NULL;
5466 dns_rdataset_t rdataset;
5467 dns_rdata_t rdata = DNS_RDATA_INIT;
5469 dns_name_t *tempname = NULL;
5470 dns_rdata_t *temprdata = NULL;
5471 dns_rdatalist_t *temprdatalist = NULL;
5472 dns_rdataset_t *temprdataset = NULL;
5474 isc_result_t result;
5476 isc_buffer_t *b = NULL;
5478 REQUIRE(DNS_ZONE_VALID(zone));
5479 REQUIRE(messagep != NULL && *messagep == NULL);
5481 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
5483 if (result != ISC_R_SUCCESS)
5486 message->opcode = dns_opcode_notify;
5487 message->flags |= DNS_MESSAGEFLAG_AA;
5488 message->rdclass = zone->rdclass;
5490 result = dns_message_gettempname(message, &tempname);
5491 if (result != ISC_R_SUCCESS)
5494 result = dns_message_gettemprdataset(message, &temprdataset);
5495 if (result != ISC_R_SUCCESS)
5501 dns_name_init(tempname, NULL);
5502 dns_name_clone(&zone->origin, tempname);
5503 dns_rdataset_init(temprdataset);
5504 dns_rdataset_makequestion(temprdataset, zone->rdclass,
5506 ISC_LIST_APPEND(tempname->list, temprdataset, link);
5507 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
5509 temprdataset = NULL;
5511 if ((flags & DNS_NOTIFY_NOSOA) != 0)
5514 result = dns_message_gettempname(message, &tempname);
5515 if (result != ISC_R_SUCCESS)
5517 result = dns_message_gettemprdata(message, &temprdata);
5518 if (result != ISC_R_SUCCESS)
5520 result = dns_message_gettemprdataset(message, &temprdataset);
5521 if (result != ISC_R_SUCCESS)
5523 result = dns_message_gettemprdatalist(message, &temprdatalist);
5524 if (result != ISC_R_SUCCESS)
5527 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5528 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
5529 dns_db_attach(zone->db, &zonedb);
5530 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5532 dns_name_init(tempname, NULL);
5533 dns_name_clone(&zone->origin, tempname);
5534 dns_db_currentversion(zonedb, &version);
5535 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
5536 if (result != ISC_R_SUCCESS)
5539 dns_rdataset_init(&rdataset);
5540 result = dns_db_findrdataset(zonedb, node, version,
5542 dns_rdatatype_none, 0, &rdataset,
5544 if (result != ISC_R_SUCCESS)
5546 result = dns_rdataset_first(&rdataset);
5547 if (result != ISC_R_SUCCESS)
5549 dns_rdataset_current(&rdataset, &rdata);
5550 dns_rdata_toregion(&rdata, &r);
5551 result = isc_buffer_allocate(zone->mctx, &b, r.length);
5552 if (result != ISC_R_SUCCESS)
5554 isc_buffer_putmem(b, r.base, r.length);
5555 isc_buffer_usedregion(b, &r);
5556 dns_rdata_init(temprdata);
5557 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
5558 dns_message_takebuffer(message, &b);
5559 result = dns_rdataset_next(&rdataset);
5560 dns_rdataset_disassociate(&rdataset);
5561 if (result != ISC_R_NOMORE)
5563 temprdatalist->rdclass = rdata.rdclass;
5564 temprdatalist->type = rdata.type;
5565 temprdatalist->covers = 0;
5566 temprdatalist->ttl = rdataset.ttl;
5567 ISC_LIST_INIT(temprdatalist->rdata);
5568 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
5570 dns_rdataset_init(temprdataset);
5571 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
5572 if (result != ISC_R_SUCCESS)
5575 ISC_LIST_APPEND(tempname->list, temprdataset, link);
5576 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
5577 temprdatalist = NULL;
5578 temprdataset = NULL;
5584 dns_db_detachnode(zonedb, &node);
5585 if (version != NULL)
5586 dns_db_closeversion(zonedb, &version, ISC_FALSE);
5588 dns_db_detach(&zonedb);
5589 if (tempname != NULL)
5590 dns_message_puttempname(message, &tempname);
5591 if (temprdata != NULL)
5592 dns_message_puttemprdata(message, &temprdata);
5593 if (temprdataset != NULL)
5594 dns_message_puttemprdataset(message, &temprdataset);
5595 if (temprdatalist != NULL)
5596 dns_message_puttemprdatalist(message, &temprdatalist);
5599 *messagep = message;
5600 return (ISC_R_SUCCESS);
5603 if (tempname != NULL)
5604 dns_message_puttempname(message, &tempname);
5605 if (temprdataset != NULL)
5606 dns_message_puttemprdataset(message, &temprdataset);
5607 dns_message_destroy(&message);
5612 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
5616 dns_rdata_soa_t soa;
5617 dns_rdataset_t *rdataset = NULL;
5618 dns_rdata_t rdata = DNS_RDATA_INIT;
5619 isc_result_t result;
5620 char fromtext[ISC_SOCKADDR_FORMATSIZE];
5622 isc_netaddr_t netaddr;
5624 REQUIRE(DNS_ZONE_VALID(zone));
5627 * If type != T_SOA return DNS_R_REFUSED. We don't yet support
5631 * Check that 'from' is a valid notify source, (zone->masters).
5632 * Return DNS_R_REFUSED if not.
5634 * If the notify message contains a serial number check it
5635 * against the zones serial and return if <= current serial
5637 * If a refresh check is progress, if so just record the
5638 * fact we received a NOTIFY and from where and return.
5639 * We will perform a new refresh check when the current one
5640 * completes. Return ISC_R_SUCCESS.
5642 * Otherwise initiate a refresh check using 'from' as the
5643 * first address to check. Return ISC_R_SUCCESS.
5646 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
5649 * We only handle NOTIFY (SOA) at the present.
5652 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
5653 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
5654 dns_rdatatype_soa, dns_rdatatype_none,
5655 NULL, NULL) != ISC_R_SUCCESS) {
5657 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
5658 dns_zone_log(zone, ISC_LOG_NOTICE,
5660 "question section from: %s", fromtext);
5661 return (DNS_R_FORMERR);
5663 dns_zone_log(zone, ISC_LOG_NOTICE,
5664 "NOTIFY zone does not match");
5665 return (DNS_R_NOTIMP);
5669 * If we are a master zone just succeed.
5671 if (zone->type == dns_zone_master) {
5673 return (ISC_R_SUCCESS);
5676 isc_netaddr_fromsockaddr(&netaddr, from);
5677 for (i = 0; i < zone->masterscnt; i++) {
5678 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
5680 if (zone->view->aclenv.match_mapped &&
5681 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
5682 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
5683 isc_netaddr_t na1, na2;
5684 isc_netaddr_fromv4mapped(&na1, &netaddr);
5685 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
5686 if (isc_netaddr_equal(&na1, &na2))
5692 * Accept notify requests from non masters if they are on
5693 * 'zone->notify_acl'.
5695 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
5696 dns_acl_match(&netaddr, NULL, zone->notify_acl,
5697 &zone->view->aclenv,
5698 &match, NULL) == ISC_R_SUCCESS &&
5701 /* Accept notify. */
5702 } else if (i >= zone->masterscnt) {
5704 dns_zone_log(zone, ISC_LOG_INFO,
5705 "refused notify from non-master: %s", fromtext);
5706 return (DNS_R_REFUSED);
5710 * If the zone is loaded and there are answers check the serial
5711 * to see if we need to do a refresh. Do not worry about this
5712 * check if we are a dialup zone as we use the notify request
5713 * to trigger a refresh check.
5715 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
5716 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
5717 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
5718 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
5721 dns_rdatatype_none, NULL,
5723 if (result == ISC_R_SUCCESS)
5724 result = dns_rdataset_first(rdataset);
5725 if (result == ISC_R_SUCCESS) {
5726 isc_uint32_t serial = 0;
5728 dns_rdataset_current(rdataset, &rdata);
5729 result = dns_rdata_tostruct(&rdata, &soa, NULL);
5730 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5731 serial = soa.serial;
5732 if (isc_serial_le(serial, zone->serial)) {
5733 dns_zone_log(zone, ISC_LOG_INFO,
5735 "zone is up to date",
5738 return (ISC_R_SUCCESS);
5744 * If we got this far and there was a refresh in progress just
5745 * let it complete. Record where we got the notify from so we
5746 * can perform a refresh check when the current one completes
5748 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
5749 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
5750 zone->notifyfrom = *from;
5752 dns_zone_log(zone, ISC_LOG_INFO,
5753 "notify from %s: refresh in progress, "
5754 "refresh check queued",
5756 return (ISC_R_SUCCESS);
5758 zone->notifyfrom = *from;
5760 dns_zone_refresh(zone);
5761 return (ISC_R_SUCCESS);
5765 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
5767 REQUIRE(DNS_ZONE_VALID(zone));
5770 if (zone->notify_acl != NULL)
5771 dns_acl_detach(&zone->notify_acl);
5772 dns_acl_attach(acl, &zone->notify_acl);
5777 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
5779 REQUIRE(DNS_ZONE_VALID(zone));
5782 if (zone->query_acl != NULL)
5783 dns_acl_detach(&zone->query_acl);
5784 dns_acl_attach(acl, &zone->query_acl);
5789 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
5791 REQUIRE(DNS_ZONE_VALID(zone));
5794 if (zone->update_acl != NULL)
5795 dns_acl_detach(&zone->update_acl);
5796 dns_acl_attach(acl, &zone->update_acl);
5801 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
5803 REQUIRE(DNS_ZONE_VALID(zone));
5806 if (zone->forward_acl != NULL)
5807 dns_acl_detach(&zone->forward_acl);
5808 dns_acl_attach(acl, &zone->forward_acl);
5813 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
5815 REQUIRE(DNS_ZONE_VALID(zone));
5818 if (zone->xfr_acl != NULL)
5819 dns_acl_detach(&zone->xfr_acl);
5820 dns_acl_attach(acl, &zone->xfr_acl);
5825 dns_zone_getnotifyacl(dns_zone_t *zone) {
5827 REQUIRE(DNS_ZONE_VALID(zone));
5829 return (zone->notify_acl);
5833 dns_zone_getqueryacl(dns_zone_t *zone) {
5835 REQUIRE(DNS_ZONE_VALID(zone));
5837 return (zone->query_acl);
5841 dns_zone_getupdateacl(dns_zone_t *zone) {
5843 REQUIRE(DNS_ZONE_VALID(zone));
5845 return (zone->update_acl);
5849 dns_zone_getforwardacl(dns_zone_t *zone) {
5851 REQUIRE(DNS_ZONE_VALID(zone));
5853 return (zone->forward_acl);
5857 dns_zone_getxfracl(dns_zone_t *zone) {
5859 REQUIRE(DNS_ZONE_VALID(zone));
5861 return (zone->xfr_acl);
5865 dns_zone_clearupdateacl(dns_zone_t *zone) {
5867 REQUIRE(DNS_ZONE_VALID(zone));
5870 if (zone->update_acl != NULL)
5871 dns_acl_detach(&zone->update_acl);
5876 dns_zone_clearforwardacl(dns_zone_t *zone) {
5878 REQUIRE(DNS_ZONE_VALID(zone));
5881 if (zone->forward_acl != NULL)
5882 dns_acl_detach(&zone->forward_acl);
5887 dns_zone_clearnotifyacl(dns_zone_t *zone) {
5889 REQUIRE(DNS_ZONE_VALID(zone));
5892 if (zone->notify_acl != NULL)
5893 dns_acl_detach(&zone->notify_acl);
5898 dns_zone_clearqueryacl(dns_zone_t *zone) {
5900 REQUIRE(DNS_ZONE_VALID(zone));
5903 if (zone->query_acl != NULL)
5904 dns_acl_detach(&zone->query_acl);
5909 dns_zone_clearxfracl(dns_zone_t *zone) {
5911 REQUIRE(DNS_ZONE_VALID(zone));
5914 if (zone->xfr_acl != NULL)
5915 dns_acl_detach(&zone->xfr_acl);
5920 dns_zone_getupdatedisabled(dns_zone_t *zone) {
5921 REQUIRE(DNS_ZONE_VALID(zone));
5922 return (zone->update_disabled);
5927 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
5928 REQUIRE(DNS_ZONE_VALID(zone));
5929 zone->update_disabled = state;
5933 dns_zone_getzeronosoattl(dns_zone_t *zone) {
5934 REQUIRE(DNS_ZONE_VALID(zone));
5935 return (zone->zero_no_soa_ttl);
5940 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
5941 REQUIRE(DNS_ZONE_VALID(zone));
5942 zone->zero_no_soa_ttl = state;
5946 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
5948 REQUIRE(DNS_ZONE_VALID(zone));
5950 zone->check_names = severity;
5954 dns_zone_getchecknames(dns_zone_t *zone) {
5956 REQUIRE(DNS_ZONE_VALID(zone));
5958 return (zone->check_names);
5962 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
5964 REQUIRE(DNS_ZONE_VALID(zone));
5966 zone->journalsize = size;
5970 dns_zone_getjournalsize(dns_zone_t *zone) {
5972 REQUIRE(DNS_ZONE_VALID(zone));
5974 return (zone->journalsize);
5978 zone_tostr(dns_zone_t *zone, char *buf, size_t length) {
5979 isc_result_t result = ISC_R_FAILURE;
5980 isc_buffer_t buffer;
5982 REQUIRE(buf != NULL);
5983 REQUIRE(length > 1U);
5986 * Leave space for terminating '\0'.
5988 isc_buffer_init(&buffer, buf, length - 1);
5989 if (dns_name_dynamic(&zone->origin))
5990 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
5991 if (result != ISC_R_SUCCESS &&
5992 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
5993 isc_buffer_putstr(&buffer, "<UNKNOWN>");
5995 if (isc_buffer_availablelength(&buffer) > 0)
5996 isc_buffer_putstr(&buffer, "/");
5997 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
5999 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
6000 strcmp(zone->view->name, "_default") != 0 &&
6001 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
6002 isc_buffer_putstr(&buffer, "/");
6003 isc_buffer_putstr(&buffer, zone->view->name);
6006 buf[isc_buffer_usedlength(&buffer)] = '\0';
6010 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
6011 REQUIRE(DNS_ZONE_VALID(zone));
6012 REQUIRE(buf != NULL);
6013 zone_tostr(zone, buf, length);
6017 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
6020 char namebuf[1024+32];
6022 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6025 zone_tostr(zone, namebuf, sizeof(namebuf));
6028 vsnprintf(message, sizeof(message), fmt, ap);
6030 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
6031 level, "zone %s: %s", namebuf, message);
6035 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
6036 int level, const char *fmt, ...) {
6039 char namebuf[1024+32];
6041 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6044 zone_tostr(zone, namebuf, sizeof(namebuf));
6047 vsnprintf(message, sizeof(message), fmt, ap);
6049 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
6050 level, "zone %s: %s", namebuf, message);
6054 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
6057 char namebuf[1024+32];
6059 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6062 zone_tostr(zone, namebuf, sizeof(namebuf));
6065 vsnprintf(message, sizeof(message), fmt, ap);
6067 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
6068 level, "zone %s: %s", namebuf, message);
6072 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
6073 const char *fmt, ...)
6077 char namebuf[1024+32];
6078 int level = ISC_LOG_DEBUG(debuglevel);
6080 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
6083 zone_tostr(zone, namebuf, sizeof(namebuf));
6086 vsnprintf(message, sizeof(message), fmt, ap);
6088 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
6089 level, "%s: zone %s: %s", me, namebuf, message);
6093 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
6095 isc_result_t result;
6097 dns_rdataset_t *curr;
6100 result = dns_message_firstname(msg, section);
6101 while (result == ISC_R_SUCCESS) {
6103 dns_message_currentname(msg, section, &name);
6105 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
6106 curr = ISC_LIST_PREV(curr, link)) {
6107 if (curr->type == type)
6110 result = dns_message_nextname(msg, section);
6117 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
6118 REQUIRE(DNS_ZONE_VALID(zone));
6120 zone->maxxfrin = maxxfrin;
6124 dns_zone_getmaxxfrin(dns_zone_t *zone) {
6125 REQUIRE(DNS_ZONE_VALID(zone));
6127 return (zone->maxxfrin);
6131 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
6132 REQUIRE(DNS_ZONE_VALID(zone));
6133 zone->maxxfrout = maxxfrout;
6137 dns_zone_getmaxxfrout(dns_zone_t *zone) {
6138 REQUIRE(DNS_ZONE_VALID(zone));
6140 return (zone->maxxfrout);
6144 dns_zone_gettype(dns_zone_t *zone) {
6145 REQUIRE(DNS_ZONE_VALID(zone));
6147 return (zone->type);
6151 dns_zone_getorigin(dns_zone_t *zone) {
6152 REQUIRE(DNS_ZONE_VALID(zone));
6154 return (&zone->origin);
6158 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
6159 REQUIRE(DNS_ZONE_VALID(zone));
6162 if (zone->task != NULL)
6163 isc_task_detach(&zone->task);
6164 isc_task_attach(task, &zone->task);
6165 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6166 if (zone->db != NULL)
6167 dns_db_settask(zone->db, zone->task);
6168 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6173 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
6174 REQUIRE(DNS_ZONE_VALID(zone));
6175 isc_task_attach(zone->task, target);
6179 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
6180 REQUIRE(DNS_ZONE_VALID(zone));
6183 idlein = DNS_DEFAULT_IDLEIN;
6184 zone->idlein = idlein;
6188 dns_zone_getidlein(dns_zone_t *zone) {
6189 REQUIRE(DNS_ZONE_VALID(zone));
6191 return (zone->idlein);
6195 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
6196 REQUIRE(DNS_ZONE_VALID(zone));
6198 zone->idleout = idleout;
6202 dns_zone_getidleout(dns_zone_t *zone) {
6203 REQUIRE(DNS_ZONE_VALID(zone));
6205 return (zone->idleout);
6209 notify_done(isc_task_t *task, isc_event_t *event) {
6210 dns_requestevent_t *revent = (dns_requestevent_t *)event;
6211 dns_notify_t *notify;
6212 isc_result_t result;
6213 dns_message_t *message = NULL;
6216 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6220 notify = event->ev_arg;
6221 REQUIRE(DNS_NOTIFY_VALID(notify));
6222 INSIST(task == notify->zone->task);
6224 isc_buffer_init(&buf, rcode, sizeof(rcode));
6225 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
6227 result = revent->result;
6228 if (result == ISC_R_SUCCESS)
6229 result = dns_message_create(notify->zone->mctx,
6230 DNS_MESSAGE_INTENTPARSE, &message);
6231 if (result == ISC_R_SUCCESS)
6232 result = dns_request_getresponse(revent->request, message,
6233 DNS_MESSAGEPARSE_PRESERVEORDER);
6234 if (result == ISC_R_SUCCESS)
6235 result = dns_rcode_totext(message->rcode, &buf);
6236 if (result == ISC_R_SUCCESS)
6237 notify_log(notify->zone, ISC_LOG_DEBUG(3),
6238 "notify response from %s: %.*s",
6239 addrbuf, (int)buf.used, rcode);
6241 notify_log(notify->zone, ISC_LOG_DEBUG(2),
6242 "notify to %s failed: %s", addrbuf,
6243 dns_result_totext(result));
6246 * Old bind's return formerr if they see a soa record. Retry w/o
6247 * the soa if we see a formerr and had sent a SOA.
6249 isc_event_free(&event);
6250 if (message != NULL && message->rcode == dns_rcode_formerr &&
6251 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
6252 notify->flags |= DNS_NOTIFY_NOSOA;
6253 dns_request_destroy(¬ify->request);
6254 result = notify_send_queue(notify);
6255 if (result != ISC_R_SUCCESS)
6256 notify_destroy(notify, ISC_FALSE);
6258 if (result == ISC_R_TIMEDOUT)
6259 notify_log(notify->zone, ISC_LOG_DEBUG(1),
6260 "notify to %s: retries exceeded", addrbuf);
6261 notify_destroy(notify, ISC_FALSE);
6263 if (message != NULL)
6264 dns_message_destroy(&message);
6268 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
6269 isc_result_t result;
6271 REQUIRE(DNS_ZONE_VALID(zone));
6273 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6274 result = zone_replacedb(zone, db, dump);
6275 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6281 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
6282 dns_dbversion_t *ver;
6283 isc_result_t result;
6284 unsigned int soacount = 0;
6285 unsigned int nscount = 0;
6288 * 'zone' and 'zonedb' locked by caller.
6290 REQUIRE(DNS_ZONE_VALID(zone));
6291 REQUIRE(LOCKED_ZONE(zone));
6293 result = zone_get_from_db(zone, db, &nscount, &soacount,
6294 NULL, NULL, NULL, NULL, NULL, NULL);
6295 if (result == ISC_R_SUCCESS) {
6296 if (soacount != 1) {
6297 dns_zone_log(zone, ISC_LOG_ERROR,
6298 "has %d SOA records", soacount);
6299 result = DNS_R_BADZONE;
6302 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
6303 result = DNS_R_BADZONE;
6305 if (result != ISC_R_SUCCESS)
6308 dns_zone_log(zone, ISC_LOG_ERROR,
6309 "retrieving SOA and NS records failed: %s",
6310 dns_result_totext(result));
6315 dns_db_currentversion(db, &ver);
6318 * The initial version of a slave zone is always dumped;
6319 * subsequent versions may be journalled instead if this
6320 * is enabled in the configuration.
6322 if (zone->db != NULL && zone->journal != NULL &&
6323 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
6324 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
6325 isc_uint32_t serial;
6327 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
6329 result = dns_db_getsoaserial(db, ver, &serial);
6330 if (result != ISC_R_SUCCESS) {
6331 dns_zone_log(zone, ISC_LOG_ERROR,
6332 "ixfr-from-differences: unable to get "
6338 * This is checked in zone_postload() for master zones.
6340 if (zone->type == dns_zone_slave &&
6341 !isc_serial_gt(serial, zone->serial)) {
6342 isc_uint32_t serialmin, serialmax;
6343 serialmin = (zone->serial + 1) & 0xffffffffU;
6344 serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU;
6345 dns_zone_log(zone, ISC_LOG_ERROR,
6346 "ixfr-from-differences: failed: "
6347 "new serial (%u) out of range [%u - %u]",
6348 serial, serialmin, serialmax);
6349 result = ISC_R_RANGE;
6353 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
6355 if (result != ISC_R_SUCCESS)
6358 zone_needdump(zone, DNS_DUMP_DELAY);
6359 else if (zone->journalsize != -1) {
6360 result = dns_journal_compact(zone->mctx, zone->journal,
6361 serial, zone->journalsize);
6365 case ISC_R_NOTFOUND:
6366 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6367 "dns_journal_compact: %s",
6368 dns_result_totext(result));
6371 dns_zone_log(zone, ISC_LOG_ERROR,
6372 "dns_journal_compact failed: %s",
6373 dns_result_totext(result));
6378 if (dump && zone->masterfile != NULL) {
6379 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6380 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6381 "dumping new zone version");
6382 result = dns_db_dump2(db, ver, zone->masterfile,
6383 zone->masterformat);
6384 if (result != ISC_R_SUCCESS)
6388 * Update the time the zone was updated, so
6389 * dns_zone_load can avoid loading it when
6390 * the server is reloaded. If isc_time_now
6391 * fails for some reason, all that happens is
6392 * the timestamp is not updated.
6394 TIME_NOW(&zone->loadtime);
6397 if (dump && zone->journal != NULL) {
6399 * The in-memory database just changed, and
6400 * because 'dump' is set, it didn't change by
6401 * being loaded from disk. Also, we have not
6402 * journalled diffs for this change.
6403 * Therefore, the on-disk journal is missing
6404 * the deltas for this change. Since it can
6405 * no longer be used to bring the zone
6406 * up-to-date, it is useless and should be
6409 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6410 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6411 "removing journal file");
6412 (void)remove(zone->journal);
6416 dns_db_closeversion(db, &ver, ISC_FALSE);
6418 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
6419 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
6420 "replacing zone database");
6422 if (zone->db != NULL)
6423 zone_detachdb(zone);
6424 zone_attachdb(zone, db);
6425 dns_db_settask(zone->db, zone->task);
6426 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
6427 return (ISC_R_SUCCESS);
6430 dns_db_closeversion(db, &ver, ISC_FALSE);
6434 /* The caller must hold the dblock as a writer. */
6436 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
6437 REQUIRE(zone->db == NULL && db != NULL);
6439 dns_db_attach(db, &zone->db);
6440 if (zone->acache != NULL) {
6441 isc_result_t result;
6442 result = dns_acache_setdb(zone->acache, db);
6443 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
6444 UNEXPECTED_ERROR(__FILE__, __LINE__,
6445 "dns_acache_setdb() failed: %s",
6446 isc_result_totext(result));
6451 /* The caller must hold the dblock as a writer. */
6453 zone_detachdb(dns_zone_t *zone) {
6454 REQUIRE(zone->db != NULL);
6456 if (zone->acache != NULL)
6457 (void)dns_acache_putdb(zone->acache, zone->db);
6458 dns_db_detach(&zone->db);
6462 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
6464 isc_boolean_t again = ISC_FALSE;
6465 unsigned int soacount;
6466 unsigned int nscount;
6467 isc_uint32_t serial, refresh, retry, expire, minimum;
6468 isc_result_t xfrresult = result;
6469 isc_boolean_t free_needed;
6471 REQUIRE(DNS_ZONE_VALID(zone));
6473 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6474 "zone transfer finished: %s", dns_result_totext(result));
6477 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
6478 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
6479 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
6484 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6486 case DNS_R_UPTODATE:
6487 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
6489 * Has the zone expired underneath us?
6491 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6492 if (zone->db == NULL) {
6493 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6498 * Update the zone structure's data from the actual
6503 INSIST(zone->db != NULL);
6504 result = zone_get_from_db(zone, zone->db, &nscount,
6505 &soacount, &serial, &refresh,
6506 &retry, &expire, &minimum, NULL);
6507 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6508 if (result == ISC_R_SUCCESS) {
6510 dns_zone_log(zone, ISC_LOG_ERROR,
6512 "has %d SOA record%s", soacount,
6513 (soacount != 0) ? "s" : "");
6515 dns_zone_log(zone, ISC_LOG_ERROR,
6517 "has no NS records");
6518 if (DNS_ZONE_FLAG(zone,
6519 DNS_ZONEFLG_HAVETIMERS)) {
6520 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
6521 zone->retry = DNS_ZONE_DEFAULTRETRY;
6523 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6527 zone->serial = serial;
6528 zone->refresh = RANGE(refresh, zone->minrefresh,
6530 zone->retry = RANGE(retry, zone->minretry,
6532 zone->expire = RANGE(expire,
6533 zone->refresh + zone->retry,
6535 zone->minimum = minimum;
6536 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
6540 * Set our next update/expire times.
6542 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
6543 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
6544 zone->refreshtime = now;
6545 DNS_ZONE_TIME_ADD(&now, zone->expire,
6548 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
6549 &zone->refreshtime);
6550 DNS_ZONE_TIME_ADD(&now, zone->expire,
6553 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
6554 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
6555 if (zone->tsigkey != NULL) {
6556 char namebuf[DNS_NAME_FORMATSIZE];
6557 dns_name_format(&zone->tsigkey->name, namebuf,
6559 snprintf(buf, sizeof(buf), ": TSIG '%s'",
6563 dns_zone_log(zone, ISC_LOG_INFO,
6564 "transferred serial %u%s",
6569 * This is not neccessary if we just performed a AXFR
6570 * however it is necessary for an IXFR / UPTODATE and
6571 * won't hurt with an AXFR.
6573 if (zone->masterfile != NULL || zone->journal != NULL) {
6574 result = ISC_R_FAILURE;
6575 if (zone->journal != NULL)
6576 result = isc_file_settime(zone->journal, &now);
6577 if (result != ISC_R_SUCCESS &&
6578 zone->masterfile != NULL)
6579 result = isc_file_settime(zone->masterfile,
6581 /* Someone removed the file from underneath us! */
6582 if (result == ISC_R_FILENOTFOUND &&
6583 zone->masterfile != NULL)
6584 zone_needdump(zone, DNS_DUMP_DELAY);
6585 else if (result != ISC_R_SUCCESS)
6586 dns_zone_log(zone, ISC_LOG_ERROR,
6587 "transfer: could not set file "
6588 "modification time of '%s': %s",
6590 dns_result_totext(result));
6596 /* Force retry with AXFR. */
6597 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
6603 * Skip to next failed / untried master.
6607 } while (zone->curmaster < zone->masterscnt &&
6608 zone->mastersok[zone->curmaster]);
6611 if (zone->curmaster >= zone->masterscnt) {
6612 zone->curmaster = 0;
6613 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
6614 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
6615 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6616 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6617 while (zone->curmaster < zone->masterscnt &&
6618 zone->mastersok[zone->curmaster])
6622 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
6624 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
6629 zone_settimer(zone, &now);
6632 * If creating the transfer object failed, zone->xfr is NULL.
6633 * Otherwise, we are called as the done callback of a zone
6634 * transfer object that just entered its shutting-down
6635 * state. Since we are no longer responsible for shutting
6636 * it down, we can detach our reference.
6638 if (zone->xfr != NULL)
6639 dns_xfrin_detach(&zone->xfr);
6641 if (zone->tsigkey != NULL)
6642 dns_tsigkey_detach(&zone->tsigkey);
6645 * Handle any deferred journal compaction.
6647 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
6648 result = dns_journal_compact(zone->mctx, zone->journal,
6649 zone->compact_serial,
6654 case ISC_R_NOTFOUND:
6655 dns_zone_log(zone, ISC_LOG_DEBUG(3),
6656 "dns_journal_compact: %s",
6657 dns_result_totext(result));
6660 dns_zone_log(zone, ISC_LOG_ERROR,
6661 "dns_journal_compact failed: %s",
6662 dns_result_totext(result));
6665 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
6669 * This transfer finishing freed up a transfer quota slot.
6670 * Let any other zones waiting for quota have it.
6672 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
6673 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
6674 zone->statelist = NULL;
6675 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
6676 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
6679 * Retry with a different server if necessary.
6681 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
6682 queue_soa_query(zone);
6684 INSIST(zone->irefs > 0);
6686 free_needed = exit_check(zone);
6693 zone_loaddone(void *arg, isc_result_t result) {
6694 static char me[] = "zone_loaddone";
6695 dns_load_t *load = arg;
6697 isc_result_t tresult;
6699 REQUIRE(DNS_LOAD_VALID(load));
6704 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
6705 if (tresult != ISC_R_SUCCESS &&
6706 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
6709 LOCK_ZONE(load->zone);
6710 (void)zone_postload(load->zone, load->db, load->loadtime, result);
6711 zonemgr_putio(&load->zone->readio);
6712 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
6713 UNLOCK_ZONE(load->zone);
6716 dns_db_detach(&load->db);
6717 if (load->zone->lctx != NULL)
6718 dns_loadctx_detach(&load->zone->lctx);
6719 dns_zone_idetach(&load->zone);
6720 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
6724 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
6725 REQUIRE(DNS_ZONE_VALID(zone));
6726 REQUIRE(table != NULL);
6727 REQUIRE(*table == NULL);
6730 if (zone->ssutable != NULL)
6731 dns_ssutable_attach(zone->ssutable, table);
6736 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
6737 REQUIRE(DNS_ZONE_VALID(zone));
6740 if (zone->ssutable != NULL)
6741 dns_ssutable_detach(&zone->ssutable);
6743 dns_ssutable_attach(table, &zone->ssutable);
6748 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
6749 REQUIRE(DNS_ZONE_VALID(zone));
6751 zone->sigvalidityinterval = interval;
6755 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
6756 REQUIRE(DNS_ZONE_VALID(zone));
6758 return (zone->sigvalidityinterval);
6762 queue_xfrin(dns_zone_t *zone) {
6763 const char me[] = "queue_xfrin";
6764 isc_result_t result;
6765 dns_zonemgr_t *zmgr = zone->zmgr;
6769 INSIST(zone->statelist == NULL);
6771 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
6772 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
6776 zone->statelist = &zmgr->waiting_for_xfrin;
6777 result = zmgr_start_xfrin_ifquota(zmgr, zone);
6778 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
6780 if (result == ISC_R_QUOTA) {
6781 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
6782 "zone transfer deferred due to quota");
6783 } else if (result != ISC_R_SUCCESS) {
6784 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
6785 "starting zone transfer: %s",
6786 isc_result_totext(result));
6791 * This event callback is called when a zone has received
6792 * any necessary zone transfer quota. This is the time
6793 * to go ahead and start the transfer.
6796 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
6797 isc_result_t result;
6798 dns_peer_t *peer = NULL;
6799 char mastertext[256];
6800 dns_rdatatype_t xfrtype;
6801 dns_zone_t *zone = event->ev_arg;
6802 isc_netaddr_t masterip;
6803 isc_sockaddr_t sourceaddr;
6804 isc_sockaddr_t masteraddr;
6808 INSIST(task == zone->task);
6810 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
6811 result = ISC_R_CANCELED;
6815 isc_sockaddr_format(&zone->masteraddr, mastertext, sizeof(mastertext));
6817 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
6818 (void)dns_peerlist_peerbyaddr(zone->view->peers,
6822 * Decide whether we should request IXFR or AXFR.
6824 if (zone->db == NULL) {
6825 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6826 "no database exists yet, "
6827 "requesting AXFR of "
6828 "initial version from %s", mastertext);
6829 xfrtype = dns_rdatatype_axfr;
6830 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
6831 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
6832 "set, requesting AXFR from %s", mastertext);
6833 xfrtype = dns_rdatatype_axfr;
6834 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
6835 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6836 "forced reload, requesting AXFR of "
6837 "initial version from %s", mastertext);
6838 xfrtype = dns_rdatatype_axfr;
6839 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
6840 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6841 "retrying with AXFR from %s due to "
6842 "previous IXFR failure", mastertext);
6843 xfrtype = dns_rdatatype_axfr;
6845 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
6848 isc_boolean_t use_ixfr = ISC_TRUE;
6850 dns_peer_getrequestixfr(peer, &use_ixfr) ==
6852 ; /* Using peer setting */
6854 use_ixfr = zone->view->requestixfr;
6856 if (use_ixfr == ISC_FALSE) {
6857 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6859 "requesting AXFR from %s",
6861 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
6862 xfrtype = dns_rdatatype_soa;
6864 xfrtype = dns_rdatatype_axfr;
6866 dns_zone_log(zone, ISC_LOG_DEBUG(1),
6867 "requesting IXFR from %s",
6869 xfrtype = dns_rdatatype_ixfr;
6874 * Determine if we should attempt to sign the request with TSIG.
6876 result = ISC_R_NOTFOUND;
6878 * First, look for a tsig key in the master statement, then
6879 * try for a server key.
6881 if ((zone->masterkeynames != NULL) &&
6882 (zone->masterkeynames[zone->curmaster] != NULL)) {
6883 dns_view_t *view = dns_zone_getview(zone);
6884 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
6885 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
6887 if (zone->tsigkey == NULL)
6888 result = dns_view_getpeertsig(zone->view, &masterip,
6891 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6892 dns_zone_log(zone, ISC_LOG_ERROR,
6893 "could not get TSIG key "
6894 "for zone transfer: %s",
6895 isc_result_totext(result));
6899 masteraddr = zone->masteraddr;
6900 sourceaddr = zone->sourceaddr;
6902 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
6903 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
6904 zone->tsigkey, zone->mctx,
6905 zone->zmgr->timermgr, zone->zmgr->socketmgr,
6906 zone->task, zone_xfrdone, &zone->xfr);
6909 * Any failure in this function is handled like a failed
6910 * zone transfer. This ensures that we get removed from
6911 * zmgr->xfrin_in_progress.
6913 if (result != ISC_R_SUCCESS)
6914 zone_xfrdone(zone, result);
6916 isc_event_free(&event);
6920 * Update forwarding support.
6924 forward_destroy(dns_forward_t *forward) {
6927 if (forward->request != NULL)
6928 dns_request_destroy(&forward->request);
6929 if (forward->msgbuf != NULL)
6930 isc_buffer_free(&forward->msgbuf);
6931 if (forward->zone != NULL)
6932 dns_zone_idetach(&forward->zone);
6933 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
6937 sendtomaster(dns_forward_t *forward) {
6938 isc_result_t result;
6941 LOCK_ZONE(forward->zone);
6942 if (forward->which >= forward->zone->masterscnt) {
6943 UNLOCK_ZONE(forward->zone);
6944 return (ISC_R_NOMORE);
6947 forward->addr = forward->zone->masters[forward->which];
6949 * Always use TCP regardless of whether the original update
6951 * XXX The timeout may but a bit small if we are far down a
6952 * transfer graph and the master has to try several masters.
6954 switch (isc_sockaddr_pf(&forward->addr)) {
6956 src = forward->zone->xfrsource4;
6959 src = forward->zone->xfrsource6;
6962 result = ISC_R_NOTIMPLEMENTED;
6965 result = dns_request_createraw(forward->zone->view->requestmgr,
6967 &src, &forward->addr,
6968 DNS_REQUESTOPT_TCP, 15 /* XXX */,
6969 forward->zone->task,
6970 forward_callback, forward,
6973 UNLOCK_ZONE(forward->zone);
6978 forward_callback(isc_task_t *task, isc_event_t *event) {
6979 const char me[] = "forward_callback";
6980 dns_requestevent_t *revent = (dns_requestevent_t *)event;
6981 dns_message_t *msg = NULL;
6982 char master[ISC_SOCKADDR_FORMATSIZE];
6983 isc_result_t result;
6984 dns_forward_t *forward;
6989 forward = revent->ev_arg;
6990 INSIST(DNS_FORWARD_VALID(forward));
6991 zone = forward->zone;
6992 INSIST(DNS_ZONE_VALID(zone));
6996 isc_sockaddr_format(&forward->addr, master, sizeof(master));
6998 if (revent->result != ISC_R_SUCCESS) {
6999 dns_zone_log(zone, ISC_LOG_INFO,
7000 "could not forward dynamic update to %s: %s",
7001 master, dns_result_totext(revent->result));
7005 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
7006 if (result != ISC_R_SUCCESS)
7009 result = dns_request_getresponse(revent->request, msg,
7010 DNS_MESSAGEPARSE_PRESERVEORDER |
7011 DNS_MESSAGEPARSE_CLONEBUFFER);
7012 if (result != ISC_R_SUCCESS)
7015 switch (msg->rcode) {
7017 * Pass these rcodes back to client.
7019 case dns_rcode_noerror:
7020 case dns_rcode_yxdomain:
7021 case dns_rcode_yxrrset:
7022 case dns_rcode_nxrrset:
7023 case dns_rcode_refused:
7024 case dns_rcode_nxdomain:
7027 /* These should not occur if the masters/zone are valid. */
7028 case dns_rcode_notzone:
7029 case dns_rcode_notauth: {
7033 isc_buffer_init(&rb, rcode, sizeof(rcode));
7034 (void)dns_rcode_totext(msg->rcode, &rb);
7035 dns_zone_log(zone, ISC_LOG_WARNING,
7036 "forwarding dynamic update: "
7037 "unexpected response: master %s returned: %.*s",
7038 master, (int)rb.used, rcode);
7042 /* Try another server for these rcodes. */
7043 case dns_rcode_formerr:
7044 case dns_rcode_servfail:
7045 case dns_rcode_notimp:
7046 case dns_rcode_badvers:
7052 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
7054 dns_request_destroy(&forward->request);
7055 forward_destroy(forward);
7056 isc_event_free(&event);
7061 dns_message_destroy(&msg);
7062 isc_event_free(&event);
7064 dns_request_destroy(&forward->request);
7065 result = sendtomaster(forward);
7066 if (result != ISC_R_SUCCESS) {
7068 dns_zone_log(zone, ISC_LOG_DEBUG(3),
7069 "exhausted dynamic update forwarder list");
7070 (forward->callback)(forward->callback_arg, result, NULL);
7071 forward_destroy(forward);
7076 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
7077 dns_updatecallback_t callback, void *callback_arg)
7079 dns_forward_t *forward;
7080 isc_result_t result;
7083 REQUIRE(DNS_ZONE_VALID(zone));
7084 REQUIRE(msg != NULL);
7085 REQUIRE(callback != NULL);
7087 forward = isc_mem_get(zone->mctx, sizeof(*forward));
7088 if (forward == NULL)
7089 return (ISC_R_NOMEMORY);
7091 forward->request = NULL;
7092 forward->zone = NULL;
7093 forward->msgbuf = NULL;
7096 forward->callback = callback;
7097 forward->callback_arg = callback_arg;
7098 forward->magic = FORWARD_MAGIC;
7100 mr = dns_message_getrawmessage(msg);
7102 result = ISC_R_UNEXPECTEDEND;
7106 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
7107 if (result != ISC_R_SUCCESS)
7109 result = isc_buffer_copyregion(forward->msgbuf, mr);
7110 if (result != ISC_R_SUCCESS)
7113 isc_mem_attach(zone->mctx, &forward->mctx);
7114 dns_zone_iattach(zone, &forward->zone);
7115 result = sendtomaster(forward);
7118 if (result != ISC_R_SUCCESS) {
7119 forward_destroy(forward);
7125 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
7126 REQUIRE(DNS_ZONE_VALID(zone));
7127 REQUIRE(next != NULL && *next == NULL);
7129 *next = ISC_LIST_NEXT(zone, link);
7131 return (ISC_R_NOMORE);
7133 return (ISC_R_SUCCESS);
7137 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
7138 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7139 REQUIRE(first != NULL && *first == NULL);
7141 *first = ISC_LIST_HEAD(zmgr->zones);
7143 return (ISC_R_NOMORE);
7145 return (ISC_R_SUCCESS);
7153 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
7154 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
7155 dns_zonemgr_t **zmgrp)
7157 dns_zonemgr_t *zmgr;
7158 isc_result_t result;
7159 isc_interval_t interval;
7161 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
7163 return (ISC_R_NOMEMORY);
7166 isc_mem_attach(mctx, &zmgr->mctx);
7167 zmgr->taskmgr = taskmgr;
7168 zmgr->timermgr = timermgr;
7169 zmgr->socketmgr = socketmgr;
7170 zmgr->zonetasks = NULL;
7173 ISC_LIST_INIT(zmgr->zones);
7174 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
7175 ISC_LIST_INIT(zmgr->xfrin_in_progress);
7176 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
7177 if (result != ISC_R_SUCCESS)
7180 zmgr->transfersin = 10;
7181 zmgr->transfersperns = 2;
7183 /* Create the zone task pool. */
7184 result = isc_taskpool_create(taskmgr, mctx,
7185 8 /* XXX */, 2, &zmgr->zonetasks);
7186 if (result != ISC_R_SUCCESS)
7189 /* Create a single task for queueing of SOA queries. */
7190 result = isc_task_create(taskmgr, 1, &zmgr->task);
7191 if (result != ISC_R_SUCCESS)
7193 isc_task_setname(zmgr->task, "zmgr", zmgr);
7194 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
7196 if (result != ISC_R_SUCCESS)
7198 /* default to 20 refresh queries / notifies per second. */
7199 isc_interval_set(&interval, 0, 1000000000/2);
7200 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
7201 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7202 isc_ratelimiter_setpertic(zmgr->rl, 10);
7206 ISC_LIST_INIT(zmgr->high);
7207 ISC_LIST_INIT(zmgr->low);
7209 result = isc_mutex_init(&zmgr->iolock);
7210 if (result != ISC_R_SUCCESS)
7213 zmgr->magic = ZONEMGR_MAGIC;
7216 return (ISC_R_SUCCESS);
7220 DESTROYLOCK(&zmgr->iolock);
7223 isc_ratelimiter_detach(&zmgr->rl);
7225 isc_task_detach(&zmgr->task);
7227 isc_taskpool_destroy(&zmgr->zonetasks);
7229 isc_rwlock_destroy(&zmgr->rwlock);
7231 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
7232 isc_mem_detach(&mctx);
7237 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7238 isc_result_t result;
7240 REQUIRE(DNS_ZONE_VALID(zone));
7241 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7243 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7245 REQUIRE(zone->task == NULL);
7246 REQUIRE(zone->timer == NULL);
7247 REQUIRE(zone->zmgr == NULL);
7249 isc_taskpool_gettask(zmgr->zonetasks,
7250 dns_name_hash(dns_zone_getorigin(zone),
7255 * Set the task name. The tag will arbitrarily point to one
7256 * of the zones sharing the task (in practice, the one
7257 * to be managed last).
7259 isc_task_setname(zone->task, "zone", zone);
7261 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
7263 zone->task, zone_timer, zone,
7265 if (result != ISC_R_SUCCESS)
7268 * The timer "holds" a iref.
7271 INSIST(zone->irefs != 0);
7273 ISC_LIST_APPEND(zmgr->zones, zone, link);
7280 isc_task_detach(&zone->task);
7284 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7289 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7290 isc_boolean_t free_now = ISC_FALSE;
7292 REQUIRE(DNS_ZONE_VALID(zone));
7293 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7294 REQUIRE(zone->zmgr == zmgr);
7296 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7299 ISC_LIST_UNLINK(zmgr->zones, zone, link);
7302 if (zmgr->refs == 0)
7303 free_now = ISC_TRUE;
7306 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7310 ENSURE(zone->zmgr == NULL);
7314 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
7315 REQUIRE(DNS_ZONEMGR_VALID(source));
7316 REQUIRE(target != NULL && *target == NULL);
7318 RWLOCK(&source->rwlock, isc_rwlocktype_write);
7319 REQUIRE(source->refs > 0);
7321 INSIST(source->refs > 0);
7322 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
7327 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
7328 dns_zonemgr_t *zmgr;
7329 isc_boolean_t free_now = ISC_FALSE;
7331 REQUIRE(zmgrp != NULL);
7333 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7335 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7337 if (zmgr->refs == 0)
7338 free_now = ISC_TRUE;
7339 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7346 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
7349 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7351 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7352 for (p = ISC_LIST_HEAD(zmgr->zones);
7354 p = ISC_LIST_NEXT(p, link))
7356 dns_zone_maintenance(p);
7358 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7361 * Recent configuration changes may have increased the
7362 * amount of available transfers quota. Make sure any
7363 * transfers currently blocked on quota get started if
7366 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7367 zmgr_resume_xfrs(zmgr, ISC_TRUE);
7368 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7369 return (ISC_R_SUCCESS);
7373 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
7375 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7377 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7378 zmgr_resume_xfrs(zmgr, ISC_TRUE);
7379 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
7383 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
7384 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7386 isc_ratelimiter_shutdown(zmgr->rl);
7388 if (zmgr->task != NULL)
7389 isc_task_destroy(&zmgr->task);
7390 if (zmgr->zonetasks != NULL)
7391 isc_taskpool_destroy(&zmgr->zonetasks);
7395 zonemgr_free(dns_zonemgr_t *zmgr) {
7398 INSIST(zmgr->refs == 0);
7399 INSIST(ISC_LIST_EMPTY(zmgr->zones));
7403 DESTROYLOCK(&zmgr->iolock);
7404 isc_ratelimiter_detach(&zmgr->rl);
7406 isc_rwlock_destroy(&zmgr->rwlock);
7408 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
7409 isc_mem_detach(&mctx);
7413 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
7414 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7416 zmgr->transfersin = value;
7420 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
7421 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7423 return (zmgr->transfersin);
7427 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
7428 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7430 zmgr->transfersperns = value;
7434 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
7435 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7437 return (zmgr->transfersperns);
7441 * Try to start a new incoming zone transfer to fill a quota
7442 * slot that was just vacated.
7445 * The zone manager is locked by the caller.
7448 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
7452 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
7456 isc_result_t result;
7457 next = ISC_LIST_NEXT(zone, statelink);
7458 result = zmgr_start_xfrin_ifquota(zmgr, zone);
7459 if (result == ISC_R_SUCCESS) {
7463 * We successfully filled the slot. We're done.
7466 } else if (result == ISC_R_QUOTA) {
7468 * Not enough quota. This is probably the per-server
7469 * quota, because we usually get called when a unit of
7470 * global quota has just been freed. Try the next
7471 * zone, it may succeed if it uses another master.
7475 dns_zone_log(zone, ISC_LOG_DEBUG(1),
7476 "starting zone transfer: %s",
7477 isc_result_totext(result));
7484 * Try to start an incoming zone transfer for 'zone', quota permitting.
7487 * The zone manager is locked by the caller.
7490 * ISC_R_SUCCESS There was enough quota and we attempted to
7491 * start a transfer. zone_xfrdone() has been or will
7493 * ISC_R_QUOTA Not enough quota.
7497 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
7498 dns_peer_t *peer = NULL;
7499 isc_netaddr_t masterip;
7500 isc_uint32_t nxfrsin, nxfrsperns;
7502 isc_uint32_t maxtransfersin, maxtransfersperns;
7506 * Find any configured information about the server we'd
7507 * like to transfer this zone from.
7509 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
7510 (void)dns_peerlist_peerbyaddr(zone->view->peers,
7514 * Determine the total maximum number of simultaneous
7515 * transfers allowed, and the maximum for this specific
7518 maxtransfersin = zmgr->transfersin;
7519 maxtransfersperns = zmgr->transfersperns;
7521 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
7524 * Count the total number of transfers that are in progress,
7525 * and the number of transfers in progress from this master.
7526 * We linearly scan a list of all transfers; if this turns
7527 * out to be too slow, we could hash on the master address.
7529 nxfrsin = nxfrsperns = 0;
7530 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
7532 x = ISC_LIST_NEXT(x, statelink))
7535 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
7537 if (isc_netaddr_equal(&xip, &masterip))
7541 /* Enforce quota. */
7542 if (nxfrsin >= maxtransfersin)
7543 return (ISC_R_QUOTA);
7545 if (nxfrsperns >= maxtransfersperns)
7546 return (ISC_R_QUOTA);
7549 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
7550 * list and send it an event to let it start the actual transfer in the
7551 * context of its own task.
7553 e = isc_event_allocate(zmgr->mctx, zmgr,
7554 DNS_EVENT_ZONESTARTXFRIN,
7555 got_transfer_quota, zone,
7556 sizeof(isc_event_t));
7558 return (ISC_R_NOMEMORY);
7561 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
7562 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
7563 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
7564 zone->statelist = &zmgr->xfrin_in_progress;
7565 isc_task_send(zone->task, &e);
7566 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
7569 return (ISC_R_SUCCESS);
7573 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
7575 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7576 REQUIRE(iolimit > 0);
7578 zmgr->iolimit = iolimit;
7582 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
7584 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7586 return (zmgr->iolimit);
7590 * Get permission to request a file handle from the OS.
7591 * An event will be sent to action when one is available.
7592 * There are two queues available (high and low), the high
7593 * queue will be serviced before the low one.
7595 * zonemgr_putio() must be called after the event is delivered to
7600 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
7601 isc_task_t *task, isc_taskaction_t action, void *arg,
7605 isc_boolean_t queue;
7607 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7608 REQUIRE(iop != NULL && *iop == NULL);
7610 io = isc_mem_get(zmgr->mctx, sizeof(*io));
7612 return (ISC_R_NOMEMORY);
7613 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
7614 action, arg, sizeof(*io->event));
7615 if (io->event == NULL) {
7616 isc_mem_put(zmgr->mctx, io, sizeof(*io));
7617 return (ISC_R_NOMEMORY);
7622 isc_task_attach(task, &io->task);
7623 ISC_LINK_INIT(io, link);
7624 io->magic = IO_MAGIC;
7626 LOCK(&zmgr->iolock);
7628 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
7631 ISC_LIST_APPEND(zmgr->high, io, link);
7633 ISC_LIST_APPEND(zmgr->low, io, link);
7635 UNLOCK(&zmgr->iolock);
7639 isc_task_send(io->task, &io->event);
7641 return (ISC_R_SUCCESS);
7645 zonemgr_putio(dns_io_t **iop) {
7648 dns_zonemgr_t *zmgr;
7650 REQUIRE(iop != NULL);
7652 REQUIRE(DNS_IO_VALID(io));
7656 INSIST(!ISC_LINK_LINKED(io, link));
7657 INSIST(io->event == NULL);
7660 isc_task_detach(&io->task);
7662 isc_mem_put(zmgr->mctx, io, sizeof(*io));
7664 LOCK(&zmgr->iolock);
7665 INSIST(zmgr->ioactive > 0);
7667 next = HEAD(zmgr->high);
7669 next = HEAD(zmgr->low);
7672 ISC_LIST_UNLINK(zmgr->high, next, link);
7674 ISC_LIST_UNLINK(zmgr->low, next, link);
7675 INSIST(next->event != NULL);
7677 UNLOCK(&zmgr->iolock);
7679 isc_task_send(next->task, &next->event);
7683 zonemgr_cancelio(dns_io_t *io) {
7684 isc_boolean_t send_event = ISC_FALSE;
7686 REQUIRE(DNS_IO_VALID(io));
7689 * If we are queued to be run then dequeue.
7691 LOCK(&io->zmgr->iolock);
7692 if (ISC_LINK_LINKED(io, link)) {
7694 ISC_LIST_UNLINK(io->zmgr->high, io, link);
7696 ISC_LIST_UNLINK(io->zmgr->low, io, link);
7698 send_event = ISC_TRUE;
7699 INSIST(io->event != NULL);
7701 UNLOCK(&io->zmgr->iolock);
7703 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
7704 isc_task_send(io->task, &io->event);
7709 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
7712 isc_result_t result;
7714 buflen = strlen(path) + strlen(templat) + 2;
7716 buf = isc_mem_get(zone->mctx, buflen);
7720 result = isc_file_template(path, templat, buf, buflen);
7721 if (result != ISC_R_SUCCESS)
7724 result = isc_file_renameunique(path, buf);
7725 if (result != ISC_R_SUCCESS)
7728 dns_zone_log(zone, ISC_LOG_INFO, "saved '%s' as '%s'",
7732 isc_mem_put(zone->mctx, buf, buflen);
7736 /* Hook for ondestroy notifcation from a database. */
7739 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
7740 dns_db_t *db = event->sender;
7743 isc_event_free(&event);
7745 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
7746 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
7747 "database (%p) destroyed", (void*) db);
7752 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
7753 isc_interval_t interval;
7755 isc_uint32_t pertic;
7756 isc_result_t result;
7758 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7767 } else if (value <= 10) {
7769 ns = 1000000000 / value;
7773 ns = (1000000000 / value) * 10;
7777 isc_interval_set(&interval, s, ns);
7778 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
7779 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7780 isc_ratelimiter_setpertic(zmgr->rl, pertic);
7782 zmgr->serialqueryrate = value;
7786 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
7787 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7789 return (zmgr->serialqueryrate);
7793 dns_zone_forcereload(dns_zone_t *zone) {
7794 REQUIRE(DNS_ZONE_VALID(zone));
7796 if (zone->type == dns_zone_master)
7800 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
7802 dns_zone_refresh(zone);
7806 dns_zone_isforced(dns_zone_t *zone) {
7807 REQUIRE(DNS_ZONE_VALID(zone));
7809 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
7813 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
7814 isc_result_t result = ISC_R_SUCCESS;
7818 if (zone->counters != NULL)
7820 result = dns_stats_alloccounters(zone->mctx, &zone->counters);
7822 if (zone->counters == NULL)
7824 dns_stats_freecounters(zone->mctx, &zone->counters);
7832 dns_zone_getstatscounters(dns_zone_t *zone) {
7833 return (zone->counters);
7837 dns_zone_dialup(dns_zone_t *zone) {
7839 REQUIRE(DNS_ZONE_VALID(zone));
7841 zone_debuglog(zone, "dns_zone_dialup", 3,
7842 "notify = %d, refresh = %d",
7843 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
7844 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
7846 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
7847 dns_zone_notify(zone);
7848 if (zone->type != dns_zone_master &&
7849 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
7850 dns_zone_refresh(zone);
7854 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
7855 REQUIRE(DNS_ZONE_VALID(zone));
7858 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
7859 DNS_ZONEFLG_DIALREFRESH |
7860 DNS_ZONEFLG_NOREFRESH);
7862 case dns_dialuptype_no:
7864 case dns_dialuptype_yes:
7865 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
7866 DNS_ZONEFLG_DIALREFRESH |
7867 DNS_ZONEFLG_NOREFRESH));
7869 case dns_dialuptype_notify:
7870 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
7872 case dns_dialuptype_notifypassive:
7873 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
7874 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7876 case dns_dialuptype_refresh:
7877 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
7878 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7880 case dns_dialuptype_passive:
7881 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
7890 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
7891 isc_result_t result = ISC_R_SUCCESS;
7893 REQUIRE(DNS_ZONE_VALID(zone));
7896 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
7903 dns_zone_getkeydirectory(dns_zone_t *zone) {
7904 REQUIRE(DNS_ZONE_VALID(zone));
7906 return (zone->keydirectory);
7910 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
7912 unsigned int count = 0;
7914 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
7916 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7918 case DNS_ZONESTATE_XFERRUNNING:
7919 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
7921 zone = ISC_LIST_NEXT(zone, statelink))
7924 case DNS_ZONESTATE_XFERDEFERRED:
7925 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
7927 zone = ISC_LIST_NEXT(zone, statelink))
7930 case DNS_ZONESTATE_SOAQUERY:
7931 for (zone = ISC_LIST_HEAD(zmgr->zones);
7933 zone = ISC_LIST_NEXT(zone, link))
7934 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
7937 case DNS_ZONESTATE_ANY:
7938 for (zone = ISC_LIST_HEAD(zmgr->zones);
7940 zone = ISC_LIST_NEXT(zone, link)) {
7941 dns_view_t *view = zone->view;
7942 if (view != NULL && strcmp(view->name, "_bind") == 0)
7951 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
7957 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
7958 isc_boolean_t ok = ISC_TRUE;
7959 isc_boolean_t fail = ISC_FALSE;
7960 char namebuf[DNS_NAME_FORMATSIZE];
7961 char namebuf2[DNS_NAME_FORMATSIZE];
7962 char typebuf[DNS_RDATATYPE_FORMATSIZE];
7963 int level = ISC_LOG_WARNING;
7966 REQUIRE(DNS_ZONE_VALID(zone));
7968 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
7969 return (ISC_R_SUCCESS);
7971 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
7972 level = ISC_LOG_ERROR;
7976 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
7978 dns_name_format(name, namebuf, sizeof(namebuf));
7979 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
7980 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
7981 dns_result_totext(DNS_R_BADOWNERNAME));
7983 return (DNS_R_BADOWNERNAME);
7986 dns_name_init(&bad, NULL);
7987 ok = dns_rdata_checknames(rdata, name, &bad);
7989 dns_name_format(name, namebuf, sizeof(namebuf));
7990 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
7991 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
7992 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
7993 namebuf2, dns_result_totext(DNS_R_BADNAME));
7995 return (DNS_R_BADNAME);
7998 return (ISC_R_SUCCESS);
8002 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
8003 REQUIRE(DNS_ZONE_VALID(zone));
8004 zone->checkmx = checkmx;
8008 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
8009 REQUIRE(DNS_ZONE_VALID(zone));
8010 zone->checksrv = checksrv;
8014 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
8015 REQUIRE(DNS_ZONE_VALID(zone));
8016 zone->checkns = checkns;
8020 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
8021 REQUIRE(DNS_ZONE_VALID(zone));
8024 zone->isself = isself;
8025 zone->isselfarg = arg;
8030 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
8031 REQUIRE(DNS_ZONE_VALID(zone));
8034 zone->notifydelay = delay;
8039 dns_zone_getnotifydelay(dns_zone_t *zone) {
8040 REQUIRE(DNS_ZONE_VALID(zone));
8042 return (zone->notifydelay);