📄 zone.c
字号:
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) { return (dns_zone_setfile2(zone, file, dns_masterformat_text));}isc_result_tdns_zone_setfile2(dns_zone_t *zone, const char *file, dns_masterformat_t format) { 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) { zone->masterformat = format; 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; } /* * 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); /* * 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) { /* * The file is already loaded. If we are just doing a * "rndc reconfig", we are done. */ if (!isc_time_isepoch(&zone->loadtime) && (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { result = ISC_R_SUCCESS; goto cleanup; } result = isc_file_getmodtime(zone->masterfile, &filetime); if (result == ISC_R_SUCCESS) { if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && 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; } loadtime = filetime; } } INSIST(zone->db_argc >= 1); /* * Built in zones don't need to be reloaded. */ if (zone->type == dns_zone_master && strcmp(zone->db_argv[0], "_builtin") == 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { result = ISC_R_SUCCESS; goto cleanup; } 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"); 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, &db); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "loading zone: creating database: %s", isc_result_totext(result)); goto cleanup; } dns_db_settask(db, zone->task); if (! dns_db_ispersistent(db)) { if (zone->masterfile != NULL) { result = zone_startload(db, zone, loadtime); } else { result = DNS_R_NOMASTERFILE; if (zone->type == dns_zone_master) { dns_zone_log(zone, ISC_LOG_ERROR, "loading zone: " "no master file configured"); goto cleanup; } dns_zone_log(zone, ISC_LOG_INFO, "loading zone: " "no master file configured: continuing"); } } if (result == DNS_R_CONTINUE) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); goto cleanup; } result = zone_postload(zone, db, loadtime, result); cleanup: UNLOCK_ZONE(zone); if (db != NULL) dns_db_detach(&db); return (result);}isc_result_tdns_zone_load(dns_zone_t *zone) { return (zone_load(zone, 0));}isc_result_tdns_zone_loadnew(dns_zone_t *zone) { return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));}static voidzone_gotreadhandle(isc_task_t *task, isc_event_t *event) { dns_load_t *load = event->ev_arg; isc_result_t result = ISC_R_SUCCESS; unsigned int options; REQUIRE(DNS_LOAD_VALID(load)); if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) result = ISC_R_CANCELED; isc_event_free(&event); if (result == ISC_R_CANCELED) goto fail; options = DNS_MASTER_ZONE; if (load->zone->type == dns_zone_slave) options |= DNS_MASTER_SLAVE; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNS)) options |= DNS_MASTER_CHECKNS; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_FATALNS)) options |= DNS_MASTER_FATALNS; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMES)) options |= DNS_MASTER_CHECKNAMES; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMESFAIL)) options |= DNS_MASTER_CHECKNAMESFAIL; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMX)) options |= DNS_MASTER_CHECKMX; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMXFAIL)) options |= DNS_MASTER_CHECKMXFAIL; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKWILDCARD)) options |= DNS_MASTER_CHECKWILDCARD; result = dns_master_loadfileinc2(load->zone->masterfile, dns_db_origin(load->db), dns_db_origin(load->db), load->zone->rdclass, options, &load->callbacks, task, zone_loaddone, load, &load->zone->lctx, load->zone->mctx, load->zone->masterformat); if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && result != DNS_R_SEENINCLUDE) goto fail; return; fail: zone_loaddone(load, result);}static voidzone_gotwritehandle(isc_task_t *task, isc_event_t *event) { const char me[] = "zone_gotwritehandle"; dns_zone_t *zone = event->ev_arg; isc_result_t result = ISC_R_SUCCESS; dns_dbversion_t *version = NULL; REQUIRE(DNS_ZONE_VALID(zone)); INSIST(task == zone->task); ENTER; if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) result = ISC_R_CANCELED; isc_event_free(&event); if (result == ISC_R_CANCELED) goto fail; LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); dns_db_currentversion(zone->db, &version); result = dns_master_dumpinc2(zone->mctx, zone->db, version, &dns_master_style_default, zone->masterfile, zone->task, dump_done, zone, &zone->dctx, zone->masterformat); dns_db_closeversion(zone->db, &version, ISC_FALSE); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); if (result != DNS_R_CONTINUE) goto fail; return; fail: dump_done(zone, result);}static isc_result_tzone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { dns_load_t *load; isc_result_t result; isc_result_t tresult; unsigned int options; options = DNS_MASTER_ZONE; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) options |= DNS_MASTER_MANYERRORS; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) options |= DNS_MASTER_CHECKNS; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) options |= DNS_MASTER_FATALNS; if (zone->type == dns_zone_slave) options |= DNS_MASTER_SLAVE; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) options |= DNS_MASTER_CHECKNAMES; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) options |= DNS_MASTER_CHECKNAMESFAIL; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) options |= DNS_MASTER_CHECKMX; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) options |= DNS_MASTER_CHECKMXFAIL; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) options |= DNS_MASTER_CHECKWILDCARD; if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) { load = isc_mem_get(zone->mctx, sizeof(*load)); if (load == NULL) return (ISC_R_NOMEMORY); load->mctx = NULL; load->zone = NULL; load->db = NULL; load->loadtime = loadtime; load->magic = LOAD_MAGIC; isc_mem_attach(zone->mctx, &load->mctx); zone_iattach(zone, &load->zone); dns_db_attach(db, &load->db); dns_rdatacallbacks_init(&load->callbacks); result = dns_db_beginload(db, &load->callbacks.add, &load->callbacks.add_private); if (result != ISC_R_SUCCESS) goto cleanup; result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task, zone_gotreadhandle, load, &zone->readio); if (result != ISC_R_SUCCESS) { /* * We can't report multiple errors so ignore * the result of dns_db_endload(). */ (void)dns_db_endload(load->db, &load->callbacks.add_private); goto cleanup; } else result = DNS_R_CONTINUE; } else { dns_rdatacallbacks_t callbacks; dns_rdatacallbacks_init(&callbacks); result = dns_db_beginload(db, &callbacks.add, &callbacks.add_private); if (result != ISC_R_SUCCESS) return (result); result = dns_master_loadfile2(zone->masterfile, &zone->origin, &zone->origin, zone->rdclass, options, &callbacks, zone->mctx, zone->masterformat); tresult = dns_db_endload(db, &callbacks.add_private); if (result == ISC_R_SUCCESS) result = tresult; } return (result); cleanup: load->magic = 0; dns_db_detach(&load->db); zone_idetach(&load->zone); isc_mem_detach(&load->mctx); isc_mem_put(zone->mctx, load, sizeof(*load)); return (result);}static isc_boolean_tzone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, dns_name_t *owner){ isc_result_t result; char ownerbuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; char altbuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t fixed; dns_name_t *foundname; int level; /* * Outside of zone. */ if (!dns_name_issubdomain(name, &zone->origin)) { if (zone->checkmx != NULL) return ((zone->checkmx)(zone, name, owner)); return (ISC_TRUE); } if (zone->type == dns_zone_master)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -