diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-07-06 12:43:08 +0300 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-07-06 12:45:36 +0300 |
| commit | 1a9923a07c1283b30a5b02a1668f57015f26232e (patch) | |
| tree | 1d503fc2c5028a772b294b18fe02139521d4e9c1 | |
| parent | 8a94a47e8068dbc8b308cea0b875c516d2ad13f5 (diff) | |
| download | accel-ppp-1a9923a07c1283b30a5b02a1668f57015f26232e.tar.gz accel-ppp-1a9923a07c1283b30a5b02a1668f57015f26232e.zip | |
radius: fix request slot leak when queued request wakeup fails
req_wakeup() ignored the return value of req->send(req, 1). When a
request dequeued from the req-limit queue failed at socket setup
(__rad_req_send returns -2, e.g. under ephemeral port exhaustion or a
routing error), the server's req_cnt slot taken in
rad_server_req_exit() was never released and the request was orphaned
with no callback and no timer.
Leaked slots accumulate until req_cnt permanently saturates req-limit,
after which every request queues forever and the server is effectively
dead until restart.
Handle -2 the same way rad_server_req_enter() does: release the slot,
mark the server failed and drive the request through the regular
failover path so it either retries on another server or reports the
failure to its owner.
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
| -rw-r--r-- | accel-pppd/radius/serv.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/accel-pppd/radius/serv.c b/accel-pppd/radius/serv.c index b48e53ac..71398c82 100644 --- a/accel-pppd/radius/serv.c +++ b/accel-pppd/radius/serv.c @@ -152,7 +152,20 @@ static void req_wakeup(struct rad_req_t *req) } pthread_mutex_unlock(&req->serv->lock); - req->send(req, 1); + if (req->send(req, 1) == -2) { + /* socket setup failed: release the slot taken in + * rad_server_req_exit() and drive the failover path, + * otherwise the server's req_cnt leaks and the request + * is orphaned */ + req->active = 0; + pthread_mutex_lock(&req->serv->lock); + req->serv->req_cnt--; + pthread_mutex_unlock(&req->serv->lock); + + rad_server_fail(req->serv); + + req->send(req, -1); + } } static void req_wakeup_failed(struct rad_req_t *req) |
