aboutsummaryrefslogtreecommitdiff
path: root/validator/validator.c
diff options
context:
space:
mode:
Diffstat (limited to 'validator/validator.c')
-rw-r--r--validator/validator.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/validator/validator.c b/validator/validator.c
index f27ae5b4290a..d3ed8be3ed34 100644
--- a/validator/validator.c
+++ b/validator/validator.c
@@ -68,6 +68,9 @@
#define MAX_VALIDATE_AT_ONCE 8
/** Max number of validation suspends allowed, error out otherwise. */
#define MAX_VALIDATION_SUSPENDS 16
+/** Max answer RRsets for qtype ANY that are validated. The lists is
+ * shortened to fit this limit. */
+#define MAX_RRSETS_ANY_VALIDATED 24
/* forward decl for cache response and normal super inform calls of a DS */
static void process_ds_response(struct module_qstate* qstate,
@@ -921,10 +924,10 @@ validate_suspend_setup_timer(struct module_qstate* qstate,
slack += 2;
else if(qstate->env->mesh->all.count >= qstate->env->mesh->max_reply_states/4)
slack += 1;
- if(vq->suspend_count > 3)
- slack += 3;
- else if(vq->suspend_count > 0)
- slack += vq->suspend_count;
+ /* One step of back-off after the first suspend so a single bad
+ * message still yields, but does not grow exponentially on its own. */
+ if(vq->suspend_count > 0)
+ slack += 1;
if(slack != 0 && slack <= 12 /* No numeric overflow. */) {
usec = usec << slack;
}
@@ -1025,6 +1028,29 @@ remove_spurious_authority(struct reply_info* chase_reply,
}
/**
+ * Cap the number of answer RRsets for validation of type ANY.
+ * This limits the number of RRSIG validations performed.
+ * It is allowed to return a subset of available RRsets when processing
+ * ANY query.
+ * @param chase_reply: the chased reply, shorten if if too long.
+ * @param orig_reply: original reply, remove the records here as well,
+ * so it can be marked as DNSSEC valid.
+ * @param skip: the number of rrsets skipped in the answer section due to
+ * CNAME chain that is followed.
+ * @param max_rrsets: the number allowed.
+ */
+static void
+shorten_answer_any(struct reply_info* chase_reply,
+ struct reply_info* orig_reply, size_t skip, size_t max_rrsets)
+{
+ if(chase_reply->an_numrrsets > max_rrsets) {
+ size_t to_rem = chase_reply->an_numrrsets - max_rrsets;
+ val_reply_remove_answers(chase_reply, max_rrsets, to_rem);
+ val_reply_remove_answers(orig_reply, skip+max_rrsets, to_rem);
+ }
+}
+
+/**
* Given a "positive" response -- a response that contains an answer to the
* question, and no CNAME chain, validate this response.
*
@@ -2306,6 +2332,9 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
&vq->qchase, vq->orig_msg->rep, vq->rrset_skip);
if(subtype != VAL_CLASS_REFERRAL)
remove_spurious_authority(vq->chase_reply, vq->orig_msg->rep);
+ if(subtype == VAL_CLASS_ANY)
+ shorten_answer_any(vq->chase_reply, vq->orig_msg->rep,
+ vq->rrset_skip, MAX_RRSETS_ANY_VALIDATED);
/* check signatures in the message;
* answer and authority must be valid, additional is only checked. */