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