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 \
#include "status.h"
#include "integer.h"
#include "ps.h"
+#include "mstats.h"
#ifdef USE_CRYPTO
#ifdef USE_OPENSSL
port_share_abort (port_share);
#endif
+#ifdef ENABLE_MEMSTATS
+ mstats_close();
+#endif
+
#ifdef ABORT_ON_ERROR
if (status == OPENVPN_EXIT_STATUS_ERROR)
abort ();
#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 */
{
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)
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)
{
#include "ps.h"
#include "lladdr.h"
#include "ping.h"
+#include "mstats.h"
#include "memdbg.h"
}
#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;
}
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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
#include "misc.h"
#include "otime.h"
#include "gremlin.h"
+#include "mstats.h"
#include "memdbg.h"
}
#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,
/* 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 */
/* increment number of current authenticated clients */
++m->n_clients;
+ update_mstat_n_clients(m->n_clients);
--mi->n_clients_delta;
#ifdef MANAGEMENT_DEF_AUTH
" 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"
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);
int fragment; /* internal fragmentation size */
+#ifdef ENABLE_MEMSTATS
+ char *memstats_fn;
+#endif
+
bool mlock;
int keepalive_ping; /* a proxy for ping/ping-restart */
#define LZO_VERSION_NUM "STUB"
#endif
+/*
+ * Enable --memstats option
+ */
+#ifdef TARGET_LINUX
+#define ENABLE_MEMSTATS
+#endif
+
#endif