- local-zone-override config directive.

git-svn-id: file:///svn/unbound/trunk@3758 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards
2016-06-06 10:00:25 +00:00
parent 44889af074
commit 65bcb9b0ca
11 changed files with 1875 additions and 1626 deletions
+1
View File
@@ -1,6 +1,7 @@
6 June 2016: Wouter
- Better help text from -h (from Ray Griffith).
- access-control-tag config directive.
- local-zone-override config directive.
3 June 2016: Wouter
- Fix to not ignore return value of chown() in daemon startup.
+3
View File
@@ -588,6 +588,9 @@ server:
# tag a localzone with a list of tag names (in "" with spaces between)
# local-zone-tag: "example.com" "tag2 tag3"
# add a netblock specific override to a localzone, with zone type
# local-zone-override: "example.com" 192.0.2.0/24 refuse
# service clients over SSL (on the TCP sockets), with plain DNS inside
# the SSL stream. Give the certificate to use and private key.
# default is "" (disabled). requires restart to take effect.
+103
View File
@@ -542,6 +542,89 @@ lz_enter_zone_tag(struct local_zones* zones, char* zname, uint8_t* list,
return r;
}
/** enter override into zone */
static int
lz_enter_override(struct local_zones* zones, char* zname, char* netblock,
char* type, uint16_t rr_class)
{
uint8_t dname[LDNS_MAX_DOMAINLEN+1];
size_t dname_len = sizeof(dname);
int dname_labs;
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
struct local_zone* z;
enum localzone_type t;
/* parse zone name */
if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) {
log_err("cannot parse zone name in local-zone-override: %s %s",
zname, netblock);
return 0;
}
dname_labs = dname_count_labels(dname);
/* parse netblock */
if(!netblockstrtoaddr(netblock, UNBOUND_DNS_PORT, &addr, &addrlen,
&net)) {
log_err("cannot parse netblock in local-zone-override: %s %s",
zname, netblock);
return 0;
}
/* parse zone type */
if(!local_zone_str2type(type, &t)) {
log_err("cannot parse type in local-zone-override: %s %s %s",
zname, netblock, type);
return 0;
}
/* find localzone entry */
lock_rw_rdlock(&zones->lock);
z = local_zones_lookup(zones, dname, dname_len, dname_labs, rr_class);
if(!z) {
lock_rw_unlock(&zones->lock);
log_err("no local-zone for local-zone-override %s", zname);
return 0;
}
lock_rw_wrlock(&z->lock);
lock_rw_unlock(&zones->lock);
/* create netblock addr_tree if not present yet */
if(!z->override_tree) {
z->override_tree = (struct rbtree_t*)regional_alloc_zero(
z->region, sizeof(*z->override_tree));
if(!z->override_tree) {
lock_rw_unlock(&z->lock);
log_err("out of memory");
return 0;
}
addr_tree_init(z->override_tree);
}
/* add new elem to tree */
if(z->override_tree) {
struct local_zone_override* n;
n = (struct local_zone_override*)regional_alloc_zero(
z->region, sizeof(*n));
if(!n) {
lock_rw_unlock(&z->lock);
log_err("out of memory");
return 0;
}
n->type = t;
if(!addr_tree_insert(z->override_tree,
(struct addr_tree_node*)n, &addr, addrlen, net)) {
lock_rw_unlock(&z->lock);
log_err("duplicate local-zone-override %s %s",
zname, netblock);
return 0;
}
}
lock_rw_unlock(&z->lock);
return 1;
}
/** parse local-zone: statements */
static int
lz_enter_zones(struct local_zones* zones, struct config_file* cfg)
@@ -720,6 +803,19 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg)
return 1;
}
/** parse local-zone-override: statements */
static int
lz_enter_overrides(struct local_zones* zones, struct config_file* cfg)
{
struct config_str3list* p;
for(p = cfg->local_zone_overrides; p; p = p->next) {
if(!lz_enter_override(zones, p->str, p->str2, p->str3,
LDNS_RR_CLASS_IN))
return 0;
}
return 1;
}
/** setup parent pointers, so that a lookup can be done for closest match */
static void
init_parents(struct local_zones* zones)
@@ -749,6 +845,9 @@ init_parents(struct local_zones* zones)
break;
}
prev = node;
if(node->override_tree)
addr_tree_init_parents(node->override_tree);
lock_rw_unlock(&node->lock);
}
lock_rw_unlock(&zones->lock);
@@ -887,6 +986,10 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
if(!lz_enter_defaults(zones, cfg)) {
return 0;
}
/* enter local zone overrides */
if(!lz_enter_overrides(zones, cfg)) {
return 0;
}
/* create implicit transparent zone from data. */
if(!lz_setup_implicit(zones, cfg)) {
return 0;
+14
View File
@@ -43,6 +43,7 @@
#define SERVICES_LOCALZONE_H
#include "util/rbtree.h"
#include "util/locks.h"
#include "util/storage/dnstree.h"
struct ub_packed_rrset_key;
struct regional;
struct config_file;
@@ -119,6 +120,9 @@ struct local_zone {
uint8_t* taglist;
/** length of the taglist (in bytes) */
size_t taglen;
/** netblock addr_tree with struct local_zone_override information
* or NULL if there are no override elements */
struct rbtree_t* override_tree;
/** in this region the zone's data is allocated.
* the struct local_zone itself is malloced. */
@@ -157,6 +161,16 @@ struct local_rrset {
struct ub_packed_rrset_key* rrset;
};
/**
* Local zone override information
*/
struct local_zone_override {
/** node in addrtree */
struct addr_tree_node node;
/** override for local zone type */
enum localzone_type type;
};
/**
* Create local zones storage
* @return new struct or NULL on error.
+43
View File
@@ -212,6 +212,7 @@ config_create(void)
cfg->local_zones = NULL;
cfg->local_zones_nodefault = NULL;
cfg->local_data = NULL;
cfg->local_zone_overrides = NULL;
cfg->unblock_lan_zones = 0;
cfg->insecure_lan_zones = 0;
cfg->python_script = NULL;
@@ -640,6 +641,14 @@ config_collate_cat(struct config_strlist* list)
func(buf, arg); \
} \
}
/** compare and print list option */
#define O_LS3(opt, name, lst) if(strcmp(opt, name)==0) { \
struct config_str3list* p = cfg->lst; \
for(p = cfg->lst; p; p = p->next) { \
snprintf(buf, len, "%s %s %s", p->str, p->str2, p->str3); \
func(buf, arg); \
} \
}
/** compare and print taglist option */
#define O_LTG(opt, name, lst) if(strcmp(opt, name)==0) { \
char* tmpstr = NULL; \
@@ -785,6 +794,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_IFC(opt, "define-tag", num_tags, tagname)
else O_LTG(opt, "local-zone-tag", local_zone_tags)
else O_LTG(opt, "access-control-tag", acl_tags)
else O_LS3(opt, "local-zone-override", local_zone_overrides)
/* not here:
* outgoing-permit, outgoing-avoid - have list of ports
* local-zone - zones and nodefault variables
@@ -936,6 +946,20 @@ config_deldblstrlist(struct config_str2list* p)
}
}
void
config_deltrplstrlist(struct config_str3list* p)
{
struct config_str3list *np;
while(p) {
np = p->next;
free(p->str);
free(p->str2);
free(p->str3);
free(p);
p = np;
}
}
void
config_delstub(struct config_stub* p)
{
@@ -1021,6 +1045,7 @@ config_delete(struct config_file* cfg)
config_deldblstrlist(cfg->local_zones);
config_delstrlist(cfg->local_zones_nodefault);
config_delstrlist(cfg->local_data);
config_deltrplstrlist(cfg->local_zone_overrides);
config_del_strarray(cfg->tagname, cfg->num_tags);
config_del_strbytelist(cfg->local_zone_tags);
config_del_strbytelist(cfg->acl_tags);
@@ -1212,6 +1237,24 @@ cfg_str2list_insert(struct config_str2list** head, char* item, char* i2)
return 1;
}
int
cfg_str3list_insert(struct config_str3list** head, char* item, char* i2,
char* i3)
{
struct config_str3list *s;
if(!item || !i2 || !i3 || !head)
return 0;
s = (struct config_str3list*)calloc(1, sizeof(struct config_str3list));
if(!s)
return 0;
s->str = item;
s->str2 = i2;
s->str3 = i3;
s->next = *head;
*head = s;
return 1;
}
int
cfg_strbytelist_insert(struct config_strbytelist** head, char* item,
uint8_t* i2, size_t i2len)
+36 -1
View File
@@ -44,6 +44,7 @@
struct config_stub;
struct config_strlist;
struct config_str2list;
struct config_str3list;
struct config_strbytelist;
struct module_qstate;
struct sock_list;
@@ -292,6 +293,8 @@ struct config_file {
struct config_strlist* local_zones_nodefault;
/** local data RRs configured */
struct config_strlist* local_data;
/** local zone override types per netblock */
struct config_str3list* local_zone_overrides;
/** unblock lan zones (reverse lookups for AS112 zones) */
int unblock_lan_zones;
/** insecure lan zones (don't validate AS112 zones) */
@@ -435,6 +438,21 @@ struct config_str2list {
char* str2;
};
/**
* List of three strings for config options
*/
struct config_str3list {
/** next item in list */
struct config_str3list* next;
/** first string */
char* str;
/** second string */
char* str2;
/** third string */
char* str3;
};
/**
* List of string, bytestring for config options
*/
@@ -586,9 +604,20 @@ int cfg_strlist_insert(struct config_strlist** head, char* item);
*/
int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2);
/**
* Insert string into str3list.
* @param head: pointer to str3list head variable.
* @param item: new item. malloced by caller. If NULL the insertion fails.
* @param i2: 2nd string, malloced by caller. If NULL the insertion fails.
* @param i3: 3rd string, malloced by caller. If NULL the insertion fails.
* @return: true on success.
*/
int cfg_str3list_insert(struct config_str3list** head, char* item, char* i2,
char* i3);
/**
* Insert string into strbytelist.
* @param head: pointer to str2list head variable.
* @param head: pointer to strbytelist head variable.
* @param item: new item. malloced by caller. If NULL the insertion fails.
* @param i2: 2nd string, malloced by caller. If NULL the insertion fails.
* @param i2len: length of the i2 bytestring.
@@ -620,6 +649,12 @@ void config_delstrlist(struct config_strlist* list);
*/
void config_deldblstrlist(struct config_str2list* list);
/**
* Delete items in config triple string list.
* @param list: list.
*/
void config_deltrplstrlist(struct config_str3list* list);
/**
* Delete a stub item
* @param p: stub item
+933 -920
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -346,6 +346,7 @@ dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) }
define-tag{COLON} { YDVAR(1, VAR_DEFINE_TAG) }
local-zone-tag{COLON} { YDVAR(2, VAR_LOCAL_ZONE_TAG) }
access-control-tag{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_TAG) }
local-zone-override{COLON} { YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) }
dnstap{COLON} { YDVAR(0, VAR_DNSTAP) }
dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) }
dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) }
+721 -700
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -212,7 +212,8 @@ extern int yydebug;
VAR_IP_FREEBIND = 422,
VAR_DEFINE_TAG = 423,
VAR_LOCAL_ZONE_TAG = 424,
VAR_ACCESS_CONTROL_TAG = 425
VAR_ACCESS_CONTROL_TAG = 425,
VAR_LOCAL_ZONE_OVERRIDE = 426
};
#endif
/* Tokens. */
@@ -384,6 +385,7 @@ extern int yydebug;
#define VAR_DEFINE_TAG 423
#define VAR_LOCAL_ZONE_TAG 424
#define VAR_ACCESS_CONTROL_TAG 425
#define VAR_LOCAL_ZONE_OVERRIDE 426
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@@ -394,7 +396,7 @@ union YYSTYPE
char* str;
#line 398 "util/configparser.h" /* yacc.c:1909 */
#line 400 "util/configparser.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;
+16 -3
View File
@@ -126,7 +126,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR
%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
%token VAR_QNAME_MINIMISATION VAR_IP_FREEBIND VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG
%token VAR_ACCESS_CONTROL_TAG
%token VAR_ACCESS_CONTROL_TAG VAR_LOCAL_ZONE_OVERRIDE
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -195,7 +195,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_caps_whitelist | server_cache_max_negative_ttl |
server_permit_small_holddown | server_qname_minimisation |
server_ip_freebind | server_define_tag | server_local_zone_tag |
server_disable_dnssec_lame_check | access_control_tag
server_disable_dnssec_lame_check | server_access_control_tag |
server_local_zone_override
;
stubstart: VAR_STUB_ZONE
{
@@ -1333,7 +1334,7 @@ server_local_zone_tag: VAR_LOCAL_ZONE_TAG STRING_ARG STRING_ARG
}
}
;
access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG
server_access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG
{
size_t len = 0;
uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3,
@@ -1352,6 +1353,18 @@ access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG
}
}
;
server_local_zone_override: VAR_LOCAL_ZONE_OVERRIDE STRING_ARG STRING_ARG STRING_ARG
{
OUTYY(("P(server_local_zone_override:%s %s %s)\n", $2, $3, $4));
if(!cfg_str3list_insert(&cfg_parser->cfg->local_zone_overrides,
$2, $3, $4)) {
yyerror("out of memory");
free($2);
free($3);
free($4);
}
}
;
server_ratelimit: VAR_RATELIMIT STRING_ARG
{
OUTYY(("P(server_ratelimit:%s)\n", $2));