diff options
-rw-r--r-- | accel-pptpd/accel-pptp.conf.5 | 10 | ||||
-rw-r--r-- | accel-pptpd/auth/CMakeLists.txt | 4 | ||||
-rw-r--r-- | accel-pptpd/cli/std_cmd.c | 210 | ||||
-rw-r--r-- | accel-pptpd/cli/telnet.c | 8 | ||||
-rw-r--r-- | accel-pptpd/ctrl/l2tp/l2tp.c | 40 | ||||
-rw-r--r-- | accel-pptpd/ctrl/pppoe/pppoe.c | 40 | ||||
-rw-r--r-- | accel-pptpd/ctrl/pptp/pptp.c | 45 | ||||
l--------- | accel-pptpd/include/cli.h | 1 | ||||
-rw-r--r-- | accel-pptpd/ppp/ppp.c | 37 | ||||
-rw-r--r-- | accel-pptpd/ppp/ppp.h | 24 |
10 files changed, 387 insertions, 32 deletions
diff --git a/accel-pptpd/accel-pptp.conf.5 b/accel-pptpd/accel-pptp.conf.5 index 694e1ecb..6de19d44 100644 --- a/accel-pptpd/accel-pptp.conf.5 +++ b/accel-pptpd/accel-pptp.conf.5 @@ -222,6 +222,16 @@ Specifies secret to use in DM/CoA communication. .BI "acct-interim-interval=" n Specifies interval in seconds to send accounting information (may be overriden by radius Acct-Interim-Interval attribute) .TP +.BI "verbose=" n +If this option is given and +.B n +is greater of zero then radius module will produce verbose logging. +.TP +.BI "interim-verbose=" n +If this option is given and +.B n +is greater of zero then radius module will produce verbose logging of interim radius packets. +.TP .SH [log] .br Configuration of log and log_file modules. diff --git a/accel-pptpd/auth/CMakeLists.txt b/accel-pptpd/auth/CMakeLists.txt index 69b18b7b..808e7d84 100644 --- a/accel-pptpd/auth/CMakeLists.txt +++ b/accel-pptpd/auth/CMakeLists.txt @@ -3,6 +3,10 @@ ADD_LIBRARY(auth_chap_md5 SHARED auth_chap_md5.c) ADD_LIBRARY(auth_mschap_v1 SHARED auth_mschap_v1.c) ADD_LIBRARY(auth_mschap_v2 SHARED auth_mschap_v2.c) +TARGET_LINK_LIBRARIES(auth_chap_md5 crypto) +TARGET_LINK_LIBRARIES(auth_mschap_v1 crypto) +TARGET_LINK_LIBRARIES(auth_mschap_v2 crypto) + INSTALL(TARGETS auth_pap auth_chap_md5 auth_mschap_v1 auth_mschap_v2 LIBRARY DESTINATION usr/lib/accel-pptp ) diff --git a/accel-pptpd/cli/std_cmd.c b/accel-pptpd/cli/std_cmd.c index 2239bef3..491caf76 100644 --- a/accel-pptpd/cli/std_cmd.c +++ b/accel-pptpd/cli/std_cmd.c @@ -1,7 +1,11 @@ #include <stdio.h> +#include <time.h> +#include <string.h> #include "triton.h" +#include "ppp.h" #include "cli.h" +#include "utils.h" int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) { @@ -10,47 +14,63 @@ int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void * if (cli_send(client, "core:\r\n")) return CLI_CMD_FAILED; - sprintf(buf, "\tmempool_allocated: %u\r\n", triton_stat.mempool_allocated); + sprintf(buf, " mempool_allocated: %u\r\n", triton_stat.mempool_allocated); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\tmempool_available: %u\r\n", triton_stat.mempool_available); + sprintf(buf, " mempool_available: %u\r\n", triton_stat.mempool_available); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\tthread_count: %u\r\n", triton_stat.thread_count); + sprintf(buf, " thread_count: %u\r\n", triton_stat.thread_count); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\tthread_active: %u\r\n", triton_stat.thread_active); + sprintf(buf, " thread_active: %u\r\n", triton_stat.thread_active); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\tcontext_count: %u\r\n", triton_stat.context_count); + sprintf(buf, " context_count: %u\r\n", triton_stat.context_count); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\tcontext_sleeping: %u\r\n", triton_stat.context_sleeping); + sprintf(buf, " context_sleeping: %u\r\n", triton_stat.context_sleeping); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\tcontext_pending: %u\r\n", triton_stat.context_pending); + sprintf(buf, " context_pending: %u\r\n", triton_stat.context_pending); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\tmd_handler_count: %u\r\n", triton_stat.md_handler_count); + sprintf(buf, " md_handler_count: %u\r\n", triton_stat.md_handler_count); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\tmd_handler_pending: %u\r\n", triton_stat.md_handler_pending); + sprintf(buf, " md_handler_pending: %u\r\n", triton_stat.md_handler_pending); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\ttimer_count: %u\r\n", triton_stat.timer_count); + sprintf(buf, " timer_count: %u\r\n", triton_stat.timer_count); if (cli_send(client, buf)) return CLI_CMD_FAILED; - sprintf(buf, "\ttimer_pending: %u\r\n", triton_stat.timer_pending); + sprintf(buf, " timer_pending: %u\r\n", triton_stat.timer_pending); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + +//=========== + if (cli_send(client, "ppp:\r\n")) + return CLI_CMD_FAILED; + + sprintf(buf, " staring: %u\r\n", ppp_stat.starting); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + + sprintf(buf, " active: %u\r\n", ppp_stat.active); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + + sprintf(buf, " finishing: %u\r\n", ppp_stat.finishing); if (cli_send(client, buf)) return CLI_CMD_FAILED; @@ -65,6 +85,16 @@ int show_stat_help(char * const *fields, int fields_cnt, void *client) return 0; } +const char *show_stat_hdr[] = {"show","stat"}; +static struct cli_simple_cmd_t show_stat_cmd = { + .hdr_len = 2, + .hdr = show_stat_hdr, + .exec = show_stat_exec, + .help = show_stat_help, +}; + +//============================= + int exit_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) { return CLI_CMD_EXIT; @@ -78,14 +108,6 @@ int exit_help(char * const *fields, int fields_cnt, void *client) return 0; } -const char *show_stat_hdr[] = {"show","stat"}; -static struct cli_simple_cmd_t show_stat_cmd = { - .hdr_len = 2, - .hdr = show_stat_hdr, - .exec = show_stat_exec, - .help = show_stat_help, -}; - const char *exit_hdr[] = {"exit"}; static struct cli_simple_cmd_t exit_cmd = { .hdr_len = 1, @@ -94,9 +116,159 @@ static struct cli_simple_cmd_t exit_cmd = { .help = exit_help, }; +//============================= + +int show_ses_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) +{ + char buf[128]; + char ip_str[17]; + char *state_str; + char time_str[12]; + time_t uptime; + int day,hour,min,sec; + struct ppp_t *ppp; + + if (cli_send(client, "interface: username: address: type: state: uptime:\r\n")) + return CLI_CMD_FAILED; + + if (cli_send(client, "------------------------------------------------------------------------\r\n")) + return CLI_CMD_FAILED; + + pthread_rwlock_rdlock(&ppp_lock); + list_for_each_entry(ppp, &ppp_list, entry) { + u_inet_ntoa(ppp->peer_ipaddr, ip_str); + + switch (ppp->state) { + case PPP_STATE_STARTING: + state_str = "start"; + break; + case PPP_STATE_ACTIVE: + state_str = "active"; + break; + case PPP_STATE_FINISHING: + state_str = "finish"; + break; + default: + state_str = "unk"; + } + + if (ppp->stop_time) + uptime = ppp->stop_time - ppp->start_time; + else { + time(&uptime); + uptime -= ppp->start_time; + } + day = uptime/ (24*60*60); uptime %= (24*60*60); + hour = uptime / (60*60); uptime %= (60*60); + min = uptime / 60; + sec = uptime % 60; + if (day) + sprintf(time_str, "%i.%02i:%02i:%02i", day, hour, min, sec); + else + sprintf(time_str, "%02i:%02i:%02i", hour, min, sec); + + sprintf(buf, "%9s %15s %16s %6s %6s %10s\r\n", ppp->ifname, ppp->username ? ppp->username : "", ip_str, ppp->ctrl->name, state_str, time_str); + if (cli_send(client, buf)) { + pthread_rwlock_unlock(&ppp_lock); + return CLI_CMD_FAILED; + } + } + pthread_rwlock_unlock(&ppp_lock); + + return CLI_CMD_OK; +} + +int show_ses_help(char * const *fields, int fields_cnt, void *client) +{ + if (cli_send(client, "show sessions - shows all sessions\r\n")) + return -1; + + return 0; +} + +const char *show_ses_hdr[] = {"show", "sessions"}; +static struct cli_simple_cmd_t show_ses_cmd = { + .hdr_len = 2, + .hdr = show_ses_hdr, + .exec = show_ses_exec, + .help = show_ses_help, +}; + +//============================= + +static void ppp_terminate_soft(struct ppp_t *ppp) +{ + ppp_terminate(ppp, 0, TERM_ADMIN_RESET); +} + +static void ppp_terminate_hard(struct ppp_t *ppp) +{ + ppp_terminate(ppp, 1, TERM_ADMIN_RESET); +} + +int terminate_help(char * const *fields, int fields_cnt, void *client); +int terminate_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) +{ + struct ppp_t *ppp; + int hard = 0; + + if (fields_cnt == 1) + return terminate_help(NULL, 0, client); + + if (fields_cnt == 3) { + if (!strcmp(fields[2], "hard")) + hard = 1; + else if (strcmp(fields[2], "soft")) + return terminate_help(NULL, 0, client); + } + + pthread_rwlock_rdlock(&ppp_lock); + if (strcmp(fields[1], "all")) { + list_for_each_entry(ppp, &ppp_list, entry) { + if (strcmp(ppp->ifname, fields[1])) + continue; + if (hard) + triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp); + else + triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp); + break; + } + } else { + list_for_each_entry(ppp, &ppp_list, entry) { + if (hard) + triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp); + else + triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp); + } + } + pthread_rwlock_unlock(&ppp_lock); + + return CLI_CMD_OK; +} + +int terminate_help(char * const *fields, int fields_cnt, void *client) +{ + if (cli_send(client, "terminate <interface> [soft|hard]- terminate session\r\n")) + return -1; + + if (cli_send(client, "terminate all [soft|hard]- terminate all session\r\n")) + return -1; + + return 0; +} + +const char *terminate_hdr[] = {"terminate"}; +static struct cli_simple_cmd_t terminate_cmd = { + .hdr_len = 1, + .hdr = terminate_hdr, + .exec = terminate_exec, + .help = terminate_help, +}; static void __init init(void) { cli_register_simple_cmd(&show_stat_cmd); + cli_register_simple_cmd(&show_ses_cmd); + cli_register_simple_cmd(&terminate_cmd); cli_register_simple_cmd(&exit_cmd); } diff --git a/accel-pptpd/cli/telnet.c b/accel-pptpd/cli/telnet.c index 30ec02b2..377f5f04 100644 --- a/accel-pptpd/cli/telnet.c +++ b/accel-pptpd/cli/telnet.c @@ -121,14 +121,14 @@ static int send_prompt(struct client_t *cln) return telnet_send(cln, conf_prompt, strlen(conf_prompt)); } -static void print_buf(const uint8_t *buf, int size) +/*static void print_buf(const uint8_t *buf, int size) { int i; for (i = 0; i < size; i++) log_debug("%x ", buf[i]); log_debug("\n"); -} +}*/ static int process_data(struct client_t *cln) { @@ -209,8 +209,8 @@ static int cln_read(struct triton_md_handler_t *h) log_error("cli: read: %s\n", strerror(errno)); return 0; } - log_debug("cli: read(%i): ", n); - print_buf(cln->recv_buf + cln->recv_pos, n); + /*log_debug("cli: read(%i): ", n); + print_buf(cln->recv_buf + cln->recv_pos, n);*/ cln->recv_pos += n; if (process_data(cln)) return -1; diff --git a/accel-pptpd/ctrl/l2tp/l2tp.c b/accel-pptpd/ctrl/l2tp/l2tp.c index c9af9126..899ac6ad 100644 --- a/accel-pptpd/ctrl/l2tp/l2tp.c +++ b/accel-pptpd/ctrl/l2tp/l2tp.c @@ -22,6 +22,7 @@ #include "events.h" #include "utils.h" #include "iprange.h" +#include "cli.h" #include "memdebug.h" @@ -49,6 +50,9 @@ int conf_retransmit = 5; int conf_hello_interval = 60; const char *conf_host_name = "accel-pptp"; +static uint32_t stat_active; +static uint32_t stat_starting; + struct l2tp_serv_t { struct triton_context_t ctx; @@ -115,9 +119,11 @@ static void l2tp_disconnect(struct l2tp_conn_t *conn) triton_timer_del(&conn->hello_timer); if (conn->state == STATE_PPP) { + __sync_fetch_and_sub(&stat_active, 1); conn->state = STATE_FIN; ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); - } + } else if (conn->state != STATE_FIN) + __sync_fetch_and_sub(&stat_starting, 1); pthread_mutex_lock(&l2tp_lock); l2tp_conn[conn->tid] = NULL; @@ -324,6 +330,8 @@ static int l2tp_tunnel_alloc(struct l2tp_serv_t *serv, struct l2tp_packet_t *pac triton_context_call(&conn->ctx, (triton_event_func)l2tp_send_SCCRP, conn); + __sync_fetch_and_add(&stat_starting, 1); + return 0; out_err: @@ -384,6 +392,9 @@ static int l2tp_connect(struct l2tp_conn_t *conn) if (establish_ppp(&conn->ppp)) return -1; + __sync_fetch_and_sub(&stat_starting, 1); + __sync_fetch_and_add(&stat_active, 1); + conn->state = STATE_PPP; return 0; @@ -1049,6 +1060,31 @@ static void start_udp_server(void) triton_context_wakeup(&udp_serv.ctx); } +static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) +{ + char buf[128]; + + if (cli_send(client, "l2tp:\r\n")) + return CLI_CMD_FAILED; + + sprintf(buf, " starting: %u\r\n", stat_starting); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + + sprintf(buf, " active: %u\r\n", stat_active); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + + return CLI_CMD_OK; +} + +static const char *show_stat_hdr[] = {"show","stat"}; +static struct cli_simple_cmd_t show_stat_cmd = { + .hdr_len = 2, + .hdr = show_stat_hdr, + .exec = show_stat_exec, +}; + static void __init l2tp_init(void) { char *opt; @@ -1083,5 +1119,7 @@ static void __init l2tp_init(void) conf_host_name = opt; start_udp_server(); + + cli_register_simple_cmd(&show_stat_cmd); } diff --git a/accel-pptpd/ctrl/pppoe/pppoe.c b/accel-pptpd/ctrl/pppoe/pppoe.c index cba26319..ef661bc4 100644 --- a/accel-pptpd/ctrl/pppoe/pppoe.c +++ b/accel-pptpd/ctrl/pppoe/pppoe.c @@ -19,6 +19,7 @@ #include "log.h" #include "ppp.h" #include "mempool.h" +#include "cli.h" #include "pppoe.h" @@ -74,6 +75,9 @@ static int conf_pado_delay = 0; static mempool_t conn_pool; static mempool_t pado_pool; +static uint32_t stat_active; +static uint32_t stat_delayed_pado; + #define SECRET_SIZE 16 static uint8_t *secret; @@ -84,6 +88,7 @@ static void pppoe_send_PADT(struct pppoe_conn_t *conn); static void disconnect(struct pppoe_conn_t *conn) { if (conn->ppp_started) { + __sync_fetch_and_sub(&stat_active, 1); conn->ppp_started = 0; ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); } @@ -92,6 +97,7 @@ static void disconnect(struct pppoe_conn_t *conn) close(conn->disc_sock); + triton_event_fire(EV_CTRL_FINISHED, &conn->ppp); if (conf_verbose) @@ -126,6 +132,7 @@ static void ppp_finished(struct ppp_t *ppp) log_ppp_debug("pppoe: ppp finished\n"); if (conn->ppp_started) { + __sync_fetch_and_sub(&stat_active, 1); conn->ppp_started = 0; disconnect(conn); } @@ -531,6 +538,7 @@ static void pado_timer(struct triton_timer_t *t) pppoe_send_PADO(pado->serv, pado->addr, pado->host_uniq, pado->relay_sid, pado->service_name); + __sync_fetch_and_sub(&stat_delayed_pado, 1); list_del(&pado->entry); if (pado->host_uniq) @@ -632,6 +640,7 @@ static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size) triton_timer_add(&serv->ctx, &pado->timer, 0); list_add_tail(&pado->entry, &serv->pado_list); + __sync_fetch_and_add(&stat_delayed_pado, 1); } else pppoe_send_PADO(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag); } @@ -731,8 +740,10 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size) pppoe_send_PADS(conn); if (connect_channel(conn)) disconnect(conn); - else + else { + __sync_fetch_and_add(&stat_active, 1); conn->ppp_started = 1; + } } } @@ -929,6 +940,31 @@ out_err: _free(serv); } +static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) +{ + char buf[128]; + + if (cli_send(client, "pppoe:\r\n")) + return CLI_CMD_FAILED; + + sprintf(buf, " active: %u\r\n", stat_active); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + + sprintf(buf, " delayed PADO: %u\r\n", stat_delayed_pado); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + + return CLI_CMD_OK; +} + +static const char *show_stat_hdr[] = {"show","stat"}; +static struct cli_simple_cmd_t show_stat_cmd = { + .hdr_len = 2, + .hdr = show_stat_hdr, + .exec = show_stat_exec, +}; + static int init_secret(void) { int fd; @@ -985,5 +1021,7 @@ static void __init pppoe_init(void) conf_pado_delay = atoi(opt->val); } } + + cli_register_simple_cmd(&show_stat_cmd); } diff --git a/accel-pptpd/ctrl/pptp/pptp.c b/accel-pptpd/ctrl/pptp/pptp.c index 4a705d53..433292f6 100644 --- a/accel-pptpd/ctrl/pptp/pptp.c +++ b/accel-pptpd/ctrl/pptp/pptp.c @@ -21,6 +21,7 @@ #include "mempool.h" #include "iprange.h" #include "utils.h" +#include "cli.h" #include "memdebug.h" @@ -58,6 +59,9 @@ static int conf_verbose = 0; static mempool_t conn_pool; +static uint32_t stat_starting; +static uint32_t 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 *); @@ -78,9 +82,11 @@ static void disconnect(struct pptp_conn_t *conn) triton_timer_del(&conn->echo_timer); if (conn->state == STATE_PPP) { + __sync_fetch_and_sub(&stat_active, 1); conn->state = STATE_CLOSE; ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); - } + } else if (conn->state != STATE_CLOSE) + __sync_fetch_and_sub(&stat_starting, 1); triton_event_fire(EV_CTRL_FINISHED, &conn->ppp); @@ -323,6 +329,8 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) return -1; } conn->state = STATE_PPP; + __sync_fetch_and_sub(&stat_starting, 1); + __sync_fetch_and_add(&stat_active, 1); if (conn->timeout_timer.tpd) triton_timer_del(&conn->timeout_timer); @@ -359,9 +367,11 @@ static int pptp_call_clear_rqst(struct pptp_conn_t *conn) log_ppp_info("recv [PPTP Call-Clear-Request <Call-ID %x>]\n", ntohs(rqst->call_id)); if (conn->state == STATE_PPP) { + __sync_fetch_and_sub(&stat_active, 1); conn->state = STATE_CLOSE; ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); - } + } else + __sync_fetch_and_sub(&stat_starting, 1); return send_pptp_call_disconnect_notify(conn, 4); } @@ -540,6 +550,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_fetch_and_sub(&stat_active, 1); conn->state = STATE_CLOSE; ppp_terminate(&conn->ppp, TERM_ADMIN_RESET, 1); if (send_pptp_call_disconnect_notify(conn, 3)) { @@ -569,6 +580,7 @@ static void ppp_finished(struct ppp_t *ppp) if (conn->state != STATE_CLOSE) { log_ppp_debug("pptp: ppp finished\n"); conn->state = STATE_CLOSE; + __sync_fetch_and_sub(&stat_active, 1); if (send_pptp_call_disconnect_notify(conn, 3)) triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); @@ -655,6 +667,8 @@ static int pptp_connect(struct triton_md_handler_t *h) triton_context_wakeup(&conn->ctx); triton_event_fire(EV_CTRL_STARTING, &conn->ppp); + + __sync_fetch_and_add(&stat_starting, 1); } return 0; } @@ -672,6 +686,31 @@ static struct pptp_serv_t serv= .ctx.close=pptp_serv_close, }; +static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) +{ + char buf[128]; + + if (cli_send(client, "pptp:\r\n")) + return CLI_CMD_FAILED; + + sprintf(buf, " starting: %u\r\n", stat_starting); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + + sprintf(buf, " active: %u\r\n", stat_active); + if (cli_send(client, buf)) + return CLI_CMD_FAILED; + + return CLI_CMD_OK; +} + +static const char *show_stat_hdr[] = {"show","stat"}; +static struct cli_simple_cmd_t show_stat_cmd = { + .hdr_len = 2, + .hdr = show_stat_hdr, + .exec = show_stat_exec, +}; + static void __init pptp_init(void) { struct sockaddr_in addr; @@ -732,5 +771,7 @@ static void __init pptp_init(void) triton_md_register_handler(&serv.ctx, &serv.hnd); triton_md_enable_handler(&serv.hnd, MD_MODE_READ); triton_context_wakeup(&serv.ctx); + + cli_register_simple_cmd(&show_stat_cmd); } diff --git a/accel-pptpd/include/cli.h b/accel-pptpd/include/cli.h new file mode 120000 index 00000000..b0f49023 --- /dev/null +++ b/accel-pptpd/include/cli.h @@ -0,0 +1 @@ +../cli/cli.h
\ No newline at end of file diff --git a/accel-pptpd/ppp/ppp.c b/accel-pptpd/ppp/ppp.c index 4cb5e163..5b1dd7cd 100644 --- a/accel-pptpd/ppp/ppp.c +++ b/accel-pptpd/ppp/ppp.c @@ -24,12 +24,17 @@ int __export conf_ppp_verbose; +pthread_rwlock_t __export ppp_lock; +__export LIST_HEAD(ppp_list); + static LIST_HEAD(layers); int __export sock_fd; static spinlock_t seq_lock = SPINLOCK_INITIALIZER; static uint64_t seq; +struct ppp_stat_t ppp_stat; + struct layer_node_t { struct list_head entry; @@ -146,6 +151,13 @@ int __export establish_ppp(struct ppp_t *ppp) triton_md_enable_handler(&ppp->chan_hnd, MD_MODE_READ); triton_md_enable_handler(&ppp->unit_hnd, MD_MODE_READ); + ppp->state = PPP_STATE_STARTING; + __sync_fetch_and_add(&ppp_stat.starting, 1); + + pthread_rwlock_wrlock(&ppp_lock); + list_add_tail(&ppp->entry, &ppp_list); + pthread_rwlock_unlock(&ppp_lock); + log_ppp_debug("ppp established\n"); triton_event_fire(EV_PPP_STARTING, ppp); @@ -166,6 +178,22 @@ exit_close_chan: static void destablish_ppp(struct ppp_t *ppp) { + pthread_rwlock_wrlock(&ppp_lock); + list_del(&ppp->entry); + pthread_rwlock_unlock(&ppp_lock); + + switch (ppp->state) { + case PPP_STATE_ACTIVE: + __sync_fetch_and_sub(&ppp_stat.active, 1); + break; + case PPP_STATE_STARTING: + __sync_fetch_and_sub(&ppp_stat.starting, 1); + break; + case PPP_STATE_FINISHING: + __sync_fetch_and_sub(&ppp_stat.finishing, 1); + break; + } + triton_md_unregister_handler(&ppp->chan_hnd); triton_md_unregister_handler(&ppp->unit_hnd); @@ -343,6 +371,9 @@ void __export ppp_layer_started(struct ppp_t *ppp, struct ppp_layer_data_t *d) if (!d->started) return; if (n->entry.next == &ppp->layers) { + ppp->state = PPP_STATE_ACTIVE; + __sync_fetch_and_sub(&ppp_stat.starting, 1); + __sync_fetch_and_add(&ppp_stat.active, 1); ppp->ctrl->started(ppp); triton_event_fire(EV_PPP_STARTED, ppp); } else { @@ -392,6 +423,12 @@ void __export ppp_terminate(struct ppp_t *ppp, int cause, int hard) } ppp->terminating = 1; + if (ppp->state == PPP_STATE_ACTIVE) + __sync_fetch_and_sub(&ppp_stat.active, 1); + else + __sync_fetch_and_sub(&ppp_stat.starting, 1); + __sync_fetch_and_add(&ppp_stat.finishing, 1); + ppp->state = PPP_STATE_FINISHING; log_ppp_debug("ppp_terminate\n"); diff --git a/accel-pptpd/ppp/ppp.h b/accel-pptpd/ppp/ppp.h index b36f0e42..f74351d4 100644 --- a/accel-pptpd/ppp/ppp.h +++ b/accel-pptpd/ppp/ppp.h @@ -4,6 +4,7 @@ #include <sys/types.h> #include <time.h> #include <netinet/in.h> +#include <pthread.h> #include "triton.h" #include "list.h" @@ -38,14 +39,13 @@ #define PPP_CBCP 0xc029 /* Callback Control Protocol */ #define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ -#define PPP_LAYER_LCP 1 -#define PPP_LAYER_AUTH 2 -#define PPP_LAYER_CCP 3 -#define PPP_LAYER_IPCP 4 - #define PPP_SESSIONID_LEN 16 #define PPP_IFNAME_LEN 10 +#define PPP_STATE_STARTING 1 +#define PPP_STATE_ACTIVE 2 +#define PPP_STATE_FINISHING 3 + #define TERM_USER_REQUEST 1 #define TERM_SESSION_TIMEOUT 2 #define TERM_ADMIN_RESET 3 @@ -75,6 +75,7 @@ struct ppp_pd_t struct ppp_t { + struct list_head entry; struct triton_md_handler_t chan_hnd; struct triton_md_handler_t unit_hnd; int fd; @@ -84,6 +85,7 @@ struct ppp_t int chan_idx; int unit_idx; + int state; char *chan_name; char ifname[PPP_IFNAME_LEN]; char sessionid[PPP_SESSIONID_LEN+1]; @@ -142,6 +144,13 @@ struct ppp_handler_t void (*recv_proto_rej)(struct ppp_handler_t *h); }; +struct ppp_stat_t +{ + uint32_t active; + uint32_t starting; + uint32_t finishing; +}; + struct ppp_t *alloc_ppp(void); void ppp_init(struct ppp_t *ppp); int establish_ppp(struct ppp_t *ppp); @@ -165,5 +174,10 @@ struct ppp_layer_data_t *ppp_find_layer_data(struct ppp_t *, struct ppp_layer_t extern int conf_ppp_verbose; +extern pthread_rwlock_t ppp_lock; +extern struct list_head ppp_list; + +extern struct ppp_stat_t ppp_stat; + extern int sock_fd; // internet socket for ioctls #endif |