]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/worker, session: correctly process connected...
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 10 Dec 2018 14:01:37 +0000 (15:01 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 11 Dec 2018 13:32:47 +0000 (14:32 +0100)
... upstreams list when closing outgoing connection

NEWS
daemon/io.c
daemon/session.c
daemon/worker.c
daemon/worker.h

diff --git a/NEWS b/NEWS
index de5801ca8334ddff8e49a3c1ec88e0030fcddee8..e726aaa76a5d4f1e69176d7e719e90ad41cf3739 100644 (file)
--- 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)
 
index 90d2dbb2640c791381632cc59a98539c5e0108a8..f7086ca533e1aa85ffc5fecf8fc8b5de2b60a24f 100644 (file)
@@ -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);
                }
        }
index 209dbb6d7c7afea8d0350e3f7cb543f970000c3f..db238233db8ecf82c37f0732ed93cd946697e0f9 100644 (file)
@@ -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);
index f02dd1e47ba80f5ff69421cfab2474210eb90018..98be1e6a1236904c0c37deff6fadab73dab230bc 100644 (file)
@@ -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;
 
index 3d9ade8bc48d40af8413f24a940aefb8c3d4ba86..f56e10d0651e176c09e118ace8272d839c32ef45 100644 (file)
@@ -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);