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);
/* 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. */
/* 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 */
}
}
+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) {
} else {
return uv_read_stop((uv_stream_t *)handle);
}
-}
\ No newline at end of file
+}
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
*/
#include <uv.h>
-
#include <libknot/packet/pkt.h>
#include <libknot/internal/net.h>
#include <libknot/internal/mempool.h>
} 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)
/* 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;
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);
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);
}
}
}
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);
}
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);
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. */
}
* @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.
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;