📄 zone.c
字号:
static void zone_maintenance(dns_zone_t *zone);static void zone_notify(dns_zone_t *zone, isc_time_t *now);static void dump_done(void *arg, isc_result_t result);#define ENTER zone_debuglog(zone, me, 1, "enter")static const unsigned int dbargc_default = 1;static const char *dbargv_default[] = { "rbt" };#define DNS_ZONE_JITTER_ADD(a, b, c) \ do { \ isc_interval_t _i; \ isc_uint32_t _j; \ _j = isc_random_jitter((b), (b)/4); \ isc_interval_set(&_i, _j, 0); \ if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ dns_zone_log(zone, ISC_LOG_WARNING, \ "epoch approaching: upgrade required: " \ "now + %s failed", #b); \ isc_interval_set(&_i, _j/2, 0); \ (void)isc_time_add((a), &_i, (c)); \ } \ } while (0)#define DNS_ZONE_TIME_ADD(a, b, c) \ do { \ isc_interval_t _i; \ isc_interval_set(&_i, (b), 0); \ if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ dns_zone_log(zone, ISC_LOG_WARNING, \ "epoch approaching: upgrade required: " \ "now + %s failed", #b); \ isc_interval_set(&_i, (b)/2, 0); \ (void)isc_time_add((a), &_i, (c)); \ } \ } while (0)/*** *** Public functions. ***/isc_result_tdns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { isc_result_t result; dns_zone_t *zone; isc_time_t now; REQUIRE(zonep != NULL && *zonep == NULL); REQUIRE(mctx != NULL); TIME_NOW(&now); zone = isc_mem_get(mctx, sizeof(*zone)); if (zone == NULL) return (ISC_R_NOMEMORY); zone->mctx = NULL; isc_mem_attach(mctx, &zone->mctx); result = isc_mutex_init(&zone->lock); if (result != ISC_R_SUCCESS) goto free_zone; result = ZONEDB_INITLOCK(&zone->dblock); if (result != ISC_R_SUCCESS) goto free_mutex; /* XXX MPA check that all elements are initialised */#ifdef DNS_ZONE_CHECKLOCK zone->locked = ISC_FALSE;#endif zone->db = NULL; zone->zmgr = NULL; ISC_LINK_INIT(zone, link); result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ if (result != ISC_R_SUCCESS) goto free_dblock; zone->irefs = 0; dns_name_init(&zone->origin, NULL); zone->masterfile = NULL; zone->masterformat = dns_masterformat_none; zone->keydirectory = NULL; zone->journalsize = -1; zone->journal = NULL; zone->rdclass = dns_rdataclass_none; zone->type = dns_zone_none; zone->flags = 0; zone->options = 0; zone->db_argc = 0; zone->db_argv = NULL; isc_time_settoepoch(&zone->expiretime); isc_time_settoepoch(&zone->refreshtime); isc_time_settoepoch(&zone->dumptime); isc_time_settoepoch(&zone->loadtime); zone->notifytime = now; zone->serial = 0; zone->refresh = DNS_ZONE_DEFAULTREFRESH; zone->retry = DNS_ZONE_DEFAULTRETRY; zone->expire = 0; zone->minimum = 0; zone->maxrefresh = DNS_ZONE_MAXREFRESH; zone->minrefresh = DNS_ZONE_MINREFRESH; zone->maxretry = DNS_ZONE_MAXRETRY; zone->minretry = DNS_ZONE_MINRETRY; zone->masters = NULL; zone->masterkeynames = NULL; zone->mastersok = NULL; zone->masterscnt = 0; zone->curmaster = 0; zone->notify = NULL; zone->notifytype = dns_notifytype_yes; zone->notifycnt = 0; zone->task = NULL; zone->update_acl = NULL; zone->forward_acl = NULL; zone->notify_acl = NULL; zone->query_acl = NULL; zone->xfr_acl = NULL; zone->update_disabled = ISC_FALSE; zone->zero_no_soa_ttl = ISC_TRUE; zone->check_names = dns_severity_ignore; zone->request = NULL; zone->lctx = NULL; zone->readio = NULL; zone->dctx = NULL; zone->writeio = NULL; zone->timer = NULL; zone->idlein = DNS_DEFAULT_IDLEIN; zone->idleout = DNS_DEFAULT_IDLEOUT; ISC_LIST_INIT(zone->notifies); isc_sockaddr_any(&zone->notifysrc4); isc_sockaddr_any6(&zone->notifysrc6); isc_sockaddr_any(&zone->xfrsource4); isc_sockaddr_any6(&zone->xfrsource6); isc_sockaddr_any(&zone->altxfrsource4); isc_sockaddr_any6(&zone->altxfrsource6); zone->xfr = NULL; zone->tsigkey = NULL; zone->maxxfrin = MAX_XFER_TIME; zone->maxxfrout = MAX_XFER_TIME; zone->ssutable = NULL; zone->sigvalidityinterval = 30 * 24 * 3600; zone->view = NULL; zone->acache = NULL; zone->checkmx = NULL; zone->checksrv = NULL; zone->checkns = NULL; ISC_LINK_INIT(zone, statelink); zone->statelist = NULL; zone->counters = NULL; zone->notifydelay = 5; zone->isself = NULL; zone->isselfarg = NULL; zone->magic = ZONE_MAGIC; /* Must be after magic is set. */ result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default); if (result != ISC_R_SUCCESS) goto free_erefs; ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL, NULL); *zonep = zone; return (ISC_R_SUCCESS); free_erefs: isc_refcount_decrement(&zone->erefs, NULL); isc_refcount_destroy(&zone->erefs); free_dblock: ZONEDB_DESTROYLOCK(&zone->dblock); free_mutex: DESTROYLOCK(&zone->lock); free_zone: isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); return (result);}/* * Free a zone. Because we require that there be no more * outstanding events or references, no locking is necessary. */static voidzone_free(dns_zone_t *zone) { isc_mem_t *mctx = NULL; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(isc_refcount_current(&zone->erefs) == 0); REQUIRE(zone->irefs == 0); REQUIRE(!LOCKED_ZONE(zone)); REQUIRE(zone->timer == NULL); /* * Managed objects. Order is important. */ if (zone->request != NULL) dns_request_destroy(&zone->request); /* XXXMPA */ INSIST(zone->readio == NULL); INSIST(zone->statelist == NULL); INSIST(zone->writeio == NULL); if (zone->task != NULL) isc_task_detach(&zone->task); if (zone->zmgr) dns_zonemgr_releasezone(zone->zmgr, zone); /* Unmanaged objects */ if (zone->masterfile != NULL) isc_mem_free(zone->mctx, zone->masterfile); zone->masterfile = NULL; if (zone->keydirectory != NULL) isc_mem_free(zone->mctx, zone->keydirectory); zone->keydirectory = NULL; zone->journalsize = -1; if (zone->journal != NULL) isc_mem_free(zone->mctx, zone->journal); zone->journal = NULL; if (zone->counters != NULL) dns_stats_freecounters(zone->mctx, &zone->counters); if (zone->db != NULL) zone_detachdb(zone); if (zone->acache != NULL) dns_acache_detach(&zone->acache); zone_freedbargs(zone); RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0) == ISC_R_SUCCESS); RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS); zone->check_names = dns_severity_ignore; if (zone->update_acl != NULL) dns_acl_detach(&zone->update_acl); if (zone->forward_acl != NULL) dns_acl_detach(&zone->forward_acl); if (zone->notify_acl != NULL) dns_acl_detach(&zone->notify_acl); if (zone->query_acl != NULL) dns_acl_detach(&zone->query_acl); if (zone->xfr_acl != NULL) dns_acl_detach(&zone->xfr_acl); if (dns_name_dynamic(&zone->origin)) dns_name_free(&zone->origin, zone->mctx); if (zone->ssutable != NULL) dns_ssutable_detach(&zone->ssutable); /* last stuff */ ZONEDB_DESTROYLOCK(&zone->dblock); DESTROYLOCK(&zone->lock); isc_refcount_destroy(&zone->erefs); zone->magic = 0; mctx = zone->mctx; isc_mem_put(mctx, zone, sizeof(*zone)); isc_mem_detach(&mctx);}/* * Single shot. */voiddns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(rdclass != dns_rdataclass_none); /* * Test and set. */ LOCK_ZONE(zone); REQUIRE(zone->rdclass == dns_rdataclass_none || zone->rdclass == rdclass); zone->rdclass = rdclass; UNLOCK_ZONE(zone);}dns_rdataclass_tdns_zone_getclass(dns_zone_t *zone){ REQUIRE(DNS_ZONE_VALID(zone)); return (zone->rdclass);}voiddns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifytype = notifytype; UNLOCK_ZONE(zone);}/* * Single shot. */voiddns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(type != dns_zone_none); /* * Test and set. */ LOCK_ZONE(zone); REQUIRE(zone->type == dns_zone_none || zone->type == type); zone->type = type; UNLOCK_ZONE(zone);}static voidzone_freedbargs(dns_zone_t *zone) { unsigned int i; /* Free the old database argument list. */ if (zone->db_argv != NULL) { for (i = 0; i < zone->db_argc; i++) isc_mem_free(zone->mctx, zone->db_argv[i]); isc_mem_put(zone->mctx, zone->db_argv, zone->db_argc * sizeof(*zone->db_argv)); } zone->db_argc = 0; zone->db_argv = NULL;}isc_result_tdns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { size_t size = 0; unsigned int i; isc_result_t result = ISC_R_SUCCESS; void *mem; char **tmp, *tmp2; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(argv != NULL && *argv == NULL); LOCK_ZONE(zone); size = (zone->db_argc + 1) * sizeof(char *); for (i = 0; i < zone->db_argc; i++) size += strlen(zone->db_argv[i]) + 1; mem = isc_mem_allocate(mctx, size); if (mem != NULL) { tmp = mem; tmp2 = mem; tmp2 += (zone->db_argc + 1) * sizeof(char *); for (i = 0; i < zone->db_argc; i++) { *tmp++ = tmp2; strcpy(tmp2, zone->db_argv[i]); tmp2 += strlen(tmp2) + 1; } *tmp = NULL; } else result = ISC_R_NOMEMORY; UNLOCK_ZONE(zone); *argv = mem; return (result);}isc_result_tdns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, const char * const *dbargv) { isc_result_t result = ISC_R_SUCCESS; char **new = NULL; unsigned int i; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(dbargc >= 1); REQUIRE(dbargv != NULL); LOCK_ZONE(zone); /* Set up a new database argument list. */ new = isc_mem_get(zone->mctx, dbargc * sizeof(*new)); if (new == NULL) goto nomem; for (i = 0; i < dbargc; i++) new[i] = NULL; for (i = 0; i < dbargc; i++) { new[i] = isc_mem_strdup(zone->mctx, dbargv[i]); if (new[i] == NULL) goto nomem; } /* Free the old list. */ zone_freedbargs(zone); zone->db_argc = dbargc; zone->db_argv = new; result = ISC_R_SUCCESS; goto unlock; nomem: if (new != NULL) { for (i = 0; i < dbargc; i++) if (new[i] != NULL) isc_mem_free(zone->mctx, new[i]); isc_mem_put(zone->mctx, new, dbargc * sizeof(*new)); } result = ISC_R_NOMEMORY; unlock: UNLOCK_ZONE(zone); return (result);}voiddns_zone_setview(dns_zone_t *zone, dns_view_t *view) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->view != NULL) dns_view_weakdetach(&zone->view); dns_view_weakattach(view, &zone->view); UNLOCK_ZONE(zone);}dns_view_t *dns_zone_getview(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->view);}isc_result_tdns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(origin != NULL); LOCK_ZONE(zone); if (dns_name_dynamic(&zone->origin)) { dns_name_free(&zone->origin, zone->mctx); dns_name_init(&zone->origin, NULL); } result = dns_name_dup(origin, zone->mctx, &zone->origin); UNLOCK_ZONE(zone); return (result);}voiddns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(acache != NULL); LOCK_ZONE(zone); if (zone->acache != NULL) dns_acache_detach(&zone->acache); dns_acache_attach(acache, &zone->acache); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { isc_result_t result; /* * If the zone reuses an existing DB, the DB needs to be * set in the acache explicitly. We can safely ignore the * case where the DB is already set. If other error happens, * the acache will not work effectively. */ result = dns_acache_setdb(acache, zone->db); if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "dns_acache_setdb() failed: %s", isc_result_totext(result)); } } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone);}static isc_result_tdns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { char *copy; if (value != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -