2256 lines
60 KiB
Diff
2256 lines
60 KiB
Diff
diff --git a/unbound-1.16.2/edns-subnet/addrtree.c b/unbound-1.16.2/edns-subnet/addrtree.c
|
|
index 180a022..ebe71b9 100644
|
|
--- a/unbound-1.16.2/edns-subnet/addrtree.c
|
|
+++ b/unbound-1.16.2/edns-subnet/addrtree.c
|
|
@@ -97,6 +97,7 @@ node_create(struct addrtree *tree, void *elem, addrlen_t scope,
|
|
tree->node_count++;
|
|
node->scope = scope;
|
|
node->ttl = ttl;
|
|
+ node->only_match_scope_zero = 0;
|
|
node->edge[0] = NULL;
|
|
node->edge[1] = NULL;
|
|
node->parent_edge = NULL;
|
|
@@ -155,6 +156,7 @@ clean_node(struct addrtree *tree, struct addrnode *node)
|
|
if (!node->elem) return;
|
|
tree->size_bytes -= tree->sizefunc(node->elem);
|
|
tree->delfunc(tree->env, node->elem);
|
|
+ node->only_match_scope_zero = 0;
|
|
node->elem = NULL;
|
|
}
|
|
|
|
@@ -358,7 +360,7 @@ issub(const addrkey_t *s1, addrlen_t l1,
|
|
void
|
|
addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
|
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
|
|
- time_t now)
|
|
+ time_t now, int only_match_scope_zero)
|
|
{
|
|
struct addrnode *newnode, *node;
|
|
struct addredge *edge;
|
|
@@ -381,6 +383,7 @@ addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
|
/* update this node's scope and data */
|
|
clean_node(tree, node);
|
|
node->ttl = ttl;
|
|
+ node->only_match_scope_zero = only_match_scope_zero;
|
|
node->elem = elem;
|
|
node->scope = scope;
|
|
tree->size_bytes += tree->sizefunc(elem);
|
|
@@ -447,6 +450,7 @@ addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
|
newnode->elem = elem;
|
|
newnode->scope = scope;
|
|
newnode->ttl = ttl;
|
|
+ newnode->only_match_scope_zero = only_match_scope_zero;
|
|
}
|
|
|
|
tree->size_bytes += node_size(tree, newnode);
|
|
@@ -483,7 +487,8 @@ addrtree_find(struct addrtree *tree, const addrkey_t *addr,
|
|
/* Current node more specific then question. */
|
|
log_assert(depth <= sourcemask);
|
|
/* does this node have data? if yes, see if we have a match */
|
|
- if (node->elem && node->ttl >= now) {
|
|
+ if (node->elem && node->ttl >= now &&
|
|
+ !(sourcemask != 0 && node->only_match_scope_zero)) {
|
|
/* saved at wrong depth */;
|
|
log_assert(node->scope >= depth);
|
|
if (depth == node->scope ||
|
|
diff --git a/unbound-1.16.2/edns-subnet/addrtree.h b/unbound-1.16.2/edns-subnet/addrtree.h
|
|
index 1aea54e..0bc1837 100644
|
|
--- a/unbound-1.16.2/edns-subnet/addrtree.h
|
|
+++ b/unbound-1.16.2/edns-subnet/addrtree.h
|
|
@@ -95,6 +95,10 @@ struct addrnode {
|
|
time_t ttl;
|
|
/** Number of significant bits in address. */
|
|
addrlen_t scope;
|
|
+ /** Only use the element for queries for subnet/0. Set if the query
|
|
+ * for /0 was answered with scope 0. For query /x answer scope 0,
|
|
+ * they can match anything and this is false. */
|
|
+ int only_match_scope_zero;
|
|
/** A node can have 0-2 edges, set to NULL for unused */
|
|
struct addredge *edge[2];
|
|
/** edge between this node and parent */
|
|
@@ -157,11 +161,12 @@ void addrtree_delete(struct addrtree *tree);
|
|
* @param scope: Number of significant bits in addr.
|
|
* @param elem: data to store in the tree.
|
|
* @param ttl: elem is valid up to this time, seconds.
|
|
+ * @param only_match_scope_zero: set for when query /0 has scope /0 answer.
|
|
* @param now: Current time in seconds.
|
|
*/
|
|
void addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
|
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
|
|
- time_t now);
|
|
+ time_t now, int only_match_scope_zero);
|
|
|
|
/**
|
|
* Find a node containing an element in the tree.
|
|
diff --git a/unbound-1.16.2/edns-subnet/subnetmod.c b/unbound-1.16.2/edns-subnet/subnetmod.c
|
|
index 7544611..53d3048 100644
|
|
--- a/unbound-1.16.2/edns-subnet/subnetmod.c
|
|
+++ b/unbound-1.16.2/edns-subnet/subnetmod.c
|
|
@@ -51,10 +51,12 @@
|
|
#include "services/cache/dns.h"
|
|
#include "util/module.h"
|
|
#include "util/regional.h"
|
|
+#include "util/fptr_wlist.h"
|
|
#include "util/storage/slabhash.h"
|
|
#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 */
|
|
@@ -151,10 +153,12 @@ int ecs_whitelist_check(struct query_info* qinfo,
|
|
|
|
/* Cache by default, might be disabled after parsing EDNS option
|
|
* received from nameserver. */
|
|
- if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL)) {
|
|
+ if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL)
|
|
+ && sq->ecs_client_in.subnet_validdata) {
|
|
qstate->no_cache_store = 0;
|
|
}
|
|
|
|
+ sq->subnet_sent_no_subnet = 0;
|
|
if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream &&
|
|
qstate->env->cfg->client_subnet_always_forward) ||
|
|
ecs_is_whitelisted(sn_env->whitelist,
|
|
@@ -165,6 +169,14 @@ int ecs_whitelist_check(struct query_info* qinfo,
|
|
* set. */
|
|
if(!edns_opt_list_find(qstate->edns_opts_back_out,
|
|
qstate->env->cfg->client_subnet_opcode)) {
|
|
+ /* if the client is not wanting an EDNS subnet option,
|
|
+ * omit it and store that we omitted it but actually
|
|
+ * are doing EDNS subnet to the server. */
|
|
+ if(sq->ecs_server_out.subnet_source_mask == 0) {
|
|
+ sq->subnet_sent_no_subnet = 1;
|
|
+ sq->subnet_sent = 0;
|
|
+ return 1;
|
|
+ }
|
|
subnet_ecs_opt_list_append(&sq->ecs_server_out,
|
|
&qstate->edns_opts_back_out, qstate, region);
|
|
}
|
|
@@ -331,6 +343,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 +405,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) {
|
|
@@ -475,6 +491,69 @@ common_prefix(uint8_t *a, uint8_t *b, uint8_t net)
|
|
return !memcmp(a, b, n) && ((net % 8) == 0 || a[n] == b[n]);
|
|
}
|
|
|
|
+/**
|
|
+ * Create sub request that looks up the query.
|
|
+ * @param qstate: query state
|
|
+ * @param sq: subnet qstate
|
|
+ * @return false on failure.
|
|
+ */
|
|
+static int
|
|
+generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq)
|
|
+{
|
|
+ struct module_qstate* subq = NULL;
|
|
+ uint16_t qflags = 0; /* OPCODE QUERY, no flags */
|
|
+ int prime = 0;
|
|
+ int valrec = 0;
|
|
+ struct query_info qinf;
|
|
+ qinf.qname = qstate->qinfo.qname;
|
|
+ qinf.qname_len = qstate->qinfo.qname_len;
|
|
+ qinf.qtype = qstate->qinfo.qtype;
|
|
+ qinf.qclass = qstate->qinfo.qclass;
|
|
+ qinf.local_alias = NULL;
|
|
+
|
|
+ qflags |= BIT_RD;
|
|
+ if((qstate->query_flags & BIT_CD)!=0) {
|
|
+ qflags |= BIT_CD;
|
|
+ valrec = 1;
|
|
+ }
|
|
+
|
|
+ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
|
+ if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
|
|
+ &subq)) {
|
|
+ return 0;
|
|
+ }
|
|
+ if(subq) {
|
|
+ /* It is possible to access the subquery module state. */
|
|
+ if(sq->ecs_client_in.subnet_source_mask == 0 &&
|
|
+ edns_opt_list_find(qstate->edns_opts_front_in,
|
|
+ qstate->env->cfg->client_subnet_opcode)) {
|
|
+ subq->no_cache_store = 1;
|
|
+ }
|
|
+ }
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Perform the query without subnet
|
|
+ * @param qstate: query state
|
|
+ * @param sq: subnet qstate
|
|
+ * @return module state
|
|
+ */
|
|
+static enum module_ext_state
|
|
+generate_lookup_without_subnet(struct module_qstate *qstate,
|
|
+ struct subnet_qstate* sq)
|
|
+{
|
|
+ verbose(VERB_ALGO, "subnetcache: make subquery to look up without subnet");
|
|
+ if(!generate_sub_request(qstate, sq)) {
|
|
+ verbose(VERB_ALGO, "Could not generate sub query");
|
|
+ qstate->return_rcode = LDNS_RCODE_FORMERR;
|
|
+ qstate->return_msg = NULL;
|
|
+ return module_finished;
|
|
+ }
|
|
+ sq->wait_subquery = 1;
|
|
+ return module_wait_subquery;
|
|
+}
|
|
+
|
|
static enum module_ext_state
|
|
eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
|
{
|
|
@@ -495,7 +574,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
|
}
|
|
|
|
/* We have not asked for subnet data */
|
|
- if (!sq->subnet_sent) {
|
|
+ if (!sq->subnet_sent && !sq->subnet_sent_no_subnet) {
|
|
if (s_in->subnet_validdata)
|
|
verbose(VERB_QUERY, "subnetcache: received spurious data");
|
|
if (sq->subnet_downstream) /* Copy back to client */
|
|
@@ -504,22 +583,27 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
|
}
|
|
|
|
/* subnet sent but nothing came back */
|
|
- if (!s_in->subnet_validdata) {
|
|
+ if (!s_in->subnet_validdata && !sq->subnet_sent_no_subnet) {
|
|
/* The authority indicated no support for edns subnet. As a
|
|
* consequence the answer ended up in the regular cache. It
|
|
* is still useful to put it in the edns subnet cache for
|
|
* when a client explicitly asks for subnet specific answer. */
|
|
verbose(VERB_QUERY, "subnetcache: Authority indicates no support");
|
|
- if(!sq->started_no_cache_store) {
|
|
- lock_rw_wrlock(&sne->biglock);
|
|
- update_cache(qstate, id);
|
|
- lock_rw_unlock(&sne->biglock);
|
|
- }
|
|
- if (sq->subnet_downstream)
|
|
- cp_edns_bad_response(c_out, c_in);
|
|
- return module_finished;
|
|
+ return generate_lookup_without_subnet(qstate, sq);
|
|
}
|
|
-
|
|
+
|
|
+ /* Purposefully there was no sent subnet, and there is consequently
|
|
+ * no subnet in the answer. If there was, use the subnet in the answer
|
|
+ * anyway. But if there is not, treat it as a prefix 0 answer. */
|
|
+ if(sq->subnet_sent_no_subnet && !s_in->subnet_validdata) {
|
|
+ /* Fill in 0.0.0.0/0 scope 0, or ::0/0 scope 0, for caching. */
|
|
+ s_in->subnet_addr_fam = s_out->subnet_addr_fam;
|
|
+ s_in->subnet_source_mask = 0;
|
|
+ s_in->subnet_scope_mask = 0;
|
|
+ memset(s_in->subnet_addr, 0, INET6_SIZE);
|
|
+ s_in->subnet_validdata = 1;
|
|
+ }
|
|
+
|
|
/* Being here means we have asked for and got a subnet specific
|
|
* answer. Also, the answer from the authority is not yet cached
|
|
* anywhere. */
|
|
@@ -530,13 +614,14 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
|
!common_prefix(s_out->subnet_addr, s_in->subnet_addr,
|
|
s_out->subnet_source_mask))
|
|
{
|
|
- /* we can not accept, restart query without option */
|
|
+ /* we can not accept, perform query without option */
|
|
verbose(VERB_QUERY, "subnetcache: forged data");
|
|
s_out->subnet_validdata = 0;
|
|
(void)edns_opt_list_remove(&qstate->edns_opts_back_out,
|
|
qstate->env->cfg->client_subnet_opcode);
|
|
sq->subnet_sent = 0;
|
|
- return module_restart_next;
|
|
+ sq->subnet_sent_no_subnet = 0;
|
|
+ return generate_lookup_without_subnet(qstate, sq);
|
|
}
|
|
|
|
lock_rw_wrlock(&sne->biglock);
|
|
@@ -656,6 +741,7 @@ ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
|
|
edns_opt_list_remove(&qstate->edns_opts_back_out,
|
|
qstate->env->cfg->client_subnet_opcode);
|
|
sq->subnet_sent = 0;
|
|
+ sq->subnet_sent_no_subnet = 0;
|
|
memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out));
|
|
} else if (!sq->track_max_scope &&
|
|
FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_NOERROR &&
|
|
@@ -674,6 +760,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 +792,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
|
|
@@ -698,6 +803,12 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
|
|
sq->ecs_server_in.subnet_scope_mask >
|
|
sq->max_scope))
|
|
sq->max_scope = sq->ecs_server_in.subnet_scope_mask;
|
|
+ } else if(sq->subnet_sent_no_subnet) {
|
|
+ /* The answer can be stored as scope 0, not in global cache. */
|
|
+ qstate->no_cache_store = 1;
|
|
+ } else if(sq->subnet_sent) {
|
|
+ /* Need another query to be able to store in global cache. */
|
|
+ qstate->no_cache_store = 1;
|
|
}
|
|
|
|
return 1;
|
|
@@ -715,6 +826,32 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|
strmodulevent(event));
|
|
log_query_info(VERB_QUERY, "subnetcache operate: query", &qstate->qinfo);
|
|
|
|
+ if(sq && sq->wait_subquery_done) {
|
|
+ /* The subquery lookup returned. */
|
|
+ if(sq->ecs_client_in.subnet_source_mask == 0 &&
|
|
+ edns_opt_list_find(qstate->edns_opts_front_in,
|
|
+ qstate->env->cfg->client_subnet_opcode)) {
|
|
+ if(!sq->started_no_cache_store &&
|
|
+ qstate->return_msg) {
|
|
+ lock_rw_wrlock(&sne->biglock);
|
|
+ update_cache(qstate, id);
|
|
+ lock_rw_unlock(&sne->biglock);
|
|
+ }
|
|
+ if (sq->subnet_downstream)
|
|
+ cp_edns_bad_response(&sq->ecs_client_out,
|
|
+ &sq->ecs_client_in);
|
|
+ /* It is a scope zero lookup, append edns subnet
|
|
+ * option to the querier. */
|
|
+ subnet_ecs_opt_list_append(&sq->ecs_client_out,
|
|
+ &qstate->edns_opts_front_out, qstate,
|
|
+ qstate->region);
|
|
+ }
|
|
+ sq->wait_subquery_done = 0;
|
|
+ qstate->ext_state[id] = module_finished;
|
|
+ qstate->no_cache_store = sq->started_no_cache_store;
|
|
+ qstate->no_cache_lookup = sq->started_no_cache_lookup;
|
|
+ return;
|
|
+ }
|
|
if((event == module_event_new || event == module_event_pass) &&
|
|
sq == NULL) {
|
|
struct edns_option* ecs_opt;
|
|
@@ -725,6 +862,8 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|
}
|
|
|
|
sq = (struct subnet_qstate*)qstate->minfo[id];
|
|
+ if(sq->wait_subquery)
|
|
+ return; /* Wait for that subquery to return */
|
|
|
|
if((ecs_opt = edns_opt_list_find(
|
|
qstate->edns_opts_front_in,
|
|
@@ -736,6 +875,7 @@ 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) {
|
|
@@ -748,6 +888,14 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|
/* No clients are interested in result or we could not
|
|
* parse it, we don't do client subnet */
|
|
sq->ecs_server_out.subnet_validdata = 0;
|
|
+ if(edns_opt_list_find(qstate->edns_opts_front_in,
|
|
+ qstate->env->cfg->client_subnet_opcode)) {
|
|
+ /* aggregated this deaggregated state */
|
|
+ qstate->ext_state[id] =
|
|
+ generate_lookup_without_subnet(
|
|
+ qstate, sq);
|
|
+ return;
|
|
+ }
|
|
verbose(VERB_ALGO, "subnetcache: pass to next module");
|
|
qstate->ext_state[id] = module_wait_module;
|
|
return;
|
|
@@ -775,10 +923,25 @@ 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);
|
|
}
|
|
+ if(sq->ecs_client_in.subnet_source_mask == 0 &&
|
|
+ edns_opt_list_find(qstate->edns_opts_front_in,
|
|
+ qstate->env->cfg->client_subnet_opcode)) {
|
|
+ /* client asked for resolution without edns subnet */
|
|
+ qstate->ext_state[id] = generate_lookup_without_subnet(
|
|
+ qstate, sq);
|
|
+ return;
|
|
+ }
|
|
|
|
sq->ecs_server_out.subnet_addr_fam =
|
|
sq->ecs_client_in.subnet_addr_fam;
|
|
@@ -815,6 +978,8 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|
qstate->ext_state[id] = module_wait_module;
|
|
return;
|
|
}
|
|
+ if(sq && sq->wait_subquery)
|
|
+ return; /* Wait for that subquery to return */
|
|
/* Query handed back by next module, we have a 'final' answer */
|
|
if(sq && event == module_event_moddone) {
|
|
qstate->ext_state[id] = eval_response(qstate, id, sq);
|
|
@@ -823,6 +988,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;
|
|
@@ -856,10 +1028,27 @@ subnetmod_clear(struct module_qstate *ATTR_UNUSED(qstate),
|
|
}
|
|
|
|
void
|
|
-subnetmod_inform_super(struct module_qstate *ATTR_UNUSED(qstate),
|
|
- int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super))
|
|
+subnetmod_inform_super(struct module_qstate *qstate, int id,
|
|
+ struct module_qstate *super)
|
|
{
|
|
- /* Not used */
|
|
+ struct subnet_qstate* super_sq =
|
|
+ (struct subnet_qstate*)super->minfo[id];
|
|
+ log_query_info(VERB_ALGO, "subnetcache inform_super: query",
|
|
+ &super->qinfo);
|
|
+ super_sq->wait_subquery = 0;
|
|
+ super_sq->wait_subquery_done = 1;
|
|
+ if(qstate->return_rcode != LDNS_RCODE_NOERROR ||
|
|
+ !qstate->return_msg) {
|
|
+ super->return_msg = NULL;
|
|
+ super->return_rcode = LDNS_RCODE_SERVFAIL;
|
|
+ return;
|
|
+ }
|
|
+ super->return_rcode = LDNS_RCODE_NOERROR;
|
|
+ super->return_msg = dns_copy_msg(qstate->return_msg, super->region);
|
|
+ if(!super->return_msg) {
|
|
+ log_err("subnetcache: copy response, out of memory");
|
|
+ super->return_rcode = LDNS_RCODE_SERVFAIL;
|
|
+ }
|
|
}
|
|
|
|
size_t
|
|
diff --git a/unbound-1.16.2/edns-subnet/subnetmod.h b/unbound-1.16.2/edns-subnet/subnetmod.h
|
|
index f0bcaad..3893820 100644
|
|
--- a/unbound-1.16.2/edns-subnet/subnetmod.h
|
|
+++ b/unbound-1.16.2/edns-subnet/subnetmod.h
|
|
@@ -85,6 +85,13 @@ struct subnet_qstate {
|
|
struct ecs_data ecs_server_out;
|
|
int subnet_downstream;
|
|
int subnet_sent;
|
|
+ /**
|
|
+ * If there was no subnet sent because the client used source prefix
|
|
+ * length 0 for omitting the information. Then the answer is cached
|
|
+ * like subnet was a /0 scope. Like the subnet_sent flag, but when
|
|
+ * the EDNS subnet option is omitted because the client asked.
|
|
+ */
|
|
+ int subnet_sent_no_subnet;
|
|
/** keep track of longest received scope, set after receiving CNAME for
|
|
* incoming QNAME. */
|
|
int track_max_scope;
|
|
@@ -95,6 +102,10 @@ struct subnet_qstate {
|
|
int started_no_cache_store;
|
|
/** has the subnet module been started with no_cache_lookup? */
|
|
int started_no_cache_lookup;
|
|
+ /** Wait for subquery that has been started for nonsubnet lookup. */
|
|
+ int wait_subquery;
|
|
+ /** The subquery waited for is done. */
|
|
+ int wait_subquery_done;
|
|
};
|
|
|
|
void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
|
|
diff --git a/unbound-1.16.2/iterator/iterator.c b/unbound-1.16.2/iterator/iterator.c
|
|
index da9b799..3cacd5d 100644
|
|
--- a/unbound-1.16.2/iterator/iterator.c
|
|
+++ b/unbound-1.16.2/iterator/iterator.c
|
|
@@ -3982,10 +3982,10 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
/* like packet got dropped */
|
|
goto handle_it;
|
|
}
|
|
- if(!inplace_cb_edns_back_parsed_call(qstate->env, qstate)) {
|
|
- log_err("unable to call edns_back_parsed callback");
|
|
- goto handle_it;
|
|
- }
|
|
+ }
|
|
+ if(!inplace_cb_edns_back_parsed_call(qstate->env, qstate)) {
|
|
+ log_err("unable to call edns_back_parsed callback");
|
|
+ goto handle_it;
|
|
}
|
|
|
|
/* remove CD-bit, we asked for in case we handle validation ourself */
|
|
diff --git a/unbound-1.16.2/testcode/unitecs.c b/unbound-1.16.2/testcode/unitecs.c
|
|
index b240bfc..68d6907 100644
|
|
--- a/unbound-1.16.2/testcode/unitecs.c
|
|
+++ b/unbound-1.16.2/testcode/unitecs.c
|
|
@@ -173,7 +173,7 @@ static void consistency_test(void)
|
|
for (i = 0; i < 1000; i++) {
|
|
l = randomkey(&k, 128);
|
|
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
|
- addrtree_insert(t, k, l, 64, elem, timenow + 10, timenow);
|
|
+ addrtree_insert(t, k, l, 64, elem, timenow + 10, timenow, 0);
|
|
/* This should always hold because no items ever expire. They
|
|
* could be overwritten, though. */
|
|
unit_assert( count <= t->node_count );
|
|
@@ -189,7 +189,7 @@ static void consistency_test(void)
|
|
for (i = 0; i < 1000; i++) {
|
|
l = randomkey(&k, 128);
|
|
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
|
- addrtree_insert(t, k, l, 64, elem, i + 10, i);
|
|
+ addrtree_insert(t, k, l, 64, elem, i + 10, i, 0);
|
|
free(k);
|
|
unit_assert( !addrtree_inconsistent(t) );
|
|
}
|
|
@@ -201,7 +201,7 @@ static void consistency_test(void)
|
|
for (i = 0; i < 1000; i++) {
|
|
l = randomkey(&k, 128);
|
|
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
|
- addrtree_insert(t, k, l, 64, elem, i + 10, i);
|
|
+ addrtree_insert(t, k, l, 64, elem, i + 10, i, 0);
|
|
unit_assert( t->node_count <= 27);
|
|
free(k);
|
|
unit_assert( !addrtree_inconsistent(t) );
|
|
diff --git a/unbound-1.16.2/testdata/subnet_noecs_mult.rpl b/unbound-1.16.2/testdata/subnet_noecs_mult.rpl
|
|
new file mode 100644
|
|
index 0000000..3e2acef
|
|
--- /dev/null
|
|
+++ b/unbound-1.16.2/testdata/subnet_noecs_mult.rpl
|
|
@@ -0,0 +1,334 @@
|
|
+# config
|
|
+server:
|
|
+ send-client-subnet: 1.2.3.4
|
|
+ max-client-subnet-ipv4: 17
|
|
+ module-config: "subnetcache iterator"
|
|
+ qname-minimisation: no
|
|
+ minimal-responses: yes
|
|
+ target-fetch-policy: "0 0 0 0 0"
|
|
+
|
|
+stub-zone:
|
|
+ name: "."
|
|
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
|
+CONFIG_END
|
|
+
|
|
+SCENARIO_BEGIN Test subnet with no edns subnet from server multiple times
|
|
+; Multiple queries are sent to a server that does not reply with the
|
|
+; edns-subnet option.
|
|
+
|
|
+; K.ROOT-SERVERS.NET.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 193.0.14.129
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+. IN NS
|
|
+SECTION ANSWER
|
|
+. IN NS K.ROOT-SERVERS.NET.
|
|
+SECTION ADDITIONAL
|
|
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode subdomain
|
|
+ADJUST copy_id copy_query
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+com. IN NS
|
|
+SECTION AUTHORITY
|
|
+com. IN NS a.gtld-servers.net.
|
|
+SECTION ADDITIONAL
|
|
+a.gtld-servers.net. IN A 192.5.6.30
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; a.gtld-servers.net.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 192.5.6.30
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode subdomain
|
|
+ADJUST copy_id copy_query
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+example.com. IN NS
|
|
+SECTION AUTHORITY
|
|
+example.com. IN NS ns.example.com.
|
|
+SECTION ADDITIONAL
|
|
+ns.example.com. IN A 1.2.3.4
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; ns.example.com.
|
|
+RANGE_BEGIN 50 52
|
|
+ ADDRESS 1.2.3.4
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+example.com. IN NS
|
|
+SECTION ANSWER
|
|
+example.com. IN NS ns.example.com.
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+ns.example.com. IN A
|
|
+SECTION ANSWER
|
|
+ns.example.com. IN A 1.2.3.4
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+ns.example.com. IN AAAA
|
|
+SECTION ANSWER
|
|
+SECTION AUTHORITY
|
|
+example.com. IN SOA ns.example.com. host.example.com. 4 86400 3600 86400 3600
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname ednsdata
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+SECTION ADDITIONAL
|
|
+ ; Match this subnet option
|
|
+ HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 11 00 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+ HEX_EDNSDATA_END
|
|
+ ; This is the response, without the subnet option
|
|
+ HEX_ANSWER_BEGIN;
|
|
+ 00 00 84 00 00 01 00 01 ; ID 0 QR AA NOERROR
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01
|
|
+ C0 0C 00 01 00 01 00 00 0E 10 ; www.example.com. A IN 3600
|
|
+ 00 04 0A 14 1E 2C ; rdata 10.20.30.44
|
|
+ 00 00 29 10 00 00 00
|
|
+ 80 00 00 00
|
|
+ HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname ednsdata
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+SECTION ADDITIONAL
|
|
+ ; Match this subnet option
|
|
+ HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.2.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 11 00 ; source mask, scopemask
|
|
+ 7f 02 00 ; address
|
|
+ HEX_EDNSDATA_END
|
|
+ ; This is the response, without the subnet option
|
|
+ HEX_ANSWER_BEGIN;
|
|
+ 00 00 84 00 00 01 00 01 ; ID 0 QR AA NOERROR
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01
|
|
+ C0 0C 00 01 00 01 00 00 0E 10 ; www.example.com. A IN 3600
|
|
+ 00 04 0A 14 1E 2C ; rdata 10.20.30.44
|
|
+ 00 00 29 10 00 00 00
|
|
+ 80 00 00 00
|
|
+ HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname ednsdata
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+SECTION ADDITIONAL
|
|
+ ; Match this subnet option
|
|
+ HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.3.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 11 00 ; source mask, scopemask
|
|
+ 7f 03 00 ; address
|
|
+ HEX_EDNSDATA_END
|
|
+ ; This is the response, without the subnet option
|
|
+ HEX_ANSWER_BEGIN;
|
|
+ 00 00 84 00 00 01 00 01 ; ID 0 QR AA NOERROR
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01
|
|
+ C0 0C 00 01 00 01 00 00 0E 10 ; www.example.com. A IN 3600
|
|
+ 00 04 0A 14 1E 2C ; rdata 10.20.30.44
|
|
+ 00 00 29 10 00 00 00
|
|
+ 80 00 00 00
|
|
+ HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; The answer for a query without subnet
|
|
+;ENTRY_BEGIN
|
|
+;MATCH opcode qtype qname
|
|
+;ADJUST copy_id
|
|
+;REPLY QR AA NOERROR
|
|
+;SECTION QUESTION
|
|
+;www.example.com. IN A
|
|
+;SECTION ANSWER
|
|
+;www.example.com. IN A 10.20.30.40
|
|
+;ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; ns.example.com.
|
|
+RANGE_BEGIN 53 57
|
|
+ ADDRESS 1.2.3.4
|
|
+; The answer for a query without subnet
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+STEP 10 QUERY
|
|
+ENTRY_BEGIN
|
|
+ HEX_ANSWER_BEGIN;
|
|
+ 00 00 01 00 00 01 00 00 ; ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 11 00 ; ip4, scope 17, source 0
|
|
+ 7f 00 00 ; 127.0.0.0/17
|
|
+ HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+STEP 20 QUERY
|
|
+ENTRY_BEGIN
|
|
+ HEX_ANSWER_BEGIN;
|
|
+ 00 00 01 00 00 01 00 00 ; ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 11 00 ; ip4, scope 17, source 0
|
|
+ 7f 02 00 ; 127.2.0.0/17
|
|
+ HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+STEP 30 QUERY
|
|
+ENTRY_BEGIN
|
|
+ HEX_ANSWER_BEGIN;
|
|
+ 00 00 01 00 00 01 00 00 ; ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 11 00 ; ip4, scope 17, source 0
|
|
+ 7f 03 00 ; 127.3.0.0/17
|
|
+ HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; recursion happens here.
|
|
+; The upstream server RANGE starts responding at STEP 50.
|
|
+STEP 50 TRAFFIC
|
|
+
|
|
+; The upstream server now responds for the nonsubnet response.
|
|
+STEP 55 TRAFFIC
|
|
+
|
|
+STEP 60 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA DO NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+;www.example.com. IN A 10.20.30.44
|
|
+SECTION ADDITIONAL
|
|
+; HEX_EDNSDATA_BEGIN
|
|
+; ; client is 127.3.0.1
|
|
+; 00 08 ; OPC
|
|
+; 00 07 ; option length
|
|
+; 00 01 ; Family
|
|
+; 11 00 ; source mask, scopemask
|
|
+; 7f 03 00 ; address
|
|
+; HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+STEP 70 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA DO NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+;www.example.com. IN A 10.20.30.44
|
|
+SECTION ADDITIONAL
|
|
+; HEX_EDNSDATA_BEGIN
|
|
+; ; client is 127.2.0.1
|
|
+; 00 08 ; OPC
|
|
+; 00 07 ; option length
|
|
+; 00 01 ; Family
|
|
+; 11 00 ; source mask, scopemask
|
|
+; 7f 02 00 ; address
|
|
+; HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+STEP 80 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA DO NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+;www.example.com. IN A 10.20.30.44
|
|
+SECTION ADDITIONAL
|
|
+; HEX_EDNSDATA_BEGIN
|
|
+; ; client is 127.0.0.1
|
|
+; 00 08 ; OPC
|
|
+; 00 07 ; option length
|
|
+; 00 01 ; Family
|
|
+; 11 00 ; source mask, scopemask
|
|
+; 7f 00 00 ; address
|
|
+; HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+SCENARIO_END
|
|
diff --git a/unbound-1.16.2/testdata/subnet_noecs_refused.rpl b/unbound-1.16.2/testdata/subnet_noecs_refused.rpl
|
|
new file mode 100644
|
|
index 0000000..39fbe85
|
|
--- /dev/null
|
|
+++ b/unbound-1.16.2/testdata/subnet_noecs_refused.rpl
|
|
@@ -0,0 +1,159 @@
|
|
+# config
|
|
+server:
|
|
+ send-client-subnet: 1.2.3.4
|
|
+ max-client-subnet-ipv4: 17
|
|
+ module-config: "subnetcache iterator"
|
|
+ qname-minimisation: no
|
|
+ minimal-responses: yes
|
|
+ target-fetch-policy: "0 0 0 0 0"
|
|
+
|
|
+stub-zone:
|
|
+ name: "."
|
|
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
|
+CONFIG_END
|
|
+
|
|
+SCENARIO_BEGIN Test subnet with no edns subnet support but it is refused
|
|
+; The query is sent to a server that does not reply with the edns-subnet
|
|
+; option. The upstream server sends rcode refused. That results in a
|
|
+; NULL return_msg.
|
|
+
|
|
+; K.ROOT-SERVERS.NET.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 193.0.14.129
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+. IN NS
|
|
+SECTION ANSWER
|
|
+. IN NS K.ROOT-SERVERS.NET.
|
|
+SECTION ADDITIONAL
|
|
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode subdomain
|
|
+ADJUST copy_id copy_query
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+com. IN NS
|
|
+SECTION AUTHORITY
|
|
+com. IN NS a.gtld-servers.net.
|
|
+SECTION ADDITIONAL
|
|
+a.gtld-servers.net. IN A 192.5.6.30
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; a.gtld-servers.net.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 192.5.6.30
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode subdomain
|
|
+ADJUST copy_id copy_query
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+example.com. IN NS
|
|
+SECTION AUTHORITY
|
|
+example.com. IN NS ns.example.com.
|
|
+SECTION ADDITIONAL
|
|
+ns.example.com. IN A 1.2.3.4
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; ns.example.com.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 1.2.3.4
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+example.com. IN NS
|
|
+SECTION ANSWER
|
|
+example.com. IN NS ns.example.com.
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+ns.example.com. IN A
|
|
+SECTION ANSWER
|
|
+ns.example.com. IN A 1.2.3.4
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+ns.example.com. IN AAAA
|
|
+SECTION ANSWER
|
|
+SECTION AUTHORITY
|
|
+example.com. IN SOA ns.example.com. host.example.com. 4 86400 3600 86400 3600
|
|
+ENTRY_END
|
|
+
|
|
+; This matches the no EDNS subnet info queries that are made for the
|
|
+; fallback without subnet. The answer is refused.
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname ednsdata
|
|
+ADJUST copy_id
|
|
+REPLY QR AA REFUSED
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+;www.example.com. IN A 10.20.30.40
|
|
+ENTRY_END
|
|
+
|
|
+; This matches the initial query with edns subnet in the query,
|
|
+; the answer has no edns subnet in the reply.
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+STEP 1 QUERY
|
|
+;ENTRY_BEGIN
|
|
+;REPLY RD DO
|
|
+;SECTION QUESTION
|
|
+;www.example.com. IN A
|
|
+; but send this query with subnet scope zero in the query, because that
|
|
+; makes the reply possibly get stored in the cache.
|
|
+;
|
|
+; query with subnet 0.0.0.0/0.
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 08
|
|
+
|
|
+ 00 08 00 04 ; OPC, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ;0.0.0.0/0
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; recursion happens here.
|
|
+STEP 10 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA DO SERVFAIL
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+;www.example.com. IN A 10.20.30.40
|
|
+ENTRY_END
|
|
+SCENARIO_END
|
|
diff --git a/unbound-1.16.2/testdata/subnet_noecs_support.rpl b/unbound-1.16.2/testdata/subnet_noecs_support.rpl
|
|
new file mode 100644
|
|
index 0000000..0c9826c
|
|
--- /dev/null
|
|
+++ b/unbound-1.16.2/testdata/subnet_noecs_support.rpl
|
|
@@ -0,0 +1,127 @@
|
|
+# config
|
|
+server:
|
|
+ send-client-subnet: 1.2.3.4
|
|
+ max-client-subnet-ipv4: 17
|
|
+ module-config: "subnetcache iterator"
|
|
+ qname-minimisation: no
|
|
+ minimal-responses: yes
|
|
+ target-fetch-policy: "0 0 0 0 0"
|
|
+
|
|
+stub-zone:
|
|
+ name: "."
|
|
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
|
+CONFIG_END
|
|
+
|
|
+SCENARIO_BEGIN Test subnet with no edns subnet support from the server
|
|
+; The query is sent to a server that does not reply with the edns-subnet
|
|
+; option.
|
|
+
|
|
+; K.ROOT-SERVERS.NET.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 193.0.14.129
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+. IN NS
|
|
+SECTION ANSWER
|
|
+. IN NS K.ROOT-SERVERS.NET.
|
|
+SECTION ADDITIONAL
|
|
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode subdomain
|
|
+ADJUST copy_id copy_query
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+com. IN NS
|
|
+SECTION AUTHORITY
|
|
+com. IN NS a.gtld-servers.net.
|
|
+SECTION ADDITIONAL
|
|
+a.gtld-servers.net. IN A 192.5.6.30
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; a.gtld-servers.net.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 192.5.6.30
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode subdomain
|
|
+ADJUST copy_id copy_query
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+example.com. IN NS
|
|
+SECTION AUTHORITY
|
|
+example.com. IN NS ns.example.com.
|
|
+SECTION ADDITIONAL
|
|
+ns.example.com. IN A 1.2.3.4
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; ns.example.com.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 1.2.3.4
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+example.com. IN NS
|
|
+SECTION ANSWER
|
|
+example.com. IN NS ns.example.com.
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+ns.example.com. IN A
|
|
+SECTION ANSWER
|
|
+ns.example.com. IN A 1.2.3.4
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+ns.example.com. IN AAAA
|
|
+SECTION ANSWER
|
|
+SECTION AUTHORITY
|
|
+example.com. IN SOA ns.example.com. host.example.com. 4 86400 3600 86400 3600
|
|
+ENTRY_END
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+STEP 1 QUERY
|
|
+ENTRY_BEGIN
|
|
+REPLY RD DO
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+ENTRY_END
|
|
+
|
|
+; recursion happens here.
|
|
+STEP 10 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA DO NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+ENTRY_END
|
|
+SCENARIO_END
|
|
diff --git a/unbound-1.16.2/testdata/subnet_prezero.rpl b/unbound-1.16.2/testdata/subnet_prezero.rpl
|
|
new file mode 100644
|
|
index 0000000..22cdfff
|
|
--- /dev/null
|
|
+++ b/unbound-1.16.2/testdata/subnet_prezero.rpl
|
|
@@ -0,0 +1,155 @@
|
|
+; subnet unit test
|
|
+server:
|
|
+ trust-anchor-signaling: no
|
|
+ send-client-subnet: 1.2.3.4
|
|
+ send-client-subnet: 1.2.3.5
|
|
+ target-fetch-policy: "0 0 0 0 0"
|
|
+ module-config: "subnetcache validator iterator"
|
|
+ qname-minimisation: no
|
|
+ minimal-responses: no
|
|
+
|
|
+stub-zone:
|
|
+ name: "example.com"
|
|
+ stub-addr: 1.2.3.4
|
|
+CONFIG_END
|
|
+
|
|
+SCENARIO_BEGIN Test subnetcache source prefix zero from client.
|
|
+; In RFC7871 section-7.1.2 (para. 2).
|
|
+; It says that the recursor must send no EDNS subnet or its own address
|
|
+; in the EDNS subnet to the upstream server. And use that answer for the
|
|
+; source prefix length zero query. That type of query is for privacy.
|
|
+; The authority server is then going to use the resolver's IP, if any, to
|
|
+; tailor the answer to the query source address.
|
|
+
|
|
+; ns.example.com
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 1.2.3.4
|
|
+
|
|
+; reply with 0.0.0.0/0 in reply
|
|
+; For the test the answers for 0.0.0.0/0 queries are SERVFAIL, the normal
|
|
+; answers are NOERROR.
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname ednsdata
|
|
+ADJUST copy_id
|
|
+REPLY QR AA DO SERVFAIL
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN CNAME star.c10r.example.com.
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 00 04 ; OPCODE=subnet, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ; 0.0.0.0/0
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; reply without subnet
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA DO NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN CNAME star.c10r.example.com.
|
|
+ENTRY_END
|
|
+
|
|
+; delegation answer for c10r.example.com, with subnet /0
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode subdomain ednsdata
|
|
+ADJUST copy_id copy_query
|
|
+REPLY QR DO SERVFAIL
|
|
+SECTION QUESTION
|
|
+c10r.example.com. IN NS
|
|
+SECTION AUTHORITY
|
|
+c10r.example.com. IN NS ns.c10r.example.com.
|
|
+SECTION ADDITIONAL
|
|
+ns.c10r.example.com. IN A 1.2.3.5
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 00 04 ; OPCODE=subnet, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ; 0.0.0.0/0
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; delegation answer for c10r.example.com, without subnet
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode subdomain
|
|
+ADJUST copy_id copy_query
|
|
+REPLY QR DO NOERROR
|
|
+SECTION QUESTION
|
|
+c10r.example.com. IN NS
|
|
+SECTION AUTHORITY
|
|
+c10r.example.com. IN NS ns.c10r.example.com.
|
|
+SECTION ADDITIONAL
|
|
+ns.c10r.example.com. IN A 1.2.3.5
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; ns.c10r.example.com
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 1.2.3.5
|
|
+
|
|
+; reply with 0.0.0.0/0 in reply
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname ednsdata
|
|
+ADJUST copy_id
|
|
+REPLY QR AA DO SERVFAIL
|
|
+SECTION QUESTION
|
|
+star.c10r.example.com. IN A
|
|
+SECTION ANSWER
|
|
+star.c10r.example.com. IN A 1.2.3.6
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 00 04 ; OPCODE=subnet, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ; 0.0.0.0/0
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; reply without subnet
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+REPLY QR AA DO NOERROR
|
|
+SECTION QUESTION
|
|
+star.c10r.example.com. IN A
|
|
+SECTION ANSWER
|
|
+star.c10r.example.com. IN A 1.2.3.6
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; ask for www.example.com
|
|
+; server answers with CNAME to a delegation, that then
|
|
+; returns a /24 answer.
|
|
+STEP 1 QUERY
|
|
+ENTRY_BEGIN
|
|
+REPLY RD DO
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 00 04 ; OPCODE=subnet, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ; 0.0.0.0/0
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+STEP 10 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA DO NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN CNAME star.c10r.example.com.
|
|
+star.c10r.example.com. IN A 1.2.3.6
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 00 04 ; OPCODE=subnet, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ; 0.0.0.0/0
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+SCENARIO_END
|
|
diff --git a/unbound-1.16.2/testdata/subnet_scopezero.rpl b/unbound-1.16.2/testdata/subnet_scopezero.rpl
|
|
new file mode 100644
|
|
index 0000000..e006514
|
|
--- /dev/null
|
|
+++ b/unbound-1.16.2/testdata/subnet_scopezero.rpl
|
|
@@ -0,0 +1,439 @@
|
|
+; scope of 0, if the query also had scope of 0, do not answer this
|
|
+; to everyone, but only for scope 0 queries. Otherwise can answer cached.
|
|
+
|
|
+server:
|
|
+ target-fetch-policy: "0 0 0 0 0"
|
|
+ send-client-subnet: 1.2.3.4
|
|
+ module-config: "subnetcache validator iterator"
|
|
+ verbosity: 4
|
|
+ qname-minimisation: no
|
|
+
|
|
+stub-zone:
|
|
+ name: "."
|
|
+ stub-addr: 193.0.14.129
|
|
+
|
|
+stub-zone:
|
|
+ name: "example.com"
|
|
+ stub-addr: 1.2.3.4
|
|
+CONFIG_END
|
|
+
|
|
+SCENARIO_BEGIN Test subnet cache with scope zero queries and responses.
|
|
+
|
|
+; the upstream server.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 193.0.14.129
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname ednsdata
|
|
+ADJUST copy_id
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+. IN NS
|
|
+SECTION ANSWER
|
|
+. IN NS K.ROOT-SERVERS.NET.
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ;; we expect to receive empty
|
|
+HEX_EDNSDATA_END
|
|
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+RANGE_BEGIN 0 11
|
|
+ ADDRESS 1.2.3.4
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+;copy_ednsdata_assume_clientsubnet
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+RANGE_BEGIN 20 31
|
|
+ ADDRESS 1.2.3.4
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+;copy_ednsdata_assume_clientsubnet
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.41
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 01 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+RANGE_BEGIN 40 51
|
|
+ ADDRESS 1.2.3.4
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+;copy_ednsdata_assume_clientsubnet
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.42
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 ; OPC
|
|
+ 00 04 ; option length
|
|
+ 00 01 ; Family
|
|
+ 00 00 ; source mask, scopemask
|
|
+ ; address 0.0.0.0/0 scope 0
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+RANGE_BEGIN 120 131
|
|
+ ADDRESS 1.2.3.4
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+;copy_ednsdata_assume_clientsubnet
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.43
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 00 ; source mask, scopemask
|
|
+ 7f 02 00 ; address 127.2.0.0/24 scope 0
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; query for 127.0.0.0/24
|
|
+STEP 1 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 00 00 ;127.0.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer is 10.20.30.40 for 127.0.0.0/24 scope 17
|
|
+STEP 10 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 127.1.0.0/24
|
|
+STEP 20 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 01 00 ;127.1.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer is 10.20.30.41 for 127.1.0.0/24 scope 17
|
|
+STEP 30 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.41
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.1.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 01 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 0.0.0.0/0
|
|
+STEP 40 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 08
|
|
+
|
|
+ 00 08 00 04 ; OPC, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ;0.0.0.0/0
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer is 10.20.30.42 for 0.0.0.0/0 scope 0
|
|
+STEP 50 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.42
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 ; OPC
|
|
+ 00 04 ; option length
|
|
+ 00 01 ; Family
|
|
+ 00 00 ; source mask, scopemask
|
|
+ ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 127.0.0.0/24, again, it should be in cache.
|
|
+; and not from the scope 0 answer.
|
|
+STEP 60 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 00 00 ;127.0.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer should be 10.20.30.40 for 127.0.0.0/24 scope 17
|
|
+STEP 70 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 127.1.0.0/24, again, it should be in cache.
|
|
+STEP 80 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 01 00 ;127.1.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer should be 10.20.30.41 for 127.1.0.0/24 scope 17
|
|
+STEP 90 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.41
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.1.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 01 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 0.0.0.0/0, again.
|
|
+STEP 100 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 08
|
|
+
|
|
+ 00 08 00 04 ; OPC, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ;0.0.0.0/0
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer should be 10.20.30.42 for 0.0.0.0/0 scope 0
|
|
+STEP 110 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.42
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 ; OPC
|
|
+ 00 04 ; option length
|
|
+ 00 01 ; Family
|
|
+ 00 00 ; source mask, scopemask
|
|
+ ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; now a query for a /24 that gets an answer for a /0.
|
|
+STEP 120 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 02 00 ;127.2.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer should be 10.20.30.43 for 127.2.0.0/24 scope 0
|
|
+STEP 130 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.43
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.2.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 00 ; source mask, scopemask
|
|
+ 7f 02 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; the scope 0 answer is now used to answer queries from
|
|
+; query for 127.0.0.0/24
|
|
+STEP 140 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 00 00 ;127.0.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+STEP 150 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.43
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 00 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+SCENARIO_END
|
|
diff --git a/unbound-1.16.2/testdata/subnet_scopezero_noedns.rpl b/unbound-1.16.2/testdata/subnet_scopezero_noedns.rpl
|
|
new file mode 100644
|
|
index 0000000..25df0dd
|
|
--- /dev/null
|
|
+++ b/unbound-1.16.2/testdata/subnet_scopezero_noedns.rpl
|
|
@@ -0,0 +1,441 @@
|
|
+; scope of 0, if the query also had scope of 0, do not answer this
|
|
+; to everyone, but only for scope 0 queries. Otherwise can answer cached.
|
|
+
|
|
+server:
|
|
+ target-fetch-policy: "0 0 0 0 0"
|
|
+ send-client-subnet: 1.2.3.4
|
|
+ module-config: "subnetcache validator iterator"
|
|
+ verbosity: 4
|
|
+ qname-minimisation: no
|
|
+
|
|
+stub-zone:
|
|
+ name: "."
|
|
+ stub-addr: 193.0.14.129
|
|
+
|
|
+stub-zone:
|
|
+ name: "example.com"
|
|
+ stub-addr: 1.2.3.4
|
|
+CONFIG_END
|
|
+
|
|
+SCENARIO_BEGIN Test subnet cache with scope zero response without EDNS.
|
|
+
|
|
+; the upstream server.
|
|
+RANGE_BEGIN 0 100
|
|
+ ADDRESS 193.0.14.129
|
|
+
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname ednsdata
|
|
+ADJUST copy_id
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+. IN NS
|
|
+SECTION ANSWER
|
|
+. IN NS K.ROOT-SERVERS.NET.
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ;; we expect to receive empty
|
|
+HEX_EDNSDATA_END
|
|
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+RANGE_BEGIN 0 11
|
|
+ ADDRESS 1.2.3.4
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+;copy_ednsdata_assume_clientsubnet
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+RANGE_BEGIN 20 31
|
|
+ ADDRESS 1.2.3.4
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+;copy_ednsdata_assume_clientsubnet
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.41
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 01 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+RANGE_BEGIN 40 51
|
|
+ ADDRESS 1.2.3.4
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+;copy_ednsdata_assume_clientsubnet
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.42
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+;no EDNS in this answer. Tests if the back_parsed callback
|
|
+;is called to process the lack of edns contents.
|
|
+;HEX_EDNSDATA_BEGIN
|
|
+ ;00 08 ; OPC
|
|
+ ;00 04 ; option length
|
|
+ ;00 01 ; Family
|
|
+ ;00 00 ; source mask, scopemask
|
|
+ ; ; address 0.0.0.0/0 scope 0
|
|
+;HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+RANGE_BEGIN 120 131
|
|
+ ADDRESS 1.2.3.4
|
|
+ENTRY_BEGIN
|
|
+MATCH opcode qtype qname
|
|
+ADJUST copy_id
|
|
+;copy_ednsdata_assume_clientsubnet
|
|
+REPLY QR NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.43
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 00 ; source mask, scopemask
|
|
+ 7f 02 00 ; address 127.2.0.0/24 scope 0
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+RANGE_END
|
|
+
|
|
+; query for 127.0.0.0/24
|
|
+STEP 1 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 00 00 ;127.0.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer is 10.20.30.40 for 127.0.0.0/24 scope 17
|
|
+STEP 10 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 127.1.0.0/24
|
|
+STEP 20 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 01 00 ;127.1.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer is 10.20.30.41 for 127.1.0.0/24 scope 17
|
|
+STEP 30 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.41
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.1.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 01 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 0.0.0.0/0
|
|
+STEP 40 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 08
|
|
+
|
|
+ 00 08 00 04 ; OPC, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ;0.0.0.0/0
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer is 10.20.30.42 for 0.0.0.0/0 scope 0
|
|
+STEP 50 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.42
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 ; OPC
|
|
+ 00 04 ; option length
|
|
+ 00 01 ; Family
|
|
+ 00 00 ; source mask, scopemask
|
|
+ ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 127.0.0.0/24, again, it should be in cache.
|
|
+; and not from the scope 0 answer.
|
|
+STEP 60 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 00 00 ;127.0.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer should be 10.20.30.40 for 127.0.0.0/24 scope 17
|
|
+STEP 70 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.40
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 127.1.0.0/24, again, it should be in cache.
|
|
+STEP 80 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 01 00 ;127.1.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer should be 10.20.30.41 for 127.1.0.0/24 scope 17
|
|
+STEP 90 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.41
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.1.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 11 ; source mask, scopemask
|
|
+ 7f 01 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; query for 0.0.0.0/0, again.
|
|
+STEP 100 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 08
|
|
+
|
|
+ 00 08 00 04 ; OPC, optlen
|
|
+ 00 01 00 00 ; ip4, scope 0, source 0
|
|
+ ;0.0.0.0/0
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer should be 10.20.30.42 for 0.0.0.0/0 scope 0
|
|
+STEP 110 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.42
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ 00 08 ; OPC
|
|
+ 00 04 ; option length
|
|
+ 00 01 ; Family
|
|
+ 00 00 ; source mask, scopemask
|
|
+ ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; now a query for a /24 that gets an answer for a /0.
|
|
+STEP 120 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 02 00 ;127.2.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+; answer should be 10.20.30.43 for 127.2.0.0/24 scope 0
|
|
+STEP 130 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.43
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.2.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 00 ; source mask, scopemask
|
|
+ 7f 02 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+; the scope 0 answer is now used to answer queries from
|
|
+; query for 127.0.0.0/24
|
|
+STEP 140 QUERY
|
|
+ENTRY_BEGIN
|
|
+HEX_ANSWER_BEGIN
|
|
+ 00 00 01 00 00 01 00 00 ;ID 0
|
|
+ 00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
|
+ 07 65 78 61 6d 70 6c 65
|
|
+ 03 63 6f 6d 00 00 01 00
|
|
+ 01 00 00 29 10 00 00 00
|
|
+ 80 00 00 0b
|
|
+
|
|
+ 00 08 00 07 ; OPC, optlen
|
|
+ 00 01 18 00 ; ip4, scope 24, source 0
|
|
+ 7f 00 00 ;127.0.0.0/24
|
|
+HEX_ANSWER_END
|
|
+ENTRY_END
|
|
+
|
|
+STEP 150 CHECK_ANSWER
|
|
+ENTRY_BEGIN
|
|
+MATCH all ednsdata
|
|
+REPLY QR RD RA NOERROR
|
|
+SECTION QUESTION
|
|
+www.example.com. IN A
|
|
+SECTION ANSWER
|
|
+www.example.com. IN A 10.20.30.43
|
|
+SECTION AUTHORITY
|
|
+SECTION ADDITIONAL
|
|
+HEX_EDNSDATA_BEGIN
|
|
+ ; client is 127.0.0.1
|
|
+ 00 08 ; OPC
|
|
+ 00 07 ; option length
|
|
+ 00 01 ; Family
|
|
+ 18 00 ; source mask, scopemask
|
|
+ 7f 00 00 ; address
|
|
+HEX_EDNSDATA_END
|
|
+ENTRY_END
|
|
+
|
|
+SCENARIO_END
|