iq->num_current_queries = 0;
iq->query_restart_count = 0;
iq->referral_count = 0;
+ iq->sent_count = 0;
iq->wait_priming_stub = 0;
iq->refetch_glue = 0;
iq->dnssec_expected = 0;
log_query_info(VERB_QUERY, "processQueryTargets:", &qstate->qinfo);
verbose(VERB_ALGO, "processQueryTargets: targetqueries %d, "
- "currentqueries %d", iq->num_target_queries,
- iq->num_current_queries);
+ "currentqueries %d sentcount %d", iq->num_target_queries,
+ iq->num_current_queries, iq->sent_count);
/* Make sure that we haven't run away */
/* FIXME: is this check even necessary? */
"number of referrrals with %d", iq->referral_count);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
+ if(iq->sent_count > MAX_SENT_COUNT) {
+ verbose(VERB_QUERY, "request has exceeded the maximum "
+ "number of sends with %d", iq->sent_count);
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+ }
/* Make sure we have a delegation point, otherwise priming failed
* or another failure occurred */
/* < not <=, because although the array is large enough for <=, the
* generated query will immediately be discarded due to depth and
* that servfail is cached, which is not good as opportunism goes. */
- if(iq->depth < ie->max_dependency_depth) {
+ if(iq->depth < ie->max_dependency_depth
+ && iq->sent_count < TARGET_FETCH_STOP) {
tf_policy = ie->target_fetch_policy[iq->depth];
}
/* the current caps_server is the number of fallbacks sent.
* the original query is one that matched too, so we have
* caps_server+1 number of matching queries now */
- if(iq->caps_server+1 >= naddr*3) {
+ if(iq->caps_server+1 >= naddr*3 ||
+ iq->caps_server+1 >= MAX_SENT_COUNT) {
/* we're done, process the response */
verbose(VERB_ALGO, "0x20 fallback had %d responses "
"match for %d wanted, done.",
}
outbound_list_insert(&iq->outlist, outq);
iq->num_current_queries++;
+ iq->sent_count++;
qstate->ext_state[id] = module_wait_reply;
return 0;
delegpt_log(VERB_ALGO, iq->dp);
/* Count this as a referral. */
iq->referral_count++;
+ iq->sent_count = 0;
/* see if the next dp is a trust anchor, or a DS was sent
* along, indicating dnssec is expected for next zone */
iq->dnssec_expected = iter_indicates_dnssec(qstate->env,
iq->dp = NULL;
/* Note the query restart. */
iq->query_restart_count++;
+ iq->sent_count = 0;
/* stop current outstanding queries.
* FIXME: should the outstanding queries be waited for and
#define MAX_RESTART_COUNT 8
/** max number of referrals. Makes sure resolver does not run away */
#define MAX_REFERRAL_COUNT 130
+/** max number of queries-sent-out. Make sure large NS set does not loop */
+#define MAX_SENT_COUNT 16
+/** at what query-sent-count to stop target fetch policy */
+#define TARGET_FETCH_STOP 3
/** how nice is a server without further information, in msec
* Equals rtt initial timeout value.
*/
/** the number of times this query as followed a referral. */
int referral_count;
+ /** number of queries fired off */
+ int sent_count;
+
/**
* The query must store NS records from referrals as parentside RRs
* Enabled once it hits resolution problems, to throttle retries.