summaryrefslogtreecommitdiff
path: root/iterator/iterator.c
diff options
context:
space:
mode:
Diffstat (limited to 'iterator/iterator.c')
-rw-r--r--iterator/iterator.c67
1 files changed, 47 insertions, 20 deletions
diff --git a/iterator/iterator.c b/iterator/iterator.c
index cc38348b39da..78cd9485bad4 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -81,7 +81,8 @@ int BLACKLIST_PENALTY = (120000*4);
/** Timeout when only a single probe query per IP is allowed. */
int PROBE_MAXRTO = PROBE_MAXRTO_DEFAULT; /* in msec */
-static void target_count_increase_nx(struct iter_qstate* iq, int num);
+static void target_count_increase_nx(struct module_qstate* qstate,
+ struct iter_qstate* iq, int num);
int
iter_init(struct module_env* env, int id)
@@ -250,7 +251,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->nat64.use_nat64)) &&
(dpns->got6 == 2 || !ie->supports_ipv6)) {
dpns->resolved = 1; /* mark as failed */
- target_count_increase_nx(super_iq, 1);
+ target_count_increase_nx(super, super_iq, 1);
}
}
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
@@ -734,7 +735,7 @@ is_caps_whitelisted(struct iter_env* ie, struct iter_qstate* iq)
* created for the parent query.
*/
static void
-target_count_create(struct iter_qstate* iq)
+target_count_create(struct module_qstate* qstate, struct iter_qstate* iq)
{
if(!iq->target_count) {
iq->target_count = (int*)calloc(TARGET_COUNT_MAX, sizeof(int));
@@ -742,33 +743,57 @@ target_count_create(struct iter_qstate* iq)
if(iq->target_count) {
iq->target_count[TARGET_COUNT_REF] = 1;
iq->nxns_dp = (uint8_t**)calloc(1, sizeof(uint8_t*));
+ /* continue global quota from where it was. */
+ if(qstate->global_quota_reached >
+ iq->target_count[TARGET_COUNT_GLOBAL_QUOTA])
+ iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] =
+ qstate->global_quota_reached;
}
}
}
static void
-target_count_increase(struct iter_qstate* iq, int num)
+target_count_store(struct module_qstate* qstate, struct iter_qstate* iq)
{
- target_count_create(iq);
+ if(iq->target_count) {
+ /* By storing the global quota counter, it stays
+ * there to be picked up if the module is restarted,
+ * eg. due to a validator retry, and then the
+ * target_count_create routine picks it up. */
+ if(iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] >
+ qstate->global_quota_reached)
+ qstate->global_quota_reached =
+ iq->target_count[TARGET_COUNT_GLOBAL_QUOTA];
+ }
+}
+
+static void
+target_count_increase(struct module_qstate* qstate,
+ struct iter_qstate* iq, int num)
+{
+ target_count_create(qstate, iq);
if(iq->target_count)
iq->target_count[TARGET_COUNT_QUERIES] += num;
iq->dp_target_count++;
}
static void
-target_count_increase_nx(struct iter_qstate* iq, int num)
+target_count_increase_nx(struct module_qstate* qstate,
+ struct iter_qstate* iq, int num)
{
- target_count_create(iq);
+ target_count_create(qstate, iq);
if(iq->target_count)
iq->target_count[TARGET_COUNT_NX] += num;
}
static void
-target_count_increase_global_quota(struct iter_qstate* iq, int num)
+target_count_increase_global_quota(struct module_qstate* qstate,
+ struct iter_qstate* iq, int num)
{
- target_count_create(iq);
+ target_count_create(qstate, iq);
if(iq->target_count)
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num;
+ target_count_store(qstate, iq);
}
/**
@@ -861,7 +886,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
subiq = (struct iter_qstate*)subq->minfo[id];
memset(subiq, 0, sizeof(*subiq));
subiq->num_target_queries = 0;
- target_count_create(iq);
+ target_count_create(qstate, iq);
subiq->target_count = iq->target_count;
if(iq->target_count) {
iq->target_count[TARGET_COUNT_REF] ++; /* extra reference */
@@ -2234,7 +2259,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->num_target_queries += qs;
- target_count_increase(iq, qs);
+ target_count_increase(qstate, iq, qs);
if(qs != 0) {
qstate->ext_state[id] = module_wait_subquery;
return 0; /* and wait for them */
@@ -2290,7 +2315,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
* lookups at a time. */
verbose(VERB_ALGO, "try parent-side glue lookup");
iq->num_target_queries += query_count;
- target_count_increase(iq, query_count);
+ target_count_increase(qstate, iq, query_count);
qstate->ext_state[id] = module_wait_subquery;
return 0;
}
@@ -2310,7 +2335,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
if(query_count != 0) { /* suspend to await results */
verbose(VERB_ALGO, "try parent-side glue lookup");
iq->num_target_queries += query_count;
- target_count_increase(iq, query_count);
+ target_count_increase(qstate, iq, query_count);
qstate->ext_state[id] = module_wait_subquery;
return 0;
}
@@ -2788,7 +2813,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->num_target_queries += extra;
- target_count_increase(iq, extra);
+ target_count_increase(qstate, iq, extra);
if(iq->num_target_queries > 0) {
/* wait to get all targets, we want to try em */
verbose(VERB_ALGO, "wait for all targets for fallback");
@@ -2839,7 +2864,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
/* errors ignored, these targets are not strictly necessary for
* this result, we do not have to reply with SERVFAIL */
iq->num_target_queries += extra;
- target_count_increase(iq, extra);
+ target_count_increase(qstate, iq, extra);
}
/* Add the current set of unused targets to our queue. */
@@ -2962,7 +2987,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
LDNS_RCODE_SERVFAIL);
}
iq->num_target_queries += qs;
- target_count_increase(iq, qs);
+ target_count_increase(qstate, iq, qs);
}
/* Since a target query might have been made, we
* need to check again. */
@@ -3022,7 +3047,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
* this result, we do not have to reply with SERVFAIL */
if(extra > 0) {
iq->num_target_queries += extra;
- target_count_increase(iq, extra);
+ target_count_increase(qstate, iq, extra);
check_waiting_queries(iq, qstate, id);
/* undo qname minimise step because we'll get back here
* to do it again */
@@ -3035,7 +3060,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
- target_count_increase_global_quota(iq, 1);
+ target_count_increase_global_quota(qstate, iq, 1);
if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]
> MAX_GLOBAL_QUOTA) {
char s[LDNS_MAX_DOMAINLEN];
@@ -3879,7 +3904,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
/* no new addresses, increase the nxns counter, like
* this could be a list of wildcards with no new
* addresses */
- target_count_increase_nx(foriq, 1);
+ target_count_increase_nx(qstate, foriq, 1);
}
verbose(VERB_ALGO, "added target response");
delegpt_log(VERB_ALGO, foriq->dp);
@@ -3891,7 +3916,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
dpns->resolved = 1; /* fail the target */
/* do not count cached answers */
if(qstate->reply_origin && qstate->reply_origin->len != 0) {
- target_count_increase_nx(foriq, 1);
+ target_count_increase_nx(qstate, foriq, 1);
}
}
}
@@ -4116,6 +4141,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
iter_store_parentside_neg(qstate->env, &qstate->qinfo,
iq->deleg_msg?iq->deleg_msg->rep:
(iq->response?iq->response->rep:NULL));
+ target_count_store(qstate, iq);
if(!iq->response) {
verbose(VERB_ALGO, "No response is set, servfail");
errinf(qstate, "(no response found at query finish)");
@@ -4531,6 +4557,7 @@ iter_clear(struct module_qstate* qstate, int id)
iq = (struct iter_qstate*)qstate->minfo[id];
if(iq) {
outbound_list_clear(&iq->outlist);
+ target_count_store(qstate, iq);
if(iq->target_count && --iq->target_count[TARGET_COUNT_REF] == 0) {
free(iq->target_count);
if(*iq->nxns_dp) free(*iq->nxns_dp);