|
|
9d429a |
Index: iterator/iterator.c
|
|
|
9d429a |
===================================================================
|
|
|
9d429a |
--- iterator/iterator.c (revision 3272)
|
|
|
9d429a |
+++ iterator/iterator.c (working copy)
|
|
|
9d429a |
@@ -120,6 +120,7 @@
|
|
|
9d429a |
iq->query_restart_count = 0;
|
|
|
9d429a |
iq->referral_count = 0;
|
|
|
9d429a |
iq->sent_count = 0;
|
|
|
9d429a |
+ iq->target_count = NULL;
|
|
|
9d429a |
iq->wait_priming_stub = 0;
|
|
|
9d429a |
iq->refetch_glue = 0;
|
|
|
9d429a |
iq->dnssec_expected = 0;
|
|
|
9d429a |
@@ -453,6 +454,26 @@
|
|
|
9d429a |
return 1;
|
|
|
9d429a |
}
|
|
|
9d429a |
|
|
|
9d429a |
+/** create target count structure for this query */
|
|
|
9d429a |
+static void
|
|
|
9d429a |
+target_count_create(struct iter_qstate* iq)
|
|
|
9d429a |
+{
|
|
|
9d429a |
+ if(!iq->target_count) {
|
|
|
9d429a |
+ iq->target_count = (int*)calloc(2, sizeof(int));
|
|
|
9d429a |
+ /* if calloc fails we simply do not track this number */
|
|
|
9d429a |
+ if(iq->target_count)
|
|
|
9d429a |
+ iq->target_count[0] = 1;
|
|
|
9d429a |
+ }
|
|
|
9d429a |
+}
|
|
|
9d429a |
+
|
|
|
9d429a |
+static void
|
|
|
9d429a |
+target_count_increase(struct iter_qstate* iq, int num)
|
|
|
9d429a |
+{
|
|
|
9d429a |
+ target_count_create(iq);
|
|
|
9d429a |
+ if(iq->target_count)
|
|
|
9d429a |
+ iq->target_count[1] += num;
|
|
|
9d429a |
+}
|
|
|
9d429a |
+
|
|
|
9d429a |
/**
|
|
|
9d429a |
* Generate a subrequest.
|
|
|
9d429a |
* Generate a local request event. Local events are tied to this module, and
|
|
|
9d429a |
@@ -524,6 +545,10 @@
|
|
|
9d429a |
subiq = (struct iter_qstate*)subq->minfo[id];
|
|
|
9d429a |
memset(subiq, 0, sizeof(*subiq));
|
|
|
9d429a |
subiq->num_target_queries = 0;
|
|
|
9d429a |
+ target_count_create(iq);
|
|
|
9d429a |
+ subiq->target_count = iq->target_count;
|
|
|
9d429a |
+ if(iq->target_count)
|
|
|
9d429a |
+ iq->target_count[0] ++; /* extra reference */
|
|
|
9d429a |
subiq->num_current_queries = 0;
|
|
|
9d429a |
subiq->depth = iq->depth+1;
|
|
|
9d429a |
outbound_list_init(&subiq->outlist);
|
|
|
9d429a |
@@ -1350,6 +1375,12 @@
|
|
|
9d429a |
|
|
|
9d429a |
if(iq->depth == ie->max_dependency_depth)
|
|
|
9d429a |
return 0;
|
|
|
9d429a |
+ if(iq->depth > 0 && iq->target_count &&
|
|
|
9d429a |
+ iq->target_count[1] > MAX_TARGET_COUNT) {
|
|
|
9d429a |
+ verbose(VERB_QUERY, "request has exceeded the maximum "
|
|
|
9d429a |
+ "number of glue fetches %d", iq->target_count[1]);
|
|
|
9d429a |
+ return 0;
|
|
|
9d429a |
+ }
|
|
|
9d429a |
|
|
|
9d429a |
iter_mark_cycle_targets(qstate, iq->dp);
|
|
|
9d429a |
missing = (int)delegpt_count_missing_targets(iq->dp);
|
|
|
9d429a |
@@ -1532,6 +1563,7 @@
|
|
|
9d429a |
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
|
|
9d429a |
}
|
|
|
9d429a |
iq->num_target_queries += qs;
|
|
|
9d429a |
+ target_count_increase(iq, qs);
|
|
|
9d429a |
if(qs != 0) {
|
|
|
9d429a |
qstate->ext_state[id] = module_wait_subquery;
|
|
|
9d429a |
return 0; /* and wait for them */
|
|
|
9d429a |
@@ -1541,6 +1573,12 @@
|
|
|
9d429a |
verbose(VERB_QUERY, "maxdepth and need more nameservers, fail");
|
|
|
9d429a |
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
|
|
9d429a |
}
|
|
|
9d429a |
+ if(iq->depth > 0 && iq->target_count &&
|
|
|
9d429a |
+ iq->target_count[1] > MAX_TARGET_COUNT) {
|
|
|
9d429a |
+ verbose(VERB_QUERY, "request has exceeded the maximum "
|
|
|
9d429a |
+ "number of glue fetches %d", iq->target_count[1]);
|
|
|
9d429a |
+ return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
|
|
9d429a |
+ }
|
|
|
9d429a |
/* mark cycle targets for parent-side lookups */
|
|
|
9d429a |
iter_mark_pside_cycle_targets(qstate, iq->dp);
|
|
|
9d429a |
/* see if we can issue queries to get nameserver addresses */
|
|
|
9d429a |
@@ -1570,6 +1608,7 @@
|
|
|
9d429a |
if(query_count != 0) { /* suspend to await results */
|
|
|
9d429a |
verbose(VERB_ALGO, "try parent-side glue lookup");
|
|
|
9d429a |
iq->num_target_queries += query_count;
|
|
|
9d429a |
+ target_count_increase(iq, query_count);
|
|
|
9d429a |
qstate->ext_state[id] = module_wait_subquery;
|
|
|
9d429a |
return 0;
|
|
|
9d429a |
}
|
|
|
9d429a |
@@ -1725,6 +1764,7 @@
|
|
|
9d429a |
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
|
|
9d429a |
}
|
|
|
9d429a |
iq->num_target_queries += extra;
|
|
|
9d429a |
+ target_count_increase(iq, extra);
|
|
|
9d429a |
if(iq->num_target_queries > 0) {
|
|
|
9d429a |
/* wait to get all targets, we want to try em */
|
|
|
9d429a |
verbose(VERB_ALGO, "wait for all targets for fallback");
|
|
|
9d429a |
@@ -1765,6 +1805,7 @@
|
|
|
9d429a |
/* errors ignored, these targets are not strictly necessary for
|
|
|
9d429a |
* this result, we do not have to reply with SERVFAIL */
|
|
|
9d429a |
iq->num_target_queries += extra;
|
|
|
9d429a |
+ target_count_increase(iq, extra);
|
|
|
9d429a |
}
|
|
|
9d429a |
|
|
|
9d429a |
/* Add the current set of unused targets to our queue. */
|
|
|
9d429a |
@@ -1810,6 +1851,7 @@
|
|
|
9d429a |
return 1;
|
|
|
9d429a |
}
|
|
|
9d429a |
iq->num_target_queries += qs;
|
|
|
9d429a |
+ target_count_increase(iq, qs);
|
|
|
9d429a |
}
|
|
|
9d429a |
/* Since a target query might have been made, we
|
|
|
9d429a |
* need to check again. */
|
|
|
9d429a |
@@ -2921,6 +2963,8 @@
|
|
|
9d429a |
iq = (struct iter_qstate*)qstate->minfo[id];
|
|
|
9d429a |
if(iq) {
|
|
|
9d429a |
outbound_list_clear(&iq->outlist);
|
|
|
9d429a |
+ if(iq->target_count && --iq->target_count[0] == 0)
|
|
|
9d429a |
+ free(iq->target_count);
|
|
|
9d429a |
iq->num_current_queries = 0;
|
|
|
9d429a |
}
|
|
|
9d429a |
qstate->minfo[id] = NULL;
|
|
|
9d429a |
Index: iterator/iterator.h
|
|
|
9d429a |
===================================================================
|
|
|
9d429a |
--- iterator/iterator.h (revision 3272)
|
|
|
9d429a |
+++ iterator/iterator.h (working copy)
|
|
|
9d429a |
@@ -52,6 +52,8 @@
|
|
|
9d429a |
struct iter_prep_list;
|
|
|
9d429a |
struct iter_priv;
|
|
|
9d429a |
|
|
|
9d429a |
+/** max number of targets spawned for a query and its subqueries */
|
|
|
9d429a |
+#define MAX_TARGET_COUNT 32
|
|
|
9d429a |
/** max number of query restarts. Determines max number of CNAME chain. */
|
|
|
9d429a |
#define MAX_RESTART_COUNT 8
|
|
|
9d429a |
/** max number of referrals. Makes sure resolver does not run away */
|
|
|
9d429a |
@@ -251,6 +253,10 @@
|
|
|
9d429a |
|
|
|
9d429a |
/** number of queries fired off */
|
|
|
9d429a |
int sent_count;
|
|
|
9d429a |
+
|
|
|
9d429a |
+ /** number of target queries spawned in [1], for this query and its
|
|
|
9d429a |
+ * subqueries, the malloced-array is shared, [0] refcount. */
|
|
|
9d429a |
+ int* target_count;
|
|
|
9d429a |
|
|
|
9d429a |
/**
|
|
|
9d429a |
* The query must store NS records from referrals as parentside RRs
|