I'm very pleased to announce the release of our new website and documentation using the new toolchain with Hugo and AsciiDoctor. To get more information about the new toolchain please read the FreeBSD Documentation Project Primer[1], Hugo docs[2] and AsciiDoctor docs[3]. Acknowledgment: Benedict Reuschling <bcr@> Glen Barber <gjb@> Hiroki Sato <hrs@> Li-Wen Hsu <lwhsu@> Sean Chittenden <seanc@> The FreeBSD Foundation [1] https://docs.FreeBSD.org/en/books/fdp-primer/ [2] https://gohugo.io/documentation/ [3] https://docs.asciidoctor.org/home/ Approved by: doceng, core
149 lines
4.8 KiB
Diff
149 lines
4.8 KiB
Diff
Index: contrib/unbound/iterator/iterator.c
|
|
===================================================================
|
|
--- contrib/unbound/iterator/iterator.c.orig
|
|
+++ contrib/unbound/iterator/iterator.c
|
|
@@ -117,6 +117,7 @@
|
|
iq->query_restart_count = 0;
|
|
iq->referral_count = 0;
|
|
iq->sent_count = 0;
|
|
+ iq->target_count = NULL;
|
|
iq->wait_priming_stub = 0;
|
|
iq->refetch_glue = 0;
|
|
iq->dnssec_expected = 0;
|
|
@@ -442,6 +443,26 @@
|
|
return 1;
|
|
}
|
|
|
|
+/** create target count structure for this query */
|
|
+static void
|
|
+target_count_create(struct iter_qstate* iq)
|
|
+{
|
|
+ if(!iq->target_count) {
|
|
+ iq->target_count = (int*)calloc(2, sizeof(int));
|
|
+ /* if calloc fails we simply do not track this number */
|
|
+ if(iq->target_count)
|
|
+ iq->target_count[0] = 1;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+target_count_increase(struct iter_qstate* iq, int num)
|
|
+{
|
|
+ target_count_create(iq);
|
|
+ if(iq->target_count)
|
|
+ iq->target_count[1] += num;
|
|
+}
|
|
+
|
|
/**
|
|
* Generate a subrequest.
|
|
* Generate a local request event. Local events are tied to this module, and
|
|
@@ -513,6 +534,10 @@
|
|
subiq = (struct iter_qstate*)subq->minfo[id];
|
|
memset(subiq, 0, sizeof(*subiq));
|
|
subiq->num_target_queries = 0;
|
|
+ target_count_create(iq);
|
|
+ subiq->target_count = iq->target_count;
|
|
+ if(iq->target_count)
|
|
+ iq->target_count[0] ++; /* extra reference */
|
|
subiq->num_current_queries = 0;
|
|
subiq->depth = iq->depth+1;
|
|
outbound_list_init(&subiq->outlist);
|
|
@@ -1339,6 +1364,12 @@
|
|
|
|
if(iq->depth == ie->max_dependency_depth)
|
|
return 0;
|
|
+ if(iq->depth > 0 && iq->target_count &&
|
|
+ iq->target_count[1] > MAX_TARGET_COUNT) {
|
|
+ verbose(VERB_QUERY, "request has exceeded the maximum "
|
|
+ "number of glue fetches %d", iq->target_count[1]);
|
|
+ return 0;
|
|
+ }
|
|
|
|
iter_mark_cycle_targets(qstate, iq->dp);
|
|
missing = (int)delegpt_count_missing_targets(iq->dp);
|
|
@@ -1487,6 +1518,7 @@
|
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
|
}
|
|
iq->num_target_queries += qs;
|
|
+ target_count_increase(iq, qs);
|
|
if(qs != 0) {
|
|
qstate->ext_state[id] = module_wait_subquery;
|
|
return 0; /* and wait for them */
|
|
@@ -1496,6 +1528,12 @@
|
|
verbose(VERB_QUERY, "maxdepth and need more nameservers, fail");
|
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
|
}
|
|
+ if(iq->depth > 0 && iq->target_count &&
|
|
+ iq->target_count[1] > MAX_TARGET_COUNT) {
|
|
+ verbose(VERB_QUERY, "request has exceeded the maximum "
|
|
+ "number of glue fetches %d", iq->target_count[1]);
|
|
+ return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
|
+ }
|
|
/* mark cycle targets for parent-side lookups */
|
|
iter_mark_pside_cycle_targets(qstate, iq->dp);
|
|
/* see if we can issue queries to get nameserver addresses */
|
|
@@ -1525,6 +1563,7 @@
|
|
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);
|
|
qstate->ext_state[id] = module_wait_subquery;
|
|
return 0;
|
|
}
|
|
@@ -1680,6 +1719,7 @@
|
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
|
}
|
|
iq->num_target_queries += extra;
|
|
+ target_count_increase(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");
|
|
@@ -1720,6 +1760,7 @@
|
|
/* 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);
|
|
}
|
|
|
|
/* Add the current set of unused targets to our queue. */
|
|
@@ -1765,6 +1806,7 @@
|
|
return 1;
|
|
}
|
|
iq->num_target_queries += qs;
|
|
+ target_count_increase(iq, qs);
|
|
}
|
|
/* Since a target query might have been made, we
|
|
* need to check again. */
|
|
@@ -2847,6 +2889,8 @@
|
|
iq = (struct iter_qstate*)qstate->minfo[id];
|
|
if(iq) {
|
|
outbound_list_clear(&iq->outlist);
|
|
+ if(iq->target_count && --iq->target_count[0] == 0)
|
|
+ free(iq->target_count);
|
|
iq->num_current_queries = 0;
|
|
}
|
|
qstate->minfo[id] = NULL;
|
|
Index: contrib/unbound/iterator/iterator.h
|
|
===================================================================
|
|
--- contrib/unbound/iterator/iterator.h.orig
|
|
+++ contrib/unbound/iterator/iterator.h
|
|
@@ -52,6 +52,8 @@
|
|
struct iter_prep_list;
|
|
struct iter_priv;
|
|
|
|
+/** max number of targets spawned for a query and its subqueries */
|
|
+#define MAX_TARGET_COUNT 32
|
|
/** max number of query restarts. Determines max number of CNAME chain. */
|
|
#define MAX_RESTART_COUNT 8
|
|
/** max number of referrals. Makes sure resolver does not run away */
|
|
@@ -254,6 +256,10 @@
|
|
|
|
/** number of queries fired off */
|
|
int sent_count;
|
|
+
|
|
+ /** number of target queries spawned in [1], for this query and its
|
|
+ * subqueries, the malloced-array is shared, [0] refcount. */
|
|
+ int* target_count;
|
|
|
|
/**
|
|
* The query must store NS records from referrals as parentside RRs
|