Ejemplo n.º 1
0
struct listen_port* daemon_remote_open_ports(struct config_file* cfg)
{
	struct listen_port* l = NULL;
	log_assert(cfg->remote_control_enable && cfg->control_port);
	if(cfg->control_ifs) {
		struct config_strlist* p;
		for(p = cfg->control_ifs; p; p = p->next) {
			if(!add_open(p->str, cfg->control_port, &l, 1)) {
				listening_ports_free(l);
				return NULL;
			}
		}
	} else {
		/* defaults */
		if(cfg->do_ip6 &&
			!add_open("::1", cfg->control_port, &l, 0)) {
			listening_ports_free(l);
			return NULL;
		}
		if(cfg->do_ip4 &&
			!add_open("127.0.0.1", cfg->control_port, &l, 1)) {
			listening_ports_free(l);
			return NULL;
		}
	}
	return l;
}
Ejemplo n.º 2
0
void 
daemon_delete(struct daemon* daemon)
{
	size_t i;
	if(!daemon)
		return;
	modstack_desetup(&daemon->mods, daemon->env);
	daemon_remote_delete(daemon->rc);
	for(i = 0; i < daemon->num_ports; i++)
		listening_ports_free(daemon->ports[i]);
	free(daemon->ports);
	listening_ports_free(daemon->rc_ports);
	if(daemon->env) {
		slabhash_delete(daemon->env->msg_cache);
		rrset_cache_delete(daemon->env->rrset_cache);
		infra_delete(daemon->env->infra_cache);
		edns_known_options_delete(daemon->env);
		auth_zones_delete(daemon->env->auth_zones);
	}
	ub_randfree(daemon->rand);
	alloc_clear(&daemon->superalloc);
	acl_list_delete(daemon->acl);
	free(daemon->chroot);
	free(daemon->pidfile);
	free(daemon->env);
#ifdef HAVE_SSL
	SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
	SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
#endif
	free(daemon);
#ifdef LEX_HAS_YYLEX_DESTROY
	/* lex cleanup */
	ub_c_lex_destroy();
#endif
	/* libcrypto cleanup */
#ifdef HAVE_SSL
#  if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
	sldns_key_EVP_unload_gost();
#  endif
#  if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
#    ifndef S_SPLINT_S
#      if OPENSSL_VERSION_NUMBER < 0x10100000
	sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
#      endif
#    endif
#  endif
#  ifdef HAVE_OPENSSL_CONFIG
	EVP_cleanup();
#  if OPENSSL_VERSION_NUMBER < 0x10100000
	ENGINE_cleanup();
#  endif
	CONF_modules_free();
#  endif
#  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
	CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
#  endif
#  ifdef HAVE_ERR_FREE_STRINGS
	ERR_free_strings();
#  endif
#  if OPENSSL_VERSION_NUMBER < 0x10100000
	RAND_cleanup();
#  endif
#  if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
	ub_openssl_lock_delete();
#  endif
#ifndef HAVE_ARC4RANDOM
	_ARC4_LOCK_DESTROY();
#endif
#elif defined(HAVE_NSS)
	NSS_Shutdown();
#endif /* HAVE_SSL or HAVE_NSS */
	checklock_stop();
#ifdef USE_WINSOCK
	if(WSACleanup() != 0) {
		log_err("Could not WSACleanup: %s", 
			wsa_strerror(WSAGetLastError()));
	}
#endif
}
Ejemplo n.º 3
0
struct listen_port* 
listening_ports_open(struct config_file* cfg)
{
	struct listen_port* list = NULL;
	struct addrinfo hints;
	int i, do_ip4, do_ip6;
	int do_tcp, do_auto;
	char portbuf[32];
	snprintf(portbuf, sizeof(portbuf), "%d", cfg->port);
	do_ip4 = cfg->do_ip4;
	do_ip6 = cfg->do_ip6;
	do_tcp = cfg->do_tcp;
	do_auto = cfg->if_automatic && cfg->do_udp;
	if(cfg->incoming_num_tcp == 0)
		do_tcp = 0;

	/* getaddrinfo */
	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_PASSIVE;
	/* no name lookups on our listening ports */
	if(cfg->num_ifs > 0)
		hints.ai_flags |= AI_NUMERICHOST;
	hints.ai_family = AF_UNSPEC;
#ifndef INET6
	do_ip6 = 0;
#endif
	if(!do_ip4 && !do_ip6) {
		return NULL;
	}
	/* create ip4 and ip6 ports so that return addresses are nice. */
	if(do_auto || cfg->num_ifs == 0) {
		if(do_ip6) {
			hints.ai_family = AF_INET6;
			if(!ports_create_if(do_auto?"::0":"::1", 
				do_auto, cfg->do_udp, do_tcp, 
				&hints, portbuf, &list,
				cfg->so_rcvbuf, cfg->so_sndbuf,
				cfg->ssl_port)) {
				listening_ports_free(list);
				return NULL;
			}
		}
		if(do_ip4) {
			hints.ai_family = AF_INET;
			if(!ports_create_if(do_auto?"0.0.0.0":"127.0.0.1", 
				do_auto, cfg->do_udp, do_tcp, 
				&hints, portbuf, &list,
				cfg->so_rcvbuf, cfg->so_sndbuf,
				cfg->ssl_port)) {
				listening_ports_free(list);
				return NULL;
			}
		}
	} else for(i = 0; i<cfg->num_ifs; i++) {
		if(str_is_ip6(cfg->ifs[i])) {
			if(!do_ip6)
				continue;
			hints.ai_family = AF_INET6;
			if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp, 
				do_tcp, &hints, portbuf, &list, 
				cfg->so_rcvbuf, cfg->so_sndbuf,
				cfg->ssl_port)) {
				listening_ports_free(list);
				return NULL;
			}
		} else {
			if(!do_ip4)
				continue;
			hints.ai_family = AF_INET;
			if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp, 
				do_tcp, &hints, portbuf, &list, 
				cfg->so_rcvbuf, cfg->so_sndbuf,
				cfg->ssl_port)) {
				listening_ports_free(list);
				return NULL;
			}
		}
	}
	return list;
}
Ejemplo n.º 4
0
int 
daemon_open_shared_ports(struct daemon* daemon)
{
	log_assert(daemon);
	if(daemon->cfg->port != daemon->listening_port) {
		size_t i;
		struct listen_port* p0;
		daemon->reuseport = 0;
		/* free and close old ports */
		if(daemon->ports != NULL) {
			for(i=0; i<daemon->num_ports; i++)
				listening_ports_free(daemon->ports[i]);
			free(daemon->ports);
			daemon->ports = NULL;
		}
		/* see if we want to reuseport */
#ifdef SO_REUSEPORT
		if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0)
			daemon->reuseport = 1;
#endif
		/* try to use reuseport */
		p0 = listening_ports_open(daemon->cfg, &daemon->reuseport);
		if(!p0) {
			listening_ports_free(p0);
			return 0;
		}
		if(daemon->reuseport) {
			/* reuseport was successful, allocate for it */
			daemon->num_ports = (size_t)daemon->cfg->num_threads;
		} else {
			/* do the normal, singleportslist thing,
			 * reuseport not enabled or did not work */
			daemon->num_ports = 1;
		}
		if(!(daemon->ports = (struct listen_port**)calloc(
			daemon->num_ports, sizeof(*daemon->ports)))) {
			listening_ports_free(p0);
			return 0;
		}
		daemon->ports[0] = p0;
		if(daemon->reuseport) {
			/* continue to use reuseport */
			for(i=1; i<daemon->num_ports; i++) {
				if(!(daemon->ports[i]=
					listening_ports_open(daemon->cfg,
						&daemon->reuseport))
					|| !daemon->reuseport ) {
					for(i=0; i<daemon->num_ports; i++)
						listening_ports_free(daemon->ports[i]);
					free(daemon->ports);
					daemon->ports = NULL;
					return 0;
				}
			}
		}
		daemon->listening_port = daemon->cfg->port;
	}
	if(!daemon->cfg->remote_control_enable && daemon->rc_port) {
		listening_ports_free(daemon->rc_ports);
		daemon->rc_ports = NULL;
		daemon->rc_port = 0;
	}
	if(daemon->cfg->remote_control_enable && 
		daemon->cfg->control_port != daemon->rc_port) {
		listening_ports_free(daemon->rc_ports);
		if(!(daemon->rc_ports=daemon_remote_open_ports(daemon->cfg)))
			return 0;
		daemon->rc_port = daemon->cfg->control_port;
	}
	return 1;
}