diff options
author | Cy Schubert <cy@FreeBSD.org> | 2022-07-13 13:02:01 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2022-07-13 13:02:01 +0000 |
commit | d57351465531b38689892ec862de2725b52842dd (patch) | |
tree | 7363167508f031fdb90b9091c07a065f3903325d /edns-subnet | |
parent | 5f9f82264b91e041df7cba2406625146e7268ce4 (diff) | |
download | src-d57351465531b38689892ec862de2725b52842dd.tar.gz src-d57351465531b38689892ec862de2725b52842dd.zip |
Diffstat (limited to 'edns-subnet')
-rw-r--r-- | edns-subnet/subnetmod.c | 49 | ||||
-rw-r--r-- | edns-subnet/subnetmod.h | 5 |
2 files changed, 34 insertions, 20 deletions
diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c index 25190b040d45..75446113b742 100644 --- a/edns-subnet/subnetmod.c +++ b/edns-subnet/subnetmod.c @@ -93,13 +93,14 @@ subnet_new_qstate(struct module_qstate *qstate, int id) qstate->minfo[id] = sq; memset(sq, 0, sizeof(*sq)); sq->started_no_cache_store = qstate->no_cache_store; + sq->started_no_cache_lookup = qstate->no_cache_lookup; return 1; } /** Add ecs struct to edns list, after parsing it to wire format. */ void subnet_ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list, - struct module_qstate *qstate) + struct module_qstate *qstate, struct regional *region) { size_t sn_octs, sn_octs_remainder; sldns_buffer* buf = qstate->env->scratch_buffer; @@ -131,7 +132,7 @@ subnet_ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list, edns_opt_list_append(list, qstate->env->cfg->client_subnet_opcode, sn_octs + sn_octs_remainder + 4, - sldns_buffer_begin(buf), qstate->region); + sldns_buffer_begin(buf), region); } } @@ -139,7 +140,7 @@ int ecs_whitelist_check(struct query_info* qinfo, uint16_t ATTR_UNUSED(flags), struct module_qstate* qstate, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), - struct regional* ATTR_UNUSED(region), int id, void* ATTR_UNUSED(cbargs)) + struct regional *region, int id, void* ATTR_UNUSED(cbargs)) { struct subnet_qstate *sq; struct subnet_env *sn_env; @@ -165,7 +166,7 @@ int ecs_whitelist_check(struct query_info* qinfo, if(!edns_opt_list_find(qstate->edns_opts_back_out, qstate->env->cfg->client_subnet_opcode)) { subnet_ecs_opt_list_append(&sq->ecs_server_out, - &qstate->edns_opts_back_out, qstate); + &qstate->edns_opts_back_out, qstate, region); } sq->subnet_sent = 1; } @@ -331,9 +332,11 @@ update_cache(struct module_qstate *qstate, int id) struct ecs_data *edns = &sq->ecs_client_in; size_t i; - /* We already calculated hash upon lookup */ - hashvalue_type h = qstate->minfo[id] ? - ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash : + /* 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, @@ -416,7 +419,10 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq) memset(&sq->ecs_client_out, 0, sizeof(sq->ecs_client_out)); - if (sq) sq->qinfo_hash = h; /* Might be useful on cache miss */ + if (sq) { + sq->qinfo_hash = h; /* Might be useful on cache miss */ + sq->qinfo_hash_calculated = 1; + } e = slabhash_lookup(sne->subnet_msg_cache, h, &qstate->qinfo, 1); if (!e) return 0; /* qinfo not in cache */ data = e->data; @@ -758,18 +764,21 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, return; } - lock_rw_wrlock(&sne->biglock); - if (lookup_and_reply(qstate, id, sq)) { - 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)) { + 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); + 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; @@ -812,9 +821,11 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, if(qstate->ext_state[id] == module_finished && qstate->return_msg) { subnet_ecs_opt_list_append(&sq->ecs_client_out, - &qstate->edns_opts_front_out, qstate); + &qstate->edns_opts_front_out, qstate, + qstate->region); } qstate->no_cache_store = sq->started_no_cache_store; + qstate->no_cache_lookup = sq->started_no_cache_lookup; return; } if(sq && outbound) { diff --git a/edns-subnet/subnetmod.h b/edns-subnet/subnetmod.h index c877692b46b1..f0bcaad33e15 100644 --- a/edns-subnet/subnetmod.h +++ b/edns-subnet/subnetmod.h @@ -76,6 +76,7 @@ struct subnet_msg_cache_data { struct subnet_qstate { /** We need the hash for both cache lookup and insert */ hashvalue_type qinfo_hash; + int qinfo_hash_calculated; /** ecs_data for client communication */ struct ecs_data ecs_client_in; struct ecs_data ecs_client_out; @@ -92,6 +93,8 @@ struct subnet_qstate { uint8_t max_scope; /** has the subnet module been started with no_cache_store? */ int started_no_cache_store; + /** has the subnet module been started with no_cache_lookup? */ + int started_no_cache_lookup; }; void subnet_data_delete(void* d, void* ATTR_UNUSED(arg)); @@ -145,7 +148,7 @@ void subnet_markdel(void* key); /** Add ecs struct to edns list, after parsing it to wire format. */ void subnet_ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list, - struct module_qstate *qstate); + struct module_qstate *qstate, struct regional *region); /** Create ecs_data from the sockaddr_storage information. */ void subnet_option_from_ss(struct sockaddr_storage *ss, struct ecs_data* ecs, |