mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-23 16:20:26 -05:00
daemon code.
git-svn-id: file:///svn/unbound/trunk@136 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
618ef6acbb
commit
d5de0d10d5
12 changed files with 382 additions and 34 deletions
|
|
@ -57,7 +57,7 @@ UNITTEST_SRC=testcode/unitmain.c $(COMMON_SRC)
|
||||||
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ)
|
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
DAEMON_SRC=$(wildcard daemon/*.c) $(COMMON_SRC)
|
DAEMON_SRC=$(wildcard daemon/*.c) $(COMMON_SRC)
|
||||||
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ)
|
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c daemon/worker.c testcode/replay.c testcode/fake_event.c $(filter-out util/netevent.c services/listen_dnsport.c services/outside_network.c, $(COMMON_SRC))
|
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c daemon/worker.c daemon/daemon.c testcode/replay.c testcode/fake_event.c $(filter-out util/netevent.c services/listen_dnsport.c services/outside_network.c, $(COMMON_SRC))
|
||||||
TESTBOUND_OBJ=$(addprefix $(BUILD),$(TESTBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
|
TESTBOUND_OBJ=$(addprefix $(BUILD),$(TESTBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) $(TESTBOUND_SRC)
|
ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) $(TESTBOUND_SRC)
|
||||||
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) $(addprefix compat/,$(LIBOBJS))) $(COMPAT_OBJ)
|
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) $(addprefix compat/,$(LIBOBJS))) $(COMPAT_OBJ)
|
||||||
|
|
|
||||||
117
daemon/daemon.c
Normal file
117
daemon/daemon.c
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* daemon/daemon.c - collection of workers that handles requests.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* The daemon consists of global settings and a number of workers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** buffer size for network connections */
|
||||||
|
#define BUFSZ 65552
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "daemon/daemon.h"
|
||||||
|
#include "daemon/worker.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/config_file.h"
|
||||||
|
#include "services/listen_dnsport.h"
|
||||||
|
|
||||||
|
struct daemon*
|
||||||
|
daemon_init()
|
||||||
|
{
|
||||||
|
struct daemon* daemon = (struct daemon*)calloc(1,
|
||||||
|
sizeof(struct daemon));
|
||||||
|
if(!daemon)
|
||||||
|
return NULL;
|
||||||
|
lock_basic_init(&daemon->lock);
|
||||||
|
daemon->need_to_exit = 0;
|
||||||
|
return daemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
daemon_open_shared_ports(struct daemon* daemon, struct config_file* cfg)
|
||||||
|
{
|
||||||
|
log_assert(daemon);
|
||||||
|
daemon->cfg = cfg;
|
||||||
|
if(daemon->cfg->port == daemon->listening_port)
|
||||||
|
return 1;
|
||||||
|
listening_ports_free(daemon->ports);
|
||||||
|
if(!(daemon->ports=listening_ports_open(daemon->cfg)))
|
||||||
|
return 0;
|
||||||
|
daemon->listening_port = daemon->cfg->port;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
daemon_fork(struct daemon* daemon)
|
||||||
|
{
|
||||||
|
/* only one thread for now */
|
||||||
|
log_assert(daemon);
|
||||||
|
daemon->num = 1;
|
||||||
|
daemon->workers = (struct worker**)calloc((size_t)daemon->num,
|
||||||
|
sizeof(struct worker*));
|
||||||
|
if(!(daemon->workers[0] = worker_init(daemon->cfg, BUFSZ)))
|
||||||
|
fatal_exit("could not initialize thread # %d", 0);
|
||||||
|
daemon->workers[0]->daemon = daemon;
|
||||||
|
daemon->workers[0]->thread_num = 0;
|
||||||
|
|
||||||
|
log_info("start of service (%s).", PACKAGE_STRING);
|
||||||
|
worker_work(daemon->workers[0]);
|
||||||
|
daemon->need_to_exit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
daemon_cleanup(struct daemon* daemon)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
log_assert(daemon);
|
||||||
|
for(i=0; i<daemon->num; i++)
|
||||||
|
worker_delete(daemon->workers[i]);
|
||||||
|
free(daemon->workers);
|
||||||
|
daemon->workers = NULL;
|
||||||
|
daemon->num = 0;
|
||||||
|
daemon->cfg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
daemon_delete(struct daemon* daemon)
|
||||||
|
{
|
||||||
|
if(!daemon)
|
||||||
|
return;
|
||||||
|
listening_ports_free(daemon->ports);
|
||||||
|
lock_basic_destroy(&daemon->lock);
|
||||||
|
free(daemon);
|
||||||
|
}
|
||||||
104
daemon/daemon.h
Normal file
104
daemon/daemon.h
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* daemon/daemon.h - collection of workers that handles requests.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* The daemon consists of global settings and a number of workers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DAEMON_H
|
||||||
|
#define DAEMON_H
|
||||||
|
|
||||||
|
#include "util/locks.h"
|
||||||
|
struct config_file;
|
||||||
|
struct worker;
|
||||||
|
struct listen_port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure holding worker list.
|
||||||
|
* Holds globally visible information.
|
||||||
|
*/
|
||||||
|
struct daemon {
|
||||||
|
/** mutex for exclusive access to this structure. */
|
||||||
|
lock_basic_t lock;
|
||||||
|
/** The config settings */
|
||||||
|
struct config_file* cfg;
|
||||||
|
/** port number that has ports opened. */
|
||||||
|
int listening_port;
|
||||||
|
/** listening ports, opened, to be shared by threads */
|
||||||
|
struct listen_port* ports;
|
||||||
|
/** num threads allocated */
|
||||||
|
int num;
|
||||||
|
/** the worker entries */
|
||||||
|
struct worker** workers;
|
||||||
|
/** do we need to exit unbound (or is it only a reload?) */
|
||||||
|
int need_to_exit;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize daemon structure.
|
||||||
|
* @return: The daemon structure, or NULL on error.
|
||||||
|
*/
|
||||||
|
struct daemon* daemon_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open shared listening ports (if needed).
|
||||||
|
* @param daemon: the daemon.
|
||||||
|
* @param cfg: the cfg settings. Applied to daemon.
|
||||||
|
* @return: false on error.
|
||||||
|
*/
|
||||||
|
int daemon_open_shared_ports(struct daemon* daemon, struct config_file* cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fork workers and start service.
|
||||||
|
* When the routine exits, it is no longer forked.
|
||||||
|
* @param daemon: the daemon.
|
||||||
|
*/
|
||||||
|
void daemon_fork(struct daemon* daemon);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close off the worker thread information.
|
||||||
|
* Bring the daemon back into state ready for daemon_fork again.
|
||||||
|
* @param daemon: the daemon.
|
||||||
|
*/
|
||||||
|
void daemon_cleanup(struct daemon* daemon);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete worker.
|
||||||
|
*/
|
||||||
|
void daemon_delete(struct daemon* daemon);
|
||||||
|
|
||||||
|
#endif /* DAEMON_H */
|
||||||
106
daemon/unbound.c
106
daemon/unbound.c
|
|
@ -42,11 +42,10 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "daemon/worker.h"
|
#include "daemon/daemon.h"
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
|
#include <fcntl.h>
|
||||||
/** buffer size for network connections */
|
#include <pwd.h>
|
||||||
#define BUFSZ 65552
|
|
||||||
|
|
||||||
/** print usage. */
|
/** print usage. */
|
||||||
static void usage()
|
static void usage()
|
||||||
|
|
@ -61,6 +60,51 @@ static void usage()
|
||||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** daemonize, drop user priviliges and chroot if needed */
|
||||||
|
static void
|
||||||
|
do_chroot(struct config_file* cfg)
|
||||||
|
{
|
||||||
|
log_assert(cfg);
|
||||||
|
|
||||||
|
/* daemonize last to be able to print error to user */
|
||||||
|
if(cfg->chrootdir && cfg->chrootdir[0])
|
||||||
|
if(chroot(cfg->chrootdir))
|
||||||
|
fatal_exit("unable to chroot: %s", strerror(errno));
|
||||||
|
if(cfg->username && cfg->username[0]) {
|
||||||
|
struct passwd *pwd;
|
||||||
|
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||||
|
fatal_exit("user '%s' does not exist.", cfg->username);
|
||||||
|
if(setgid(pwd->pw_gid) != 0)
|
||||||
|
fatal_exit("unable to set group id: %s", strerror(errno));
|
||||||
|
if(setuid(pwd->pw_uid) != 0)
|
||||||
|
fatal_exit("unable to set user id: %s", strerror(errno));
|
||||||
|
endpwent();
|
||||||
|
}
|
||||||
|
if(cfg->do_daemonize) {
|
||||||
|
int fd;
|
||||||
|
/* Take off... */
|
||||||
|
switch (fork()) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
fatal_exit("fork failed: %s", strerror(errno));
|
||||||
|
default:
|
||||||
|
/* exit interactive session */
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
/* detach */
|
||||||
|
if(setsid() == -1)
|
||||||
|
fatal_exit("setsid() failed: %s", strerror(errno));
|
||||||
|
if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
|
||||||
|
(void)dup2(fd, STDIN_FILENO);
|
||||||
|
(void)dup2(fd, STDOUT_FILENO);
|
||||||
|
(void)dup2(fd, STDERR_FILENO);
|
||||||
|
if (fd > 2)
|
||||||
|
(void)close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the daemon.
|
* Run the daemon.
|
||||||
* @param cfgfile: the config file name.
|
* @param cfgfile: the config file name.
|
||||||
|
|
@ -69,35 +113,41 @@ static void usage()
|
||||||
*/
|
*/
|
||||||
static void run_daemon(const char* cfgfile, int cmdline_verbose)
|
static void run_daemon(const char* cfgfile, int cmdline_verbose)
|
||||||
{
|
{
|
||||||
struct worker* worker = NULL;
|
struct config_file* cfg = NULL;
|
||||||
struct config_file *cfg = NULL;
|
struct daemon* daemon = NULL;
|
||||||
|
int done_chroot = 0;
|
||||||
|
|
||||||
if(!(cfg = config_create())) {
|
if(!(daemon = daemon_init()))
|
||||||
fprintf(stderr, "Could not init config defaults.");
|
fatal_exit("alloc failure");
|
||||||
exit(1);
|
while(!daemon->need_to_exit) {
|
||||||
}
|
if(done_chroot)
|
||||||
if(cfgfile) {
|
log_info("Restart of %s.", PACKAGE_STRING);
|
||||||
if(!config_read(cfg, cfgfile)) {
|
else log_info("Start of %s.", PACKAGE_STRING);
|
||||||
config_delete(cfg);
|
|
||||||
exit(1);
|
/* config stuff */
|
||||||
}
|
if(!(cfg = config_create()))
|
||||||
|
fatal_exit("Could not alloc config defaults");
|
||||||
|
if(!config_read(cfg, cfgfile))
|
||||||
|
fatal_exit("Could not read config file: %s", cfgfile);
|
||||||
verbosity = cmdline_verbose + cfg->verbosity;
|
verbosity = cmdline_verbose + cfg->verbosity;
|
||||||
}
|
|
||||||
log_info("Start of %s.", PACKAGE_STRING);
|
|
||||||
|
|
||||||
/* setup */
|
|
||||||
worker = worker_init(cfg, BUFSZ);
|
|
||||||
if(!worker) {
|
|
||||||
fatal_exit("could not initialize");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* drop user priviliges and chroot if needed */
|
/* prepare */
|
||||||
log_info("start of service (%s).", PACKAGE_STRING);
|
if(!daemon_open_shared_ports(daemon, cfg))
|
||||||
worker_work(worker);
|
fatal_exit("could not open ports");
|
||||||
|
if(!done_chroot) {
|
||||||
|
do_chroot(cfg);
|
||||||
|
done_chroot = 1;
|
||||||
|
}
|
||||||
|
/* work */
|
||||||
|
daemon_fork(daemon);
|
||||||
|
|
||||||
/* cleanup */
|
/* clean up for restart */
|
||||||
|
verbose(VERB_ALGO, "cleanup.");
|
||||||
|
daemon_cleanup(daemon);
|
||||||
|
config_delete(cfg);
|
||||||
|
}
|
||||||
verbose(VERB_ALGO, "Exit cleanup.");
|
verbose(VERB_ALGO, "Exit cleanup.");
|
||||||
worker_delete(worker);
|
daemon_delete(daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** getopt global, in case header files fail to declare it. */
|
/** getopt global, in case header files fail to declare it. */
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,7 @@ worker_delete(struct worker* worker)
|
||||||
outside_network_delete(worker->back);
|
outside_network_delete(worker->back);
|
||||||
comm_signal_delete(worker->comsig);
|
comm_signal_delete(worker->comsig);
|
||||||
comm_base_delete(worker->base);
|
comm_base_delete(worker->base);
|
||||||
|
free(worker->rndstate);
|
||||||
free(worker);
|
free(worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,11 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util/netevent.h"
|
#include "util/netevent.h"
|
||||||
|
#include "util/locks.h"
|
||||||
struct listen_dnsport;
|
struct listen_dnsport;
|
||||||
struct outside_network;
|
struct outside_network;
|
||||||
struct config_file;
|
struct config_file;
|
||||||
|
struct daemon;
|
||||||
|
|
||||||
/** size of table used for random numbers. large to be more secure. */
|
/** size of table used for random numbers. large to be more secure. */
|
||||||
#define RND_STATE_SIZE 256
|
#define RND_STATE_SIZE 256
|
||||||
|
|
@ -57,6 +59,10 @@ struct config_file;
|
||||||
* Holds globally visible information.
|
* Holds globally visible information.
|
||||||
*/
|
*/
|
||||||
struct worker {
|
struct worker {
|
||||||
|
/** global shared daemon structure */
|
||||||
|
struct daemon* daemon;
|
||||||
|
/** the thread number (in daemon array). */
|
||||||
|
int thread_num;
|
||||||
/** the event base this worker works with */
|
/** the event base this worker works with */
|
||||||
struct comm_base* base;
|
struct comm_base* base;
|
||||||
/** the frontside listening interface where request events come in */
|
/** the frontside listening interface where request events come in */
|
||||||
|
|
|
||||||
|
|
@ -391,3 +391,14 @@ listen_delete(struct listen_dnsport* front)
|
||||||
ldns_buffer_free(front->udp_buff);
|
ldns_buffer_free(front->udp_buff);
|
||||||
free(front);
|
free(front);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct listen_port*
|
||||||
|
listening_ports_open(struct config_file* cfg)
|
||||||
|
{
|
||||||
|
return calloc(1,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void listening_ports_free(struct listen_port* list)
|
||||||
|
{
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
#include "util/netevent.h"
|
#include "util/netevent.h"
|
||||||
struct listen_list;
|
struct listen_list;
|
||||||
struct addrinfo;
|
struct addrinfo;
|
||||||
|
struct config_file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listening for queries structure.
|
* Listening for queries structure.
|
||||||
|
|
@ -73,6 +74,31 @@ struct listen_list {
|
||||||
struct comm_point* com;
|
struct comm_point* com;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single linked list to store shared ports that have been
|
||||||
|
* opened for use by all threads.
|
||||||
|
*/
|
||||||
|
struct listen_port {
|
||||||
|
/** next in list */
|
||||||
|
struct listen_port* next;
|
||||||
|
/** file descriptor, open and ready for use */
|
||||||
|
int fd;
|
||||||
|
/** type of file descriptor, udp or tcp */
|
||||||
|
int is_udp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create shared listening ports
|
||||||
|
* @param cfg: settings on what ports to open.
|
||||||
|
* @return: linked list of ports or NULL on error.
|
||||||
|
*/
|
||||||
|
struct listen_port* listening_ports_open(struct config_file* cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close and delete the (list of) listening ports.
|
||||||
|
*/
|
||||||
|
void listening_ports_free(struct listen_port* list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getaddrinfo, create socket, bind and listen to zero or more
|
* Getaddrinfo, create socket, bind and listen to zero or more
|
||||||
* interfaces for IP4 and/or IP6, for UDP and/or TCP.
|
* interfaces for IP4 and/or IP6, for UDP and/or TCP.
|
||||||
|
|
|
||||||
|
|
@ -690,4 +690,15 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||||
runtime->pending_list = pend;
|
runtime->pending_list = pend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg))
|
||||||
|
{
|
||||||
|
return calloc(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void listening_ports_free(struct listen_port* list)
|
||||||
|
{
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********** End of Dummy routines ***********/
|
/*********** End of Dummy routines ***********/
|
||||||
|
|
|
||||||
|
|
@ -77,12 +77,20 @@ config_create()
|
||||||
cfg->do_tcp = 1;
|
cfg->do_tcp = 1;
|
||||||
cfg->outgoing_base_port = cfg->port + 1000;
|
cfg->outgoing_base_port = cfg->port + 1000;
|
||||||
cfg->outgoing_num_ports = 16;
|
cfg->outgoing_num_ports = 16;
|
||||||
cfg->fwd_address = strdup("");
|
if(!(cfg->fwd_address = strdup(""))) {
|
||||||
if(!cfg->fwd_address) {
|
config_delete(cfg);
|
||||||
free(cfg);
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!(cfg->username = strdup(""))) {
|
||||||
|
config_delete(cfg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!(cfg->chrootdir = strdup(""))) {
|
||||||
|
config_delete(cfg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
cfg->fwd_port = UNBOUND_DNS_PORT;
|
cfg->fwd_port = UNBOUND_DNS_PORT;
|
||||||
|
cfg->do_daemonize = 0;
|
||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,7 +109,10 @@ create_cfg_parser(struct config_file* cfg, char* filename)
|
||||||
int
|
int
|
||||||
config_read(struct config_file* cfg, const char* filename)
|
config_read(struct config_file* cfg, const char* filename)
|
||||||
{
|
{
|
||||||
FILE *in = fopen(filename, "r");
|
FILE *in;
|
||||||
|
if(!filename)
|
||||||
|
return 1;
|
||||||
|
in = fopen(filename, "r");
|
||||||
if(!in) {
|
if(!in) {
|
||||||
log_err("Could not open %s: %s", filename, strerror(errno));
|
log_err("Could not open %s: %s", filename, strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -124,6 +135,8 @@ config_delete(struct config_file* cfg)
|
||||||
{
|
{
|
||||||
if(!cfg) return;
|
if(!cfg) return;
|
||||||
free(cfg->fwd_address);
|
free(cfg->fwd_address);
|
||||||
|
free(cfg->username);
|
||||||
|
free(cfg->chrootdir);
|
||||||
free(cfg);
|
free(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,14 @@ struct config_file {
|
||||||
char* fwd_address;
|
char* fwd_address;
|
||||||
/** forwarder port */
|
/** forwarder port */
|
||||||
int fwd_port;
|
int fwd_port;
|
||||||
|
|
||||||
|
/** chrootdir, if not "" or chroot will be done */
|
||||||
|
char* chrootdir;
|
||||||
|
/** username to change to, if not "". */
|
||||||
|
char* username;
|
||||||
|
|
||||||
|
/** daemonize, i.e. fork into the background. */
|
||||||
|
int do_daemonize;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -84,7 +92,7 @@ struct config_file* config_create();
|
||||||
/**
|
/**
|
||||||
* Read the config file from the specified filename.
|
* Read the config file from the specified filename.
|
||||||
* @param config: where options are stored into, must be freshly created.
|
* @param config: where options are stored into, must be freshly created.
|
||||||
* @param filename: name of configfile.
|
* @param filename: name of configfile. If NULL nothing is done.
|
||||||
* @return: false on error.
|
* @return: false on error.
|
||||||
*/
|
*/
|
||||||
int config_read(struct config_file* config, const char* filename);
|
int config_read(struct config_file* config, const char* filename);
|
||||||
|
|
|
||||||
|
|
@ -676,6 +676,7 @@ comm_point_delete(struct comm_point* c)
|
||||||
comm_point_delete(c->tcp_handlers[i]);
|
comm_point_delete(c->tcp_handlers[i]);
|
||||||
free(c->tcp_handlers);
|
free(c->tcp_handlers);
|
||||||
}
|
}
|
||||||
|
free(c->timeout);
|
||||||
if(c->type == comm_tcp)
|
if(c->type == comm_tcp)
|
||||||
ldns_buffer_free(c->buffer);
|
ldns_buffer_free(c->buffer);
|
||||||
free(c->ev);
|
free(c->ev);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue