- Add markdel function to ECS slabhash.

- Limit ECS scope returned to client to the scope used for caching.      
 - Make lint like previous #4154 fix. 


git-svn-id: file:///svn/unbound/trunk@4946 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Ralph Dolmans 2018-10-24 13:50:18 +00:00
parent 5fec1c8b1f
commit 140a165ab2
10 changed files with 110 additions and 5 deletions

View File

@ -1,3 +1,8 @@
24 October 2018: Ralph
- Add markdel function to ECS slabhash.
- Limit ECS scope returned to client to the scope used for caching.
- Make lint like previous #4154 fix.
22 October 2018: Wouter
- Fix #4192: unbound-control-setup generates keys not readable by
group.

View File

@ -119,7 +119,7 @@ node_size(const struct addrtree *tree, const struct addrnode *n)
struct addrtree *
addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *),
size_t (*sizefunc)(void *), void *env, unsigned int max_node_count)
size_t (*sizefunc)(void *), void *env, uint32_t max_node_count)
{
struct addrtree *tree;
log_assert(delfunc != NULL);

View File

@ -66,10 +66,10 @@ struct addrtree {
struct addrnode *root;
/** Number of elements in the tree (not always equal to number of
* nodes) */
unsigned int node_count;
uint32_t node_count;
/** Maximum number of allowed nodes, will be enforced by LRU list.
* Excluding the root node, 0 for unlimited */
unsigned int max_node_count;
uint32_t max_node_count;
/** Size of tree in bytes */
size_t size_bytes;
/** Maximum prefix length we are willing to cache. */
@ -137,7 +137,7 @@ size_t addrtree_size(const struct addrtree *tree);
*/
struct addrtree *
addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *),
size_t (*sizefunc)(void *), void *env, unsigned int max_node_count);
size_t (*sizefunc)(void *), void *env, uint32_t max_node_count);
/**
* Free tree and all nodes below.

View File

@ -175,6 +175,14 @@ int ecs_whitelist_check(struct query_info* qinfo,
}
void
subnet_markdel(void* key)
{
struct msgreply_entry *e = (struct msgreply_entry*)key;
e->key.qtype = 0;
e->key.qclass = 0;
}
int
subnetmod_init(struct module_env *env, int id)
{
@ -191,6 +199,7 @@ subnetmod_init(struct module_env *env, int id)
HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
msg_cache_sizefunc, query_info_compare, query_entry_delete,
subnet_data_delete, NULL);
slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
if(!sn_env->subnet_msg_cache) {
log_err("subnet: could not create cache");
free(sn_env);
@ -524,6 +533,19 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
c_out->subnet_source_mask = c_in->subnet_source_mask;
memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE);
c_out->subnet_scope_mask = s_in->subnet_scope_mask;
/* Limit scope returned to client to scope used for caching. */
if(c_out->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
if(c_out->subnet_scope_mask >
qstate->env->cfg->max_client_subnet_ipv4) {
c_out->subnet_scope_mask =
qstate->env->cfg->max_client_subnet_ipv4;
}
}
else if(c_out->subnet_scope_mask >
qstate->env->cfg->max_client_subnet_ipv6) {
c_out->subnet_scope_mask =
qstate->env->cfg->max_client_subnet_ipv6;
}
c_out->subnet_validdata = 1;
}
return module_finished;

View File

@ -131,4 +131,7 @@ int ecs_edns_back_parsed(struct module_qstate* qstate, int id, void* cbargs);
int ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
int id, void* cbargs);
/** mark subnet msg to be deleted */
void subnet_markdel(void* key);
#endif /* SUBNETMOD_H */

View File

@ -236,6 +236,8 @@ static void adjustline(char* line, struct entry* e,
e->copy_query = 1;
} else if(str_keyword(&parse, "copy_ednsdata_assume_clientsubnet")) {
e->copy_ednsdata_assume_clientsubnet = 1;
} else if(str_keyword(&parse, "increment_ecs_scope")) {
e->increment_ecs_scope = 1;
} else if(str_keyword(&parse, "sleep=")) {
e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10);
while(isspace((unsigned char)*parse))
@ -274,6 +276,7 @@ static struct entry* new_entry(void)
e->copy_id = 0;
e->copy_query = 0;
e->copy_ednsdata_assume_clientsubnet = 0;
e->increment_ecs_scope = 0;
e->sleeptime = 0;
e->next = NULL;
return e;
@ -1593,6 +1596,9 @@ adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len,
if(walk_qlen >= 15 && walk_plen >= 15) {
walk_p[15] = walk_q[14];
}
if(match->increment_ecs_scope) {
walk_p[15]++;
}
}
if(match->sleeptime > 0) {

View File

@ -208,6 +208,8 @@ struct entry {
/** copy ednsdata to reply, assume it is clientsubnet and
* adjust scopemask to match sourcemask */
uint8_t copy_ednsdata_assume_clientsubnet;
/** increment the ECS scope copied from the sourcemask by one */
uint8_t increment_ecs_scope;
/** in seconds */
unsigned int sleeptime;

View File

@ -158,7 +158,7 @@ static void consistency_test(void)
{
addrlen_t l;
time_t i;
unsigned int count;
uint32_t count;
addrkey_t *k;
struct addrtree* t;
struct module_env env;

View File

@ -145,6 +145,29 @@ RANGE_BEGIN 0 100
ns.example.com. IN A 1.2.3.4
ENTRY_END
; client send /17, we return /18
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id copy_ednsdata_assume_clientsubnet increment_ecs_scope
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN TXT
SECTION ANSWER
www.example.com. IN TXT "longer scope"
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 127.1.0.1
00 08 ; OPC
00 07 ; option length
00 01 ; Family
11 00 ; source mask, scopemask
7f 01 00 ; address
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
STEP 1 QUERY
@ -229,5 +252,46 @@ ENTRY_BEGIN
ns.example.com. IN A 1.2.3.4
ENTRY_END
STEP 21 QUERY
ENTRY_BEGIN
HEX_ANSWER_BEGIN;
00 00 01 00 00 01 00 00 ;ID 0
00 00 00 01 03 77 77 77 ; www.example.com TXT? (DO)
07 65 78 61 6d 70 6c 65
03 63 6f 6d 00 00 10 00
01 00 00 29 10 00 00 00
80 00 00 0b
00 08 00 07 ; OPC, optlen
00 01 11 00 ; ip4, scope 17, source 0
7f 01 00 ;127.1.0.0/17
HEX_ANSWER_END
ENTRY_END
; server returns /18, since we cache the result to max-client-subnet-ipv4 (/17),
; the initial answer returned to the client should also be capped to /17.
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ednsdata
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN TXT
SECTION ANSWER
www.example.com. IN TXT "longer scope"
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 127.1.0.1
00 08 ; OPC
00 07 ; option length
00 01 ; Family
11 11 ; source mask, scopemask
7f 01 00 ; address
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ENTRY_END
SCENARIO_END

View File

@ -303,6 +303,9 @@ fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr)
{
if(fptr == NULL) return 1;
else if(fptr == &rrset_markdel) return 1;
#ifdef CLIENT_SUBNET
else if(fptr == &subnet_markdel) return 1;
#endif
return 0;
}