summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-04-29 13:38:11 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-05-04 03:09:49 +0300
commitdd29f19a14a79437928638029bdb43ba1bba8c08 (patch)
tree65c8b66a3db3f3188a67709dcac2568737efc3fc
parentd28a24252f0df8c8babf3a7321f303d3298029fc (diff)
downloadaccel-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.c27
-rw-r--r--accel-pppd/radius/auth.c9
-rw-r--r--accel-pppd/radius/radius_p.h58
-rw-r--r--accel-pppd/radius/serv.c190
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);