From: Marek VavruĊĦa Date: Tue, 28 Apr 2015 06:59:04 +0000 (+0200) Subject: daemon/worker: implemented iteration limit X-Git-Tag: v1.0.0-beta1~227^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2c0abb46d65855421d02c69ded34286cf63060ae;p=thirdparty%2Fknot-resolver.git daemon/worker: implemented iteration limit refs #15 --- diff --git a/daemon/engine.h b/daemon/engine.h index d7acd94d8..bb1f9c37c 100644 --- a/daemon/engine.h +++ b/daemon/engine.h @@ -39,6 +39,6 @@ int engine_start(struct engine *engine); void engine_stop(struct engine *engine); int engine_register(struct engine *engine, const char *module); int engine_unregister(struct engine *engine, const char *module); -/** Return engine light userdata. */ void engine_lualib(struct engine *engine, const char *name, int (*lib_cb) (struct lua_State *)); +/** Return engine light userdata. */ struct engine *engine_luaget(struct lua_State *L); diff --git a/daemon/io.c b/daemon/io.c index 6f7e01187..548100371 100644 --- a/daemon/io.c +++ b/daemon/io.c @@ -56,7 +56,7 @@ void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, /* UDP requests are oneshot, always close afterwards */ if (handle->data && !uv_is_closing((uv_handle_t *)handle)) { /* Do not free master socket */ - uv_close((uv_handle_t *)handle, handle_free); + io_close((uv_handle_t *)handle); } /* Check the incoming wire length. */ @@ -96,7 +96,7 @@ static void tcp_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) /* Check for connection close */ if (nread <= 0) { - uv_close((uv_handle_t *)handle, handle_free); + io_close((uv_handle_t *)handle); return; } else if (nread < 2) { /* Not enough bytes to read length */ @@ -175,6 +175,11 @@ uv_handle_t *io_create(uv_loop_t *loop, int type) } } +void io_close(uv_handle_t *handle) +{ + uv_close(handle, (uv_close_cb) handle_free); +} + int io_start_read(uv_handle_t *handle) { if (handle->type == UV_UDP) { @@ -191,4 +196,4 @@ int io_stop_read(uv_handle_t *handle) } else { return uv_read_stop((uv_stream_t *)handle); } -} \ No newline at end of file +} diff --git a/daemon/io.h b/daemon/io.h index 815387f0a..83e01a068 100644 --- a/daemon/io.h +++ b/daemon/io.h @@ -25,5 +25,6 @@ void udp_unbind(struct endpoint *ep); int tcp_bind(struct endpoint *ep, struct sockaddr *addr); void tcp_unbind(struct endpoint *ep); uv_handle_t *io_create(uv_loop_t *loop, int type); +void io_close(uv_handle_t *handle); int io_start_read(uv_handle_t *handle); int io_stop_read(uv_handle_t *handle); \ No newline at end of file diff --git a/daemon/worker.c b/daemon/worker.c index 732b30977..55fbbd9a4 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -15,7 +15,6 @@ */ #include - #include #include #include @@ -43,8 +42,11 @@ struct qr_task } addr; uv_handle_t *handle; } source; + uint16_t iter_count; + uint16_t flags; }; +/* Forward decls */ static int qr_task_step(struct qr_task *task, knot_pkt_t *packet); static int parse_query(knot_pkt_t *query) @@ -71,6 +73,7 @@ static struct qr_task *qr_task_create(struct worker_ctx *worker, uv_handle_t *ha /* Create worker task */ struct engine *engine = worker->engine; struct qr_task *task = mm_alloc(&pool, sizeof(*task)); + memset(task, 0, sizeof(*task)); if (!task) { mp_delete(pool.ctx); return NULL; @@ -98,7 +101,7 @@ static struct qr_task *qr_task_create(struct worker_ctx *worker, uv_handle_t *ha return task; } -static void qr_task_close(uv_handle_t *handle) +static void qr_task_free(uv_handle_t *handle) { struct qr_task *task = handle->data; mp_delete(task->req.pool.ctx); @@ -123,9 +126,8 @@ static void qr_task_on_send(uv_req_t* req, int status) if (status == 0 && task->next_handle) { io_start_read(task->next_handle); } - } else { - /* Finalize task */ - uv_close((uv_handle_t *)&task->timeout, qr_task_close); + } else { /* Finalize task */ + uv_close((uv_handle_t *)&task->timeout, qr_task_free); } } } @@ -163,7 +165,6 @@ static void qr_task_on_connect(uv_connect_t *connect, int status) static int qr_task_finalize(struct qr_task *task, int state) { kr_resolve_finish(&task->req, state); - uv_timer_stop(&task->timeout); qr_task_send(task, task->source.handle, (struct sockaddr *)&task->source.addr, task->req.answer); return state == KNOT_STATE_DONE ? 0 : kr_error(EIO); } @@ -188,6 +189,11 @@ static int qr_task_step(struct qr_task *task, knot_pkt_t *packet) return qr_task_finalize(task, state); } + /* Iteration limit */ + if (++task->iter_count > KR_ITER_LIMIT) { + return qr_task_finalize(task, KNOT_STATE_FAIL); + } + /* Create connection for iterative query */ uv_handle_t *source_handle = task->source.handle; task->next_handle = io_create(source_handle->loop, sock_type); @@ -233,7 +239,6 @@ int worker_exec(struct worker_ctx *worker, uv_handle_t *handle, knot_pkt_t *quer struct qr_task *task = handle->data; bool is_master_socket = (!task); if (is_master_socket) { - /* Accept only queries */ if (knot_wire_get_qr(query->wire)) { return kr_error(EINVAL); /* Ignore. */ } diff --git a/lib/defines.h b/lib/defines.h index 141f21955..773314a11 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -33,7 +33,7 @@ * @cond internal */ #define KR_CONN_RTT_MAX 5000 /* Timeout for network activity */ -#define ITER_LIMIT 50 /* Built-in iterator limit */ +#define KR_ITER_LIMIT 50 /* Built-in iterator limit */ /* * Timers. diff --git a/lib/resolve.c b/lib/resolve.c index 4c1b91200..1a96d03d0 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -168,7 +168,7 @@ int kr_resolve(struct kr_context* ctx, knot_pkt_t *answer, int state = kr_resolve_query(&request, qname, qclass, qtype); while (state == KNOT_STATE_PRODUCE) { /* Hardlimit on iterative queries */ - if (++iter_count > ITER_LIMIT) { + if (++iter_count > KR_ITER_LIMIT) { DEBUG_MSG("iteration limit %d reached\n", ITER_LIMIT); state = KNOT_STATE_FAIL; break;