]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/session2: pass events to parent sessions and create convenience function for...
authorFrantisek Tobias <frantisek.tobias@nic.cz>
Wed, 3 Jun 2026 13:17:23 +0000 (15:17 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 22 Jul 2026 04:50:45 +0000 (06:50 +0200)
for transport.type = SESSION2_TRANSPORT_PARENT sessions pass events along to parent sessions. This is useful for DoQ (which is the only protolayer group using sub-sessions) as it allows us to cleanup references to sub-sessions that are about to be closed

daemon/session2.c
daemon/session2.h

index 88b422f4c1acc5f7e62a6d11a9f2b079cfc1c7f8..d07119bfc97d25489641ec4b172318178672f42e 100644 (file)
@@ -1000,6 +1000,16 @@ uv_handle_t *session2_get_handle(struct session2 *s)
                : NULL;
 }
 
+struct session2 *session2_get_root(struct session2 *s)
+{
+       while (s && s->transport.type == SESSION2_TRANSPORT_PARENT)
+               s = s->transport.parent;
+
+       return (s && s->transport.type == SESSION2_TRANSPORT_IO)
+               ? s
+               : NULL;
+}
+
 static void session2_on_timeout(uv_timer_t *timer)
 {
        struct session2 *s = timer->data;
@@ -1774,8 +1784,6 @@ static int session2_transport_event(struct session2 *s,
        bool is_close_event = (event == PROTOLAYER_EVENT_CLOSE ||
                        event == PROTOLAYER_EVENT_FORCE_CLOSE);
        if (is_close_event) {
-               session2_waitinglist_finalize(s, KR_STATE_FAIL);
-               session2_tasklist_finalize(s, KR_STATE_FAIL);
                session2_timer_stop(s);
                s->closing = true;
        }
@@ -1792,7 +1800,13 @@ static int session2_transport_event(struct session2 *s,
                return kr_ok();
 
        case SESSION2_TRANSPORT_PARENT:;
-               session2_event_wrap(s, event, baton);
+               /* Pass the event along to the parent session. So far only DoQ uses
+                * subsessions. These events are used to remove references
+                * to terminating sessions in the parent session. */
+               if (kr_fails_assert(s->transport.parent)) {
+                       return kr_error(EINVAL);
+               }
+               session2_event_wrap(s->transport.parent, event, baton);
                return kr_ok();
 
        default:
index a812ac2f6105842b276941b366f25c5fade8df1a..1ba05ae3154a15b7bf6a863d47c222d695de4a13 100644 (file)
@@ -1025,6 +1025,13 @@ struct sockaddr *session2_get_sockname(struct session2 *s);
  * May return `NULL` if no peer is set.  */
 KR_EXPORT uv_handle_t *session2_get_handle(struct session2 *s);
 
+/** Gets the io session from the specified session, iterating through the
+ * session hierarchy (child-to-parent) until an `_IO` session is found if
+ * needed.
+ *
+ * May return `NULL` if no peer is set.  */
+KR_EXPORT struct session2 *session2_get_root(struct session2 *s);
+
 /** Start the session timer. On timeout, the specified `event` is sent in the
  * `_UNWRAP` direction. Only a single timeout can be active at a time. */
 int session2_timer_start(struct session2 *s, enum protolayer_event_type event,