summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-07-19 00:56:35 +0300
committerGitHub <noreply@github.com>2026-07-19 00:56:35 +0300
commit0656937adf3aedaddc55e71aecb788f8856118fe (patch)
treebe190e4d85b0e925c1d90f3ce88272990ab440df
parent626acba0b8ca5efda607296277392a04f909ff72 (diff)
parent1a9923a07c1283b30a5b02a1668f57015f26232e (diff)
downloadaccel-ppp-0656937adf3aedaddc55e71aecb788f8856118fe.tar.gz
accel-ppp-0656937adf3aedaddc55e71aecb788f8856118fe.zip
Merge pull request #328 from nuclearcat/radius-leak-fixes
Radius leak fixes
-rw-r--r--accel-pppd/radius/acct.c21
-rw-r--r--accel-pppd/radius/serv.c15
2 files changed, 33 insertions, 3 deletions
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index 69bd3d56..d30aae7a 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -373,6 +373,16 @@ static void rad_acct_stop_sent(struct rad_req_t *req, int res)
rpd->acct_req = NULL;
} else if (req->rpd)
rad_acct_stop_defer(req->rpd);
+ else {
+ /* deferred request: the timeout timer is one-shot and
+ * nobody else references this request, re-arm it to
+ * retry later, otherwise the request and its socket
+ * leak */
+ if (req->timeout.tpd)
+ triton_timer_mod(&req->timeout, 0);
+ else
+ triton_timer_add(NULL, &req->timeout, 0);
+ }
return;
}
@@ -423,7 +433,7 @@ static void rad_acct_stop_timeout(struct triton_timer_t *t)
req->pack->id++;
}
- if (req->try == conf_max_try) {
+ if (req->try >= conf_max_try) {
if (req->rpd)
req->rpd->acct_req = NULL;
rad_req_free(req);
@@ -437,7 +447,14 @@ static void rad_acct_stop_timeout(struct triton_timer_t *t)
rad_req_free(req);
return;
}
- req->try = 0;
+ /* no server available at the moment; the timeout timer is
+ * one-shot, re-arm it to retry later, otherwise the request
+ * and its socket leak; failed attempts count towards
+ * conf_max_try so the request is freed above eventually */
+ if (req->timeout.tpd)
+ triton_timer_mod(&req->timeout, 0);
+ else
+ triton_timer_add(req->rpd ? req->rpd->ses->ctrl->ctx : NULL, &req->timeout, 0);
}
}
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)