Version 2.1.16
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@7653 e7ae566f-a301-0410-adde-c780ea21d3b5
... | ... |
@@ -35,6 +35,7 @@ |
35 | 35 |
#include "status.h" |
36 | 36 |
#include "integer.h" |
37 | 37 |
#include "ps.h" |
38 |
+#include "mstats.h" |
|
38 | 39 |
|
39 | 40 |
#ifdef USE_CRYPTO |
40 | 41 |
#ifdef USE_OPENSSL |
... | ... |
@@ -679,6 +680,10 @@ openvpn_exit (const int status) |
679 | 679 |
port_share_abort (port_share); |
680 | 680 |
#endif |
681 | 681 |
|
682 |
+#ifdef ENABLE_MEMSTATS |
|
683 |
+ mstats_close(); |
|
684 |
+#endif |
|
685 |
+ |
|
682 | 686 |
#ifdef ABORT_ON_ERROR |
683 | 687 |
if (status == OPENVPN_EXIT_STATUS_ERROR) |
684 | 688 |
abort (); |
... | ... |
@@ -39,6 +39,7 @@ |
39 | 39 |
#include "forward-inline.h" |
40 | 40 |
#include "occ-inline.h" |
41 | 41 |
#include "ping-inline.h" |
42 |
+#include "mstats.h" |
|
42 | 43 |
|
43 | 44 |
counter_type link_read_bytes_global; /* GLOBAL */ |
44 | 45 |
counter_type link_write_bytes_global; /* GLOBAL */ |
... | ... |
@@ -738,6 +739,10 @@ process_incoming_link (struct context *c) |
738 | 738 |
{ |
739 | 739 |
c->c2.link_read_bytes += c->c2.buf.len; |
740 | 740 |
link_read_bytes_global += c->c2.buf.len; |
741 |
+#ifdef ENABLE_MEMSTATS |
|
742 |
+ if (mmap_stats) |
|
743 |
+ mmap_stats->link_read_bytes = link_read_bytes_global; |
|
744 |
+#endif |
|
741 | 745 |
c->c2.original_recv_size = c->c2.buf.len; |
742 | 746 |
#ifdef ENABLE_MANAGEMENT |
743 | 747 |
if (management) |
... | ... |
@@ -1137,6 +1142,10 @@ process_outgoing_link (struct context *c) |
1137 | 1137 |
c->c2.max_send_size_local = max_int (size, c->c2.max_send_size_local); |
1138 | 1138 |
c->c2.link_write_bytes += size; |
1139 | 1139 |
link_write_bytes_global += size; |
1140 |
+#ifdef ENABLE_MEMSTATS |
|
1141 |
+ if (mmap_stats) |
|
1142 |
+ mmap_stats->link_write_bytes = link_write_bytes_global; |
|
1143 |
+#endif |
|
1140 | 1144 |
#ifdef ENABLE_MANAGEMENT |
1141 | 1145 |
if (management) |
1142 | 1146 |
{ |
... | ... |
@@ -36,6 +36,7 @@ |
36 | 36 |
#include "ps.h" |
37 | 37 |
#include "lladdr.h" |
38 | 38 |
#include "ping.h" |
39 |
+#include "mstats.h" |
|
39 | 40 |
|
40 | 41 |
#include "memdbg.h" |
41 | 42 |
|
... | ... |
@@ -815,6 +816,22 @@ init_static (void) |
815 | 815 |
} |
816 | 816 |
#endif |
817 | 817 |
|
818 |
+#ifdef MSTATS_TEST |
|
819 |
+ { |
|
820 |
+ int i; |
|
821 |
+ mstats_open("/dev/shm/mstats.dat"); |
|
822 |
+ for (i = 0; i < 30; ++i) |
|
823 |
+ { |
|
824 |
+ mmap_stats->n_clients += 1; |
|
825 |
+ mmap_stats->link_write_bytes += 8; |
|
826 |
+ mmap_stats->link_read_bytes += 16; |
|
827 |
+ sleep(1); |
|
828 |
+ } |
|
829 |
+ mstats_close(); |
|
830 |
+ return false; |
|
831 |
+ } |
|
832 |
+#endif |
|
833 |
+ |
|
818 | 834 |
return true; |
819 | 835 |
} |
820 | 836 |
|
... | ... |
@@ -1014,6 +1031,11 @@ do_uid_gid_chroot (struct context *c, bool no_delay) |
1014 | 1014 |
msg (M_INFO, "NOTE: UID/GID downgrade %s", why_not); |
1015 | 1015 |
} |
1016 | 1016 |
|
1017 |
+#ifdef ENABLE_MEMSTATS |
|
1018 |
+ if (c->options.memstats_fn) |
|
1019 |
+ mstats_open(c->options.memstats_fn); |
|
1020 |
+#endif |
|
1021 |
+ |
|
1017 | 1022 |
#ifdef HAVE_SETCON |
1018 | 1023 |
/* Apply a SELinux context in order to restrict what OpenVPN can do |
1019 | 1024 |
* to _only_ what it is supposed to do after initialization is complete |
1020 | 1025 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,116 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2011 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * |
|
9 |
+ * This program is free software; you can redistribute it and/or modify |
|
10 |
+ * it under the terms of the GNU General Public License version 2 |
|
11 |
+ * as published by the Free Software Foundation. |
|
12 |
+ * |
|
13 |
+ * This program is distributed in the hope that it will be useful, |
|
14 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 |
+ * GNU General Public License for more details. |
|
17 |
+ * |
|
18 |
+ * You should have received a copy of the GNU General Public License |
|
19 |
+ * along with this program (see the file COPYING included with this |
|
20 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
21 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
22 |
+ */ |
|
23 |
+ |
|
24 |
+/* |
|
25 |
+ * Maintain usage stats in a memory-mapped file |
|
26 |
+ */ |
|
27 |
+ |
|
28 |
+#include "syshead.h" |
|
29 |
+ |
|
30 |
+#if defined(ENABLE_MEMSTATS) |
|
31 |
+ |
|
32 |
+#include <sys/mman.h> |
|
33 |
+ |
|
34 |
+#include "error.h" |
|
35 |
+#include "misc.h" |
|
36 |
+#include "mstats.h" |
|
37 |
+ |
|
38 |
+#include "memdbg.h" |
|
39 |
+ |
|
40 |
+volatile struct mmap_stats *mmap_stats = NULL; /* GLOBAL */ |
|
41 |
+static char mmap_fn[128]; |
|
42 |
+ |
|
43 |
+void |
|
44 |
+mstats_open(const char *fn) |
|
45 |
+{ |
|
46 |
+ void *data; |
|
47 |
+ ssize_t stat; |
|
48 |
+ int fd; |
|
49 |
+ struct mmap_stats ms; |
|
50 |
+ |
|
51 |
+ if (mmap_stats) /* already called? */ |
|
52 |
+ return; |
|
53 |
+ |
|
54 |
+ /* verify that filename is not too long */ |
|
55 |
+ if (strlen(fn) >= sizeof(mmap_fn)) |
|
56 |
+ msg (M_FATAL, "mstats_open: filename too long"); |
|
57 |
+ |
|
58 |
+ /* create file that will be memory mapped */ |
|
59 |
+ fd = open (fn, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); |
|
60 |
+ if (fd < 0) |
|
61 |
+ { |
|
62 |
+ msg (M_ERR, "mstats_open: cannot open: %s", fn); |
|
63 |
+ return; |
|
64 |
+ } |
|
65 |
+ |
|
66 |
+ /* set the file to the correct size to contain a |
|
67 |
+ struct mmap_stats, and zero it */ |
|
68 |
+ CLEAR(ms); |
|
69 |
+ ms.state = MSTATS_ACTIVE; |
|
70 |
+ stat = write(fd, &ms, sizeof(ms)); |
|
71 |
+ if (stat != sizeof(ms)) |
|
72 |
+ { |
|
73 |
+ msg (M_ERR, "mstats_open: write error: %s", fn); |
|
74 |
+ close(fd); |
|
75 |
+ return; |
|
76 |
+ } |
|
77 |
+ |
|
78 |
+ /* mmap the file */ |
|
79 |
+ data = mmap(NULL, sizeof(struct mmap_stats), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); |
|
80 |
+ if (data == MAP_FAILED) |
|
81 |
+ { |
|
82 |
+ msg (M_ERR, "mstats_open: write error: %s", fn); |
|
83 |
+ close(fd); |
|
84 |
+ return; |
|
85 |
+ } |
|
86 |
+ |
|
87 |
+ /* close the fd (mmap now controls the file) */ |
|
88 |
+ if (close(fd)) |
|
89 |
+ { |
|
90 |
+ msg (M_ERR, "mstats_open: close error: %s", fn); |
|
91 |
+ } |
|
92 |
+ |
|
93 |
+ /* save filename so we can delete it later */ |
|
94 |
+ strcpy(mmap_fn, fn); |
|
95 |
+ |
|
96 |
+ /* save a global pointer to memory-mapped region */ |
|
97 |
+ mmap_stats = (struct mmap_stats *)data; |
|
98 |
+ |
|
99 |
+ msg (M_INFO, "memstats data will be written to %s", fn); |
|
100 |
+} |
|
101 |
+ |
|
102 |
+void |
|
103 |
+mstats_close(void) |
|
104 |
+{ |
|
105 |
+ if (mmap_stats) |
|
106 |
+ { |
|
107 |
+ mmap_stats->state = MSTATS_EXPIRED; |
|
108 |
+ if (munmap((void *)mmap_stats, sizeof(struct mmap_stats))) |
|
109 |
+ msg (M_WARN | M_ERRNO, "mstats_close: munmap error"); |
|
110 |
+ delete_file(mmap_fn); |
|
111 |
+ mmap_stats = NULL; |
|
112 |
+ } |
|
113 |
+} |
|
114 |
+ |
|
115 |
+#endif |
0 | 116 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,51 @@ |
0 |
+/* |
|
1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
3 |
+ * session authentication and key exchange, |
|
4 |
+ * packet encryption, packet authentication, and |
|
5 |
+ * packet compression. |
|
6 |
+ * |
|
7 |
+ * Copyright (C) 2002-2011 OpenVPN Technologies, Inc. <sales@openvpn.net> |
|
8 |
+ * |
|
9 |
+ * This program is free software; you can redistribute it and/or modify |
|
10 |
+ * it under the terms of the GNU General Public License version 2 |
|
11 |
+ * as published by the Free Software Foundation. |
|
12 |
+ * |
|
13 |
+ * This program is distributed in the hope that it will be useful, |
|
14 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 |
+ * GNU General Public License for more details. |
|
17 |
+ * |
|
18 |
+ * You should have received a copy of the GNU General Public License |
|
19 |
+ * along with this program (see the file COPYING included with this |
|
20 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
21 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
22 |
+ */ |
|
23 |
+ |
|
24 |
+/* |
|
25 |
+ * Maintain usage stats in a memory-mapped file |
|
26 |
+ */ |
|
27 |
+ |
|
28 |
+#if !defined(OPENVPN_MEMSTATS_H) && defined(ENABLE_MEMSTATS) |
|
29 |
+#define OPENVPN_MEMSTATS_H |
|
30 |
+ |
|
31 |
+#include "basic.h" |
|
32 |
+ |
|
33 |
+/* this struct is mapped to the file */ |
|
34 |
+struct mmap_stats { |
|
35 |
+ counter_type link_read_bytes; /* counter_type can be assumed to be a uint64_t */ |
|
36 |
+ counter_type link_write_bytes; |
|
37 |
+ int n_clients; |
|
38 |
+ |
|
39 |
+# define MSTATS_UNDEF 0 |
|
40 |
+# define MSTATS_ACTIVE 1 |
|
41 |
+# define MSTATS_EXPIRED 2 |
|
42 |
+ int state; |
|
43 |
+}; |
|
44 |
+ |
|
45 |
+extern volatile struct mmap_stats *mmap_stats; /* GLOBAL */ |
|
46 |
+ |
|
47 |
+void mstats_open(const char *fn); |
|
48 |
+void mstats_close(void); |
|
49 |
+ |
|
50 |
+#endif |
... | ... |
@@ -31,6 +31,7 @@ |
31 | 31 |
#include "misc.h" |
32 | 32 |
#include "otime.h" |
33 | 33 |
#include "gremlin.h" |
34 |
+#include "mstats.h" |
|
34 | 35 |
|
35 | 36 |
#include "memdbg.h" |
36 | 37 |
|
... | ... |
@@ -60,6 +61,15 @@ set_cc_config (struct multi_instance *mi, struct buffer_list *cc_config) |
60 | 60 |
} |
61 | 61 |
#endif |
62 | 62 |
|
63 |
+static inline void |
|
64 |
+update_mstat_n_clients(const int n_clients) |
|
65 |
+{ |
|
66 |
+#ifdef ENABLE_MEMSTATS |
|
67 |
+ if (mmap_stats) |
|
68 |
+ mmap_stats->n_clients = n_clients; |
|
69 |
+#endif |
|
70 |
+} |
|
71 |
+ |
|
63 | 72 |
static bool |
64 | 73 |
learn_address_script (const struct multi_context *m, |
65 | 74 |
const struct multi_instance *mi, |
... | ... |
@@ -510,6 +520,7 @@ multi_close_instance (struct multi_context *m, |
510 | 510 |
|
511 | 511 |
/* adjust current client connection count */ |
512 | 512 |
m->n_clients += mi->n_clients_delta; |
513 |
+ update_mstat_n_clients(m->n_clients); |
|
513 | 514 |
mi->n_clients_delta = 0; |
514 | 515 |
|
515 | 516 |
/* prevent dangling pointers */ |
... | ... |
@@ -1842,6 +1853,7 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi |
1842 | 1842 |
|
1843 | 1843 |
/* increment number of current authenticated clients */ |
1844 | 1844 |
++m->n_clients; |
1845 |
+ update_mstat_n_clients(m->n_clients); |
|
1845 | 1846 |
--mi->n_clients_delta; |
1846 | 1847 |
|
1847 | 1848 |
#ifdef MANAGEMENT_DEF_AUTH |
... | ... |
@@ -299,6 +299,9 @@ static const char usage_message[] = |
299 | 299 |
" can be matched in policy routing and packetfilter rules.\n" |
300 | 300 |
#endif |
301 | 301 |
"--txqueuelen n : Set the tun/tap TX queue length to n (Linux only).\n" |
302 |
+#ifdef ENABLE_MEMSTATS |
|
303 |
+ "--memstats file : Write live usage stats to memory mapped binary file.\n" |
|
304 |
+#endif |
|
302 | 305 |
"--mlock : Disable Paging -- ensures key material and tunnel\n" |
303 | 306 |
" data will never be written to disk.\n" |
304 | 307 |
"--up cmd : Shell cmd to execute after successful tun device open.\n" |
... | ... |
@@ -4602,6 +4605,13 @@ add_option (struct options *options, |
4602 | 4602 |
options->log = true; |
4603 | 4603 |
redirect_stdout_stderr (p[1], true); |
4604 | 4604 |
} |
4605 |
+#ifdef ENABLE_MEMSTATS |
|
4606 |
+ else if (streq (p[0], "memstats") && p[1]) |
|
4607 |
+ { |
|
4608 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
4609 |
+ options->memstats_fn = p[1]; |
|
4610 |
+ } |
|
4611 |
+#endif |
|
4605 | 4612 |
else if (streq (p[0], "mlock")) |
4606 | 4613 |
{ |
4607 | 4614 |
VERIFY_PERMISSION (OPT_P_GENERAL); |