mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-09-23 18:24:58 +02:00
- local-zone-override config directive.
git-svn-id: file:///svn/unbound/trunk@3758 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
File diff suppressed because it is too large
Load Diff
+4
-2
@@ -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
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user