diff options
author | Kozlov Dmitry <xeb@mail.ru> | 2012-09-05 23:24:51 +0400 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2012-09-05 23:24:51 +0400 |
commit | 490f6384f6a54e388587329c0309a6602d5544e8 (patch) | |
tree | 5e70a9e4e7a8f6714a4694826ec68f293d1e55a8 | |
parent | a10ec0f4636cd559209659304709924daad96340 (diff) | |
download | accel-ppp-490f6384f6a54e388587329c0309a6602d5544e8.tar.gz accel-ppp-490f6384f6a54e388587329c0309a6602d5544e8.zip |
generalize interface statistics gathering
-rw-r--r-- | accel-pppd/CMakeLists.txt | 2 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 2 | ||||
-rw-r--r-- | accel-pppd/extra/CMakeLists.txt | 3 | ||||
-rw-r--r-- | accel-pppd/extra/pppd_compat.c | 33 | ||||
-rw-r--r-- | accel-pppd/extra/sigchld.c | 3 | ||||
-rw-r--r-- | accel-pppd/include/ap_session.h | 13 | ||||
l--------- | accel-pppd/include/iplink.h | 1 | ||||
l--------- | accel-pppd/include/iputils.h | 1 | ||||
-rw-r--r-- | accel-pppd/libnetlink/iputils.c (renamed from accel-pppd/libnetlink/iplink.c) | 2 | ||||
-rw-r--r-- | accel-pppd/libnetlink/iputils.h (renamed from accel-pppd/libnetlink/iplink.h) | 0 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_lcp.c | 10 | ||||
-rw-r--r-- | accel-pppd/radius/acct.c | 45 | ||||
-rw-r--r-- | accel-pppd/radius/radius.c | 11 | ||||
-rw-r--r-- | accel-pppd/radius/radius_p.h | 11 | ||||
-rw-r--r-- | accel-pppd/session.c | 46 |
15 files changed, 90 insertions, 93 deletions
diff --git a/accel-pppd/CMakeLists.txt b/accel-pppd/CMakeLists.txt index 92d7cfba..7b33e684 100644 --- a/accel-pppd/CMakeLists.txt +++ b/accel-pppd/CMakeLists.txt @@ -76,7 +76,7 @@ ADD_EXECUTABLE(accel-pppd cli/cli.c libnetlink/libnetlink.c - libnetlink/iplink.c + libnetlink/iputils.c libnetlink/genl.c pwdb.c diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index 1ddec374..a871f0fa 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -28,7 +28,7 @@ #include "pwdb.h" #include "ipdb.h" -#include "iplink.h" +#include "iputils.h" #include "connlimit.h" #ifdef RADIUS #include "radius.h" diff --git a/accel-pppd/extra/CMakeLists.txt b/accel-pppd/extra/CMakeLists.txt index da1ac54c..ea640b18 100644 --- a/accel-pppd/extra/CMakeLists.txt +++ b/accel-pppd/extra/CMakeLists.txt @@ -1,7 +1,8 @@ +ADD_LIBRARY(sigchld SHARED sigchld.c) ADD_LIBRARY(pppd_compat SHARED pppd_compat.c) +TARGET_LINK_LIBRARIES(pppd_compat sigchld) ADD_LIBRARY(ippool SHARED ippool.c) ADD_LIBRARY(ipv6pool SHARED ipv6pool.c) -ADD_LIBRARY(sigchld SHARED sigchld.c) ADD_LIBRARY(chap-secrets SHARED chap-secrets.c) ADD_LIBRARY(logwtmp SHARED logwtmp.c) TARGET_LINK_LIBRARIES(logwtmp util) diff --git a/accel-pppd/extra/pppd_compat.c b/accel-pppd/extra/pppd_compat.c index 71934ab8..59d052c9 100644 --- a/accel-pppd/extra/pppd_compat.c +++ b/accel-pppd/extra/pppd_compat.c @@ -6,6 +6,7 @@ #include <unistd.h> #include <sched.h> #include <limits.h> +#include <inttypes.h> #include <sys/ioctl.h> #include <netinet/in.h> #include "linux_ppp.h" @@ -18,7 +19,7 @@ #include "log.h" #include "utils.h" #include "sigchld.h" -#include "iplink.h" +#include "iputils.h" #ifdef RADIUS #include "radius.h" @@ -48,8 +49,6 @@ struct pppd_compat_pd_t #endif int started:1; int res; - int bytes_sent; - int bytes_rcvd; in_addr_t ipv4_addr; in_addr_t ipv4_peer_addr; }; @@ -226,23 +225,6 @@ static void ev_ses_started(struct ap_session *ses) pd->started = 1; } -static void ev_ses_finishing(struct ap_session *ses) -{ - struct rtnl_link_stats stats; - struct pppd_compat_pd_t *pd = find_pd(ses); - - if (!pd) - return; - - if (iplink_get_stats(ses->ifindex, &stats)) { - log_ppp_error("pppd_compat: failed to get interface statistics\n"); - return; - } - - pd->bytes_sent = stats.tx_bytes; - pd->bytes_rcvd = stats.rx_bytes; -} - static void ev_ses_finished(struct ap_session *ses) { pid_t pid; @@ -498,12 +480,18 @@ static void fill_argv(char **argv, struct pppd_compat_pd_t *pd, char *path) static void fill_env(char **env, struct pppd_compat_pd_t *pd) { + struct ap_session *ses = pd->ses; + uint64_t tx_bytes, rx_bytes; + + tx_bytes = (uint64_t)ses->acct_tx_bytes + ses->acct_output_gigawords*4294967296llu; + rx_bytes = (uint64_t)ses->acct_rx_bytes + ses->acct_input_gigawords*4294967296llu; + snprintf(env[0], 64, "PEERNAME=%s", pd->ses->username); if (pd->ses->stop_time && env[1]) { snprintf(env[1], 24, "CONNECT_TIME=%lu", pd->ses->stop_time - pd->ses->start_time); - snprintf(env[2], 24, "BYTES_SENT=%u", pd->bytes_sent); - snprintf(env[3], 24, "BYTES_RCVD=%u", pd->bytes_rcvd); + snprintf(env[2], 24, "BYTES_SENT=%" PRIu64, tx_bytes); + snprintf(env[3], 24, "BYTES_RCVD=%" PRIu64, rx_bytes); } } @@ -538,7 +526,6 @@ static void init(void) triton_event_register_handler(EV_SES_STARTING, (triton_event_func)ev_ses_starting); triton_event_register_handler(EV_SES_PRE_UP, (triton_event_func)ev_ses_pre_up); triton_event_register_handler(EV_SES_STARTED, (triton_event_func)ev_ses_started); - triton_event_register_handler(EV_SES_FINISHING, (triton_event_func)ev_ses_finishing); triton_event_register_handler(EV_SES_PRE_FINISHED, (triton_event_func)ev_ses_finished); #ifdef RADIUS if (triton_module_loaded("radius")) { diff --git a/accel-pppd/extra/sigchld.c b/accel-pppd/extra/sigchld.c index 8f1a979e..d6b0df5f 100644 --- a/accel-pppd/extra/sigchld.c +++ b/accel-pppd/extra/sigchld.c @@ -109,10 +109,9 @@ void __export sigchld_unlock() pthread_mutex_unlock(&handlers_lock); } -static void init(void) +static void __init init(void) { if (pthread_create(&sigchld_thr, NULL, sigchld_thread, NULL)) log_emerg("sigchld: pthread_create: %s\n", strerror(errno)); } -DEFINE_INIT(100, init);
\ No newline at end of file diff --git a/accel-pppd/include/ap_session.h b/accel-pppd/include/ap_session.h index 95f0ea21..82654f8b 100644 --- a/accel-pppd/include/ap_session.h +++ b/accel-pppd/include/ap_session.h @@ -35,6 +35,7 @@ struct ap_session; struct backup_data; +struct rtnl_link_stats; struct ap_ctrl { @@ -70,6 +71,7 @@ struct ap_session char sessionid[AP_SESSIONID_LEN+1]; time_t start_time; time_t stop_time; + time_t idle_time; char *username; struct ipv4db_item_t *ipv4; struct ipv6db_item_t *ipv6; @@ -87,6 +89,15 @@ struct ap_session int terminate_cause; struct list_head pd_list; + + uint32_t acct_rx_bytes; + uint32_t acct_tx_bytes; + uint32_t acct_input_gigawords; + uint32_t acct_output_gigawords; + uint32_t acct_rx_packets_i; + uint32_t acct_tx_packets_i; + uint32_t acct_rx_bytes_i; + uint32_t acct_tx_bytes_i; }; struct ap_session_stat @@ -114,6 +125,8 @@ void ap_session_activate(struct ap_session *ses); void ap_session_ifup(struct ap_session *ses); void ap_session_ifdown(struct ap_session *ses); +int ap_session_read_stats(struct ap_session *ses, struct rtnl_link_stats *stats); + void ap_shutdown_soft(void (*cb)(void)); #endif diff --git a/accel-pppd/include/iplink.h b/accel-pppd/include/iplink.h deleted file mode 120000 index 7f0f09d4..00000000 --- a/accel-pppd/include/iplink.h +++ /dev/null @@ -1 +0,0 @@ -../libnetlink/iplink.h
\ No newline at end of file diff --git a/accel-pppd/include/iputils.h b/accel-pppd/include/iputils.h new file mode 120000 index 00000000..c91d11c9 --- /dev/null +++ b/accel-pppd/include/iputils.h @@ -0,0 +1 @@ +../libnetlink/iputils.h
\ No newline at end of file diff --git a/accel-pppd/libnetlink/iplink.c b/accel-pppd/libnetlink/iputils.c index 4b85afe2..0ae4b04c 100644 --- a/accel-pppd/libnetlink/iplink.c +++ b/accel-pppd/libnetlink/iputils.c @@ -20,7 +20,7 @@ #include "log.h" #include "libnetlink.h" -#include "iplink.h" +#include "iputils.h" #include "memdebug.h" diff --git a/accel-pppd/libnetlink/iplink.h b/accel-pppd/libnetlink/iputils.h index f9124343..f9124343 100644 --- a/accel-pppd/libnetlink/iplink.h +++ b/accel-pppd/libnetlink/iputils.h diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c index 1b47cad5..2d1e195d 100644 --- a/accel-pppd/ppp/ppp_lcp.c +++ b/accel-pppd/ppp/ppp_lcp.c @@ -12,7 +12,7 @@ #include "ppp.h" #include "ppp_lcp.h" #include "events.h" -#include "iplink.h" +#include "iputils.h" #include "memdebug.h" @@ -656,15 +656,15 @@ static void send_echo_request(struct triton_timer_t *t) ++lcp->echo_sent; + ap_session_read_stats(&lcp->ppp->ses, &stats); + if (conf_echo_timeout) { if (lcp->echo_sent == 2) { - if (iplink_get_stats(lcp->ppp->ses.ifindex, &stats) == 0) - lcp->last_ipackets = stats.rx_packets; - + lcp->last_ipackets = stats.rx_packets; time(&lcp->last_echo_ts); } else if (lcp->echo_sent > 2) { time(&ts); - if (iplink_get_stats(lcp->ppp->ses.ifindex, &stats) == 0 && lcp->last_ipackets != stats.rx_packets) { + if (lcp->last_ipackets != stats.rx_packets) { lcp->echo_sent = 1; lcp_update_echo_timer(lcp); } else if (ts - lcp->last_echo_ts > conf_echo_timeout) { diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c index ab71c453..81145cd1 100644 --- a/accel-pppd/radius/acct.c +++ b/accel-pppd/radius/acct.c @@ -12,7 +12,7 @@ #include "log.h" #include "backup.h" #include "ap_session_backup.h" -#include "iplink.h" +#include "iputils.h" #include "radius_p.h" @@ -21,33 +21,6 @@ #define STAT_UPDATE_INTERVAL (10 * 60 * 1000) #define INTERIM_SAFE_TIME 10 -int rad_read_stats(struct radius_pd_t *rpd, struct rtnl_link_stats *stats) -{ - int r; - - if (iplink_get_stats(rpd->ses->ifindex, stats)) { - log_ppp_warn("radius: failed to get interface statistics\n"); - return -1; - } - - stats->rx_packets -= rpd->acct_rx_packets_i; - stats->tx_packets -= rpd->acct_tx_packets_i; - stats->rx_bytes -= rpd->acct_rx_bytes_i; - stats->tx_bytes -= rpd->acct_tx_bytes_i; - - r = stats->rx_bytes != rpd->acct_rx_bytes || stats->tx_bytes < rpd->acct_tx_bytes; - - if (stats->rx_bytes < rpd->acct_rx_bytes) - rpd->acct_input_gigawords++; - rpd->acct_rx_bytes = stats->rx_packets; - - if (stats->tx_bytes < rpd->acct_tx_bytes) - rpd->acct_output_gigawords++; - rpd->acct_tx_bytes = stats->tx_bytes; - - return r; -} - static int req_set_RA(struct rad_req_t *req, const char *secret) { MD5_CTX ctx; @@ -75,13 +48,13 @@ static void req_set_stat(struct rad_req_t *req, struct ap_session *ses) else time(&stop_time); - if (rad_read_stats(rpd, &stats) > 0) { + if (ap_session_read_stats(ses, &stats) == 0) { rad_packet_change_int(req->pack, NULL, "Acct-Input-Octets", stats.rx_bytes); rad_packet_change_int(req->pack, NULL, "Acct-Output-Octets", stats.tx_bytes); rad_packet_change_int(req->pack, NULL, "Acct-Input-Packets", stats.rx_packets); rad_packet_change_int(req->pack, NULL, "Acct-Output-Packets", stats.tx_packets); - rad_packet_change_int(req->pack, NULL, "Acct-Input-Gigawords", rpd->acct_input_gigawords); - rad_packet_change_int(req->pack, NULL, "Acct-Output-Gigawords", rpd->acct_output_gigawords); + rad_packet_change_int(req->pack, NULL, "Acct-Input-Gigawords", rpd->ses->acct_input_gigawords); + rad_packet_change_int(req->pack, NULL, "Acct-Output-Gigawords", rpd->ses->acct_output_gigawords); } rad_packet_change_int(req->pack, NULL, "Acct-Session-Time", stop_time - ses->start_time); @@ -248,20 +221,10 @@ int rad_acct_start(struct radius_pd_t *rpd) int i; time_t ts; unsigned int dt; - struct rtnl_link_stats stats; if (!conf_accounting) return 0; - if (iplink_get_stats(rpd->ses->ifindex, &stats)) - log_ppp_warn("radius: failed to get interface statistics\n"); - else { - rpd->acct_rx_packets_i = stats.rx_packets; - rpd->acct_tx_packets_i = stats.tx_packets; - rpd->acct_rx_bytes_i = stats.rx_bytes; - rpd->acct_tx_bytes_i = stats.tx_bytes; - } - if (!rpd->acct_req) rpd->acct_req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ses->username); diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c index 5f5d0ba4..67c18e6d 100644 --- a/accel-pppd/radius/radius.c +++ b/accel-pppd/radius/radius.c @@ -235,19 +235,18 @@ static void session_timeout(struct triton_timer_t *t) static void idle_timeout(struct triton_timer_t *t) { struct radius_pd_t *rpd = container_of(t, typeof(*rpd), idle_timeout); - struct rtnl_link_stats stats; + time_t tt; if (rpd->ses->stop_time) return; - rad_read_stats(rpd, &stats); + time(&tt); - if (stats.rx_packets == rpd->acct_rx_packets && stats.tx_packets == rpd->acct_tx_packets) { + ap_session_read_stats(rpd->ses, NULL); + + if (tt - rpd->ses->idle_time > t->period / 1000) { log_ppp_msg("radius: idle timed out\n"); ap_session_terminate(rpd->ses, TERM_IDLE_TIMEOUT, 0); - } else { - rpd->acct_rx_packets = stats.rx_packets; - rpd->acct_tx_packets = stats.tx_packets; } } diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h index 8a4d27a9..4a17202f 100644 --- a/accel-pppd/radius/radius_p.h +++ b/accel-pppd/radius/radius_p.h @@ -25,17 +25,6 @@ struct radius_pd_t struct rad_req_t *acct_req; struct triton_timer_t acct_interim_timer; - uint32_t acct_rx_bytes; - uint32_t acct_tx_bytes; - uint32_t acct_rx_packets; - uint32_t acct_tx_packets; - uint32_t acct_input_gigawords; - uint32_t acct_output_gigawords; - uint32_t acct_rx_packets_i; - uint32_t acct_tx_packets_i; - uint32_t acct_rx_bytes_i; - uint32_t acct_tx_bytes_i; - struct triton_timer_t session_timeout; struct triton_timer_t idle_timeout; diff --git a/accel-pppd/session.c b/accel-pppd/session.c index 0ca115c3..41c5d693 100644 --- a/accel-pppd/session.c +++ b/accel-pppd/session.c @@ -18,6 +18,7 @@ #include "events.h" #include "ap_session.h" #include "backup.h" +#include "iputils.h" #include "spinlock.h" #include "mempool.h" #include "memdebug.h" @@ -53,6 +54,7 @@ void __export ap_session_init(struct ap_session *ses) int __export ap_session_starting(struct ap_session *ses) { struct ifreq ifr; + struct rtnl_link_stats stats; if (ses->ifindex == -1) { memset(&ifr, 0, sizeof(ifr)); @@ -64,9 +66,19 @@ int __export ap_session_starting(struct ap_session *ses) } ses->ifindex = ifr.ifr_ifindex; } + + if (iplink_get_stats(ses->ifindex, &stats)) + log_ppp_warn("failed to get interface statistics\n"); + else { + ses->acct_rx_packets_i = stats.rx_packets; + ses->acct_tx_packets_i = stats.tx_packets; + ses->acct_rx_bytes_i = stats.rx_bytes; + ses->acct_tx_bytes_i = stats.tx_bytes; + } if (ses->state != AP_STATE_RESTORE) { ses->start_time = time(NULL); + ses->idle_time = ses->start_time; generate_sessionid(ses); ses->state = AP_STATE_STARTING; @@ -215,6 +227,40 @@ static void generate_sessionid(struct ap_session *ses) sprintf(ses->sessionid, "%016llx", sid); } +int __export ap_session_read_stats(struct ap_session *ses, struct rtnl_link_stats *stats) +{ + struct rtnl_link_stats lstats; + time_t t; + + if (!stats) + stats = &lstats; + + time(&t); + + if (iplink_get_stats(ses->ifindex, stats)) { + log_ppp_warn("failed to get interface statistics\n"); + return -1; + } + + stats->rx_packets -= ses->acct_rx_packets_i; + stats->tx_packets -= ses->acct_tx_packets_i; + stats->rx_bytes -= ses->acct_rx_bytes_i; + stats->tx_bytes -= ses->acct_tx_bytes_i; + + if (stats->rx_bytes != ses->acct_rx_bytes || stats->tx_bytes != ses->acct_tx_bytes) + time(&ses->idle_time); + + if (stats->rx_bytes < ses->acct_rx_bytes) + ses->acct_input_gigawords++; + ses->acct_rx_bytes = stats->rx_bytes; + + if (stats->tx_bytes < ses->acct_tx_bytes) + ses->acct_output_gigawords++; + ses->acct_tx_bytes = stats->tx_bytes; + + return 0; +} + static void save_seq(void) { FILE *f; |