aboutsummaryrefslogtreecommitdiff
path: root/daemon/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/daemon.c')
-rw-r--r--daemon/daemon.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/daemon/daemon.c b/daemon/daemon.c
index 4ed531855ee6..71091133a487 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -96,6 +96,9 @@
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
/** How many quit requests happened. */
static int sig_record_quit = 0;
@@ -271,8 +274,17 @@ daemon_init(void)
free(daemon);
return NULL;
}
+ daemon->acl_interface = acl_list_create();
+ if(!daemon->acl_interface) {
+ acl_list_delete(daemon->acl);
+ edns_known_options_delete(daemon->env);
+ free(daemon->env);
+ free(daemon);
+ return NULL;
+ }
daemon->tcl = tcl_list_create();
if(!daemon->tcl) {
+ acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
edns_known_options_delete(daemon->env);
free(daemon->env);
@@ -284,6 +296,7 @@ daemon_init(void)
log_err("gettimeofday: %s", strerror(errno));
daemon->time_last_stat = daemon->time_boot;
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
+ acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
@@ -293,6 +306,7 @@ daemon_init(void)
}
if(!(daemon->env->edns_strings = edns_strings_create())) {
auth_zones_delete(daemon->env->auth_zones);
+ acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
@@ -303,6 +317,29 @@ daemon_init(void)
return daemon;
}
+static int setup_acl_for_ports(struct acl_list* list,
+ struct listen_port* port_list)
+{
+ struct acl_addr* acl_node;
+ struct addrinfo* addr;
+ for(; port_list; port_list=port_list->next) {
+ if(!port_list->socket) {
+ /* This is mainly for testbound where port_list is
+ * empty. */
+ continue;
+ }
+ addr = port_list->socket->addr;
+ if(!(acl_node = acl_interface_insert(list,
+ (struct sockaddr_storage*)addr->ai_addr,
+ (socklen_t)addr->ai_addrlen,
+ acl_refuse))) {
+ return 0;
+ }
+ port_list->socket->acl = acl_node;
+ }
+ return 1;
+}
+
int
daemon_open_shared_ports(struct daemon* daemon)
{
@@ -320,6 +357,8 @@ daemon_open_shared_ports(struct daemon* daemon)
free(daemon->ports);
daemon->ports = NULL;
}
+ /* clean acl_interface */
+ acl_interface_init(daemon->acl_interface);
if(!resolve_interface_names(daemon->cfg->ifs,
daemon->cfg->num_ifs, NULL, &resif, &num_resif))
return 0;
@@ -329,7 +368,8 @@ daemon_open_shared_ports(struct daemon* daemon)
daemon->reuseport = 1;
#endif
/* try to use reuseport */
- p0 = listening_ports_open(daemon->cfg, resif, num_resif, &daemon->reuseport);
+ p0 = listening_ports_open(daemon->cfg, resif, num_resif,
+ &daemon->reuseport);
if(!p0) {
listening_ports_free(p0);
config_del_strarray(resif, num_resif);
@@ -350,6 +390,12 @@ daemon_open_shared_ports(struct daemon* daemon)
return 0;
}
daemon->ports[0] = p0;
+ if(!setup_acl_for_ports(daemon->acl_interface,
+ daemon->ports[0])) {
+ listening_ports_free(p0);
+ config_del_strarray(resif, num_resif);
+ return 0;
+ }
if(daemon->reuseport) {
/* continue to use reuseport */
for(i=1; i<daemon->num_ports; i++) {
@@ -365,6 +411,15 @@ daemon_open_shared_ports(struct daemon* daemon)
config_del_strarray(resif, num_resif);
return 0;
}
+ if(!setup_acl_for_ports(daemon->acl_interface,
+ daemon->ports[i])) {
+ for(i=0; i<daemon->num_ports; i++)
+ listening_ports_free(daemon->ports[i]);
+ free(daemon->ports);
+ daemon->ports = NULL;
+ config_del_strarray(resif, num_resif);
+ return 0;
+ }
}
}
config_del_strarray(resif, num_resif);
@@ -604,6 +659,9 @@ daemon_fork(struct daemon* daemon)
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
fatal_exit("Could not setup access control list");
+ if(!acl_interface_apply_cfg(daemon->acl_interface, daemon->cfg,
+ daemon->views))
+ fatal_exit("Could not setup interface control list");
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
fatal_exit("Could not setup TCP connection limits");
if(daemon->cfg->dnscrypt) {
@@ -780,6 +838,7 @@ daemon_delete(struct daemon* daemon)
ub_randfree(daemon->rand);
alloc_clear(&daemon->superalloc);
acl_list_delete(daemon->acl);
+ acl_list_delete(daemon->acl_interface);
tcl_list_delete(daemon->tcl);
listen_desetup_locks();
free(daemon->chroot);