📄 zone.c
字号:
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->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->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->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; ISC_LINK_INIT(zone, statelink); zone->statelist = NULL; zone->counters = 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_mutex; 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_mutex: DESTROYLOCK(&zone->lock); return (ISC_R_NOMEMORY);}/* * 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) dns_db_detach(&zone->db); 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 */ 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_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 (zone->db_argv[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, 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);}static isc_result_tdns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { char *copy; if (value != NULL) { copy = isc_mem_strdup(zone->mctx, value); if (copy == NULL) return (ISC_R_NOMEMORY); } else { copy = NULL; } if (*field != NULL) isc_mem_free(zone->mctx, *field); *field = copy; return (ISC_R_SUCCESS);}isc_result_tdns_zone_setfile(dns_zone_t *zone, const char *file) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); result = dns_zone_setstring(zone, &zone->masterfile, file); if (result == ISC_R_SUCCESS) result = default_journal(zone); UNLOCK_ZONE(zone); return (result);}const char *dns_zone_getfile(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->masterfile);}static isc_result_tdefault_journal(dns_zone_t *zone) { isc_result_t result; char *journal; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); if (zone->masterfile != NULL) { /* Calculate string length including '\0'. */ int len = strlen(zone->masterfile) + sizeof(".jnl"); journal = isc_mem_allocate(zone->mctx, len); if (journal == NULL) return (ISC_R_NOMEMORY); strcpy(journal, zone->masterfile); strcat(journal, ".jnl"); } else { journal = NULL; } result = dns_zone_setstring(zone, &zone->journal, journal); if (journal != NULL) isc_mem_free(zone->mctx, journal); return (result);}isc_result_tdns_zone_setjournal(dns_zone_t *zone, const char *journal) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); result = dns_zone_setstring(zone, &zone->journal, journal); UNLOCK_ZONE(zone); return (result);}char *dns_zone_getjournal(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->journal);}/* * Return true iff the zone is "dynamic", in the sense that the zone's * master file (if any) is written by the server, rather than being * updated manually and read by the server. * * This is true for slave zones, stub zones, and zones that allow * dynamic updates either by having an update policy ("ssutable") * or an "allow-update" ACL with a value other than exactly "{ none; }". */static isc_boolean_tzone_isdynamic(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (ISC_TF(zone->type == dns_zone_slave || zone->type == dns_zone_stub || (!zone->update_disabled && zone->ssutable != NULL) || (!zone->update_disabled && zone->update_acl != NULL && ! (zone->update_acl->length == 1 && zone->update_acl->elements[0].negative == ISC_TRUE && zone->update_acl->elements[0].type == dns_aclelementtype_any))));}static isc_result_tzone_load(dns_zone_t *zone, unsigned int flags) { isc_result_t result; isc_time_t now; isc_time_t loadtime, filetime; dns_db_t *db = NULL; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); TIME_NOW(&now); INSIST(zone->type != dns_zone_none); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { result = ISC_R_SUCCESS; goto cleanup; } if (zone->db != NULL && zone->masterfile == NULL) { /* * The zone has no master file configured, but it already * has a database. It could be the built-in * version.bind. CH zone, a zone with a persistent * database being reloaded, or maybe a zone that * used to have a master file but whose configuration * was changed so that it no longer has one. Do nothing. */ result = ISC_R_SUCCESS; goto cleanup; } if (zone->db != NULL && zone_isdynamic(zone)) { /* * This is a slave, stub, or dynamically updated * zone being reloaded. Do nothing - the database * we already have is guaranteed to be up-to-date. */ if (zone->type == dns_zone_master) result = DNS_R_DYNAMIC; else result = ISC_R_SUCCESS; goto cleanup; } /* * Don't do the load if the file that stores the zone is older * than the last time the zone was loaded. If the zone has not * been loaded yet, zone->loadtime will be the epoch. */ if (zone->masterfile != NULL && ! isc_time_isepoch(&zone->loadtime)) { /* * The file is already loaded. If we are just doing a * "rndc reconfig", we are done. */ if ((flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { result = ISC_R_SUCCESS; goto cleanup; } if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE)) { result = isc_file_getmodtime(zone->masterfile, &filetime); if (result == ISC_R_SUCCESS && isc_time_compare(&filetime, &zone->loadtime) < 0) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "skipping load: master file older " "than last load"); result = DNS_R_UPTODATE; goto cleanup; } } } INSIST(zone->db_argc >= 1); if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) && (strcmp(zone->db_argv[0], "rbt") == 0 || strcmp(zone->db_argv[0], "rbt64") == 0)) { if (zone->masterfile == NULL || !isc_file_exists(zone->masterfile)) { if (zone->masterfile != NULL) dns_zone_log(zone, ISC_LOG_DEBUG(1), "no master file"); zone->refreshtime = now; if (zone->task != NULL) zone_settimer(zone, &now); result = ISC_R_SUCCESS; goto cleanup; } } dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load"); /* * Store the current time before the zone is loaded, so that if the * file changes between the time of the load and the time that * zone->loadtime is set, then the file will still be reloaded * the next time dns_zone_load is called. */ TIME_NOW(&loadtime); result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, (zone->type == dns_zone_stub) ? dns_dbtype_stub : dns_dbtype_zone, zone->rdclass, zone->db_argc - 1, zone->db_argv + 1,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -