Пример #1
0
/** Iterate through raw view data and apply the view-specific respip
 * configuration; at this point we should have already seen all the views,
 * so if any of the views that respip data refer to does not exist, that's
 * an error.  This additional iteration through view configuration data
 * is expected to not have significant performance impact (or rather, its
 * performance impact is not expected to be prohibitive in the configuration
 * processing phase).
 */
int
respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
	int* have_view_respip_cfg)
{
	struct config_view* cv;
	struct view* v;
	int ret;

	for(cv = cfg->views; cv; cv = cv->next) {

		/** if no respip config for this view then there's
		  * nothing to do; note that even though respip data must go
		  * with respip action, we're checking for both here because
		  * we want to catch the case where the respip action is missing
		  * while the data is present */
		if(!cv->respip_actions && !cv->respip_data)
			continue;

		if(!(v = views_find_view(vs, cv->name, 1))) {
			log_err("view '%s' unexpectedly missing", cv->name);
			return 0;
		}
		if(!v->respip_set) {
			v->respip_set = respip_set_create();
			if(!v->respip_set) {
				log_err("out of memory");
				lock_rw_unlock(&v->lock);
				return 0;
			}
		}
		ret = respip_set_apply_cfg(v->respip_set, NULL, 0, NULL,
			cv->respip_actions, cv->respip_data);
		lock_rw_unlock(&v->lock);
		if(!ret) {
			log_err("Error while applying respip configuration "
				"for view '%s'", cv->name);
			return 0;
		}
		*have_view_respip_cfg = (*have_view_respip_cfg ||
			v->respip_set->ip_tree.count);
		cv->respip_actions = NULL;
		cv->respip_data = NULL;
	}
	return 1;
}
Пример #2
0
void 
daemon_fork(struct daemon* daemon)
{
	int have_view_respip_cfg = 0;

	log_assert(daemon);
	if(!(daemon->views = views_create()))
		fatal_exit("Could not create views: out of memory");
	/* create individual views and their localzone/data trees */
	if(!views_apply_cfg(daemon->views, daemon->cfg))
		fatal_exit("Could not set up views");

	if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
		fatal_exit("Could not setup access control list");
	if(daemon->cfg->dnscrypt) {
#ifdef USE_DNSCRYPT
		daemon->dnscenv = dnsc_create();
		if (!daemon->dnscenv)
			fatal_exit("dnsc_create failed");
		dnsc_apply_cfg(daemon->dnscenv, daemon->cfg);
#else
		fatal_exit("dnscrypt enabled in config but unbound was not built with "
				   "dnscrypt support");
#endif
	}
	/* create global local_zones */
	if(!(daemon->local_zones = local_zones_create()))
		fatal_exit("Could not create local zones: out of memory");
	if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
		fatal_exit("Could not set up local zones");

	/* process raw response-ip configuration data */
	if(!(daemon->respip_set = respip_set_create()))
		fatal_exit("Could not create response IP set");
	if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg))
		fatal_exit("Could not set up response IP set");
	if(!respip_views_apply_cfg(daemon->views, daemon->cfg,
		&have_view_respip_cfg))
		fatal_exit("Could not set up per-view response IP sets");
	daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
		have_view_respip_cfg;
	
	/* read auth zonefiles */
	if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1))
		fatal_exit("auth_zones could not be setup");

	/* setup modules */
	daemon_setup_modules(daemon);

	/* response-ip-xxx options don't work as expected without the respip
	 * module.  To avoid run-time operational surprise we reject such
	 * configuration. */
	if(daemon->use_response_ip &&
		modstack_find(&daemon->mods, "respip") < 0)
		fatal_exit("response-ip options require respip module");

	/* first create all the worker structures, so we can pass
	 * them to the newly created threads. 
	 */
	daemon_create_workers(daemon);

#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
	/* in libev the first inited base gets signals */
	if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1))
		fatal_exit("Could not initialize main thread");
#endif
	
	/* Now create the threads and init the workers.
	 * By the way, this is thread #0 (the main thread).
	 */
	daemon_start_others(daemon);

	/* Special handling for the main thread. This is the thread
	 * that handles signals and remote control.
	 */
#if !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP))
	/* libevent has the last inited base get signals (or any base) */
	if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1))
		fatal_exit("Could not initialize main thread");
#endif
	signal_handling_playback(daemon->workers[0]);

	if (!shm_main_init(daemon))
		log_warn("SHM has failed");

	/* Start resolver service on main thread. */
#ifdef HAVE_SYSTEMD
	sd_notify(0, "READY=1");
#endif
	log_info("start of service (%s).", PACKAGE_STRING);
	worker_work(daemon->workers[0]);
#ifdef HAVE_SYSTEMD
	sd_notify(0, "STOPPING=1");
#endif
	log_info("service stopped (%s).", PACKAGE_STRING);

	/* we exited! a signal happened! Stop other threads */
	daemon_stop_others(daemon);

	/* Shutdown SHM */
	shm_main_shutdown(daemon);

	daemon->need_to_exit = daemon->workers[0]->need_to_exit;
}