diff options
-rw-r--r-- | accel-pppd/cli/std_cmd.c | 2 | ||||
-rw-r--r-- | accel-pppd/radius/CMakeLists.txt | 1 | ||||
-rw-r--r-- | accel-pppd/radius/acct.c | 30 | ||||
-rw-r--r-- | accel-pppd/radius/auth.c | 13 | ||||
-rw-r--r-- | accel-pppd/radius/packet.c | 3 | ||||
-rw-r--r-- | accel-pppd/radius/radius.c | 49 | ||||
-rw-r--r-- | accel-pppd/radius/radius.h | 2 | ||||
-rw-r--r-- | accel-pppd/radius/radius_p.h | 22 | ||||
-rw-r--r-- | accel-pppd/radius/stat_accm.c | 96 |
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)); +} + |