interface names.
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
$(CACHEDB_SRC) respip/respip.c $(CHECKLOCK_SRC) \
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC) daemon/acl_list.c
+$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
-outside_network.lo acl_list.lo
+outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
# set to $COMMON_OBJ or to "" if --enableallsymbols
COMMON_OBJ_ALL_SYMBOLS=@COMMON_OBJ_ALL_SYMBOLS@
unittcpreuse.lo
UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \
$(COMPAT_OBJ)
-DAEMON_SRC=daemon/cachedump.c daemon/daemon.c \
+DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \
daemon/remote.c daemon/stats.c daemon/unbound.c daemon/worker.c @WIN_DAEMON_SRC@
-DAEMON_OBJ=cachedump.lo daemon.lo \
+DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo \
shm_main.lo remote.lo stats.lo unbound.lo \
worker.lo @WIN_DAEMON_OBJ@
DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
/** find or create node (NULL on parse or error) */
static struct acl_addr*
-acl_find_or_create(struct acl_list* acl, const char* str, int is_interface,
- int port)
+acl_find_or_create_str2addr(struct acl_list* acl, const char* str,
+ int is_interface, int port)
{
struct acl_addr* node;
struct sockaddr_storage addr;
return node;
}
+/** find or create node (NULL on error) */
+static struct acl_addr*
+acl_find_or_create(struct acl_list* acl, struct sockaddr_storage* addr,
+ socklen_t addrlen, enum acl_access control)
+{
+ struct acl_addr* node;
+ int net = (addr_is_ip6(addr, addrlen)?128:32);
+ /* find or create node */
+ if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, addr,
+ addrlen, net))) {
+ /* create node;
+ * can override with specific access-control: cfg */
+ if(!(node=(struct acl_addr*)acl_list_insert(acl, addr,
+ addrlen, net, control, 1))) {
+ log_err("out of memory");
+ return NULL;
+ }
+ }
+ return node;
+}
+
/** apply acl_interface string */
static int
acl_interface_str_cfg(struct acl_list* acl_interface, const char* interface,
if(!parse_acl_access(s2, &control)) {
return 0;
}
- if(!(node=acl_find_or_create(acl_interface, interface, 1, port))) {
+ if(!(node=acl_find_or_create_str2addr(acl_interface, interface, 1, port))) {
log_err("cannot update ACL on non-configured interface: %s %d",
interface, port);
return 0;
}
struct acl_addr*
-acl_interface_insert(struct acl_list* acl_interface, const char* interface,
- const char* s2, int port)
+acl_interface_insert(struct acl_list* acl_interface,
+ struct sockaddr_storage* addr, socklen_t addrlen,
+ enum acl_access control)
{
- struct acl_addr* node;
- struct sockaddr_storage addr;
- socklen_t addrlen;
- enum acl_access control;
- int net = (str_is_ip6(interface)?128:32);
- if(!parse_acl_access(s2, &control)) {
- return NULL;
- }
- if((node=acl_find_or_create(acl_interface, interface, 1, port))) {
- return node;
- }
- if(!extstrtoaddr(interface, &addr, &addrlen, port)) {
- log_err("cannot parse access control: %s %s", interface, s2);
- return NULL;
- }
- return acl_list_insert(acl_interface, &addr, addrlen, net, control, 1);
+ return acl_find_or_create(acl_interface, addr, addrlen, control);
}
/** apply acl_tag string */
size_t bitmaplen, int is_interface, int port)
{
struct acl_addr* node;
- if(!(node=acl_find_or_create(acl, str, is_interface, port))) {
+ if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
return 0;
struct views* vs, int is_interface, int port)
{
struct acl_addr* node;
- if(!(node=acl_find_or_create(acl, str, is_interface, port))) {
+ if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
return 0;
struct acl_addr* node;
int tagid;
enum localzone_type t;
- if(!(node=acl_find_or_create(acl, str, is_interface, port))) {
+ if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
return 0;
struct acl_addr* node;
int tagid;
char* dupdata;
- if(!(node=acl_find_or_create(acl, str, is_interface, port))) {
+ if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
return 0;
acl_interface_init(struct acl_list* acl_interface)
{
regional_free_all(acl_interface->region);
- /* We want comparison in the tree to include both IP and port.
- * Initialise with the given compare fucntion but keep treating it as
- * an addr_tree. */
- rbtree_init(&acl_interface->tree, &acl_interface_compare);
+ /* We want comparison in the tree to include only address and port.
+ * We don't care about comparing node->net. All addresses in the
+ * acl_interface->tree should have either 32 (ipv4) or 128 (ipv6).
+ * Initialise with the appropriate compare fucntion but keep treating
+ * it as an addr_tree. */
+ addr_tree_addrport_init(&acl_interface->tree);
}
static int
return 0;
}
for(i = 0; i<num_resif; i++) {
- if(!acl_list_view_cfg(acl_interface, p->str, p->str2,
+ if(!acl_list_view_cfg(acl_interface, resif[i], p->str2,
v, 1, port)) {
config_del_strarray(resif, num_resif);
config_deldblstrlist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
- if(!acl_list_tags_cfg(acl_interface, p->str, p->str2,
+ if(!acl_list_tags_cfg(acl_interface, resif[i], p->str2,
p->str2len, 1, port)) {
config_del_strbytelist(p);
config_del_strarray(resif, num_resif);
return 0;
}
for(i = 0; i<num_resif; i++) {
- if(!acl_list_tag_action_cfg(acl_interface, cfg, p->str,
- p->str2, p->str3, 1, port)) {
+ if(!acl_list_tag_action_cfg(acl_interface, cfg,
+ resif[i], p->str2, p->str3, 1, port)) {
config_deltrplstrlist(p);
config_del_strarray(resif, num_resif);
return 0;
return 0;
}
for(i = 0; i<num_resif; i++) {
- if(!acl_list_tag_data_cfg(acl_interface, cfg, p->str,
- p->str2, p->str3, 1, port)) {
+ if(!acl_list_tag_data_cfg(acl_interface, cfg,
+ resif[i], p->str2, p->str3, 1, port)) {
config_deltrplstrlist(p);
config_del_strarray(resif, num_resif);
return 0;
* Insert interface in the alc_list. This should happen when the listening
* interface is setup.
* @param acl_interface: acl_list to insert to.
- * @param interface: interface (IP) in string format.
- * @param s2: acl_access in string format.
- * @param port: default port.
+ * @param addr: interface IP.
+ * @param addrlen: length of the interface IP.
+ * @param control: acl_access.
* @return new structure or NULL on error.
*/
struct acl_addr*
-acl_interface_insert(struct acl_list* acl_interface, const char* interface,
- const char* s2, int port);
+acl_interface_insert(struct acl_list* acl_interface,
+ struct sockaddr_storage* addr, socklen_t addrlen,
+ enum acl_access control);
/**
* Process access control config.
#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;
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)
{
daemon->reuseport = 1;
#endif
/* try to use reuseport */
- p0 = listening_ports_open(daemon->cfg, daemon->acl_interface,
- 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);
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++) {
if(!(daemon->ports[i]=
listening_ports_open(daemon->cfg,
- daemon->acl_interface,
resif, num_resif,
&daemon->reuseport))
|| !daemon->reuseport ) {
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);
* @param hints: for getaddrinfo. family and flags have to be set by caller.
* @param port: Port number to use (as string).
* @param list: list of open ports, appended to, changed to point to list head.
- * @param acl_interface: acl list with options for the interface.
* @param rcv: receive buffer size for UDP
* @param snd: send buffer size for UDP
* @param ssl_port: ssl service port number
static int
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
struct addrinfo *hints, const char* port, struct listen_port** list,
- struct acl_list* acl_interface, size_t rcv, size_t snd, int ssl_port,
+ size_t rcv, size_t snd, int ssl_port,
struct config_strlist* tls_additional_port, int https_port,
int* reuseport, int transparent, int tcp_mss, int freebind,
int http2_nodelay, int use_systemd, int dnscrypt_port, int dscp)
int is_https = if_is_https(ifname, port, https_port);
int nodelay = is_https && http2_nodelay;
struct unbound_socket* ub_sock;
- struct acl_addr* acl_node;
#ifdef USE_DNSCRYPT
int is_dnscrypt = ((strchr(ifname, '@') &&
atoi(strchr(ifname, '@')+1) == dnscrypt_port) ||
if(do_auto) {
ub_sock = calloc(1, sizeof(struct unbound_socket));
- acl_node = NULL;
if(!ub_sock)
return 0;
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
free(ub_sock);
return 0;
}
- if(!(acl_node = acl_interface_insert(acl_interface, ifname,
- "refuse", ntohs(((struct sockaddr_in*)ub_sock->addr->ai_addr)->sin_port)))) {
- sock_close(s);
- freeaddrinfo(ub_sock->addr);
- free(ub_sock);
- return 0;
- }
- ub_sock->acl = acl_node;
} else if(do_udp) {
ub_sock = calloc(1, sizeof(struct unbound_socket));
- acl_node = NULL;
if(!ub_sock)
return 0;
/* regular udp socket */
free(ub_sock);
return 0;
}
- if(!(acl_node = acl_interface_insert(acl_interface, ifname,
- "refuse", ntohs(((struct sockaddr_in*)ub_sock->addr->ai_addr)->sin_port)))) {
- sock_close(s);
- freeaddrinfo(ub_sock->addr);
- free(ub_sock);
- return 0;
- }
- ub_sock->acl = acl_node;
}
if(do_tcp) {
int is_ssl = if_is_ssl(ifname, port, ssl_port,
tls_additional_port);
enum listen_type port_type;
ub_sock = calloc(1, sizeof(struct unbound_socket));
- acl_node = NULL;
if(!ub_sock)
return 0;
if(is_ssl)
free(ub_sock);
return 0;
}
- if(!(acl_node = acl_interface_insert(acl_interface, ifname,
- "refuse", ntohs(((struct sockaddr_in*)ub_sock->addr->ai_addr)->sin_port)))) {
- sock_close(s);
- freeaddrinfo(ub_sock->addr);
- free(ub_sock);
- return 0;
- }
- ub_sock->acl = acl_node;
}
return 1;
}
}
struct listen_port*
-listening_ports_open(struct config_file* cfg, struct acl_list* acl_interface,
- char** ifs, int num_ifs, int* reuseport)
+listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
+ int* reuseport)
{
struct listen_port* list = NULL;
struct addrinfo hints;
hints.ai_family = AF_INET6;
if(!ports_create_if(do_auto?"::0":"::1",
do_auto, cfg->do_udp, do_tcp,
- &hints, portbuf, &list, acl_interface,
+ &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, reuseport, cfg->ip_transparent,
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, acl_interface,
+ &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, reuseport, cfg->ip_transparent,
continue;
hints.ai_family = AF_INET6;
if(!ports_create_if(ifs[i], 0, cfg->do_udp,
- do_tcp, &hints, portbuf, &list, acl_interface,
+ do_tcp, &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, reuseport, cfg->ip_transparent,
continue;
hints.ai_family = AF_INET;
if(!ports_create_if(ifs[i], 0, cfg->do_udp,
- do_tcp, &hints, portbuf, &list, acl_interface,
+ do_tcp, &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, reuseport, cfg->ip_transparent,
* interfaces for IP4 and/or IP6, for UDP and/or TCP.
* On the given port number. It creates the sockets.
* @param cfg: settings on what ports to open.
- * @param acl_interface: acl list for interface options.
* @param ifs: interfaces to open, array of IP addresses, "ip[@port]".
* @param num_ifs: length of ifs.
* @param reuseport: set to true if you want reuseport, or NULL to not have it,
* @return: linked list of ports or NULL on error.
*/
struct listen_port* listening_ports_open(struct config_file* cfg,
- struct acl_list* acl_interface,
char** ifs, int num_ifs, int* reuseport);
/**
}
struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg),
- struct acl_list* ATTR_UNUSED(acl_interface),
char** ATTR_UNUSED(ifs), int ATTR_UNUSED(num_ifs),
int* ATTR_UNUSED(reuseport))
{
- return calloc(1, 1);
+ return calloc(1, sizeof(struct listen_port));
}
void listening_ports_free(struct listen_port* list)
chroot: ""
username: ""
do-not-query-localhost: no
- use-caps-for-id: yes
+ use-caps-for-id: no
+ define-tag: "one two refuse"
# Interface configuration for IPv4
interface: @IPV4_ADDR@@@PORT_ALLOW@
interface: @IPV4_ADDR@@@PORT_DENY@
interface: @IPV4_ADDR@@@PORT_REFUSE@
+ interface: @IPV4_ADDR@@@PORT_TAG_1@
+ interface: @IPV4_ADDR@@@PORT_TAG_2@
+ interface: @IPV4_ADDR@@@PORT_TAG_3@
interface: @IPV4_ADDR@@@PORT_VIEW_INT@
interface: @IPV4_ADDR@@@PORT_VIEW_EXT@
interface: @IPV4_ADDR@@@PORT_VIEW_INTEXT@
interface-action: @IPV4_ADDR@@@PORT_ALLOW@ allow
interface-action: @IPV4_ADDR@@@PORT_DENY@ deny
+ # interface-action: @IPV4_ADDR@@@PORT_REFUSE@ refuse # This is the default action
+ interface-action: @IPV4_ADDR@@@PORT_TAG_1@ allow
+ interface-action: @IPV4_ADDR@@@PORT_TAG_2@ allow
+ interface-action: @IPV4_ADDR@@@PORT_TAG_3@ allow
interface-action: @IPV4_ADDR@@@PORT_VIEW_INT@ allow
interface-action: @IPV4_ADDR@@@PORT_VIEW_EXT@ allow
interface-action: @IPV4_ADDR@@@PORT_VIEW_INTEXT@ allow
+ interface-tag: @IPV4_ADDR@@@PORT_TAG_1@ "one"
+ interface-tag: @IPV4_ADDR@@@PORT_TAG_2@ "two"
+ interface-tag: @IPV4_ADDR@@@PORT_TAG_3@ "refuse"
+ interface-tag-action: @IPV4_ADDR@@@PORT_TAG_1@ one redirect
+ interface-tag-data: @IPV4_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
+ interface-tag-action: @IPV4_ADDR@@@PORT_TAG_2@ two redirect
+ interface-tag-data: @IPV4_ADDR@@@PORT_TAG_2@ two "A 2.2.2.2"
+ interface-tag-action: @IPV4_ADDR@@@PORT_TAG_3@ refuse always_refuse
+
interface-view: @IPV4_ADDR@@@PORT_VIEW_INT@ "int"
interface-view: @IPV4_ADDR@@@PORT_VIEW_EXT@ "ext"
interface-view: @IPV4_ADDR@@@PORT_VIEW_INTEXT@ "intext"
interface: @IPV6_ADDR@@@PORT_ALLOW@
interface: @IPV6_ADDR@@@PORT_DENY@
interface: @IPV6_ADDR@@@PORT_REFUSE@
+ interface: @IPV6_ADDR@@@PORT_TAG_1@
+ interface: @IPV6_ADDR@@@PORT_TAG_2@
+ interface: @IPV6_ADDR@@@PORT_TAG_3@
interface: @IPV6_ADDR@@@PORT_VIEW_INT@
interface: @IPV6_ADDR@@@PORT_VIEW_EXT@
interface: @IPV6_ADDR@@@PORT_VIEW_INTEXT@
interface-action: @IPV6_ADDR@@@PORT_ALLOW@ allow
interface-action: @IPV6_ADDR@@@PORT_DENY@ deny
+ # interface-action: @IPV6_ADDR@@@PORT_REFUSE@ refuse # This is the default action
+ interface-action: @IPV6_ADDR@@@PORT_TAG_1@ allow
+ interface-action: @IPV6_ADDR@@@PORT_TAG_2@ allow
+ interface-action: @IPV6_ADDR@@@PORT_TAG_3@ allow
interface-action: @IPV6_ADDR@@@PORT_VIEW_INT@ allow
interface-action: @IPV6_ADDR@@@PORT_VIEW_EXT@ allow
interface-action: @IPV6_ADDR@@@PORT_VIEW_INTEXT@ allow
+ interface-tag: @IPV6_ADDR@@@PORT_TAG_1@ "one"
+ interface-tag: @IPV6_ADDR@@@PORT_TAG_2@ "two"
+ interface-tag: @IPV6_ADDR@@@PORT_TAG_3@ "refuse"
+ interface-tag-action: @IPV6_ADDR@@@PORT_TAG_1@ one redirect
+ interface-tag-data: @IPV6_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
+ interface-tag-action: @IPV6_ADDR@@@PORT_TAG_2@ two redirect
+ interface-tag-data: @IPV6_ADDR@@@PORT_TAG_2@ two "A 2.2.2.2"
+ interface-tag-action: @IPV6_ADDR@@@PORT_TAG_3@ refuse always_refuse
+
interface-view: @IPV6_ADDR@@@PORT_VIEW_INT@ "int"
interface-view: @IPV6_ADDR@@@PORT_VIEW_EXT@ "ext"
interface-view: @IPV6_ADDR@@@PORT_VIEW_INTEXT@ "intext"
+# Mirrored interface configuration for interface name
+ interface: @INTERFACE@@@PORT_ALLOW@
+ interface: @INTERFACE@@@PORT_DENY@
+ interface: @INTERFACE@@@PORT_REFUSE@
+ interface: @INTERFACE@@@PORT_TAG_1@
+ interface: @INTERFACE@@@PORT_TAG_2@
+ interface: @INTERFACE@@@PORT_TAG_3@
+ interface: @INTERFACE@@@PORT_VIEW_INT@
+ interface: @INTERFACE@@@PORT_VIEW_EXT@
+ interface: @INTERFACE@@@PORT_VIEW_INTEXT@
+
+ interface-action: @INTERFACE@@@PORT_ALLOW@ allow
+ interface-action: @INTERFACE@@@PORT_DENY@ deny
+ # interface-action: @INTERFACE@@@PORT_REFUSE@ refuse # This is the default action
+ interface-action: @INTERFACE@@@PORT_TAG_1@ allow
+ interface-action: @INTERFACE@@@PORT_TAG_2@ allow
+ interface-action: @INTERFACE@@@PORT_TAG_3@ allow
+ interface-action: @INTERFACE@@@PORT_VIEW_INT@ allow
+ interface-action: @INTERFACE@@@PORT_VIEW_EXT@ allow
+ interface-action: @INTERFACE@@@PORT_VIEW_INTEXT@ allow
+
+ interface-tag: @INTERFACE@@@PORT_TAG_1@ "one"
+ interface-tag: @INTERFACE@@@PORT_TAG_2@ "two"
+ interface-tag: @INTERFACE@@@PORT_TAG_3@ "refuse"
+ interface-tag-action: @INTERFACE@@@PORT_TAG_1@ one redirect
+ interface-tag-data: @INTERFACE@@@PORT_TAG_1@ one "A 1.1.1.1"
+ interface-tag-action: @INTERFACE@@@PORT_TAG_2@ two redirect
+ interface-tag-data: @INTERFACE@@@PORT_TAG_2@ two "A 2.2.2.2"
+ interface-tag-action: @INTERFACE@@@PORT_TAG_3@ refuse always_refuse
+
+ interface-view: @INTERFACE@@@PORT_VIEW_INT@ "int"
+ interface-view: @INTERFACE@@@PORT_VIEW_EXT@ "ext"
+ interface-view: @INTERFACE@@@PORT_VIEW_INTEXT@ "intext"
+
+# Local zones configuration
+ local-zone: local. transparent
+ local-data: "local. A 0.0.0.0"
+ local-zone-tag: local. "one two refuse"
+
# Views configuration
view:
name: "int"
skip_test "no unshare (from util-linux package) available, skip test"
fi
-get_random_port 8
+get_random_port 11
PORT_ALLOW=$RND_PORT
PORT_DENY=$(($RND_PORT + 1))
PORT_REFUSE=$(($RND_PORT + 2))
-PORT_VIEW_INT=$(($RND_PORT + 3))
-PORT_VIEW_EXT=$(($RND_PORT + 4))
-PORT_VIEW_INTEXT=$(($RND_PORT + 5))
-FORWARD_PORT=$(($RND_PORT + 6))
-STUB_PORT=$(($RND_PORT + 7))
+PORT_TAG_1=$(($RND_PORT + 3))
+PORT_TAG_2=$(($RND_PORT + 4))
+PORT_TAG_3=$(($RND_PORT + 5))
+PORT_VIEW_INT=$(($RND_PORT + 6))
+PORT_VIEW_EXT=$(($RND_PORT + 7))
+PORT_VIEW_INTEXT=$(($RND_PORT + 8))
+FORWARD_PORT=$(($RND_PORT + 9))
+STUB_PORT=$(($RND_PORT + 10))
IPV4_ADDR=192.168.1.1
IPV6_ADDR=2001:db8::1
+INTERFACE=eth24
+INTERFACE_ADDR_1=10.0.0.1
+INTERFACE_ADDR_2=10.0.0.2
+INTERFACE_ADDR_3=10.0.0.3
+INTERFACE_ADDR_4=10.0.0.4
+
# make config file
sed \
-e 's/@PORT_ALLOW\@/'$PORT_ALLOW'/' \
-e 's/@PORT_DENY\@/'$PORT_DENY'/' \
-e 's/@PORT_REFUSE\@/'$PORT_REFUSE'/' \
+ -e 's/@PORT_TAG_1\@/'$PORT_TAG_1'/' \
+ -e 's/@PORT_TAG_2\@/'$PORT_TAG_2'/' \
+ -e 's/@PORT_TAG_3\@/'$PORT_TAG_3'/' \
-e 's/@PORT_VIEW_INT\@/'$PORT_VIEW_INT'/' \
-e 's/@PORT_VIEW_EXT\@/'$PORT_VIEW_EXT'/' \
-e 's/@PORT_VIEW_INTEXT\@/'$PORT_VIEW_INTEXT'/' \
-e 's/@STUB_PORT\@/'$STUB_PORT'/' \
-e 's/@IPV4_ADDR\@/'$IPV4_ADDR'/' \
-e 's/@IPV6_ADDR\@/'$IPV6_ADDR'/' \
+ -e 's/@INTERFACE\@/'$INTERFACE'/' \
< acl_interface.conf > ub.conf
if test -x "`which bash`"; then
echo "PORT_ALLOW=$PORT_ALLOW" >> .tpkg.var.test
echo "PORT_DENY=$PORT_DENY" >> .tpkg.var.test
echo "PORT_REFUSE=$PORT_REFUSE" >> .tpkg.var.test
+echo "PORT_TAG_1=$PORT_TAG_1" >> .tpkg.var.test
+echo "PORT_TAG_2=$PORT_TAG_2" >> .tpkg.var.test
+echo "PORT_TAG_3=$PORT_TAG_3" >> .tpkg.var.test
echo "PORT_VIEW_INT=$PORT_VIEW_INT" >> .tpkg.var.test
echo "PORT_VIEW_EXT=$PORT_VIEW_EXT" >> .tpkg.var.test
echo "PORT_VIEW_INTEXT=$PORT_VIEW_INTEXT" >> .tpkg.var.test
echo "STUB_PORT=$STUB_PORT" >> .tpkg.var.test
echo "IPV4_ADDR=$IPV4_ADDR" >> .tpkg.var.test
echo "IPV6_ADDR=$IPV6_ADDR" >> .tpkg.var.test
+echo "INTERFACE=$INTERFACE" >> .tpkg.var.test
+echo "INTERFACE_ADDR_1=$INTERFACE_ADDR_1" >> .tpkg.var.test
+echo "INTERFACE_ADDR_2=$INTERFACE_ADDR_2" >> .tpkg.var.test
+echo "INTERFACE_ADDR_3=$INTERFACE_ADDR_3" >> .tpkg.var.test
+echo "INTERFACE_ADDR_4=$INTERFACE_ADDR_4" >> .tpkg.var.test
echo "shell=$shell" >> .tpkg.var.test
ip addr add $IPV6_ADDR dev lo
ip link set lo up
+ip link add $INTERFACE type dummy
+ip addr add $INTERFACE_ADDR_1 dev $INTERFACE
+ip addr add $INTERFACE_ADDR_2 dev $INTERFACE
+ip addr add $INTERFACE_ADDR_3 dev $INTERFACE
+ip addr add $INTERFACE_ADDR_4 dev $INTERFACE
+ip link set $INTERFACE up
+
# start the forwarder in the background
get_ldns_testns
$LDNS_TESTNS -p $FORWARD_PORT acl_interface.testns >fwd.log 2>&1 &
wait_ldns_testns_up fwd2.log
wait_unbound_up unbound.log
+end () {
+ echo "> cat logfiles"
+ cat fwd.log
+ cat fwd2.log
+ cat unbound.log
+ exit $1
+}
+
# Query for the given domain to the given port
# $1: address family [4, 6]
# $2: port
dig @"$addr" -p $2 $3 | tee outfile
}
+# Query for the given domain to the given port
+# $1: address
+# $2: port
+# $3: dname
+query_addr () {
+ echo "> dig @$1 -p $2 $3"
+ dig @"$1" -p $2 $3 | tee outfile
+}
+
expect_refused () {
echo "> check answer for REFUSED"
if grep "REFUSED" outfile; then
echo "OK"
else
echo "Not OK"
- exit 1
+ end 1
fi
}
echo "OK"
else
echo "Not OK"
- exit 1
+ end 1
fi
}
echo "OK"
else
echo "Not OK"
- exit 1
+ end 1
+ fi
+}
+
+expect_tag_one_answer () {
+ echo "> check tag 'one' answer"
+ if grep "1.1.1.1" outfile; then
+ echo "OK"
+ else
+ echo "Not OK"
+ end 1
fi
}
+expect_tag_two_answer () {
+ echo "> check tag 'two' answer"
+ if grep "2.2.2.2" outfile; then
+ echo "OK"
+ else
+ echo "Not OK"
+ end 1
+ fi
+}
# do the test
query $i $PORT_ALLOW "www.internal"
expect_internal_answer
+ query $i $PORT_TAG_1 "local"
+ expect_tag_one_answer
+
+ query $i $PORT_TAG_2 "local"
+ expect_tag_two_answer
+
+ query $i $PORT_TAG_3 "local"
+ expect_refused
+
query $i $PORT_VIEW_INT "www.internal"
expect_internal_answer
expect_external_answer
done
-echo "> cat logfiles"
-cat fwd.log
-cat fwd2.log
-cat unbound.log
-exit 0
+for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADDR_4; do
+ query_addr $addr $PORT_REFUSE "www.external"
+ expect_refused
+
+ query_addr $addr $PORT_REFUSE "www.internal"
+ expect_refused
+
+ query_addr $addr $PORT_ALLOW "www.external"
+ expect_external_answer
+
+ query_addr $addr $PORT_ALLOW "www.internal"
+ expect_internal_answer
+
+ query_addr $addr $PORT_TAG_1 "local"
+ expect_tag_one_answer
+
+ query_addr $addr $PORT_TAG_2 "local"
+ expect_tag_two_answer
+
+ query_addr $addr $PORT_TAG_3 "local"
+ expect_refused
+
+ query_addr $addr $PORT_VIEW_INT "www.internal"
+ expect_internal_answer
+
+ query_addr $addr $PORT_VIEW_INT "www.external"
+ expect_refused
+
+ query_addr $addr $PORT_VIEW_EXT "www.internal"
+ expect_refused
+
+ query_addr $addr $PORT_VIEW_EXT "www.external"
+ expect_external_answer
+
+ query_addr $addr $PORT_VIEW_INTEXT "www.internal"
+ expect_internal_answer
+
+ query_addr $addr $PORT_VIEW_INTEXT "www.external"
+ expect_external_answer
+done
+
+end 0
SECTION ANSWER
www IN A 1.2.3.4
ENTRY_END
+
+$ORIGIN local.
+$TTL 3600
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+@ IN A
+SECTION ANSWER
+@ IN A 127.0.0.1
+ENTRY_END
* boundaries in the program.
*/
#include "config.h"
-#include "daemon/acl_list.h"
#include "util/fptr_wlist.h"
#include "util/mini_event.h"
#include "services/outside_network.h"
if(fptr == &mesh_state_compare) return 1;
else if(fptr == &mesh_state_ref_compare) return 1;
else if(fptr == &addr_tree_compare) return 1;
+ else if(fptr == &addr_tree_addrport_compare) return 1;
else if(fptr == &local_zone_cmp) return 1;
else if(fptr == &local_data_cmp) return 1;
else if(fptr == &fwd_cmp) return 1;
else if(fptr == &auth_zone_cmp) return 1;
else if(fptr == &auth_data_cmp) return 1;
else if(fptr == &auth_xfer_cmp) return 1;
- else if(fptr == &acl_interface_compare) return 1;
return 0;
}
return 0;
}
+int addr_tree_addrport_compare(const void* k1, const void* k2)
+{
+ struct addr_tree_node* n1 = (struct addr_tree_node*)k1;
+ struct addr_tree_node* n2 = (struct addr_tree_node*)k2;
+ return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr,
+ n2->addrlen);
+}
+
void name_tree_init(rbtree_type* tree)
{
rbtree_init(tree, &name_tree_compare);
rbtree_init(tree, &addr_tree_compare);
}
+void addr_tree_addrport_init(rbtree_type* tree)
+{
+ rbtree_init(tree, &addr_tree_addrport_compare);
+}
+
int name_tree_insert(rbtree_type* tree, struct name_tree_node* node,
uint8_t* name, size_t len, int labs, uint16_t dclass)
{
*/
void addr_tree_init(rbtree_type* tree);
+/**
+ * Init addr tree to be empty.
+ * The comparison function to be used is addr_tree_addrport_compare.
+ * @param tree: to init.
+ */
+void addr_tree_addrport_init(rbtree_type* tree);
+
/**
* insert element into addr tree.
* @param tree: addr tree
/** compare addr tree nodes */
int addr_tree_compare(const void* k1, const void* k2);
+/** compare addr tree nodes (address and port only) */
+int addr_tree_addrport_compare(const void* k1, const void* k2);
+
#endif /* UTIL_STORAGE_DNSTREE_H */