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