Replace edns-client-tag with edns-client-string option

This commit is contained in:
Ralph Dolmans 2020-09-30 23:17:53 +02:00
parent 46b3440aea
commit eb799026ff
18 changed files with 2177 additions and 2027 deletions

View File

@ -291,7 +291,7 @@ daemon_init(void)
free(daemon);
return NULL;
}
if(!(daemon->env->edns_tags = edns_tags_create())) {
if(!(daemon->env->edns_strings = edns_strings_create())) {
auth_zones_delete(daemon->env->auth_zones);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
@ -638,9 +638,9 @@ daemon_fork(struct daemon* daemon)
&daemon->use_rpz))
fatal_exit("auth_zones could not be setup");
/* Set-up EDNS tags */
if(!edns_tags_apply_cfg(daemon->env->edns_tags, daemon->cfg))
fatal_exit("Could not set up EDNS tags");
/* Set-up EDNS strings */
if(!edns_strings_apply_cfg(daemon->env->edns_strings, daemon->cfg))
fatal_exit("Could not set up EDNS strings");
/* setup modules */
daemon_setup_modules(daemon);
@ -773,7 +773,7 @@ daemon_delete(struct daemon* daemon)
rrset_cache_delete(daemon->env->rrset_cache);
infra_delete(daemon->env->infra_cache);
edns_known_options_delete(daemon->env);
edns_tags_delete(daemon->env->edns_tags);
edns_strings_delete(daemon->env->edns_strings);
auth_zones_delete(daemon->env->auth_zones);
}
ub_randfree(daemon->rand);

View File

@ -1535,15 +1535,14 @@ Set the number of servers that should be used for fast server selection. Only
use the fastest specified number of servers with the fast\-server\-permil
option, that turns this on or off. The default is to use the fastest 3 servers.
.TP 5
.B edns\-client\-tag: \fI<IP netblock> <tag data>
Include an edns-client-tag option in queries with destination address matching
the configured IP netblock. This configuration option can be used multiple
times. The most specific match will be used. The tag data is configured in
decimal format, from 0 to 65535.
.B edns\-client\-string: \fI<IP netblock> <string>
Include an EDNS0 option containing configured ascii string in queries with
destination address matching the configured IP netblock. This configuration
option can be used multiple times. The most specific match will be used.
.TP 5
.B edns\-client\-tag\-opcode: \fI<opcode>
EDNS0 option code for the edns-client-tag option, from 0 to 65535. Default is
16, as assigned by IANA.
.B edns\-client\-string\-opcode: \fI<opcode>
EDNS0 option code for the edns-client-string option, from 0 to 65535. Default is
65001.
.SS "Remote Control Options"
In the
.B remote\-control:

View File

@ -80,7 +80,7 @@ context_finalize(struct ub_ctx* ctx)
return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz))
return UB_INITFAIL;
if(!edns_tags_apply_cfg(ctx->env->edns_tags, cfg))
if(!edns_strings_apply_cfg(ctx->env->edns_strings, cfg))
return UB_INITFAIL;
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) {

View File

@ -154,8 +154,8 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
errno = ENOMEM;
return NULL;
}
ctx->env->edns_tags = edns_tags_create();
if(!ctx->env->edns_tags) {
ctx->env->edns_strings = edns_strings_create();
if(!ctx->env->edns_strings) {
auth_zones_delete(ctx->env->auth_zones);
edns_known_options_delete(ctx->env);
config_delete(ctx->env->cfg);
@ -186,7 +186,7 @@ ub_ctx_create(void)
config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags);
edns_strings_delete(ctx->env->edns_strings);
free(ctx->env);
free(ctx);
errno = e;
@ -199,7 +199,7 @@ ub_ctx_create(void)
config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags);
edns_strings_delete(ctx->env->edns_strings);
free(ctx->env);
free(ctx);
errno = e;
@ -338,7 +338,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
infra_delete(ctx->env->infra_cache);
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags);
edns_strings_delete(ctx->env->edns_strings);
auth_zones_delete(ctx->env->auth_zones);
free(ctx->env);
}

View File

@ -2097,18 +2097,18 @@ outnet_serviced_query(struct outside_network* outnet,
{
struct serviced_query* sq;
struct service_callback* cb;
struct edns_tag_addr* client_tag_addr;
struct edns_string_addr* client_string_addr;
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, zone, zonelen,
qstate, qstate->region))
return NULL;
if((client_tag_addr = edns_tag_addr_lookup(&env->edns_tags->client_tags,
addr, addrlen))) {
uint16_t client_tag = htons(client_tag_addr->tag_data);
if((client_string_addr = edns_string_addr_lookup(
&env->edns_strings->client_strings, addr, addrlen))) {
edns_opt_list_append(&qstate->edns_opts_back_out,
env->edns_tags->client_tag_opcode, 2,
(uint8_t*)&client_tag, qstate->region);
env->edns_strings->client_string_opcode,
client_string_addr->string_len,
client_string_addr->string, qstate->region);
}
serviced_gen_query(buff, qinfo->qname, qinfo->qname_len, qinfo->qtype,

View File

@ -1213,7 +1213,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
sldns_buffer_flip(pend->buffer);
if(1) {
struct edns_data edns;
struct edns_tag_addr* client_tag_addr;
struct edns_string_addr* client_string_addr;
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen,
zone, zonelen, qstate, qstate->region)) {
free(pend);
@ -1227,13 +1227,13 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
edns.bits = 0;
if(dnssec)
edns.bits = EDNS_DO;
if((client_tag_addr = edns_tag_addr_lookup(
&env->edns_tags->client_tags,
if((client_string_addr = edns_string_addr_lookup(
&env->edns_strings->client_strings,
addr, addrlen))) {
uint16_t client_tag = htons(client_tag_addr->tag_data);
edns_opt_list_append(&qstate->edns_opts_back_out,
env->edns_tags->client_tag_opcode, 2,
(uint8_t*)&client_tag, qstate->region);
env->edns_strings->client_string_opcode,
client_string_addr->string_len,
client_string_addr->string, qstate->region);
}
edns.opt_list = qstate->edns_opts_back_out;
attach_edns_record(pend->buffer, &edns);

View File

@ -1,14 +1,14 @@
; config options
server:
edns-client-tag: 10.0.0.0/24 1234
edns-client-tag: 10.0.0.10/32 5678
edns-client-string: 10.0.0.0/24 "abc d"
edns-client-string: 10.0.0.10/32 "123AbC!"
stub-zone:
name: "tag1234."
name: "edns-string-abc."
stub-addr: 10.0.0.1
stub-zone:
name: "tag5678."
name: "edns-string-123."
stub-addr: 10.0.0.10
stub-zone:
@ -17,7 +17,7 @@ stub-zone:
CONFIG_END
SCENARIO_BEGIN Test EDNS client tag option
SCENARIO_BEGIN Test EDNS string tag option
RANGE_BEGIN 0 1000
ADDRESS 10.0.0.1
@ -26,9 +26,9 @@ MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
tag1234. IN A
edns-string-abc. IN A
SECTION ANSWER
tag1234. IN A 10.20.30.40
edns-string-abc. IN A 10.20.30.40
SECTION ADDITIONAL
ENTRY_END
RANGE_END
@ -40,9 +40,9 @@ MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
tag5678. IN A
edns-string-123. IN A
SECTION ANSWER
tag5678. IN A 10.20.30.40
edns-string-123. IN A 10.20.30.40
SECTION ADDITIONAL
ENTRY_END
RANGE_END
@ -65,19 +65,19 @@ STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
tag1234. IN A
edns-string-abc. IN A
ENTRY_END
STEP 20 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode ednsdata
SECTION QUESTION
tag1234. IN A
edns-string-abc. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 10 ; Opcode 16
00 02 ; Length 2
04 d2 ; 1234
fd e9 ; Opcode 65001
00 05 ; Length 5
61 62 63 20 64 ; "abc d"
HEX_EDNSDATA_END
ENTRY_END
@ -86,28 +86,29 @@ ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
tag1234. IN A
edns-string-abc. IN A
SECTION ANSWER
tag1234. IN A 10.20.30.40
edns-string-abc. IN A 10.20.30.40
ENTRY_END
STEP 110 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
tag5678. IN A
edns-string-123. IN A
ENTRY_END
STEP 120 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode ednsdata
SECTION QUESTION
tag5678. IN A
edns-string-123. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 10 ; Opcode 16
00 02 ; Length 2
16 2e ; 5678
fd e9 ; Opcode 65001
00 07 ; Length 7
31 32 33 41 62 ; "123Ab"
43 21 ; "C!"
HEX_EDNSDATA_END
ENTRY_END
@ -116,9 +117,9 @@ ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
tag5678. IN A
edns-string-123. IN A
SECTION ANSWER
tag5678. IN A 10.20.30.40
edns-string-123. IN A 10.20.30.40
ENTRY_END
STEP 210 QUERY

153
testdata/edns_client_string_opcode.rpl vendored Normal file
View File

@ -0,0 +1,153 @@
; config options
server:
edns-client-string: 10.0.0.0/24 "abc d"
edns-client-string: 10.0.0.10/32 "123AbC!"
edns-client-string-opcode: 65432
stub-zone:
name: "edns-string-abc."
stub-addr: 10.0.0.1
stub-zone:
name: "edns-string-123."
stub-addr: 10.0.0.10
stub-zone:
name: "notag."
stub-addr: 10.10.0.1
CONFIG_END
SCENARIO_BEGIN Test EDNS string tag option
RANGE_BEGIN 0 1000
ADDRESS 10.0.0.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
edns-string-abc. IN A
SECTION ANSWER
edns-string-abc. IN A 10.20.30.40
SECTION ADDITIONAL
ENTRY_END
RANGE_END
RANGE_BEGIN 0 1000
ADDRESS 10.0.0.10
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
edns-string-123. IN A
SECTION ANSWER
edns-string-123. IN A 10.20.30.40
SECTION ADDITIONAL
ENTRY_END
RANGE_END
RANGE_BEGIN 0 1000
ADDRESS 10.10.0.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
notag. IN A
SECTION ANSWER
notag. IN A 10.20.30.40
SECTION ADDITIONAL
ENTRY_END
RANGE_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
edns-string-abc. IN A
ENTRY_END
STEP 20 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode ednsdata
SECTION QUESTION
edns-string-abc. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
ff 98 ; Opcode 65432
00 05 ; Length 5
61 62 63 20 64 ; "abc d"
HEX_EDNSDATA_END
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
edns-string-abc. IN A
SECTION ANSWER
edns-string-abc. IN A 10.20.30.40
ENTRY_END
STEP 110 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
edns-string-123. IN A
ENTRY_END
STEP 120 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode ednsdata
SECTION QUESTION
edns-string-123. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
ff 98 ; Opcode 65432
00 07 ; Length 7
31 32 33 41 62 ; "123Ab"
43 21 ; "C!"
HEX_EDNSDATA_END
ENTRY_END
STEP 130 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
edns-string-123. IN A
SECTION ANSWER
edns-string-123. IN A 10.20.30.40
ENTRY_END
STEP 210 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
notag. IN A
ENTRY_END
STEP 220 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode ednsdata
SECTION QUESTION
notag. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
STEP 230 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
notag. IN A
SECTION ANSWER
notag. IN A 10.20.30.40
ENTRY_END
SCENARIO_END

View File

@ -321,8 +321,8 @@ config_create(void)
cfg->qname_minimisation_strict = 0;
cfg->shm_enable = 0;
cfg->shm_key = 11777;
cfg->edns_client_tags = NULL;
cfg->edns_client_tag_opcode = LDNS_EDNS_CLIENT_TAG;
cfg->edns_client_strings = NULL;
cfg->edns_client_string_opcode = 65001;
cfg->dnscrypt = 0;
cfg->dnscrypt_port = 0;
cfg->dnscrypt_provider = NULL;
@ -1150,7 +1150,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
else O_LS2(opt, "access-control-view", acl_view)
else O_LS2(opt, "edns-client-tags", edns_client_tags)
else O_LS2(opt, "edns-client-strings", edns_client_strings)
#ifdef USE_IPSECMOD
else O_YNO(opt, "ipsecmod-enabled", ipsecmod_enabled)
else O_YNO(opt, "ipsecmod-ignore-bogus", ipsecmod_ignore_bogus)
@ -1519,7 +1519,7 @@ config_delete(struct config_file* cfg)
config_deldblstrlist(cfg->ratelimit_below_domain);
config_delstrlist(cfg->python_script);
config_delstrlist(cfg->dynlib_file);
config_deldblstrlist(cfg->edns_client_tags);
config_deldblstrlist(cfg->edns_client_strings);
#ifdef USE_IPSECMOD
free(cfg->ipsecmod_hook);
config_delstrlist(cfg->ipsecmod_whitelist);

View File

@ -562,10 +562,10 @@ struct config_file {
/** SHM data - key for the shm */
int shm_key;
/** list of EDNS client tag entries, linked list */
struct config_str2list* edns_client_tags;
/** EDNS opcode to use for EDNS client tags */
uint16_t edns_client_tag_opcode;
/** list of EDNS client string entries, linked list */
struct config_str2list* edns_client_strings;
/** EDNS opcode to use for EDNS client strings */
uint16_t edns_client_string_opcode;
/** DNSCrypt */
/** true to enable dnscrypt */

File diff suppressed because it is too large Load Diff

View File

@ -526,8 +526,8 @@ name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) }
name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) }
udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
edns-client-tag{COLON} { YDVAR(2, VAR_EDNS_CLIENT_TAG) }
edns-client-tag-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_TAG_OPCODE) }
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
/* Quoted strings. Strip leading and ending quotes */

File diff suppressed because it is too large Load Diff

View File

@ -344,8 +344,8 @@ extern int yydebug;
VAR_RPZ_LOG_NAME = 550,
VAR_DYNLIB = 551,
VAR_DYNLIB_FILE = 552,
VAR_EDNS_CLIENT_TAG = 553,
VAR_EDNS_CLIENT_TAG_OPCODE = 554
VAR_EDNS_CLIENT_STRING = 553,
VAR_EDNS_CLIENT_STRING_OPCODE = 554
};
#endif
/* Tokens. */
@ -644,8 +644,8 @@ extern int yydebug;
#define VAR_RPZ_LOG_NAME 550
#define VAR_DYNLIB 551
#define VAR_DYNLIB_FILE 552
#define VAR_EDNS_CLIENT_TAG 553
#define VAR_EDNS_CLIENT_TAG_OPCODE 554
#define VAR_EDNS_CLIENT_STRING 553
#define VAR_EDNS_CLIENT_STRING_OPCODE 554
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED

View File

@ -178,7 +178,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_TAG VAR_EDNS_CLIENT_TAG_OPCODE
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING
%token VAR_EDNS_CLIENT_STRING_OPCODE
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -291,8 +292,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_unknown_server_time_limit | server_log_tag_queryreply |
server_stream_wait_size | server_tls_ciphers |
server_tls_ciphersuites | server_tls_session_ticket_keys |
server_tls_use_sni | server_edns_client_tag |
server_edns_client_tag_opcode
server_tls_use_sni | server_edns_client_string |
server_edns_client_string_opcode
;
stubstart: VAR_STUB_ZONE
{
@ -2465,29 +2466,23 @@ server_ipsecmod_strict: VAR_IPSECMOD_STRICT STRING_ARG
#endif
}
;
server_edns_client_tag: VAR_EDNS_CLIENT_TAG STRING_ARG STRING_ARG
server_edns_client_string: VAR_EDNS_CLIENT_STRING STRING_ARG STRING_ARG
{
int tag_data;
OUTYY(("P(server_edns_client_tag:%s %s)\n", $2, $3));
tag_data = atoi($3);
if(tag_data > 65535 || tag_data < 0 ||
(tag_data == 0 && (strlen($3) != 1 || $3[0] != '0')))
yyerror("edns-client-tag data invalid, needs to be a "
"number from 0 to 65535");
OUTYY(("P(server_edns_client_string:%s %s)\n", $2, $3));
if(!cfg_str2list_insert(
&cfg_parser->cfg->edns_client_tags, $2, $3))
&cfg_parser->cfg->edns_client_strings, $2, $3))
fatal_exit("out of memory adding "
"edns-client-tag");
"edns-client-string");
}
;
server_edns_client_tag_opcode: VAR_EDNS_CLIENT_TAG_OPCODE STRING_ARG
server_edns_client_string_opcode: VAR_EDNS_CLIENT_STRING_OPCODE STRING_ARG
{
OUTYY(("P(edns_client_tag_opcode:%s)\n", $2));
OUTYY(("P(edns_client_string_opcode:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("option code expected");
else if(atoi($2) > 65535 || atoi($2) < 0)
yyerror("option code must be in interval [0, 65535]");
else cfg_parser->cfg->edns_client_tag_opcode = atoi($2);
else cfg_parser->cfg->edns_client_string_opcode = atoi($2);
}
;

View File

@ -48,81 +48,84 @@
#include "util/data/msgparse.h"
#include "util/data/msgreply.h"
struct edns_tags* edns_tags_create(void)
struct edns_strings* edns_strings_create(void)
{
struct edns_tags* edns_tags = calloc(1, sizeof(struct edns_tags));
if(!edns_tags)
struct edns_strings* edns_strings = calloc(1,
sizeof(struct edns_strings));
if(!edns_strings)
return NULL;
if(!(edns_tags->region = regional_create())) {
edns_tags_delete(edns_tags);
if(!(edns_strings->region = regional_create())) {
edns_strings_delete(edns_strings);
return NULL;
}
return edns_tags;
return edns_strings;
}
void edns_tags_delete(struct edns_tags* edns_tags)
void edns_strings_delete(struct edns_strings* edns_strings)
{
if(!edns_tags)
if(!edns_strings)
return;
regional_destroy(edns_tags->region);
free(edns_tags);
regional_destroy(edns_strings->region);
free(edns_strings);
}
static int
edns_tags_client_insert(struct edns_tags* edns_tags,
edns_strings_client_insert(struct edns_strings* edns_strings,
struct sockaddr_storage* addr, socklen_t addrlen, int net,
uint16_t tag_data)
const char* string)
{
struct edns_tag_addr* eta = regional_alloc_zero(edns_tags->region,
sizeof(struct edns_tag_addr));
if(!eta)
struct edns_string_addr* esa = regional_alloc_zero(edns_strings->region,
sizeof(struct edns_string_addr));
if(!esa)
return 0;
eta->tag_data = tag_data;
if(!addr_tree_insert(&edns_tags->client_tags, &eta->node, addr, addrlen,
net)) {
verbose(VERB_QUERY, "duplicate EDNS client tag ignored.");
esa->string_len = strlen(string);
esa->string = regional_alloc_init(edns_strings->region, string,
esa->string_len);
if(!esa->string)
return 0;
if(!addr_tree_insert(&edns_strings->client_strings, &esa->node, addr,
addrlen, net)) {
verbose(VERB_QUERY, "duplicate EDNS client string ignored.");
}
return 1;
}
int edns_tags_apply_cfg(struct edns_tags* edns_tags,
int edns_strings_apply_cfg(struct edns_strings* edns_strings,
struct config_file* config)
{
struct config_str2list* c;
regional_free_all(edns_tags->region);
addr_tree_init(&edns_tags->client_tags);
regional_free_all(edns_strings->region);
addr_tree_init(&edns_strings->client_strings);
for(c=config->edns_client_tags; c; c=c->next) {
for(c=config->edns_client_strings; c; c=c->next) {
struct sockaddr_storage addr;
socklen_t addrlen;
int net;
uint16_t tag_data;
log_assert(c->str && c->str2);
if(!netblockstrtoaddr(c->str, UNBOUND_DNS_PORT, &addr, &addrlen,
&net)) {
log_err("cannot parse EDNS client tag IP netblock: %s",
c->str);
log_err("cannot parse EDNS client string IP netblock: "
"%s", c->str);
return 0;
}
tag_data = atoi(c->str2); /* validated in config parser */
if(!edns_tags_client_insert(edns_tags, &addr, addrlen, net,
tag_data)) {
log_err("out of memory while adding EDNS tags");
if(!edns_strings_client_insert(edns_strings, &addr, addrlen,
net, c->str2)) {
log_err("out of memory while adding EDNS strings");
return 0;
}
}
edns_tags->client_tag_opcode = config->edns_client_tag_opcode;
edns_strings->client_string_opcode = config->edns_client_string_opcode;
addr_tree_init_parents(&edns_tags->client_tags);
addr_tree_init_parents(&edns_strings->client_strings);
return 1;
}
struct edns_tag_addr*
edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
struct edns_string_addr*
edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
socklen_t addrlen)
{
return (struct edns_tag_addr*)addr_tree_lookup(tree, addr, addrlen);
return (struct edns_string_addr*)addr_tree_lookup(tree, addr, addrlen);
}
static int edns_keepalive(struct edns_data* edns_out, struct edns_data* edns_in,

View File

@ -50,58 +50,60 @@ struct comm_point;
struct regional;
/**
* Structure containing all EDNS tags.
* Structure containing all EDNS strings.
*/
struct edns_tags {
/** Tree of EDNS client tags to use in upstream queries, per address
* prefix. Contains nodes of type edns_tag_addr. */
rbtree_type client_tags;
/** EDNS opcode to use for client tags */
uint16_t client_tag_opcode;
struct edns_strings {
/** Tree of EDNS client strings to use in upstream queries, per address
* prefix. Contains nodes of type edns_string_addr. */
rbtree_type client_strings;
/** EDNS opcode to use for client strings */
uint16_t client_string_opcode;
/** region to allocate tree nodes in */
struct regional* region;
};
/**
* EDNS tag. Node of rbtree, containing tag and prefix.
* EDNS string. Node of rbtree, containing string and prefix.
*/
struct edns_tag_addr {
struct edns_string_addr {
/** node in address tree, used for tree lookups. Need to be the first
* member of this struct. */
struct addr_tree_node node;
/** tag data, in host byte ordering */
uint16_t tag_data;
/** string, ascii format */
uint8_t* string;
/** length of string */
size_t string_len;
};
/**
* Create structure to hold EDNS tags
* @return: newly created edns_tags, NULL on alloc failure.
* Create structure to hold EDNS strings
* @return: newly created edns_strings, NULL on alloc failure.
*/
struct edns_tags* edns_tags_create(void);
struct edns_strings* edns_strings_create(void);
/** Delete EDNS tags structure
* @param edns_tags: struct to delete
/** Delete EDNS strings structure
* @param edns_strings: struct to delete
*/
void edns_tags_delete(struct edns_tags* edns_tags);
void edns_strings_delete(struct edns_strings* edns_strings);
/**
* Add configured EDNS tags
* @param edns_tags: edns tags to apply config to
* @param config: struct containing EDNS tags configuration
* Add configured EDNS strings
* @param edns_strings: edns strings to apply config to
* @param config: struct containing EDNS strings configuration
* @return 0 on error
*/
int edns_tags_apply_cfg(struct edns_tags* edns_tags,
int edns_strings_apply_cfg(struct edns_strings* edns_strings,
struct config_file* config);
/**
* Find tag for address.
* @param tree: tree containing EDNS tags per address prefix.
* Find string for address.
* @param tree: tree containing EDNS strings per address prefix.
* @param addr: address to use for tree lookup
* @param addrlen: length of address
* @return: matching tree node, NULL otherwise
*/
struct edns_tag_addr*
edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
struct edns_string_addr*
edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
socklen_t addrlen);
/**

View File

@ -520,8 +520,8 @@ struct module_env {
struct edns_known_option* edns_known_options;
/* Number of known edns options */
size_t edns_known_options_num;
/** EDNS client tag information */
struct edns_tags* edns_tags;
/** EDNS client string information */
struct edns_strings* edns_strings;
/* Make every mesh state unique, do not aggregate mesh states. */
int unique_mesh;