]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Add markdel function to ECS slabhash.
authorRalph Dolmans <ralph@nlnetlabs.nl>
Wed, 24 Oct 2018 13:50:18 +0000 (13:50 +0000)
committerRalph Dolmans <ralph@nlnetlabs.nl>
Wed, 24 Oct 2018 13:50:18 +0000 (13:50 +0000)
 - 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

doc/Changelog
edns-subnet/addrtree.c
edns-subnet/addrtree.h
edns-subnet/subnetmod.c
edns-subnet/subnetmod.h
testcode/testpkts.c
testcode/testpkts.h
testcode/unitecs.c
testdata/subnet_max_source.crpl
util/fptr_wlist.c

index 5dadeafaac4038207eb2c77cb28c6c0a26eff380..51070c414e09dd1b064970cce2ce4716d75c4458 100644 (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.
index 9a02db062c51af04970ce95b36c7a8b94071c6a3..180a0227917c50c01cf957689650210a8ba78db9 100644 (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);
index 71d9d2ec6c9bb94361c9189ebc1242a53c0f5c41..1aea54e01f79544b3583f5d286e5112eab91f7fe 100644 (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.
index 456de213c37845c7fae6e18ee0991803120cb496..9b123222db77c3a48cc867527821010a68d9c1a4 100644 (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;
index f417a64a45b0682e6831effb793c6e298163c85a..9c95a290fd2f9b261dbecd4b29faa51cc02223e8 100644 (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 */
index 01f23e48ed2e73216e920f030c143afee1667383..1d89c38fc8f1ca30a5c2e457466c53f48d076718 100644 (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) {
index b175cab066ab91a5d4e5c035df92b0473cdcaaf4..6e032fa90a65b4b572a8f7403d3b3ea740b152f9 100644 (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; 
 
index 097ae9ebba6acd9f8b2050ad285dd5b98ce59daf..b240bfcc666e99d54152bd9af9ede04d6dc9a3ae 100644 (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;
index e1c6cf5f99f7d9c03b115070f16812e927ce44b4..f5c7464ed7b2a67c6ce6196efedb8d6f244fdf0b 100644 (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
index 302b6f7843ea2de3ae11253f074bafd3350f34d2..271d862569835378dc216a7582014b30a8069ba8 100644 (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;
 }