]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/session2: fix memory leak at kresd stoppage
authorOto Šťáva <oto.stava@nic.cz>
Thu, 2 Feb 2023 07:46:46 +0000 (08:46 +0100)
committerOto Šťáva <oto.stava@nic.cz>
Thu, 2 Feb 2023 07:46:46 +0000 (08:46 +0100)
daemon/network.c
daemon/session2.c

index cc170bf97392916a06ecfc27fdcc9f4f1f59ba63..75a517f29f63f1b55583f190714f11b03745f11c 100644 (file)
@@ -232,7 +232,9 @@ static void endpoint_close(struct endpoint *ep, bool force)
                }
                if (ep->handle) {
                        ep->handle->loop = NULL;
-                       io_free(ep->handle);
+                       struct session2 *s = ep->handle->data;
+                       if (s)
+                               session2_event(s, PROTOLAYER_EVENT_CLOSE, NULL);
                }
        } else { /* Asynchronous close */
                struct session2 *s = ep->handle->data;
index 780d7eb118b25d3b52032663f049fd41de11f3e6..4000a1b0980358575371c787ac9e0b5dfc8133ef 100644 (file)
@@ -1400,12 +1400,23 @@ static void on_session2_timer_close(uv_handle_t *handle)
        session2_unhandle(handle->data);
 }
 
-static int session2_handle_close(struct session2 *s, uv_handle_t *handle)
+static int session2_handle_close(struct session2 *s)
 {
-       if (kr_fails_assert(s->transport.type == SESSION2_TRANSPORT_IO
-                               && s->transport.io.handle == handle))
+       if (kr_fails_assert(s->transport.type == SESSION2_TRANSPORT_IO))
                return kr_error(EINVAL);
 
+       uv_handle_t *handle = s->transport.io.handle;
+
+       if (!handle->loop) {
+               /* This happens when kresd is stopping and the libUV loop has
+                * been ended. We do not `uv_close` the handles, we just free
+                * up the memory. */
+
+               session2_unhandle(s); /* For timer handle */
+               io_free(handle); /* This will unhandle the transport handle */
+               return kr_ok();
+       }
+
        io_stop_read(handle);
        uv_close((uv_handle_t *)&s->timer, on_session2_timer_close);
        uv_close(handle, on_session2_handle_close);
@@ -1429,13 +1440,12 @@ static int session2_transport_event(struct session2 *s,
 
        switch (s->transport.type) {
        case SESSION2_TRANSPORT_IO:;
-               uv_handle_t *handle = s->transport.io.handle;
-               if (kr_fails_assert(handle)) {
+               if (kr_fails_assert(s->transport.io.handle)) {
                        return kr_error(EINVAL);
                }
 
                if (is_close_event)
-                       return session2_handle_close(s, handle);
+                       return session2_handle_close(s);
 
                return kr_ok();