aboutsummaryrefslogtreecommitdiff
path: root/edns-subnet
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2022-07-13 13:02:01 +0000
committerCy Schubert <cy@FreeBSD.org>2022-07-13 13:02:01 +0000
commitd57351465531b38689892ec862de2725b52842dd (patch)
tree7363167508f031fdb90b9091c07a065f3903325d /edns-subnet
parent5f9f82264b91e041df7cba2406625146e7268ce4 (diff)
downloadsrc-d57351465531b38689892ec862de2725b52842dd.tar.gz
src-d57351465531b38689892ec862de2725b52842dd.zip
Diffstat (limited to 'edns-subnet')
-rw-r--r--edns-subnet/subnetmod.c49
-rw-r--r--edns-subnet/subnetmod.h5
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,