📄 zone.c
字号:
else if (result != DNS_R_NOMASTERFILE) dns_zone_log(zone, ISC_LOG_ERROR, "loading from master file %s " "failed: %s", zone->masterfile, dns_result_totext(result)); } else dns_zone_log(zone, ISC_LOG_ERROR, "loading from master file %s failed: %s", zone->masterfile, dns_result_totext(result)); goto cleanup; } dns_zone_log(zone, ISC_LOG_DEBUG(2), "number of nodes in database: %u", dns_db_nodecount(db)); if (result == DNS_R_SEENINCLUDE) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); else DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); /* * Apply update log, if any, on initial load. */ if (zone->journal != NULL && ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { result = dns_journal_rollforward(zone->mctx, db, zone->journal); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND && result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL && result != ISC_R_RANGE) { dns_zone_log(zone, ISC_LOG_ERROR, "journal rollforward failed: %s", dns_result_totext(result)); goto cleanup; } if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { dns_zone_log(zone, ISC_LOG_ERROR, "journal rollforward failed: " "journal out of sync with zone"); goto cleanup; } dns_zone_log(zone, ISC_LOG_DEBUG(1), "journal rollforward completed " "successfully: %s", dns_result_totext(result)); if (result == ISC_R_SUCCESS) needdump = ISC_TRUE; } zone->loadtime = loadtime; dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded"); /* * Obtain ns, soa and cname counts for top of zone. */ INSIST(db != NULL); result = zone_get_from_db(zone, db, &nscount, &soacount, &serial, &refresh, &retry, &expire, &minimum, &errors); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "could not find NS and/or SOA records"); } /* * Master / Slave / Stub zones require both NS and SOA records at * the top of the zone. */ switch (zone->type) { case dns_zone_master: case dns_zone_slave: case dns_zone_stub: if (soacount != 1) { dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", soacount); result = DNS_R_BADZONE; } if (nscount == 0) { dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); result = DNS_R_BADZONE; } if (result != ISC_R_SUCCESS) goto cleanup; if (zone->type == dns_zone_master && errors != 0) { result = DNS_R_BADZONE; goto cleanup; } if (zone->type == dns_zone_master && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && !integrity_checks(zone, db)) { result = DNS_R_BADZONE; goto cleanup; } if (zone->db != NULL) { /* * This is checked in zone_replacedb() for slave zones * as they don't reload from disk. */ if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !isc_serial_gt(serial, zone->serial)) { isc_uint32_t serialmin, serialmax; INSIST(zone->type == dns_zone_master); serialmin = (zone->serial + 1) & 0xffffffffU; serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU; dns_zone_log(zone, ISC_LOG_ERROR, "ixfr-from-differences: " "new serial (%u) out of range " "[%u - %u]", serial, serialmin, serialmax); result = DNS_R_BADZONE; goto cleanup; } else if (!isc_serial_ge(serial, zone->serial)) dns_zone_log(zone, ISC_LOG_ERROR, "zone serial has gone backwards"); else if (serial == zone->serial && !hasinclude) dns_zone_log(zone, ISC_LOG_ERROR, "zone serial unchanged. " "zone may fail to transfer " "to slaves."); } zone->serial = serial; zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, zone->minretry, zone->maxretry); zone->expire = RANGE(expire, zone->refresh + zone->retry, DNS_MAX_EXPIRE); zone->minimum = minimum; DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); if (zone->type == dns_zone_slave || zone->type == dns_zone_stub) { isc_time_t t; isc_uint32_t delay; result = isc_file_getmodtime(zone->journal, &t); if (result != ISC_R_SUCCESS) result = isc_file_getmodtime(zone->masterfile, &t); if (result == ISC_R_SUCCESS) DNS_ZONE_TIME_ADD(&t, zone->expire, &zone->expiretime); else DNS_ZONE_TIME_ADD(&now, zone->retry, &zone->expiretime); delay = isc_random_jitter(zone->retry, (zone->retry * 3) / 4); DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); if (isc_time_compare(&zone->refreshtime, &zone->expiretime) >= 0) zone->refreshtime = now; } break; default: UNEXPECTED_ERROR(__FILE__, __LINE__, "unexpected zone type %d", zone->type); result = ISC_R_UNEXPECTED; goto cleanup; } /* * Check for weak DNSKEY's. */ if (zone->type == dns_zone_master) zone_check_dnskeys(zone, db);#if 0 /* destroy notification example. */ { isc_event_t *e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_DBDESTROYED, dns_zonemgr_dbdestroyed, zone, sizeof(isc_event_t)); dns_db_ondestroy(db, zone->task, &e); }#endif ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db != NULL) { result = zone_replacedb(zone, db, ISC_FALSE); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); if (result != ISC_R_SUCCESS) goto cleanup; } else { zone_attachdb(zone, db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); } result = ISC_R_SUCCESS; if (needdump) zone_needdump(zone, DNS_DUMP_DELAY); if (zone->task != NULL) zone_settimer(zone, &now); if (! dns_db_ispersistent(db)) dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", zone->serial, dns_db_issecure(db) ? " (signed)" : ""); return (result); cleanup: if (zone->type == dns_zone_slave || zone->type == dns_zone_stub) { if (zone->journal != NULL) zone_saveunique(zone, zone->journal, "jn-XXXXXXXX"); if (zone->masterfile != NULL) zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX"); /* Mark the zone for immediate refresh. */ zone->refreshtime = now; if (zone->task != NULL) zone_settimer(zone, &now); result = ISC_R_SUCCESS; } return (result);}static isc_boolean_texit_check(dns_zone_t *zone) { REQUIRE(LOCKED_ZONE(zone)); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) { /* * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. */ INSIST(isc_refcount_current(&zone->erefs) == 0); return (ISC_TRUE); } return (ISC_FALSE);}static isc_boolean_tzone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) { isc_result_t result; char namebuf[DNS_NAME_FORMATSIZE]; char altbuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t fixed; dns_name_t *foundname; int level; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) return (ISC_TRUE); if (zone->type == dns_zone_master) level = ISC_LOG_ERROR; else level = ISC_LOG_WARNING; dns_fixedname_init(&fixed); foundname = dns_fixedname_name(&fixed); result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, foundname, NULL, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); if (result == DNS_R_NXRRSET) { result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, NULL, foundname, NULL, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); } dns_name_format(name, namebuf, sizeof namebuf); if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || result == DNS_R_EMPTYNAME) { dns_zone_log(zone, level, "NS '%s' has no address records (A or AAAA)", namebuf); /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ return (ISC_TRUE); } if (result == DNS_R_CNAME) { dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)", namebuf); /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ return (ISC_TRUE); } if (result == DNS_R_DNAME) { dns_name_format(foundname, altbuf, sizeof altbuf); dns_zone_log(zone, level, "NS '%s' is below a DNAME '%s' (illegal)", namebuf, altbuf); /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ return (ISC_TRUE); } return (ISC_TRUE);}static isc_result_tzone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, unsigned int *nscount, unsigned int *errors){ isc_result_t result; unsigned int count = 0; unsigned int ecount = 0; dns_rdataset_t rdataset; dns_rdata_t rdata; dns_rdata_ns_t ns; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, dns_rdatatype_none, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto success; if (result != ISC_R_SUCCESS) goto invalidate_rdataset; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { if (errors != NULL && zone->rdclass == dns_rdataclass_in && (zone->type == dns_zone_master || zone->type == dns_zone_slave)) { dns_rdata_init(&rdata); dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (dns_name_issubdomain(&ns.name, &zone->origin) && !zone_check_ns(zone, db, &ns.name)) ecount++; } count++; result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); success: if (nscount != NULL) *nscount = count; if (errors != NULL) *errors = ecount; result = ISC_R_SUCCESS; invalidate_rdataset: dns_rdataset_invalidate(&rdataset); return (result);}static isc_result_tzone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, isc_uint32_t *expire, isc_uint32_t *minimum){ isc_result_t result; unsigned int count; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_soa_t soa; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, dns_rdatatype_none, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { if (soacount != NULL) *soacount = 0; if (serial != NULL) *serial = 0; if (refresh != NULL) *refresh = 0; if (retry != NULL) *retry = 0; if (expire != NULL) *expire = 0; if (minimum != NULL) *minimum = 0; result = ISC_R_SUCCESS; goto invalidate_rdataset; } if (result != ISC_R_SUCCESS) goto invalidate_rdataset; count = 0; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdata_init(&rdata); dns_rdataset_current(&rdataset, &rdata); count++; if (count == 1) { result = dns_rdata_tostruct(&rdata, &soa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); } result = dns_rdataset_next(&rdataset); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&rdataset); if (soacount != NULL) *soacount = count; if (count > 0) { if (serial != NULL) *serial = soa.serial; if (refresh != NULL) *refresh = soa.refresh; if (retry != NULL) *retry = soa.retry; if (expire != NULL) *expire = soa.expire; if (minimum != NULL) *minimum = soa.minimum; } result = ISC_R_SUCCESS; invalidate_rdataset: dns_rdataset_invalidate(&rdataset); return (result);}/* * zone must be locked. */static isc_result_tzone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, isc_uint32_t *expire, isc_uint32_t *minimum, unsigned int *errors){ dns_dbversion_t *version; isc_result_t result; isc_result_t answer = ISC_R_SUCCESS; dns_dbnode_t *node; REQUIRE(db != NULL); REQUIRE(zone != NULL); version = NULL; dns_db_currentversion(db, &version); node = NULL; result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) { answer = result; goto closeversion; } if (nscount != NULL || errors != NULL) { result = zone_count_ns_rr(zone, db, node, version, nscount, errors); if (result != ISC_R_SUCCESS) answer = result; } if (soacount != NULL || serial != NULL || refresh != NULL || retry
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -