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, ¶m); knot_requestor_overlay(&requestor, LAYER_ITERATE, ¶m); knot_requestor_overlay(&requestor, LAYER_STATS, ¶m); + 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