diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-05-13 21:43:13 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-13 21:43:13 +0300 |
| commit | d611c3240863f79029ab48d492659a67f82465d9 (patch) | |
| tree | 8171a65c511849b941fbf492514cb5c89918b4e4 | |
| parent | 5b78328068085a8dc530978fd0b51f5c187a6aff (diff) | |
| parent | e5fe0eaa1fc6b1109db784e818e360159d8dd2ac (diff) | |
| download | accel-ppp-d611c3240863f79029ab48d492659a67f82465d9.tar.gz accel-ppp-d611c3240863f79029ab48d492659a67f82465d9.zip | |
Merge pull request #308 from nuclearcat/stats-rework
stats: improve how we handle statistics in the code
33 files changed, 1321 insertions, 630 deletions
diff --git a/accel-pppd/cli/std_cmd.c b/accel-pppd/cli/std_cmd.c index c37777b1..951b10da 100644 --- a/accel-pppd/cli/std_cmd.c +++ b/accel-pppd/cli/std_cmd.c @@ -30,6 +30,9 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, #ifdef MEMDEBUG struct mallinfo mi = mallinfo(); #endif + struct triton_stat_t stat; + + triton_stat_get(&stat); sprintf(statm_fname, "/proc/%i/statm", getpid()); f = fopen(statm_fname, "r"); @@ -39,14 +42,14 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, } clock_gettime(CLOCK_MONOTONIC, &ts); - dt = ts.tv_sec - triton_stat.start_time; + dt = ts.tv_sec - stat.start_time; day = dt / (60 * 60 * 24); dt %= 60 * 60 * 24; hour = dt / (60 * 60); dt %= 60 * 60; cli_sendv(client, "uptime: %i.%02i:%02lu:%02lu\r\n", day, hour, dt / 60, dt % 60); - cli_sendv(client, "cpu: %i%%\r\n", triton_stat.cpu); + cli_sendv(client, "cpu: %i%%\r\n", stat.cpu); #ifdef MEMDEBUG cli_send(client, "memory:\r\n"); cli_sendv(client, " rss/virt: %lu/%lu kB\r\n", vmrss * page_size_kb, vmsize * page_size_kb); @@ -58,23 +61,29 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, cli_sendv(client, "mem(rss/virt): %lu/%lu kB\r\n", vmrss * page_size_kb, vmsize * page_size_kb); #endif cli_send(client, "core:\r\n"); - cli_sendv(client, " mempool_allocated: %" PRIu64 "\r\n", triton_stat.mempool_allocated); - cli_sendv(client, " mempool_available: %" PRIu64 "\r\n", triton_stat.mempool_available); - cli_sendv(client, " thread_count: %u\r\n", triton_stat.thread_count); - cli_sendv(client, " thread_active: %u\r\n", triton_stat.thread_active); - cli_sendv(client, " context_count: %u\r\n", triton_stat.context_count); - cli_sendv(client, " context_sleeping: %u\r\n", triton_stat.context_sleeping); - cli_sendv(client, " context_pending: %u\r\n", triton_stat.context_pending); - cli_sendv(client, " md_handler_count: %u\r\n", triton_stat.md_handler_count); - cli_sendv(client, " md_handler_pending: %u\r\n", triton_stat.md_handler_pending); - cli_sendv(client, " timer_count: %u\r\n", triton_stat.timer_count); - cli_sendv(client, " timer_pending: %u\r\n", triton_stat.timer_pending); + cli_sendv(client, " mempool_allocated: %" PRIu64 "\r\n", stat.mempool_allocated); + cli_sendv(client, " mempool_available: %" PRIu64 "\r\n", stat.mempool_available); + cli_sendv(client, " thread_count: %u\r\n", stat.thread_count); + cli_sendv(client, " thread_active: %u\r\n", stat.thread_active); + cli_sendv(client, " context_count: %u\r\n", stat.context_count); + cli_sendv(client, " context_sleeping: %u\r\n", stat.context_sleeping); + cli_sendv(client, " context_pending: %u\r\n", stat.context_pending); + cli_sendv(client, " md_handler_count: %u\r\n", stat.md_handler_count); + cli_sendv(client, " md_handler_pending: %u\r\n", stat.md_handler_pending); + cli_sendv(client, " timer_count: %u\r\n", stat.timer_count); + cli_sendv(client, " timer_pending: %u\r\n", stat.timer_pending); //=========== - cli_send(client, "sessions:\r\n"); - cli_sendv(client, " starting: %u\r\n", ap_session_stat.starting); - cli_sendv(client, " active: %u\r\n", ap_session_stat.active); - cli_sendv(client, " finishing: %u\r\n", ap_session_stat.finishing); + { + struct ap_session_stat ses_stat; + + ap_session_stat_get(&ses_stat); + + cli_send(client, "sessions:\r\n"); + cli_sendv(client, " starting: %u\r\n", ses_stat.starting); + cli_sendv(client, " active: %u\r\n", ses_stat.active); + cli_sendv(client, " finishing: %u\r\n", ses_stat.finishing); + } return CLI_CMD_OK; } diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index e215c565..5592845f 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -180,9 +180,7 @@ static int conf_check_mac_change; static int conf_soft_terminate; static int conf_calling_sid = SID_MAC; -static unsigned int stat_starting; -static unsigned int stat_active; -static unsigned int stat_delayed_offer; +static struct ipoe_stat_t ipoe_stat; static mempool_t ses_pool; static mempool_t disc_item_pool; @@ -225,6 +223,39 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc static void __terminate(struct ap_session *ses); static void ipoe_ipv6_disable(struct ipoe_serv *serv); +void __export ipoe_stat_get(struct ipoe_stat_t *stat) +{ + stat->starting = __atomic_load_n(&ipoe_stat.starting, __ATOMIC_RELAXED); + stat->active = __atomic_load_n(&ipoe_stat.active, __ATOMIC_RELAXED); + stat->delayed_offer = __atomic_load_n(&ipoe_stat.delayed_offer, __ATOMIC_RELAXED); +} + +unsigned int __export ipoe_stat_starting(void) +{ + return __atomic_load_n(&ipoe_stat.starting, __ATOMIC_RELAXED); +} + +unsigned int __export ipoe_stat_active(void) +{ + return __atomic_load_n(&ipoe_stat.active, __ATOMIC_RELAXED); +} + +static void ipoe_stat_inc(unsigned int *stat) +{ + __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void ipoe_stat_dec(unsigned int *stat) +{ + __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void ipoe_stat_move(unsigned int *from, unsigned int *to) +{ + ipoe_stat_dec(from); + ipoe_stat_inc(to); +} + static void ipoe_ctx_switch(struct triton_context_t *ctx, void *arg) { if (arg) { @@ -741,7 +772,7 @@ static void ipoe_session_start(struct ipoe_session *ses) } } - __sync_add_and_fetch(&stat_starting, 1); + ipoe_stat_inc(&ipoe_stat.starting); assert(!ses->ses.username); @@ -1058,8 +1089,7 @@ static void __ipoe_session_activate(struct ipoe_session *ses) } } - __sync_sub_and_fetch(&stat_starting, 1); - __sync_add_and_fetch(&stat_active, 1); + ipoe_stat_move(&ipoe_stat.starting, &ipoe_stat.active); ses->started = 1; ap_session_activate(&ses->ses); @@ -1184,9 +1214,9 @@ static void ipoe_session_started(struct ap_session *s) static void ipoe_session_free(struct ipoe_session *ses) { if (ses->started) - __sync_sub_and_fetch(&stat_active, 1); + ipoe_stat_dec(&ipoe_stat.active); else - __sync_sub_and_fetch(&stat_starting, 1); + ipoe_stat_dec(&ipoe_stat.starting); if (ses->timer.tpd) triton_timer_del(&ses->timer); @@ -1362,10 +1392,10 @@ static struct ipoe_session *ipoe_session_create_dhcpv4(struct ipoe_serv *serv, s if (ap_shutdown) return NULL; - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) return NULL; - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) return NULL; ses = ipoe_session_alloc(serv->ifname); @@ -1632,7 +1662,7 @@ static void ipoe_serv_disc_timer(struct triton_timer_t *t) list_del(&d->entry); mempool_free(d); - __sync_sub_and_fetch(&stat_delayed_offer, 1); + ipoe_stat_dec(&ipoe_stat.delayed_offer); } while (!list_empty(&serv->arp_list)) { @@ -1651,7 +1681,7 @@ static void ipoe_serv_disc_timer(struct triton_timer_t *t) list_del(&d->entry); mempool_free(d); - __sync_sub_and_fetch(&stat_delayed_offer, 1); + ipoe_stat_dec(&ipoe_stat.delayed_offer); } if (list_empty(&serv->disc_list) && list_empty(&serv->arp_list)) @@ -1672,7 +1702,7 @@ static void ipoe_serv_add_disc_arp(struct ipoe_serv *serv, struct _arphdr *arph, if (!d) return; - __sync_add_and_fetch(&stat_delayed_offer, 1); + ipoe_stat_inc(&ipoe_stat.delayed_offer); memcpy(&d->arph, arph, sizeof(*arph)); clock_gettime(CLOCK_MONOTONIC, &d->ts); @@ -1692,7 +1722,7 @@ static void ipoe_serv_add_disc(struct ipoe_serv *serv, struct dhcpv4_packet *pac if (!d) return; - __sync_add_and_fetch(&stat_delayed_offer, 1); + ipoe_stat_inc(&ipoe_stat.delayed_offer); dhcpv4_packet_ref(pack); d->pack = pack; @@ -1721,7 +1751,7 @@ static int ipoe_serv_check_disc(struct ipoe_serv *serv, struct dhcpv4_packet *pa dhcpv4_packet_free(d->pack); mempool_free(d); - __sync_sub_and_fetch(&stat_delayed_offer, 1); + ipoe_stat_dec(&ipoe_stat.delayed_offer); return 1; } @@ -1869,7 +1899,7 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet if (!ses) goto out; - ses->weight = weight = serv->opt_weight >= 0 ? serv->sess_cnt * serv->opt_weight : (stat_active + 1) * conf_weight; + ses->weight = weight = serv->opt_weight >= 0 ? serv->sess_cnt * serv->opt_weight : (ipoe_stat_active() + 1) * conf_weight; } else { if (ses->terminate) { triton_context_call(ses->ctrl.ctx, (triton_event_func)ipoe_session_terminated, ses); @@ -2107,10 +2137,10 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc if (ap_shutdown) return NULL; - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) return NULL; - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) return NULL; if (connlimit_loaded && connlimit_check(serv->opt_shared ? cl_key_from_ipv4(saddr) : serv->ifindex)) @@ -2327,7 +2357,7 @@ void ipoe_serv_recv_arp(struct ipoe_serv *serv, struct _arphdr *arph) list_del(&d->entry); mempool_free(d); - __sync_sub_and_fetch(&stat_delayed_offer, 1); + ipoe_stat_dec(&ipoe_stat.delayed_offer); break; } @@ -2624,14 +2654,14 @@ static void ipoe_serv_release(struct ipoe_serv *serv) list_del(&d->entry); dhcpv4_packet_free(d->pack); mempool_free(d); - __sync_sub_and_fetch(&stat_delayed_offer, 1); + ipoe_stat_dec(&ipoe_stat.delayed_offer); } while (!list_empty(&serv->arp_list)) { struct arp_item *d = list_entry(serv->arp_list.next, typeof(*d), entry); list_del(&d->entry); mempool_free(d); - __sync_sub_and_fetch(&stat_delayed_offer, 1); + ipoe_stat_dec(&ipoe_stat.delayed_offer); } while (!list_empty(&serv->req_list)) { @@ -2704,10 +2734,14 @@ static void l4_redirect_ctx_close(struct triton_context_t *ctx) static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) { + struct ipoe_stat_t stat; + + ipoe_stat_get(&stat); + cli_send(client, "ipoe:\r\n"); - cli_sendv(client," starting: %u\r\n", stat_starting); - cli_sendv(client," active: %u\r\n", stat_active); - cli_sendv(client," delayed: %u\r\n", stat_delayed_offer); + cli_sendv(client," starting: %u\r\n", stat.starting); + cli_sendv(client," active: %u\r\n", stat.active); + cli_sendv(client," delayed: %u\r\n", stat.delayed_offer); return CLI_CMD_OK; } @@ -2725,12 +2759,6 @@ static void print_session_type(struct ap_session *s, char *buf) *buf = 0; } -void __export ipoe_get_stat(unsigned int **starting, unsigned int **active) -{ - *starting = &stat_starting; - *active = &stat_active; -} - static void __terminate(struct ap_session *ses) { ap_session_terminate(ses, TERM_NAS_REQUEST, 1); @@ -2768,9 +2796,10 @@ struct ipoe_serv *ipoe_find_serv(const char *ifname) static int get_offer_delay() { struct delay *r, *prev = NULL; + unsigned int active = ipoe_stat_active(); list_for_each_entry(r, &conf_offer_delay, entry) { - if (!prev || stat_active >= r->conn_cnt) { + if (!prev || active >= r->conn_cnt) { prev = r; continue; } diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h index 38f521e1..37c26a63 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.h +++ b/accel-pppd/ctrl/ipoe/ipoe.h @@ -130,6 +130,17 @@ struct ipoe_session_info { uint32_t peer_addr; }; +struct ipoe_stat_t +{ + unsigned int starting; + unsigned int active; + unsigned int delayed_offer; +}; + +void ipoe_stat_get(struct ipoe_stat_t *stat); +unsigned int ipoe_stat_starting(void); +unsigned int ipoe_stat_active(void); + int ipoe_ipv6_nd_start(struct ipoe_serv *serv); #ifdef USE_LUA diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c index 1a4c63d4..cf0c502c 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.c +++ b/accel-pppd/ctrl/l2tp/l2tp.c @@ -100,17 +100,22 @@ static const char *conf_ipv6_pool; static const char *conf_dpv6_pool; static const char *conf_ifname; -static unsigned int stat_conn_starting; -static unsigned int stat_conn_active; -static unsigned int stat_conn_finishing; +struct l2tp_stat_t +{ + unsigned int conn_starting; + unsigned int conn_active; + unsigned int conn_finishing; + + unsigned int sess_starting; + unsigned int sess_active; + unsigned int sess_finishing; -static unsigned int stat_sess_starting; -static unsigned int stat_sess_active; -static unsigned int stat_sess_finishing; + unsigned int data_starting; + unsigned int data_active; + unsigned int data_finishing; +}; -static unsigned int stat_active; -static unsigned int stat_starting; -static unsigned int stat_finishing; +static struct l2tp_stat_t l2tp_stat; struct l2tp_serv_t { @@ -205,6 +210,45 @@ static void l2tp_session_free(struct l2tp_sess_t *sess); static void l2tp_tunnel_free(struct l2tp_conn_t *conn); static void apses_stop(void *data); +static void l2tp_stat_inc(unsigned int *stat) +{ + __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void l2tp_stat_dec(unsigned int *stat) +{ + __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void l2tp_stat_move(unsigned int *from, unsigned int *to) +{ + l2tp_stat_dec(from); + l2tp_stat_inc(to); +} + +static void l2tp_stat_get(struct l2tp_stat_t *stat) +{ + stat->conn_starting = __atomic_load_n(&l2tp_stat.conn_starting, __ATOMIC_RELAXED); + stat->conn_active = __atomic_load_n(&l2tp_stat.conn_active, __ATOMIC_RELAXED); + stat->conn_finishing = __atomic_load_n(&l2tp_stat.conn_finishing, __ATOMIC_RELAXED); + stat->sess_starting = __atomic_load_n(&l2tp_stat.sess_starting, __ATOMIC_RELAXED); + stat->sess_active = __atomic_load_n(&l2tp_stat.sess_active, __ATOMIC_RELAXED); + stat->sess_finishing = __atomic_load_n(&l2tp_stat.sess_finishing, __ATOMIC_RELAXED); + stat->data_starting = __atomic_load_n(&l2tp_stat.data_starting, __ATOMIC_RELAXED); + stat->data_active = __atomic_load_n(&l2tp_stat.data_active, __ATOMIC_RELAXED); + stat->data_finishing = __atomic_load_n(&l2tp_stat.data_finishing, __ATOMIC_RELAXED); +} + +unsigned int __export l2tp_stat_starting(void) +{ + return __atomic_load_n(&l2tp_stat.data_starting, __ATOMIC_RELAXED); +} + +unsigned int __export l2tp_stat_active(void) +{ + return __atomic_load_n(&l2tp_stat.data_active, __ATOMIC_RELAXED); +} + #define log_tunnel(log_func, conn, fmt, ...) \ do { \ @@ -877,12 +921,10 @@ static int l2tp_tunnel_disconnect(struct l2tp_conn_t *conn, case STATE_INIT: case STATE_WAIT_SCCRP: case STATE_WAIT_SCCCN: - __sync_sub_and_fetch(&stat_conn_starting, 1); - __sync_add_and_fetch(&stat_conn_finishing, 1); + l2tp_stat_move(&l2tp_stat.conn_starting, &l2tp_stat.conn_finishing); break; case STATE_ESTB: - __sync_sub_and_fetch(&stat_conn_active, 1); - __sync_add_and_fetch(&stat_conn_finishing, 1); + l2tp_stat_move(&l2tp_stat.conn_active, &l2tp_stat.conn_finishing); break; case STATE_FIN: case STATE_FIN_WAIT: @@ -962,7 +1004,7 @@ static void __tunnel_destroy(struct l2tp_conn_t *conn) mempool_free(conn); - __sync_sub_and_fetch(&stat_conn_finishing, 1); + l2tp_stat_dec(&l2tp_stat.conn_finishing); } static void tunnel_put(struct l2tp_conn_t *conn) @@ -999,7 +1041,7 @@ static void __session_destroy(struct l2tp_sess_t *sess) mempool_free(sess); - __sync_sub_and_fetch(&stat_sess_finishing, 1); + l2tp_stat_dec(&l2tp_stat.sess_finishing); /* Now that the session is fully destroyed, * drop the reference to the tunnel. @@ -1032,15 +1074,13 @@ static void l2tp_session_free(struct l2tp_sess_t *sess) case STATE_WAIT_OCCN: log_session(log_info2, sess, "deleting session\n"); - __sync_sub_and_fetch(&stat_sess_starting, 1); - __sync_add_and_fetch(&stat_sess_finishing, 1); + l2tp_stat_move(&l2tp_stat.sess_starting, &l2tp_stat.sess_finishing); break; case STATE_ESTB: log_session(log_info2, sess, "deleting session\n"); triton_event_fire(EV_CTRL_FINISHED, &sess->ppp.ses); - __sync_sub_and_fetch(&stat_sess_active, 1); - __sync_add_and_fetch(&stat_sess_finishing, 1); + l2tp_stat_move(&l2tp_stat.sess_active, &l2tp_stat.sess_finishing); pthread_mutex_lock(&sess->apses_lock); if (sess->apses_ctx.tpd) @@ -1135,12 +1175,10 @@ static void l2tp_tunnel_free(struct l2tp_conn_t *conn) case STATE_INIT: case STATE_WAIT_SCCRP: case STATE_WAIT_SCCCN: - __sync_sub_and_fetch(&stat_conn_starting, 1); - __sync_add_and_fetch(&stat_conn_finishing, 1); + l2tp_stat_move(&l2tp_stat.conn_starting, &l2tp_stat.conn_finishing); break; case STATE_ESTB: - __sync_sub_and_fetch(&stat_conn_active, 1); - __sync_add_and_fetch(&stat_conn_finishing, 1); + l2tp_stat_move(&l2tp_stat.conn_active, &l2tp_stat.conn_finishing); break; case STATE_FIN: case STATE_FIN_WAIT: @@ -1263,7 +1301,7 @@ static void __apses_destroy(void *data) log_ppp_info2("session destroyed\n"); - __sync_sub_and_fetch(&stat_finishing, 1); + l2tp_stat_dec(&l2tp_stat.data_finishing); /* Drop reference to the L2TP session */ session_put(sess); @@ -1278,12 +1316,10 @@ static void apses_finished(struct ap_session *apses) switch (sess->apses_state) { case APSTATE_STARTING: - __sync_sub_and_fetch(&stat_starting, 1); - __sync_add_and_fetch(&stat_finishing, 1); + l2tp_stat_move(&l2tp_stat.data_starting, &l2tp_stat.data_finishing); break; case APSTATE_STARTED: - __sync_sub_and_fetch(&stat_active, 1); - __sync_add_and_fetch(&stat_finishing, 1); + l2tp_stat_move(&l2tp_stat.data_active, &l2tp_stat.data_finishing); break; case APSTATE_FINISHING: break; @@ -1324,12 +1360,10 @@ static void apses_stop(void *data) switch (sess->apses_state) { case APSTATE_INIT: case APSTATE_STARTING: - __sync_sub_and_fetch(&stat_starting, 1); - __sync_add_and_fetch(&stat_finishing, 1); + l2tp_stat_move(&l2tp_stat.data_starting, &l2tp_stat.data_finishing); break; case APSTATE_STARTED: - __sync_sub_and_fetch(&stat_active, 1); - __sync_add_and_fetch(&stat_finishing, 1); + l2tp_stat_move(&l2tp_stat.data_active, &l2tp_stat.data_finishing); break; case APSTATE_FINISHING: break; @@ -1388,8 +1422,7 @@ static void apses_started(struct ap_session *apses) return; } - __sync_sub_and_fetch(&stat_starting, 1); - __sync_add_and_fetch(&stat_active, 1); + l2tp_stat_move(&l2tp_stat.data_starting, &l2tp_stat.data_active); sess->apses_state = APSTATE_STARTED; log_ppp_info1("session started over l2tp session %hu-%hu, %hu-%hu\n", @@ -1518,7 +1551,7 @@ static struct l2tp_sess_t *l2tp_tunnel_alloc_session(struct l2tp_conn_t *conn) tunnel_hold(conn); session_hold(sess); - __sync_add_and_fetch(&stat_sess_starting, 1); + l2tp_stat_inc(&l2tp_stat.sess_starting); return sess; } @@ -1737,7 +1770,7 @@ static struct l2tp_conn_t *l2tp_tunnel_alloc(const struct sockaddr_in *peer, conn->peer_rcv_wnd_sz = DEFAULT_PEER_RECV_WINDOW_SIZE; tunnel_hold(conn); - __sync_add_and_fetch(&stat_conn_starting, 1); + l2tp_stat_inc(&l2tp_stat.conn_starting); return conn; @@ -1882,7 +1915,7 @@ static int l2tp_session_start_data_channel(struct l2tp_sess_t *sess) goto err_put_ctx; } - __sync_add_and_fetch(&stat_starting, 1); + l2tp_stat_inc(&l2tp_stat.data_starting); return 0; @@ -2012,8 +2045,7 @@ static int l2tp_session_connect(struct l2tp_sess_t *sess) } triton_event_fire(EV_CTRL_STARTED, &sess->ppp.ses); - __sync_sub_and_fetch(&stat_sess_starting, 1); - __sync_add_and_fetch(&stat_sess_active, 1); + l2tp_stat_move(&l2tp_stat.sess_starting, &l2tp_stat.sess_active); sess->state1 = STATE_ESTB; if (l2tp_session_start_data_channel(sess) < 0) { @@ -2091,8 +2123,7 @@ static int l2tp_tunnel_connect(struct l2tp_conn_t *conn) close(tunnel_fd); - __sync_sub_and_fetch(&stat_conn_starting, 1); - __sync_add_and_fetch(&stat_conn_active, 1); + l2tp_stat_move(&l2tp_stat.conn_starting, &l2tp_stat.conn_active); conn->state = STATE_ESTB; return 0; @@ -2722,12 +2753,10 @@ static void l2tp_tunnel_finwait(struct l2tp_conn_t *conn) switch (conn->state) { case STATE_WAIT_SCCRP: case STATE_WAIT_SCCCN: - __sync_sub_and_fetch(&stat_conn_starting, 1); - __sync_add_and_fetch(&stat_conn_finishing, 1); + l2tp_stat_move(&l2tp_stat.conn_starting, &l2tp_stat.conn_finishing); break; case STATE_ESTB: - __sync_sub_and_fetch(&stat_conn_active, 1); - __sync_add_and_fetch(&stat_conn_finishing, 1); + l2tp_stat_move(&l2tp_stat.conn_active, &l2tp_stat.conn_finishing); break; case STATE_FIN: break; @@ -2807,10 +2836,10 @@ static int l2tp_recv_SCCRQ(const struct l2tp_serv_t *serv, return 0; } - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) return 0; - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) return 0; if (triton_module_loaded("connlimit") @@ -3353,10 +3382,10 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, return 0; } - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) return 0; - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) return 0; if (triton_module_loaded("connlimit") @@ -3693,10 +3722,10 @@ static int l2tp_recv_OCRQ(struct l2tp_conn_t *conn, return 0; } - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) return 0; - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) return 0; if (triton_module_loaded("connlimit") @@ -4713,21 +4742,25 @@ err_fd: static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) { + struct l2tp_stat_t stat; + + l2tp_stat_get(&stat); + cli_send(client, "l2tp:\r\n"); cli_send(client, " tunnels:\r\n"); - cli_sendv(client, " starting: %u\r\n", stat_conn_starting); - cli_sendv(client, " active: %u\r\n", stat_conn_active); - cli_sendv(client, " finishing: %u\r\n", stat_conn_finishing); + cli_sendv(client, " starting: %u\r\n", stat.conn_starting); + cli_sendv(client, " active: %u\r\n", stat.conn_active); + cli_sendv(client, " finishing: %u\r\n", stat.conn_finishing); cli_send(client, " sessions (control channels):\r\n"); - cli_sendv(client, " starting: %u\r\n", stat_sess_starting); - cli_sendv(client, " active: %u\r\n", stat_sess_active); - cli_sendv(client, " finishing: %u\r\n", stat_sess_finishing); + cli_sendv(client, " starting: %u\r\n", stat.sess_starting); + cli_sendv(client, " active: %u\r\n", stat.sess_active); + cli_sendv(client, " finishing: %u\r\n", stat.sess_finishing); cli_send(client, " sessions (data channels):\r\n"); - cli_sendv(client, " starting: %u\r\n", stat_starting); - cli_sendv(client, " active: %u\r\n", stat_active); - cli_sendv(client, " finishing: %u\r\n", stat_finishing); + cli_sendv(client, " starting: %u\r\n", stat.data_starting); + cli_sendv(client, " active: %u\r\n", stat.data_active); + cli_sendv(client, " finishing: %u\r\n", stat.data_finishing); return CLI_CMD_OK; } @@ -4933,12 +4966,6 @@ static void l2tp_create_session_help(char * const *fields, int fields_cnt, " - place new call in tunnel <tid>\r\n"); } -void __export l2tp_get_stat(unsigned int **starting, unsigned int **active) -{ - *starting = &stat_starting; - *active = &stat_active; -} - static void load_config(void) { const char *opt; diff --git a/accel-pppd/ctrl/l2tp/l2tp.h b/accel-pppd/ctrl/l2tp/l2tp.h index 76de867f..2f113a25 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.h +++ b/accel-pppd/ctrl/l2tp/l2tp.h @@ -77,6 +77,9 @@ struct l2tp_packet_t extern int conf_verbose; extern int conf_avp_permissive; +unsigned int l2tp_stat_starting(void); +unsigned int l2tp_stat_active(void); + static inline int l2tp_packet_is_ZLB(const struct l2tp_packet_t *pack) { return list_empty(&pack->attrs); diff --git a/accel-pppd/ctrl/pppoe/cli.c b/accel-pppd/ctrl/pppoe/cli.c index d8399543..453c0cf3 100644 --- a/accel-pppd/ctrl/pppoe/cli.c +++ b/accel-pppd/ctrl/pppoe/cli.c @@ -88,16 +88,20 @@ help: static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) { + struct pppoe_stat_t stat; + + pppoe_stat_get(&stat); + cli_send(client, "pppoe:\r\n"); - cli_sendv(client, " starting: %u\r\n", stat_starting); - cli_sendv(client, " active: %u\r\n", stat_active); - cli_sendv(client, " delayed PADO: %u\r\n", stat_delayed_pado); - cli_sendv(client, " recv PADI: %lu\r\n", stat_PADI_recv); - cli_sendv(client, " drop PADI: %lu\r\n", stat_PADI_drop); - cli_sendv(client, " sent PADO: %lu\r\n", stat_PADO_sent); - cli_sendv(client, " recv PADR(dup): %lu(%lu)\r\n", stat_PADR_recv, stat_PADR_dup_recv); - cli_sendv(client, " sent PADS: %lu\r\n", stat_PADS_sent); - cli_sendv(client, " filtered: %lu\r\n", stat_filtered); + cli_sendv(client, " starting: %u\r\n", stat.starting); + cli_sendv(client, " active: %u\r\n", stat.active); + cli_sendv(client, " delayed PADO: %u\r\n", stat.delayed_PADO); + cli_sendv(client, " recv PADI: %lu\r\n", stat.PADI_recv); + cli_sendv(client, " drop PADI: %lu\r\n", stat.PADI_drop); + cli_sendv(client, " sent PADO: %lu\r\n", stat.PADO_sent); + cli_sendv(client, " recv PADR(dup): %lu(%lu)\r\n", stat.PADR_recv, stat.PADR_dup_recv); + cli_sendv(client, " sent PADS: %lu\r\n", stat.PADS_sent); + cli_sendv(client, " filtered: %lu\r\n", stat.filtered); return CLI_CMD_OK; } diff --git a/accel-pppd/ctrl/pppoe/disc.c b/accel-pppd/ctrl/pppoe/disc.c index 8a82e1d2..e673a97a 100644 --- a/accel-pppd/ctrl/pppoe/disc.c +++ b/accel-pppd/ctrl/pppoe/disc.c @@ -329,7 +329,7 @@ static int disc_read(struct triton_md_handler_t *h) } if (mac_filter_check(ethhdr->h_source)) { - __sync_add_and_fetch(&stat_filtered, 1); + pppoe_stat_add_filtered(); continue; } diff --git a/accel-pppd/ctrl/pppoe/dpado.c b/accel-pppd/ctrl/pppoe/dpado.c index 71faa130..351a43dc 100644 --- a/accel-pppd/ctrl/pppoe/dpado.c +++ b/accel-pppd/ctrl/pppoe/dpado.c @@ -77,6 +77,7 @@ int dpado_parse(const char *str) { char *str1 = _strdup(str); char *ptr1, *ptr2, *ptr3, *endptr; + unsigned int active = pppoe_stat_active(); LIST_HEAD(range_list); struct dpado_range_t *r; @@ -131,7 +132,7 @@ int dpado_parse(const char *str) dpado_range_prev = NULL; list_for_each_entry(r, &dpado_range_list, entry) { - if (!dpado_range_prev || stat_active >= r->conn_cnt) { + if (!dpado_range_prev || active >= r->conn_cnt) { dpado_range_prev = r; if (r->entry.next != &dpado_range_list) dpado_range_next = list_entry(r->entry.next, typeof(*r), entry); diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c index 6ec07c9d..93824af5 100644 --- a/accel-pppd/ctrl/pppoe/pppoe.c +++ b/accel-pppd/ctrl/pppoe/pppoe.c @@ -43,6 +43,7 @@ struct pppoe_conn_t { struct pppoe_serv_t *serv; uint16_t sid; uint8_t addr[ETH_ALEN]; + unsigned int ppp_starting:1; unsigned int ppp_started:1; struct pppoe_tag *relay_sid; @@ -109,17 +110,8 @@ static mempool_t conn_pool; static mempool_t pado_pool; static mempool_t padi_pool; -unsigned int stat_starting; -unsigned int stat_active; -unsigned int stat_delayed_pado; -unsigned long stat_PADI_recv; -unsigned long stat_PADI_drop; -unsigned long stat_PADO_sent; -unsigned long stat_PADR_recv; -unsigned long stat_PADR_dup_recv; -unsigned long stat_PADS_sent; +static struct pppoe_stat_t pppoe_stat; unsigned int total_padi_cnt; -unsigned long stat_filtered; pthread_rwlock_t serv_lock = PTHREAD_RWLOCK_INITIALIZER; LIST_HEAD(serv_list); @@ -131,6 +123,35 @@ static unsigned long *sid_map; static unsigned long *sid_ptr; static int sid_idx; +void __export pppoe_stat_get(struct pppoe_stat_t *stat) +{ + stat->starting = __atomic_load_n(&pppoe_stat.starting, __ATOMIC_RELAXED); + stat->active = __atomic_load_n(&pppoe_stat.active, __ATOMIC_RELAXED); + stat->delayed_PADO = __atomic_load_n(&pppoe_stat.delayed_PADO, __ATOMIC_RELAXED); + stat->PADI_recv = __atomic_load_n(&pppoe_stat.PADI_recv, __ATOMIC_RELAXED); + stat->PADI_drop = __atomic_load_n(&pppoe_stat.PADI_drop, __ATOMIC_RELAXED); + stat->PADO_sent = __atomic_load_n(&pppoe_stat.PADO_sent, __ATOMIC_RELAXED); + stat->PADR_recv = __atomic_load_n(&pppoe_stat.PADR_recv, __ATOMIC_RELAXED); + stat->PADR_dup_recv = __atomic_load_n(&pppoe_stat.PADR_dup_recv, __ATOMIC_RELAXED); + stat->PADS_sent = __atomic_load_n(&pppoe_stat.PADS_sent, __ATOMIC_RELAXED); + stat->filtered = __atomic_load_n(&pppoe_stat.filtered, __ATOMIC_RELAXED); +} + +unsigned int __export pppoe_stat_starting(void) +{ + return __atomic_load_n(&pppoe_stat.starting, __ATOMIC_RELAXED); +} + +unsigned int __export pppoe_stat_active(void) +{ + return __atomic_load_n(&pppoe_stat.active, __ATOMIC_RELAXED); +} + +void __export pppoe_stat_add_filtered(void) +{ + __atomic_add_fetch(&pppoe_stat.filtered, 1, __ATOMIC_RELAXED); +} + static uint8_t bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; static void pppoe_send_PADT(struct pppoe_conn_t *conn); @@ -168,9 +189,12 @@ static void disconnect(struct pppoe_conn_t *conn) struct pppoe_serv_t *serv = conn->serv; if (conn->ppp_started) { - dpado_check_prev(__sync_fetch_and_sub(&stat_active, 1)); + dpado_check_prev(__atomic_fetch_sub(&pppoe_stat.active, 1, __ATOMIC_RELAXED)); conn->ppp_started = 0; ap_session_terminate(&conn->ppp.ses, TERM_USER_REQUEST, 1); + } else if (conn->ppp_starting) { + __atomic_sub_fetch(&pppoe_stat.starting, 1, __ATOMIC_RELAXED); + conn->ppp_starting = 0; } pppoe_send_PADT(conn); @@ -227,7 +251,7 @@ static void ppp_finished(struct ap_session *ses) log_ppp_debug("pppoe: ppp finished\n"); if (conn->ppp_started) { - dpado_check_prev(__sync_fetch_and_sub(&stat_active, 1)); + dpado_check_prev(__atomic_fetch_sub(&pppoe_stat.active, 1, __ATOMIC_RELAXED)); conn->ppp_started = 0; triton_context_call(&conn->ctx, (triton_event_func)disconnect, conn); } @@ -445,6 +469,9 @@ static void connect_channel(struct pppoe_conn_t *conn) struct sockaddr_pppox sp; triton_event_fire(EV_CTRL_STARTING, &conn->ppp.ses); + conn->ppp_starting = 1; + __atomic_add_fetch(&pppoe_stat.starting, 1, __ATOMIC_RELAXED); + triton_event_fire(EV_CTRL_STARTED, &conn->ppp.ses); sock = net->socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE); @@ -481,9 +508,11 @@ static void connect_channel(struct pppoe_conn_t *conn) } #endif + conn->ppp_starting = 0; conn->ppp_started = 1; - dpado_check_next(__sync_add_and_fetch(&stat_active, 1)); + __atomic_sub_fetch(&pppoe_stat.starting, 1, __ATOMIC_RELAXED); + dpado_check_next(__atomic_add_fetch(&pppoe_stat.active, 1, __ATOMIC_RELAXED)); return; @@ -817,7 +846,7 @@ static void pppoe_send_PADO(struct pppoe_serv_t *serv, const uint8_t *addr, cons if (conf_verbose) print_packet(serv->ifname, "send", pack); - __sync_add_and_fetch(&stat_PADO_sent, 1); + __atomic_add_fetch(&pppoe_stat.PADO_sent, 1, __ATOMIC_RELAXED); pppoe_send(serv, pack); } @@ -866,7 +895,7 @@ static void pppoe_send_PADS(struct pppoe_conn_t *conn) if (conf_verbose) print_packet(conn->serv->ifname, "send", pack); - __sync_add_and_fetch(&stat_PADS_sent, 1); + __atomic_add_fetch(&pppoe_stat.PADS_sent, 1, __ATOMIC_RELAXED); pppoe_send(conn->serv, pack); } @@ -893,7 +922,7 @@ static void free_delayed_pado(struct delayed_pado_t *pado) { triton_timer_del(&pado->timer); - __sync_sub_and_fetch(&stat_delayed_pado, 1); + __atomic_sub_fetch(&pppoe_stat.delayed_PADO, 1, __ATOMIC_RELAXED); list_del(&pado->entry); if (pado->host_uniq) @@ -979,19 +1008,19 @@ static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size) struct timespec ts; uint16_t ppp_max_payload = 0; - __sync_add_and_fetch(&stat_PADI_recv, 1); + __atomic_add_fetch(&pppoe_stat.PADI_recv, 1, __ATOMIC_RELAXED); if (ap_shutdown || pado_delay == -1) return; - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) return; - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) return; if (check_padi_limit(serv, ethhdr->h_source)) { - __sync_add_and_fetch(&stat_PADI_drop, 1); + __atomic_add_fetch(&pppoe_stat.PADI_drop, 1, __ATOMIC_RELAXED); if (conf_verbose) { clock_gettime(CLOCK_MONOTONIC, &ts); if (ts.tv_sec - 60 >= serv->last_padi_limit_warn) { @@ -1094,7 +1123,7 @@ tags_done: triton_timer_add(&serv->ctx, &pado->timer, 0); list_add_tail(&pado->entry, &serv->pado_list); - __sync_add_and_fetch(&stat_delayed_pado, 1); + __atomic_add_fetch(&pppoe_stat.delayed_PADO, 1, __ATOMIC_RELAXED); } else pppoe_send_PADO(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag, ppp_max_payload); } @@ -1114,15 +1143,15 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size) int vendor_id; uint16_t ppp_max_payload = 0; - __sync_add_and_fetch(&stat_PADR_recv, 1); + __atomic_add_fetch(&pppoe_stat.PADR_recv, 1, __ATOMIC_RELAXED); if (ap_shutdown) return; - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) return; - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) return; if (!memcmp(ethhdr->h_dest, bc_addr, ETH_ALEN)) { @@ -1227,7 +1256,7 @@ padr_tags_done: pthread_mutex_lock(&serv->lock); conn = find_channel(serv, (uint8_t *)ac_cookie_tag->tag_data); if (conn && !conn->ppp.ses.username) { - __sync_add_and_fetch(&stat_PADR_dup_recv, 1); + __atomic_add_fetch(&pppoe_stat.PADR_dup_recv, 1, __ATOMIC_RELAXED); pppoe_send_PADS(conn); } pthread_mutex_unlock(&serv->lock); @@ -1643,12 +1672,6 @@ void pppoe_server_stop(const char *ifname) pthread_rwlock_unlock(&serv_lock); } -void __export pppoe_get_stat(unsigned int **starting, unsigned int **active) -{ - *starting = &stat_starting; - *active = &stat_active; -} - static int init_secret(struct pppoe_serv_t *serv) { DES_cblock key; diff --git a/accel-pppd/ctrl/pppoe/pppoe.h b/accel-pppd/ctrl/pppoe/pppoe.h index 2510c320..42067590 100644 --- a/accel-pppd/ctrl/pppoe/pppoe.h +++ b/accel-pppd/ctrl/pppoe/pppoe.h @@ -109,16 +109,24 @@ extern int conf_accept_any_service; extern char *conf_ac_name; extern char *conf_pado_delay; -extern unsigned int stat_starting; -extern unsigned int stat_active; -extern unsigned int stat_delayed_pado; -extern unsigned long stat_PADI_recv; -extern unsigned long stat_PADO_sent; -extern unsigned long stat_PADR_recv; -extern unsigned long stat_PADR_dup_recv; -extern unsigned long stat_PADS_sent; -extern unsigned long stat_PADI_drop; -extern unsigned long stat_filtered; +struct pppoe_stat_t +{ + unsigned int starting; + unsigned int active; + unsigned int delayed_PADO; + unsigned long PADI_recv; + unsigned long PADI_drop; + unsigned long PADO_sent; + unsigned long PADR_recv; + unsigned long PADR_dup_recv; + unsigned long PADS_sent; + unsigned long filtered; +}; + +void pppoe_stat_get(struct pppoe_stat_t *stat); +unsigned int pppoe_stat_starting(void); +unsigned int pppoe_stat_active(void); +void pppoe_stat_add_filtered(void); extern pthread_rwlock_t serv_lock; extern struct list_head serv_list; @@ -142,4 +150,3 @@ int tr101_send_access_request(struct pppoe_tag *tr101, struct rad_packet_t *pack int tr101_send_accounting_request(struct pppoe_tag *tr101, struct rad_packet_t *pack); #endif - diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c index 24984db8..f8e498d6 100644 --- a/accel-pppd/ctrl/pptp/pptp.c +++ b/accel-pppd/ctrl/pptp/pptp.c @@ -25,6 +25,7 @@ #include "cli.h" #include "connlimit.h" +#include "pptp.h" #include "memdebug.h" @@ -55,6 +56,19 @@ struct pptp_conn_t struct ppp_t ppp; }; +struct pptp_stat_t +{ + unsigned int starting; + unsigned int active; +}; + +struct pptp_serv_t +{ + struct triton_context_t ctx; + struct triton_md_handler_t hnd; + struct pptp_stat_t stat; +}; + static int conf_ppp_max_mtu = PPTP_MAX_MTU; static int conf_timeout = 5; static int conf_echo_interval = 0; @@ -69,14 +83,53 @@ static const char *conf_ifname; static mempool_t conn_pool; -static unsigned int stat_starting; -static unsigned int stat_active; - static int pptp_read(struct triton_md_handler_t *h); static int pptp_write(struct triton_md_handler_t *h); static void pptp_timeout(struct triton_timer_t *); static void ppp_started(struct ap_session *); static void ppp_finished(struct ap_session *); +static void pptp_ctx_switch(struct triton_context_t *ctx, void *arg); +static int pptp_connect(struct triton_md_handler_t *h); +static void pptp_serv_close(struct triton_context_t *ctx); + +static struct pptp_serv_t serv = +{ + .hnd.read = pptp_connect, + .ctx.close = pptp_serv_close, + .ctx.before_switch = pptp_ctx_switch, +}; + +static void pptp_stat_inc(unsigned int *stat) +{ + __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void pptp_stat_dec(unsigned int *stat) +{ + __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void pptp_stat_move(unsigned int *from, unsigned int *to) +{ + pptp_stat_dec(from); + pptp_stat_inc(to); +} + +static void pptp_stat_get(struct pptp_stat_t *stat) +{ + stat->starting = __atomic_load_n(&serv.stat.starting, __ATOMIC_RELAXED); + stat->active = __atomic_load_n(&serv.stat.active, __ATOMIC_RELAXED); +} + +unsigned int __export pptp_stat_starting(void) +{ + return __atomic_load_n(&serv.stat.starting, __ATOMIC_RELAXED); +} + +unsigned int __export pptp_stat_active(void) +{ + return __atomic_load_n(&serv.stat.active, __ATOMIC_RELAXED); +} static void pptp_ctx_switch(struct triton_context_t *ctx, void *arg) { @@ -101,11 +154,11 @@ static void disconnect(struct pptp_conn_t *conn) triton_timer_del(&conn->echo_timer); if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); + pptp_stat_dec(&serv.stat.active); conn->state = STATE_CLOSE; ap_session_terminate(&conn->ppp.ses, TERM_LOST_CARRIER, 1); } else if (conn->state != STATE_CLOSE) - __sync_sub_and_fetch(&stat_starting, 1); + pptp_stat_dec(&serv.stat.starting); triton_event_fire(EV_CTRL_FINISHED, &conn->ppp.ses); @@ -356,8 +409,7 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) return -1; } conn->state = STATE_PPP; - __sync_sub_and_fetch(&stat_starting, 1); - __sync_add_and_fetch(&stat_active, 1); + pptp_stat_move(&serv.stat.starting, &serv.stat.active); if (conn->timeout_timer.tpd) triton_timer_del(&conn->timeout_timer); @@ -397,7 +449,7 @@ static int pptp_call_clear_rqst(struct pptp_conn_t *conn) triton_timer_del(&conn->echo_timer); if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); + pptp_stat_dec(&serv.stat.active); conn->state = STATE_CLOSE; ap_session_terminate(&conn->ppp.ses, TERM_USER_REQUEST, 1); } @@ -578,7 +630,7 @@ static void pptp_close(struct triton_context_t *ctx) { struct pptp_conn_t *conn = container_of(ctx, typeof(*conn), ctx); if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); + pptp_stat_dec(&serv.stat.active); conn->state = STATE_CLOSE; ap_session_terminate(&conn->ppp.ses, TERM_ADMIN_RESET, 1); if (send_pptp_call_disconnect_notify(conn, 3)) { @@ -609,7 +661,7 @@ static void ppp_finished(struct ap_session *ses) if (conn->state != STATE_CLOSE) { log_ppp_debug("pptp: ppp finished\n"); conn->state = STATE_CLOSE; - __sync_sub_and_fetch(&stat_active, 1); + pptp_stat_dec(&serv.stat.active); if (send_pptp_call_disconnect_notify(conn, 3)) triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); @@ -626,12 +678,6 @@ static void ppp_finished(struct ap_session *ses) //================================== -struct pptp_serv_t -{ - struct triton_context_t ctx; - struct triton_md_handler_t hnd; -}; - static int pptp_connect(struct triton_md_handler_t *h) { struct sockaddr_in addr; @@ -653,12 +699,12 @@ static int pptp_connect(struct triton_md_handler_t *h) continue; } - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) { + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) { close(sock); continue; } - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) { + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) { close(sock); continue; } @@ -733,7 +779,7 @@ static int pptp_connect(struct triton_md_handler_t *h) triton_event_fire(EV_CTRL_STARTING, &conn->ppp.ses); - __sync_add_and_fetch(&stat_starting, 1); + pptp_stat_inc(&serv.stat.starting); } return 0; } @@ -744,28 +790,19 @@ static void pptp_serv_close(struct triton_context_t *ctx) triton_context_unregister(ctx); } -static struct pptp_serv_t serv= -{ - .hnd.read = pptp_connect, - .ctx.close = pptp_serv_close, - .ctx.before_switch = pptp_ctx_switch, -}; - static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) { + struct pptp_stat_t stat; + + pptp_stat_get(&stat); + cli_send(client, "pptp:\r\n"); - cli_sendv(client," starting: %u\r\n", stat_starting); - cli_sendv(client," active: %u\r\n", stat_active); + cli_sendv(client," starting: %u\r\n", stat.starting); + cli_sendv(client," active: %u\r\n", stat.active); return CLI_CMD_OK; } -void __export pptp_get_stat(unsigned int **starting, unsigned int **active) -{ - *starting = &stat_starting; - *active = &stat_active; -} - static void load_config(void) { char *opt; diff --git a/accel-pppd/ctrl/pptp/pptp.h b/accel-pppd/ctrl/pptp/pptp.h new file mode 100644 index 00000000..29f24ca2 --- /dev/null +++ b/accel-pppd/ctrl/pptp/pptp.h @@ -0,0 +1,7 @@ +#ifndef __PPTP_H +#define __PPTP_H + +unsigned int pptp_stat_starting(void); +unsigned int pptp_stat_active(void); + +#endif diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c index 4dab0c8e..21c519fa 100644 --- a/accel-pppd/ctrl/sstp/sstp.c +++ b/accel-pppd/ctrl/sstp/sstp.c @@ -41,6 +41,7 @@ #include "memdebug.h" #include "proxy_prot.h" +#include "sstp.h" #include "sstp_prot.h" #ifndef min @@ -148,14 +149,17 @@ struct sstp_conn_t { struct ap_ctrl ctrl; }; -static struct sstp_serv_t { +struct sstp_serv_t { struct triton_context_t ctx; struct triton_md_handler_t hnd; struct sockaddr_t addr; SSL_CTX *ssl_ctx; -} serv; + struct sstp_stat_t stat; +}; + +static struct sstp_serv_t serv; static int conf_timeout = SSTP_NEGOTIOATION_TIMEOUT; static int conf_hello_interval = SSTP_HELLO_TIMEOUT; @@ -186,9 +190,6 @@ static const char *conf_http_url = NULL; static mempool_t conn_pool; -static unsigned int stat_starting; -static unsigned int stat_active; - static inline void sstp_queue(struct sstp_conn_t *conn, struct buffer_t *buf); static int sstp_send(struct sstp_conn_t *conn, struct buffer_t *buf); static inline void sstp_queue_deferred(struct sstp_conn_t *conn, struct buffer_t *buf); @@ -199,6 +200,38 @@ static void sstp_disconnect(struct sstp_conn_t *conn); static int sstp_handler(struct sstp_conn_t *conn, struct buffer_t *buf); static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf); +void __export sstp_stat_get(struct sstp_stat_t *stat) +{ + stat->starting = __atomic_load_n(&serv.stat.starting, __ATOMIC_RELAXED); + stat->active = __atomic_load_n(&serv.stat.active, __ATOMIC_RELAXED); +} + +unsigned int __export sstp_stat_starting(void) +{ + return __atomic_load_n(&serv.stat.starting, __ATOMIC_RELAXED); +} + +unsigned int __export sstp_stat_active(void) +{ + return __atomic_load_n(&serv.stat.active, __ATOMIC_RELAXED); +} + +static void sstp_stat_inc(unsigned int *stat) +{ + __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void sstp_stat_dec(unsigned int *stat) +{ + __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void sstp_stat_move(unsigned int *from, unsigned int *to) +{ + sstp_stat_dec(from); + sstp_stat_inc(to); +} + /* * FCS lookup table as calculated by genfcstab. */ @@ -1507,8 +1540,7 @@ static int sstp_recv_msg_call_connect_request(struct sstp_conn_t *conn, struct s goto error; conn->sstp_state = STATE_SERVER_CALL_CONNECTED_PENDING; - __sync_sub_and_fetch(&stat_starting, 1); - __sync_add_and_fetch(&stat_active, 1); + sstp_stat_move(&serv.stat.starting, &serv.stat.active); triton_event_fire(EV_CTRL_STARTED, &conn->ppp.ses); conn->ppp_state = STATE_STARTING; @@ -2209,17 +2241,17 @@ static void sstp_disconnect(struct sstp_conn_t *conn) switch (conn->ppp_state) { case STATE_INIT: - __sync_sub_and_fetch(&stat_starting, 1); + sstp_stat_dec(&serv.stat.starting); break; case STATE_STARTING: case STATE_AUTHORIZED: case STATE_STARTED: conn->ppp_state = STATE_FINISHED; - __sync_sub_and_fetch(&stat_active, 1); + sstp_stat_dec(&serv.stat.active); ap_session_terminate(&conn->ppp.ses, TERM_LOST_CARRIER, 1); break; case STATE_FINISHED: - __sync_sub_and_fetch(&stat_active, 1); + sstp_stat_dec(&serv.stat.active); break; } triton_event_fire(EV_CTRL_FINISHED, &conn->ppp.ses); @@ -2298,12 +2330,12 @@ static int sstp_connect(struct triton_md_handler_t *h) continue; } - if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) { + if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) { close(sock); continue; } - if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) { + if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) { close(sock); continue; } @@ -2424,7 +2456,7 @@ static int sstp_connect(struct triton_md_handler_t *h) triton_event_fire(EV_CTRL_STARTING, &conn->ppp.ses); - __sync_add_and_fetch(&stat_starting, 1); + sstp_stat_inc(&serv.stat.starting); } return 0; @@ -2766,19 +2798,17 @@ static void ev_ses_authorized(struct ap_session *ses) static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) { + struct sstp_stat_t stat; + + sstp_stat_get(&stat); + cli_send(client, "sstp:\r\n"); - cli_sendv(client," starting: %u\r\n", stat_starting); - cli_sendv(client," active: %u\r\n", stat_active); + cli_sendv(client," starting: %u\r\n", stat.starting); + cli_sendv(client," active: %u\r\n", stat.active); return CLI_CMD_OK; } -void __export sstp_get_stat(unsigned int **starting, unsigned int **active) -{ - *starting = &stat_starting; - *active = &stat_active; -} - static void load_config(void) { int ipmode; diff --git a/accel-pppd/ctrl/sstp/sstp.h b/accel-pppd/ctrl/sstp/sstp.h new file mode 100644 index 00000000..eff8e053 --- /dev/null +++ b/accel-pppd/ctrl/sstp/sstp.h @@ -0,0 +1,14 @@ +#ifndef __SSTP_H +#define __SSTP_H + +struct sstp_stat_t +{ + unsigned int starting; + unsigned int active; +}; + +void sstp_stat_get(struct sstp_stat_t *stat); +unsigned int sstp_stat_starting(void); +unsigned int sstp_stat_active(void); + +#endif diff --git a/accel-pppd/extra/net-snmp/statCore.c b/accel-pppd/extra/net-snmp/statCore.c index c2e64689..7e9047da 100644 --- a/accel-pppd/extra/net-snmp/statCore.c +++ b/accel-pppd/extra/net-snmp/statCore.c @@ -49,7 +49,7 @@ handle_statCoreUpTime(netsnmp_mib_handler *handler, struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - ts.tv_sec -= triton_stat.start_time; + ts.tv_sec -= triton_stat_start_time(); /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ @@ -80,6 +80,8 @@ handle_statCoreCPU(netsnmp_mib_handler *handler, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { + long cpu; + /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ @@ -89,9 +91,10 @@ handle_statCoreCPU(netsnmp_mib_handler *handler, switch(reqinfo->mode) { case MODE_GET: + cpu = triton_stat_cpu(); snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, - (u_char *)&triton_stat.cpu /* XXX: a pointer to the scalar's data */, - sizeof(triton_stat.cpu)/* XXX: the length of the data in bytes */); + (u_char *)&cpu /* XXX: a pointer to the scalar's data */, + sizeof(cpu)/* XXX: the length of the data in bytes */); break; diff --git a/accel-pppd/extra/net-snmp/statIPOE.c b/accel-pppd/extra/net-snmp/statIPOE.c index 24f154fd..33430fe6 100644 --- a/accel-pppd/extra/net-snmp/statIPOE.c +++ b/accel-pppd/extra/net-snmp/statIPOE.c @@ -8,18 +8,17 @@ #include <net-snmp/agent/net-snmp-agent-includes.h> #include "triton.h" +#include "accel-pppd/ctrl/ipoe/ipoe.h" #include "statIPOE.h" -/* - * The variables we want to tie the relevant OIDs to. - * The agent will handle all GET and (if applicable) SET requests - * to these variables automatically, changing the values as needed. - */ - -void ipoe_get_stat(unsigned int **, unsigned int **); - -static unsigned int *stat_starting; -static unsigned int *stat_active; +static int handle_statIPOEStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); +static int handle_statIPOEActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); /* * Our initialization routine, called automatically by the agent @@ -28,9 +27,6 @@ static unsigned int *stat_active; void init_statIPOE(void) { - netsnmp_handler_registration *reg; - netsnmp_watcher_info *winfo; - static oid statIPOEStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,6,1 }; static oid statIPOEActive_oid[] = { 1,3,6,1,4,1,8072,100,1,6,2 }; @@ -43,51 +39,75 @@ init_statIPOE(void) if (!triton_module_loaded("ipoe")) return; - ipoe_get_stat(&stat_starting, &stat_active); - - /* - * Register scalar watchers for each of the MIB objects. - * The ASN type and RO/RW status are taken from the MIB definition, - * but can be adjusted if needed. - * - * In most circumstances, the scalar watcher will handle all - * of the necessary processing. But the NULL parameter in the - * netsnmp_create_handler_registration() call can be used to - * supply a user-provided handler if necessary. - * - * This approach can also be used to handle Counter64, string- - * and OID-based watched scalars (although variable-sized writeable - * objects will need some more specialised initialisation). - */ DEBUGMSGTL(("statIPOE", "Initializing statIPOEStarting scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statIPOEStarting", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statIPOEStarting", handle_statIPOEStarting, statIPOEStarting_oid, OID_LENGTH(statIPOEStarting_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_starting, sizeof(*stat_starting), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statIPOEStarting" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statIPOEStarting" ); } DEBUGMSGTL(("statIPOE", "Initializing statIPOEActive scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statIPOEActive", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statIPOEActive", handle_statIPOEActive, statIPOEActive_oid, OID_LENGTH(statIPOEActive_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_active, sizeof(*stat_active), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statIPOEActive" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statIPOEActive" ); } DEBUGMSGTL(("statIPOE", "Done initalizing statIPOE module\n")); } + +static int handle_statIPOEStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = ipoe_stat_starting(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statIPOEStarting\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + +static int handle_statIPOEActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = ipoe_stat_active(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statIPOEActive\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} diff --git a/accel-pppd/extra/net-snmp/statL2TP.c b/accel-pppd/extra/net-snmp/statL2TP.c index 59998386..36e6f90b 100644 --- a/accel-pppd/extra/net-snmp/statL2TP.c +++ b/accel-pppd/extra/net-snmp/statL2TP.c @@ -8,19 +8,18 @@ #include <net-snmp/agent/net-snmp-agent-includes.h> #include "triton.h" +#include "accel-pppd/ctrl/l2tp/l2tp.h" #include "statL2TP.h" -/* - * The variables we want to tie the relevant OIDs to. - * The agent will handle all GET and (if applicable) SET requests - * to these variables automatically, changing the values as needed. - */ - -void l2tp_get_stat(unsigned int **, unsigned int **); - -static unsigned int *stat_starting; -static unsigned int *stat_active; +static int handle_statL2TPStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); +static int handle_statL2TPActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); /* * Our initialization routine, called automatically by the agent @@ -29,9 +28,6 @@ static unsigned int *stat_active; void init_statL2TP(void) { - netsnmp_handler_registration *reg; - netsnmp_watcher_info *winfo; - static oid statL2TPStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,4,1 }; static oid statL2TPActive_oid[] = { 1,3,6,1,4,1,8072,100,1,4,2 }; @@ -44,51 +40,75 @@ init_statL2TP(void) if (!triton_module_loaded("l2tp")) return; - l2tp_get_stat(&stat_starting, &stat_active); - - /* - * Register scalar watchers for each of the MIB objects. - * The ASN type and RO/RW status are taken from the MIB definition, - * but can be adjusted if needed. - * - * In most circumstances, the scalar watcher will handle all - * of the necessary processing. But the NULL parameter in the - * netsnmp_create_handler_registration() call can be used to - * supply a user-provided handler if necessary. - * - * This approach can also be used to handle Counter64, string- - * and OID-based watched scalars (although variable-sized writeable - * objects will need some more specialised initialisation). - */ DEBUGMSGTL(("statL2TP", "Initializing statL2TPStarting scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statL2TPStarting", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statL2TPStarting", handle_statL2TPStarting, statL2TPStarting_oid, OID_LENGTH(statL2TPStarting_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_starting, sizeof(*stat_starting), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statL2TPStarting" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statL2TPStarting" ); } DEBUGMSGTL(("statL2TP", "Initializing statL2TPActive scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statL2TPActive", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statL2TPActive", handle_statL2TPActive, statL2TPActive_oid, OID_LENGTH(statL2TPActive_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_active, sizeof(*stat_active), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statL2TPActive" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statL2TPActive" ); } DEBUGMSGTL(("statL2TP", "Done initalizing statL2TP module\n")); } + +static int handle_statL2TPStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = l2tp_stat_starting(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statL2TPStarting\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + +static int handle_statL2TPActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = l2tp_stat_active(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statL2TPActive\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} diff --git a/accel-pppd/extra/net-snmp/statPPP.c b/accel-pppd/extra/net-snmp/statPPP.c index 37e4630c..7dc1f659 100644 --- a/accel-pppd/extra/net-snmp/statPPP.c +++ b/accel-pppd/extra/net-snmp/statPPP.c @@ -6,9 +6,22 @@ #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h> #include <net-snmp/agent/net-snmp-agent-includes.h> + +#include "ap_session.h" #include "statPPP.h" -#include "ppp.h" +static int handle_statPPPStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); +static int handle_statPPPActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); +static int handle_statPPPFinishing(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); /* * Our initialization routine, called automatically by the agent @@ -17,77 +30,115 @@ void init_statPPP(void) { - netsnmp_handler_registration *reg; - netsnmp_watcher_info *winfo; - static oid statPPPStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,2,1 }; static oid statPPPActive_oid[] = { 1,3,6,1,4,1,8072,100,1,2,2 }; static oid statPPPFinishing_oid[] = { 1,3,6,1,4,1,8072,100,1,2,3 }; - /* - * a debugging statement. Run the agent with -DstatPPP to see - * the output of this debugging statement. - */ DEBUGMSGTL(("statPPP", "Initializing the statPPP module\n")); - - /* - * Register scalar watchers for each of the MIB objects. - * The ASN type and RO/RW status are taken from the MIB definition, - * but can be adjusted if needed. - * - * In most circumstances, the scalar watcher will handle all - * of the necessary processing. But the NULL parameter in the - * netsnmp_create_handler_registration() call can be used to - * supply a user-provided handler if necessary. - * - * This approach can also be used to handle Counter64, string- - * and OID-based watched scalars (although variable-sized writeable - * objects will need some more specialised initialisation). - */ DEBUGMSGTL(("statPPP", "Initializing statPPPStarting scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statPPPStarting", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statPPPStarting", handle_statPPPStarting, statPPPStarting_oid, OID_LENGTH(statPPPStarting_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - &ap_session_stat.starting, sizeof(ap_session_stat.starting), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statPPPStarting" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statPPPStarting" ); } DEBUGMSGTL(("statPPP", "Initializing statPPPActive scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statPPPActive", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statPPPActive", handle_statPPPActive, statPPPActive_oid, OID_LENGTH(statPPPActive_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - &ap_session_stat.active, sizeof(ap_session_stat.active), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statPPPActive" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statPPPActive" ); } DEBUGMSGTL(("statPPP", "Initializing statPPPFinishing scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statPPPFinishing", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statPPPFinishing", handle_statPPPFinishing, statPPPFinishing_oid, OID_LENGTH(statPPPFinishing_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - &ap_session_stat.finishing, sizeof(ap_session_stat.finishing), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statPPPFinishing" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statPPPFinishing" ); } DEBUGMSGTL(("statPPP", "Done initalizing statPPP module\n")); } + +static int handle_statPPPStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = ap_session_stat_starting(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statPPPStarting\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + +static int handle_statPPPActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = ap_session_stat_active(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statPPPActive\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + +static int handle_statPPPFinishing(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = ap_session_stat_finishing(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statPPPFinishing\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} diff --git a/accel-pppd/extra/net-snmp/statPPPOE.c b/accel-pppd/extra/net-snmp/statPPPOE.c index 6042dc5b..64e61c3c 100644 --- a/accel-pppd/extra/net-snmp/statPPPOE.c +++ b/accel-pppd/extra/net-snmp/statPPPOE.c @@ -10,16 +10,17 @@ #include "triton.h" #include "statPPPOE.h" -/* - * The variables we want to tie the relevant OIDs to. - * The agent will handle all GET and (if applicable) SET requests - * to these variables automatically, changing the values as needed. - */ +unsigned int pppoe_stat_starting(void); +unsigned int pppoe_stat_active(void); -void pppoe_get_stat(unsigned int **, unsigned int **); - -static unsigned int *stat_starting; -static unsigned int *stat_active; +static int handle_statPPPOEStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); +static int handle_statPPPOEActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); /* * Our initialization routine, called automatically by the agent @@ -28,9 +29,6 @@ static unsigned int *stat_active; void init_statPPPOE(void) { - netsnmp_handler_registration *reg; - netsnmp_watcher_info *winfo; - static oid statPPPOEStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,5,1 }; static oid statPPPOEActive_oid[] = { 1,3,6,1,4,1,8072,100,1,5,2 }; @@ -43,51 +41,69 @@ init_statPPPOE(void) if (!triton_module_loaded("pppoe")) return; - pppoe_get_stat(&stat_starting, &stat_active); - - /* - * Register scalar watchers for each of the MIB objects. - * The ASN type and RO/RW status are taken from the MIB definition, - * but can be adjusted if needed. - * - * In most circumstances, the scalar watcher will handle all - * of the necessary processing. But the NULL parameter in the - * netsnmp_create_handler_registration() call can be used to - * supply a user-provided handler if necessary. - * - * This approach can also be used to handle Counter64, string- - * and OID-based watched scalars (although variable-sized writeable - * objects will need some more specialised initialisation). - */ DEBUGMSGTL(("statPPPOE", "Initializing statPPPOEStarting scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statPPPOEStarting", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statPPPOEStarting", handle_statPPPOEStarting, statPPPOEStarting_oid, OID_LENGTH(statPPPOEStarting_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_starting, sizeof(*stat_starting), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statPPPOEStarting" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statPPPOEStarting" ); } DEBUGMSGTL(("statPPPOE", "Initializing statPPPOEActive scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statPPPOEActive", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statPPPOEActive", handle_statPPPOEActive, statPPPOEActive_oid, OID_LENGTH(statPPPOEActive_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_active, sizeof(*stat_active), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statPPPOEActive" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statPPPOEActive" ); } DEBUGMSGTL(("statPPPOE", - "Done initalizing statPPPOE module\n")); + "Done initalizing statPPPOE module\n")); +} + +static int handle_statPPPOEStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + switch (reqinfo->mode) { + case MODE_GET: + stat = pppoe_stat_starting(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statPPPOEStarting\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + +static int handle_statPPPOEActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + switch (reqinfo->mode) { + case MODE_GET: + stat = pppoe_stat_active(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statPPPOEActive\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; } diff --git a/accel-pppd/extra/net-snmp/statPPTP.c b/accel-pppd/extra/net-snmp/statPPTP.c index 48642202..8a633da3 100644 --- a/accel-pppd/extra/net-snmp/statPPTP.c +++ b/accel-pppd/extra/net-snmp/statPPTP.c @@ -6,20 +6,19 @@ #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h> #include <net-snmp/agent/net-snmp-agent-includes.h> -#include "statPPTP.h" #include "triton.h" +#include "accel-pppd/ctrl/pptp/pptp.h" +#include "statPPTP.h" -/* - * The variables we want to tie the relevant OIDs to. - * The agent will handle all GET and (if applicable) SET requests - * to these variables automatically, changing the values as needed. - */ - -void pptp_get_stat(unsigned int **, unsigned int **); - -static unsigned int *stat_starting; -static unsigned int *stat_active; +static int handle_statPPTPStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); +static int handle_statPPTPActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); /* * Our initialization routine, called automatically by the agent @@ -28,9 +27,6 @@ static unsigned int *stat_active; void init_statPPTP(void) { - netsnmp_handler_registration *reg; - netsnmp_watcher_info *winfo; - static oid statPPTPStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,3,1 }; static oid statPPTPActive_oid[] = { 1,3,6,1,4,1,8072,100,1,3,2 }; @@ -43,50 +39,75 @@ init_statPPTP(void) if (!triton_module_loaded("pptp")) return; - pptp_get_stat(&stat_starting, &stat_active); - /* - * Register scalar watchers for each of the MIB objects. - * The ASN type and RO/RW status are taken from the MIB definition, - * but can be adjusted if needed. - * - * In most circumstances, the scalar watcher will handle all - * of the necessary processing. But the NULL parameter in the - * netsnmp_create_handler_registration() call can be used to - * supply a user-provided handler if necessary. - * - * This approach can also be used to handle Counter64, string- - * and OID-based watched scalars (although variable-sized writeable - * objects will need some more specialised initialisation). - */ DEBUGMSGTL(("statPPTP", "Initializing statPPTPStarting scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statPPTPStarting", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statPPTPStarting", handle_statPPTPStarting, statPPTPStarting_oid, OID_LENGTH(statPPTPStarting_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_starting, sizeof(*stat_starting), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statPPTPStarting" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statPPTPStarting" ); } DEBUGMSGTL(("statPPTP", "Initializing statPPTPActive scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statPPTPActive", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statPPTPActive", handle_statPPTPActive, statPPTPActive_oid, OID_LENGTH(statPPTPActive_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_active, sizeof(*stat_active), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statPPTPActive" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statPPTPActive" ); } DEBUGMSGTL(("statPPTP", "Done initalizing statPPTP module\n")); } + +static int handle_statPPTPStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = pptp_stat_starting(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statPPTPStarting\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + +static int handle_statPPTPActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = pptp_stat_active(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statPPTPActive\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} diff --git a/accel-pppd/extra/net-snmp/statSSTP.c b/accel-pppd/extra/net-snmp/statSSTP.c index 06ba6aa1..62948acd 100644 --- a/accel-pppd/extra/net-snmp/statSSTP.c +++ b/accel-pppd/extra/net-snmp/statSSTP.c @@ -8,18 +8,17 @@ #include <net-snmp/agent/net-snmp-agent-includes.h> #include "triton.h" +#include "accel-pppd/ctrl/sstp/sstp.h" #include "statSSTP.h" -/* - * The variables we want to tie the relevant OIDs to. - * The agent will handle all GET and (if applicable) SET requests - * to these variables automatically, changing the values as needed. - */ - -void sstp_get_stat(unsigned int **, unsigned int **); - -static unsigned int *stat_starting; -static unsigned int *stat_active; +static int handle_statSSTPStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); +static int handle_statSSTPActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests); /* * Our initialization routine, called automatically by the agent @@ -28,9 +27,6 @@ static unsigned int *stat_active; void init_statSSTP(void) { - netsnmp_handler_registration *reg; - netsnmp_watcher_info *winfo; - static oid statSSTPStarting_oid[] = { 1,3,6,1,4,1,8072,100,1,7,1 }; static oid statSSTPActive_oid[] = { 1,3,6,1,4,1,8072,100,1,7,2 }; @@ -43,51 +39,75 @@ init_statSSTP(void) if (!triton_module_loaded("sstp")) return; - sstp_get_stat(&stat_starting, &stat_active); - - /* - * Register scalar watchers for each of the MIB objects. - * The ASN type and RO/RW status are taken from the MIB definition, - * but can be adjusted if needed. - * - * In most circumstances, the scalar watcher will handle all - * of the necessary processing. But the NULL parameter in the - * netsnmp_create_handler_registration() call can be used to - * supply a user-provided handler if necessary. - * - * This approach can also be used to handle Counter64, string- - * and OID-based watched scalars (although variable-sized writeable - * objects will need some more specialised initialisation). - */ DEBUGMSGTL(("statSSTP", "Initializing statSSTPStarting scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statSSTPStarting", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statSSTPStarting", handle_statSSTPStarting, statSSTPStarting_oid, OID_LENGTH(statSSTPStarting_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_starting, sizeof(*stat_starting), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statSSTPStarting" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statSSTPStarting" ); } DEBUGMSGTL(("statSSTP", "Initializing statSSTPActive scalar integer. Default value = %d\n", 0)); - reg = netsnmp_create_handler_registration( - "statSSTPActive", NULL, + if (netsnmp_register_scalar(netsnmp_create_handler_registration( + "statSSTPActive", handle_statSSTPActive, statSSTPActive_oid, OID_LENGTH(statSSTPActive_oid), - HANDLER_CAN_RONLY); - winfo = netsnmp_create_watcher_info( - stat_active, sizeof(*stat_active), - ASN_INTEGER, WATCHER_FIXED_SIZE); - if (netsnmp_register_watched_scalar( reg, winfo ) < 0 ) { - snmp_log( LOG_ERR, "Failed to register watched statSSTPActive" ); + HANDLER_CAN_RONLY)) < 0 ) { + snmp_log( LOG_ERR, "Failed to register statSSTPActive" ); } DEBUGMSGTL(("statSSTP", "Done initalizing statSSTP module\n")); } + +static int handle_statSSTPStarting(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = sstp_stat_starting(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statSSTPStarting\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + +static int handle_statSSTPActive(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + long stat; + + (void)handler; + (void)reginfo; + + switch (reqinfo->mode) { + case MODE_GET: + stat = sstp_stat_active(); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&stat, sizeof(stat)); + break; + default: + snmp_log(LOG_ERR, "unknown mode (%d) in handle_statSSTPActive\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} diff --git a/accel-pppd/include/ap_session.h b/accel-pppd/include/ap_session.h index 27471859..a4d3b867 100644 --- a/accel-pppd/include/ap_session.h +++ b/accel-pppd/include/ap_session.h @@ -136,10 +136,14 @@ extern int ap_shutdown; extern int sock_fd; extern int sock6_fd; extern int urandom_fd; -extern struct ap_session_stat ap_session_stat; extern int conf_max_sessions; extern int conf_max_starting; +void ap_session_stat_get(struct ap_session_stat *stat); +unsigned int ap_session_stat_starting(void); +unsigned int ap_session_stat_active(void); +unsigned int ap_session_stat_finishing(void); + void ap_session_init(struct ap_session *ses); void ap_session_set_ifindex(struct ap_session *ses); int ap_session_starting(struct ap_session *ses); 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); diff --git a/accel-pppd/session.c b/accel-pppd/session.c index a1b194a3..c16f68ae 100644 --- a/accel-pppd/session.c +++ b/accel-pppd/session.c @@ -62,13 +62,58 @@ static spinlock_t seq_lock; static long long unsigned seq; static struct timespec seq_ts; -struct ap_session_stat __export ap_session_stat; +static struct ap_session_stat ap_session_stat; static void (*shutdown_cb)(void); static void generate_sessionid(struct ap_session *ses); static void save_seq(void); +void __export ap_session_stat_get(struct ap_session_stat *stat) +{ + stat->starting = __atomic_load_n(&ap_session_stat.starting, __ATOMIC_RELAXED); + stat->active = __atomic_load_n(&ap_session_stat.active, __ATOMIC_RELAXED); + stat->finishing = __atomic_load_n(&ap_session_stat.finishing, __ATOMIC_RELAXED); +} + +unsigned int __export ap_session_stat_starting(void) +{ + return __atomic_load_n(&ap_session_stat.starting, __ATOMIC_RELAXED); +} + +unsigned int __export ap_session_stat_active(void) +{ + return __atomic_load_n(&ap_session_stat.active, __ATOMIC_RELAXED); +} + +unsigned int __export ap_session_stat_finishing(void) +{ + return __atomic_load_n(&ap_session_stat.finishing, __ATOMIC_RELAXED); +} + +static void ap_session_stat_inc(unsigned int *stat) +{ + __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void ap_session_stat_dec(unsigned int *stat) +{ + __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED); +} + +static void ap_session_stat_move(unsigned int *from, unsigned int *to) +{ + ap_session_stat_dec(from); + ap_session_stat_inc(to); +} + +static int ap_session_stat_idle(void) +{ + return !ap_session_stat_starting() + && !ap_session_stat_active() + && !ap_session_stat_finishing(); +} + void __export ap_session_init(struct ap_session *ses) { memset(ses, 0, sizeof(*ses)); @@ -113,7 +158,7 @@ int __export ap_session_starting(struct ap_session *ses) ses->state = AP_STATE_STARTING; } - __sync_add_and_fetch(&ap_session_stat.starting, 1); + ap_session_stat_inc(&ap_session_stat.starting); pthread_rwlock_wrlock(&ses_lock); list_add_tail(&ses->entry, &ses_list); @@ -156,8 +201,7 @@ void __export ap_session_activate(struct ap_session *ses) return; ses->state = AP_STATE_ACTIVE; - __sync_sub_and_fetch(&ap_session_stat.starting, 1); - __sync_add_and_fetch(&ap_session_stat.active, 1); + ap_session_stat_move(&ap_session_stat.starting, &ap_session_stat.active); if (!ses->session_timeout && conf_session_timeout) ses->session_timeout = conf_session_timeout; @@ -198,14 +242,14 @@ void __export ap_session_finished(struct ap_session *ses) switch (ses->state) { case AP_STATE_ACTIVE: - __sync_sub_and_fetch(&ap_session_stat.active, 1); + ap_session_stat_dec(&ap_session_stat.active); break; case AP_STATE_RESTORE: case AP_STATE_STARTING: - __sync_sub_and_fetch(&ap_session_stat.starting, 1); + ap_session_stat_dec(&ap_session_stat.starting); break; case AP_STATE_FINISHING: - __sync_sub_and_fetch(&ap_session_stat.finishing, 1); + ap_session_stat_dec(&ap_session_stat.finishing); break; } @@ -266,7 +310,7 @@ void __export ap_session_finished(struct ap_session *ses) ses->backup->storage->free(ses->backup); #endif - if (ap_shutdown && !ap_session_stat.starting && !ap_session_stat.active && !ap_session_stat.finishing) { + if (ap_shutdown && ap_session_stat_idle()) { if (shutdown_cb) shutdown_cb(); else @@ -299,11 +343,10 @@ void __export ap_session_terminate(struct ap_session *ses, int cause, int hard) } if (ses->state == AP_STATE_ACTIVE) - __sync_sub_and_fetch(&ap_session_stat.active, 1); + ap_session_stat_move(&ap_session_stat.active, &ap_session_stat.finishing); else - __sync_sub_and_fetch(&ap_session_stat.starting, 1); + ap_session_stat_move(&ap_session_stat.starting, &ap_session_stat.finishing); - __sync_add_and_fetch(&ap_session_stat.finishing, 1); ses->terminating = 1; ses->state = AP_STATE_FINISHING; @@ -333,7 +376,7 @@ int ap_shutdown_soft(void (*cb)(void), int term) pthread_rwlock_rdlock(&ses_lock); - if (!ap_session_stat.starting && !ap_session_stat.active && !ap_session_stat.finishing) { + if (ap_session_stat_idle()) { pthread_rwlock_unlock(&ses_lock); if (shutdown_cb) shutdown_cb(); diff --git a/accel-pppd/triton/md.c b/accel-pppd/triton/md.c index 9b7dd81a..374e49a5 100644 --- a/accel-pppd/triton/md.c +++ b/accel-pppd/triton/md.c @@ -87,7 +87,7 @@ static void *md_thread(void *arg) if (!h->pending) { list_add_tail(&h->entry2, &h->ctx->pending_handlers); h->pending = 1; - __sync_add_and_fetch(&triton_stat.md_handler_pending, 1); + triton_stat_md_handler_pending_inc(); r = triton_queue_ctx(h->ctx); } else r = 0; @@ -129,7 +129,7 @@ void __export triton_md_register_handler(struct triton_context_t *ctx, struct tr list_add_tail(&h->entry, &h->ctx->handlers); spin_unlock(&h->ctx->lock); - __sync_add_and_fetch(&triton_stat.md_handler_count, 1); + triton_stat_md_handler_count_inc(); } void __export triton_md_unregister_handler(struct triton_md_handler_t *ud, int c) @@ -148,7 +148,7 @@ void __export triton_md_unregister_handler(struct triton_md_handler_t *ud, int c list_del(&h->entry); if (h->pending) { list_del(&h->entry2); - __sync_sub_and_fetch(&triton_stat.md_handler_pending, 1); + triton_stat_md_handler_pending_dec(); } spin_unlock(&h->ctx->lock); @@ -158,7 +158,7 @@ void __export triton_md_unregister_handler(struct triton_md_handler_t *ud, int c ud->tpd = NULL; - __sync_sub_and_fetch(&triton_stat.md_handler_count, 1); + triton_stat_md_handler_count_dec(); } int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode) diff --git a/accel-pppd/triton/mempool.c b/accel-pppd/triton/mempool.c index 149f09d5..a3c72dae 100644 --- a/accel-pppd/triton/mempool.c +++ b/accel-pppd/triton/mempool.c @@ -104,7 +104,7 @@ void __export *mempool_alloc(mempool_t *pool) spin_unlock(&p->lock); --p->objects; - __sync_sub_and_fetch(&triton_stat.mempool_available, size); + triton_stat_mempool_available_sub(size); return it->ptr; } @@ -121,10 +121,10 @@ void __export *mempool_alloc(mempool_t *pool) it = (struct _item_t *)mmap_ptr; mmap_ptr += size; spin_unlock(&mmap_lock); - __sync_sub_and_fetch(&triton_stat.mempool_available, size); + triton_stat_mempool_available_sub(size); } else { it = _malloc(size); - __sync_add_and_fetch(&triton_stat.mempool_allocated, size); + triton_stat_mempool_allocated_add(size); } if (!it) { @@ -184,9 +184,9 @@ void __export mempool_free(void *ptr) #else if (need_free) { _free(it); - __sync_sub_and_fetch(&triton_stat.mempool_allocated, size); + triton_stat_mempool_allocated_sub(size); } else - __sync_add_and_fetch(&triton_stat.mempool_available, size); + triton_stat_mempool_available_add(size); #endif } @@ -238,8 +238,8 @@ static void mempool_clean(void) #endif list_del(&it->entry); _free(it); - __sync_sub_and_fetch(&triton_stat.mempool_allocated, size); - __sync_sub_and_fetch(&triton_stat.mempool_available, size); + triton_stat_mempool_allocated_sub(size); + triton_stat_mempool_available_sub(size); #ifdef VALGRIND } else break; @@ -275,8 +275,8 @@ static int mmap_grow(void) mmap_endptr = ptr + size; - __sync_add_and_fetch(&triton_stat.mempool_allocated, size); - __sync_add_and_fetch(&triton_stat.mempool_available, size); + triton_stat_mempool_allocated_add(size); + triton_stat_mempool_available_add(size); return 0; oom: diff --git a/accel-pppd/triton/timer.c b/accel-pppd/triton/timer.c index 5b5d9535..ed23eb1d 100644 --- a/accel-pppd/triton/timer.c +++ b/accel-pppd/triton/timer.c @@ -95,7 +95,7 @@ void *timer_thread(void *arg) if (!t->pending) { list_add_tail(&t->entry2, &t->ctx->pending_timers); t->pending = 1; - __sync_add_and_fetch(&triton_stat.timer_pending, 1); + triton_stat_timer_pending_inc(); r = triton_queue_ctx(t->ctx); } else r = 0; @@ -167,7 +167,7 @@ int __export triton_timer_add(struct triton_context_t *ctx, struct triton_timer_ goto out_err; } - __sync_add_and_fetch(&triton_stat.timer_count, 1); + triton_stat_timer_count_inc(); return 0; @@ -206,7 +206,7 @@ void __export triton_timer_del(struct triton_timer_t *ud) list_del(&t->entry); if (t->pending) { list_del(&t->entry2); - __sync_sub_and_fetch(&triton_stat.timer_pending, 1); + triton_stat_timer_pending_dec(); } spin_unlock(&t->ctx->lock); @@ -216,6 +216,6 @@ void __export triton_timer_del(struct triton_timer_t *ud) ud->tpd = NULL; - __sync_sub_and_fetch(&triton_stat.timer_count, 1); + triton_stat_timer_count_dec(); } diff --git a/accel-pppd/triton/triton.c b/accel-pppd/triton/triton.c index 395a42df..5c7231b7 100644 --- a/accel-pppd/triton/triton.c +++ b/accel-pppd/triton/triton.c @@ -38,7 +38,7 @@ static void (*config_reload_notify)(int); static mempool_t *ctx_pool; static mempool_t *call_pool; -struct triton_stat_t __export triton_stat; +static struct triton_stat_t triton_stat; static struct timeval ru_utime; static struct timeval ru_stime; @@ -57,6 +57,153 @@ static __thread void *thread_frame; #define log_debug2(fmt, ...) +void __export triton_stat_get(struct triton_stat_t *stat) +{ + stat->mempool_allocated = __atomic_load_n(&triton_stat.mempool_allocated, __ATOMIC_RELAXED); + stat->mempool_available = __atomic_load_n(&triton_stat.mempool_available, __ATOMIC_RELAXED); + stat->thread_count = __atomic_load_n(&triton_stat.thread_count, __ATOMIC_RELAXED); + stat->thread_active = __atomic_load_n(&triton_stat.thread_active, __ATOMIC_RELAXED); + stat->context_count = __atomic_load_n(&triton_stat.context_count, __ATOMIC_RELAXED); + stat->context_sleeping = __atomic_load_n(&triton_stat.context_sleeping, __ATOMIC_RELAXED); + stat->context_pending = __atomic_load_n(&triton_stat.context_pending, __ATOMIC_RELAXED); + stat->md_handler_count = __atomic_load_n(&triton_stat.md_handler_count, __ATOMIC_RELAXED); + stat->md_handler_pending = __atomic_load_n(&triton_stat.md_handler_pending, __ATOMIC_RELAXED); + stat->timer_count = __atomic_load_n(&triton_stat.timer_count, __ATOMIC_RELAXED); + stat->timer_pending = __atomic_load_n(&triton_stat.timer_pending, __ATOMIC_RELAXED); + stat->start_time = __atomic_load_n(&triton_stat.start_time, __ATOMIC_RELAXED); + stat->cpu = __atomic_load_n(&triton_stat.cpu, __ATOMIC_RELAXED); +} + +time_t __export triton_stat_start_time(void) +{ + return __atomic_load_n(&triton_stat.start_time, __ATOMIC_RELAXED); +} + +unsigned int __export triton_stat_cpu(void) +{ + return __atomic_load_n(&triton_stat.cpu, __ATOMIC_RELAXED); +} + +void triton_stat_mempool_allocated_add(uint64_t value) +{ + __atomic_add_fetch(&triton_stat.mempool_allocated, value, __ATOMIC_RELAXED); +} + +void triton_stat_mempool_allocated_sub(uint64_t value) +{ + __atomic_sub_fetch(&triton_stat.mempool_allocated, value, __ATOMIC_RELAXED); +} + +void triton_stat_mempool_available_add(uint64_t value) +{ + __atomic_add_fetch(&triton_stat.mempool_available, value, __ATOMIC_RELAXED); +} + +void triton_stat_mempool_available_sub(uint64_t value) +{ + __atomic_sub_fetch(&triton_stat.mempool_available, value, __ATOMIC_RELAXED); +} + +void triton_stat_thread_count_inc(void) +{ + __atomic_add_fetch(&triton_stat.thread_count, 1, __ATOMIC_RELAXED); +} + +void triton_stat_thread_active_inc(void) +{ + __atomic_add_fetch(&triton_stat.thread_active, 1, __ATOMIC_RELAXED); +} + +unsigned int triton_stat_thread_active_dec(void) +{ + return __atomic_sub_fetch(&triton_stat.thread_active, 1, __ATOMIC_RELAXED); +} + +static unsigned int triton_stat_thread_active(void) +{ + return __atomic_load_n(&triton_stat.thread_active, __ATOMIC_RELAXED); +} + +void triton_stat_context_count_inc(void) +{ + __atomic_add_fetch(&triton_stat.context_count, 1, __ATOMIC_RELAXED); +} + +unsigned int triton_stat_context_count_dec(void) +{ + return __atomic_sub_fetch(&triton_stat.context_count, 1, __ATOMIC_RELAXED); +} + +void triton_stat_context_sleeping_inc(void) +{ + __atomic_add_fetch(&triton_stat.context_sleeping, 1, __ATOMIC_RELAXED); +} + +void triton_stat_context_sleeping_dec(void) +{ + __atomic_sub_fetch(&triton_stat.context_sleeping, 1, __ATOMIC_RELAXED); +} + +void triton_stat_context_pending_inc(void) +{ + __atomic_add_fetch(&triton_stat.context_pending, 1, __ATOMIC_RELAXED); +} + +void triton_stat_context_pending_dec(void) +{ + __atomic_sub_fetch(&triton_stat.context_pending, 1, __ATOMIC_RELAXED); +} + +void triton_stat_md_handler_count_inc(void) +{ + __atomic_add_fetch(&triton_stat.md_handler_count, 1, __ATOMIC_RELAXED); +} + +void triton_stat_md_handler_count_dec(void) +{ + __atomic_sub_fetch(&triton_stat.md_handler_count, 1, __ATOMIC_RELAXED); +} + +void triton_stat_md_handler_pending_inc(void) +{ + __atomic_add_fetch(&triton_stat.md_handler_pending, 1, __ATOMIC_RELAXED); +} + +void triton_stat_md_handler_pending_dec(void) +{ + __atomic_sub_fetch(&triton_stat.md_handler_pending, 1, __ATOMIC_RELAXED); +} + +void triton_stat_timer_count_inc(void) +{ + __atomic_add_fetch(&triton_stat.timer_count, 1, __ATOMIC_RELAXED); +} + +void triton_stat_timer_count_dec(void) +{ + __atomic_sub_fetch(&triton_stat.timer_count, 1, __ATOMIC_RELAXED); +} + +void triton_stat_timer_pending_inc(void) +{ + __atomic_add_fetch(&triton_stat.timer_pending, 1, __ATOMIC_RELAXED); +} + +void triton_stat_timer_pending_dec(void) +{ + __atomic_sub_fetch(&triton_stat.timer_pending, 1, __ATOMIC_RELAXED); +} + +void triton_stat_set_cpu(unsigned int value) +{ + __atomic_store_n(&triton_stat.cpu, value, __ATOMIC_RELAXED); +} + +void triton_stat_set_start_time(time_t value) +{ + __atomic_store_n(&triton_stat.start_time, value, __ATOMIC_RELAXED); +} + void triton_thread_wakeup(struct _triton_thread_t *thread) { log_debug2("wake up thread %p\n", thread); @@ -146,7 +293,7 @@ static void* triton_thread(struct _triton_thread_t *thread) thread->ctx->thread = thread; thread->ctx->queued = 0; spin_unlock(&threads_lock); - __sync_sub_and_fetch(&triton_stat.context_pending, 1); + triton_stat_context_pending_dec(); } } else { log_debug2("thread: %p: sleeping\n", thread); @@ -154,7 +301,7 @@ static void* triton_thread(struct _triton_thread_t *thread) if (!terminate) list_add(&thread->entry2, &sleep_threads); - if (__sync_sub_and_fetch(&triton_stat.thread_active, 1) == 0 && need_config_reload) { + if (triton_stat_thread_active_dec() == 0 && need_config_reload) { spin_unlock(&threads_lock); __config_reload(config_reload_notify); } else @@ -172,7 +319,7 @@ static void* triton_thread(struct _triton_thread_t *thread) //printf("thread %p: exit sigwait\n", thread); spin_lock(&threads_lock); - __sync_add_and_fetch(&triton_stat.thread_active, 1); + triton_stat_thread_active_inc(); if (!thread->ctx) { list_del(&thread->entry2); spin_unlock(&threads_lock); @@ -228,7 +375,7 @@ static void ctx_thread(struct _triton_context_t *ctx) list_del(&t->entry2); t->pending = 0; spin_unlock(&ctx->lock); - __sync_sub_and_fetch(&triton_stat.timer_pending, 1); + triton_stat_timer_pending_dec(); read(t->fd, &tt, sizeof(tt)); if (t->ud) t->ud->expire(t->ud); @@ -243,7 +390,7 @@ static void ctx_thread(struct _triton_context_t *ctx) h->trig_epoll_events = 0; spin_unlock(&ctx->lock); - __sync_sub_and_fetch(&triton_stat.md_handler_pending, 1); + triton_stat_md_handler_pending_dec(); h->armed = 0; @@ -320,8 +467,8 @@ struct _triton_thread_t *create_thread() while (pthread_create(&thread->thread, &attr, (void*(*)(void*))triton_thread, thread)) sleep(1); - __sync_add_and_fetch(&triton_stat.thread_count, 1); - __sync_add_and_fetch(&triton_stat.thread_active, 1); + triton_stat_thread_count_inc(); + triton_stat_thread_active_inc(); return thread; } @@ -340,7 +487,7 @@ int triton_queue_ctx(struct _triton_context_t *ctx) spin_unlock(&threads_lock); ctx->queued = 1; log_debug2("ctx %p: queued\n", ctx); - __sync_add_and_fetch(&triton_stat.context_pending, 1); + triton_stat_context_pending_inc(); return 0; } @@ -386,8 +533,8 @@ int __export triton_context_register(struct triton_context_t *ud, void *bf_arg) list_add_tail(&ctx->entry, &ctx_list); spin_unlock(&ctx_list_lock); - __sync_add_and_fetch(&triton_stat.context_sleeping, 1); - __sync_add_and_fetch(&triton_stat.context_count, 1); + triton_stat_context_sleeping_inc(); + triton_stat_context_count_inc(); return 0; } @@ -437,7 +584,7 @@ void __export triton_context_unregister(struct triton_context_t *ud) spin_lock(&ctx_list_lock); list_del(&ctx->entry); - if (__sync_sub_and_fetch(&triton_stat.context_count, 1) == 1) { + if (triton_stat_context_count_dec() == 1) { if (need_terminate) terminate = 1; } @@ -492,7 +639,7 @@ void __export triton_context_schedule() volatile struct _triton_context_t *ctx = (struct _triton_context_t *)this_ctx->tpd; log_debug2("ctx %p: enter schedule\n", ctx); - __sync_add_and_fetch(&triton_stat.context_sleeping, 1); + triton_stat_context_sleeping_inc(); ctx->uc = alloc_context(); @@ -509,7 +656,7 @@ void __export triton_context_schedule() spin_unlock(&threads_lock); _free(ctx->uc); ctx->uc = NULL; - __sync_sub_and_fetch(&triton_stat.context_sleeping, 1); + triton_stat_context_sleeping_dec(); log_debug2("ctx %p: exit schedule\n", ctx); } else { ctx->asleep = 1; @@ -527,7 +674,7 @@ void __export triton_context_wakeup(struct triton_context_t *ud) log_debug2("ctx %p: wakeup\n", ctx); if (ctx->init) { - __sync_sub_and_fetch(&triton_stat.context_sleeping, 1); + triton_stat_context_sleeping_dec(); spin_lock(&ctx->lock); ctx->init = 0; if (ctx->pending) @@ -610,7 +757,7 @@ void __export triton_collect_cpu_usage(void) clock_gettime(CLOCK_MONOTONIC, &ru_timestamp); ru_utime = rusage.ru_utime; ru_stime = rusage.ru_stime; - triton_stat.cpu = 0; + triton_stat_set_cpu(0); } } @@ -634,7 +781,7 @@ static void ru_update(struct triton_timer_t *t) val = (double)((rusage.ru_utime.tv_sec - ru_utime.tv_sec) * 1000000 + (rusage.ru_utime.tv_usec - ru_utime.tv_usec) + (rusage.ru_stime.tv_sec - ru_stime.tv_sec) * 1000000 + (rusage.ru_stime.tv_usec - ru_stime.tv_usec)) / dt * 100; - triton_stat.cpu = val; + triton_stat_set_cpu(val); ru_timestamp = ts; ru_utime = rusage.ru_utime; @@ -714,7 +861,7 @@ void __export triton_conf_reload(void (*notify)(int)) spin_lock(&threads_lock); need_config_reload = 1; config_reload_notify = notify; - if (triton_stat.thread_active == 0) { + if (triton_stat_thread_active() == 0) { spin_unlock(&threads_lock); __config_reload(notify); } else @@ -752,7 +899,7 @@ void __export triton_run() } clock_gettime(CLOCK_MONOTONIC, &ts); - triton_stat.start_time = ts.tv_sec; + triton_stat_set_start_time(ts.tv_sec); md_run(); timer_run(); diff --git a/accel-pppd/triton/triton.h b/accel-pppd/triton/triton.h index 3ce4bcbd..aef77c2b 100644 --- a/accel-pppd/triton/triton.h +++ b/accel-pppd/triton/triton.h @@ -70,7 +70,9 @@ struct triton_stat_t unsigned int cpu; }; -extern struct triton_stat_t triton_stat; +void triton_stat_get(struct triton_stat_t *stat); +time_t triton_stat_start_time(void); +unsigned int triton_stat_cpu(void); int triton_context_register(struct triton_context_t *, void *arg); void triton_context_unregister(struct triton_context_t *); void triton_context_set_priority(struct triton_context_t *, int); diff --git a/accel-pppd/triton/triton_p.h b/accel-pppd/triton/triton_p.h index bc39d626..7fa70b63 100644 --- a/accel-pppd/triton/triton_p.h +++ b/accel-pppd/triton/triton_p.h @@ -119,4 +119,28 @@ void triton_log_debug(const char *fmt, ...) __attribute__((format(gnu_printf, 1, int load_modules(const char *name); void triton_context_release(struct _triton_context_t *ctx); +void triton_stat_mempool_allocated_add(uint64_t value); +void triton_stat_mempool_allocated_sub(uint64_t value); +void triton_stat_mempool_available_add(uint64_t value); +void triton_stat_mempool_available_sub(uint64_t value); +void triton_stat_thread_count_inc(void); +void triton_stat_thread_active_inc(void); +unsigned int triton_stat_thread_active_dec(void); +void triton_stat_context_count_inc(void); +unsigned int triton_stat_context_count_dec(void); +void triton_stat_context_sleeping_inc(void); +void triton_stat_context_sleeping_dec(void); +void triton_stat_context_pending_inc(void); +void triton_stat_context_pending_dec(void); +void triton_stat_md_handler_count_inc(void); +void triton_stat_md_handler_count_dec(void); +void triton_stat_md_handler_pending_inc(void); +void triton_stat_md_handler_pending_dec(void); +void triton_stat_timer_count_inc(void); +void triton_stat_timer_count_dec(void); +void triton_stat_timer_pending_inc(void); +void triton_stat_timer_pending_dec(void); +void triton_stat_set_cpu(unsigned int value); +void triton_stat_set_start_time(time_t value); + #endif |
