From c8f919ecd33d1185a072647e05637481a3e9501d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Vavru=C5=A1a?= <marek.vavrusa@nic.cz>
Date: Mon, 8 Dec 2014 14:02:05 +0100
Subject: [PATCH] resolve: set limit to prevent infinite loops on server
 failure

---
 daemon/layer/query.c |  2 +-
 lib/resolve.c        | 15 ++++++++++++++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/daemon/layer/query.c b/daemon/layer/query.c
index f97bb4471..662e79d8e 100644
--- a/daemon/layer/query.c
+++ b/daemon/layer/query.c
@@ -52,7 +52,7 @@ static int input_query(knot_layer_t *ctx, knot_pkt_t *pkt)
 	knot_pkt_t *answer = param->result->ans;
 	knot_wire_set_id(answer->wire, knot_wire_get_id(pkt->wire));
 
-	if (ret != 0) {
+	if (ret != KNOT_EOK) {
 		return KNOT_NS_PROC_FAIL;
 	} else {
 		return KNOT_NS_PROC_DONE;
diff --git a/lib/resolve.c b/lib/resolve.c
index 779f0fd79..8dd8ec043 100644
--- a/lib/resolve.c
+++ b/lib/resolve.c
@@ -12,6 +12,8 @@
 #define DEBUG_MSG(fmt, ...) fprintf(stderr, "[reslv] " fmt, ## __VA_ARGS__)
 
 static int resolve_ns(struct kr_context *resolve, struct kr_ns *ns)
+/* Defines */
+#define ITER_LIMIT 50
 {
 	/* Create an address query. */
 	struct kr_query *qry = kr_rplan_push(&resolve->rplan, ns->name,
@@ -114,12 +116,23 @@ int kr_resolve(struct kr_context* ctx, struct kr_result* result,
 	knot_requestor_overlay(&requestor, LAYER_STATIC, &param);
 	knot_requestor_overlay(&requestor, LAYER_ITERATE, &param);
 	knot_requestor_overlay(&requestor, LAYER_STATS, &param);
+	unsigned iter_count = 0;
 	while(ctx->state & (KNOT_NS_PROC_MORE|KNOT_NS_PROC_FULL)) {
 		iterate(&requestor, ctx);
+		if (++iter_count > ITER_LIMIT) {
+			DEBUG_MSG("iteration limit %d reached => SERVFAIL\n", ITER_LIMIT);
+			ctx->state = KNOT_NS_PROC_FAIL;
+		}
 	}
 
 	/* Clean up. */
 	knot_requestor_clear(&requestor);
 
-	return 0;
+	/* Set RCODE on internal failure. */
+	if (ctx->state != KNOT_NS_PROC_DONE) {
+		knot_wire_set_rcode(result->ans->wire, KNOT_RCODE_SERVFAIL);
+		return KNOT_ERROR;
+	}
+
+	return KNOT_EOK;
 }
-- 
GitLab