📄 server.c
字号:
forview = ""; } /* * Set the view's port number for outgoing queries. */ CHECKM(ns_config_getport(config, &port), "port"); dns_view_setdstport(view, port); /* * Create additional cache for this view and zones under the view * if explicitly enabled. * XXX950 default to on. */ obj = NULL; (void)ns_config_get(maps, "acache-enable", &obj); if (obj != NULL && cfg_obj_asboolean(obj)) { cmctx = NULL; CHECK(isc_mem_create(0, 0, &cmctx)); CHECK(dns_acache_create(&view->acache, cmctx, ns_g_taskmgr, ns_g_timermgr)); isc_mem_detach(&cmctx); } if (view->acache != NULL) { obj = NULL; result = ns_config_get(maps, "acache-cleaning-interval", &obj); INSIST(result == ISC_R_SUCCESS); dns_acache_setcleaninginterval(view->acache, cfg_obj_asuint32(obj) * 60); obj = NULL; result = ns_config_get(maps, "max-acache-size", &obj); INSIST(result == ISC_R_SUCCESS); if (cfg_obj_isstring(obj)) { str = cfg_obj_asstring(obj); INSIST(strcasecmp(str, "unlimited") == 0); max_acache_size = ISC_UINT32_MAX; } else { isc_resourcevalue_t value; value = cfg_obj_asuint64(obj); if (value > ISC_UINT32_MAX) { cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "'max-acache-size " "%" ISC_PRINT_QUADFORMAT "d' is too large", value); result = ISC_R_RANGE; goto cleanup; } max_acache_size = (isc_uint32_t)value; } dns_acache_setcachesize(view->acache, max_acache_size); } /* * Configure the zones. */ zonelist = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "zone", &zonelist); else (void)cfg_map_get(config, "zone", &zonelist); for (element = cfg_list_first(zonelist); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *zconfig = cfg_listelt_value(element); CHECK(configure_zone(config, zconfig, vconfig, mctx, view, actx)); }#ifdef DLZ /* * Create Dynamically Loadable Zone driver. */ dlz = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "dlz", &dlz); else (void)cfg_map_get(config, "dlz", &dlz); obj = NULL; if (dlz != NULL) { (void)cfg_map_get(cfg_tuple_get(dlz, "options"), "database", &obj); if (obj != NULL) { char *s = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); if (s == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } result = dns_dlzstrtoargv(mctx, s, &dlzargc, &dlzargv); if (result != ISC_R_SUCCESS) { isc_mem_free(mctx, s); goto cleanup; } obj = cfg_tuple_get(dlz, "name"); result = dns_dlzcreate(mctx, cfg_obj_asstring(obj), dlzargv[0], dlzargc, dlzargv, &view->dlzdatabase); isc_mem_free(mctx, s); isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv)); if (result != ISC_R_SUCCESS) goto cleanup; } }#endif /* * Configure the view's cache. Try to reuse an existing * cache if possible, otherwise create a new cache. * Note that the ADB is not preserved in either case. * * XXX Determining when it is safe to reuse a cache is * tricky. When the view's configuration changes, the cached * data may become invalid because it reflects our old * view of the world. As more view attributes become * configurable, we will have to add code here to check * whether they have changed in ways that could * invalidate the cache. */ result = dns_viewlist_find(&ns_g_server->viewlist, view->name, view->rdclass, &pview); if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) goto cleanup; if (pview != NULL) { INSIST(pview->cache != NULL); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(3), "reusing existing cache"); reused_cache = ISC_TRUE; dns_cache_attach(pview->cache, &cache); dns_view_detach(&pview); } else { CHECK(isc_mem_create(0, 0, &cmctx)); CHECK(dns_cache_create(cmctx, ns_g_taskmgr, ns_g_timermgr, view->rdclass, "rbt", 0, NULL, &cache)); } dns_view_setcache(view, cache); /* * cache-file cannot be inherited if views are present, but this * should be caught by the configuration checking stage. */ obj = NULL; result = ns_config_get(maps, "cache-file", &obj); if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) { CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj))); if (!reused_cache) CHECK(dns_cache_load(cache)); } obj = NULL; result = ns_config_get(maps, "cleaning-interval", &obj); INSIST(result == ISC_R_SUCCESS); dns_cache_setcleaninginterval(cache, cfg_obj_asuint32(obj) * 60); obj = NULL; result = ns_config_get(maps, "max-cache-size", &obj); INSIST(result == ISC_R_SUCCESS); if (cfg_obj_isstring(obj)) { str = cfg_obj_asstring(obj); INSIST(strcasecmp(str, "unlimited") == 0); max_cache_size = ISC_UINT32_MAX; } else { isc_resourcevalue_t value; value = cfg_obj_asuint64(obj); if (value > ISC_UINT32_MAX) { cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "'max-cache-size " "%" ISC_PRINT_QUADFORMAT "d' is too large", value); result = ISC_R_RANGE; goto cleanup; } max_cache_size = (isc_uint32_t)value; } dns_cache_setcachesize(cache, max_cache_size); dns_cache_detach(&cache); /* * Check-names. */ obj = NULL; result = ns_checknames_get(maps, "response", &obj); INSIST(result == ISC_R_SUCCESS); str = cfg_obj_asstring(obj); if (strcasecmp(str, "fail") == 0) { check = DNS_RESOLVER_CHECKNAMES | DNS_RESOLVER_CHECKNAMESFAIL; view->checknames = ISC_TRUE; } else if (strcasecmp(str, "warn") == 0) { check = DNS_RESOLVER_CHECKNAMES; view->checknames = ISC_FALSE; } else if (strcasecmp(str, "ignore") == 0) { check = 0; view->checknames = ISC_FALSE; } else INSIST(0); /* * Resolver. * * XXXRTH Hardwired number of tasks. */ CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4)); CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6)); if (dispatch4 == NULL && dispatch6 == NULL) { UNEXPECTED_ERROR(__FILE__, __LINE__, "unable to obtain neither an IPv4 nor" " an IPv6 dispatch"); result = ISC_R_UNEXPECTED; goto cleanup; } CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, ns_g_socketmgr, ns_g_timermgr, check, ns_g_dispatchmgr, dispatch4, dispatch6)); /* * Set the ADB cache size to 1/8th of the max-cache-size. */ max_adb_size = 0; if (max_cache_size != 0) { max_adb_size = max_cache_size / 8; if (max_adb_size == 0) max_adb_size = 1; /* Force minimum. */ } dns_adb_setadbsize(view->adb, max_adb_size); /* * Set resolver's lame-ttl. */ obj = NULL; result = ns_config_get(maps, "lame-ttl", &obj); INSIST(result == ISC_R_SUCCESS); lame_ttl = cfg_obj_asuint32(obj); if (lame_ttl > 1800) lame_ttl = 1800; dns_resolver_setlamettl(view->resolver, lame_ttl); obj = NULL; result = ns_config_get(maps, "zero-no-soa-ttl-cache", &obj); INSIST(result == ISC_R_SUCCESS); dns_resolver_setzeronosoattl(view->resolver, cfg_obj_asboolean(obj)); /* * Set the resolver's EDNS UDP size. */ obj = NULL; result = ns_config_get(maps, "edns-udp-size", &obj); INSIST(result == ISC_R_SUCCESS); udpsize = cfg_obj_asuint32(obj); if (udpsize < 512) udpsize = 512; if (udpsize > 4096) udpsize = 4096; dns_resolver_setudpsize(view->resolver, (isc_uint16_t)udpsize); /* * Set the maximum UDP response size. */ obj = NULL; result = ns_config_get(maps, "max-udp-size", &obj); INSIST(result == ISC_R_SUCCESS); udpsize = cfg_obj_asuint32(obj); if (udpsize < 512) udpsize = 512; if (udpsize > 4096) udpsize = 4096; view->maxudp = udpsize; /* * Set supported DNSSEC algorithms. */ dns_resolver_reset_algorithms(view->resolver); disabled = NULL; (void)ns_config_get(maps, "disable-algorithms", &disabled); if (disabled != NULL) { for (element = cfg_list_first(disabled); element != NULL; element = cfg_list_next(element)) CHECK(disable_algorithms(cfg_listelt_value(element), view->resolver)); } /* * A global or view "forwarders" option, if present, * creates an entry for "." in the forwarding table. */ forwardtype = NULL; forwarders = NULL; (void)ns_config_get(maps, "forward", &forwardtype); (void)ns_config_get(maps, "forwarders", &forwarders); if (forwarders != NULL) CHECK(configure_forward(config, view, dns_rootname, forwarders, forwardtype)); /* * Dual Stack Servers. */ alternates = NULL; (void)ns_config_get(maps, "dual-stack-servers", &alternates); if (alternates != NULL) CHECK(configure_alternates(config, view, alternates)); /* * We have default hints for class IN if we need them. */ if (view->rdclass == dns_rdataclass_in && view->hints == NULL) dns_view_sethints(view, ns_g_server->in_roothints); /* * If we still have no hints, this is a non-IN view with no * "hints zone" configured. Issue a warning, except if this * is a root server. Root servers never need to consult * their hints, so it's no point requiring users to configure * them. */ if (view->hints == NULL) { dns_zone_t *rootzone = NULL; (void)dns_view_findzone(view, dns_rootname, &rootzone); if (rootzone != NULL) { dns_zone_detach(&rootzone); need_hints = ISC_FALSE; } if (need_hints) isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_WARNING, "no root hints for view '%s'", view->name); } /* * Configure the view's TSIG keys. */ ring = NULL; CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring)); dns_view_setkeyring(view, ring); /* * Configure the view's peer list. */ { const cfg_obj_t *peers = NULL; const cfg_listelt_t *element; dns_peerlist_t *newpeers = NULL; (void)ns_config_get(cfgmaps, "server", &peers); CHECK(dns_peerlist_new(mctx, &newpeers)); for (element = cfg_list_first(peers); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *cpeer = cfg_listelt_value(element); dns_peer_t *peer; CHECK(configure_peer(cpeer, mctx, &peer)); dns_peerlist_addpeer(newpeers, peer); dns_peer_detach(&peer); } dns_peerlist_detach(&view->peers); view->peers = newpeers; /* Transfer ownership. */ } /* * Configure the views rrset-order. */ { const cfg_obj_t *rrsetorder = NULL; const cfg_listelt_t *element; (void)ns_config_get(maps, "rrset-order", &rrsetorder); CHECK(dns_order_create(mctx, &order)); for (element = cfg_list_first(rrsetorder); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *ent = cfg_listelt_value(element); CHECK(configure_order(order, ent)); } if (view->order != NULL) dns_order_detach(&view->order); dns_order_attach(order, &view->order); dns_order_detach(&order); } /* * Copy the aclenv object. */ dns_aclenv_copy(&view->aclenv, &ns_g_server->aclenv); /* * Configure the "match-clients" and "match-destinations" ACL. */ CHECK(configure_view_acl(vconfig, config, "match-clients", actx, ns_g_mctx, &view->matchclients)); CHECK(configure_view_acl(vconfig, config, "match-destinations", actx, ns_g_mctx, &view->matchdestinations)); /* * Configure the "match-recursive-only" option. */ obj = NULL; (void)ns_config_get(maps, "match-recursive-only", &obj); if (obj != NULL && cfg_obj_asboolean(obj)) view->matchrecursiveonly = ISC_TRUE; else view->matchrecursiveonly = ISC_FALSE; /* * Configure other configurable data. */ obj = NULL; result = ns_config_get(maps, "recursion", &obj); INSIST(result == ISC_R_SUCCESS); view->recursion = cfg_obj_asboolean(obj); obj = NULL; result = ns_config_get(maps, "auth-nxdomain", &obj); INSIST(result == ISC_R_SUCCESS); view->auth_nxdomain = cfg_obj_asboolean(obj); obj = NULL; result = ns_config_get(maps, "minimal-responses", &obj); INSIST(result == ISC_R_SUCCESS); view->minimalresponses = cfg_obj_asboolean(obj); obj = NULL; result = ns_config_get(maps, "transfer-format", &obj); INSIST(result == ISC_R_SUCCESS); str = cfg_obj_asstring(obj); if (strcasecmp(str, "many-answers") == 0) view->transfer_format = dns_many_answers; else if (strcasecmp(str, "one-answer") == 0) view->transfer_format = dns_one_answer; else INSIST(0); /* * Set sources where additional data and CNAME/DNAME * targets for authoritative answers may be found. */ obj = NULL; result = ns_config_get(maps, "additional-from-auth", &obj); INSIST(result == ISC_R_SUCCESS); view->additionalfromauth = cfg_obj_asboolean(obj); if (view->recursion && ! view->additionalfromauth) { cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, "'additional-from-auth no' is only supported " "with 'recursion no'"); view->additionalfromauth = ISC_TRUE; } obj = NULL; result = ns_config_get(maps, "additional-from-cache", &obj); INSIST(result == ISC_R_SUCCESS); view->additionalfromcache = cfg_obj_asboolean(obj); if (view->recursion && ! view->additionalfromcache) { cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, "'additional-from-cache no' is only supported " "with 'recursion no'"); view->additionalfromcache = ISC_TRUE; } CHECK(configure_view_acl(vconfig, config, "allow-query-cache", actx, ns_g_mctx, &view->queryacl)); if (view->queryacl == NULL) CHECK(configure_view_acl(NULL, ns_g_defaults, "allow-query-cache", actx, ns_g_mctx, &view->queryacl)); if (strcmp(view->name, "_bind") != 0) CHECK(configure_view_acl(vconfig, config, "allow-recursion", actx, ns_g_mctx, &view->recursionacl)); /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -