summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <xeb@mail.ru>2012-09-05 23:24:51 +0400
committerKozlov Dmitry <xeb@mail.ru>2012-09-05 23:24:51 +0400
commit490f6384f6a54e388587329c0309a6602d5544e8 (patch)
tree5e70a9e4e7a8f6714a4694826ec68f293d1e55a8
parenta10ec0f4636cd559209659304709924daad96340 (diff)
downloadaccel-ppp-490f6384f6a54e388587329c0309a6602d5544e8.tar.gz
accel-ppp-490f6384f6a54e388587329c0309a6602d5544e8.zip
generalize interface statistics gathering
-rw-r--r--accel-pppd/CMakeLists.txt2
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c2
-rw-r--r--accel-pppd/extra/CMakeLists.txt3
-rw-r--r--accel-pppd/extra/pppd_compat.c33
-rw-r--r--accel-pppd/extra/sigchld.c3
-rw-r--r--accel-pppd/include/ap_session.h13
l---------accel-pppd/include/iplink.h1
l---------accel-pppd/include/iputils.h1
-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.c10
-rw-r--r--accel-pppd/radius/acct.c45
-rw-r--r--accel-pppd/radius/radius.c11
-rw-r--r--accel-pppd/radius/radius_p.h11
-rw-r--r--accel-pppd/session.c46
15 files changed, 90 insertions, 93 deletions
diff --git a/accel-pppd/CMakeLists.txt b/accel-pppd/CMakeLists.txt
index 92d7cfb..7b33e68 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 1ddec37..a871f0f 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 da1ac54..ea640b1 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 71934ab..59d052c 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 8f1a979..d6b0df5 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 95f0ea2..82654f8 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 7f0f09d..0000000
--- 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 0000000..c91d11c
--- /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 4b85afe..0ae4b04 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 f912434..f912434 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 1b47cad..2d1e195 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 ab71c45..81145cd 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 5f5d0ba..67c18e6 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 8a4d27a..4a17202 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 0ca115c..41c5d69 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;