diff options
author | James Yonan <james@openvpn.net> | 2011-10-18 08:12:51 +0000 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2011-12-14 17:03:24 +0100 |
commit | ffea644ce62a67ea06e375c17277cea4e9cb9873 (patch) | |
tree | f9d897b7b3b6d54474d846de9a54ffc1b1c7cc60 | |
parent | 359adbf136e07011ad6733c3ba679b2d5cc47fdc (diff) | |
download | openvpn-ffea644ce62a67ea06e375c17277cea4e9cb9873.tar.gz openvpn-ffea644ce62a67ea06e375c17277cea4e9cb9873.tar.xz openvpn-ffea644ce62a67ea06e375c17277cea4e9cb9873.zip |
Added "memstats" option to maintain real-time operating stats
in a memory-mapped file.
Version 2.1.16
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@7653 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | error.c | 5 | ||||
-rw-r--r-- | forward.c | 9 | ||||
-rw-r--r-- | init.c | 22 | ||||
-rw-r--r-- | mstats.c | 116 | ||||
-rw-r--r-- | mstats.h | 51 | ||||
-rw-r--r-- | multi.c | 12 | ||||
-rw-r--r-- | options.c | 10 | ||||
-rw-r--r-- | options.h | 4 | ||||
-rw-r--r-- | syshead.h | 7 |
10 files changed, 237 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 075270f..a47c0c1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -110,6 +110,7 @@ openvpn_SOURCES = \ misc.c misc.h \ mroute.c mroute.h \ mss.c mss.h \ + mstats.c mstats.h \ mtcp.c mtcp.h \ mtu.c mtu.h \ mudp.c mudp.h \ @@ -35,6 +35,7 @@ #include "status.h" #include "integer.h" #include "ps.h" +#include "mstats.h" #ifdef USE_CRYPTO #ifdef USE_OPENSSL @@ -679,6 +680,10 @@ openvpn_exit (const int status) port_share_abort (port_share); #endif +#ifdef ENABLE_MEMSTATS + mstats_close(); +#endif + #ifdef ABORT_ON_ERROR if (status == OPENVPN_EXIT_STATUS_ERROR) abort (); @@ -39,6 +39,7 @@ #include "forward-inline.h" #include "occ-inline.h" #include "ping-inline.h" +#include "mstats.h" counter_type link_read_bytes_global; /* GLOBAL */ counter_type link_write_bytes_global; /* GLOBAL */ @@ -738,6 +739,10 @@ process_incoming_link (struct context *c) { c->c2.link_read_bytes += c->c2.buf.len; link_read_bytes_global += c->c2.buf.len; +#ifdef ENABLE_MEMSTATS + if (mmap_stats) + mmap_stats->link_read_bytes = link_read_bytes_global; +#endif c->c2.original_recv_size = c->c2.buf.len; #ifdef ENABLE_MANAGEMENT if (management) @@ -1137,6 +1142,10 @@ process_outgoing_link (struct context *c) c->c2.max_send_size_local = max_int (size, c->c2.max_send_size_local); c->c2.link_write_bytes += size; link_write_bytes_global += size; +#ifdef ENABLE_MEMSTATS + if (mmap_stats) + mmap_stats->link_write_bytes = link_write_bytes_global; +#endif #ifdef ENABLE_MANAGEMENT if (management) { @@ -36,6 +36,7 @@ #include "ps.h" #include "lladdr.h" #include "ping.h" +#include "mstats.h" #include "memdbg.h" @@ -815,6 +816,22 @@ init_static (void) } #endif +#ifdef MSTATS_TEST + { + int i; + mstats_open("/dev/shm/mstats.dat"); + for (i = 0; i < 30; ++i) + { + mmap_stats->n_clients += 1; + mmap_stats->link_write_bytes += 8; + mmap_stats->link_read_bytes += 16; + sleep(1); + } + mstats_close(); + return false; + } +#endif + return true; } @@ -1014,6 +1031,11 @@ do_uid_gid_chroot (struct context *c, bool no_delay) msg (M_INFO, "NOTE: UID/GID downgrade %s", why_not); } +#ifdef ENABLE_MEMSTATS + if (c->options.memstats_fn) + mstats_open(c->options.memstats_fn); +#endif + #ifdef HAVE_SETCON /* Apply a SELinux context in order to restrict what OpenVPN can do * to _only_ what it is supposed to do after initialization is complete diff --git a/mstats.c b/mstats.c new file mode 100644 index 0000000..2f29d94 --- /dev/null +++ b/mstats.c @@ -0,0 +1,116 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2002-2011 OpenVPN Technologies, Inc. <sales@openvpn.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Maintain usage stats in a memory-mapped file + */ + +#include "syshead.h" + +#if defined(ENABLE_MEMSTATS) + +#include <sys/mman.h> + +#include "error.h" +#include "misc.h" +#include "mstats.h" + +#include "memdbg.h" + +volatile struct mmap_stats *mmap_stats = NULL; /* GLOBAL */ +static char mmap_fn[128]; + +void +mstats_open(const char *fn) +{ + void *data; + ssize_t stat; + int fd; + struct mmap_stats ms; + + if (mmap_stats) /* already called? */ + return; + + /* verify that filename is not too long */ + if (strlen(fn) >= sizeof(mmap_fn)) + msg (M_FATAL, "mstats_open: filename too long"); + + /* create file that will be memory mapped */ + fd = open (fn, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) + { + msg (M_ERR, "mstats_open: cannot open: %s", fn); + return; + } + + /* set the file to the correct size to contain a + struct mmap_stats, and zero it */ + CLEAR(ms); + ms.state = MSTATS_ACTIVE; + stat = write(fd, &ms, sizeof(ms)); + if (stat != sizeof(ms)) + { + msg (M_ERR, "mstats_open: write error: %s", fn); + close(fd); + return; + } + + /* mmap the file */ + data = mmap(NULL, sizeof(struct mmap_stats), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) + { + msg (M_ERR, "mstats_open: write error: %s", fn); + close(fd); + return; + } + + /* close the fd (mmap now controls the file) */ + if (close(fd)) + { + msg (M_ERR, "mstats_open: close error: %s", fn); + } + + /* save filename so we can delete it later */ + strcpy(mmap_fn, fn); + + /* save a global pointer to memory-mapped region */ + mmap_stats = (struct mmap_stats *)data; + + msg (M_INFO, "memstats data will be written to %s", fn); +} + +void +mstats_close(void) +{ + if (mmap_stats) + { + mmap_stats->state = MSTATS_EXPIRED; + if (munmap((void *)mmap_stats, sizeof(struct mmap_stats))) + msg (M_WARN | M_ERRNO, "mstats_close: munmap error"); + delete_file(mmap_fn); + mmap_stats = NULL; + } +} + +#endif diff --git a/mstats.h b/mstats.h new file mode 100644 index 0000000..dab05fe --- /dev/null +++ b/mstats.h @@ -0,0 +1,51 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2002-2011 OpenVPN Technologies, Inc. <sales@openvpn.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Maintain usage stats in a memory-mapped file + */ + +#if !defined(OPENVPN_MEMSTATS_H) && defined(ENABLE_MEMSTATS) +#define OPENVPN_MEMSTATS_H + +#include "basic.h" + +/* this struct is mapped to the file */ +struct mmap_stats { + counter_type link_read_bytes; /* counter_type can be assumed to be a uint64_t */ + counter_type link_write_bytes; + int n_clients; + +# define MSTATS_UNDEF 0 +# define MSTATS_ACTIVE 1 +# define MSTATS_EXPIRED 2 + int state; +}; + +extern volatile struct mmap_stats *mmap_stats; /* GLOBAL */ + +void mstats_open(const char *fn); +void mstats_close(void); + +#endif @@ -31,6 +31,7 @@ #include "misc.h" #include "otime.h" #include "gremlin.h" +#include "mstats.h" #include "memdbg.h" @@ -60,6 +61,15 @@ set_cc_config (struct multi_instance *mi, struct buffer_list *cc_config) } #endif +static inline void +update_mstat_n_clients(const int n_clients) +{ +#ifdef ENABLE_MEMSTATS + if (mmap_stats) + mmap_stats->n_clients = n_clients; +#endif +} + static bool learn_address_script (const struct multi_context *m, const struct multi_instance *mi, @@ -510,6 +520,7 @@ multi_close_instance (struct multi_context *m, /* adjust current client connection count */ m->n_clients += mi->n_clients_delta; + update_mstat_n_clients(m->n_clients); mi->n_clients_delta = 0; /* prevent dangling pointers */ @@ -1842,6 +1853,7 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi /* increment number of current authenticated clients */ ++m->n_clients; + update_mstat_n_clients(m->n_clients); --mi->n_clients_delta; #ifdef MANAGEMENT_DEF_AUTH @@ -299,6 +299,9 @@ static const char usage_message[] = " can be matched in policy routing and packetfilter rules.\n" #endif "--txqueuelen n : Set the tun/tap TX queue length to n (Linux only).\n" +#ifdef ENABLE_MEMSTATS + "--memstats file : Write live usage stats to memory mapped binary file.\n" +#endif "--mlock : Disable Paging -- ensures key material and tunnel\n" " data will never be written to disk.\n" "--up cmd : Shell cmd to execute after successful tun device open.\n" @@ -4602,6 +4605,13 @@ add_option (struct options *options, options->log = true; redirect_stdout_stderr (p[1], true); } +#ifdef ENABLE_MEMSTATS + else if (streq (p[0], "memstats") && p[1]) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->memstats_fn = p[1]; + } +#endif else if (streq (p[0], "mlock")) { VERIFY_PERMISSION (OPT_P_GENERAL); @@ -260,6 +260,10 @@ struct options int fragment; /* internal fragmentation size */ +#ifdef ENABLE_MEMSTATS + char *memstats_fn; +#endif + bool mlock; int keepalive_ping; /* a proxy for ping/ping-restart */ @@ -737,4 +737,11 @@ socket_defined (const socket_descriptor_t sd) #define LZO_VERSION_NUM "STUB" #endif +/* + * Enable --memstats option + */ +#ifdef TARGET_LINUX +#define ENABLE_MEMSTATS +#endif + #endif |