summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2011-01-27 08:27:39 +0300
committerDmitry Kozlov <xeb@mail.ru>2011-01-27 08:27:39 +0300
commit673bea74d2beb8d4260355f928499230c7ff9b17 (patch)
tree4b5474b9623f0b6f5a8dbdde48f1dc906fdd322e
parent7f8d3e240fe9544b22846ea05b09515922d1de57 (diff)
downloadaccel-ppp-673bea74d2beb8d4260355f928499230c7ff9b17.tar.gz
accel-ppp-673bea74d2beb8d4260355f928499230c7ff9b17.zip
radius: extended statistics calculation
-rw-r--r--accel-pppd/cli/std_cmd.c2
-rw-r--r--accel-pppd/radius/CMakeLists.txt1
-rw-r--r--accel-pppd/radius/acct.c30
-rw-r--r--accel-pppd/radius/auth.c13
-rw-r--r--accel-pppd/radius/packet.c3
-rw-r--r--accel-pppd/radius/radius.c49
-rw-r--r--accel-pppd/radius/radius.h2
-rw-r--r--accel-pppd/radius/radius_p.h22
-rw-r--r--accel-pppd/radius/stat_accm.c96
9 files changed, 213 insertions, 5 deletions
diff --git a/accel-pppd/cli/std_cmd.c b/accel-pppd/cli/std_cmd.c
index 3adb926a..43407f19 100644
--- a/accel-pppd/cli/std_cmd.c
+++ b/accel-pppd/cli/std_cmd.c
@@ -67,7 +67,7 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
//===========
cli_send(client, "ppp:\r\n");
- cli_sendv(client, " staring: %u\r\n", ppp_stat.starting);
+ cli_sendv(client, " starting: %u\r\n", ppp_stat.starting);
cli_sendv(client, " active: %u\r\n", ppp_stat.active);
cli_sendv(client, " finishing: %u\r\n", ppp_stat.finishing);
diff --git a/accel-pppd/radius/CMakeLists.txt b/accel-pppd/radius/CMakeLists.txt
index 322bee51..d85d60c8 100644
--- a/accel-pppd/radius/CMakeLists.txt
+++ b/accel-pppd/radius/CMakeLists.txt
@@ -1,4 +1,5 @@
SET(sources
+ stat_accm.c
dict.c
req.c
packet.c
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index 40f6f810..62387934 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -73,6 +73,7 @@ static int rad_acct_read(struct triton_md_handler_t *h)
struct rad_req_t *req = container_of(h, typeof(*req), hnd);
struct rad_packet_t *pack;
int r;
+ unsigned int dt;
if (req->reply) {
rad_packet_free(req->reply);
@@ -99,6 +100,11 @@ static int rad_acct_read(struct triton_md_handler_t *h)
if (!req->reply)
return 0;
+ dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 +
+ (req->reply->tv.tv_usec - req->pack->tv.tv_usec) / 1000;
+ stat_accm_add(stat_interim_query_1m, dt);
+ stat_accm_add(stat_interim_query_5m, dt);
+
if (req->reply->code != CODE_ACCOUNTING_RESPONSE || req->reply->id != req->pack->id) {
rad_packet_free(req->reply);
req->reply = NULL;
@@ -116,6 +122,8 @@ static void rad_acct_timeout(struct triton_timer_t *t)
time_t ts, dt;
__sync_add_and_fetch(&stat_interim_lost, 1);
+ stat_accm_add(stat_interim_lost_1m, 1);
+ stat_accm_add(stat_interim_lost_5m, 1);
time(&ts);
@@ -177,6 +185,7 @@ int rad_acct_start(struct radius_pd_t *rpd)
{
int i;
time_t ts;
+ unsigned int dt;
rpd->acct_req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ppp->username);
if (!rpd->acct_req) {
@@ -213,13 +222,23 @@ int rad_acct_start(struct radius_pd_t *rpd)
if (!rpd->acct_req->reply) {
rpd->acct_req->pack->id++;
__sync_add_and_fetch(&stat_acct_lost, 1);
+ stat_accm_add(stat_acct_lost_1m, 1);
+ stat_accm_add(stat_acct_lost_5m, 1);
continue;
}
+
+ dt = (rpd->acct_req->reply->tv.tv_sec - rpd->acct_req->pack->tv.tv_sec) * 1000 +
+ (rpd->acct_req->reply->tv.tv_usec - rpd->acct_req->pack->tv.tv_usec) / 1000;
+ stat_accm_add(stat_acct_query_1m, dt);
+ stat_accm_add(stat_acct_query_5m, dt);
+
if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) {
rad_packet_free(rpd->acct_req->reply);
rpd->acct_req->reply = NULL;
rpd->acct_req->pack->id++;
__sync_add_and_fetch(&stat_acct_lost, 1);
+ stat_accm_add(stat_acct_lost_1m, 1);
+ stat_accm_add(stat_acct_lost_5m, 1);
} else
break;
}
@@ -257,6 +276,7 @@ void rad_acct_stop(struct radius_pd_t *rpd)
{
int i;
time_t ts;
+ unsigned int dt;
if (rpd->acct_interim_timer.tpd)
triton_timer_del(&rpd->acct_interim_timer);
@@ -317,12 +337,22 @@ void rad_acct_stop(struct radius_pd_t *rpd)
rad_req_wait(rpd->acct_req, conf_timeout);
if (!rpd->acct_req->reply) {
__sync_add_and_fetch(&stat_acct_lost, 1);
+ stat_accm_add(stat_acct_lost_1m, 1);
+ stat_accm_add(stat_acct_lost_5m, 1);
continue;
}
+
+ dt = (rpd->acct_req->reply->tv.tv_sec - rpd->acct_req->pack->tv.tv_sec) * 1000 +
+ (rpd->acct_req->reply->tv.tv_usec - rpd->acct_req->pack->tv.tv_usec) / 1000;
+ stat_accm_add(stat_acct_query_1m, dt);
+ stat_accm_add(stat_acct_query_5m, dt);
+
if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) {
rad_packet_free(rpd->acct_req->reply);
rpd->acct_req->reply = NULL;
__sync_add_and_fetch(&stat_acct_lost, 1);
+ stat_accm_add(stat_acct_lost_1m, 1);
+ stat_accm_add(stat_acct_lost_5m, 1);
} else
break;
}
diff --git a/accel-pppd/radius/auth.c b/accel-pppd/radius/auth.c
index 692830ed..70ecbbe2 100644
--- a/accel-pppd/radius/auth.c
+++ b/accel-pppd/radius/auth.c
@@ -145,9 +145,12 @@ static uint8_t* encrypt_password(const char *passwd, const char *secret, const u
static int rad_auth_send(struct rad_req_t *req)
{
int i;
+ struct timeval tv;
+ unsigned int dt;
for(i = 0; i < conf_max_try; i++) {
__sync_add_and_fetch(&stat_auth_sent, 1);
+ gettimeofday(&tv, NULL);
if (rad_req_send(req, conf_verbose))
goto out;
@@ -156,12 +159,20 @@ static int rad_auth_send(struct rad_req_t *req)
if (req->reply) {
if (req->reply->id != req->pack->id) {
__sync_add_and_fetch(&stat_auth_lost, 1);
+ stat_accm_add(stat_auth_lost_1m, 1);
+ stat_accm_add(stat_auth_lost_5m, 1);
rad_packet_free(req->reply);
req->reply = NULL;
- } else
+ } else {
+ dt = (req->reply->tv.tv_sec - tv.tv_sec) * 1000 + (req->reply->tv.tv_usec - tv.tv_usec) / 1000;
+ stat_accm_add(stat_auth_query_1m, dt);
+ stat_accm_add(stat_auth_query_5m, dt);
break;
+ }
} else
__sync_add_and_fetch(&stat_auth_lost, 1);
+ stat_accm_add(stat_auth_lost_1m, 1);
+ stat_accm_add(stat_auth_lost_5m, 1);
}
if (!req->reply)
diff --git a/accel-pppd/radius/packet.c b/accel-pppd/radius/packet.c
index dc355d55..b6230d64 100644
--- a/accel-pppd/radius/packet.c
+++ b/accel-pppd/radius/packet.c
@@ -127,6 +127,7 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
}
pack->buf = ptr;
+ gettimeofday(&pack->tv, NULL);
while (1) {
if (addr)
@@ -625,6 +626,8 @@ int rad_packet_send(struct rad_packet_t *pack, int fd, struct sockaddr_in *addr)
{
int n;
+ gettimeofday(&pack->tv, NULL);
+
while (1) {
if (addr)
n = sendto(fd, pack->buf, pack->len, 0, addr, sizeof(*addr));
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index f371598a..b50b5257 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -56,6 +56,21 @@ unsigned long stat_acct_lost;
unsigned long stat_interim_sent;
unsigned long stat_interim_lost;
+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;
+
static LIST_HEAD(sessions);
static pthread_rwlock_t sessions_lock = PTHREAD_RWLOCK_INITIALIZER;
@@ -360,11 +375,23 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
{
cli_send(client, "radius:\r\n");
cli_sendv(client, " auth sent: %lu\r\n", stat_auth_sent);
- cli_sendv(client, " auth lost: %lu\r\n", stat_auth_lost);
+ cli_sendv(client, " auth lost(total/5m/1m): %lu/%lu/%lu\r\n",
+ stat_auth_lost, stat_accm_get_cnt(stat_auth_lost_5m), stat_accm_get_cnt(stat_auth_lost_1m));
+ cli_sendv(client, " auth avg query time(5m/1m): %lu/%lu ms\n",
+ stat_accm_get_avg(stat_auth_query_5m), stat_accm_get_avg(stat_auth_query_1m));
+
cli_sendv(client, " acct sent: %lu\r\n", stat_acct_sent);
- cli_sendv(client, " acct lost: %lu\r\n", stat_acct_lost);
+ cli_sendv(client, " acct lost(total/5m/1m): %lu/%lu/%lu\r\n",
+ stat_acct_lost, stat_accm_get_cnt(stat_acct_lost_5m), stat_accm_get_cnt(stat_acct_lost_1m));
+ cli_sendv(client, " acct avg query time(5m/1m): %lu/%lu ms\n",
+ stat_accm_get_avg(stat_acct_query_5m), stat_accm_get_avg(stat_acct_query_1m));
+
cli_sendv(client, " interim sent: %lu\r\n", stat_interim_sent);
- cli_sendv(client, " interim lost: %lu\r\n", stat_interim_lost);
+ cli_sendv(client, " interim lost(total/5m/1m): %lu/%lu/%lu\r\n",
+ stat_interim_lost, stat_accm_get_cnt(stat_interim_lost_5m), stat_accm_get_cnt(stat_interim_lost_1m));
+ cli_sendv(client, " interim avg query time(5m/1m): %lu/%lu ms\n",
+ stat_accm_get_avg(stat_interim_query_5m), stat_accm_get_avg(stat_interim_query_1m));
+
return CLI_CMD_OK;
}
@@ -535,4 +562,20 @@ static void __init radius_init(void)
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat");
+
+ stat_auth_lost_1m = stat_accm_create(60);
+ stat_auth_lost_5m = stat_accm_create(5 * 60);
+ stat_auth_query_1m = stat_accm_create(60);
+ stat_auth_query_5m = stat_accm_create(5 * 60);
+
+ stat_acct_lost_1m = stat_accm_create(60);
+ stat_acct_lost_5m = stat_accm_create(5 * 60);
+ stat_acct_query_1m = stat_accm_create(60);
+ stat_acct_query_5m = stat_accm_create(5 * 60);
+
+ stat_interim_lost_1m = stat_accm_create(60);
+ stat_interim_lost_5m = stat_accm_create(5 * 60);
+ stat_interim_query_1m = stat_accm_create(60);
+ stat_interim_query_5m = stat_accm_create(5 * 60);
}
+
diff --git a/accel-pppd/radius/radius.h b/accel-pppd/radius/radius.h
index ad229d22..e580b936 100644
--- a/accel-pppd/radius/radius.h
+++ b/accel-pppd/radius/radius.h
@@ -2,6 +2,7 @@
#define __RADIUS_H
#include <stdint.h>
+#include <sys/time.h>
#define REQ_LENGTH_MAX 4096
@@ -80,6 +81,7 @@ struct rad_packet_t
int code;
uint8_t id;
int len;
+ struct timeval tv;
struct list_head attrs;
void *buf;
};
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index e539dd8b..32acd497 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -3,6 +3,7 @@
#include <netinet/in.h>
#include <pthread.h>
+#include <stdarg.h>
#include "triton.h"
#include "radius.h"
@@ -57,6 +58,7 @@ struct rad_req_t
struct radius_pd_t *rpd;
};
+
extern int conf_max_try;
extern int conf_timeout;
extern int conf_acct_timeout;
@@ -119,5 +121,25 @@ int rad_packet_send(struct rad_packet_t *pck, int fd, struct sockaddr_in *addr);
void dm_coa_cancel(struct radius_pd_t *pd);
+struct stat_accm_t;
+struct stat_accm_t *stat_accm_create(unsigned int time);
+void stat_accm_add(struct stat_accm_t *, unsigned int);
+unsigned long stat_accm_get_cnt(struct stat_accm_t *);
+unsigned long stat_accm_get_avg(struct stat_accm_t *);
+
+extern struct stat_accm_t *stat_auth_lost_1m;
+extern struct stat_accm_t *stat_auth_lost_5m;
+extern struct stat_accm_t *stat_auth_query_1m;
+extern struct stat_accm_t *stat_auth_query_5m;
+
+extern struct stat_accm_t *stat_acct_lost_1m;
+extern struct stat_accm_t *stat_acct_lost_5m;
+extern struct stat_accm_t *stat_acct_query_1m;
+extern struct stat_accm_t *stat_acct_query_5m;
+
+extern struct stat_accm_t *stat_interim_lost_1m;
+extern struct stat_accm_t *stat_interim_lost_5m;
+extern struct stat_accm_t *stat_interim_query_1m;
+extern struct stat_accm_t *stat_interim_query_5m;
#endif
diff --git a/accel-pppd/radius/stat_accm.c b/accel-pppd/radius/stat_accm.c
new file mode 100644
index 00000000..9367ceb3
--- /dev/null
+++ b/accel-pppd/radius/stat_accm.c
@@ -0,0 +1,96 @@
+#include <string.h>
+
+#include "radius_p.h"
+#include "mempool.h"
+#include "memdebug.h"
+
+struct item_t
+{
+ struct list_head entry;
+ unsigned int val;
+ time_t ts;
+};
+
+struct stat_accm_t
+{
+ pthread_mutex_t lock;
+ struct list_head items;
+ unsigned int items_cnt;
+ unsigned int time;
+ unsigned long total;
+};
+
+static mempool_t item_pool;
+
+struct stat_accm_t *stat_accm_create(unsigned int time)
+{
+ struct stat_accm_t *s = _malloc(sizeof(*s));
+
+ memset(s, 0, sizeof(*s));
+ pthread_mutex_init(&s->lock, NULL);
+ INIT_LIST_HEAD(&s->items);
+ s->time = time;
+
+ return s;
+}
+
+static void stat_accm_clean(struct stat_accm_t *s)
+{
+ struct item_t *it;
+ time_t ts = time(NULL);
+
+ while (!list_empty(&s->items)) {
+ it = list_entry(s->items.next, typeof(*it), entry);
+ if (ts - it->ts > s->time) {
+ list_del(&it->entry);
+ --s->items_cnt;
+ s->total -= it->val;
+ mempool_free(it);
+ } else
+ break;
+ }
+}
+
+void stat_accm_add(struct stat_accm_t *s, unsigned int val)
+{
+ struct item_t *it;
+
+ pthread_mutex_lock(&s->lock);
+
+ stat_accm_clean(s);
+
+ it = mempool_alloc(item_pool);
+ it->ts = time(NULL);
+ it->val = val;
+ list_add_tail(&it->entry, &s->items);
+ ++s->items_cnt;
+ s->total += val;
+
+ pthread_mutex_unlock(&s->lock);
+}
+
+unsigned long stat_accm_get_cnt(struct stat_accm_t *s)
+{
+ pthread_mutex_lock(&s->lock);
+ stat_accm_clean(s);
+ pthread_mutex_unlock(&s->lock);
+
+ return s->items_cnt;
+}
+
+unsigned long stat_accm_get_avg(struct stat_accm_t *s)
+{
+ unsigned long val;
+ pthread_mutex_lock(&s->lock);
+ stat_accm_clean(s);
+ val = s->items_cnt ? s->total/s->items_cnt : 0;
+ pthread_mutex_unlock(&s->lock);
+
+ return val;
+}
+
+static void __init init(void)
+{
+ item_pool = mempool_create(sizeof(struct item_t));
+}
+