- Added domain name based ECS whitelist.

git-svn-id: file:///svn/unbound/trunk@4217 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Ralph Dolmans 2017-06-08 14:44:55 +00:00
parent e2459be7e1
commit 998793998d
13 changed files with 2439 additions and 2331 deletions

View File

@ -1,3 +1,6 @@
8 June 2017: Ralph
- Added domain name based ECS whitelist.
8 June 2017: Wouter
- Detect chacha for dnscrypt at configure time.
- dnscrypt unit tests with chacha.

View File

@ -1515,7 +1515,12 @@ entries will be purged from cache.
Send client source address to this authority. Append /num to indicate a
classless delegation netblock, for example like 10.2.3.4/24 or 2001::11/64. Can
be given multiple times. Authorities not listed will not receive edns-subnet
information.
information, unless domain in query is specified in \fBclient\-subnet\-zone\fR.
.TP
.B client\-subnet\-zone: \fI<domain>\fR
Send client source address in queries for this domain and its subdomains. Can be
given multiple times. Zones not listed will not receive edns-subnet information,
unless hosted by authority specified in \fBsend\-client\-subnet\fR.
.TP
.B client\-subnet\-always\-forward: \fI<yes or no>\fR
Specify whether the ECS whitelist check (configured using

View File

@ -50,42 +50,44 @@
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/storage/dnstree.h"
#include "sldns/str2wire.h"
#include "util/data/dname.h"
struct ednssubnet_upstream*
upstream_create(void)
struct ecs_whitelist*
ecs_whitelist_create(void)
{
struct ednssubnet_upstream* upstream =
(struct ednssubnet_upstream*)calloc(1,
sizeof(struct ednssubnet_upstream));
if(!upstream)
struct ecs_whitelist* whitelist =
(struct ecs_whitelist*)calloc(1,
sizeof(struct ecs_whitelist));
if(!whitelist)
return NULL;
upstream->region = regional_create();
if(!upstream->region) {
upstream_delete(upstream);
whitelist->region = regional_create();
if(!whitelist->region) {
ecs_whitelist_delete(whitelist);
return NULL;
}
return upstream;
return whitelist;
}
void
upstream_delete(struct ednssubnet_upstream* upstream)
ecs_whitelist_delete(struct ecs_whitelist* whitelist)
{
if(!upstream)
if(!whitelist)
return;
regional_destroy(upstream->region);
free(upstream);
regional_destroy(whitelist->region);
free(whitelist);
}
/** insert new address into upstream structure */
/** insert new address into whitelist structure */
static int
upstream_insert(struct ednssubnet_upstream* upstream,
upstream_insert(struct ecs_whitelist* whitelist,
struct sockaddr_storage* addr, socklen_t addrlen, int net)
{
struct addr_tree_node* node = (struct addr_tree_node*)regional_alloc(
upstream->region, sizeof(*node));
whitelist->region, sizeof(*node));
if(!node)
return 0;
if(!addr_tree_insert(&upstream->tree, node, addr, addrlen, net)) {
if(!addr_tree_insert(&whitelist->upstream, node, addr, addrlen, net)) {
verbose(VERB_QUERY,
"duplicate send-client-subnet address ignored.");
}
@ -94,7 +96,7 @@ upstream_insert(struct ednssubnet_upstream* upstream,
/** apply edns-subnet string */
static int
upstream_str_cfg(struct ednssubnet_upstream* upstream, const char* str)
upstream_str_cfg(struct ecs_whitelist* whitelist, const char* str)
{
struct sockaddr_storage addr;
int net;
@ -104,7 +106,7 @@ upstream_str_cfg(struct ednssubnet_upstream* upstream, const char* str)
log_err("cannot parse send-client-subnet netblock: %s", str);
return 0;
}
if(!upstream_insert(upstream, &addr, addrlen, net)) {
if(!upstream_insert(whitelist, &addr, addrlen, net)) {
log_err("out of memory");
return 0;
}
@ -113,41 +115,93 @@ upstream_str_cfg(struct ednssubnet_upstream* upstream, const char* str)
/** read client_subnet config */
static int
read_upstream(struct ednssubnet_upstream* upstream, struct config_file* cfg)
read_upstream(struct ecs_whitelist* whitelist, struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->client_subnet; p; p = p->next) {
log_assert(p->str);
if(!upstream_str_cfg(upstream, p->str))
if(!upstream_str_cfg(whitelist, p->str))
return 0;
}
return 1;
}
int
upstream_apply_cfg(struct ednssubnet_upstream* upstream,
struct config_file* cfg)
/** read client_subnet_zone config */
static int
read_names(struct ecs_whitelist* whitelist, struct config_file* cfg)
{
regional_free_all(upstream->region);
addr_tree_init(&upstream->tree);
if(!read_upstream(upstream, cfg))
return 0;
addr_tree_init_parents(&upstream->tree);
/* parse names, report errors, insert into tree */
struct config_strlist* p;
struct name_tree_node* n;
uint8_t* nm, *nmr;
size_t nm_len;
int nm_labs;
for(p = cfg->client_subnet_zone; p; p = p->next) {
log_assert(p->str);
nm = sldns_str2wire_dname(p->str, &nm_len);
if(!nm) {
log_err("cannot parse client-subnet-zone: %s", p->str);
return 0;
}
nm_labs = dname_count_size_labels(nm, &nm_len);
nmr = (uint8_t*)regional_alloc_init(whitelist->region, nm,
nm_len);
free(nm);
if(!nmr) {
log_err("out of memory");
return 0;
}
n = (struct name_tree_node*)regional_alloc(whitelist->region,
sizeof(*n));
if(!n) {
log_err("out of memory");
return 0;
}
if(!name_tree_insert(&whitelist->dname, n, nmr, nm_len, nm_labs,
LDNS_RR_CLASS_IN)) {
verbose(VERB_QUERY, "ignoring duplicate "
"client-subnet-zone: %s", p->str);
}
}
return 1;
}
int
upstream_is_whitelisted(struct ednssubnet_upstream* upstream,
struct sockaddr_storage* addr, socklen_t addrlen)
ecs_whitelist_apply_cfg(struct ecs_whitelist* whitelist,
struct config_file* cfg)
{
return addr_tree_lookup(&upstream->tree, addr, addrlen) != NULL;
regional_free_all(whitelist->region);
addr_tree_init(&whitelist->upstream);
name_tree_init(&whitelist->dname);
if(!read_upstream(whitelist, cfg))
return 0;
if(!read_names(whitelist, cfg))
return 0;
addr_tree_init_parents(&whitelist->upstream);
name_tree_init_parents(&whitelist->dname);
return 1;
}
int
ecs_is_whitelisted(struct ecs_whitelist* whitelist,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* qname,
size_t qname_len, uint16_t qclass)
{
int labs;
if(addr_tree_lookup(&whitelist->upstream, addr, addrlen))
return 1;
/* Not in upstream whitelist, check dname whitelist. */
labs = dname_count_labels(qname);
return name_tree_lookup(&whitelist->dname, qname, qname_len, labs,
qclass) != NULL;
}
size_t
upstream_get_mem(struct ednssubnet_upstream* upstream)
ecs_whitelist_get_mem(struct ecs_whitelist* whitelist)
{
if(!upstream) return 0;
return sizeof(*upstream) + regional_get_mem(upstream->region);
if(!whitelist) return 0;
return sizeof(*whitelist) + regional_get_mem(whitelist->region);
}
#endif /* CLIENT_SUBNET */

View File

@ -36,8 +36,8 @@
/**
* \file
*
* Keep track of the white listed servers for subnet option. Based
* on acl_list.c|h
* Keep track of the white listed servers and domain names for subnet option.
* Based on acl_list.c|h
*/
#ifndef EDNSSUBNET_WHITELIST_H
@ -48,9 +48,9 @@ struct config_file;
struct regional;
/**
* ednssubnet_upstream structure
* ecs_whitelist structure
*/
struct ednssubnet_upstream {
struct ecs_whitelist {
/** regional for allocation */
struct regional* region;
/**
@ -58,45 +58,54 @@ struct ednssubnet_upstream {
* contents of type addr_tree_node. Each node is an address span
* Unbound will append subnet option for.
*/
rbtree_type tree;
rbtree_type upstream;
/**
* Tree of domain names for which Unbound will append an ECS option.
* rbtree of struct name_tree_node.
*/
rbtree_type dname;
};
/**
* Create ednssubnet_upstream structure
* Create ecs_whitelist structure
* @return new structure or NULL on error.
*/
struct ednssubnet_upstream* upstream_create(void);
struct ecs_whitelist* ecs_whitelist_create(void);
/**
* Delete ednssubnet_upstream structure.
* @param upstream: to delete.
* Delete ecs_whitelist structure.
* @param whitelist: to delete.
*/
void upstream_delete(struct ednssubnet_upstream* upstream);
void ecs_whitelist_delete(struct ecs_whitelist* whitelist);
/**
* Process ednssubnet_upstream config.
* @param upstream: where to store.
* Process ecs_whitelist config.
* @param whitelist: where to store.
* @param cfg: config options.
* @return 0 on error.
*/
int upstream_apply_cfg(struct ednssubnet_upstream* upstream,
int ecs_whitelist_apply_cfg(struct ecs_whitelist* whitelist,
struct config_file* cfg);
/**
* See if an address is whitelisted.
* @param upstream: structure for address storage.
* See if an address or domain is whitelisted.
* @param whitelist: structure for address storage.
* @param addr: address to check
* @param addrlen: length of addr.
* @param qname: dname in query
* @param qname_len: length of dname
* @param qclass: class in query
* @return: true if the address is whitelisted for subnet option.
*/
int upstream_is_whitelisted(struct ednssubnet_upstream* upstream,
struct sockaddr_storage* addr, socklen_t addrlen);
int ecs_is_whitelisted(struct ecs_whitelist* whitelist,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* qname,
size_t qname_len, uint16_t qclass);
/**
* Get memory used by ednssubnet_upstream structure.
* @param upstream: structure for address storage.
* Get memory used by ecs_whitelist structure.
* @param whitelist: structure for address storage.
* @return bytes in use.
*/
size_t upstream_get_mem(struct ednssubnet_upstream* upstream);
size_t ecs_whitelist_get_mem(struct ecs_whitelist* whitelist);
#endif /* EDNSSUBNET_WHITELIST_H */

View File

@ -135,7 +135,7 @@ ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list,
}
}
int ecs_whitelist_check(struct query_info* ATTR_UNUSED(qinfo),
int ecs_whitelist_check(struct query_info* qinfo,
uint16_t ATTR_UNUSED(flags), struct module_qstate* qstate,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
@ -154,8 +154,9 @@ int ecs_whitelist_check(struct query_info* ATTR_UNUSED(qinfo),
if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream &&
qstate->env->cfg->client_subnet_always_forward) ||
upstream_is_whitelisted(sn_env->edns_subnet_upstreams,
addr, addrlen))) {
ecs_is_whitelisted(sn_env->whitelist,
addr, addrlen, qinfo->qname, qinfo->qname_len,
qinfo->qclass))) {
/* Address on whitelist or client query contains ECS option, we
* want to sent out ECS. Only add option if it is not already
* set. */
@ -199,9 +200,9 @@ subnetmod_init(struct module_env *env, int id)
return 0;
}
/* whitelist for edns subnet capable servers */
sn_env->edns_subnet_upstreams = upstream_create();
if(!sn_env->edns_subnet_upstreams ||
!upstream_apply_cfg(sn_env->edns_subnet_upstreams, env->cfg)) {
sn_env->whitelist = ecs_whitelist_create();
if(!sn_env->whitelist ||
!ecs_whitelist_apply_cfg(sn_env->whitelist, env->cfg)) {
log_err("subnet: could not create ECS whitelist");
slabhash_delete(sn_env->subnet_msg_cache);
free(sn_env);
@ -217,7 +218,7 @@ subnetmod_init(struct module_env *env, int id)
env->cfg->client_subnet_always_forward /* bypass cache */,
0 /* no aggregation */, env)) {
log_err("subnet: could not register opcode");
upstream_delete(sn_env->edns_subnet_upstreams);
ecs_whitelist_delete(sn_env->whitelist);
slabhash_delete(sn_env->subnet_msg_cache);
free(sn_env);
env->modinfo[id] = NULL;
@ -243,7 +244,7 @@ subnetmod_deinit(struct module_env *env, int id)
lock_rw_destroy(&sn_env->biglock);
inplace_cb_delete(env, inplace_cb_edns_back_parsed, id);
inplace_cb_delete(env, inplace_cb_query, id);
upstream_delete(sn_env->edns_subnet_upstreams);
ecs_whitelist_delete(sn_env->whitelist);
slabhash_delete(sn_env->subnet_msg_cache);
alloc_clear(&sn_env->alloc);
free(sn_env);
@ -781,7 +782,7 @@ subnetmod_get_mem(struct module_env *env, int id)
if (!sn_env) return 0;
return sizeof(*sn_env) +
slabhash_get_mem(sn_env->subnet_msg_cache) +
upstream_get_mem(sn_env->edns_subnet_upstreams);
ecs_whitelist_get_mem(sn_env->whitelist);
}
/**

View File

@ -57,7 +57,7 @@ struct subnet_env {
* data: struct subnet_msg_cache_data* */
struct slabhash* subnet_msg_cache;
/** access control, which upstream servers we send client address */
struct ednssubnet_upstream* edns_subnet_upstreams;
struct ecs_whitelist* whitelist;
/** allocation service */
struct alloc_cache alloc;
lock_rw_type biglock;

View File

@ -178,6 +178,7 @@ config_create(void)
cfg->forwards = NULL;
#ifdef CLIENT_SUBNET
cfg->client_subnet = NULL;
cfg->client_subnet_zone = NULL;
cfg->client_subnet_opcode = LDNS_EDNS_CLIENT_SUBNET;
cfg->client_subnet_always_forward = 0;
cfg->max_client_subnet_ipv4 = 24;
@ -889,6 +890,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin)
#ifdef CLIENT_SUBNET
else O_LST(opt, "send-client-subnet", client_subnet)
else O_LST(opt, "client-subnet-zone", client_subnet_zone)
else O_DEC(opt, "max-client-subnet-ipv4", max_client_subnet_ipv4)
else O_DEC(opt, "max-client-subnet-ipv6", max_client_subnet_ipv6)
else O_YNO(opt, "client-subnet-always-forward:",
@ -1213,6 +1215,7 @@ config_delete(struct config_file* cfg)
config_delstrlist(cfg->root_hints);
#ifdef CLIENT_SUBNET
config_delstrlist(cfg->client_subnet);
config_delstrlist(cfg->client_subnet_zone);
#endif
free(cfg->identity);
free(cfg->version);

View File

@ -176,6 +176,8 @@ struct config_file {
/** list of servers we send edns-client-subnet option to and
* accept option from, linked list */
struct config_strlist* client_subnet;
/** list of zones we send edns-client-subnet option for */
struct config_strlist* client_subnet_zone;
/** opcode assigned by IANA for edns0-client-subnet option */
uint16_t client_subnet_opcode;
/** Do not check whitelist if incoming query contains an ECS record */

File diff suppressed because it is too large Load Diff

View File

@ -301,6 +301,7 @@ do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }
do-not-query-localhost{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) }
access-control{COLON} { YDVAR(2, VAR_ACCESS_CONTROL) }
send-client-subnet{COLON} { YDVAR(1, VAR_SEND_CLIENT_SUBNET) }
client-subnet-zone{COLON} { YDVAR(1, VAR_CLIENT_SUBNET_ZONE) }
client-subnet-always-forward{COLON} { YDVAR(1, VAR_CLIENT_SUBNET_ALWAYS_FORWARD) }
client-subnet-opcode{COLON} { YDVAR(1, VAR_CLIENT_SUBNET_OPCODE) }
max-client-subnet-ipv4{COLON} { YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV4) }

File diff suppressed because it is too large Load Diff

View File

@ -217,46 +217,47 @@ extern int yydebug;
VAR_IP_RATELIMIT_FACTOR = 427,
VAR_RATELIMIT_FACTOR = 428,
VAR_SEND_CLIENT_SUBNET = 429,
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 430,
VAR_CLIENT_SUBNET_OPCODE = 431,
VAR_MAX_CLIENT_SUBNET_IPV4 = 432,
VAR_MAX_CLIENT_SUBNET_IPV6 = 433,
VAR_CAPS_WHITELIST = 434,
VAR_CACHE_MAX_NEGATIVE_TTL = 435,
VAR_PERMIT_SMALL_HOLDDOWN = 436,
VAR_QNAME_MINIMISATION = 437,
VAR_QNAME_MINIMISATION_STRICT = 438,
VAR_IP_FREEBIND = 439,
VAR_DEFINE_TAG = 440,
VAR_LOCAL_ZONE_TAG = 441,
VAR_ACCESS_CONTROL_TAG = 442,
VAR_LOCAL_ZONE_OVERRIDE = 443,
VAR_ACCESS_CONTROL_TAG_ACTION = 444,
VAR_ACCESS_CONTROL_TAG_DATA = 445,
VAR_VIEW = 446,
VAR_ACCESS_CONTROL_VIEW = 447,
VAR_VIEW_FIRST = 448,
VAR_SERVE_EXPIRED = 449,
VAR_FAKE_DSA = 450,
VAR_FAKE_SHA1 = 451,
VAR_LOG_IDENTITY = 452,
VAR_HIDE_TRUSTANCHOR = 453,
VAR_TRUST_ANCHOR_SIGNALING = 454,
VAR_USE_SYSTEMD = 455,
VAR_SHM_ENABLE = 456,
VAR_SHM_KEY = 457,
VAR_DNSCRYPT = 458,
VAR_DNSCRYPT_ENABLE = 459,
VAR_DNSCRYPT_PORT = 460,
VAR_DNSCRYPT_PROVIDER = 461,
VAR_DNSCRYPT_SECRET_KEY = 462,
VAR_DNSCRYPT_PROVIDER_CERT = 463,
VAR_IPSECMOD_ENABLED = 464,
VAR_IPSECMOD_HOOK = 465,
VAR_IPSECMOD_IGNORE_BOGUS = 466,
VAR_IPSECMOD_MAX_TTL = 467,
VAR_IPSECMOD_WHITELIST = 468,
VAR_IPSECMOD_STRICT = 469
VAR_CLIENT_SUBNET_ZONE = 430,
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 431,
VAR_CLIENT_SUBNET_OPCODE = 432,
VAR_MAX_CLIENT_SUBNET_IPV4 = 433,
VAR_MAX_CLIENT_SUBNET_IPV6 = 434,
VAR_CAPS_WHITELIST = 435,
VAR_CACHE_MAX_NEGATIVE_TTL = 436,
VAR_PERMIT_SMALL_HOLDDOWN = 437,
VAR_QNAME_MINIMISATION = 438,
VAR_QNAME_MINIMISATION_STRICT = 439,
VAR_IP_FREEBIND = 440,
VAR_DEFINE_TAG = 441,
VAR_LOCAL_ZONE_TAG = 442,
VAR_ACCESS_CONTROL_TAG = 443,
VAR_LOCAL_ZONE_OVERRIDE = 444,
VAR_ACCESS_CONTROL_TAG_ACTION = 445,
VAR_ACCESS_CONTROL_TAG_DATA = 446,
VAR_VIEW = 447,
VAR_ACCESS_CONTROL_VIEW = 448,
VAR_VIEW_FIRST = 449,
VAR_SERVE_EXPIRED = 450,
VAR_FAKE_DSA = 451,
VAR_FAKE_SHA1 = 452,
VAR_LOG_IDENTITY = 453,
VAR_HIDE_TRUSTANCHOR = 454,
VAR_TRUST_ANCHOR_SIGNALING = 455,
VAR_USE_SYSTEMD = 456,
VAR_SHM_ENABLE = 457,
VAR_SHM_KEY = 458,
VAR_DNSCRYPT = 459,
VAR_DNSCRYPT_ENABLE = 460,
VAR_DNSCRYPT_PORT = 461,
VAR_DNSCRYPT_PROVIDER = 462,
VAR_DNSCRYPT_SECRET_KEY = 463,
VAR_DNSCRYPT_PROVIDER_CERT = 464,
VAR_IPSECMOD_ENABLED = 465,
VAR_IPSECMOD_HOOK = 466,
VAR_IPSECMOD_IGNORE_BOGUS = 467,
VAR_IPSECMOD_MAX_TTL = 468,
VAR_IPSECMOD_WHITELIST = 469,
VAR_IPSECMOD_STRICT = 470
};
#endif
/* Tokens. */
@ -432,46 +433,47 @@ extern int yydebug;
#define VAR_IP_RATELIMIT_FACTOR 427
#define VAR_RATELIMIT_FACTOR 428
#define VAR_SEND_CLIENT_SUBNET 429
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 430
#define VAR_CLIENT_SUBNET_OPCODE 431
#define VAR_MAX_CLIENT_SUBNET_IPV4 432
#define VAR_MAX_CLIENT_SUBNET_IPV6 433
#define VAR_CAPS_WHITELIST 434
#define VAR_CACHE_MAX_NEGATIVE_TTL 435
#define VAR_PERMIT_SMALL_HOLDDOWN 436
#define VAR_QNAME_MINIMISATION 437
#define VAR_QNAME_MINIMISATION_STRICT 438
#define VAR_IP_FREEBIND 439
#define VAR_DEFINE_TAG 440
#define VAR_LOCAL_ZONE_TAG 441
#define VAR_ACCESS_CONTROL_TAG 442
#define VAR_LOCAL_ZONE_OVERRIDE 443
#define VAR_ACCESS_CONTROL_TAG_ACTION 444
#define VAR_ACCESS_CONTROL_TAG_DATA 445
#define VAR_VIEW 446
#define VAR_ACCESS_CONTROL_VIEW 447
#define VAR_VIEW_FIRST 448
#define VAR_SERVE_EXPIRED 449
#define VAR_FAKE_DSA 450
#define VAR_FAKE_SHA1 451
#define VAR_LOG_IDENTITY 452
#define VAR_HIDE_TRUSTANCHOR 453
#define VAR_TRUST_ANCHOR_SIGNALING 454
#define VAR_USE_SYSTEMD 455
#define VAR_SHM_ENABLE 456
#define VAR_SHM_KEY 457
#define VAR_DNSCRYPT 458
#define VAR_DNSCRYPT_ENABLE 459
#define VAR_DNSCRYPT_PORT 460
#define VAR_DNSCRYPT_PROVIDER 461
#define VAR_DNSCRYPT_SECRET_KEY 462
#define VAR_DNSCRYPT_PROVIDER_CERT 463
#define VAR_IPSECMOD_ENABLED 464
#define VAR_IPSECMOD_HOOK 465
#define VAR_IPSECMOD_IGNORE_BOGUS 466
#define VAR_IPSECMOD_MAX_TTL 467
#define VAR_IPSECMOD_WHITELIST 468
#define VAR_IPSECMOD_STRICT 469
#define VAR_CLIENT_SUBNET_ZONE 430
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 431
#define VAR_CLIENT_SUBNET_OPCODE 432
#define VAR_MAX_CLIENT_SUBNET_IPV4 433
#define VAR_MAX_CLIENT_SUBNET_IPV6 434
#define VAR_CAPS_WHITELIST 435
#define VAR_CACHE_MAX_NEGATIVE_TTL 436
#define VAR_PERMIT_SMALL_HOLDDOWN 437
#define VAR_QNAME_MINIMISATION 438
#define VAR_QNAME_MINIMISATION_STRICT 439
#define VAR_IP_FREEBIND 440
#define VAR_DEFINE_TAG 441
#define VAR_LOCAL_ZONE_TAG 442
#define VAR_ACCESS_CONTROL_TAG 443
#define VAR_LOCAL_ZONE_OVERRIDE 444
#define VAR_ACCESS_CONTROL_TAG_ACTION 445
#define VAR_ACCESS_CONTROL_TAG_DATA 446
#define VAR_VIEW 447
#define VAR_ACCESS_CONTROL_VIEW 448
#define VAR_VIEW_FIRST 449
#define VAR_SERVE_EXPIRED 450
#define VAR_FAKE_DSA 451
#define VAR_FAKE_SHA1 452
#define VAR_LOG_IDENTITY 453
#define VAR_HIDE_TRUSTANCHOR 454
#define VAR_TRUST_ANCHOR_SIGNALING 455
#define VAR_USE_SYSTEMD 456
#define VAR_SHM_ENABLE 457
#define VAR_SHM_KEY 458
#define VAR_DNSCRYPT 459
#define VAR_DNSCRYPT_ENABLE 460
#define VAR_DNSCRYPT_PORT 461
#define VAR_DNSCRYPT_PROVIDER 462
#define VAR_DNSCRYPT_SECRET_KEY 463
#define VAR_DNSCRYPT_PROVIDER_CERT 464
#define VAR_IPSECMOD_ENABLED 465
#define VAR_IPSECMOD_HOOK 466
#define VAR_IPSECMOD_IGNORE_BOGUS 467
#define VAR_IPSECMOD_MAX_TTL 468
#define VAR_IPSECMOD_WHITELIST 469
#define VAR_IPSECMOD_STRICT 470
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@ -482,7 +484,7 @@ union YYSTYPE
char* str;
#line 486 "util/configparser.h" /* yacc.c:1909 */
#line 488 "util/configparser.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;

View File

@ -131,8 +131,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE
%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN
%token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR
%token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ALWAYS_FORWARD
%token VAR_CLIENT_SUBNET_OPCODE
%token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ZONE
%token VAR_CLIENT_SUBNET_ALWAYS_FORWARD VAR_CLIENT_SUBNET_OPCODE
%token VAR_MAX_CLIENT_SUBNET_IPV4 VAR_MAX_CLIENT_SUBNET_IPV6
%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
%token VAR_QNAME_MINIMISATION VAR_QNAME_MINIMISATION_STRICT VAR_IP_FREEBIND
@ -217,7 +217,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ratelimit_for_domain |
server_ratelimit_below_domain | server_ratelimit_factor |
server_ip_ratelimit_factor | server_send_client_subnet |
server_client_subnet_always_forward |
server_client_subnet_zone | server_client_subnet_always_forward |
server_client_subnet_opcode |
server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
server_caps_whitelist | server_cache_max_negative_ttl |
@ -375,6 +375,18 @@ server_send_client_subnet: VAR_SEND_CLIENT_SUBNET STRING_ARG
#endif
}
;
server_client_subnet_zone: VAR_CLIENT_SUBNET_ZONE STRING_ARG
{
#ifdef CLIENT_SUBNET
OUTYY(("P(server_client_subnet_zone:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->client_subnet_zone,
$2))
fatal_exit("out of memory adding client-subnet-zone");
#else
OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
#endif
}
;
server_client_subnet_always_forward:
VAR_CLIENT_SUBNET_ALWAYS_FORWARD STRING_ARG
{