📄 server.c
字号:
attrs, attrmask, &disp); if (result != ISC_R_SUCCESS) { isc_sockaddr_t any; char buf[ISC_SOCKADDR_FORMATSIZE]; switch (af) { case AF_INET: isc_sockaddr_any(&any); break; case AF_INET6: isc_sockaddr_any6(&any); break; } if (isc_sockaddr_equal(&sa, &any)) return (ISC_R_SUCCESS); isc_sockaddr_format(&sa, buf, sizeof(buf)); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "could not get query source dispatcher (%s)", buf); return (result); } *dispatchp = disp; return (ISC_R_SUCCESS);}static isc_result_tconfigure_order(dns_order_t *order, cfg_obj_t *ent) { dns_rdataclass_t rdclass; dns_rdatatype_t rdtype; cfg_obj_t *obj; dns_fixedname_t fixed; unsigned int mode = 0; const char *str; isc_buffer_t b; isc_result_t result; result = ns_config_getclass(cfg_tuple_get(ent, "class"), dns_rdataclass_any, &rdclass); if (result != ISC_R_SUCCESS) return (result); result = ns_config_gettype(cfg_tuple_get(ent, "type"), dns_rdatatype_any, &rdtype); if (result != ISC_R_SUCCESS) return (result); obj = cfg_tuple_get(ent, "name"); if (cfg_obj_isstring(obj)) str = cfg_obj_asstring(obj); else str = "*"; isc_buffer_init(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); dns_fixedname_init(&fixed); result = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, ISC_FALSE, NULL); if (result != ISC_R_SUCCESS) return (result); obj = cfg_tuple_get(ent, "ordering"); INSIST(cfg_obj_isstring(obj)); str = cfg_obj_asstring(obj); if (!strcasecmp(str, "fixed")) mode = DNS_RDATASETATTR_FIXEDORDER; else if (!strcasecmp(str, "random")) mode = DNS_RDATASETATTR_RANDOMIZE; else if (!strcasecmp(str, "cyclic")) mode = 0; else INSIST(0); return (dns_order_add(order, dns_fixedname_name(&fixed), rdtype, rdclass, mode));}static isc_result_tconfigure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { isc_sockaddr_t *sa; isc_netaddr_t na; dns_peer_t *peer; cfg_obj_t *obj; char *str; isc_result_t result; sa = cfg_obj_assockaddr(cfg_map_getname(cpeer)); isc_netaddr_fromsockaddr(&na, sa); peer = NULL; result = dns_peer_new(mctx, &na, &peer); if (result != ISC_R_SUCCESS) return (result); obj = NULL; (void)cfg_map_get(cpeer, "bogus", &obj); if (obj != NULL) CHECK(dns_peer_setbogus(peer, cfg_obj_asboolean(obj))); obj = NULL; (void)cfg_map_get(cpeer, "provide-ixfr", &obj); if (obj != NULL) CHECK(dns_peer_setprovideixfr(peer, cfg_obj_asboolean(obj))); obj = NULL; (void)cfg_map_get(cpeer, "request-ixfr", &obj); if (obj != NULL) CHECK(dns_peer_setrequestixfr(peer, cfg_obj_asboolean(obj))); obj = NULL; (void)cfg_map_get(cpeer, "edns", &obj); if (obj != NULL) CHECK(dns_peer_setsupportedns(peer, cfg_obj_asboolean(obj))); obj = NULL; (void)cfg_map_get(cpeer, "transfers", &obj); if (obj != NULL) CHECK(dns_peer_settransfers(peer, cfg_obj_asuint32(obj))); obj = NULL; (void)cfg_map_get(cpeer, "transfer-format", &obj); if (obj != NULL) { str = cfg_obj_asstring(obj); if (strcasecmp(str, "many-answers") == 0) CHECK(dns_peer_settransferformat(peer, dns_many_answers)); else if (strcasecmp(str, "one-answer") == 0) CHECK(dns_peer_settransferformat(peer, dns_one_answer)); else INSIST(0); } obj = NULL; (void)cfg_map_get(cpeer, "keys", &obj); if (obj != NULL) { result = dns_peer_setkeybycharp(peer, cfg_obj_asstring(obj)); if (result != ISC_R_SUCCESS) goto cleanup; } obj = NULL; if (isc_sockaddr_pf(sa) == AF_INET) (void)cfg_map_get(cpeer, "transfer-source", &obj); else (void)cfg_map_get(cpeer, "transfer-source-v6", &obj); if (obj != NULL) { result = dns_peer_settransfersource(peer, cfg_obj_assockaddr(obj)); if (result != ISC_R_SUCCESS) goto cleanup; } *peerp = peer; return (ISC_R_SUCCESS); cleanup: dns_peer_detach(&peer); return (result);}static isc_result_tdisable_algorithms(cfg_obj_t *disabled, dns_resolver_t *resolver) { isc_result_t result; cfg_obj_t *algorithms; cfg_listelt_t *element; const char *str; dns_fixedname_t fixed; dns_name_t *name; isc_buffer_t b; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); str = cfg_obj_asstring(cfg_tuple_get(disabled, "name")); isc_buffer_init(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); CHECK(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL)); algorithms = cfg_tuple_get(disabled, "algorithms"); for (element = cfg_list_first(algorithms); element != NULL; element = cfg_list_next(element)) { isc_textregion_t r; dns_secalg_t alg; r.base = cfg_obj_asstring(cfg_listelt_value(element)); r.length = strlen(r.base); result = dns_secalg_fromtext(&alg, &r); if (result != ISC_R_SUCCESS) { isc_uint8_t ui; result = isc_parse_uint8(&ui, r.base, 10); alg = ui; } if (result != ISC_R_SUCCESS) { cfg_obj_log(cfg_listelt_value(element), ns_g_lctx, ISC_LOG_ERROR, "invalid algorithm"); CHECK(result); } CHECK(dns_resolver_disable_algorithm(resolver, name, alg)); } cleanup: return (result);}/* * Configure 'view' according to 'vconfig', taking defaults from 'config' * where values are missing in 'vconfig'. * * When configuring the default view, 'vconfig' will be NULL and the * global defaults in 'config' used exclusively. */static isc_result_tconfigure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, isc_mem_t *mctx, ns_aclconfctx_t *actx, isc_boolean_t need_hints){ cfg_obj_t *maps[4]; cfg_obj_t *cfgmaps[3]; cfg_obj_t *options = NULL; cfg_obj_t *voptions = NULL; cfg_obj_t *forwardtype; cfg_obj_t *forwarders; cfg_obj_t *alternates; cfg_obj_t *zonelist; cfg_obj_t *disabled; cfg_obj_t *obj; cfg_listelt_t *element; in_port_t port; dns_cache_t *cache = NULL; isc_result_t result; isc_uint32_t max_adb_size; isc_uint32_t max_cache_size; isc_uint32_t lame_ttl; dns_tsig_keyring_t *ring; dns_view_t *pview = NULL; /* Production view */ isc_mem_t *cmctx; dns_dispatch_t *dispatch4 = NULL; dns_dispatch_t *dispatch6 = NULL; isc_boolean_t reused_cache = ISC_FALSE; int i; const char *str; dns_order_t *order = NULL; isc_uint32_t udpsize; unsigned int check = 0; REQUIRE(DNS_VIEW_VALID(view)); cmctx = NULL; if (config != NULL) (void)cfg_map_get(config, "options", &options); i = 0; if (vconfig != NULL) { voptions = cfg_tuple_get(vconfig, "options"); maps[i++] = voptions; } if (options != NULL) maps[i++] = options; maps[i++] = ns_g_defaults; maps[i] = NULL; i = 0; if (voptions != NULL) cfgmaps[i++] = voptions; if (config != NULL) cfgmaps[i++] = config; cfgmaps[i] = NULL; /* * Set the view's port number for outgoing queries. */ CHECKM(ns_config_getport(config, &port), "port"); dns_view_setdstport(view, port); /* * 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)) { cfg_obj_t *zconfig = cfg_listelt_value(element); CHECK(configure_zone(config, zconfig, vconfig, mctx, view, actx)); } /* * 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); /* * 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 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -