From: Marek VavruĊĦa Date: Thu, 21 May 2015 16:30:55 +0000 (+0200) Subject: daemon/worker: uv_connect_t lifetime max exceed qr_task X-Git-Tag: v1.0.0-beta1~154 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=198b13b5e9faef50e95024f6b7b666b5f4a6129e;p=thirdparty%2Fknot-resolver.git daemon/worker: uv_connect_t lifetime max exceed qr_task --- diff --git a/daemon/worker.c b/daemon/worker.c index d5aa0e0d3..4bc787b16 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -30,7 +30,6 @@ struct qr_task knot_pkt_t *next_query; uv_handle_t *next_handle; uv_timer_t timeout; - uv_connect_t connect; struct { union { struct sockaddr_in ip4; @@ -165,12 +164,11 @@ static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockad static void qr_task_on_connect(uv_connect_t *connect, int status) { - uv_stream_t *handle = connect->handle; - struct qr_task *task = connect->data; - /* Use only if succeeded, and the connection didn't change. */ - if (status == 0 && ((uv_handle_t *)handle == task->next_handle)) { - qr_task_send(task, (uv_handle_t *)handle, NULL, task->next_query); + if (status == 0) { + struct qr_task *task = connect->data; + qr_task_send(task, (uv_handle_t *)connect->handle, NULL, task->next_query); } + free(connect); } static int qr_task_finalize(struct qr_task *task, int state) @@ -190,7 +188,6 @@ static int qr_task_step(struct qr_task *task, knot_pkt_t *packet) } uv_timer_stop(&task->timeout); task->next_handle = NULL; - task->connect.handle = NULL; } /* Consume input and produce next query */ @@ -220,11 +217,14 @@ static int qr_task_step(struct qr_task *task, knot_pkt_t *packet) /* Connect or issue query datagram */ task->next_handle->data = task; if (sock_type == SOCK_STREAM) { - uv_connect_t *connect = &task->connect; - connect->data = task; - if (uv_tcp_connect(connect, (uv_tcp_t *)task->next_handle, addr, qr_task_on_connect) != 0) { + /* connect handle must be persistent even if the task mempool drops, + * as it is referenced internally in the libuv event loop */ + uv_connect_t *connect = malloc(sizeof(*connect)); + if (!connect || uv_tcp_connect(connect, (uv_tcp_t *)task->next_handle, addr, qr_task_on_connect) != 0) { + free(connect); return qr_task_step(task, NULL); } + connect->data = task; } else { if (qr_task_send(task, task->next_handle, addr, next_query) != 0) { return qr_task_step(task, NULL);