|
|
|
@@ -32,7 +32,33 @@
|
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
*/
|
|
|
|
|
// @JESSE: Iterator (this file) is the module that does all the needed DNS
|
|
|
|
|
// iterations and walking the DNS tree to try and find an answer.
|
|
|
|
|
// It includes but not limited to:
|
|
|
|
|
// 1. Finding the closest known delegation point
|
|
|
|
|
// (root at startup, or configured zones)
|
|
|
|
|
// 2. Sends a query (the original query if no qname-minimisation)
|
|
|
|
|
// to that and gets either an answer or a referral answer.
|
|
|
|
|
// 3. In case of referral answer goes back to 1.
|
|
|
|
|
//
|
|
|
|
|
// A lot more is happening here, like fallbacks and retries. Don't try
|
|
|
|
|
// to understand everything at once, it's better to go with the flow
|
|
|
|
|
// and see what is relevant for you.
|
|
|
|
|
|
|
|
|
|
// @JESSE: We do not use '//' comments in the Unbound code base. I explicitly
|
|
|
|
|
// use them to identify non-relevant parts or WIP comments.
|
|
|
|
|
|
|
|
|
|
// @JESSE: Some tips:
|
|
|
|
|
// - For printf kind of debug logging it's easier to use log_err();
|
|
|
|
|
// these are printed on all verbosity levels.
|
|
|
|
|
// - For domain name manipulation methods you can have a look at
|
|
|
|
|
// dname.c/h.
|
|
|
|
|
// - If you need to do allocations; for your case everything should
|
|
|
|
|
// have the lifetime of the query state (qstate); you can use
|
|
|
|
|
// qstate->region as your arena allocator and pass that region to
|
|
|
|
|
// functions that require one. You can then alloc items there and
|
|
|
|
|
// forget about them. The whole region is freed when the qstate is
|
|
|
|
|
// no more.
|
|
|
|
|
/**
|
|
|
|
|
* \file
|
|
|
|
|
*
|
|
|
|
@@ -70,6 +96,7 @@
|
|
|
|
|
#include "sldns/parseutil.h"
|
|
|
|
|
#include "sldns/sbuffer.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* in msec */
|
|
|
|
|
int UNKNOWN_SERVER_NICENESS = 376;
|
|
|
|
|
/* in msec */
|
|
|
|
@@ -136,6 +163,8 @@ iter_deinit(struct module_env* env, int id)
|
|
|
|
|
static int
|
|
|
|
|
iter_new(struct module_qstate* qstate, int id)
|
|
|
|
|
{
|
|
|
|
|
// @JESSE: each module can have its own query state. The iter_qstate
|
|
|
|
|
// struct below is the state for the iterator.
|
|
|
|
|
struct iter_qstate* iq = (struct iter_qstate*)regional_alloc(
|
|
|
|
|
qstate->region, sizeof(struct iter_qstate));
|
|
|
|
|
qstate->minfo[id] = iq;
|
|
|
|
@@ -164,7 +193,13 @@ iter_new(struct module_qstate* qstate, int id)
|
|
|
|
|
iq->dnssec_lame_query = 0;
|
|
|
|
|
iq->chase_flags = qstate->query_flags;
|
|
|
|
|
/* Start with the (current) qname. */
|
|
|
|
|
// @JESSE: iq->qchase will be the qinfo iterator will be working on and
|
|
|
|
|
// updating through the iteration process. It is set here to
|
|
|
|
|
// the initial query (qstate->qinfo) that started all this.
|
|
|
|
|
iq->qchase = qstate->qinfo;
|
|
|
|
|
iq->deleg_state = 2;
|
|
|
|
|
iq->deleg_original_qname_len = 0;
|
|
|
|
|
iq->deleg_original_qname = NULL;
|
|
|
|
|
outbound_list_init(&iq->outlist);
|
|
|
|
|
iq->minimise_count = 0;
|
|
|
|
|
iq->timeout_count = 0;
|
|
|
|
@@ -172,7 +207,7 @@ iter_new(struct module_qstate* qstate, int id)
|
|
|
|
|
iq->minimisation_state = INIT_MINIMISE_STATE;
|
|
|
|
|
else
|
|
|
|
|
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
|
|
|
|
|
|
|
|
|
// @JESSE: iq->qinfo_out is the qinfo that will be sent out.
|
|
|
|
|
memset(&iq->qinfo_out, 0, sizeof(struct query_info));
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
@@ -1596,8 +1631,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
delname = iq->dp->name;
|
|
|
|
|
delnamelen = iq->dp->namelen;
|
|
|
|
|
} else {
|
|
|
|
|
delname = iq->qchase.qname;
|
|
|
|
|
delnamelen = iq->qchase.qname_len;
|
|
|
|
|
// @JESSE: Here we set the delegation name to be the original
|
|
|
|
|
// one ...
|
|
|
|
|
delname = iq->qchase.qname;
|
|
|
|
|
delnamelen = iq->qchase.qname_len;
|
|
|
|
|
}
|
|
|
|
|
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
|
|
|
|
|
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
|
|
|
|
@@ -1618,8 +1655,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
|
|
|
|
|
/* Lookup the delegation in the cache. If null, then the
|
|
|
|
|
* cache needs to be primed for the qclass. */
|
|
|
|
|
// @JESSE: ... and here we'll try to get the closest delegation
|
|
|
|
|
// from cache.
|
|
|
|
|
if(delname)
|
|
|
|
|
iq->dp = dns_cache_find_delegation(qstate->env, delname,
|
|
|
|
|
iq->dp = dns_cache_find_delegation(qstate->env, delname,
|
|
|
|
|
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
|
|
|
|
|
qstate->region, &iq->deleg_msg,
|
|
|
|
|
*qstate->env->now+qstate->prefetch_leeway, 1,
|
|
|
|
@@ -2384,6 +2423,7 @@ check_waiting_queries(struct iter_qstate* iq, struct module_qstate* qstate,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// @JESSE: This is where most of the iteration time will be spent.
|
|
|
|
|
/**
|
|
|
|
|
* This is the request event state where the request will be sent to one of
|
|
|
|
|
* its current query targets. This state also handles issuing target lookup
|
|
|
|
@@ -2537,6 +2577,77 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
if(!ie->supports_ipv4 && !ie->use_nat64)
|
|
|
|
|
delegpt_no_ipv4(iq->dp);
|
|
|
|
|
delegpt_log(VERB_ALGO, iq->dp);
|
|
|
|
|
log_err("Tes Test jesse jess", iq->deleg_original_qname);
|
|
|
|
|
|
|
|
|
|
uint8_t root_len = iq->qchase.qname[0];
|
|
|
|
|
//todo have to remove this from iq when query has been resolved
|
|
|
|
|
if (iq->deleg_original_qname == NULL) {
|
|
|
|
|
iq->deleg_original_qname = (uint8_t *)regional_alloc(qstate->region, iq->qchase.qname_len + 1);
|
|
|
|
|
memcpy(iq->deleg_original_qname, qstate->qinfo.qname, iq->qchase.qname_len);
|
|
|
|
|
iq->deleg_original_qname_len = iq->qchase.qname_len;
|
|
|
|
|
iq->original_query = iq->qchase.qtype;
|
|
|
|
|
} else {
|
|
|
|
|
//restore qname to original to put _deleg in correct point
|
|
|
|
|
memcpy(qstate->qinfo.qname, iq->deleg_original_qname, iq->deleg_original_qname_len);
|
|
|
|
|
memcpy(iq->qchase.qname, iq->deleg_original_qname, iq->deleg_original_qname_len);
|
|
|
|
|
iq->qchase.qname_len = iq->deleg_original_qname_len;
|
|
|
|
|
iq->qchase.qtype = iq->original_query;
|
|
|
|
|
iq->qinfo_out.qtype = iq->original_query;
|
|
|
|
|
}
|
|
|
|
|
if (iq->deleg_state == 0 && root_len > 0) {
|
|
|
|
|
iq->deleg_original_qname_len = iq->qchase.qname_len;
|
|
|
|
|
iq->deleg_state = 1;
|
|
|
|
|
|
|
|
|
|
int qchase_label_len = dname_count_labels(iq->qchase.qname);
|
|
|
|
|
size_t labdiff = qchase_label_len - iq->dp->namelabs - 1;
|
|
|
|
|
dname_remove_labels(&iq->qchase.qname, &iq->qchase.qname_len, labdiff);
|
|
|
|
|
|
|
|
|
|
//we have to add _deleg after the first label
|
|
|
|
|
//for ex. jesse.nlnetlabs.nl becomes jesse._deleg.nlnetlabs.nl
|
|
|
|
|
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
|
|
|
|
|
size_t delnamelen = iq->qchase.qname_len + sizeof(deleg_wireformat);
|
|
|
|
|
uint8_t *delname = (uint8_t *)regional_alloc(qstate->region, delnamelen);
|
|
|
|
|
//put first label of original qname
|
|
|
|
|
uint8_t first_label_len = iq->qchase.qname[0];
|
|
|
|
|
uint8_t *qname_minus_first_label = iq->qchase.qname + first_label_len + 1;
|
|
|
|
|
uint8_t leftover_len = iq->qchase.qname_len - first_label_len - 1;
|
|
|
|
|
|
|
|
|
|
memcpy(delname, iq->qchase.qname, first_label_len + 1); //memcpy 1st label into delname
|
|
|
|
|
memcpy(delname + first_label_len + 1, deleg_wireformat, sizeof(deleg_wireformat)); //memcpy _deleg label in delname
|
|
|
|
|
memcpy(delname + first_label_len + sizeof(deleg_wireformat) + 1, qname_minus_first_label, leftover_len); //memcpy other labels in delname
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
iq->dp->namelen = delnamelen;
|
|
|
|
|
iq->qchase.qtype = LDNS_RR_TYPE_IDELEG;
|
|
|
|
|
iq->qchase.qname = delname;
|
|
|
|
|
iq->qchase.qname_len = delnamelen;
|
|
|
|
|
|
|
|
|
|
iq->qinfo_out.qtype = LDNS_RR_TYPE_IDELEG;
|
|
|
|
|
iq->qinfo_out.qname = delname;
|
|
|
|
|
iq->qinfo_out.qname_len = delnamelen;
|
|
|
|
|
} else if (root_len > 0 && iq->deleg_state == 2) { //in this state create deleg prime query
|
|
|
|
|
int qchase_label_len = dname_count_labels(iq->qchase.qname);
|
|
|
|
|
size_t labdiff = qchase_label_len - iq->dp->namelabs;
|
|
|
|
|
dname_remove_labels(&iq->qchase.qname, &iq->qchase.qname_len, labdiff);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
|
|
|
|
|
size_t deleg_len = sizeof(deleg_wireformat);
|
|
|
|
|
|
|
|
|
|
size_t delnamelen = iq->qchase.qname_len + deleg_len;
|
|
|
|
|
uint8_t *delname = (uint8_t *)regional_alloc(qstate->region, delnamelen);
|
|
|
|
|
|
|
|
|
|
memcpy(delname, deleg_wireformat, deleg_len);
|
|
|
|
|
memcpy(delname+deleg_len, iq->qchase.qname, iq->qchase.qname_len);
|
|
|
|
|
|
|
|
|
|
iq->qchase.qtype = LDNS_RR_TYPE_IDELEG;
|
|
|
|
|
iq->qchase.qname = delname;
|
|
|
|
|
iq->qchase.qname_len = delnamelen;
|
|
|
|
|
|
|
|
|
|
iq->qinfo_out.qtype = LDNS_RR_TYPE_IDELEG;
|
|
|
|
|
iq->qinfo_out.qname = delname;
|
|
|
|
|
iq->qinfo_out.qname_len = delnamelen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(iq->num_current_queries>0) {
|
|
|
|
|
/* already busy answering a query, this restart is because
|
|
|
|
@@ -2547,6 +2658,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//DELEG first check if _deleg in delegation point
|
|
|
|
|
//if no _deleg let unbound handle it
|
|
|
|
|
// @JESSE: The following ifs is where most qname-minimisation happens.
|
|
|
|
|
// We need something similar (adding a label at a time) but
|
|
|
|
|
// without the best-effort nature of qname-minimisation and its
|
|
|
|
|
// fallback. You can take inspiration from here on how to
|
|
|
|
|
// correctly set iq->qinfo_out.
|
|
|
|
|
if(iq->minimisation_state == INIT_MINIMISE_STATE
|
|
|
|
|
&& !(iq->chase_flags & BIT_RD)) {
|
|
|
|
|
/* (Re)set qinfo_out to (new) delegation point, except when
|
|
|
|
@@ -3031,7 +3149,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
log_name_addr(VERB_QUERY, "applied NAT64:",
|
|
|
|
|
iq->dp->name, &real_addr, real_addrlen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// @JESSE: This is where a query is finally going out, hopefully.
|
|
|
|
|
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
|
|
|
|
|
outq = (*qstate->env->send_query)(&iq->qinfo_out,
|
|
|
|
|
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
|
|
|
|
@@ -3085,7 +3203,7 @@ find_NS(struct reply_info* rep, size_t from, size_t to)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// @JESSE: This is where responses are read.
|
|
|
|
|
/**
|
|
|
|
|
* Process the query response. All queries end up at this state first. This
|
|
|
|
|
* process generally consists of analyzing the response and routing the
|
|
|
|
@@ -3180,8 +3298,114 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
dnsseclame = 1;
|
|
|
|
|
}
|
|
|
|
|
} else iq->dnssec_lame_query = 0;
|
|
|
|
|
// @JESSE: Answers to _deleg queries would end up here. You need to
|
|
|
|
|
// make sure you identify those answers correclty and treat
|
|
|
|
|
// them the same way as referrals below.
|
|
|
|
|
/* handle each of the type cases */
|
|
|
|
|
// uint16_t SVCB_QTYPE = LDNS_RR_TYPE_IDELEG;
|
|
|
|
|
|
|
|
|
|
//check wether it was a deleg query
|
|
|
|
|
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
|
|
|
|
|
uint8_t first_label_len = iq->qchase.qname[0];
|
|
|
|
|
int is_deleg_query = memcmp(iq->qchase.qname + first_label_len + 1, deleg_wireformat, 7);
|
|
|
|
|
int is_deleg_prime_query = memcmp(iq->qchase.qname, deleg_wireformat, 7);
|
|
|
|
|
|
|
|
|
|
if (iq->deleg_state == 1 && type == RESPONSE_TYPE_ANSWER && iq->qchase.qtype == 64 && is_deleg_query == 0) {
|
|
|
|
|
//result of a deleg refferal
|
|
|
|
|
if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NXDOMAIN) {
|
|
|
|
|
//whem _deleg return NXDOMAIN
|
|
|
|
|
|
|
|
|
|
//turns all values back to normal when no _deleg (NXDOMAIN)
|
|
|
|
|
iq->qchase.qname = iq->deleg_original_qname;
|
|
|
|
|
iq->qchase.qtype = iq->original_query;
|
|
|
|
|
iq->qchase.qname_len = iq->deleg_original_qname_len;
|
|
|
|
|
|
|
|
|
|
iq->qinfo_out.qtype = iq->original_query;
|
|
|
|
|
iq->qinfo_out.qname = iq->deleg_original_qname;
|
|
|
|
|
iq->qinfo_out.qname_len = iq->deleg_original_qname_len;
|
|
|
|
|
return next_state(iq, QUERYTARGETS_STATE);
|
|
|
|
|
}
|
|
|
|
|
//In this scenario _deleg exists
|
|
|
|
|
iq->deleg_state = 2;
|
|
|
|
|
struct ub_packed_rrset_key* rrset_key;
|
|
|
|
|
rrset_key = reply_find_answer_rrset(&iq->qchase, iq->response->rep);
|
|
|
|
|
if(rrset_key) {
|
|
|
|
|
struct packed_rrset_data* rrset_data = (struct packed_rrset_data*) rrset_key->entry.data;
|
|
|
|
|
|
|
|
|
|
size_t data_len = rrset_data->rr_len[0];
|
|
|
|
|
uint8_t* svcb_data = rrset_data->rr_data[0];
|
|
|
|
|
|
|
|
|
|
size_t index = 4; //index of 4 to start at first label (skip message length(2 octet) and priority(2 octet))
|
|
|
|
|
while(svcb_data[index] != 0) { //loop through dns labels, label length 0 means root so stop looping though labels
|
|
|
|
|
index = index + svcb_data[index] + 1;
|
|
|
|
|
}
|
|
|
|
|
index = index + 1;//add 1 for the root label
|
|
|
|
|
//Reference https://datatracker.ietf.org/doc/rfc9460/ section 2.2
|
|
|
|
|
uint8_t *ipv4 = NULL;
|
|
|
|
|
uint8_t *ipv6 = NULL;
|
|
|
|
|
while(index < data_len && (ipv4 == NULL || ipv6 == NULL)) {
|
|
|
|
|
uint16_t svcParamkey = (svcb_data[index] << 8) | svcb_data[index+1];
|
|
|
|
|
uint16_t svcParamValLen = (svcb_data[index+2] << 8) | svcb_data[index+3];
|
|
|
|
|
index = index + 4;
|
|
|
|
|
if (svcParamkey == 4) { //parse IPv4
|
|
|
|
|
ipv4 = (uint8_t *)regional_alloc(qstate->region, 4 * sizeof(uint8_t));
|
|
|
|
|
memcpy(ipv4, svcb_data + index, 4);
|
|
|
|
|
} else if (svcParamkey == 6) { //parse ipv6
|
|
|
|
|
ipv6 = (uint8_t *)regional_alloc(qstate->region, 16 * sizeof(uint8_t));
|
|
|
|
|
memcpy(ipv6, svcb_data + index, 16);
|
|
|
|
|
}
|
|
|
|
|
index = index + svcParamValLen;
|
|
|
|
|
}
|
|
|
|
|
//to get the new delegation name, we have to remove the second label, which is the _deleg label
|
|
|
|
|
//count labels with dname_count_labels()
|
|
|
|
|
size_t new_delegation_label_count = dname_count_labels(rrset_key->rk.dname);
|
|
|
|
|
size_t old_label_count = dname_count_labels(iq->deleg_original_qname);
|
|
|
|
|
size_t diff_label_len = old_label_count - new_delegation_label_count + 1;
|
|
|
|
|
|
|
|
|
|
uint8_t *new_delegation_name = (uint8_t *)regional_alloc(qstate->region, iq->deleg_original_qname_len);
|
|
|
|
|
size_t new_delegation_name_len = iq->deleg_original_qname_len;
|
|
|
|
|
memcpy(new_delegation_name, iq->deleg_original_qname, iq->deleg_original_qname_len);
|
|
|
|
|
dname_remove_labels(&new_delegation_name, &new_delegation_name_len, diff_label_len);
|
|
|
|
|
|
|
|
|
|
iq->dp = delegpt_from_deleg(iq->response, qstate->region, ipv4, ipv6, new_delegation_name, new_delegation_name_len);
|
|
|
|
|
iq->referral_count++;
|
|
|
|
|
iq->sent_count = 0;
|
|
|
|
|
iq->dp_target_count = 0;
|
|
|
|
|
if(qstate->env->cfg->harden_referral_path)
|
|
|
|
|
generate_ns_check(qstate, iq, id);
|
|
|
|
|
|
|
|
|
|
/* stop current outstanding queries.
|
|
|
|
|
* FIXME: should the outstanding queries be waited for and
|
|
|
|
|
* handled? Say by a subquery that inherits the outbound_entry.
|
|
|
|
|
*/
|
|
|
|
|
outbound_list_clear(&iq->outlist);
|
|
|
|
|
iq->num_current_queries = 0;
|
|
|
|
|
fptr_ok(fptr_whitelist_modenv_detach_subs(
|
|
|
|
|
qstate->env->detach_subs));
|
|
|
|
|
(*qstate->env->detach_subs)(qstate);
|
|
|
|
|
iq->num_target_queries = 0;
|
|
|
|
|
iq->response = NULL;
|
|
|
|
|
iq->fail_addr_type = 0;
|
|
|
|
|
verbose(VERB_ALGO, "cleared outbound list for next round");
|
|
|
|
|
|
|
|
|
|
return next_state(iq, QUERYTARGETS_STATE);
|
|
|
|
|
}
|
|
|
|
|
} else if (is_deleg_prime_query == 0) {
|
|
|
|
|
if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NXDOMAIN) {
|
|
|
|
|
//NX DOMAIN mean deleg not supported (no error and answer count = 0)
|
|
|
|
|
iq->deleg_state = 1;
|
|
|
|
|
return next_state(iq, QUERYTARGETS_STATE);
|
|
|
|
|
} else if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NOERROR && iq->response->rep->an_numrrsets == 0) {
|
|
|
|
|
//no data means _deleg supported
|
|
|
|
|
iq->deleg_state = 0;
|
|
|
|
|
return next_state(iq, QUERYTARGETS_STATE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* see if referral brings us close to the target */
|
|
|
|
|
if(type == RESPONSE_TYPE_REFERRAL) {
|
|
|
|
|
if(type == RESPONSE_TYPE_REFERRAL){
|
|
|
|
|
//deleg: go to state 2 when normal refferal found, to try deleg again for child
|
|
|
|
|
iq->deleg_state = 2;
|
|
|
|
|
struct ub_packed_rrset_key* ns = find_NS(
|
|
|
|
|
iq->response->rep, iq->response->rep->an_numrrsets,
|
|
|
|
|
iq->response->rep->an_numrrsets
|
|
|
|
@@ -3224,8 +3448,14 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
type = RESPONSE_TYPE_ANSWER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* handle each of the type cases */
|
|
|
|
|
if(type == RESPONSE_TYPE_ANSWER) {
|
|
|
|
|
if(type == RESPONSE_TYPE_ANSWER ){
|
|
|
|
|
//set original qname to NULL after query has been resolved, to handle new queries
|
|
|
|
|
if (iq->deleg_original_qname != NULL) {
|
|
|
|
|
iq->deleg_original_qname = NULL;
|
|
|
|
|
iq->deleg_original_qname_len = 0;
|
|
|
|
|
iq->original_query = 0;
|
|
|
|
|
log_err("en hier ook nog wel??");
|
|
|
|
|
}
|
|
|
|
|
/* ANSWER type responses terminate the query algorithm,
|
|
|
|
|
* so they sent on their */
|
|
|
|
|
if(verbosity >= VERB_DETAIL) {
|
|
|
|
@@ -3235,6 +3465,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
(iq->response->rep->an_numrrsets?"ANSWER":
|
|
|
|
|
"nodata ANSWER"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if qtype is DS, check we have the right level of answer,
|
|
|
|
|
* like grandchild answer but we need the middle, reject it */
|
|
|
|
|
if(iq->qchase.qtype == LDNS_RR_TYPE_DS && !iq->dsns_point
|
|
|
|
@@ -3323,8 +3554,13 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
return next_state(iq, QUERYTARGETS_STATE);
|
|
|
|
|
}
|
|
|
|
|
return final_state(iq);
|
|
|
|
|
// @JESSE: I guess for the test environemnt we mostly don't care about
|
|
|
|
|
// referrals; these are traditional DNS referral responses.
|
|
|
|
|
} else if(type == RESPONSE_TYPE_REFERRAL) {
|
|
|
|
|
//added code
|
|
|
|
|
// iq->deleg_state = 0;
|
|
|
|
|
struct delegpt* old_dp = NULL;
|
|
|
|
|
|
|
|
|
|
/* REFERRAL type responses get a reset of the
|
|
|
|
|
* delegation point, and back to the QUERYTARGETS_STATE. */
|
|
|
|
|
verbose(VERB_DETAIL, "query response was REFERRAL");
|
|
|
|
@@ -3593,6 +3829,14 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|
|
|
|
* In this case, the event is just sent directly back to
|
|
|
|
|
* the QUERYTARGETS_STATE without resetting anything,
|
|
|
|
|
* because, clearly, the next target must be tried. */
|
|
|
|
|
iq->qchase.qname = iq->deleg_original_qname;
|
|
|
|
|
iq->qchase.qtype = iq->original_query;
|
|
|
|
|
iq->qchase.qname_len = iq->deleg_original_qname_len;
|
|
|
|
|
|
|
|
|
|
iq->qinfo_out.qtype = iq->original_query;
|
|
|
|
|
iq->qinfo_out.qname = iq->deleg_original_qname;
|
|
|
|
|
iq->qinfo_out.qname_len = iq->deleg_original_qname_len;
|
|
|
|
|
|
|
|
|
|
verbose(VERB_DETAIL, "query response was THROWAWAY");
|
|
|
|
|
} else {
|
|
|
|
|
log_warn("A query response came back with an unknown type: %d",
|
|
|
|
@@ -4140,6 +4384,12 @@ iter_inform_super(struct module_qstate* qstate, int id,
|
|
|
|
|
else processTargetResponse(qstate, id, super);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// @JESSE: These are all the available states the iterator could be for a given
|
|
|
|
|
// query. You should not worry about the following cases:
|
|
|
|
|
// - COLLECT_CLASS_STATE (it has to do with ANY queries)
|
|
|
|
|
// - DSNS_FIND_STATE (it tries to find the correct parent for a DS
|
|
|
|
|
// query; I think it is not relevant since the
|
|
|
|
|
// _deleg stuff always live at the parent)
|
|
|
|
|
/**
|
|
|
|
|
* Handle iterator state.
|
|
|
|
|
* Handle events. This is the real processing loop for events, responsible
|
|
|
|
|