mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Added views functionality.
git-svn-id: file:///svn/unbound/trunk@3876 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
145bdd7466
commit
b587c7f72d
25 changed files with 3575 additions and 2478 deletions
21
Makefile.in
21
Makefile.in
|
|
@ -101,7 +101,7 @@ util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \
|
||||||
iterator/iter_delegpt.c iterator/iter_donotq.c iterator/iter_fwd.c \
|
iterator/iter_delegpt.c iterator/iter_donotq.c iterator/iter_fwd.c \
|
||||||
iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \
|
iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \
|
||||||
iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
|
iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
|
||||||
services/localzone.c services/mesh.c services/modstack.c \
|
services/localzone.c services/mesh.c services/modstack.c services/view.c \
|
||||||
services/outbound_list.c services/outside_network.c util/alloc.c \
|
services/outbound_list.c services/outside_network.c util/alloc.c \
|
||||||
util/config_file.c util/configlexer.c util/configparser.c \
|
util/config_file.c util/configlexer.c util/configparser.c \
|
||||||
util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
|
util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
|
||||||
|
|
@ -117,7 +117,7 @@ $(DNSTAP_SRC)
|
||||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
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 \
|
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 \
|
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
|
||||||
iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo \
|
iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo view.lo \
|
||||||
outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
|
outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
|
||||||
fptr_wlist.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
|
fptr_wlist.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
|
||||||
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
|
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
|
||||||
|
|
@ -710,6 +710,9 @@ localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/serv
|
||||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h \
|
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h \
|
||||||
$(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
$(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||||
$(srcdir)/util/as112.h
|
$(srcdir)/util/as112.h
|
||||||
|
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/localzone.h \
|
||||||
|
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||||
|
$(srcdir)/util/config_file.h
|
||||||
mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||||
$(srcdir)/util/netevent.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
|
$(srcdir)/util/netevent.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
|
||||||
$(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
|
$(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
|
||||||
|
|
@ -759,7 +762,7 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
|
||||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
|
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
|
||||||
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
|
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
|
||||||
$(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
|
$(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h $(srcdir)/services/view.h\
|
||||||
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/infra.h \
|
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/infra.h \
|
||||||
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
|
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
|
||||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
|
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
|
||||||
|
|
@ -958,7 +961,7 @@ unitldns.lo unitldns.o: $(srcdir)/testcode/unitldns.c config.h $(srcdir)/util/lo
|
||||||
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
||||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
|
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
|
||||||
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/locks.h \
|
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/locks.h \
|
||||||
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
|
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h
|
||||||
cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \
|
cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \
|
||||||
$(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
$(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||||
|
|
@ -981,7 +984,7 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h
|
||||||
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
|
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
|
||||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
|
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
|
||||||
$(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
|
$(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
|
||||||
$(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
|
$(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/services/view.h
|
||||||
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
|
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
|
||||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
|
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
|
||||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
|
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
|
||||||
|
|
@ -1027,7 +1030,7 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||||
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
|
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
|
||||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
|
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
|
||||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
|
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
|
||||||
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
|
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h $(srcdir)/services/view.h\
|
||||||
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
|
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
|
||||||
$(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
$(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
||||||
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
|
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
|
||||||
|
|
@ -1056,7 +1059,7 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||||
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
|
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
|
||||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
|
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
|
||||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
|
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
|
||||||
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
|
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h $(srcdir)/services/view.h \
|
||||||
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
|
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
|
||||||
$(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
$(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
||||||
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
|
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
|
||||||
|
|
@ -1066,7 +1069,7 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||||
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
||||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
|
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
|
||||||
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/locks.h \
|
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/locks.h \
|
||||||
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
|
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h
|
||||||
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
|
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
|
||||||
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||||
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||||
|
|
@ -1077,7 +1080,7 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h
|
||||||
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
|
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
|
||||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
|
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
|
||||||
$(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
|
$(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
|
||||||
$(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
|
$(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/services/view.h
|
||||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||||
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,23 @@ acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** apply acl_view string */
|
||||||
|
static int
|
||||||
|
acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
|
||||||
|
struct views* vs)
|
||||||
|
{
|
||||||
|
struct acl_addr* node;
|
||||||
|
if(!(node=acl_find_or_create(acl, str)))
|
||||||
|
return 0;
|
||||||
|
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
|
||||||
|
if(!node->view) {
|
||||||
|
log_err("no view with name: %s", str2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lock_rw_unlock(&node->view->lock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/** apply acl_tag_action string */
|
/** apply acl_tag_action string */
|
||||||
static int
|
static int
|
||||||
acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
|
acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||||
|
|
@ -312,6 +329,27 @@ read_acl_tags(struct acl_list* acl, struct config_file* cfg)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** read acl view config */
|
||||||
|
static int
|
||||||
|
read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
|
||||||
|
{
|
||||||
|
struct config_str2list* np, *p = cfg->acl_view;
|
||||||
|
cfg->acl_view = NULL;
|
||||||
|
while(p) {
|
||||||
|
log_assert(p->str && p->str2);
|
||||||
|
if(!acl_list_view_cfg(acl, p->str, p->str2, v)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* free the items as we go to free up memory */
|
||||||
|
np = p->next;
|
||||||
|
free(p->str);
|
||||||
|
free(p->str2);
|
||||||
|
free(p);
|
||||||
|
p = np;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/** read acl tag actions config */
|
/** read acl tag actions config */
|
||||||
static int
|
static int
|
||||||
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
|
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
|
||||||
|
|
@ -362,12 +400,15 @@ read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||||
|
struct views* v)
|
||||||
{
|
{
|
||||||
regional_free_all(acl->region);
|
regional_free_all(acl->region);
|
||||||
addr_tree_init(&acl->tree);
|
addr_tree_init(&acl->tree);
|
||||||
if(!read_acl_list(acl, cfg))
|
if(!read_acl_list(acl, cfg))
|
||||||
return 0;
|
return 0;
|
||||||
|
if(!read_acl_view(acl, cfg, v))
|
||||||
|
return 0;
|
||||||
if(!read_acl_tags(acl, cfg))
|
if(!read_acl_tags(acl, cfg))
|
||||||
return 0;
|
return 0;
|
||||||
if(!read_acl_tag_actions(acl, cfg))
|
if(!read_acl_tag_actions(acl, cfg))
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#ifndef DAEMON_ACL_LIST_H
|
#ifndef DAEMON_ACL_LIST_H
|
||||||
#define DAEMON_ACL_LIST_H
|
#define DAEMON_ACL_LIST_H
|
||||||
#include "util/storage/dnstree.h"
|
#include "util/storage/dnstree.h"
|
||||||
|
#include "services/view.h"
|
||||||
struct config_file;
|
struct config_file;
|
||||||
struct regional;
|
struct regional;
|
||||||
|
|
||||||
|
|
@ -100,6 +101,8 @@ struct acl_addr {
|
||||||
struct config_strlist** tag_datas;
|
struct config_strlist** tag_datas;
|
||||||
/** size of the tag_datas array */
|
/** size of the tag_datas array */
|
||||||
size_t tag_datas_size;
|
size_t tag_datas_size;
|
||||||
|
/* view element, NULL if none */
|
||||||
|
struct view* view;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -118,9 +121,11 @@ void acl_list_delete(struct acl_list* acl);
|
||||||
* Process access control config.
|
* Process access control config.
|
||||||
* @param acl: where to store.
|
* @param acl: where to store.
|
||||||
* @param cfg: config options.
|
* @param cfg: config options.
|
||||||
|
* @param v: views structure
|
||||||
* @return 0 on error.
|
* @return 0 on error.
|
||||||
*/
|
*/
|
||||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg);
|
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||||
|
struct views* v);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup access control status for acl structure.
|
* Lookup access control status for acl structure.
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@
|
||||||
#include "services/cache/rrset.h"
|
#include "services/cache/rrset.h"
|
||||||
#include "services/cache/infra.h"
|
#include "services/cache/infra.h"
|
||||||
#include "services/localzone.h"
|
#include "services/localzone.h"
|
||||||
|
#include "services/view.h"
|
||||||
#include "services/modstack.h"
|
#include "services/modstack.h"
|
||||||
#include "util/module.h"
|
#include "util/module.h"
|
||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
|
|
@ -542,8 +543,15 @@ void
|
||||||
daemon_fork(struct daemon* daemon)
|
daemon_fork(struct daemon* daemon)
|
||||||
{
|
{
|
||||||
log_assert(daemon);
|
log_assert(daemon);
|
||||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg))
|
if(!(daemon->views = views_create()))
|
||||||
|
fatal_exit("Could not create views: out of memory");
|
||||||
|
/* create individual views and their localzone/data trees */
|
||||||
|
if(!views_apply_cfg(daemon->views, daemon->cfg))
|
||||||
|
fatal_exit("Could not set up views");
|
||||||
|
|
||||||
|
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
|
||||||
fatal_exit("Could not setup access control list");
|
fatal_exit("Could not setup access control list");
|
||||||
|
/* create global local_zones */
|
||||||
if(!(daemon->local_zones = local_zones_create()))
|
if(!(daemon->local_zones = local_zones_create()))
|
||||||
fatal_exit("Could not create local zones: out of memory");
|
fatal_exit("Could not create local zones: out of memory");
|
||||||
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
|
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
|
||||||
|
|
@ -605,6 +613,8 @@ daemon_cleanup(struct daemon* daemon)
|
||||||
slabhash_clear(daemon->env->msg_cache);
|
slabhash_clear(daemon->env->msg_cache);
|
||||||
local_zones_delete(daemon->local_zones);
|
local_zones_delete(daemon->local_zones);
|
||||||
daemon->local_zones = NULL;
|
daemon->local_zones = NULL;
|
||||||
|
views_delete(daemon->views);
|
||||||
|
daemon->views = NULL;
|
||||||
/* key cache is cleared by module desetup during next daemon_fork() */
|
/* key cache is cleared by module desetup during next daemon_fork() */
|
||||||
daemon_remote_clear(daemon->rc);
|
daemon_remote_clear(daemon->rc);
|
||||||
for(i=0; i<daemon->num; i++)
|
for(i=0; i<daemon->num; i++)
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ struct module_env;
|
||||||
struct rrset_cache;
|
struct rrset_cache;
|
||||||
struct acl_list;
|
struct acl_list;
|
||||||
struct local_zones;
|
struct local_zones;
|
||||||
|
struct views;
|
||||||
struct ub_randstate;
|
struct ub_randstate;
|
||||||
struct daemon_remote;
|
struct daemon_remote;
|
||||||
|
|
||||||
|
|
@ -111,6 +112,8 @@ struct daemon {
|
||||||
struct timeval time_last_stat;
|
struct timeval time_last_stat;
|
||||||
/** time when daemon started */
|
/** time when daemon started */
|
||||||
struct timeval time_boot;
|
struct timeval time_boot;
|
||||||
|
/** views structure containing view tree */
|
||||||
|
struct views* views;
|
||||||
#ifdef USE_DNSTAP
|
#ifdef USE_DNSTAP
|
||||||
/** the dnstap environment master value, copied and changed by threads*/
|
/** the dnstap environment master value, copied and changed by threads*/
|
||||||
struct dt_env* dtenv;
|
struct dt_env* dtenv;
|
||||||
|
|
|
||||||
164
daemon/remote.c
164
daemon/remote.c
|
|
@ -1124,7 +1124,7 @@ find_arg2(SSL* ssl, char* arg, char** arg2)
|
||||||
|
|
||||||
/** Add a new zone */
|
/** Add a new zone */
|
||||||
static void
|
static void
|
||||||
do_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
do_zone_add(SSL* ssl, struct local_zones* zones, char* arg)
|
||||||
{
|
{
|
||||||
uint8_t* nm;
|
uint8_t* nm;
|
||||||
int nmlabs;
|
int nmlabs;
|
||||||
|
|
@ -1141,31 +1141,31 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
||||||
free(nm);
|
free(nm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lock_rw_wrlock(&worker->daemon->local_zones->lock);
|
lock_rw_wrlock(&zones->lock);
|
||||||
if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen,
|
if((z=local_zones_find(zones, nm, nmlen,
|
||||||
nmlabs, LDNS_RR_CLASS_IN))) {
|
nmlabs, LDNS_RR_CLASS_IN))) {
|
||||||
/* already present in tree */
|
/* already present in tree */
|
||||||
lock_rw_wrlock(&z->lock);
|
lock_rw_wrlock(&z->lock);
|
||||||
z->type = t; /* update type anyway */
|
z->type = t; /* update type anyway */
|
||||||
lock_rw_unlock(&z->lock);
|
lock_rw_unlock(&z->lock);
|
||||||
free(nm);
|
free(nm);
|
||||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
lock_rw_unlock(&zones->lock);
|
||||||
send_ok(ssl);
|
send_ok(ssl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!local_zones_add_zone(worker->daemon->local_zones, nm, nmlen,
|
if(!local_zones_add_zone(zones, nm, nmlen,
|
||||||
nmlabs, LDNS_RR_CLASS_IN, t)) {
|
nmlabs, LDNS_RR_CLASS_IN, t)) {
|
||||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
lock_rw_unlock(&zones->lock);
|
||||||
ssl_printf(ssl, "error out of memory\n");
|
ssl_printf(ssl, "error out of memory\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
lock_rw_unlock(&zones->lock);
|
||||||
send_ok(ssl);
|
send_ok(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove a zone */
|
/** Remove a zone */
|
||||||
static void
|
static void
|
||||||
do_zone_remove(SSL* ssl, struct worker* worker, char* arg)
|
do_zone_remove(SSL* ssl, struct local_zones* zones, char* arg)
|
||||||
{
|
{
|
||||||
uint8_t* nm;
|
uint8_t* nm;
|
||||||
int nmlabs;
|
int nmlabs;
|
||||||
|
|
@ -1173,22 +1173,22 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||||
struct local_zone* z;
|
struct local_zone* z;
|
||||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||||
return;
|
return;
|
||||||
lock_rw_wrlock(&worker->daemon->local_zones->lock);
|
lock_rw_wrlock(&zones->lock);
|
||||||
if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen,
|
if((z=local_zones_find(zones, nm, nmlen,
|
||||||
nmlabs, LDNS_RR_CLASS_IN))) {
|
nmlabs, LDNS_RR_CLASS_IN))) {
|
||||||
/* present in tree */
|
/* present in tree */
|
||||||
local_zones_del_zone(worker->daemon->local_zones, z);
|
local_zones_del_zone(zones, z);
|
||||||
}
|
}
|
||||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
lock_rw_unlock(&zones->lock);
|
||||||
free(nm);
|
free(nm);
|
||||||
send_ok(ssl);
|
send_ok(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add new RR data */
|
/** Add new RR data */
|
||||||
static void
|
static void
|
||||||
do_data_add(SSL* ssl, struct worker* worker, char* arg)
|
do_data_add(SSL* ssl, struct local_zones* zones, char* arg)
|
||||||
{
|
{
|
||||||
if(!local_zones_add_RR(worker->daemon->local_zones, arg)) {
|
if(!local_zones_add_RR(zones, arg)) {
|
||||||
ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg);
|
ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1197,19 +1197,91 @@ do_data_add(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
|
||||||
/** Remove RR data */
|
/** Remove RR data */
|
||||||
static void
|
static void
|
||||||
do_data_remove(SSL* ssl, struct worker* worker, char* arg)
|
do_data_remove(SSL* ssl, struct local_zones* zones, char* arg)
|
||||||
{
|
{
|
||||||
uint8_t* nm;
|
uint8_t* nm;
|
||||||
int nmlabs;
|
int nmlabs;
|
||||||
size_t nmlen;
|
size_t nmlen;
|
||||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||||
return;
|
return;
|
||||||
local_zones_del_data(worker->daemon->local_zones, nm,
|
local_zones_del_data(zones, nm,
|
||||||
nmlen, nmlabs, LDNS_RR_CLASS_IN);
|
nmlen, nmlabs, LDNS_RR_CLASS_IN);
|
||||||
free(nm);
|
free(nm);
|
||||||
send_ok(ssl);
|
send_ok(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add a new zone to view */
|
||||||
|
static void
|
||||||
|
do_view_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
{
|
||||||
|
char* arg2;
|
||||||
|
struct view* v;
|
||||||
|
if(!find_arg2(ssl, arg, &arg2))
|
||||||
|
return;
|
||||||
|
v = views_find_view(worker->daemon->views,
|
||||||
|
arg, 1 /* get write lock*/);
|
||||||
|
if(!v) {
|
||||||
|
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do_zone_add(ssl, v->local_zones, arg2);
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove a zone from view */
|
||||||
|
static void
|
||||||
|
do_view_zone_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
{
|
||||||
|
char* arg2;
|
||||||
|
struct view* v;
|
||||||
|
if(!find_arg2(ssl, arg, &arg2))
|
||||||
|
return;
|
||||||
|
v = views_find_view(worker->daemon->views,
|
||||||
|
arg, 1 /* get write lock*/);
|
||||||
|
if(!v) {
|
||||||
|
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do_zone_remove(ssl, v->local_zones, arg2);
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add new RR data to view */
|
||||||
|
static void
|
||||||
|
do_view_data_add(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
{
|
||||||
|
char* arg2;
|
||||||
|
struct view* v;
|
||||||
|
if(!find_arg2(ssl, arg, &arg2))
|
||||||
|
return;
|
||||||
|
v = views_find_view(worker->daemon->views,
|
||||||
|
arg, 1 /* get write lock*/);
|
||||||
|
if(!v) {
|
||||||
|
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do_data_add(ssl, v->local_zones, arg2);
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove RR data from view */
|
||||||
|
static void
|
||||||
|
do_view_data_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
{
|
||||||
|
char* arg2;
|
||||||
|
struct view* v;
|
||||||
|
if(!find_arg2(ssl, arg, &arg2))
|
||||||
|
return;
|
||||||
|
v = views_find_view(worker->daemon->views,
|
||||||
|
arg, 1 /* get write lock*/);
|
||||||
|
if(!v) {
|
||||||
|
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do_data_remove(ssl, v->local_zones, arg2);
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
}
|
||||||
|
|
||||||
/** cache lookup of nameservers */
|
/** cache lookup of nameservers */
|
||||||
static void
|
static void
|
||||||
do_lookup(SSL* ssl, struct worker* worker, char* arg)
|
do_lookup(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
|
@ -2263,9 +2335,8 @@ do_list_stubs(SSL* ssl, struct worker* worker)
|
||||||
|
|
||||||
/** do the list_local_zones command */
|
/** do the list_local_zones command */
|
||||||
static void
|
static void
|
||||||
do_list_local_zones(SSL* ssl, struct worker* worker)
|
do_list_local_zones(SSL* ssl, struct local_zones* zones)
|
||||||
{
|
{
|
||||||
struct local_zones* zones = worker->daemon->local_zones;
|
|
||||||
struct local_zone* z;
|
struct local_zone* z;
|
||||||
char buf[257];
|
char buf[257];
|
||||||
lock_rw_rdlock(&zones->lock);
|
lock_rw_rdlock(&zones->lock);
|
||||||
|
|
@ -2286,9 +2357,8 @@ do_list_local_zones(SSL* ssl, struct worker* worker)
|
||||||
|
|
||||||
/** do the list_local_data command */
|
/** do the list_local_data command */
|
||||||
static void
|
static void
|
||||||
do_list_local_data(SSL* ssl, struct worker* worker)
|
do_list_local_data(SSL* ssl, struct worker* worker, struct local_zones* zones)
|
||||||
{
|
{
|
||||||
struct local_zones* zones = worker->daemon->local_zones;
|
|
||||||
struct local_zone* z;
|
struct local_zone* z;
|
||||||
struct local_data* d;
|
struct local_data* d;
|
||||||
struct local_rrset* p;
|
struct local_rrset* p;
|
||||||
|
|
@ -2324,6 +2394,34 @@ do_list_local_data(SSL* ssl, struct worker* worker)
|
||||||
lock_rw_unlock(&zones->lock);
|
lock_rw_unlock(&zones->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** do the view_list_local_zones command */
|
||||||
|
static void
|
||||||
|
do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
{
|
||||||
|
struct view* v = views_find_view(worker->daemon->views,
|
||||||
|
arg, 0 /* get read lock*/);
|
||||||
|
if(!v) {
|
||||||
|
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do_list_local_zones(ssl, v->local_zones);
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** do the view_list_local_data command */
|
||||||
|
static void
|
||||||
|
do_view_list_local_data(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
{
|
||||||
|
struct view* v = views_find_view(worker->daemon->views,
|
||||||
|
arg, 0 /* get read lock*/);
|
||||||
|
if(!v) {
|
||||||
|
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do_list_local_data(ssl, worker, v->local_zones);
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
}
|
||||||
|
|
||||||
/** struct for user arg ratelimit list */
|
/** struct for user arg ratelimit list */
|
||||||
struct ratelimit_list_arg {
|
struct ratelimit_list_arg {
|
||||||
/** the infra cache */
|
/** the infra cache */
|
||||||
|
|
@ -2436,10 +2534,16 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||||
do_insecure_list(ssl, worker);
|
do_insecure_list(ssl, worker);
|
||||||
return;
|
return;
|
||||||
} else if(cmdcmp(p, "list_local_zones", 16)) {
|
} else if(cmdcmp(p, "list_local_zones", 16)) {
|
||||||
do_list_local_zones(ssl, worker);
|
do_list_local_zones(ssl, worker->daemon->local_zones);
|
||||||
return;
|
return;
|
||||||
} else if(cmdcmp(p, "list_local_data", 15)) {
|
} else if(cmdcmp(p, "list_local_data", 15)) {
|
||||||
do_list_local_data(ssl, worker);
|
do_list_local_data(ssl, worker, worker->daemon->local_zones);
|
||||||
|
return;
|
||||||
|
} else if(cmdcmp(p, "view_list_local_zones", 21)) {
|
||||||
|
do_view_list_local_zones(ssl, worker, skipwhite(p+21));
|
||||||
|
return;
|
||||||
|
} else if(cmdcmp(p, "view_list_local_data", 20)) {
|
||||||
|
do_view_list_local_data(ssl, worker, skipwhite(p+20));
|
||||||
return;
|
return;
|
||||||
} else if(cmdcmp(p, "ratelimit_list", 14)) {
|
} else if(cmdcmp(p, "ratelimit_list", 14)) {
|
||||||
do_ratelimit_list(ssl, worker, p+14);
|
do_ratelimit_list(ssl, worker, p+14);
|
||||||
|
|
@ -2505,13 +2609,21 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||||
if(cmdcmp(p, "verbosity", 9)) {
|
if(cmdcmp(p, "verbosity", 9)) {
|
||||||
do_verbosity(ssl, skipwhite(p+9));
|
do_verbosity(ssl, skipwhite(p+9));
|
||||||
} else if(cmdcmp(p, "local_zone_remove", 17)) {
|
} else if(cmdcmp(p, "local_zone_remove", 17)) {
|
||||||
do_zone_remove(ssl, worker, skipwhite(p+17));
|
do_zone_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
|
||||||
} else if(cmdcmp(p, "local_zone", 10)) {
|
} else if(cmdcmp(p, "local_zone", 10)) {
|
||||||
do_zone_add(ssl, worker, skipwhite(p+10));
|
do_zone_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
|
||||||
} else if(cmdcmp(p, "local_data_remove", 17)) {
|
} else if(cmdcmp(p, "local_data_remove", 17)) {
|
||||||
do_data_remove(ssl, worker, skipwhite(p+17));
|
do_data_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
|
||||||
} else if(cmdcmp(p, "local_data", 10)) {
|
} else if(cmdcmp(p, "local_data", 10)) {
|
||||||
do_data_add(ssl, worker, skipwhite(p+10));
|
do_data_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
|
||||||
|
} else if(cmdcmp(p, "view_local_zone_remove", 22)) {
|
||||||
|
do_view_zone_remove(ssl, worker, skipwhite(p+22));
|
||||||
|
} else if(cmdcmp(p, "view_local_zone", 15)) {
|
||||||
|
do_view_zone_add(ssl, worker, skipwhite(p+15));
|
||||||
|
} else if(cmdcmp(p, "view_local_data_remove", 22)) {
|
||||||
|
do_view_data_remove(ssl, worker, skipwhite(p+22));
|
||||||
|
} else if(cmdcmp(p, "view_local_data", 15)) {
|
||||||
|
do_view_data_add(ssl, worker, skipwhite(p+15));
|
||||||
} else if(cmdcmp(p, "flush_zone", 10)) {
|
} else if(cmdcmp(p, "flush_zone", 10)) {
|
||||||
do_flush_zone(ssl, worker, skipwhite(p+10));
|
do_flush_zone(ssl, worker, skipwhite(p+10));
|
||||||
} else if(cmdcmp(p, "flush_type", 10)) {
|
} else if(cmdcmp(p, "flush_type", 10)) {
|
||||||
|
|
|
||||||
|
|
@ -949,7 +949,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
acladdr->taglist, acladdr->taglen, acladdr->tag_actions,
|
acladdr->taglist, acladdr->taglen, acladdr->tag_actions,
|
||||||
acladdr->tag_actions_size, acladdr->tag_datas,
|
acladdr->tag_actions_size, acladdr->tag_datas,
|
||||||
acladdr->tag_datas_size, worker->daemon->cfg->tagname,
|
acladdr->tag_datas_size, worker->daemon->cfg->tagname,
|
||||||
worker->daemon->cfg->num_tags)) {
|
worker->daemon->cfg->num_tags, acladdr->view)) {
|
||||||
regional_free_all(worker->scratchpad);
|
regional_free_all(worker->scratchpad);
|
||||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||||
comm_point_drop_reply(repinfo);
|
comm_point_drop_reply(repinfo);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
5 October 2016: Ralph
|
||||||
|
- Added views functionality.
|
||||||
|
|
||||||
30 September 2016: Wouter
|
30 September 2016: Wouter
|
||||||
- Fix Nits for 1.5.10 reported by Dag-Erling Smorgrav.
|
- Fix Nits for 1.5.10 reported by Dag-Erling Smorgrav.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,9 @@ server:
|
||||||
# set redirect data for particular tag for access control element
|
# set redirect data for particular tag for access control element
|
||||||
# access-control-tag-data: 192.0.2.0/24 tag2 "A 127.0.0.1"
|
# access-control-tag-data: 192.0.2.0/24 tag2 "A 127.0.0.1"
|
||||||
|
|
||||||
|
# Set view for access control element
|
||||||
|
# access-control-view: 192.0.2.0/24 viewname
|
||||||
|
|
||||||
# if given, a chroot(2) is done to the given directory.
|
# if given, a chroot(2) is done to the given directory.
|
||||||
# i.e. you can chroot to the working directory, for example,
|
# i.e. you can chroot to the working directory, for example,
|
||||||
# for extra security, but make sure all files are in that directory.
|
# for extra security, but make sure all files are in that directory.
|
||||||
|
|
@ -718,3 +721,19 @@ remote-control:
|
||||||
# forward-zone:
|
# forward-zone:
|
||||||
# name: "example.org"
|
# name: "example.org"
|
||||||
# forward-host: fwd.example.com
|
# forward-host: fwd.example.com
|
||||||
|
|
||||||
|
# Views
|
||||||
|
# Create named views. Name must be unique. Map views to requests using
|
||||||
|
# the access-control-view option. Views can contain zero or more local-zone
|
||||||
|
# and local-data options. Options from matching views will override global
|
||||||
|
# options. Global options will be used if no matching view is found.
|
||||||
|
# With view-first yes, it will try to answer using the global local-zone and
|
||||||
|
# local-data elements if there is no view specific match.
|
||||||
|
# view:
|
||||||
|
# name: "viewname"
|
||||||
|
# local-zone: "example.com" redirect
|
||||||
|
# local-data: "example.com A 192.0.2.3"
|
||||||
|
# view-first: no
|
||||||
|
# view:
|
||||||
|
# name: "anotherview"
|
||||||
|
# local-zone: "example.com" refuse
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,21 @@ estimated qps and qps limit from config. With +a it prints all domains, not
|
||||||
just the ratelimited domains, with their estimated qps. The ratelimited
|
just the ratelimited domains, with their estimated qps. The ratelimited
|
||||||
domains return an error for uncached (new) queries, but cached queries work
|
domains return an error for uncached (new) queries, but cached queries work
|
||||||
as normal.
|
as normal.
|
||||||
|
.TP
|
||||||
|
.B view_list_local_zones \fIview\fR
|
||||||
|
\fIlist_local_zones\fR for given view.
|
||||||
|
.TP
|
||||||
|
.B view_local_zone \fIview\fR \fIname\fR \fItype
|
||||||
|
\fIlocal_zone\fR for given view.
|
||||||
|
.TP
|
||||||
|
.B view_local_zone_remove \fIview\fR \fIname
|
||||||
|
\fIlocal_zone_remove\fR for given view.
|
||||||
|
.TP
|
||||||
|
.B view_local_data \fIview\fR \fIRR data...
|
||||||
|
\fIlocal_data\fR for given view.
|
||||||
|
.TP
|
||||||
|
.B view_local_data_remove \fIview\fR \fIname
|
||||||
|
\fIlocal_data_remove\fR for given view.
|
||||||
.SH "EXIT CODE"
|
.SH "EXIT CODE"
|
||||||
The unbound\-control program exits with status code 1 on error, 0 on success.
|
The unbound\-control program exits with status code 1 on error, 0 on success.
|
||||||
.SH "SET UP"
|
.SH "SET UP"
|
||||||
|
|
|
||||||
|
|
@ -474,6 +474,9 @@ order of the define-tag values.
|
||||||
.B access\-control\-tag\-data: \fI<IP netblock> <tag> <"resource record string">
|
.B access\-control\-tag\-data: \fI<IP netblock> <tag> <"resource record string">
|
||||||
Set redirect data for particular tag for given access control element.
|
Set redirect data for particular tag for given access control element.
|
||||||
.TP
|
.TP
|
||||||
|
.B access\-control\-view: \fI<IP netblock> <view name>
|
||||||
|
Set view for given access control element.
|
||||||
|
.TP
|
||||||
.B chroot: \fI<directory>
|
.B chroot: \fI<directory>
|
||||||
If chroot is enabled, you should pass the configfile (from the
|
If chroot is enabled, you should pass the configfile (from the
|
||||||
commandline) as a full path from the original root. After the
|
commandline) as a full path from the original root. After the
|
||||||
|
|
@ -1310,6 +1313,32 @@ If enabled, a query is attempted without the forward clause if it fails.
|
||||||
The data could not be retrieved and would have caused SERVFAIL because
|
The data could not be retrieved and would have caused SERVFAIL because
|
||||||
the servers are unreachable, instead it is tried without this clause.
|
the servers are unreachable, instead it is tried without this clause.
|
||||||
The default is no.
|
The default is no.
|
||||||
|
.SS "View Options"
|
||||||
|
.LP
|
||||||
|
There may be multiple
|
||||||
|
.B view:
|
||||||
|
clauses. Each with a \fBname:\fR and zero or more \fBlocal\-zone\fR and
|
||||||
|
\fBlocal\-data\fR elements. View can be mapped to requests by specifying the view
|
||||||
|
name in an \fBaccess\-control\-view\fR element. Options from matching views will
|
||||||
|
override global options. Global options will be used if no matching view
|
||||||
|
is found.
|
||||||
|
.TP
|
||||||
|
.B name: \fI<view name>
|
||||||
|
Name of the view. Must be unique. This name is used in access\-control\-view
|
||||||
|
elements.
|
||||||
|
.TP
|
||||||
|
.B local\-zone: \fI<zone> <type>
|
||||||
|
View specific local\-zone elements. Has the same types and behaviour as the
|
||||||
|
global local\-zone elements.
|
||||||
|
.TP
|
||||||
|
.B local\-data: \fI"<resource record string>"
|
||||||
|
View specific local\-data elements. Has the same behaviour as the global
|
||||||
|
local\-data elements.
|
||||||
|
.TP
|
||||||
|
.B view\-first: \fI<yes or no>
|
||||||
|
If enabled, it attempts to use the global local\-zone and local\-data if there
|
||||||
|
is no match in the view specific options.
|
||||||
|
The default is no.
|
||||||
.SS "Python Module Options"
|
.SS "Python Module Options"
|
||||||
.LP
|
.LP
|
||||||
The
|
The
|
||||||
|
|
|
||||||
|
|
@ -609,7 +609,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||||
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
||||||
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
|
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
|
||||||
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
||||||
NULL, 0, NULL, 0)) {
|
NULL, 0, NULL, 0, NULL)) {
|
||||||
regional_free_all(w->env->scratch);
|
regional_free_all(w->env->scratch);
|
||||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||||
w->back->udp_buff, sec_status_insecure, NULL);
|
w->back->udp_buff, sec_status_insecure, NULL);
|
||||||
|
|
@ -680,7 +680,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||||
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
||||||
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
|
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
|
||||||
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
||||||
NULL, 0, NULL, 0)) {
|
NULL, 0, NULL, 0, NULL)) {
|
||||||
regional_free_all(w->env->scratch);
|
regional_free_all(w->env->scratch);
|
||||||
free(qinfo.qname);
|
free(qinfo.qname);
|
||||||
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
||||||
|
|
@ -801,7 +801,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||||
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
||||||
if(local_zones_answer(w->ctx->local_zones, &qinfo, &edns,
|
if(local_zones_answer(w->ctx->local_zones, &qinfo, &edns,
|
||||||
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
||||||
NULL, 0, NULL, 0)) {
|
NULL, 0, NULL, 0, NULL)) {
|
||||||
regional_free_all(w->env->scratch);
|
regional_free_all(w->env->scratch);
|
||||||
q->msg_security = sec_status_insecure;
|
q->msg_security = sec_status_insecure;
|
||||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
||||||
#include "util/data/msgreply.h"
|
#include "util/data/msgreply.h"
|
||||||
#include "util/data/msgparse.h"
|
#include "util/data/msgparse.h"
|
||||||
#include "util/as112.h"
|
#include "util/as112.h"
|
||||||
|
#include "util/config_file.h"
|
||||||
|
|
||||||
/* maximum RRs in an RRset, to cap possible 'endless' list RRs.
|
/* maximum RRs in an RRset, to cap possible 'endless' list RRs.
|
||||||
* with 16 bytes for an A record, a 64K packet has about 4000 max */
|
* with 16 bytes for an A record, a 64K packet has about 4000 max */
|
||||||
|
|
@ -158,7 +159,7 @@ local_zone_create(uint8_t* nm, size_t len, int labs,
|
||||||
z->namelen = len;
|
z->namelen = len;
|
||||||
z->namelabs = labs;
|
z->namelabs = labs;
|
||||||
lock_rw_init(&z->lock);
|
lock_rw_init(&z->lock);
|
||||||
z->region = regional_create_custom(sizeof(struct regional));
|
z->region = regional_create();
|
||||||
if(!z->region) {
|
if(!z->region) {
|
||||||
free(z);
|
free(z);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1462,35 +1463,57 @@ local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
|
||||||
struct comm_reply* repinfo, uint8_t* taglist, size_t taglen,
|
struct comm_reply* repinfo, uint8_t* taglist, size_t taglen,
|
||||||
uint8_t* tagactions, size_t tagactionssize,
|
uint8_t* tagactions, size_t tagactionssize,
|
||||||
struct config_strlist** tag_datas, size_t tag_datas_size,
|
struct config_strlist** tag_datas, size_t tag_datas_size,
|
||||||
char** tagname, int num_tags)
|
char** tagname, int num_tags, struct view* view)
|
||||||
{
|
{
|
||||||
/* see if query is covered by a zone,
|
/* see if query is covered by a zone,
|
||||||
* if so: - try to match (exact) local data
|
* if so: - try to match (exact) local data
|
||||||
* - look at zone type for negative response. */
|
* - look at zone type for negative response. */
|
||||||
int labs = dname_count_labels(qinfo->qname);
|
int labs = dname_count_labels(qinfo->qname);
|
||||||
struct local_data* ld = NULL;
|
struct local_data* ld = NULL;
|
||||||
struct local_zone* z;
|
struct local_zone* z = NULL;
|
||||||
enum localzone_type lzt;
|
enum localzone_type lzt;
|
||||||
int r, tag = -1;
|
int r, tag = -1;
|
||||||
lock_rw_rdlock(&zones->lock);
|
|
||||||
z = local_zones_tags_lookup(zones, qinfo->qname,
|
if(view) {
|
||||||
qinfo->qname_len, labs, qinfo->qclass, taglist, taglen, 0);
|
lock_rw_rdlock(&view->lock);
|
||||||
|
if(view->local_zones &&
|
||||||
|
(z = local_zones_lookup(view->local_zones,
|
||||||
|
qinfo->qname, qinfo->qname_len, labs,
|
||||||
|
qinfo->qclass))) {
|
||||||
|
verbose(VERB_ALGO,
|
||||||
|
"using localzone from view: %s",
|
||||||
|
view->name);
|
||||||
|
lock_rw_rdlock(&z->lock);
|
||||||
|
lzt = z->type;
|
||||||
|
}
|
||||||
|
if(!z && !view->isfirst){
|
||||||
|
lock_rw_unlock(&view->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lock_rw_unlock(&view->lock);
|
||||||
|
}
|
||||||
if(!z) {
|
if(!z) {
|
||||||
|
/* try global local_zones tree */
|
||||||
|
lock_rw_rdlock(&zones->lock);
|
||||||
|
if(!(z = local_zones_tags_lookup(zones, qinfo->qname,
|
||||||
|
qinfo->qname_len, labs, qinfo->qclass, taglist,
|
||||||
|
taglen, 0))) {
|
||||||
lock_rw_unlock(&zones->lock);
|
lock_rw_unlock(&zones->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
lock_rw_rdlock(&z->lock);
|
lock_rw_rdlock(&z->lock);
|
||||||
|
|
||||||
|
lzt = lz_type(taglist, taglen, z->taglist, z->taglen,
|
||||||
|
tagactions, tagactionssize, z->type, repinfo,
|
||||||
|
z->override_tree, &tag, tagname, num_tags);
|
||||||
lock_rw_unlock(&zones->lock);
|
lock_rw_unlock(&zones->lock);
|
||||||
|
}
|
||||||
lzt = lz_type(taglist, taglen, z->taglist, z->taglen, tagactions,
|
|
||||||
tagactionssize, z->type, repinfo, z->override_tree, &tag,
|
|
||||||
tagname, num_tags);
|
|
||||||
|
|
||||||
if((lzt == local_zone_inform || lzt == local_zone_inform_deny)
|
if((lzt == local_zone_inform || lzt == local_zone_inform_deny)
|
||||||
&& repinfo)
|
&& repinfo)
|
||||||
lz_inform_print(z, qinfo, repinfo);
|
lz_inform_print(z, qinfo, repinfo);
|
||||||
|
|
||||||
if(lzt != local_zone_always_refuse && lzt != local_zone_always_transparent
|
if(lzt != local_zone_always_refuse
|
||||||
|
&& lzt != local_zone_always_transparent
|
||||||
&& lzt != local_zone_always_nxdomain
|
&& lzt != local_zone_always_nxdomain
|
||||||
&& local_data_answer(z, qinfo, edns, buf, temp, labs, &ld, lzt,
|
&& local_data_answer(z, qinfo, edns, buf, temp, labs, &ld, lzt,
|
||||||
tag, tag_datas, tag_datas_size, tagname, num_tags)) {
|
tag, tag_datas, tag_datas_size, tagname, num_tags)) {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include "util/rbtree.h"
|
#include "util/rbtree.h"
|
||||||
#include "util/locks.h"
|
#include "util/locks.h"
|
||||||
#include "util/storage/dnstree.h"
|
#include "util/storage/dnstree.h"
|
||||||
|
#include "services/view.h"
|
||||||
struct ub_packed_rrset_key;
|
struct ub_packed_rrset_key;
|
||||||
struct regional;
|
struct regional;
|
||||||
struct config_file;
|
struct config_file;
|
||||||
|
|
@ -277,6 +278,7 @@ void local_zones_print(struct local_zones* zones);
|
||||||
* @param tag_datas_size: size of tag_datas array.
|
* @param tag_datas_size: size of tag_datas array.
|
||||||
* @param tagname: array of tag name strings (for debug output).
|
* @param tagname: array of tag name strings (for debug output).
|
||||||
* @param num_tags: number of items in tagname array.
|
* @param num_tags: number of items in tagname array.
|
||||||
|
* @param view: answer using this view. May be NULL.
|
||||||
* @return true if answer is in buffer. false if query is not answered
|
* @return true if answer is in buffer. false if query is not answered
|
||||||
* by authority data. If the reply should be dropped altogether, the return
|
* by authority data. If the reply should be dropped altogether, the return
|
||||||
* value is true, but the buffer is cleared (empty).
|
* value is true, but the buffer is cleared (empty).
|
||||||
|
|
@ -286,7 +288,7 @@ int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
|
||||||
struct comm_reply* repinfo, uint8_t* taglist, size_t taglen,
|
struct comm_reply* repinfo, uint8_t* taglist, size_t taglen,
|
||||||
uint8_t* tagactions, size_t tagactionssize,
|
uint8_t* tagactions, size_t tagactionssize,
|
||||||
struct config_strlist** tag_datas, size_t tag_datas_size,
|
struct config_strlist** tag_datas, size_t tag_datas_size,
|
||||||
char** tagname, int num_tags);
|
char** tagname, int num_tags, struct view* view);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the string into localzone type.
|
* Parse the string into localzone type.
|
||||||
|
|
|
||||||
200
services/view.c
Normal file
200
services/view.c
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
* services/view.c - named views containing local zones authority service.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 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 COPYRIGHT
|
||||||
|
* HOLDER 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
|
||||||
|
*
|
||||||
|
* This file contains functions to enable named views that can hold local zone
|
||||||
|
* authority service.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include "services/view.h"
|
||||||
|
#include "services/localzone.h"
|
||||||
|
#include "util/config_file.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
view_cmp(const void* v1, const void* v2)
|
||||||
|
{
|
||||||
|
struct view* a = (struct view*)v1;
|
||||||
|
struct view* b = (struct view*)v2;
|
||||||
|
|
||||||
|
return strcmp(a->name, b->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct views*
|
||||||
|
views_create(void)
|
||||||
|
{
|
||||||
|
struct views* v = (struct views*)calloc(1,
|
||||||
|
sizeof(*v));
|
||||||
|
if(!v)
|
||||||
|
return NULL;
|
||||||
|
rbtree_init(&v->vtree, &view_cmp);
|
||||||
|
lock_rw_init(&v->lock);
|
||||||
|
lock_protect(&v->lock, &v->vtree, sizeof(v->vtree));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
view_delete(struct view* v)
|
||||||
|
{
|
||||||
|
if(!v)
|
||||||
|
return;
|
||||||
|
lock_rw_destroy(&v->lock);
|
||||||
|
local_zones_delete(v->local_zones);
|
||||||
|
free(v->name);
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
delviewnode(rbnode_t* n, void* ATTR_UNUSED(arg))
|
||||||
|
{
|
||||||
|
struct view* v = (struct view*)n;
|
||||||
|
view_delete(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
views_delete(struct views* v)
|
||||||
|
{
|
||||||
|
if(!v)
|
||||||
|
return;
|
||||||
|
lock_rw_destroy(&v->lock);
|
||||||
|
traverse_postorder(&v->vtree, delviewnode, NULL);
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** create a new view */
|
||||||
|
static struct view*
|
||||||
|
view_create(char* name)
|
||||||
|
{
|
||||||
|
struct view* v = (struct view*)calloc(1, sizeof(*v));
|
||||||
|
if(!v)
|
||||||
|
return NULL;
|
||||||
|
v->node.key = v;
|
||||||
|
if(!(v->name = strdup(name))) {
|
||||||
|
free(v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
lock_rw_init(&v->lock);
|
||||||
|
lock_protect(&v->lock, &v->name, sizeof(*v)-sizeof(rbnode_t));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** enter a new view returns with WRlock */
|
||||||
|
static struct view*
|
||||||
|
views_enter_view_name(struct views* vs, char* name)
|
||||||
|
{
|
||||||
|
struct view* v = view_create(name);
|
||||||
|
if(!v) {
|
||||||
|
log_err("out of memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add to rbtree */
|
||||||
|
lock_rw_wrlock(&vs->lock);
|
||||||
|
lock_rw_wrlock(&v->lock);
|
||||||
|
if(!rbtree_insert(&vs->vtree, &v->node)) {
|
||||||
|
log_warn("duplicate view: %s", name);
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
view_delete(v);
|
||||||
|
lock_rw_unlock(&vs->lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
lock_rw_unlock(&vs->lock);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
views_apply_cfg(struct views* vs, struct config_file* cfg)
|
||||||
|
{
|
||||||
|
struct config_view* cv;
|
||||||
|
struct view* v;
|
||||||
|
struct config_file lz_cfg;
|
||||||
|
/* Check existence of name in first view (last in config). Rest of
|
||||||
|
* views are already checked when parsing config. */
|
||||||
|
if(cfg->views && !cfg->views->name) {
|
||||||
|
log_err("view without a name");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(cv = cfg->views; cv; cv = cv->next) {
|
||||||
|
/* create and enter view */
|
||||||
|
if(!(v = views_enter_view_name(vs, cv->name)))
|
||||||
|
return 0;
|
||||||
|
v->isfirst = cv->isfirst;
|
||||||
|
if(cv->local_zones || cv->local_data) {
|
||||||
|
if(!(v->local_zones = local_zones_create())){
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(&lz_cfg, 0, sizeof(lz_cfg));
|
||||||
|
lz_cfg.local_zones = cv->local_zones;
|
||||||
|
lz_cfg.local_data = cv->local_data;
|
||||||
|
lz_cfg.local_zones_nodefault =
|
||||||
|
cv->local_zones_nodefault;
|
||||||
|
if(!local_zones_apply_cfg(v->local_zones, &lz_cfg)){
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lock_rw_unlock(&v->lock);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** find a view by name */
|
||||||
|
struct view*
|
||||||
|
views_find_view(struct views* vs, const char* name, int write)
|
||||||
|
{
|
||||||
|
struct view* v;
|
||||||
|
struct view key;
|
||||||
|
key.node.key = &v;
|
||||||
|
key.name = (char *)name;
|
||||||
|
lock_rw_rdlock(&vs->lock);
|
||||||
|
if(!(v = (struct view*)rbtree_search(&vs->vtree, &key.node))) {
|
||||||
|
lock_rw_unlock(&vs->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(write)
|
||||||
|
lock_rw_wrlock(&v->lock);
|
||||||
|
else
|
||||||
|
lock_rw_rdlock(&v->lock);
|
||||||
|
lock_rw_unlock(&vs->lock);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void views_print(struct views* v)
|
||||||
|
{
|
||||||
|
/* TODO implement print */
|
||||||
|
(void)v;
|
||||||
|
}
|
||||||
135
services/view.h
Normal file
135
services/view.h
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* services/view.h - named views containing local zones authority service.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 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 COPYRIGHT
|
||||||
|
* HOLDER 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
|
||||||
|
*
|
||||||
|
* This file contains functions to enable named views that can hold local zone
|
||||||
|
* authority service.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SERVICES_VIEW_H
|
||||||
|
#define SERVICES_VIEW_H
|
||||||
|
#include "util/rbtree.h"
|
||||||
|
#include "util/locks.h"
|
||||||
|
struct regional;
|
||||||
|
struct config_file;
|
||||||
|
struct config_view;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Views storage, shared.
|
||||||
|
*/
|
||||||
|
struct views {
|
||||||
|
/** lock on the view tree */
|
||||||
|
lock_rw_t lock;
|
||||||
|
/** rbtree of struct view */
|
||||||
|
rbtree_t vtree;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View. Named structure holding local authority zones.
|
||||||
|
*/
|
||||||
|
struct view {
|
||||||
|
/** rbtree node, key is name */
|
||||||
|
rbnode_t node;
|
||||||
|
/** view name.
|
||||||
|
* Has to be right after rbnode_t due to pointer arithmatic in
|
||||||
|
* view_create's lock protect */
|
||||||
|
char* name;
|
||||||
|
/** view specific local authority zones */
|
||||||
|
struct local_zones* local_zones;
|
||||||
|
/** Fallback to global local_zones when there is no match in the view
|
||||||
|
* specific tree. 1 for yes, 0 for no */
|
||||||
|
int isfirst;
|
||||||
|
/** lock on the data in the structure
|
||||||
|
* For the node and name you
|
||||||
|
* need to also hold the views_tree lock to change them (or to
|
||||||
|
* delete this view) */
|
||||||
|
lock_rw_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create views storage
|
||||||
|
* @return new struct or NULL on error.
|
||||||
|
*/
|
||||||
|
struct views* views_create(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete views storage
|
||||||
|
* @param v: views to delete.
|
||||||
|
*/
|
||||||
|
void views_delete(struct views* v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply config settings;
|
||||||
|
* Takes care of locking.
|
||||||
|
* @param v: view is set up.
|
||||||
|
* @param cfg: config data.
|
||||||
|
* @return false on error.
|
||||||
|
*/
|
||||||
|
int views_apply_cfg(struct views* v, struct config_file* cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two view entries in rbtree. Sort canonical.
|
||||||
|
* @param v1: view 1
|
||||||
|
* @param v2: view 2
|
||||||
|
* @return: negative, positive or 0 comparison value.
|
||||||
|
*/
|
||||||
|
int view_cmp(const void* v1, const void* v2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete one view
|
||||||
|
* @param v: view to delete.
|
||||||
|
*/
|
||||||
|
void view_delete(struct view* v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug helper. Print all views
|
||||||
|
* Takes care of locking.
|
||||||
|
* @param v: the views tree
|
||||||
|
*/
|
||||||
|
void views_print(struct views* v);
|
||||||
|
|
||||||
|
/* Find a view by name.
|
||||||
|
* @param vs: views
|
||||||
|
* @param name: name of the view we are looking for
|
||||||
|
* @param write: 1 for obtaining write lock on found view, 0 for read lock
|
||||||
|
* @return: locked view or NULL.
|
||||||
|
*/
|
||||||
|
struct view* views_find_view(struct views* vs, const char* name, int write);
|
||||||
|
|
||||||
|
#endif /* SERVICES_VIEW_H */
|
||||||
210
testdata/views.rpl
vendored
Normal file
210
testdata/views.rpl
vendored
Normal file
|
|
@ -0,0 +1,210 @@
|
||||||
|
; config options
|
||||||
|
server:
|
||||||
|
target-fetch-policy: "0 0 0 0 0"
|
||||||
|
|
||||||
|
access-control: 10.10.10.0/24 allow
|
||||||
|
access-control-view: 10.10.10.10/32 "view1"
|
||||||
|
access-control-view: 10.10.10.20/32 "view2"
|
||||||
|
access-control-view: 10.10.10.30/32 "view3"
|
||||||
|
access-control-view: 10.10.10.40/32 "view4"
|
||||||
|
|
||||||
|
local-zone: "example.com." redirect
|
||||||
|
local-data: 'example.com. IN TXT "global"'
|
||||||
|
|
||||||
|
view:
|
||||||
|
name: "view1"
|
||||||
|
local-zone: "nomatch.example.com." redirect
|
||||||
|
local-data: 'nomatch.example.com. IN TXT "view 1"'
|
||||||
|
view-first: no
|
||||||
|
|
||||||
|
view:
|
||||||
|
name: "view2"
|
||||||
|
local-zone: "example.com." redirect
|
||||||
|
local-data: 'example.com. IN TXT "view 2"'
|
||||||
|
; view-first default = no
|
||||||
|
|
||||||
|
view:
|
||||||
|
name: "view3"
|
||||||
|
local-zone: "nomatch.example.com." redirect
|
||||||
|
local-data: 'nomatch.example.com. IN TXT "view 3"'
|
||||||
|
view-first: yes
|
||||||
|
|
||||||
|
view:
|
||||||
|
name: "view4"
|
||||||
|
local-zone: "example.com." redirect
|
||||||
|
local-data: 'example.com. IN TXT "view 4"'
|
||||||
|
view-first: yes
|
||||||
|
|
||||||
|
stub-zone:
|
||||||
|
name: "."
|
||||||
|
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||||
|
CONFIG_END
|
||||||
|
SCENARIO_BEGIN Test view specific local-zone and local-data elements
|
||||||
|
|
||||||
|
; K.ROOT-SERVERS.NET.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 193.0.14.129
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
. IN NS K.ROOT-SERVERS.NET.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
SECTION AUTHORITY
|
||||||
|
com. IN NS a.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; a.gtld-servers.net.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 192.5.6.30
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
com. IN NS a.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; ns.example.com.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 1.2.3.4
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN TXT "auth data"
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
STEP 1 QUERY ADDRESS 10.10.10.10
|
||||||
|
ENTRY_BEGIN
|
||||||
|
REPLY RD
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
ENTRY_END
|
||||||
|
STEP 2 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR RD RA
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN TXT "auth data"
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
STEP 3 QUERY ADDRESS 10.10.10.20
|
||||||
|
ENTRY_BEGIN
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
ENTRY_END
|
||||||
|
STEP 4 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR RA AA
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN TXT "view 2"
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
STEP 5 QUERY ADDRESS 10.10.10.30
|
||||||
|
ENTRY_BEGIN
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
ENTRY_END
|
||||||
|
STEP 6 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR RA AA
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN TXT "global"
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
STEP 7 QUERY ADDRESS 10.10.10.40
|
||||||
|
ENTRY_BEGIN
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
ENTRY_END
|
||||||
|
STEP 8 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR RA AA
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN TXT "view 4"
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
STEP 9 QUERY ADDRESS 10.10.10.50
|
||||||
|
ENTRY_BEGIN
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
ENTRY_END
|
||||||
|
STEP 10 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR RA AA
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN TXT
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN TXT "global"
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
SCENARIO_END
|
||||||
|
|
@ -512,7 +512,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||||
* forward-first, stub-first,
|
* forward-first, stub-first,
|
||||||
* forward-zone, name, forward-addr, forward-host,
|
* forward-zone, name, forward-addr, forward-host,
|
||||||
* ratelimit-for-domain, ratelimit-below-domain,
|
* ratelimit-for-domain, ratelimit-below-domain,
|
||||||
* local-zone-tag */
|
* local-zone-tag, access-control-view */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -797,6 +797,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||||
else O_LS3(opt, "local-zone-override", local_zone_overrides)
|
else O_LS3(opt, "local-zone-override", local_zone_overrides)
|
||||||
else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
|
else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
|
||||||
else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
|
else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
|
||||||
|
else O_LS2(opt, "access-control-view", acl_view)
|
||||||
/* not here:
|
/* not here:
|
||||||
* outgoing-permit, outgoing-avoid - have list of ports
|
* outgoing-permit, outgoing-avoid - have list of ports
|
||||||
* local-zone - zones and nodefault variables
|
* local-zone - zones and nodefault variables
|
||||||
|
|
@ -983,6 +984,25 @@ config_delstubs(struct config_stub* p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
config_delview(struct config_view* p)
|
||||||
|
{
|
||||||
|
if(!p) return;
|
||||||
|
free(p->name);
|
||||||
|
config_deldblstrlist(p->local_zones);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
config_delviews(struct config_view* p)
|
||||||
|
{
|
||||||
|
struct config_view* np;
|
||||||
|
while(p) {
|
||||||
|
np = p->next;
|
||||||
|
config_delview(p);
|
||||||
|
p = np;
|
||||||
|
}
|
||||||
|
}
|
||||||
/** delete string array */
|
/** delete string array */
|
||||||
static void
|
static void
|
||||||
config_del_strarray(char** array, int num)
|
config_del_strarray(char** array, int num)
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
#ifndef UTIL_CONFIG_FILE_H
|
#ifndef UTIL_CONFIG_FILE_H
|
||||||
#define UTIL_CONFIG_FILE_H
|
#define UTIL_CONFIG_FILE_H
|
||||||
struct config_stub;
|
struct config_stub;
|
||||||
|
struct config_view;
|
||||||
struct config_strlist;
|
struct config_strlist;
|
||||||
struct config_str2list;
|
struct config_str2list;
|
||||||
struct config_str3list;
|
struct config_str3list;
|
||||||
|
|
@ -167,6 +168,8 @@ struct config_file {
|
||||||
struct config_stub* stubs;
|
struct config_stub* stubs;
|
||||||
/** the forward zone definitions, linked list */
|
/** the forward zone definitions, linked list */
|
||||||
struct config_stub* forwards;
|
struct config_stub* forwards;
|
||||||
|
/** the views definitions, linked list */
|
||||||
|
struct config_view* views;
|
||||||
/** list of donotquery addresses, linked list */
|
/** list of donotquery addresses, linked list */
|
||||||
struct config_strlist* donotqueryaddrs;
|
struct config_strlist* donotqueryaddrs;
|
||||||
/** list of access control entries, linked list */
|
/** list of access control entries, linked list */
|
||||||
|
|
@ -310,6 +313,8 @@ struct config_file {
|
||||||
struct config_str3list* acl_tag_actions;
|
struct config_str3list* acl_tag_actions;
|
||||||
/** list of aclname, tagname, redirectdata */
|
/** list of aclname, tagname, redirectdata */
|
||||||
struct config_str3list* acl_tag_datas;
|
struct config_str3list* acl_tag_datas;
|
||||||
|
/** list of aclname, view*/
|
||||||
|
struct config_str2list* acl_view;
|
||||||
/** tag list, array with tagname[i] is malloced string */
|
/** tag list, array with tagname[i] is malloced string */
|
||||||
char** tagname;
|
char** tagname;
|
||||||
/** number of items in the taglist */
|
/** number of items in the taglist */
|
||||||
|
|
@ -423,6 +428,25 @@ struct config_stub {
|
||||||
int isfirst;
|
int isfirst;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View config options
|
||||||
|
*/
|
||||||
|
struct config_view {
|
||||||
|
/** next in list */
|
||||||
|
struct config_view* next;
|
||||||
|
/** view name */
|
||||||
|
char* name;
|
||||||
|
/** local zones */
|
||||||
|
struct config_str2list* local_zones;
|
||||||
|
/** local data RRs */
|
||||||
|
struct config_strlist* local_data;
|
||||||
|
/** local zones nodefault list */
|
||||||
|
struct config_strlist* local_zones_nodefault;
|
||||||
|
/** Fallback to global local_zones when there is no match in the view
|
||||||
|
* view specific tree. 1 for yes, 0 for no */
|
||||||
|
int isfirst;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of strings for config options
|
* List of strings for config options
|
||||||
*/
|
*/
|
||||||
|
|
@ -681,6 +705,18 @@ void config_delstub(struct config_stub* p);
|
||||||
*/
|
*/
|
||||||
void config_delstubs(struct config_stub* list);
|
void config_delstubs(struct config_stub* list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a view item
|
||||||
|
* @param p: view item
|
||||||
|
*/
|
||||||
|
void config_delview(struct config_view* p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete items in config view list.
|
||||||
|
* @param list: list.
|
||||||
|
*/
|
||||||
|
void config_delviews(struct config_view* list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert 14digit to time value
|
* Convert 14digit to time value
|
||||||
* @param str: string of 14 digits
|
* @param str: string of 14 digits
|
||||||
|
|
|
||||||
3097
util/configlexer.c
3097
util/configlexer.c
File diff suppressed because it is too large
Load diff
|
|
@ -289,6 +289,8 @@ forward-zone{COLON} { YDVAR(0, VAR_FORWARD_ZONE) }
|
||||||
forward-addr{COLON} { YDVAR(1, VAR_FORWARD_ADDR) }
|
forward-addr{COLON} { YDVAR(1, VAR_FORWARD_ADDR) }
|
||||||
forward-host{COLON} { YDVAR(1, VAR_FORWARD_HOST) }
|
forward-host{COLON} { YDVAR(1, VAR_FORWARD_HOST) }
|
||||||
forward-first{COLON} { YDVAR(1, VAR_FORWARD_FIRST) }
|
forward-first{COLON} { YDVAR(1, VAR_FORWARD_FIRST) }
|
||||||
|
view{COLON} { YDVAR(0, VAR_VIEW) }
|
||||||
|
view-first{COLON} { YDVAR(1, VAR_VIEW_FIRST) }
|
||||||
do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }
|
do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }
|
||||||
do-not-query-localhost{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) }
|
do-not-query-localhost{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) }
|
||||||
access-control{COLON} { YDVAR(2, VAR_ACCESS_CONTROL) }
|
access-control{COLON} { YDVAR(2, VAR_ACCESS_CONTROL) }
|
||||||
|
|
@ -353,6 +355,7 @@ local-zone-tag{COLON} { YDVAR(2, VAR_LOCAL_ZONE_TAG) }
|
||||||
access-control-tag{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_TAG) }
|
access-control-tag{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_TAG) }
|
||||||
access-control-tag-action{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_ACTION) }
|
access-control-tag-action{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_ACTION) }
|
||||||
access-control-tag-data{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_DATA) }
|
access-control-tag-data{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_DATA) }
|
||||||
|
access-control-view{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_VIEW) }
|
||||||
local-zone-override{COLON} { YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) }
|
local-zone-override{COLON} { YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) }
|
||||||
dnstap{COLON} { YDVAR(0, VAR_DNSTAP) }
|
dnstap{COLON} { YDVAR(0, VAR_DNSTAP) }
|
||||||
dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) }
|
dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) }
|
||||||
|
|
|
||||||
1843
util/configparser.c
1843
util/configparser.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
||||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
/* A Bison parser, made by GNU Bison 3.0.2. */
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -216,7 +216,10 @@ extern int yydebug;
|
||||||
VAR_ACCESS_CONTROL_TAG = 426,
|
VAR_ACCESS_CONTROL_TAG = 426,
|
||||||
VAR_LOCAL_ZONE_OVERRIDE = 427,
|
VAR_LOCAL_ZONE_OVERRIDE = 427,
|
||||||
VAR_ACCESS_CONTROL_TAG_ACTION = 428,
|
VAR_ACCESS_CONTROL_TAG_ACTION = 428,
|
||||||
VAR_ACCESS_CONTROL_TAG_DATA = 429
|
VAR_ACCESS_CONTROL_TAG_DATA = 429,
|
||||||
|
VAR_VIEW = 430,
|
||||||
|
VAR_ACCESS_CONTROL_VIEW = 431,
|
||||||
|
VAR_VIEW_FIRST = 432
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/* Tokens. */
|
/* Tokens. */
|
||||||
|
|
@ -392,20 +395,21 @@ extern int yydebug;
|
||||||
#define VAR_LOCAL_ZONE_OVERRIDE 427
|
#define VAR_LOCAL_ZONE_OVERRIDE 427
|
||||||
#define VAR_ACCESS_CONTROL_TAG_ACTION 428
|
#define VAR_ACCESS_CONTROL_TAG_ACTION 428
|
||||||
#define VAR_ACCESS_CONTROL_TAG_DATA 429
|
#define VAR_ACCESS_CONTROL_TAG_DATA 429
|
||||||
|
#define VAR_VIEW 430
|
||||||
|
#define VAR_ACCESS_CONTROL_VIEW 431
|
||||||
|
#define VAR_VIEW_FIRST 432
|
||||||
|
|
||||||
/* Value type. */
|
/* Value type. */
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
|
typedef union YYSTYPE YYSTYPE;
|
||||||
union YYSTYPE
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
#line 64 "./util/configparser.y" /* yacc.c:1909 */
|
#line 64 "./util/configparser.y" /* yacc.c:1909 */
|
||||||
|
|
||||||
char* str;
|
char* str;
|
||||||
|
|
||||||
#line 406 "util/configparser.h" /* yacc.c:1909 */
|
#line 412 "util/configparser.h" /* yacc.c:1909 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union YYSTYPE YYSTYPE;
|
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -128,12 +128,14 @@ extern struct config_parser_state* cfg_parser;
|
||||||
%token VAR_QNAME_MINIMISATION VAR_IP_FREEBIND VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG
|
%token VAR_QNAME_MINIMISATION VAR_IP_FREEBIND VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG
|
||||||
%token VAR_ACCESS_CONTROL_TAG VAR_LOCAL_ZONE_OVERRIDE
|
%token VAR_ACCESS_CONTROL_TAG VAR_LOCAL_ZONE_OVERRIDE
|
||||||
%token VAR_ACCESS_CONTROL_TAG_ACTION VAR_ACCESS_CONTROL_TAG_DATA
|
%token VAR_ACCESS_CONTROL_TAG_ACTION VAR_ACCESS_CONTROL_TAG_DATA
|
||||||
|
%token VAR_VIEW VAR_ACCESS_CONTROL_VIEW VAR_VIEW_FIRST
|
||||||
|
|
||||||
%%
|
%%
|
||||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||||
toplevelvar: serverstart contents_server | stubstart contents_stub |
|
toplevelvar: serverstart contents_server | stubstart contents_stub |
|
||||||
forwardstart contents_forward | pythonstart contents_py |
|
forwardstart contents_forward | pythonstart contents_py |
|
||||||
rcstart contents_rc | dtstart contents_dt
|
rcstart contents_rc | dtstart contents_dt | viewstart
|
||||||
|
contents_view
|
||||||
;
|
;
|
||||||
|
|
||||||
/* server: declaration */
|
/* server: declaration */
|
||||||
|
|
@ -199,7 +201,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||||
server_ip_freebind | server_define_tag | server_local_zone_tag |
|
server_ip_freebind | server_define_tag | server_local_zone_tag |
|
||||||
server_disable_dnssec_lame_check | server_access_control_tag |
|
server_disable_dnssec_lame_check | server_access_control_tag |
|
||||||
server_local_zone_override | server_access_control_tag_action |
|
server_local_zone_override | server_access_control_tag_action |
|
||||||
server_access_control_tag_data
|
server_access_control_tag_data | server_access_control_view
|
||||||
;
|
;
|
||||||
stubstart: VAR_STUB_ZONE
|
stubstart: VAR_STUB_ZONE
|
||||||
{
|
{
|
||||||
|
|
@ -233,6 +235,24 @@ contents_forward: contents_forward content_forward
|
||||||
| ;
|
| ;
|
||||||
content_forward: forward_name | forward_host | forward_addr | forward_first
|
content_forward: forward_name | forward_host | forward_addr | forward_first
|
||||||
;
|
;
|
||||||
|
viewstart: VAR_VIEW
|
||||||
|
{
|
||||||
|
struct config_view* s;
|
||||||
|
OUTYY(("\nP(view:)\n"));
|
||||||
|
s = (struct config_view*)calloc(1, sizeof(struct config_view));
|
||||||
|
if(s) {
|
||||||
|
s->next = cfg_parser->cfg->views;
|
||||||
|
if(s->next && !s->next->name)
|
||||||
|
yyerror("view without name");
|
||||||
|
cfg_parser->cfg->views = s;
|
||||||
|
} else
|
||||||
|
yyerror("out of memory");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
contents_view: contents_view content_view
|
||||||
|
| ;
|
||||||
|
content_view: view_name | view_local_zone | view_local_data | view_first
|
||||||
|
;
|
||||||
server_num_threads: VAR_NUM_THREADS STRING_ARG
|
server_num_threads: VAR_NUM_THREADS STRING_ARG
|
||||||
{
|
{
|
||||||
OUTYY(("P(server_num_threads:%s)\n", $2));
|
OUTYY(("P(server_num_threads:%s)\n", $2));
|
||||||
|
|
@ -1422,6 +1442,17 @@ server_local_zone_override: VAR_LOCAL_ZONE_OVERRIDE STRING_ARG STRING_ARG STRING
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
server_access_control_view: VAR_ACCESS_CONTROL_VIEW STRING_ARG STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(server_access_control_view:%s %s)\n", $2, $3));
|
||||||
|
if(!cfg_str2list_insert(&cfg_parser->cfg->acl_view,
|
||||||
|
$2, $3)) {
|
||||||
|
yyerror("out of memory");
|
||||||
|
free($2);
|
||||||
|
free($3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
server_ratelimit: VAR_RATELIMIT STRING_ARG
|
server_ratelimit: VAR_RATELIMIT STRING_ARG
|
||||||
{
|
{
|
||||||
OUTYY(("P(server_ratelimit:%s)\n", $2));
|
OUTYY(("P(server_ratelimit:%s)\n", $2));
|
||||||
|
|
@ -1573,6 +1604,63 @@ forward_first: VAR_FORWARD_FIRST STRING_ARG
|
||||||
free($2);
|
free($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
view_name: VAR_NAME STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(name:%s)\n", $2));
|
||||||
|
if(cfg_parser->cfg->views->name)
|
||||||
|
yyerror("view name override, there must be one "
|
||||||
|
"name for one view");
|
||||||
|
free(cfg_parser->cfg->views->name);
|
||||||
|
cfg_parser->cfg->views->name = $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(view_local_zone:%s %s)\n", $2, $3));
|
||||||
|
if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
|
||||||
|
strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 &&
|
||||||
|
strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
|
||||||
|
&& strcmp($3, "typetransparent")!=0
|
||||||
|
&& strcmp($3, "always_transparent")!=0
|
||||||
|
&& strcmp($3, "always_refuse")!=0
|
||||||
|
&& strcmp($3, "always_nxdomain")!=0
|
||||||
|
&& strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0)
|
||||||
|
yyerror("local-zone type: expected static, deny, "
|
||||||
|
"refuse, redirect, transparent, "
|
||||||
|
"typetransparent, inform, inform_deny, "
|
||||||
|
"always_transparent, always_refuse, "
|
||||||
|
"always_nxdomain or nodefault");
|
||||||
|
else if(strcmp($3, "nodefault")==0) {
|
||||||
|
if(!cfg_strlist_insert(&cfg_parser->cfg->views->
|
||||||
|
local_zones_nodefault, $2))
|
||||||
|
fatal_exit("out of memory adding local-zone");
|
||||||
|
free($3);
|
||||||
|
} else {
|
||||||
|
if(!cfg_str2list_insert(
|
||||||
|
&cfg_parser->cfg->views->local_zones,
|
||||||
|
$2, $3))
|
||||||
|
fatal_exit("out of memory adding local-zone");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
view_local_data: VAR_LOCAL_DATA STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(view_local_data:%s)\n", $2));
|
||||||
|
if(!cfg_strlist_insert(&cfg_parser->cfg->views->local_data, $2)) {
|
||||||
|
fatal_exit("out of memory adding local-data");
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
view_first: VAR_VIEW_FIRST STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(view-first:%s)\n", $2));
|
||||||
|
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||||
|
yyerror("expected yes or no.");
|
||||||
|
else cfg_parser->cfg->views->isfirst=(strcmp($2, "yes")==0);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
rcstart: VAR_REMOTE_CONTROL
|
rcstart: VAR_REMOTE_CONTROL
|
||||||
{
|
{
|
||||||
OUTYY(("\nP(remote-control:)\n"));
|
OUTYY(("\nP(remote-control:)\n"));
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@
|
||||||
#include "services/localzone.h"
|
#include "services/localzone.h"
|
||||||
#include "services/cache/infra.h"
|
#include "services/cache/infra.h"
|
||||||
#include "services/cache/rrset.h"
|
#include "services/cache/rrset.h"
|
||||||
|
#include "services/view.h"
|
||||||
#include "dns64/dns64.h"
|
#include "dns64/dns64.h"
|
||||||
#include "iterator/iterator.h"
|
#include "iterator/iterator.h"
|
||||||
#include "iterator/iter_fwd.h"
|
#include "iterator/iter_fwd.h"
|
||||||
|
|
@ -203,6 +204,7 @@ fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *))
|
||||||
else if(fptr == &val_neg_zone_compare) return 1;
|
else if(fptr == &val_neg_zone_compare) return 1;
|
||||||
else if(fptr == &probetree_cmp) return 1;
|
else if(fptr == &probetree_cmp) return 1;
|
||||||
else if(fptr == &replay_var_compare) return 1;
|
else if(fptr == &replay_var_compare) return 1;
|
||||||
|
else if(fptr == &view_cmp) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue