⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -