From bd936f6074b6b6c515cfd40a1c0215b3dfa7889d Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Sat, 28 Feb 2026 08:25:59 +0200 Subject: radius: fix stop accounting timeout flow and request cleanup When sending accounting STOP requests, the timer callback was incorrectly set to the START timeout handler. This caused stop retries to follow the wrong termination path. Also clear rpd->acct_req before freeing on stop timeout/shutdown failures to avoid leaving a stale pointer. This bug is very nasty, revealed during stress tests, leading to memory corruption and other bad stuff when there is noticeable loss of radius "Stop" packets. Signed-off-by: Denys Fedoryshchenko --- accel-pppd/radius/acct.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c index 9d375d22..e7145a10 100644 --- a/accel-pppd/radius/acct.c +++ b/accel-pppd/radius/acct.c @@ -424,12 +424,16 @@ static void rad_acct_stop_timeout(struct triton_timer_t *t) } if (req->try == conf_max_try) { + if (req->rpd) + req->rpd->acct_req = NULL; rad_req_free(req); return; } if (rad_req_send(req)) { if (ap_shutdown) { + if (req->rpd) + req->rpd->acct_req = NULL; rad_req_free(req); return; } @@ -532,7 +536,7 @@ int rad_acct_stop(struct radius_pd_t *rpd) req_set_RA(req, req->serv->secret); req->recv = rad_acct_stop_recv; - req->timeout.expire = rad_acct_start_timeout; + req->timeout.expire = rad_acct_stop_timeout; req->timeout.expire_tv.tv_sec = conf_timeout; req->sent = rad_acct_stop_sent; req->log = conf_verbose ? log_ppp_info1 : NULL; -- cgit v1.2.3