From: George Thessalonikefs Date: Fri, 7 Jul 2023 14:27:49 +0000 (+0200) Subject: Merge branch 'tilan7663-subnet_cache_prefetch' into subnet_cache_prefetch X-Git-Tag: release-1.18.0rc1~24^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F907%2Fhead;p=thirdparty%2Funbound.git Merge branch 'tilan7663-subnet_cache_prefetch' into subnet_cache_prefetch --- a952ac17bec769bf31ef78f677acc5ce2a7a2f8e diff --cc daemon/worker.c index d70e08e8f,d85e1f6e6..c0b34ff4a --- a/daemon/worker.c +++ b/daemon/worker.c @@@ -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 diff --cc edns-subnet/subnetmod.c index 5e6d9efd3,6ec3be497..13fd669b5 --- a/edns-subnet/subnetmod.c +++ b/edns-subnet/subnetmod.c @@@ -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 2bc042596,2eea0b558..6148b0bc6 --- a/services/mesh.c +++ b/services/mesh.c @@@ -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; + #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.addr; ++ 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 testdata/subnet_prefetch.crpl index 04922f2bb,934103811..aaa6bf08c --- a/testdata/subnet_prefetch.crpl +++ b/testdata/subnet_prefetch.crpl @@@ -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