diff --git a/NEWS b/NEWS index de5801ca8334ddff8e49a3c1ec88e0030fcddee8..e726aaa76a5d4f1e69176d7e719e90ad41cf3739 100644 --- a/NEWS +++ b/NEWS @@ -18,7 +18,7 @@ Bugfixes -------- - http module: only run prometheus in parent process if using --forks=N, as the submodule collects metrics from all sub-processes as well. -- TLS fixes for corner cases (!714, !700) +- TLS fixes for corner cases (!700, !714, !721) - fix build with -DNOVERBOSELOG (#424) - policy.{FORWARD,TLS_FORWARD,STUB}: respect net.ipv{4,6} setting (!710) diff --git a/daemon/io.c b/daemon/io.c index 90d2dbb2640c791381632cc59a98539c5e0108a8..f7086ca533e1aa85ffc5fecf8fc8b5de2b60a24f 100644 --- a/daemon/io.c +++ b/daemon/io.c @@ -181,6 +181,10 @@ void tcp_timeout_trigger(uv_timer_t *timer) char *peer_str = kr_straddr(peer); kr_log_verbose("[io] => closing connection to '%s'\n", peer_str ? peer_str : ""); + if (session_flags(s)->outgoing) { + worker_del_tcp_waiting(worker, peer); + worker_del_tcp_connected(worker, peer); + } session_close(s); } } diff --git a/daemon/session.c b/daemon/session.c index 209dbb6d7c7afea8d0350e3f7cb543f970000c3f..db238233db8ecf82c37f0732ed93cd946697e0f9 100644 --- a/daemon/session.c +++ b/daemon/session.c @@ -102,12 +102,6 @@ void session_close(struct session *session) uv_handle_t *handle = session->handle; io_stop_read(handle); session->sflags.closing = true; - if (session->peer.ip.sa_family != AF_UNSPEC && handle->type == UV_TCP) { - struct worker_ctx *worker = handle->loop->data; - struct sockaddr *peer = &session->peer.ip; - worker_del_tcp_connected(worker, peer); - session->sflags.connected = false; - } if (!uv_is_closing((uv_handle_t *)&session->timeout)) { uv_timer_stop(&session->timeout); diff --git a/daemon/worker.c b/daemon/worker.c index f02dd1e47ba80f5ff69421cfab2474210eb90018..98be1e6a1236904c0c37deff6fadab73dab230bc 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -117,8 +117,6 @@ static struct session* worker_find_tcp_connected(struct worker_ctx *worker, static int worker_add_tcp_waiting(struct worker_ctx *worker, const struct sockaddr *addr, struct session *session); -static int worker_del_tcp_waiting(struct worker_ctx *worker, - const struct sockaddr *addr); static struct session* worker_find_tcp_waiting(struct worker_ctx *worker, const struct sockaddr *addr); static void on_tcp_connect_timeout(uv_timer_t *timer); @@ -752,8 +750,7 @@ static int session_tls_hs_cb(struct session *session, int status) if (ret != kr_ok()) { /* Something went wrong. - * Session isn't in the list of waiting sessions, - * or addition to the list of connected sessions failed, + * Either addition to the list of connected sessions * or write to upstream failed. */ worker_del_tcp_connected(worker, peer); session_waitinglist_finalize(session, KR_STATE_FAIL); @@ -774,8 +771,11 @@ static int send_waiting(struct session *session) struct qr_task *t = session_waitinglist_get(session); ret = qr_task_send(t, session, NULL, NULL); if (ret != 0) { + struct worker_ctx *worker = t->ctx->worker; + struct sockaddr *peer = session_get_peer(session); session_waitinglist_finalize(session, KR_STATE_FAIL); session_tasklist_finalize(session, KR_STATE_FAIL); + worker_del_tcp_connected(worker, peer); session_close(session); break; } @@ -865,7 +865,6 @@ static void on_connect(uv_connect_t *req, int status) ret = send_waiting(session); if (ret != 0) { - worker_del_tcp_connected(worker, peer); return; } @@ -1209,6 +1208,7 @@ static int tcp_task_existing_connection(struct session *session, struct qr_task /* Error, finalize task with SERVFAIL and * close connection to upstream. */ session_tasklist_finalize(session, KR_STATE_FAIL); + worker_del_tcp_connected(worker, session_get_peer(session)); session_close(session); return kr_error(EINVAL); } @@ -1620,8 +1620,8 @@ static int worker_add_tcp_waiting(struct worker_ctx *worker, return map_add_tcp_session(&worker->tcp_waiting, addr, session); } -static int worker_del_tcp_waiting(struct worker_ctx *worker, - const struct sockaddr* addr) +int worker_del_tcp_waiting(struct worker_ctx *worker, + const struct sockaddr* addr) { assert(addr && tcpsess_key(addr)); return map_del_tcp_session(&worker->tcp_waiting, addr); @@ -1645,6 +1645,7 @@ int worker_end_tcp(struct session *session) struct worker_ctx *worker = handle->loop->data; struct sockaddr *peer = session_get_peer(session); + worker_del_tcp_waiting(worker, peer); worker_del_tcp_connected(worker, peer); session_flags(session)->connected = false; diff --git a/daemon/worker.h b/daemon/worker.h index 3d9ade8bc48d40af8413f24a940aefb8c3d4ba86..f56e10d0651e176c09e118ace8272d839c32ef45 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -91,7 +91,8 @@ int worker_add_tcp_connected(struct worker_ctx *worker, struct session *session); int worker_del_tcp_connected(struct worker_ctx *worker, const struct sockaddr *addr); - +int worker_del_tcp_waiting(struct worker_ctx *worker, + const struct sockaddr* addr); knot_pkt_t *worker_task_get_pktbuf(const struct qr_task *task); struct request_ctx *worker_task_get_request(struct qr_task *task);