From: Vladimír Čunát Date: Thu, 24 Apr 2025 08:10:44 +0000 (+0200) Subject: daemon/worker pl_dns_stream_disconnected(): fix tasklist confusion X-Git-Tag: v6.0.12~1^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e3646d4873d5c4f2dad438f1bfe7f5ac9df4f00;p=thirdparty%2Fknot-resolver.git daemon/worker pl_dns_stream_disconnected(): fix tasklist confusion The tasks on the waitinglist are not present in the taskslist, so let's not incorrectly attempt removal in this case. We didn't check the return value here, and the disconnection event won't even happen in the typical cases, so this has been unnoticed - until the deletion actually did find a matching msgid (lucky!) by a *different* task (of course) which triggered an assertion (crash). --- diff --git a/NEWS b/NEWS index 5ff5a7b90..4ff8bd37b 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ Improvements - /local-data/rpz/*/watchdog: new configuration to enable watchdog for RPZ files (!1665) - daemon: fix rare crashes with either of the lines below [system] requirement "h && h->end > h->begin" failed in queue_pop_impl + [system] requirement "val == task" failed in session2_tasklist_del Knot Resolver 6.0.11 (2025-02-26) diff --git a/daemon/session2.h b/daemon/session2.h index f94a82fa0..f0f1868b7 100644 --- a/daemon/session2.h +++ b/daemon/session2.h @@ -828,7 +828,15 @@ struct session2 { uv_timer_t timer; /**< For session-wide timeout events. */ enum protolayer_event_type timer_event; /**< The event fired on timeout. */ - trie_t *tasks; /**< List of tasks associated with given session. */ + + /** List of tasks where an unreplied query has been sent over this session. + * + * Use session2_tasklist_*() functions to manipulate this. + * + * In outgoing sessions the tasks are organized by message ID of the unreplied query. + */ + trie_t *tasks; + queue_t(struct qr_task *) waiting; /**< List of tasks waiting for * sending to upstream. */ struct wire_buf wire_buf; diff --git a/daemon/worker.c b/daemon/worker.c index a58db0caf..6f6cda584 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -2037,7 +2037,7 @@ static enum protolayer_event_cb_result pl_dns_stream_disconnected( while (!session2_waitinglist_is_empty(session)) { struct qr_task *task = session2_waitinglist_pop(session, false); kr_assert(task->refs > 1); - session2_tasklist_del(session, task); + if (session->outgoing) { if (task->ctx->req.options.FORWARD) { /* We are in TCP_FORWARD mode.