aboutsummaryrefslogtreecommitdiff
path: root/edns-subnet/subnetmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'edns-subnet/subnetmod.c')
-rw-r--r--edns-subnet/subnetmod.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c
index 75446113b742..0f1df417f6b5 100644
--- a/edns-subnet/subnetmod.c
+++ b/edns-subnet/subnetmod.c
@@ -55,6 +55,7 @@
#include "util/config_file.h"
#include "util/data/msgreply.h"
#include "sldns/sbuffer.h"
+#include "sldns/wire2str.h"
#include "iterator/iter_utils.h"
/** externally called */
@@ -331,6 +332,7 @@ update_cache(struct module_qstate *qstate, int id)
struct slabhash *subnet_msg_cache = sne->subnet_msg_cache;
struct ecs_data *edns = &sq->ecs_client_in;
size_t i;
+ int only_match_scope_zero;
/* We already calculated hash upon lookup (lookup_and_reply) if we were
* allowed to look in the ECS cache */
@@ -392,9 +394,12 @@ update_cache(struct module_qstate *qstate, int id)
reply_info_set_ttls(rep, *qstate->env->now);
rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */
rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */
+ if(edns->subnet_source_mask == 0 && edns->subnet_scope_mask == 0)
+ only_match_scope_zero = 1;
+ else only_match_scope_zero = 0;
addrtree_insert(tree, (addrkey_t*)edns->subnet_addr,
edns->subnet_source_mask, sq->max_scope, rep,
- rep->ttl, *qstate->env->now);
+ rep->ttl, *qstate->env->now, only_match_scope_zero);
lock_rw_unlock(&lru_entry->lock);
if (need_to_insert) {
@@ -674,6 +679,24 @@ ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
return 1;
}
+/** verbose print edns subnet option in pretty print */
+static void
+subnet_log_print(const char* s, struct edns_option* ecs_opt)
+{
+ if(verbosity >= VERB_ALGO) {
+ char buf[256];
+ char* str = buf;
+ size_t str_len = sizeof(buf);
+ if(!ecs_opt) {
+ verbose(VERB_ALGO, "%s (null)", s);
+ return;
+ }
+ (void)sldns_wire2str_edns_subnet_print(&str, &str_len,
+ ecs_opt->opt_data, ecs_opt->opt_len);
+ verbose(VERB_ALGO, "%s %s", s, buf);
+ }
+}
+
int
ecs_edns_back_parsed(struct module_qstate* qstate, int id,
void* ATTR_UNUSED(cbargs))
@@ -688,6 +711,7 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
qstate->env->cfg->client_subnet_opcode)) &&
parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
sq->subnet_sent && sq->ecs_server_in.subnet_validdata) {
+ subnet_log_print("answer has edns subnet", ecs_opt);
/* Only skip global cache store if we sent an ECS option
* and received one back. Answers from non-whitelisted
* servers will end up in global cache. Answers for
@@ -736,11 +760,12 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
qstate->ext_state[id] = module_finished;
return;
}
+ subnet_log_print("query has edns subnet", ecs_opt);
sq->subnet_downstream = 1;
}
else if(qstate->mesh_info->reply_list) {
subnet_option_from_ss(
- &qstate->mesh_info->reply_list->query_reply.addr,
+ &qstate->mesh_info->reply_list->query_reply.client_addr,
&sq->ecs_client_in, qstate->env->cfg);
}
@@ -775,6 +800,13 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
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);
@@ -823,6 +855,13 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
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));
+ }
}
qstate->no_cache_store = sq->started_no_cache_store;
qstate->no_cache_lookup = sq->started_no_cache_lookup;