diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-04-29 13:38:11 +0300 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-05-04 03:09:49 +0300 |
| commit | dd29f19a14a79437928638029bdb43ba1bba8c08 (patch) | |
| tree | 65c8b66a3db3f3188a67709dcac2568737efc3fc | |
| parent | d28a24252f0df8c8babf3a7321f303d3298029fc (diff) | |
| download | accel-ppp-dd29f19a14a79437928638029bdb43ba1bba8c08.tar.gz accel-ppp-dd29f19a14a79437928638029bdb43ba1bba8c08.zip | |
radius: encapsulate server statistics counters
Group the per-server RADIUS statistics in struct rad_server_stat_t under rad_server_t.stat instead of keeping auth, accounting, interim, and failure counters as separate fields on rad_server_t. This keeps the statistics state collected behind one ownership boundary and makes the relationship between the total counters and their rolling accumulators explicit.
Route counter updates through rad_server_stat_*() helpers. Auth, accounting, interim, and server-failure paths no longer open-code individual counter increments and accumulator updates; the update policy now lives in serv.c with the rest of the RADIUS server accounting logic.
Make the CLI show-stat path render from a local snapshot. The displayed totals are loaded with relaxed atomic reads, the rolling one-minute/five-minute values are collected in one place, and the in-flight request/queue counters are copied under the server lock before printing. Future changes to synchronization or accumulator storage can stay inside the snapshot/update helpers instead of leaking into the CLI formatting code.
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
| -rw-r--r-- | accel-pppd/radius/acct.c | 27 | ||||
| -rw-r--r-- | accel-pppd/radius/auth.c | 9 | ||||
| -rw-r--r-- | accel-pppd/radius/radius_p.h | 58 | ||||
| -rw-r--r-- | accel-pppd/radius/serv.c | 190 |
4 files changed, 201 insertions, 83 deletions
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c index e7145a10..8b04a03f 100644 --- a/accel-pppd/radius/acct.c +++ b/accel-pppd/radius/acct.c @@ -70,7 +70,7 @@ static void rad_acct_sent(struct rad_req_t *req, int res) if (res) return; - __sync_add_and_fetch(&req->serv->stat_interim_sent, 1); + rad_server_stat_interim_sent(req->serv); if (!req->hnd.tpd) triton_md_register_handler(req->rpd->ses->ctrl->ctx, &req->hnd); @@ -88,8 +88,7 @@ static void rad_acct_recv(struct rad_req_t *req) int dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 + (req->reply->tv.tv_nsec - req->pack->tv.tv_nsec) / 1000000; - stat_accm_add(req->serv->stat_interim_query_1m, dt); - stat_accm_add(req->serv->stat_interim_query_5m, dt); + rad_server_stat_interim_query(req->serv, dt); if (req->timeout.tpd) triton_timer_del(&req->timeout); @@ -109,9 +108,7 @@ static void rad_acct_timeout(struct triton_timer_t *t) rad_server_req_exit(req); rad_server_timeout(req->serv); - __sync_add_and_fetch(&req->serv->stat_interim_lost, 1); - stat_accm_add(req->serv->stat_interim_lost_1m, 1); - stat_accm_add(req->serv->stat_interim_lost_5m, 1); + rad_server_stat_interim_lost(req->serv); if (conf_acct_timeout == 0) { triton_timer_del(t); @@ -227,7 +224,7 @@ static void rad_acct_start_sent(struct rad_req_t *req, int res) return; } - __sync_add_and_fetch(&req->serv->stat_acct_sent, 1); + rad_server_stat_acct_sent(req->serv); if (!req->hnd.tpd) triton_md_register_handler(req->rpd->ses->ctrl->ctx, &req->hnd); @@ -246,8 +243,7 @@ static void rad_acct_start_recv(struct rad_req_t *req) int dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 + (req->reply->tv.tv_nsec - req->pack->tv.tv_nsec) / 1000000; - stat_accm_add(req->serv->stat_acct_query_1m, dt); - stat_accm_add(req->serv->stat_acct_query_5m, dt); + rad_server_stat_acct_query(req->serv, dt); triton_timer_del(&req->timeout); @@ -289,9 +285,7 @@ static void rad_acct_start_timeout(struct triton_timer_t *t) rad_server_timeout(req->serv); - __sync_add_and_fetch(&req->serv->stat_acct_lost, 1); - stat_accm_add(req->serv->stat_acct_lost_1m, 1); - stat_accm_add(req->serv->stat_acct_lost_5m, 1); + rad_server_stat_acct_lost(req->serv); if (req->before_send) req->pack->id++; @@ -374,7 +368,7 @@ static void rad_acct_stop_sent(struct rad_req_t *req, int res) return; } - __sync_add_and_fetch(&req->serv->stat_acct_sent, 1); + rad_server_stat_acct_sent(req->serv); if (!req->hnd.tpd) triton_md_register_handler(req->rpd ? req->rpd->ses->ctrl->ctx : NULL, &req->hnd); @@ -393,8 +387,7 @@ static void rad_acct_stop_recv(struct rad_req_t *req) int dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 + (req->reply->tv.tv_nsec - req->pack->tv.tv_nsec) / 1000000; - stat_accm_add(req->serv->stat_acct_query_1m, dt); - stat_accm_add(req->serv->stat_acct_query_5m, dt); + rad_server_stat_acct_query(req->serv, dt); rad_req_free(req); @@ -415,9 +408,7 @@ static void rad_acct_stop_timeout(struct triton_timer_t *t) rad_server_timeout(req->serv); rad_server_req_exit(req); - __sync_add_and_fetch(&req->serv->stat_acct_lost, 1); - stat_accm_add(req->serv->stat_acct_lost_1m, 1); - stat_accm_add(req->serv->stat_acct_lost_5m, 1); + rad_server_stat_acct_lost(req->serv); if (req->before_send) req->pack->id++; diff --git a/accel-pppd/radius/auth.c b/accel-pppd/radius/auth.c index 73e7a50c..593623ee 100644 --- a/accel-pppd/radius/auth.c +++ b/accel-pppd/radius/auth.c @@ -172,8 +172,7 @@ static void rad_auth_recv(struct rad_req_t *req) triton_timer_del(&req->timeout); dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 + (req->reply->tv.tv_nsec - req->pack->tv.tv_nsec) / 1000000; - stat_accm_add(req->serv->stat_auth_query_1m, dt); - stat_accm_add(req->serv->stat_auth_query_5m, dt); + rad_server_stat_auth_query(req->serv, dt); if (pack->code == CODE_ACCESS_ACCEPT) { if (rad_proc_attrs(req)) { @@ -208,9 +207,7 @@ static void rad_auth_timeout(struct triton_timer_t *t) rad_server_timeout(req->serv); - __sync_add_and_fetch(&req->serv->stat_auth_lost, 1); - stat_accm_add(req->serv->stat_auth_lost_1m, 1); - stat_accm_add(req->serv->stat_auth_lost_5m, 1); + rad_server_stat_auth_lost(req->serv); if (rad_req_send(req)) rad_auth_finalize(req->rpd, PWDB_DENIED); @@ -223,7 +220,7 @@ static void rad_auth_sent(struct rad_req_t *req, int res) return; } - __sync_add_and_fetch(&req->serv->stat_auth_sent, 1); + rad_server_stat_auth_sent(req->serv); if (!req->hnd.tpd) triton_md_register_handler(req->rpd->ses->ctrl->ctx, &req->hnd); diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h index 26d877a7..4c2aedaf 100644 --- a/accel-pppd/radius/radius_p.h +++ b/accel-pppd/radius/radius_p.h @@ -115,6 +115,31 @@ struct rad_req_t { void (*log)(const char *fmt, ...); }; +struct rad_server_stat_t { + unsigned long auth_sent; + unsigned long auth_lost; + unsigned long acct_sent; + unsigned long acct_lost; + unsigned long interim_sent; + unsigned long interim_lost; + unsigned long fail_cnt; + + struct stat_accm_t *auth_lost_1m; + struct stat_accm_t *auth_lost_5m; + struct stat_accm_t *auth_query_1m; + struct stat_accm_t *auth_query_5m; + + struct stat_accm_t *acct_lost_1m; + struct stat_accm_t *acct_lost_5m; + struct stat_accm_t *acct_query_1m; + struct stat_accm_t *acct_query_5m; + + struct stat_accm_t *interim_lost_1m; + struct stat_accm_t *interim_lost_5m; + struct stat_accm_t *interim_query_1m; + struct stat_accm_t *interim_query_5m; +}; + struct rad_server_t { struct list_head entry; struct triton_context_t ctx; @@ -139,28 +164,7 @@ struct rad_server_t { int weight; pthread_mutex_t lock; - unsigned long stat_auth_sent; - unsigned long stat_auth_lost; - unsigned long stat_acct_sent; - unsigned long stat_acct_lost; - unsigned long stat_interim_sent; - unsigned long stat_interim_lost; - unsigned long stat_fail_cnt; - - struct stat_accm_t *stat_auth_lost_1m; - struct stat_accm_t *stat_auth_lost_5m; - struct stat_accm_t *stat_auth_query_1m; - struct stat_accm_t *stat_auth_query_5m; - - struct stat_accm_t *stat_acct_lost_1m; - struct stat_accm_t *stat_acct_lost_5m; - struct stat_accm_t *stat_acct_query_1m; - struct stat_accm_t *stat_acct_query_5m; - - struct stat_accm_t *stat_interim_lost_1m; - struct stat_accm_t *stat_interim_lost_5m; - struct stat_accm_t *stat_interim_query_1m; - struct stat_accm_t *stat_interim_query_5m; + struct rad_server_stat_t stat; unsigned int backup:1; unsigned int starting:1; @@ -252,6 +256,16 @@ int rad_server_realloc(struct rad_req_t *); void rad_server_fail(struct rad_server_t *); void rad_server_timeout(struct rad_server_t *); void rad_server_reply(struct rad_server_t *); +void rad_server_stat_fail(struct rad_server_t *); +void rad_server_stat_auth_sent(struct rad_server_t *); +void rad_server_stat_auth_lost(struct rad_server_t *); +void rad_server_stat_auth_query(struct rad_server_t *, unsigned int dt); +void rad_server_stat_acct_sent(struct rad_server_t *); +void rad_server_stat_acct_lost(struct rad_server_t *); +void rad_server_stat_acct_query(struct rad_server_t *, unsigned int dt); +void rad_server_stat_interim_sent(struct rad_server_t *); +void rad_server_stat_interim_lost(struct rad_server_t *); +void rad_server_stat_interim_query(struct rad_server_t *, unsigned int dt); void rad_update_session_timeout(struct radius_pd_t *rpd, int timeout); diff --git a/accel-pppd/radius/serv.c b/accel-pppd/radius/serv.c index 4d97b076..8005bff6 100644 --- a/accel-pppd/radius/serv.c +++ b/accel-pppd/radius/serv.c @@ -346,7 +346,7 @@ void rad_server_fail(struct rad_server_t *s) } s->queue_cnt = 0; - s->stat_fail_cnt++; + rad_server_stat_fail(s); pthread_mutex_unlock(&s->lock); } @@ -366,6 +366,65 @@ void rad_server_reply(struct rad_server_t *s) s->timeout_cnt = 0; } +void rad_server_stat_fail(struct rad_server_t *s) +{ + __atomic_add_fetch(&s->stat.fail_cnt, 1, __ATOMIC_RELAXED); +} + +void rad_server_stat_auth_sent(struct rad_server_t *s) +{ + __atomic_add_fetch(&s->stat.auth_sent, 1, __ATOMIC_RELAXED); +} + +void rad_server_stat_auth_lost(struct rad_server_t *s) +{ + __atomic_add_fetch(&s->stat.auth_lost, 1, __ATOMIC_RELAXED); + stat_accm_add(s->stat.auth_lost_1m, 1); + stat_accm_add(s->stat.auth_lost_5m, 1); +} + +void rad_server_stat_auth_query(struct rad_server_t *s, unsigned int dt) +{ + stat_accm_add(s->stat.auth_query_1m, dt); + stat_accm_add(s->stat.auth_query_5m, dt); +} + +void rad_server_stat_acct_sent(struct rad_server_t *s) +{ + __atomic_add_fetch(&s->stat.acct_sent, 1, __ATOMIC_RELAXED); +} + +void rad_server_stat_acct_lost(struct rad_server_t *s) +{ + __atomic_add_fetch(&s->stat.acct_lost, 1, __ATOMIC_RELAXED); + stat_accm_add(s->stat.acct_lost_1m, 1); + stat_accm_add(s->stat.acct_lost_5m, 1); +} + +void rad_server_stat_acct_query(struct rad_server_t *s, unsigned int dt) +{ + stat_accm_add(s->stat.acct_query_1m, dt); + stat_accm_add(s->stat.acct_query_5m, dt); +} + +void rad_server_stat_interim_sent(struct rad_server_t *s) +{ + __atomic_add_fetch(&s->stat.interim_sent, 1, __ATOMIC_RELAXED); +} + +void rad_server_stat_interim_lost(struct rad_server_t *s) +{ + __atomic_add_fetch(&s->stat.interim_lost, 1, __ATOMIC_RELAXED); + stat_accm_add(s->stat.interim_lost_1m, 1); + stat_accm_add(s->stat.interim_lost_5m, 1); +} + +void rad_server_stat_interim_query(struct rad_server_t *s, unsigned int dt) +{ + stat_accm_add(s->stat.interim_query_1m, dt); + stat_accm_add(s->stat.interim_query_5m, dt); +} + static int req_set_RA(struct rad_req_t *req, const char *secret) { MD5_CTX ctx; @@ -497,10 +556,66 @@ static void serv_ctx_close(struct triton_context_t *ctx) } } +struct rad_server_stat_snapshot_t { + int req_cnt; + int queue_cnt; + unsigned long auth_sent; + unsigned long auth_lost; + unsigned long auth_lost_1m; + unsigned long auth_lost_5m; + unsigned long auth_query_1m; + unsigned long auth_query_5m; + unsigned long acct_sent; + unsigned long acct_lost; + unsigned long acct_lost_1m; + unsigned long acct_lost_5m; + unsigned long acct_query_1m; + unsigned long acct_query_5m; + unsigned long interim_sent; + unsigned long interim_lost; + unsigned long interim_lost_1m; + unsigned long interim_lost_5m; + unsigned long interim_query_1m; + unsigned long interim_query_5m; + unsigned long fail_cnt; +}; + +static void rad_server_stat_get(struct rad_server_t *s, struct rad_server_stat_snapshot_t *stat) +{ + pthread_mutex_lock(&s->lock); + stat->req_cnt = s->req_cnt; + stat->queue_cnt = s->queue_cnt; + pthread_mutex_unlock(&s->lock); + + stat->auth_sent = __atomic_load_n(&s->stat.auth_sent, __ATOMIC_RELAXED); + stat->auth_lost = __atomic_load_n(&s->stat.auth_lost, __ATOMIC_RELAXED); + stat->auth_lost_1m = stat_accm_get_cnt(s->stat.auth_lost_1m); + stat->auth_lost_5m = stat_accm_get_cnt(s->stat.auth_lost_5m); + stat->auth_query_1m = stat_accm_get_avg(s->stat.auth_query_1m); + stat->auth_query_5m = stat_accm_get_avg(s->stat.auth_query_5m); + + stat->acct_sent = __atomic_load_n(&s->stat.acct_sent, __ATOMIC_RELAXED); + stat->acct_lost = __atomic_load_n(&s->stat.acct_lost, __ATOMIC_RELAXED); + stat->acct_lost_1m = stat_accm_get_cnt(s->stat.acct_lost_1m); + stat->acct_lost_5m = stat_accm_get_cnt(s->stat.acct_lost_5m); + stat->acct_query_1m = stat_accm_get_avg(s->stat.acct_query_1m); + stat->acct_query_5m = stat_accm_get_avg(s->stat.acct_query_5m); + + stat->interim_sent = __atomic_load_n(&s->stat.interim_sent, __ATOMIC_RELAXED); + stat->interim_lost = __atomic_load_n(&s->stat.interim_lost, __ATOMIC_RELAXED); + stat->interim_lost_1m = stat_accm_get_cnt(s->stat.interim_lost_1m); + stat->interim_lost_5m = stat_accm_get_cnt(s->stat.interim_lost_5m); + stat->interim_query_1m = stat_accm_get_avg(s->stat.interim_query_1m); + stat->interim_query_5m = stat_accm_get_avg(s->stat.interim_query_5m); + + stat->fail_cnt = __atomic_load_n(&s->stat.fail_cnt, __ATOMIC_RELAXED); +} + static void show_stat(struct rad_server_t *s, void *client) { char addr[INET6_ADDRSTRLEN]; // Sufficient size for both IPv4 and IPv6 addresses struct timespec ts; + struct rad_server_stat_snapshot_t stat; if (s->ipv4) { u_inet_ntoa(s->addr, addr); @@ -509,6 +624,7 @@ static void show_stat(struct rad_server_t *s, void *client) } clock_gettime(CLOCK_MONOTONIC, &ts); + rad_server_stat_get(s, &stat); cli_sendv(client, "radius(%i, %s):\r\n", s->id, addr); @@ -517,31 +633,31 @@ static void show_stat(struct rad_server_t *s, void *client) else cli_send(client, " state: active\r\n"); - cli_sendv(client, " fail count: %lu\r\n", s->stat_fail_cnt); + cli_sendv(client, " fail count: %lu\r\n", stat.fail_cnt); - cli_sendv(client, " request count: %i\r\n", s->req_cnt); - cli_sendv(client, " queue length: %i\r\n", s->queue_cnt); + cli_sendv(client, " request count: %i\r\n", stat.req_cnt); + cli_sendv(client, " queue length: %i\r\n", stat.queue_cnt); if (s->auth_port) { - cli_sendv(client, " auth sent: %lu\r\n", s->stat_auth_sent); + cli_sendv(client, " auth sent: %lu\r\n", stat.auth_sent); cli_sendv(client, " auth lost(total/5m/1m): %lu/%lu/%lu\r\n", - s->stat_auth_lost, stat_accm_get_cnt(s->stat_auth_lost_5m), stat_accm_get_cnt(s->stat_auth_lost_1m)); + stat.auth_lost, stat.auth_lost_5m, stat.auth_lost_1m); cli_sendv(client, " auth avg query time(5m/1m): %lu/%lu ms\r\n", - stat_accm_get_avg(s->stat_auth_query_5m), stat_accm_get_avg(s->stat_auth_query_1m)); + stat.auth_query_5m, stat.auth_query_1m); } if (s->acct_port) { - cli_sendv(client, " acct sent: %lu\r\n", s->stat_acct_sent); + cli_sendv(client, " acct sent: %lu\r\n", stat.acct_sent); cli_sendv(client, " acct lost(total/5m/1m): %lu/%lu/%lu\r\n", - s->stat_acct_lost, stat_accm_get_cnt(s->stat_acct_lost_5m), stat_accm_get_cnt(s->stat_acct_lost_1m)); + stat.acct_lost, stat.acct_lost_5m, stat.acct_lost_1m); cli_sendv(client, " acct avg query time(5m/1m): %lu/%lu ms\r\n", - stat_accm_get_avg(s->stat_acct_query_5m), stat_accm_get_avg(s->stat_acct_query_1m)); + stat.acct_query_5m, stat.acct_query_1m); - cli_sendv(client, " interim sent: %lu\r\n", s->stat_interim_sent); + cli_sendv(client, " interim sent: %lu\r\n", stat.interim_sent); cli_sendv(client, " interim lost(total/5m/1m): %lu/%lu/%lu\r\n", - s->stat_interim_lost, stat_accm_get_cnt(s->stat_interim_lost_5m), stat_accm_get_cnt(s->stat_interim_lost_1m)); + stat.interim_lost, stat.interim_lost_5m, stat.interim_lost_1m); cli_sendv(client, " interim avg query time(5m/1m): %lu/%lu ms\r\n", - stat_accm_get_avg(s->stat_interim_query_5m), stat_accm_get_avg(s->stat_interim_query_1m)); + stat.interim_query_5m, stat.interim_query_1m); } } @@ -579,20 +695,20 @@ static void __add_server(struct rad_server_t *s) list_add_tail(&s->entry, &serv_list); s->starting = conf_acct_on; - s->stat_auth_lost_1m = stat_accm_create(60); - s->stat_auth_lost_5m = stat_accm_create(5 * 60); - s->stat_auth_query_1m = stat_accm_create(60); - s->stat_auth_query_5m = stat_accm_create(5 * 60); + s->stat.auth_lost_1m = stat_accm_create(60); + s->stat.auth_lost_5m = stat_accm_create(5 * 60); + s->stat.auth_query_1m = stat_accm_create(60); + s->stat.auth_query_5m = stat_accm_create(5 * 60); - s->stat_acct_lost_1m = stat_accm_create(60); - s->stat_acct_lost_5m = stat_accm_create(5 * 60); - s->stat_acct_query_1m = stat_accm_create(60); - s->stat_acct_query_5m = stat_accm_create(5 * 60); + s->stat.acct_lost_1m = stat_accm_create(60); + s->stat.acct_lost_5m = stat_accm_create(5 * 60); + s->stat.acct_query_1m = stat_accm_create(60); + s->stat.acct_query_5m = stat_accm_create(5 * 60); - s->stat_interim_lost_1m = stat_accm_create(60); - s->stat_interim_lost_5m = stat_accm_create(5 * 60); - s->stat_interim_query_1m = stat_accm_create(60); - s->stat_interim_query_5m = stat_accm_create(5 * 60); + s->stat.interim_lost_1m = stat_accm_create(60); + s->stat.interim_lost_5m = stat_accm_create(5 * 60); + s->stat.interim_query_1m = stat_accm_create(60); + s->stat.interim_query_5m = stat_accm_create(5 * 60); s->ctx.close = serv_ctx_close; @@ -607,20 +723,20 @@ static void __free_server(struct rad_server_t *s) { log_debug("radius: free(%i)\n", s->id); - stat_accm_free(s->stat_auth_lost_1m); - stat_accm_free(s->stat_auth_lost_5m); - stat_accm_free(s->stat_auth_query_1m); - stat_accm_free(s->stat_auth_query_5m); + stat_accm_free(s->stat.auth_lost_1m); + stat_accm_free(s->stat.auth_lost_5m); + stat_accm_free(s->stat.auth_query_1m); + stat_accm_free(s->stat.auth_query_5m); - stat_accm_free(s->stat_acct_lost_1m); - stat_accm_free(s->stat_acct_lost_5m); - stat_accm_free(s->stat_acct_query_1m); - stat_accm_free(s->stat_acct_query_5m); + stat_accm_free(s->stat.acct_lost_1m); + stat_accm_free(s->stat.acct_lost_5m); + stat_accm_free(s->stat.acct_query_1m); + stat_accm_free(s->stat.acct_query_5m); - stat_accm_free(s->stat_interim_lost_1m); - stat_accm_free(s->stat_interim_lost_5m); - stat_accm_free(s->stat_interim_query_1m); - stat_accm_free(s->stat_interim_query_5m); + stat_accm_free(s->stat.interim_lost_1m); + stat_accm_free(s->stat.interim_lost_5m); + stat_accm_free(s->stat.interim_query_1m); + stat_accm_free(s->stat.interim_query_5m); triton_context_unregister(&s->ctx); |
