]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Merge branch 'tilan7663-subnet_cache_prefetch' into subnet_cache_prefetch 907/head
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Fri, 7 Jul 2023 14:27:49 +0000 (16:27 +0200)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Fri, 7 Jul 2023 14:50:58 +0000 (16:50 +0200)
1  2 
daemon/worker.c
edns-subnet/subnetmod.c
services/mesh.c
services/mesh.h
testdata/subnet_prefetch.crpl
util/data/msgreply.c

diff --cc daemon/worker.c
index d70e08e8fba11dd5d803d4fd64fde6ed66781ffd,d85e1f6e65d8d049a52fbc92867b05697110ef0e..c0b34ff4a7fd70d65f081492bc1a20f4e1b5b1d0
@@@ -817,7 -786,7 +817,8 @@@ reply_and_prefetch(struct worker* worke
        if(modstack_find(&worker->env.mesh->mods, "subnetcache") != -1
                && worker->env.unique_mesh) {
                mesh_new_prefetch(worker->env.mesh, qinfo, flags, leeway +
-                       PREFETCH_EXPIRY_ADD, rpz_passthru, repinfo, opt_list);
 -                      PREFETCH_EXPIRY_ADD, rpz_passthru, &repinfo->addr, opt_list);
++                      PREFETCH_EXPIRY_ADD, rpz_passthru,
++                      &repinfo->client_addr, opt_list);
                return;
        }
  #endif
index 5e6d9efd372db7f788e80147710ab79d6b94661a,6ec3be49770b4002d41526be46509f282af01a55..13fd669b5d52250e0efec4a590a22c7081a11e1f
@@@ -343,18 -330,21 +343,18 @@@ update_cache(struct module_qstate *qsta
        struct slabhash *subnet_msg_cache = sne->subnet_msg_cache;
        struct ecs_data *edns = &sq->ecs_client_in;
        size_t i;
 -      hashvalue_type h;
 -      struct lruhash_entry* lru_entry;
 -      int need_to_insert;
 -
 -      /* qinfo_hash is not set if it is prefetch request */
 -      if (qstate->minfo[id] && ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash) {
 -              h = ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash;
 -      } else {
 -              h = query_info_hash(&qstate->qinfo, qstate->query_flags);
 -      }
 -
 +      int only_match_scope_zero;
 +
 +      /* We already calculated hash upon lookup (lookup_and_reply) if we were
 +       * allowed to look in the ECS cache */
 +      hashvalue_type h = qstate->minfo[id] &&
 +              ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash_calculated?
 +              ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash :
 +              query_info_hash(&qstate->qinfo, qstate->query_flags);
        /* Step 1, general qinfo lookup */
-       struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h,
 -      lru_entry = slabhash_lookup(subnet_msg_cache, h,
++      struct lruhash_entry* lru_entry = slabhash_lookup(subnet_msg_cache, h,
                &qstate->qinfo, 1);
 -      need_to_insert = (lru_entry == NULL);
 +      int need_to_insert = (lru_entry == NULL);
        if (!lru_entry) {
                void* data = calloc(1,
                        sizeof(struct subnet_msg_cache_data));
@@@ -805,28 -768,18 +809,30 @@@ subnetmod_operate(struct module_qstate 
                                return;
                }
  
 -              lock_rw_wrlock(&sne->biglock);
 -              if (qstate->mesh_info->reply_list && lookup_and_reply(qstate, id, sq, qstate->env->cfg->prefetch)) {
 -                      sne->num_msg_cache++;
 -                      lock_rw_unlock(&sne->biglock);
 -                      verbose(VERB_QUERY, "subnetcache: answered from cache");
 -                      qstate->ext_state[id] = module_finished;
 +              if(!sq->started_no_cache_lookup && !qstate->blacklist) {
 +                      lock_rw_wrlock(&sne->biglock);
-                       if(lookup_and_reply(qstate, id, sq)) {
++                      if(qstate->mesh_info->reply_list &&
++                              lookup_and_reply(qstate, id, sq,
++                              qstate->env->cfg->prefetch)) {
 +                              sne->num_msg_cache++;
 +                              lock_rw_unlock(&sne->biglock);
 +                              verbose(VERB_QUERY, "subnetcache: answered from cache");
 +                              qstate->ext_state[id] = module_finished;
  
 -                      subnet_ecs_opt_list_append(&sq->ecs_client_out,
 -                              &qstate->edns_opts_front_out, qstate);
 -                      return;
 +                              subnet_ecs_opt_list_append(&sq->ecs_client_out,
 +                                      &qstate->edns_opts_front_out, qstate,
 +                                      qstate->region);
 +                              if(verbosity >= VERB_ALGO) {
 +                                      subnet_log_print("reply has edns subnet",
 +                                              edns_opt_list_find(
 +                                              qstate->edns_opts_front_out,
 +                                              qstate->env->cfg->
 +                                              client_subnet_opcode));
 +                              }
 +                              return;
 +                      }
 +                      lock_rw_unlock(&sne->biglock);
                }
 -              lock_rw_unlock(&sne->biglock);
                
                sq->ecs_server_out.subnet_addr_fam =
                        sq->ecs_client_in.subnet_addr_fam;
diff --cc services/mesh.c
index 2bc04259629cfffb00b4a5b3964a6c78a9e4719e,2eea0b558be881da13cf07485dce6498497dc693..6148b0bc612f8912efd5d8d0c699ba2245a5db1d
@@@ -735,10 -803,19 +735,10 @@@ static void mesh_schedule_prefetch_subn
                        return;
                }
        } else {
 -              /* Fake the ECS data from the client's IP */
 -              struct ecs_data ecs;
 -              memset(&ecs, 0, sizeof(ecs));
 -              subnet_option_from_ss(addr, &ecs, mesh->env->cfg);
 -              if(ecs.subnet_validdata == 0) {
 -                      log_err("prefetch_subnet subnet_option_from_ss: invalid data");
 -                      return;
 -              }
 -              subnet_ecs_opt_list_append(&ecs, &s->s.edns_opts_front_in, &s->s);
 -              if(!s->s.edns_opts_front_in) {
 -                      log_err("prefetch_subnet subnet_ecs_opt_list_append: out of memory");
 -                      return;
 -              }
 +              /* Store the client's address. Later in the subnet module,
 +               * it is decided whether to include an ECS option or not.
 +               */
-               s->s.client_addr =  rep->client_addr;
++              s->s.client_addr =  *addr;
        }
  #ifdef UNBOUND_DEBUG
        n =
@@@ -1794,9 -1838,20 +1794,21 @@@ mesh_continue(struct mesh_area* mesh, s
        if(s == module_finished) {
                if(mstate->s.curmod == 0) {
                        struct query_info* qinfo = NULL;
 -                      struct edns_option* opt_list = NULL, *ecs;
++                      struct edns_option* opt_list = NULL;
+                       struct sockaddr_storage addr;
                        uint16_t qflags;
                        int rpz_p = 0;
  
 -                              addr = mstate->reply_list->query_reply.addr;
+ #ifdef CLIENT_SUBNET
++                      struct edns_option* ecs;
+                       if(mstate->s.need_refetch && mstate->reply_list &&
+                               modstack_find(&mesh->mods, "subnetcache") != -1 &&
+                               mstate->s.env->unique_mesh) {
++                              addr = mstate->reply_list->query_reply.client_addr;
+                       } else
+ #endif
+                               memset(&addr, 0, sizeof(addr));
                        mesh_query_done(mstate);
                        mesh_walk_supers(mesh, mstate);
  
diff --cc services/mesh.h
Simple merge
index 04922f2bbe4810f99573d15e73d02e4a07b83b71,93410381165117a8cb734b1ce7c960d75b8d5136..aaa6bf08c4500a59a40749f8456b8f5975820f58
@@@ -185,21 -154,19 +154,19 @@@ ENTRY_BEGI
  MATCH all ttl
  REPLY QR RD RA NOERROR
  SECTION QUESTION
 -www.example.com. IN A
 +www.example.com.              IN A
  SECTION ANSWER
- www.example.com.      1       IN A    10.20.30.40
+ www.example.com. 1 IN A       10.20.30.40
  SECTION AUTHORITY
- example.com.          3591    IN NS   ns.example.com.
+ example.com.  3591 IN NS      ns.example.com.
  SECTION ADDITIONAL
- ns.example.com.               3591    IN A    1.2.3.4
+ ns.example.com.       3591 IN         A       1.2.3.4
  ENTRY_END
  
- ; Allow time to pass so that the global cache record is expired
- STEP 13 TIME_PASSES ELAPSE 2
+ ; Allow for some time to pass to differentiate from a cached vs resolved answer
+ STEP 6 TIME_PASSES ELAPSE 1
  
- ; Query again to verify that the record was prefetched and stored in the ECS
- ; cache (because the server replied with ECS this time)
- STEP 14 QUERY
+ STEP 7 QUERY
  ENTRY_BEGIN
  REPLY RD
  SECTION QUESTION
Simple merge