From 2d8540f1eedeacd5a58aa5a19cfe7bc1d7df8549 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 24 Mar 2026 18:02:46 +0300 Subject: [PATCH] transport: fix process_startup cert-auth path missing connection-ready setup When authenticate() returns a user directly (certificate-based auth, introduced in 20e9619bb1), process_startup was missing the same post-authentication bookkeeping that the no-auth and SASL paths perform: - update_scheduling_group(): without it, the connection runs under the default scheduling group instead of the one mapped to the user's service level. - _authenticating = false / _ready = true: without them, system.clients reports connection_stage = AUTHENTICATING forever instead of READY. - on_connection_ready(): without it, the connection never releases its slot in the uninitialized-connections concurrency semaphore (acquired at connection creation), leaking one unit per cert-authenticated connection for the lifetime of the connection. The omission was introduced when on_connection_ready() was added to the else and SASL branches in 474e84199c but the cert-auth branch was missed. Fixes: 20e9619bb1 ("auth: support certificate-based authentication") Signed-off-by: Pavel Emelyanov Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- test/cluster/auth_cluster/test_connection_stage.py | 2 +- transport/server.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/test/cluster/auth_cluster/test_connection_stage.py b/test/cluster/auth_cluster/test_connection_stage.py index b825e3b6de..095987e217 100644 --- a/test/cluster/auth_cluster/test_connection_stage.py +++ b/test/cluster/auth_cluster/test_connection_stage.py @@ -68,7 +68,7 @@ def make_server_config(auth_type: str) -> dict: @pytest.mark.parametrize("auth_type", [ "allow_all", "password", - pytest.param("cert_bypass", marks=pytest.mark.xfail(reason="bug in process_startup cert-auth path", strict=True)), + "cert_bypass", ]) @pytest.mark.skip_mode("release", reason="error injections are not supported in release mode") async def test_connection_stage_ready_after_auth(manager: ManagerClient, auth_type: str) -> None: diff --git a/transport/server.cc b/transport/server.cc index 76256224d2..5caf2d69c0 100644 --- a/transport/server.cc +++ b/transport/server.cc @@ -1405,6 +1405,10 @@ future> cql_server::connection::process_st client_state.set_login(std::move(*opt_user)); co_await client_state.check_user_can_login(); client_state.maybe_update_per_service_level_params(); + update_scheduling_group(); + _authenticating = false; + _ready = true; + on_connection_ready(); res = make_ready(stream, trace_state); } else { res = make_autheticate(stream, a.qualified_java_name(), trace_state);