From: Ralph Dolmans Date: Wed, 24 Oct 2018 13:50:18 +0000 (+0000) Subject: - Add markdel function to ECS slabhash. X-Git-Tag: release-1.8.2rc1~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=140a165ab26cab53fef69ba34c029702be8ff462;p=thirdparty%2Funbound.git - 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 --- diff --git a/doc/Changelog b/doc/Changelog index 5dadeafaa..51070c414 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/edns-subnet/addrtree.c b/edns-subnet/addrtree.c index 9a02db062..180a02279 100644 --- a/edns-subnet/addrtree.c +++ b/edns-subnet/addrtree.c @@ -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); diff --git a/edns-subnet/addrtree.h b/edns-subnet/addrtree.h index 71d9d2ec6..1aea54e01 100644 --- a/edns-subnet/addrtree.h +++ b/edns-subnet/addrtree.h @@ -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. diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c index 456de213c..9b123222d 100644 --- a/edns-subnet/subnetmod.c +++ b/edns-subnet/subnetmod.c @@ -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; diff --git a/edns-subnet/subnetmod.h b/edns-subnet/subnetmod.h index f417a64a4..9c95a290f 100644 --- a/edns-subnet/subnetmod.h +++ b/edns-subnet/subnetmod.h @@ -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 */ diff --git a/testcode/testpkts.c b/testcode/testpkts.c index 01f23e48e..1d89c38fc 100644 --- a/testcode/testpkts.c +++ b/testcode/testpkts.c @@ -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) { diff --git a/testcode/testpkts.h b/testcode/testpkts.h index b175cab06..6e032fa90 100644 --- a/testcode/testpkts.h +++ b/testcode/testpkts.h @@ -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; diff --git a/testcode/unitecs.c b/testcode/unitecs.c index 097ae9ebb..b240bfcc6 100644 --- a/testcode/unitecs.c +++ b/testcode/unitecs.c @@ -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; diff --git a/testdata/subnet_max_source.crpl b/testdata/subnet_max_source.crpl index e1c6cf5f9..f5c7464ed 100644 --- a/testdata/subnet_max_source.crpl +++ b/testdata/subnet_max_source.crpl @@ -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 diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index 302b6f784..271d86256 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -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; }