Skip to content

Commit

Permalink
Added "memstats" option to maintain real-time operating stats
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jamesyonan authored and David Sommerseth committed Dec 14, 2011
1 parent 359adbf commit ffea644
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
5 changes: 5 additions & 0 deletions error.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "status.h"
#include "integer.h"
#include "ps.h"
#include "mstats.h"

#ifdef USE_CRYPTO
#ifdef USE_OPENSSL
Expand Down Expand Up @@ -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 ();
Expand Down
9 changes: 9 additions & 0 deletions forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down
22 changes: 22 additions & 0 deletions init.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "ps.h"
#include "lladdr.h"
#include "ping.h"
#include "mstats.h"

#include "memdbg.h"

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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
Expand Down
116 changes: 116 additions & 0 deletions mstats.c
Original file line number Diff line number Diff line change
@@ -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. <[email protected]>
*
* 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
51 changes: 51 additions & 0 deletions mstats.h
Original file line number Diff line number Diff line change
@@ -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. <[email protected]>
*
* 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
12 changes: 12 additions & 0 deletions multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "misc.h"
#include "otime.h"
#include "gremlin.h"
#include "mstats.h"

#include "memdbg.h"

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions options.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions options.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
7 changes: 7 additions & 0 deletions syshead.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit ffea644

Please sign in to comment.