📄 server.c
字号:
CHECK(dns_zone_create(&zone, mctx)); CHECK(dns_zone_setorigin(zone, origin)); dns_zone_setview(zone, view); CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); } /* * If the zone contains a 'forwarders' statement, configure * selective forwarding. */ forwarders = NULL; if (cfg_map_get(zoptions, "forwarders", &forwarders) == ISC_R_SUCCESS) { forwardtype = NULL; cfg_map_get(zoptions, "forward", &forwardtype); CHECK(configure_forward(config, view, origin, forwarders, forwardtype)); } /* * Stub and forward zones may also refer to delegation only points. */ only = NULL; if (cfg_map_get(zoptions, "delegation-only", &only) == ISC_R_SUCCESS) { if (cfg_obj_asboolean(only)) CHECK(dns_view_adddelegationonly(view, origin)); } /* * Configure the zone. */ CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone)); /* * Add the zone to its view in the new view list. */ CHECK(dns_view_addzone(view, zone)); cleanup: if (zone != NULL) dns_zone_detach(&zone); if (pview != NULL) dns_view_detach(&pview); return (result);}/* * Configure a single server quota. */static voidconfigure_server_quota(cfg_obj_t **maps, const char *name, isc_quota_t *quota){ cfg_obj_t *obj = NULL; isc_result_t result; result = ns_config_get(maps, name, &obj); INSIST(result == ISC_R_SUCCESS); quota->max = cfg_obj_asuint32(obj);}/* * This function is called as soon as the 'directory' statement has been * parsed. This can be extended to support other options if necessary. */static isc_result_tdirectory_callback(const char *clausename, cfg_obj_t *obj, void *arg) { isc_result_t result; char *directory; REQUIRE(strcasecmp("directory", clausename) == 0); UNUSED(arg); UNUSED(clausename); /* * Change directory. */ directory = cfg_obj_asstring(obj); if (! isc_file_ischdiridempotent(directory)) cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, "option 'directory' contains relative path '%s'", directory); result = isc_dir_chdir(directory); if (result != ISC_R_SUCCESS) { cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "change directory to '%s' failed: %s", directory, isc_result_totext(result)); return (result); } return (ISC_R_SUCCESS);}static voidscan_interfaces(ns_server_t *server, isc_boolean_t verbose) { isc_boolean_t match_mapped = server->aclenv.match_mapped; ns_interfacemgr_scan(server->interfacemgr, verbose); /* * Update the "localhost" and "localnets" ACLs to match the * current set of network interfaces. */ dns_aclenv_copy(&server->aclenv, ns_interfacemgr_getaclenv(server->interfacemgr)); server->aclenv.match_mapped = match_mapped;}/* * This event callback is invoked to do periodic network * interface scanning. */static voidinterface_timer_tick(isc_task_t *task, isc_event_t *event) { isc_result_t result; ns_server_t *server = (ns_server_t *) event->ev_arg; INSIST(task == server->task); UNUSED(task); isc_event_free(&event); /* * XXX should scan interfaces unlocked and get exclusive access * only to replace ACLs. */ result = isc_task_beginexclusive(server->task); RUNTIME_CHECK(result == ISC_R_SUCCESS); scan_interfaces(server, ISC_FALSE); isc_task_endexclusive(server->task); }static voidheartbeat_timer_tick(isc_task_t *task, isc_event_t *event) { ns_server_t *server = (ns_server_t *) event->ev_arg; dns_view_t *view; UNUSED(task); isc_event_free(&event); view = ISC_LIST_HEAD(server->viewlist); while (view != NULL) { dns_view_dialup(view); view = ISC_LIST_NEXT(view, link); }}static isc_result_tsetstatsfile(ns_server_t *server, const char *name) { char *p; REQUIRE(name != NULL); p = isc_mem_strdup(server->mctx, name); if (p == NULL) return (ISC_R_NOMEMORY); if (server->statsfile != NULL) isc_mem_free(server->mctx, server->statsfile); server->statsfile = p; return (ISC_R_SUCCESS);}static isc_result_tsetdumpfile(ns_server_t *server, const char *name) { char *p; REQUIRE(name != NULL); p = isc_mem_strdup(server->mctx, name); if (p == NULL) return (ISC_R_NOMEMORY); if (server->dumpfile != NULL) isc_mem_free(server->mctx, server->dumpfile); server->dumpfile = p; return (ISC_R_SUCCESS);}static voidset_limit(cfg_obj_t **maps, const char *configname, const char *description, isc_resource_t resourceid, isc_resourcevalue_t defaultvalue){ cfg_obj_t *obj = NULL; char *resource; isc_resourcevalue_t value; isc_result_t result; if (ns_config_get(maps, configname, &obj) != ISC_R_SUCCESS) return; if (cfg_obj_isstring(obj)) { resource = cfg_obj_asstring(obj); if (strcasecmp(resource, "unlimited") == 0) value = ISC_RESOURCE_UNLIMITED; else { INSIST(strcasecmp(resource, "default") == 0); value = defaultvalue; } } else value = cfg_obj_asuint64(obj); result = isc_resource_setlimit(resourceid, value); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, result == ISC_R_SUCCESS ? ISC_LOG_DEBUG(3) : ISC_LOG_WARNING, "set maximum %s to %" ISC_PRINT_QUADFORMAT "d: %s", description, value, isc_result_totext(result));}#define SETLIMIT(cfgvar, resource, description) \ set_limit(maps, cfgvar, description, isc_resource_ ## resource, \ ns_g_init ## resource)static voidset_limits(cfg_obj_t **maps) { SETLIMIT("stacksize", stacksize, "stack size"); SETLIMIT("datasize", datasize, "data size"); SETLIMIT("coresize", coresize, "core size"); SETLIMIT("files", openfiles, "open files");}static isc_result_tload_configuration(const char *filename, ns_server_t *server, isc_boolean_t first_time){ isc_result_t result; cfg_parser_t *parser = NULL; cfg_obj_t *config; cfg_obj_t *options; cfg_obj_t *views; cfg_obj_t *obj; cfg_obj_t *maps[3]; cfg_listelt_t *element; dns_view_t *view = NULL; dns_view_t *view_next; dns_viewlist_t viewlist; dns_viewlist_t tmpviewlist; ns_aclconfctx_t aclconfctx; dns_dispatch_t *dispatchv4 = NULL; dns_dispatch_t *dispatchv6 = NULL; isc_uint32_t interface_interval; isc_uint32_t heartbeat_interval; in_port_t listen_port; int i; ns_aclconfctx_init(&aclconfctx); ISC_LIST_INIT(viewlist); /* Ensure exclusive access to configuration data. */ result = isc_task_beginexclusive(server->task); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* * Parse the global default pseudo-config file. */ if (first_time) { CHECK(ns_config_parsedefaults(ns_g_parser, &ns_g_config)); RUNTIME_CHECK(cfg_map_get(ns_g_config, "options", &ns_g_defaults) == ISC_R_SUCCESS); } /* * Parse the configuration file using the new config code. */ result = ISC_R_FAILURE; config = NULL; /* * Unless this is lwresd with the -C option, parse the config file. */ if (!(ns_g_lwresdonly && lwresd_g_useresolvconf)) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, "loading configuration from '%s'", filename); CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser)); cfg_parser_setcallback(parser, directory_callback, NULL); result = cfg_parse_file(parser, filename, &cfg_type_namedconf, &config); } /* * If this is lwresd with the -C option, or lwresd with no -C or -c * option where the above parsing failed, parse resolv.conf. */ if (ns_g_lwresdonly && (lwresd_g_useresolvconf || (!ns_g_conffileset && result == ISC_R_FILENOTFOUND))) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, "loading configuration from '%s'", lwresd_g_resolvconffile); if (parser != NULL) cfg_parser_destroy(&parser); CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser)); result = ns_lwresd_parseeresolvconf(ns_g_mctx, parser, &config); } CHECK(result); /* * Check the validity of the configuration. */ CHECK(cfg_check_namedconf(config, ns_g_lctx, ns_g_mctx)); /* * Fill in the maps array, used for resolving defaults. */ i = 0; options = NULL; result = cfg_map_get(config, "options", &options); if (result == ISC_R_SUCCESS) maps[i++] = options; maps[i++] = ns_g_defaults; maps[i++] = NULL; /* * Set process limits, which (usually) needs to be done as root. */ set_limits(maps); /* * Configure various server options. */ configure_server_quota(maps, "transfers-out", &server->xfroutquota); configure_server_quota(maps, "tcp-clients", &server->tcpquota); configure_server_quota(maps, "recursive-clients", &server->recursionquota); CHECK(configure_view_acl(NULL, config, "blackhole", &aclconfctx, ns_g_mctx, &server->blackholeacl)); if (server->blackholeacl != NULL) dns_dispatchmgr_setblackhole(ns_g_dispatchmgr, server->blackholeacl); obj = NULL; result = ns_config_get(maps, "match-mapped-addresses", &obj); INSIST(result == ISC_R_SUCCESS); server->aclenv.match_mapped = cfg_obj_asboolean(obj); /* * Configure the zone manager. */ obj = NULL; result = ns_config_get(maps, "transfers-in", &obj); INSIST(result == ISC_R_SUCCESS); dns_zonemgr_settransfersin(server->zonemgr, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "transfers-per-ns", &obj); INSIST(result == ISC_R_SUCCESS); dns_zonemgr_settransfersperns(server->zonemgr, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "serial-query-rate", &obj); INSIST(result == ISC_R_SUCCESS); dns_zonemgr_setserialqueryrate(server->zonemgr, cfg_obj_asuint32(obj)); /* * Determine which port to use for listening for incoming connections. */ if (ns_g_port != 0) listen_port = ns_g_port; else CHECKM(ns_config_getport(config, &listen_port), "port"); /* * Configure the interface manager according to the "listen-on" * statement. */ { cfg_obj_t *clistenon = NULL; ns_listenlist_t *listenon = NULL; clistenon = NULL; /* * Even though listen-on is present in the default * configuration, we can't use it here, since it isn't * used if we're in lwresd mode. This way is easier. */ if (options != NULL) (void)cfg_map_get(options, "listen-on", &clistenon); if (clistenon != NULL) { result = ns_listenlist_fromconfig(clistenon, config, &aclconfctx, ns_g_mctx, &listenon); } else if (!ns_g_lwresdonly) { /* * Not specified, use default. */ CHECK(ns_listenlist_default(ns_g_mctx, listen_port, ISC_TRUE, &listenon)); } if (listenon != NULL) { ns_interfacemgr_setlistenon4(server->interfacemgr, listenon); ns_listenlist_detach(&listenon); } } /* * Ditto for IPv6. */ { cfg_obj_t *clistenon = NULL; ns_listenlist_t *listenon = NULL; if (options != NULL) (void)cfg_map_get(options, "listen-on-v6", &clistenon); if (clistenon != NULL) { result = ns_listenlist_fromconfig(clistenon, config, &aclconfctx, ns_g_mctx, &listenon); } else if (!ns_g_lwresdonly) { /* * Not specified, use default. */ CHECK(ns_listenlist_default(ns_g_mctx, listen_port, ISC_FALSE, &listenon)); } if (listenon != NULL) { ns_interfacemgr_setlistenon6(server->interfacemgr, listenon); ns_listenlist_detach(&listenon); } } /* * Rescan the interface list to pick up changes in the * listen-on option. It's important that we do this before we try * to configure the query source, since the dispatcher we use might * be shared with an interface. */ scan_interfaces(server, ISC_TRUE); /* * Arrange for further interface scanning to occur periodically * as specified by the "interface-interval" option. */ obj = NULL; result = ns_config_get(maps, "interface-interval", &obj); INSIST(result == ISC_R_SUCCESS); interface_interval = cfg_obj_asuint32(obj) * 60; if (interface_interval == 0) { isc_timer_reset(server->interface_timer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); } else if (server->interface_interval != interface_interval) { isc_interval_t interval; isc_interval_set(&interval, interface_interval, 0); isc_timer_reset(server->interface_timer, isc_timertype_ticker, NULL, &interval, ISC_FALSE); } server->interface_interval = interface_interval; /* * Configure the dialup heartbeat timer. */ obj = NULL; result = ns_config_get(maps, "heartbeat-interval", &obj); INSIST(result == ISC_R_SUCCESS); heartbeat_interval = cfg_obj_asuint32(obj) * 60; if (heartbeat_interval == 0) { isc_timer_reset(server->heartbeat_timer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); } else if (server->heartbeat_interval != heartbeat_interval) { isc_interval_t interval; isc_interval_set(&interval, heartbeat_interval, 0); isc_timer_reset(server->heartbeat_timer, isc_timertype_ticker, NULL, &interval, ISC_FALSE); } server->heartbeat_interval = heartbeat_interval; /* * Configure and freeze all explicit views. Explicit * views that have zones were already created at parsing * time, but views with no zones must be created here. */ views = NULL; (void)cfg_map_get(config, "view", &views); for (element = cfg_list_first(views); element != NULL; element = cfg_list_next(element))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -