xref: /openbsd-src/usr.sbin/unbound/daemon/daemon.c (revision 98bc733b08604094f4138174a0ee0bb9faaca4bd)
1933707f3Ssthen /*
2933707f3Ssthen  * daemon/daemon.c - collection of workers that handles requests.
3933707f3Ssthen  *
4933707f3Ssthen  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5933707f3Ssthen  *
6933707f3Ssthen  * This software is open source.
7933707f3Ssthen  *
8933707f3Ssthen  * Redistribution and use in source and binary forms, with or without
9933707f3Ssthen  * modification, are permitted provided that the following conditions
10933707f3Ssthen  * are met:
11933707f3Ssthen  *
12933707f3Ssthen  * Redistributions of source code must retain the above copyright notice,
13933707f3Ssthen  * this list of conditions and the following disclaimer.
14933707f3Ssthen  *
15933707f3Ssthen  * Redistributions in binary form must reproduce the above copyright notice,
16933707f3Ssthen  * this list of conditions and the following disclaimer in the documentation
17933707f3Ssthen  * and/or other materials provided with the distribution.
18933707f3Ssthen  *
19933707f3Ssthen  * Neither the name of the NLNET LABS nor the names of its contributors may
20933707f3Ssthen  * be used to endorse or promote products derived from this software without
21933707f3Ssthen  * specific prior written permission.
22933707f3Ssthen  *
23933707f3Ssthen  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
245d76a658Ssthen  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
255d76a658Ssthen  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
265d76a658Ssthen  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
275d76a658Ssthen  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
285d76a658Ssthen  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
295d76a658Ssthen  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
305d76a658Ssthen  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
315d76a658Ssthen  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
325d76a658Ssthen  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
335d76a658Ssthen  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34933707f3Ssthen  */
35933707f3Ssthen 
36933707f3Ssthen /**
37933707f3Ssthen  * \file
38933707f3Ssthen  *
39933707f3Ssthen  * The daemon consists of global settings and a number of workers.
40933707f3Ssthen  */
41933707f3Ssthen 
42933707f3Ssthen #include "config.h"
43933707f3Ssthen #ifdef HAVE_OPENSSL_ERR_H
44933707f3Ssthen #include <openssl/err.h>
45933707f3Ssthen #endif
46933707f3Ssthen 
47933707f3Ssthen #ifdef HAVE_OPENSSL_RAND_H
48933707f3Ssthen #include <openssl/rand.h>
49933707f3Ssthen #endif
50933707f3Ssthen 
51933707f3Ssthen #ifdef HAVE_OPENSSL_CONF_H
52933707f3Ssthen #include <openssl/conf.h>
53933707f3Ssthen #endif
54933707f3Ssthen 
55933707f3Ssthen #ifdef HAVE_OPENSSL_ENGINE_H
56933707f3Ssthen #include <openssl/engine.h>
57933707f3Ssthen #endif
583dcb24b8Ssthen 
595d76a658Ssthen #ifdef HAVE_TIME_H
605d76a658Ssthen #include <time.h>
615d76a658Ssthen #endif
625d76a658Ssthen #include <sys/time.h>
635d76a658Ssthen 
643dcb24b8Ssthen #ifdef HAVE_NSS
65229e174cSsthen /* nss3 */
66229e174cSsthen #include "nss.h"
673dcb24b8Ssthen #endif
683dcb24b8Ssthen 
69933707f3Ssthen #include "daemon/daemon.h"
70933707f3Ssthen #include "daemon/worker.h"
71933707f3Ssthen #include "daemon/remote.h"
72933707f3Ssthen #include "daemon/acl_list.h"
73933707f3Ssthen #include "util/log.h"
74933707f3Ssthen #include "util/config_file.h"
75933707f3Ssthen #include "util/data/msgreply.h"
762be9e038Ssthen #include "util/shm_side/shm_main.h"
77933707f3Ssthen #include "util/storage/lookup3.h"
78933707f3Ssthen #include "util/storage/slabhash.h"
792308e98cSsthen #include "util/tcp_conn_limit.h"
802c144df0Ssthen #include "util/edns.h"
81933707f3Ssthen #include "services/listen_dnsport.h"
82933707f3Ssthen #include "services/cache/rrset.h"
83933707f3Ssthen #include "services/cache/infra.h"
84933707f3Ssthen #include "services/localzone.h"
8577079be7Ssthen #include "services/view.h"
86933707f3Ssthen #include "services/modstack.h"
87938a3a5eSflorian #include "services/authzone.h"
88933707f3Ssthen #include "util/module.h"
89933707f3Ssthen #include "util/random.h"
90933707f3Ssthen #include "util/tube.h"
91229e174cSsthen #include "util/net_help.h"
92fdfb4ba6Ssthen #include "sldns/keyraw.h"
932be9e038Ssthen #include "respip/respip.h"
942bdc0ed1Ssthen #include "iterator/iter_fwd.h"
952bdc0ed1Ssthen #include "iterator/iter_hints.h"
96933707f3Ssthen #include <signal.h>
97933707f3Ssthen 
9877079be7Ssthen #ifdef HAVE_SYSTEMD
9977079be7Ssthen #include <systemd/sd-daemon.h>
10077079be7Ssthen #endif
10145872187Ssthen #ifdef HAVE_NETDB_H
10245872187Ssthen #include <netdb.h>
10345872187Ssthen #endif
1042bdc0ed1Ssthen #ifdef USE_CACHEDB
1052bdc0ed1Ssthen #include "cachedb/cachedb.h"
1062bdc0ed1Ssthen #endif
10777079be7Ssthen 
108933707f3Ssthen /** How many quit requests happened. */
109933707f3Ssthen static int sig_record_quit = 0;
110933707f3Ssthen /** How many reload requests happened. */
111933707f3Ssthen static int sig_record_reload = 0;
112933707f3Ssthen 
113933707f3Ssthen #if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
114933707f3Ssthen /** cleaner ssl memory freeup */
115933707f3Ssthen static void* comp_meth = NULL;
116933707f3Ssthen #endif
117933707f3Ssthen /** remove buffers for parsing and init */
118933707f3Ssthen int ub_c_lex_destroy(void);
119933707f3Ssthen 
120933707f3Ssthen /** used when no other sighandling happens, so we don't die
121933707f3Ssthen   * when multiple signals in quick succession are sent to us.
122933707f3Ssthen   * @param sig: signal number.
123933707f3Ssthen   * @return signal handler return type (void or int).
124933707f3Ssthen   */
125933707f3Ssthen static RETSIGTYPE record_sigh(int sig)
126933707f3Ssthen {
127933707f3Ssthen #ifdef LIBEVENT_SIGNAL_PROBLEM
12898f3ca02Sbrad 	/* cannot log, verbose here because locks may be held */
12998f3ca02Sbrad 	/* quit on signal, no cleanup and statistics,
13098f3ca02Sbrad 	   because installed libevent version is not threadsafe */
131933707f3Ssthen 	exit(0);
132933707f3Ssthen #endif
133933707f3Ssthen 	switch(sig)
134933707f3Ssthen 	{
135933707f3Ssthen 		case SIGTERM:
136933707f3Ssthen #ifdef SIGQUIT
137933707f3Ssthen 		case SIGQUIT:
138933707f3Ssthen #endif
139933707f3Ssthen #ifdef SIGBREAK
140933707f3Ssthen 		case SIGBREAK:
141933707f3Ssthen #endif
142933707f3Ssthen 		case SIGINT:
143933707f3Ssthen 			sig_record_quit++;
144933707f3Ssthen 			break;
145933707f3Ssthen #ifdef SIGHUP
146933707f3Ssthen 		case SIGHUP:
147933707f3Ssthen 			sig_record_reload++;
148933707f3Ssthen 			break;
149933707f3Ssthen #endif
150933707f3Ssthen #ifdef SIGPIPE
151933707f3Ssthen 		case SIGPIPE:
152933707f3Ssthen 			break;
153933707f3Ssthen #endif
154933707f3Ssthen 		default:
15598f3ca02Sbrad 			/* ignoring signal */
15698f3ca02Sbrad 			break;
157933707f3Ssthen 	}
158933707f3Ssthen }
159933707f3Ssthen 
160933707f3Ssthen /**
161933707f3Ssthen  * Signal handling during the time when netevent is disabled.
162933707f3Ssthen  * Stores signals to replay later.
163933707f3Ssthen  */
164933707f3Ssthen static void
165933707f3Ssthen signal_handling_record(void)
166933707f3Ssthen {
167933707f3Ssthen 	if( signal(SIGTERM, record_sigh) == SIG_ERR ||
168933707f3Ssthen #ifdef SIGQUIT
169933707f3Ssthen 		signal(SIGQUIT, record_sigh) == SIG_ERR ||
170933707f3Ssthen #endif
171933707f3Ssthen #ifdef SIGBREAK
172933707f3Ssthen 		signal(SIGBREAK, record_sigh) == SIG_ERR ||
173933707f3Ssthen #endif
174933707f3Ssthen #ifdef SIGHUP
175933707f3Ssthen 		signal(SIGHUP, record_sigh) == SIG_ERR ||
176933707f3Ssthen #endif
177933707f3Ssthen #ifdef SIGPIPE
178933707f3Ssthen 		signal(SIGPIPE, SIG_IGN) == SIG_ERR ||
179933707f3Ssthen #endif
180933707f3Ssthen 		signal(SIGINT, record_sigh) == SIG_ERR
181933707f3Ssthen 		)
182933707f3Ssthen 		log_err("install sighandler: %s", strerror(errno));
183933707f3Ssthen }
184933707f3Ssthen 
185933707f3Ssthen /**
186933707f3Ssthen  * Replay old signals.
187933707f3Ssthen  * @param wrk: worker that handles signals.
188933707f3Ssthen  */
189933707f3Ssthen static void
190933707f3Ssthen signal_handling_playback(struct worker* wrk)
191933707f3Ssthen {
192933707f3Ssthen #ifdef SIGHUP
1932308e98cSsthen 	if(sig_record_reload)
194933707f3Ssthen 		worker_sighandler(SIGHUP, wrk);
195933707f3Ssthen #endif
196933707f3Ssthen 	if(sig_record_quit)
197933707f3Ssthen 		worker_sighandler(SIGTERM, wrk);
198933707f3Ssthen 	sig_record_quit = 0;
199933707f3Ssthen 	sig_record_reload = 0;
200933707f3Ssthen }
201933707f3Ssthen 
202933707f3Ssthen struct daemon*
203933707f3Ssthen daemon_init(void)
204933707f3Ssthen {
205933707f3Ssthen 	struct daemon* daemon = (struct daemon*)calloc(1,
206933707f3Ssthen 		sizeof(struct daemon));
207933707f3Ssthen #ifdef USE_WINSOCK
208933707f3Ssthen 	int r;
209933707f3Ssthen 	WSADATA wsa_data;
210933707f3Ssthen #endif
211933707f3Ssthen 	if(!daemon)
212933707f3Ssthen 		return NULL;
213933707f3Ssthen #ifdef USE_WINSOCK
214933707f3Ssthen 	r = WSAStartup(MAKEWORD(2,2), &wsa_data);
215933707f3Ssthen 	if(r != 0) {
216933707f3Ssthen 		fatal_exit("could not init winsock. WSAStartup: %s",
217933707f3Ssthen 			wsa_strerror(r));
218933707f3Ssthen 	}
219933707f3Ssthen #endif /* USE_WINSOCK */
220933707f3Ssthen 	signal_handling_record();
2213dcb24b8Ssthen #ifdef HAVE_SSL
22277079be7Ssthen #  ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
223933707f3Ssthen 	ERR_load_crypto_strings();
22477079be7Ssthen #  endif
2257191de28Ssthen #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
226933707f3Ssthen 	ERR_load_SSL_strings();
2277191de28Ssthen #endif
228933707f3Ssthen #  ifdef USE_GOST
2295d76a658Ssthen 	(void)sldns_key_EVP_load_gost_id();
230933707f3Ssthen #  endif
23177079be7Ssthen #  if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
232ebf5bb73Ssthen #    ifndef S_SPLINT_S
233933707f3Ssthen 	OpenSSL_add_all_algorithms();
234ebf5bb73Ssthen #    endif
23577079be7Ssthen #  else
23677079be7Ssthen 	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
23777079be7Ssthen 		| OPENSSL_INIT_ADD_ALL_DIGESTS
23877079be7Ssthen 		| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
23977079be7Ssthen #  endif
240933707f3Ssthen #  if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
241933707f3Ssthen 	/* grab the COMP method ptr because openssl leaks it */
242933707f3Ssthen 	comp_meth = (void*)SSL_COMP_get_compression_methods();
243933707f3Ssthen #  endif
24477079be7Ssthen #  if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
245933707f3Ssthen 	(void)SSL_library_init();
24677079be7Ssthen #  else
2477191de28Ssthen 	(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
24877079be7Ssthen #  endif
249229e174cSsthen #  if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
250229e174cSsthen 	if(!ub_openssl_lock_init())
251229e174cSsthen 		fatal_exit("could not init openssl locks");
252229e174cSsthen #  endif
2533dcb24b8Ssthen #elif defined(HAVE_NSS)
2543dcb24b8Ssthen 	if(NSS_NoDB_Init(NULL) != SECSuccess)
2553dcb24b8Ssthen 		fatal_exit("could not init NSS");
2563dcb24b8Ssthen #endif /* HAVE_SSL or HAVE_NSS */
257933707f3Ssthen #ifdef HAVE_TZSET
258933707f3Ssthen 	/* init timezone info while we are not chrooted yet */
259933707f3Ssthen 	tzset();
260933707f3Ssthen #endif
261933707f3Ssthen 	daemon->need_to_exit = 0;
262933707f3Ssthen 	modstack_init(&daemon->mods);
263933707f3Ssthen 	if(!(daemon->env = (struct module_env*)calloc(1,
264933707f3Ssthen 		sizeof(*daemon->env)))) {
265933707f3Ssthen 		free(daemon);
266933707f3Ssthen 		return NULL;
267933707f3Ssthen 	}
2682bdc0ed1Ssthen 	daemon->env->modstack = &daemon->mods;
26977079be7Ssthen 	/* init edns_known_options */
27077079be7Ssthen 	if(!edns_known_options_init(daemon->env)) {
27177079be7Ssthen 		free(daemon->env);
27277079be7Ssthen 		free(daemon);
27377079be7Ssthen 		return NULL;
27477079be7Ssthen 	}
275933707f3Ssthen 	alloc_init(&daemon->superalloc, NULL, 0);
276933707f3Ssthen 	daemon->acl = acl_list_create();
277933707f3Ssthen 	if(!daemon->acl) {
27877079be7Ssthen 		edns_known_options_delete(daemon->env);
279933707f3Ssthen 		free(daemon->env);
280933707f3Ssthen 		free(daemon);
281933707f3Ssthen 		return NULL;
282933707f3Ssthen 	}
28345872187Ssthen 	daemon->acl_interface = acl_list_create();
28445872187Ssthen 	if(!daemon->acl_interface) {
28545872187Ssthen 		acl_list_delete(daemon->acl);
28645872187Ssthen 		edns_known_options_delete(daemon->env);
28745872187Ssthen 		free(daemon->env);
28845872187Ssthen 		free(daemon);
28945872187Ssthen 		return NULL;
29045872187Ssthen 	}
2912308e98cSsthen 	daemon->tcl = tcl_list_create();
2922308e98cSsthen 	if(!daemon->tcl) {
29345872187Ssthen 		acl_list_delete(daemon->acl_interface);
2942308e98cSsthen 		acl_list_delete(daemon->acl);
2952308e98cSsthen 		edns_known_options_delete(daemon->env);
2962308e98cSsthen 		free(daemon->env);
2972308e98cSsthen 		free(daemon);
2982308e98cSsthen 		return NULL;
2992308e98cSsthen 	}
300e21c60efSsthen 	listen_setup_locks();
301933707f3Ssthen 	if(gettimeofday(&daemon->time_boot, NULL) < 0)
302933707f3Ssthen 		log_err("gettimeofday: %s", strerror(errno));
303933707f3Ssthen 	daemon->time_last_stat = daemon->time_boot;
304938a3a5eSflorian 	if((daemon->env->auth_zones = auth_zones_create()) == 0) {
30545872187Ssthen 		acl_list_delete(daemon->acl_interface);
306938a3a5eSflorian 		acl_list_delete(daemon->acl);
3072308e98cSsthen 		tcl_list_delete(daemon->tcl);
308938a3a5eSflorian 		edns_known_options_delete(daemon->env);
309938a3a5eSflorian 		free(daemon->env);
310938a3a5eSflorian 		free(daemon);
311938a3a5eSflorian 		return NULL;
312938a3a5eSflorian 	}
313eba819a2Ssthen 	if(!(daemon->env->edns_strings = edns_strings_create())) {
3142c144df0Ssthen 		auth_zones_delete(daemon->env->auth_zones);
31545872187Ssthen 		acl_list_delete(daemon->acl_interface);
3162c144df0Ssthen 		acl_list_delete(daemon->acl);
3172c144df0Ssthen 		tcl_list_delete(daemon->tcl);
3182c144df0Ssthen 		edns_known_options_delete(daemon->env);
3192c144df0Ssthen 		free(daemon->env);
3202c144df0Ssthen 		free(daemon);
3212c144df0Ssthen 		return NULL;
3222c144df0Ssthen 	}
323933707f3Ssthen 	return daemon;
324933707f3Ssthen }
325933707f3Ssthen 
32645872187Ssthen static int setup_acl_for_ports(struct acl_list* list,
32745872187Ssthen 	struct listen_port* port_list)
32845872187Ssthen {
32945872187Ssthen 	struct acl_addr* acl_node;
33045872187Ssthen 	for(; port_list; port_list=port_list->next) {
33145872187Ssthen 		if(!port_list->socket) {
33245872187Ssthen 			/* This is mainly for testbound where port_list is
33345872187Ssthen 			 * empty. */
33445872187Ssthen 			continue;
33545872187Ssthen 		}
33645872187Ssthen 		if(!(acl_node = acl_interface_insert(list,
3372bdc0ed1Ssthen 			(struct sockaddr_storage*)port_list->socket->addr,
3382bdc0ed1Ssthen 			port_list->socket->addrlen,
33945872187Ssthen 			acl_refuse))) {
34045872187Ssthen 			return 0;
34145872187Ssthen 		}
34245872187Ssthen 		port_list->socket->acl = acl_node;
34345872187Ssthen 	}
34445872187Ssthen 	return 1;
34545872187Ssthen }
34645872187Ssthen 
347933707f3Ssthen int
348933707f3Ssthen daemon_open_shared_ports(struct daemon* daemon)
349933707f3Ssthen {
350933707f3Ssthen 	log_assert(daemon);
351933707f3Ssthen 	if(daemon->cfg->port != daemon->listening_port) {
3522c144df0Ssthen 		char** resif = NULL;
3532c144df0Ssthen 		int num_resif = 0;
3545d76a658Ssthen 		size_t i;
3555d76a658Ssthen 		struct listen_port* p0;
35698f3ca02Sbrad 		daemon->reuseport = 0;
3575d76a658Ssthen 		/* free and close old ports */
3585d76a658Ssthen 		if(daemon->ports != NULL) {
3595d76a658Ssthen 			for(i=0; i<daemon->num_ports; i++)
3605d76a658Ssthen 				listening_ports_free(daemon->ports[i]);
3615d76a658Ssthen 			free(daemon->ports);
3625d76a658Ssthen 			daemon->ports = NULL;
3635d76a658Ssthen 		}
36445872187Ssthen 		/* clean acl_interface */
36545872187Ssthen 		acl_interface_init(daemon->acl_interface);
366191f22c6Ssthen 		if(!resolve_interface_names(daemon->cfg->ifs,
367191f22c6Ssthen 			daemon->cfg->num_ifs, NULL, &resif, &num_resif))
3682c144df0Ssthen 			return 0;
3695d76a658Ssthen 		/* see if we want to reuseport */
37098f3ca02Sbrad #ifdef SO_REUSEPORT
3715d76a658Ssthen 		if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0)
37298f3ca02Sbrad 			daemon->reuseport = 1;
3735d76a658Ssthen #endif
3745d76a658Ssthen 		/* try to use reuseport */
37545872187Ssthen 		p0 = listening_ports_open(daemon->cfg, resif, num_resif,
37645872187Ssthen 			&daemon->reuseport);
3775d76a658Ssthen 		if(!p0) {
3785d76a658Ssthen 			listening_ports_free(p0);
3792c144df0Ssthen 			config_del_strarray(resif, num_resif);
380933707f3Ssthen 			return 0;
3815d76a658Ssthen 		}
38298f3ca02Sbrad 		if(daemon->reuseport) {
3835d76a658Ssthen 			/* reuseport was successful, allocate for it */
3845d76a658Ssthen 			daemon->num_ports = (size_t)daemon->cfg->num_threads;
3855d76a658Ssthen 		} else {
3865d76a658Ssthen 			/* do the normal, singleportslist thing,
3875d76a658Ssthen 			 * reuseport not enabled or did not work */
3885d76a658Ssthen 			daemon->num_ports = 1;
3895d76a658Ssthen 		}
3905d76a658Ssthen 		if(!(daemon->ports = (struct listen_port**)calloc(
3915d76a658Ssthen 			daemon->num_ports, sizeof(*daemon->ports)))) {
3925d76a658Ssthen 			listening_ports_free(p0);
3932c144df0Ssthen 			config_del_strarray(resif, num_resif);
3945d76a658Ssthen 			return 0;
3955d76a658Ssthen 		}
3965d76a658Ssthen 		daemon->ports[0] = p0;
39745872187Ssthen 		if(!setup_acl_for_ports(daemon->acl_interface,
39845872187Ssthen 		    daemon->ports[0])) {
39945872187Ssthen 			listening_ports_free(p0);
40045872187Ssthen 			config_del_strarray(resif, num_resif);
40145872187Ssthen 			return 0;
40245872187Ssthen 		}
40398f3ca02Sbrad 		if(daemon->reuseport) {
4045d76a658Ssthen 			/* continue to use reuseport */
4055d76a658Ssthen 			for(i=1; i<daemon->num_ports; i++) {
4065d76a658Ssthen 				if(!(daemon->ports[i]=
4075d76a658Ssthen 					listening_ports_open(daemon->cfg,
4082c144df0Ssthen 						resif, num_resif,
40998f3ca02Sbrad 						&daemon->reuseport))
41098f3ca02Sbrad 					|| !daemon->reuseport ) {
4115d76a658Ssthen 					for(i=0; i<daemon->num_ports; i++)
4125d76a658Ssthen 						listening_ports_free(daemon->ports[i]);
4135d76a658Ssthen 					free(daemon->ports);
4145d76a658Ssthen 					daemon->ports = NULL;
4152c144df0Ssthen 					config_del_strarray(resif, num_resif);
4165d76a658Ssthen 					return 0;
4175d76a658Ssthen 				}
41845872187Ssthen 				if(!setup_acl_for_ports(daemon->acl_interface,
41945872187Ssthen 					daemon->ports[i])) {
42045872187Ssthen 					for(i=0; i<daemon->num_ports; i++)
42145872187Ssthen 						listening_ports_free(daemon->ports[i]);
42245872187Ssthen 					free(daemon->ports);
42345872187Ssthen 					daemon->ports = NULL;
42445872187Ssthen 					config_del_strarray(resif, num_resif);
42545872187Ssthen 					return 0;
42645872187Ssthen 				}
4275d76a658Ssthen 			}
4285d76a658Ssthen 		}
4292c144df0Ssthen 		config_del_strarray(resif, num_resif);
430933707f3Ssthen 		daemon->listening_port = daemon->cfg->port;
431933707f3Ssthen 	}
432933707f3Ssthen 	if(!daemon->cfg->remote_control_enable && daemon->rc_port) {
433933707f3Ssthen 		listening_ports_free(daemon->rc_ports);
434933707f3Ssthen 		daemon->rc_ports = NULL;
435933707f3Ssthen 		daemon->rc_port = 0;
436933707f3Ssthen 	}
437933707f3Ssthen 	if(daemon->cfg->remote_control_enable &&
438933707f3Ssthen 		daemon->cfg->control_port != daemon->rc_port) {
439933707f3Ssthen 		listening_ports_free(daemon->rc_ports);
440933707f3Ssthen 		if(!(daemon->rc_ports=daemon_remote_open_ports(daemon->cfg)))
441933707f3Ssthen 			return 0;
442933707f3Ssthen 		daemon->rc_port = daemon->cfg->control_port;
443933707f3Ssthen 	}
444933707f3Ssthen 	return 1;
445933707f3Ssthen }
446933707f3Ssthen 
447*98bc733bSsthen int
448*98bc733bSsthen daemon_privileged(struct daemon* daemon)
449*98bc733bSsthen {
450*98bc733bSsthen 	daemon->env->cfg = daemon->cfg;
451*98bc733bSsthen 	daemon->env->alloc = &daemon->superalloc;
452*98bc733bSsthen 	daemon->env->worker = NULL;
453*98bc733bSsthen 	if(!modstack_call_startup(&daemon->mods, daemon->cfg->module_conf,
454*98bc733bSsthen 		daemon->env)) {
455*98bc733bSsthen 		fatal_exit("failed to startup modules");
456*98bc733bSsthen 	}
457*98bc733bSsthen 	return 1;
458*98bc733bSsthen }
459*98bc733bSsthen 
460933707f3Ssthen /**
461933707f3Ssthen  * Setup modules. setup module stack.
462933707f3Ssthen  * @param daemon: the daemon
463933707f3Ssthen  */
464933707f3Ssthen static void daemon_setup_modules(struct daemon* daemon)
465933707f3Ssthen {
466933707f3Ssthen 	daemon->env->cfg = daemon->cfg;
467933707f3Ssthen 	daemon->env->alloc = &daemon->superalloc;
468933707f3Ssthen 	daemon->env->worker = NULL;
469*98bc733bSsthen 	if(daemon->mods_inited) {
470*98bc733bSsthen 		modstack_call_deinit(&daemon->mods, daemon->env);
471933707f3Ssthen 	}
472*98bc733bSsthen 	daemon->env->need_to_validate = 0; /* set by module init below */
473*98bc733bSsthen 	if(!modstack_call_init(&daemon->mods, daemon->cfg->module_conf,
474*98bc733bSsthen 		daemon->env)) {
475*98bc733bSsthen 		fatal_exit("failed to init modules");
476*98bc733bSsthen 	}
477*98bc733bSsthen 	daemon->mods_inited = 1;
47877079be7Ssthen 	log_edns_known_options(VERB_ALGO, daemon->env);
479933707f3Ssthen }
480933707f3Ssthen 
481933707f3Ssthen /**
482933707f3Ssthen  * Obtain allowed port numbers, concatenate the list, and shuffle them
483933707f3Ssthen  * (ready to be handed out to threads).
484933707f3Ssthen  * @param daemon: the daemon. Uses rand and cfg.
485933707f3Ssthen  * @param shufport: the portlist output.
486933707f3Ssthen  * @return number of ports available.
487933707f3Ssthen  */
488933707f3Ssthen static int daemon_get_shufport(struct daemon* daemon, int* shufport)
489933707f3Ssthen {
490933707f3Ssthen 	int i, n, k, temp;
491933707f3Ssthen 	int avail = 0;
492933707f3Ssthen 	for(i=0; i<65536; i++) {
493933707f3Ssthen 		if(daemon->cfg->outgoing_avail_ports[i]) {
494933707f3Ssthen 			shufport[avail++] = daemon->cfg->
495933707f3Ssthen 				outgoing_avail_ports[i];
496933707f3Ssthen 		}
497933707f3Ssthen 	}
498933707f3Ssthen 	if(avail == 0)
499933707f3Ssthen 		fatal_exit("no ports are permitted for UDP, add "
500933707f3Ssthen 			"with outgoing-port-permit");
501933707f3Ssthen         /* Knuth shuffle */
502933707f3Ssthen 	n = avail;
503933707f3Ssthen 	while(--n > 0) {
504933707f3Ssthen 		k = ub_random_max(daemon->rand, n+1); /* 0<= k<= n */
505933707f3Ssthen 		temp = shufport[k];
506933707f3Ssthen 		shufport[k] = shufport[n];
507933707f3Ssthen 		shufport[n] = temp;
508933707f3Ssthen 	}
509933707f3Ssthen 	return avail;
510933707f3Ssthen }
511933707f3Ssthen 
512933707f3Ssthen /**
5138b7325afSsthen  * Clear and delete per-worker alloc caches, and free memory maintained in
5148b7325afSsthen  * superalloc.
5158b7325afSsthen  * The rrset and message caches must be empty at the time of call.
5168b7325afSsthen  * @param daemon: the daemon that maintains the alloc caches to be cleared.
5178b7325afSsthen  */
5188b7325afSsthen static void
5198b7325afSsthen daemon_clear_allocs(struct daemon* daemon)
5208b7325afSsthen {
5218b7325afSsthen 	int i;
5228b7325afSsthen 
523*98bc733bSsthen 	/* daemon->num may be different during reloads (after configuration
524*98bc733bSsthen 	 * read). Use old_num which has the correct value used to setup the
525*98bc733bSsthen 	 * worker_allocs */
526*98bc733bSsthen 	for(i=0; i<daemon->old_num; i++) {
5278b7325afSsthen 		alloc_clear(daemon->worker_allocs[i]);
5288b7325afSsthen 		free(daemon->worker_allocs[i]);
5298b7325afSsthen 	}
5308b7325afSsthen 	free(daemon->worker_allocs);
5318b7325afSsthen 	daemon->worker_allocs = NULL;
5328b7325afSsthen 
5338b7325afSsthen 	alloc_clear_special(&daemon->superalloc);
5348b7325afSsthen }
5358b7325afSsthen 
5368b7325afSsthen /**
537933707f3Ssthen  * Allocate empty worker structures. With backptr and thread-number,
538933707f3Ssthen  * from 0..numthread initialised. Used as user arguments to new threads.
539933707f3Ssthen  * Creates the daemon random generator if it does not exist yet.
540933707f3Ssthen  * The random generator stays existing between reloads with a unique state.
541933707f3Ssthen  * @param daemon: the daemon with (new) config settings.
542933707f3Ssthen  */
543933707f3Ssthen static void
544933707f3Ssthen daemon_create_workers(struct daemon* daemon)
545933707f3Ssthen {
546933707f3Ssthen 	int i, numport;
547933707f3Ssthen 	int* shufport;
548933707f3Ssthen 	log_assert(daemon && daemon->cfg);
549933707f3Ssthen 	if(!daemon->rand) {
550ebf5bb73Ssthen 		daemon->rand = ub_initstate(NULL);
551933707f3Ssthen 		if(!daemon->rand)
552933707f3Ssthen 			fatal_exit("could not init random generator");
553933707f3Ssthen 		hash_set_raninit((uint32_t)ub_random(daemon->rand));
5547191de28Ssthen 	}
555933707f3Ssthen 	shufport = (int*)calloc(65536, sizeof(int));
556933707f3Ssthen 	if(!shufport)
557933707f3Ssthen 		fatal_exit("out of memory during daemon init");
558933707f3Ssthen 	numport = daemon_get_shufport(daemon, shufport);
559933707f3Ssthen 	verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
560933707f3Ssthen 
561933707f3Ssthen 	daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
562a961b961Ssthen 	if(daemon->reuseport && (int)daemon->num < (int)daemon->num_ports) {
563a961b961Ssthen 		log_warn("cannot reduce num-threads to %d because so-reuseport "
564a961b961Ssthen 			"so continuing with %d threads.", (int)daemon->num,
565a961b961Ssthen 			(int)daemon->num_ports);
566a961b961Ssthen 		daemon->num = (int)daemon->num_ports;
567a961b961Ssthen 	}
568933707f3Ssthen 	daemon->workers = (struct worker**)calloc((size_t)daemon->num,
569933707f3Ssthen 		sizeof(struct worker*));
57077079be7Ssthen 	if(!daemon->workers)
57177079be7Ssthen 		fatal_exit("out of memory during daemon init");
57298f3ca02Sbrad 	if(daemon->cfg->dnstap) {
57398f3ca02Sbrad #ifdef USE_DNSTAP
574a3167c07Ssthen 		daemon->dtenv = dt_create(daemon->cfg);
57598f3ca02Sbrad 		if (!daemon->dtenv)
57698f3ca02Sbrad 			fatal_exit("dt_create failed");
57798f3ca02Sbrad #else
57898f3ca02Sbrad 		fatal_exit("dnstap enabled in config but not built with dnstap support");
57998f3ca02Sbrad #endif
58098f3ca02Sbrad 	}
581933707f3Ssthen 	for(i=0; i<daemon->num; i++) {
582933707f3Ssthen 		if(!(daemon->workers[i] = worker_create(daemon, i,
583933707f3Ssthen 			shufport+numport*i/daemon->num,
584933707f3Ssthen 			numport*(i+1)/daemon->num - numport*i/daemon->num)))
585933707f3Ssthen 			/* the above is not ports/numthr, due to rounding */
586933707f3Ssthen 			fatal_exit("could not create worker");
587933707f3Ssthen 	}
5888b7325afSsthen 	/* create per-worker alloc caches if not reusing existing ones. */
5898b7325afSsthen 	if(!daemon->worker_allocs) {
5908b7325afSsthen 		daemon->worker_allocs = (struct alloc_cache**)calloc(
5918b7325afSsthen 			(size_t)daemon->num, sizeof(struct alloc_cache*));
5928b7325afSsthen 		if(!daemon->worker_allocs)
5938b7325afSsthen 			fatal_exit("could not allocate worker allocs");
5948b7325afSsthen 		for(i=0; i<daemon->num; i++) {
5958b7325afSsthen 			struct alloc_cache* alloc = calloc(1,
5968b7325afSsthen 				sizeof(struct alloc_cache));
5978b7325afSsthen 			if (!alloc)
5988b7325afSsthen 				fatal_exit("could not allocate worker alloc");
5998b7325afSsthen 			alloc_init(alloc, &daemon->superalloc, i);
6008b7325afSsthen 			daemon->worker_allocs[i] = alloc;
6018b7325afSsthen 		}
6028b7325afSsthen 	}
603933707f3Ssthen 	free(shufport);
604933707f3Ssthen }
605933707f3Ssthen 
606933707f3Ssthen #ifdef THREADS_DISABLED
607933707f3Ssthen /**
608933707f3Ssthen  * Close all pipes except for the numbered thread.
609933707f3Ssthen  * @param daemon: daemon to close pipes in.
610933707f3Ssthen  * @param thr: thread number 0..num-1 of thread to skip.
611933707f3Ssthen  */
612933707f3Ssthen static void close_other_pipes(struct daemon* daemon, int thr)
613933707f3Ssthen {
614933707f3Ssthen 	int i;
615933707f3Ssthen 	for(i=0; i<daemon->num; i++)
616933707f3Ssthen 		if(i!=thr) {
617933707f3Ssthen 			if(i==0) {
618933707f3Ssthen 				/* only close read part, need to write stats */
619933707f3Ssthen 				tube_close_read(daemon->workers[i]->cmd);
620933707f3Ssthen 			} else {
621933707f3Ssthen 				/* complete close channel to others */
622933707f3Ssthen 				tube_delete(daemon->workers[i]->cmd);
623933707f3Ssthen 				daemon->workers[i]->cmd = NULL;
624933707f3Ssthen 			}
625933707f3Ssthen 		}
626933707f3Ssthen }
627933707f3Ssthen #endif /* THREADS_DISABLED */
628933707f3Ssthen 
629933707f3Ssthen /**
630933707f3Ssthen  * Function to start one thread.
631933707f3Ssthen  * @param arg: user argument.
632933707f3Ssthen  * @return: void* user return value could be used for thread_join results.
633933707f3Ssthen  */
634933707f3Ssthen static void*
635933707f3Ssthen thread_start(void* arg)
636933707f3Ssthen {
637933707f3Ssthen 	struct worker* worker = (struct worker*)arg;
6385d76a658Ssthen 	int port_num = 0;
639933707f3Ssthen 	log_thread_set(&worker->thread_num);
640933707f3Ssthen 	ub_thread_blocksigs();
641933707f3Ssthen #ifdef THREADS_DISABLED
642933707f3Ssthen 	/* close pipe ends used by main */
643933707f3Ssthen 	tube_close_write(worker->cmd);
644933707f3Ssthen 	close_other_pipes(worker->daemon, worker->thread_num);
645933707f3Ssthen #endif
64698f3ca02Sbrad #ifdef SO_REUSEPORT
6475d76a658Ssthen 	if(worker->daemon->cfg->so_reuseport)
648a961b961Ssthen 		port_num = worker->thread_num % worker->daemon->num_ports;
6495d76a658Ssthen 	else
6505d76a658Ssthen 		port_num = 0;
6515d76a658Ssthen #endif
6525d76a658Ssthen 	if(!worker_init(worker, worker->daemon->cfg,
6535d76a658Ssthen 			worker->daemon->ports[port_num], 0))
654933707f3Ssthen 		fatal_exit("Could not initialize thread");
655933707f3Ssthen 
656933707f3Ssthen 	worker_work(worker);
657933707f3Ssthen 	return NULL;
658933707f3Ssthen }
659933707f3Ssthen 
660933707f3Ssthen /**
661933707f3Ssthen  * Fork and init the other threads. Main thread returns for special handling.
662933707f3Ssthen  * @param daemon: the daemon with other threads to fork.
663933707f3Ssthen  */
664933707f3Ssthen static void
665933707f3Ssthen daemon_start_others(struct daemon* daemon)
666933707f3Ssthen {
667933707f3Ssthen 	int i;
668933707f3Ssthen 	log_assert(daemon);
669933707f3Ssthen 	verbose(VERB_ALGO, "start threads");
670933707f3Ssthen 	/* skip i=0, is this thread */
671933707f3Ssthen 	for(i=1; i<daemon->num; i++) {
672933707f3Ssthen 		ub_thread_create(&daemon->workers[i]->thr_id,
673933707f3Ssthen 			thread_start, daemon->workers[i]);
674933707f3Ssthen #ifdef THREADS_DISABLED
675933707f3Ssthen 		/* close pipe end of child */
676933707f3Ssthen 		tube_close_read(daemon->workers[i]->cmd);
677933707f3Ssthen #endif /* no threads */
678933707f3Ssthen 	}
679933707f3Ssthen }
680933707f3Ssthen 
681933707f3Ssthen /**
682933707f3Ssthen  * Stop the other threads.
683933707f3Ssthen  * @param daemon: the daemon with other threads.
684933707f3Ssthen  */
685933707f3Ssthen static void
686933707f3Ssthen daemon_stop_others(struct daemon* daemon)
687933707f3Ssthen {
688933707f3Ssthen 	int i;
689933707f3Ssthen 	log_assert(daemon);
690933707f3Ssthen 	verbose(VERB_ALGO, "stop threads");
691933707f3Ssthen 	/* skip i=0, is this thread */
692933707f3Ssthen 	/* use i=0 buffer for sending cmds; because we are #0 */
693933707f3Ssthen 	for(i=1; i<daemon->num; i++) {
694933707f3Ssthen 		worker_send_cmd(daemon->workers[i], worker_cmd_quit);
695933707f3Ssthen 	}
696933707f3Ssthen 	/* wait for them to quit */
697933707f3Ssthen 	for(i=1; i<daemon->num; i++) {
698933707f3Ssthen 		/* join it to make sure its dead */
699933707f3Ssthen 		verbose(VERB_ALGO, "join %d", i);
700933707f3Ssthen 		ub_thread_join(daemon->workers[i]->thr_id);
701933707f3Ssthen 		verbose(VERB_ALGO, "join success %d", i);
702933707f3Ssthen 	}
703933707f3Ssthen }
704933707f3Ssthen 
705933707f3Ssthen void
706933707f3Ssthen daemon_fork(struct daemon* daemon)
707933707f3Ssthen {
7082be9e038Ssthen 	int have_view_respip_cfg = 0;
7098240c1b9Ssthen #ifdef HAVE_SYSTEMD
7108240c1b9Ssthen 	int ret;
7118240c1b9Ssthen #endif
7122be9e038Ssthen 
713933707f3Ssthen 	log_assert(daemon);
71477079be7Ssthen 	if(!(daemon->views = views_create()))
71577079be7Ssthen 		fatal_exit("Could not create views: out of memory");
71677079be7Ssthen 	/* create individual views and their localzone/data trees */
71777079be7Ssthen 	if(!views_apply_cfg(daemon->views, daemon->cfg))
71877079be7Ssthen 		fatal_exit("Could not set up views");
71977079be7Ssthen 
72077079be7Ssthen 	if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
721933707f3Ssthen 		fatal_exit("Could not setup access control list");
72245872187Ssthen 	if(!acl_interface_apply_cfg(daemon->acl_interface, daemon->cfg,
72345872187Ssthen 		daemon->views))
72445872187Ssthen 		fatal_exit("Could not setup interface control list");
7252308e98cSsthen 	if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
7262308e98cSsthen 		fatal_exit("Could not setup TCP connection limits");
7272be9e038Ssthen 	if(daemon->cfg->dnscrypt) {
7282be9e038Ssthen #ifdef USE_DNSCRYPT
7292be9e038Ssthen 		daemon->dnscenv = dnsc_create();
7302be9e038Ssthen 		if (!daemon->dnscenv)
7312be9e038Ssthen 			fatal_exit("dnsc_create failed");
7322be9e038Ssthen 		dnsc_apply_cfg(daemon->dnscenv, daemon->cfg);
7332be9e038Ssthen #else
7342be9e038Ssthen 		fatal_exit("dnscrypt enabled in config but unbound was not built with "
7352be9e038Ssthen 				   "dnscrypt support");
7362be9e038Ssthen #endif
7372be9e038Ssthen 	}
738*98bc733bSsthen 	if(daemon->cfg->cookie_secret_file &&
739*98bc733bSsthen 		daemon->cfg->cookie_secret_file[0]) {
740*98bc733bSsthen 		if(!(daemon->cookie_secrets = cookie_secrets_create()))
741*98bc733bSsthen 			fatal_exit("Could not create cookie_secrets: out of memory");
742*98bc733bSsthen 		if(!cookie_secrets_apply_cfg(daemon->cookie_secrets,
743*98bc733bSsthen 			daemon->cfg->cookie_secret_file))
744*98bc733bSsthen 			fatal_exit("Could not setup cookie_secrets");
745*98bc733bSsthen 	}
74677079be7Ssthen 	/* create global local_zones */
747933707f3Ssthen 	if(!(daemon->local_zones = local_zones_create()))
748933707f3Ssthen 		fatal_exit("Could not create local zones: out of memory");
749933707f3Ssthen 	if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
750933707f3Ssthen 		fatal_exit("Could not set up local zones");
7512bdc0ed1Ssthen 	if(!(daemon->env->fwds = forwards_create()) ||
7522bdc0ed1Ssthen 		!forwards_apply_cfg(daemon->env->fwds, daemon->cfg))
7532bdc0ed1Ssthen 		fatal_exit("Could not set forward zones");
7542bdc0ed1Ssthen 	if(!(daemon->env->hints = hints_create()) ||
7552bdc0ed1Ssthen 		!hints_apply_cfg(daemon->env->hints, daemon->cfg))
7562bdc0ed1Ssthen 		fatal_exit("Could not set root or stub hints");
757933707f3Ssthen 
7582be9e038Ssthen 	/* process raw response-ip configuration data */
7592be9e038Ssthen 	if(!(daemon->respip_set = respip_set_create()))
7602be9e038Ssthen 		fatal_exit("Could not create response IP set");
7612be9e038Ssthen 	if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg))
7622be9e038Ssthen 		fatal_exit("Could not set up response IP set");
7632be9e038Ssthen 	if(!respip_views_apply_cfg(daemon->views, daemon->cfg,
7642be9e038Ssthen 		&have_view_respip_cfg))
7652be9e038Ssthen 		fatal_exit("Could not set up per-view response IP sets");
7662be9e038Ssthen 	daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
7672be9e038Ssthen 		have_view_respip_cfg;
7682be9e038Ssthen 
769191f22c6Ssthen 	/* setup modules */
770191f22c6Ssthen 	daemon_setup_modules(daemon);
771191f22c6Ssthen 
772938a3a5eSflorian 	/* read auth zonefiles */
773eaf2578eSsthen 	if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
774191f22c6Ssthen 		&daemon->use_rpz, daemon->env, &daemon->mods))
775938a3a5eSflorian 		fatal_exit("auth_zones could not be setup");
776938a3a5eSflorian 
777eba819a2Ssthen 	/* Set-up EDNS strings */
778eba819a2Ssthen 	if(!edns_strings_apply_cfg(daemon->env->edns_strings, daemon->cfg))
779eba819a2Ssthen 		fatal_exit("Could not set up EDNS strings");
7802c144df0Ssthen 
7812bdc0ed1Ssthen #ifdef USE_CACHEDB
7822bdc0ed1Ssthen 	daemon->env->cachedb_enabled = cachedb_is_enabled(&daemon->mods,
7832bdc0ed1Ssthen 		daemon->env);
7842bdc0ed1Ssthen #endif
7852be9e038Ssthen 	/* response-ip-xxx options don't work as expected without the respip
7862be9e038Ssthen 	 * module.  To avoid run-time operational surprise we reject such
7872be9e038Ssthen 	 * configuration. */
7882be9e038Ssthen 	if(daemon->use_response_ip &&
7892be9e038Ssthen 		modstack_find(&daemon->mods, "respip") < 0)
7902be9e038Ssthen 		fatal_exit("response-ip options require respip module");
791eaf2578eSsthen 	/* RPZ response ip triggers don't work as expected without the respip
792eaf2578eSsthen 	 * module.  To avoid run-time operational surprise we reject such
793eaf2578eSsthen 	 * configuration. */
794eaf2578eSsthen 	if(daemon->use_rpz &&
795eaf2578eSsthen 		modstack_find(&daemon->mods, "respip") < 0)
796eaf2578eSsthen 		fatal_exit("RPZ requires the respip module");
7972be9e038Ssthen 
798933707f3Ssthen 	/* first create all the worker structures, so we can pass
799933707f3Ssthen 	 * them to the newly created threads.
800933707f3Ssthen 	 */
801933707f3Ssthen 	daemon_create_workers(daemon);
802933707f3Ssthen 
803933707f3Ssthen #if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
804933707f3Ssthen 	/* in libev the first inited base gets signals */
8055d76a658Ssthen 	if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1))
806933707f3Ssthen 		fatal_exit("Could not initialize main thread");
807933707f3Ssthen #endif
808933707f3Ssthen 
809933707f3Ssthen 	/* Now create the threads and init the workers.
810933707f3Ssthen 	 * By the way, this is thread #0 (the main thread).
811933707f3Ssthen 	 */
812933707f3Ssthen 	daemon_start_others(daemon);
813933707f3Ssthen 
814933707f3Ssthen 	/* Special handling for the main thread. This is the thread
815933707f3Ssthen 	 * that handles signals and remote control.
816933707f3Ssthen 	 */
817933707f3Ssthen #if !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP))
818933707f3Ssthen 	/* libevent has the last inited base get signals (or any base) */
8195d76a658Ssthen 	if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1))
820933707f3Ssthen 		fatal_exit("Could not initialize main thread");
821933707f3Ssthen #endif
822933707f3Ssthen 	signal_handling_playback(daemon->workers[0]);
823933707f3Ssthen 
8242be9e038Ssthen 	if (!shm_main_init(daemon))
8252be9e038Ssthen 		log_warn("SHM has failed");
8262be9e038Ssthen 
827933707f3Ssthen 	/* Start resolver service on main thread. */
82877079be7Ssthen #ifdef HAVE_SYSTEMD
8298240c1b9Ssthen 	ret = sd_notify(0, "READY=1");
8308240c1b9Ssthen 	if(ret <= 0 && getenv("NOTIFY_SOCKET"))
8318240c1b9Ssthen 		fatal_exit("sd_notify failed %s: %s. Make sure that unbound has "
8328240c1b9Ssthen 				"access/permission to use the socket presented by systemd.",
8338240c1b9Ssthen 				getenv("NOTIFY_SOCKET"),
8348240c1b9Ssthen 				(ret==0?"no $NOTIFY_SOCKET": strerror(-ret)));
83577079be7Ssthen #endif
836933707f3Ssthen 	log_info("start of service (%s).", PACKAGE_STRING);
837933707f3Ssthen 	worker_work(daemon->workers[0]);
83877079be7Ssthen #ifdef HAVE_SYSTEMD
8392308e98cSsthen 	if (daemon->workers[0]->need_to_exit)
84077079be7Ssthen 		sd_notify(0, "STOPPING=1");
8412308e98cSsthen 	else
8422308e98cSsthen 		sd_notify(0, "RELOADING=1");
84377079be7Ssthen #endif
844933707f3Ssthen 	log_info("service stopped (%s).", PACKAGE_STRING);
845933707f3Ssthen 
846933707f3Ssthen 	/* we exited! a signal happened! Stop other threads */
847933707f3Ssthen 	daemon_stop_others(daemon);
848933707f3Ssthen 
8492be9e038Ssthen 	/* Shutdown SHM */
8502be9e038Ssthen 	shm_main_shutdown(daemon);
8512be9e038Ssthen 
8528b7325afSsthen 	daemon->reuse_cache = daemon->workers[0]->reuse_cache;
853933707f3Ssthen 	daemon->need_to_exit = daemon->workers[0]->need_to_exit;
854933707f3Ssthen }
855933707f3Ssthen 
856933707f3Ssthen void
857933707f3Ssthen daemon_cleanup(struct daemon* daemon)
858933707f3Ssthen {
859933707f3Ssthen 	int i;
860933707f3Ssthen 	log_assert(daemon);
861933707f3Ssthen 	/* before stopping main worker, handle signals ourselves, so we
862933707f3Ssthen 	   don't die on multiple reload signals for example. */
863933707f3Ssthen 	signal_handling_record();
864933707f3Ssthen 	log_thread_set(NULL);
865933707f3Ssthen 	/* clean up caches because
866933707f3Ssthen 	 * a) RRset IDs will be recycled after a reload, causing collisions
8678b7325afSsthen 	 * b) validation config can change, thus rrset, msg, keycache clear
8688b7325afSsthen 	 *
8698b7325afSsthen 	 * If we are trying to keep the cache as long as possible, we should
8708b7325afSsthen 	 * defer the cleanup until we know whether the new configuration allows
8718b7325afSsthen 	 * the reuse.  (If we're exiting, cleanup should be done here). */
8728b7325afSsthen 	if(!daemon->reuse_cache || daemon->need_to_exit) {
873933707f3Ssthen 		slabhash_clear(&daemon->env->rrset_cache->table);
874933707f3Ssthen 		slabhash_clear(daemon->env->msg_cache);
8758b7325afSsthen 	}
8768b7325afSsthen 	daemon->old_num = daemon->num; /* save the current num */
8772bdc0ed1Ssthen 	forwards_delete(daemon->env->fwds);
8782bdc0ed1Ssthen 	daemon->env->fwds = NULL;
8792bdc0ed1Ssthen 	hints_delete(daemon->env->hints);
8802bdc0ed1Ssthen 	daemon->env->hints = NULL;
881933707f3Ssthen 	local_zones_delete(daemon->local_zones);
882933707f3Ssthen 	daemon->local_zones = NULL;
8832be9e038Ssthen 	respip_set_delete(daemon->respip_set);
8842be9e038Ssthen 	daemon->respip_set = NULL;
88577079be7Ssthen 	views_delete(daemon->views);
88677079be7Ssthen 	daemon->views = NULL;
887938a3a5eSflorian 	if(daemon->env->auth_zones)
888938a3a5eSflorian 		auth_zones_cleanup(daemon->env->auth_zones);
889*98bc733bSsthen 	/* key cache is cleared by module deinit during next daemon_fork() */
890933707f3Ssthen 	daemon_remote_clear(daemon->rc);
891933707f3Ssthen 	for(i=0; i<daemon->num; i++)
892933707f3Ssthen 		worker_delete(daemon->workers[i]);
893933707f3Ssthen 	free(daemon->workers);
894933707f3Ssthen 	daemon->workers = NULL;
8958b7325afSsthen 	/* Unless we're trying to keep the cache, worker alloc_caches should be
8968b7325afSsthen 	 * cleared and freed here. We do this after deleting workers to
8978b7325afSsthen 	 * guarantee that the alloc caches are valid throughout the lifetime
8988b7325afSsthen 	 * of workers. */
8998b7325afSsthen 	if(!daemon->reuse_cache || daemon->need_to_exit)
9008b7325afSsthen 		daemon_clear_allocs(daemon);
901933707f3Ssthen 	daemon->num = 0;
90298f3ca02Sbrad #ifdef USE_DNSTAP
90398f3ca02Sbrad 	dt_delete(daemon->dtenv);
90420237c55Ssthen 	daemon->dtenv = NULL;
90598f3ca02Sbrad #endif
9067191de28Ssthen #ifdef USE_DNSCRYPT
9077191de28Ssthen 	dnsc_delete(daemon->dnscenv);
90820237c55Ssthen 	daemon->dnscenv = NULL;
9097191de28Ssthen #endif
910933707f3Ssthen 	daemon->cfg = NULL;
911933707f3Ssthen }
912933707f3Ssthen 
913933707f3Ssthen void
914933707f3Ssthen daemon_delete(struct daemon* daemon)
915933707f3Ssthen {
9165d76a658Ssthen 	size_t i;
917933707f3Ssthen 	if(!daemon)
918933707f3Ssthen 		return;
919*98bc733bSsthen 	modstack_call_deinit(&daemon->mods, daemon->env);
920*98bc733bSsthen 	modstack_call_destartup(&daemon->mods, daemon->env);
921*98bc733bSsthen 	modstack_free(&daemon->mods);
922933707f3Ssthen 	daemon_remote_delete(daemon->rc);
9235d76a658Ssthen 	for(i = 0; i < daemon->num_ports; i++)
9245d76a658Ssthen 		listening_ports_free(daemon->ports[i]);
9255d76a658Ssthen 	free(daemon->ports);
926933707f3Ssthen 	listening_ports_free(daemon->rc_ports);
927933707f3Ssthen 	if(daemon->env) {
928933707f3Ssthen 		slabhash_delete(daemon->env->msg_cache);
929933707f3Ssthen 		rrset_cache_delete(daemon->env->rrset_cache);
930933707f3Ssthen 		infra_delete(daemon->env->infra_cache);
93177079be7Ssthen 		edns_known_options_delete(daemon->env);
932eba819a2Ssthen 		edns_strings_delete(daemon->env->edns_strings);
933938a3a5eSflorian 		auth_zones_delete(daemon->env->auth_zones);
934933707f3Ssthen 	}
935933707f3Ssthen 	ub_randfree(daemon->rand);
936933707f3Ssthen 	alloc_clear(&daemon->superalloc);
937933707f3Ssthen 	acl_list_delete(daemon->acl);
93845872187Ssthen 	acl_list_delete(daemon->acl_interface);
9392308e98cSsthen 	tcl_list_delete(daemon->tcl);
940*98bc733bSsthen 	cookie_secrets_delete(daemon->cookie_secrets);
941e21c60efSsthen 	listen_desetup_locks();
942933707f3Ssthen 	free(daemon->chroot);
943933707f3Ssthen 	free(daemon->pidfile);
944933707f3Ssthen 	free(daemon->env);
9453dcb24b8Ssthen #ifdef HAVE_SSL
946f6b99bafSsthen 	listen_sslctx_delete_ticket_keys();
947933707f3Ssthen 	SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
948933707f3Ssthen 	SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
9493dcb24b8Ssthen #endif
950933707f3Ssthen 	free(daemon);
951933707f3Ssthen 	/* lex cleanup */
952933707f3Ssthen 	ub_c_lex_destroy();
953933707f3Ssthen 	/* libcrypto cleanup */
9543dcb24b8Ssthen #ifdef HAVE_SSL
955d1e2768aSsthen #  if defined(USE_GOST)
9565d76a658Ssthen 	sldns_key_EVP_unload_gost();
957933707f3Ssthen #  endif
958933707f3Ssthen #  if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
959933707f3Ssthen #    ifndef S_SPLINT_S
9602ee382b6Ssthen #      if OPENSSL_VERSION_NUMBER < 0x10100000
961933707f3Ssthen 	sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
962933707f3Ssthen #      endif
963933707f3Ssthen #    endif
9642ee382b6Ssthen #  endif
965933707f3Ssthen #  ifdef HAVE_OPENSSL_CONFIG
966933707f3Ssthen 	EVP_cleanup();
967a3167c07Ssthen #  if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
968933707f3Ssthen 	ENGINE_cleanup();
9692ee382b6Ssthen #  endif
970933707f3Ssthen 	CONF_modules_free();
971933707f3Ssthen #  endif
97277079be7Ssthen #  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
973933707f3Ssthen 	CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
97477079be7Ssthen #  endif
97577079be7Ssthen #  ifdef HAVE_ERR_FREE_STRINGS
976933707f3Ssthen 	ERR_free_strings();
97777079be7Ssthen #  endif
9782ee382b6Ssthen #  if OPENSSL_VERSION_NUMBER < 0x10100000
979933707f3Ssthen 	RAND_cleanup();
9802ee382b6Ssthen #  endif
981229e174cSsthen #  if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
982229e174cSsthen 	ub_openssl_lock_delete();
983229e174cSsthen #  endif
984938a3a5eSflorian #ifndef HAVE_ARC4RANDOM
985938a3a5eSflorian 	_ARC4_LOCK_DESTROY();
986938a3a5eSflorian #endif
9873dcb24b8Ssthen #elif defined(HAVE_NSS)
9883dcb24b8Ssthen 	NSS_Shutdown();
9893dcb24b8Ssthen #endif /* HAVE_SSL or HAVE_NSS */
990933707f3Ssthen 	checklock_stop();
991933707f3Ssthen #ifdef USE_WINSOCK
992933707f3Ssthen 	if(WSACleanup() != 0) {
993933707f3Ssthen 		log_err("Could not WSACleanup: %s",
994933707f3Ssthen 			wsa_strerror(WSAGetLastError()));
995933707f3Ssthen 	}
996933707f3Ssthen #endif
997933707f3Ssthen }
998933707f3Ssthen 
999933707f3Ssthen void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg)
1000933707f3Ssthen {
10018b7325afSsthen 	int new_num = cfg->num_threads?cfg->num_threads:1;
10028b7325afSsthen 
1003933707f3Ssthen         daemon->cfg = cfg;
1004933707f3Ssthen 	config_apply(cfg);
10058b7325afSsthen 
10068b7325afSsthen 	/* If this is a reload and we deferred the decision on whether to
10078b7325afSsthen 	 * reuse the alloc, RRset, and message caches, then check to see if
10088b7325afSsthen 	 * it's safe to keep the caches:
10098b7325afSsthen 	 * - changing the number of threads is obviously incompatible with
10108b7325afSsthen 	 *   keeping the per-thread alloc caches. It also means we have to
10118b7325afSsthen 	 *   clear RRset and message caches. (note that 'new_num' may be
10128b7325afSsthen 	 *   adjusted in daemon_create_workers, but for our purpose we can
10138b7325afSsthen 	 *   simply compare it with 'old_num'; if they are equal here,
10148b7325afSsthen 	 *   'new_num' won't be adjusted to a different value than 'old_num').
10158b7325afSsthen 	 * - changing RRset cache size effectively clears any remaining cache
10168b7325afSsthen 	 *   entries. We could keep their keys in alloc caches, but it would
10178b7325afSsthen 	 *   be more consistent with the sense of the change to clear allocs
10188b7325afSsthen 	 *   and free memory. To do so we also have to clear message cache.
10198b7325afSsthen 	 * - only changing message cache size does not necessarily affect
10208b7325afSsthen 	 *   RRset or alloc cache. But almost all new subsequent queries will
10218b7325afSsthen 	 *   require recursive resolution anyway, so it doesn't help much to
10228b7325afSsthen 	 *   just keep RRset and alloc caches. For simplicity we clear/free
10238b7325afSsthen 	 *   the other two, too. */
10248b7325afSsthen 	if(daemon->worker_allocs &&
10258b7325afSsthen 		(new_num != daemon->old_num ||
10268b7325afSsthen 		 !slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
10278b7325afSsthen 			cfg->msg_cache_slabs) ||
10288b7325afSsthen 		 !slabhash_is_size(&daemon->env->rrset_cache->table,
10298b7325afSsthen 			cfg->rrset_cache_size, cfg->rrset_cache_slabs)))
10308b7325afSsthen 	{
10318b7325afSsthen 		log_warn("cannot reuse caches due to critical config change");
10328b7325afSsthen 		slabhash_clear(&daemon->env->rrset_cache->table);
10338b7325afSsthen 		slabhash_clear(daemon->env->msg_cache);
10348b7325afSsthen 		daemon_clear_allocs(daemon);
10358b7325afSsthen 	}
10368b7325afSsthen 
10372308e98cSsthen 	if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
10382308e98cSsthen 	   	cfg->msg_cache_slabs)) {
1039933707f3Ssthen 		slabhash_delete(daemon->env->msg_cache);
1040933707f3Ssthen 		daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
1041933707f3Ssthen 			HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
1042933707f3Ssthen 			msgreply_sizefunc, query_info_compare,
1043933707f3Ssthen 			query_entry_delete, reply_info_delete, NULL);
1044933707f3Ssthen 		if(!daemon->env->msg_cache) {
1045933707f3Ssthen 			fatal_exit("malloc failure updating config settings");
1046933707f3Ssthen 		}
1047933707f3Ssthen 	}
1048933707f3Ssthen 	if((daemon->env->rrset_cache = rrset_cache_adjust(
1049933707f3Ssthen 		daemon->env->rrset_cache, cfg, &daemon->superalloc)) == 0)
1050933707f3Ssthen 		fatal_exit("malloc failure updating config settings");
1051933707f3Ssthen 	if((daemon->env->infra_cache = infra_adjust(daemon->env->infra_cache,
1052933707f3Ssthen 		cfg))==0)
1053933707f3Ssthen 		fatal_exit("malloc failure updating config settings");
1054933707f3Ssthen }
1055