📄 zone.c
字号:
zone->refreshcnt = 0; /* initiate soa query */ queue_soa_query(zone); unlock: UNLOCK_ZONE(zone);}isc_result_tdns_zone_flush(dns_zone_t *zone) { isc_result_t result = ISC_R_ALREADYRUNNING; isc_boolean_t dumping; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && zone->masterfile != NULL) dumping = was_dumping(zone); else dumping = ISC_TRUE; UNLOCK_ZONE(zone); if (!dumping) result = zone_dump(zone); return (result);}isc_result_tdns_zone_dump(dns_zone_t *zone) { isc_result_t result = ISC_R_ALREADYRUNNING; isc_boolean_t dumping; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); dumping = was_dumping(zone); UNLOCK_ZONE(zone); if (!dumping) result = zone_dump(zone); return (result);}static voidzone_needdump(dns_zone_t *zone, unsigned int delay) { isc_time_t dumptime; isc_time_t now; isc_interval_t i; /* * 'zone' locked by caller */ REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); /* * Do we have a place to dump to and are we loaded? */ if (zone->masterfile == NULL || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) return; isc_interval_set(&i, delay, 0); isc_time_now(&now); isc_time_add(&now, &i, &dumptime); /* add some noise */ delay = isc_random_jitter(delay, delay/4); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); if (isc_time_isepoch(&zone->dumptime) || isc_time_compare(&zone->dumptime, &dumptime) > 0) zone->dumptime = dumptime; if (zone->task != NULL) zone_settimer(zone, &now);}static isc_result_tzone_dump(dns_zone_t *zone) { isc_result_t result; dns_dbversion_t *version = NULL; isc_boolean_t again; dns_db_t *db = NULL; char *masterfile = NULL; REQUIRE(DNS_ZONE_VALID(zone)); redo: LOCK_ZONE(zone); if (zone->db != NULL) dns_db_attach(zone->db, &db); if (zone->masterfile != NULL) masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); UNLOCK_ZONE(zone); if (db == NULL) { result = DNS_R_NOTLOADED; goto fail; } if (masterfile == NULL) { result = DNS_R_NOMASTERFILE; goto fail; } dns_db_currentversion(db, &version); result = dns_master_dump(zone->mctx, db, version, &dns_master_style_default, masterfile); dns_db_closeversion(db, &version, ISC_FALSE); fail: if (db != NULL) dns_db_detach(&db); if (masterfile != NULL) isc_mem_free(zone->mctx, masterfile); masterfile = NULL; again = ISC_FALSE; LOCK_ZONE(zone); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); if (result != ISC_R_SUCCESS) { /* * Try again in a short while. */ zone_needdump(zone, DNS_DUMP_DELAY); } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); isc_time_settoepoch(&zone->dumptime); again = ISC_TRUE; } UNLOCK_ZONE(zone); if (again) goto redo; return (result);}isc_result_tdns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { isc_result_t result; dns_dbversion_t *version = NULL; dns_db_t *db = NULL; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->db != NULL) dns_db_attach(zone->db, &db); UNLOCK_ZONE(zone); if (db == NULL) return (DNS_R_NOTLOADED); dns_db_currentversion(db, &version); result = dns_master_dumptostream(zone->mctx, db, version, &dns_master_style_default, fd); dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); return (result);}voiddns_zone_unload(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone_unload(zone); UNLOCK_ZONE(zone);}static voidnotify_cancel(dns_zone_t *zone) { dns_notify_t *notify; /* * 'zone' locked by caller. */ REQUIRE(LOCKED_ZONE(zone)); for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; notify = ISC_LIST_NEXT(notify, link)) { if (notify->find != NULL) dns_adb_cancelfind(notify->find); if (notify->request != NULL) dns_request_cancel(notify->request); }}static voidzone_unload(dns_zone_t *zone) { /* * 'zone' locked by caller. */ REQUIRE(LOCKED_ZONE(zone)); dns_db_detach(&zone->db); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);}voiddns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(val > 0); zone->minrefresh = val;}voiddns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(val > 0); zone->maxrefresh = val;}voiddns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(val > 0); zone->minretry = val;}voiddns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(val > 0); zone->maxretry = val;}static isc_boolean_tnotify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) { dns_notify_t *notify; for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; notify = ISC_LIST_NEXT(notify, link)) { if (notify->request != NULL) continue; if (name != NULL && dns_name_dynamic(¬ify->ns) && dns_name_equal(name, ¬ify->ns)) return (ISC_TRUE); if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst)) return (ISC_TRUE); } return (ISC_FALSE);}static voidnotify_destroy(dns_notify_t *notify, isc_boolean_t locked) { isc_mem_t *mctx; /* * Caller holds zone lock. */ REQUIRE(DNS_NOTIFY_VALID(notify)); if (notify->zone != NULL) { if (!locked) LOCK_ZONE(notify->zone); REQUIRE(LOCKED_ZONE(notify->zone)); if (ISC_LINK_LINKED(notify, link)) ISC_LIST_UNLINK(notify->zone->notifies, notify, link); if (!locked) UNLOCK_ZONE(notify->zone); if (locked) zone_idetach(¬ify->zone); else dns_zone_idetach(¬ify->zone); } if (notify->find != NULL) dns_adb_destroyfind(¬ify->find); if (notify->request != NULL) dns_request_destroy(¬ify->request); if (dns_name_dynamic(¬ify->ns)) dns_name_free(¬ify->ns, notify->mctx); mctx = notify->mctx; isc_mem_put(notify->mctx, notify, sizeof *notify); isc_mem_detach(&mctx);}static isc_result_tnotify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { dns_notify_t *notify; REQUIRE(notifyp != NULL && *notifyp == NULL); notify = isc_mem_get(mctx, sizeof *notify); if (notify == NULL) return (ISC_R_NOMEMORY); notify->mctx = NULL; isc_mem_attach(mctx, ¬ify->mctx); notify->flags = flags; notify->zone = NULL; notify->find = NULL; notify->request = NULL; isc_sockaddr_any(¬ify->dst); dns_name_init(¬ify->ns, NULL); notify->attempt = 0; ISC_LINK_INIT(notify, link); notify->magic = NOTIFY_MAGIC; *notifyp = notify; return (ISC_R_SUCCESS);}/* * XXXAG should check for DNS_ZONEFLG_EXITING */static voidprocess_adb_event(isc_task_t *task, isc_event_t *ev) { dns_notify_t *notify; isc_eventtype_t result; UNUSED(task); notify = ev->ev_arg; REQUIRE(DNS_NOTIFY_VALID(notify)); INSIST(task == notify->zone->task); result = ev->ev_type; isc_event_free(&ev); if (result == DNS_EVENT_ADBMOREADDRESSES) { dns_adb_destroyfind(¬ify->find); notify_find_address(notify); return; } if (result == DNS_EVENT_ADBNOMOREADDRESSES) { LOCK_ZONE(notify->zone); notify_send(notify); UNLOCK_ZONE(notify->zone); } notify_destroy(notify, ISC_FALSE);}static voidnotify_find_address(dns_notify_t *notify) { isc_result_t result; unsigned int options; REQUIRE(DNS_NOTIFY_VALID(notify)); options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME; if (notify->zone->view->adb == NULL) goto destroy; result = dns_adb_createfind(notify->zone->view->adb, notify->zone->task, process_adb_event, notify, ¬ify->ns, dns_rootname, options, 0, NULL, notify->zone->view->dstport, ¬ify->find); /* Something failed? */ if (result != ISC_R_SUCCESS) goto destroy; /* More addresses pending? */ if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) return; /* We have as many addresses as we can get. */ LOCK_ZONE(notify->zone); notify_send(notify); UNLOCK_ZONE(notify->zone); destroy: notify_destroy(notify, ISC_FALSE);}static isc_result_tnotify_send_queue(dns_notify_t *notify) { isc_event_t *e; isc_result_t result; e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR, notify_send_toaddr, notify, sizeof(isc_event_t)); if (e == NULL) return (ISC_R_NOMEMORY); e->ev_arg = notify; e->ev_sender = NULL; result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl, notify->zone->task, &e); if (result != ISC_R_SUCCESS) isc_event_free(&e); return (result);}static voidnotify_send_toaddr(isc_task_t *task, isc_event_t *event) { dns_notify_t *notify; isc_result_t result; dns_message_t *message = NULL; isc_netaddr_t dstip; dns_tsigkey_t *key = NULL; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t src; int timeout; notify = event->ev_arg; REQUIRE(DNS_NOTIFY_VALID(notify)); UNUSED(task); LOCK_ZONE(notify->zone); if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) { result = ISC_R_CANCELED; goto cleanup; } if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || notify->zone->view->requestmgr == NULL || notify->zone->db == NULL) { result = ISC_R_CANCELED; goto cleanup; } result = notify_createmessage(notify->zone, notify->flags, &message); if (result != ISC_R_SUCCESS) goto cleanup; isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); (void)dns_view_getpeertsig(notify->zone->view, &dstip, &key); isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", addrbuf); switch (isc_sockaddr_pf(¬ify->dst)) { case PF_INET: src = notify->zone->notifysrc4; break; case PF_INET6: src = notify->zone->notifysrc6; break; default: result = ISC_R_NOTIMPLEMENTED; goto cleanup_key; } timeout = 15; if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) timeout = 30; result = dns_request_createvia(notify->zone->view->requestmgr, message, &src, ¬ify->dst, 0, key, timeout, notify->zone->task, notify_done, notify, ¬ify->request); cleanup_key: if (key != NULL) dns_tsigkey_detach(&key); dns_message_destroy(&message); cleanup: UNLOCK_ZONE(notify->zone); if (result != ISC_R_SUCCESS) notify_destroy(notify, ISC_FALSE); isc_event_free(&event);}static voidnotify_send(dns_notify_t *notify) { dns_adbaddrinfo_t *ai; isc_sockaddr_t dst; isc_result_t result; dns_notify_t *new = NULL; /* * Zone lock held by caller. */ REQUIRE(DNS_NOTIFY_VALID(notify)); REQUIRE(LOCKED_ZONE(notify->zone)); for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL; ai = ISC_LIST_NEXT(ai, publink)) { dst = ai->sockaddr; if (notify_isqueued(notify->zone, NULL, &dst)) continue; new = NULL; result = notify_create(notify->mctx, (notify->flags & DNS_NOTIFY_NOSOA), &new); if (result != ISC_R_SUCCESS) goto cleanup; zone_iattach(notify->zone, &new->zone); ISC_LIST_APPEND(new->zone->notifies, new, link); new->dst = dst; result = notify_send_queue(new); if (result != ISC_R_SUCCESS) goto cleanup; new = NULL; } cleanup: if (new != NULL) notify_destroy(new, ISC_TRUE);}voiddns_zone_notify(dns_zone_t *zone) { isc_time_t now; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); isc_time_now(&now); zone_settimer(zone, &now); UNLOCK_ZONE(zone);}static voidzone_notify(dns_zone_t *zone) { dns_dbnode_t *node = NULL; dns_dbversion_t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -