📄 zone.c
字号:
REQUIRE(LOCKED_ZONE(source)); REQUIRE(DNS_ZONE_VALID(source)); REQUIRE(target != NULL && *target == NULL); INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0); source->irefs++; INSIST(source->irefs != 0); *target = source;}static voidzone_idetach(dns_zone_t **zonep) { dns_zone_t *zone; /* * 'zone' locked by caller. */ REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); zone = *zonep; REQUIRE(LOCKED_ZONE(*zonep)); *zonep = NULL; INSIST(zone->irefs > 0); zone->irefs--; INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);}voiddns_zone_idetach(dns_zone_t **zonep) { dns_zone_t *zone; isc_boolean_t free_needed; REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); zone = *zonep; *zonep = NULL; LOCK_ZONE(zone); INSIST(zone->irefs > 0); zone->irefs--; free_needed = exit_check(zone); UNLOCK_ZONE(zone); if (free_needed) zone_free(zone);}isc_mem_t *dns_zone_getmctx(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->mctx);}dns_zonemgr_t *dns_zone_getmgr(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->zmgr);}voiddns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (value) DNS_ZONE_SETFLAG(zone, flags); else DNS_ZONE_CLRFLAG(zone, flags); UNLOCK_ZONE(zone);}voiddns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value){ REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (value) zone->options |= option; else zone->options &= ~option; UNLOCK_ZONE(zone);}unsigned intdns_zone_getoptions(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->options);}isc_result_tdns_zone_setxfrsource4(dns_zone_t *zone, isc_sockaddr_t *xfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->xfrsource4 = *xfrsource; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS);}isc_sockaddr_t *dns_zone_getxfrsource4(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->xfrsource4);}isc_result_tdns_zone_setxfrsource6(dns_zone_t *zone, isc_sockaddr_t *xfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->xfrsource6 = *xfrsource; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS);}isc_sockaddr_t *dns_zone_getxfrsource6(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->xfrsource6);}isc_result_tdns_zone_setnotifysrc4(dns_zone_t *zone, isc_sockaddr_t *notifysrc) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifysrc4 = *notifysrc; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS);}isc_sockaddr_t *dns_zone_getnotifysrc4(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->notifysrc4);}isc_result_tdns_zone_setnotifysrc6(dns_zone_t *zone, isc_sockaddr_t *notifysrc) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifysrc6 = *notifysrc; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS);}isc_sockaddr_t *dns_zone_getnotifysrc6(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->notifysrc6);}isc_result_tdns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *notify, isc_uint32_t count){ isc_sockaddr_t *new; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(count == 0 || notify != NULL); LOCK_ZONE(zone); if (zone->notify != NULL) { isc_mem_put(zone->mctx, zone->notify, zone->notifycnt * sizeof *new); zone->notify = NULL; zone->notifycnt = 0; } if (count != 0) { new = isc_mem_get(zone->mctx, count * sizeof *new); if (new == NULL) { UNLOCK_ZONE(zone); return (ISC_R_NOMEMORY); } memcpy(new, notify, count * sizeof *new); zone->notify = new; zone->notifycnt = count; } UNLOCK_ZONE(zone); return (ISC_R_SUCCESS);}isc_result_tdns_zone_setmasters(dns_zone_t *zone, isc_sockaddr_t *masters, isc_uint32_t count){ isc_result_t result; result = dns_zone_setmasterswithkeys(zone, masters, NULL, count); return (result);}isc_result_tdns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, dns_name_t **keynames, isc_uint32_t count){ isc_sockaddr_t *new; isc_result_t result = ISC_R_SUCCESS; dns_name_t **newname; unsigned int i; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(count == 0 || masters != NULL); if (keynames != NULL) { REQUIRE(count != 0); } LOCK_ZONE(zone); if (zone->masters != NULL) { isc_mem_put(zone->mctx, zone->masters, zone->masterscnt * sizeof *new); zone->masters = NULL; } if (zone->masterkeynames != NULL) { for (i = 0; i < zone->masterscnt; i++) { if (zone->masterkeynames[i] != NULL) { dns_name_free(zone->masterkeynames[i], zone->mctx); isc_mem_put(zone->mctx, zone->masterkeynames[i], sizeof(dns_name_t)); zone->masterkeynames[i] = NULL; } } isc_mem_put(zone->mctx, zone->masterkeynames, zone->masterscnt * sizeof(dns_name_t *)); zone->masterkeynames = NULL; } zone->masterscnt = 0; /* * If count == 0, don't allocate any space for masters or keynames * so internally, those pointers are NULL if count == 0 */ if (count == 0) goto unlock; /* * masters must countain count elements! */ new = isc_mem_get(zone->mctx, count * sizeof(isc_sockaddr_t)); if (new == NULL) { result = ISC_R_NOMEMORY; goto unlock; } memcpy(new, masters, count * sizeof *new); zone->masters = new; zone->masterscnt = count; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS); /* * if keynames is non-NULL, it must contain count elements! */ if (keynames != NULL) { newname = isc_mem_get(zone->mctx, count * sizeof(dns_name_t *)); if (newname == NULL) { result = ISC_R_NOMEMORY; isc_mem_put(zone->mctx, zone->masters, count * sizeof *new); goto unlock; } for (i = 0; i < count; i++) newname[i] = NULL; for (i = 0; i < count; i++) { if (keynames[i] != NULL) { newname[i] = isc_mem_get(zone->mctx, sizeof(dns_name_t)); if (newname[i] == NULL) goto allocfail; dns_name_init(newname[i], NULL); result = dns_name_dup(keynames[i], zone->mctx, newname[i]); if (result != ISC_R_SUCCESS) { allocfail: for (i = 0; i < count; i++) if (newname[i] != NULL) dns_name_free( newname[i], zone->mctx); isc_mem_put(zone->mctx, zone->masters, count * sizeof *new); isc_mem_put(zone->mctx, newname, count * sizeof *newname); goto unlock; } } } zone->masterkeynames = newname; } unlock: UNLOCK_ZONE(zone); return (result);}isc_result_tdns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->db == NULL) result = DNS_R_NOTLOADED; else dns_db_attach(zone->db, dpb); UNLOCK_ZONE(zone); return (result);}/* * Co-ordinates the starting of routine jobs. */voiddns_zone_maintenance(dns_zone_t *zone) { const char me[] = "dns_zone_maintenance"; isc_time_t now; REQUIRE(DNS_ZONE_VALID(zone)); ENTER; LOCK_ZONE(zone); isc_time_now(&now); zone_settimer(zone, &now); UNLOCK_ZONE(zone);}static inline isc_boolean_twas_dumping(dns_zone_t *zone) { isc_boolean_t dumping; REQUIRE(LOCKED_ZONE(zone)); dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); if (!dumping) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); isc_time_settoepoch(&zone->dumptime); } return (dumping);}static voidzone_maintenance(dns_zone_t *zone) { const char me[] = "zone_maintenance"; isc_time_t now; isc_result_t result; isc_boolean_t dumping; REQUIRE(DNS_ZONE_VALID(zone)); ENTER; /* * Configuring the view of this zone may have * failed, for example because the config file * had a syntax error. In that case, the view * adb or resolver, and we had better not try * to do maintenance on it. */ if (zone->view == NULL || zone->view->adb == NULL) return; isc_time_now(&now); /* * Expire check. */ switch (zone->type) { case dns_zone_slave: case dns_zone_stub: LOCK_ZONE(zone); if (isc_time_compare(&now, &zone->expiretime) >= 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { zone_expire(zone); zone->refreshtime = now; } UNLOCK_ZONE(zone); break; default: break; } /* * Up to date check. */ switch (zone->type) { case dns_zone_slave: case dns_zone_stub: if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && isc_time_compare(&now, &zone->refreshtime) >= 0) dns_zone_refresh(zone); break; default: break; } /* * Do we need to consolidate the backing store? */ switch (zone->type) { case dns_zone_master: case dns_zone_slave: LOCK_ZONE(zone); if (zone->masterfile != NULL && isc_time_compare(&now, &zone->dumptime) >= 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { dumping = was_dumping(zone); } else dumping = ISC_TRUE; UNLOCK_ZONE(zone); if (!dumping) { result = zone_dump(zone); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_WARNING, "dump failed: %s", dns_result_totext(result)); } break; default: break; } /* * Do we need to send out notify messages? */ switch (zone->type) { case dns_zone_master: case dns_zone_slave: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) zone_notify(zone); break; default: break; } zone_settimer(zone, &now);}voiddns_zone_markdirty(dns_zone_t *zone) { LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); UNLOCK_ZONE(zone);}voiddns_zone_expire(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone_expire(zone); UNLOCK_ZONE(zone);}static voidzone_expire(dns_zone_t *zone) { /* * 'zone' locked by caller. */ REQUIRE(LOCKED_ZONE(zone)); dns_zone_log(zone, ISC_LOG_WARNING, "expired"); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); zone->refresh = DNS_ZONE_DEFAULTREFRESH; zone->retry = DNS_ZONE_DEFAULTRETRY; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); zone_unload(zone);}voiddns_zone_refresh(dns_zone_t *zone) { isc_interval_t i; isc_uint32_t oldflags; REQUIRE(DNS_ZONE_VALID(zone)); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) return; /* * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation * in progress at a time. */ LOCK_ZONE(zone); oldflags = zone->flags; if (zone->masterscnt == 0) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS); if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) dns_zone_log(zone, ISC_LOG_ERROR, "cannot refresh: no masters"); goto unlock; } DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0) goto unlock; /* * Set the next refresh time as if refresh check has failed. * Setting this to the retry time will do that. XXXMLG * If we are successful it will be reset using zone->refresh. */ isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), 0); isc_time_nowplusinterval(&zone->refreshtime, &i); /* * When lacking user-specified timer values from the SOA, * do exponential backoff of the retry time up to a * maximum of six hours. */ if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); zone->curmaster = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -