From abd0c006106f626f9bdadeffd69127f4dea717ce Mon Sep 17 00:00:00 2001 From: Arc Date: Mon, 17 Aug 2026 22:24:05 -0500 Subject: [PATCH] fix(cmrpc): release session when resend exhaustion aborts the AR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pf_cmrpc_send_with_timeout exhausts its resend counter — a CControl request that never got a response, or a fragment that timed out — it aborts the AR (and, in the CControl branch, closes the socket) but never calls pf_session_release. The session stays in_use forever. With PF_MAX_SESSION = 2 * PNET_MAX_AR + 1 (three sessions in the default single-AR configuration), a handful of unanswered CControl requests permanently exhausts the pool. From then on the device logs "CMRPC: Out of session resources for incoming frame" for every incoming RPC frame: new Connects are still accepted (they reuse the recovered connect session) but record writes and PrmEnd stall until the controller's RPC timeout, and the AR eventually aborts with a CMSM startup timeout. The device is wedged until restart. Reproduced with a PROFINET controller repeatedly connecting/aborting against p-net sample devices: before this change a device wedged after ~3 unanswered CControls; after it, 3 consecutive full reconnect cycles across 32 simulated devices completed with flat establish times and zero session-exhaustion errors. Release the session in both exhaustion branches, after the AR abort. Co-Authored-By: Claude Fable 5 --- src/device/pf_cmrpc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/device/pf_cmrpc.c b/src/device/pf_cmrpc.c index 8acb1533..9573caba 100644 --- a/src/device/pf_cmrpc.c +++ b/src/device/pf_cmrpc.c @@ -1135,6 +1135,12 @@ static void pf_cmrpc_send_with_timeout ( pf_udp_close (p_net, p_sess->socket); p_sess->socket = -1; } + /* Release the session, or it stays in_use forever. With + * PF_MAX_SESSION = 2*PNET_MAX_AR + 1 sessions in total, a few + * unanswered CControl requests otherwise exhaust the pool and + * the device permanently logs "Out of session resources" for + * every subsequent incoming frame. */ + pf_session_release (p_net, p_sess); } else { @@ -1148,6 +1154,8 @@ static void pf_cmrpc_send_with_timeout ( p_sess->p_ar->err_code = PNET_ERROR_CODE_2_ABORT_AR_RPC_CONTROL_ERROR; (void)pf_cmdev_cm_abort (p_net, p_sess->p_ar); + /* Same leak as the CControl branch above: release the session. */ + pf_session_release (p_net, p_sess); } } }