1 From 9d065b401c2c393bef5a6e58b5deeda7d59d4f39 Mon Sep 17 00:00:00 2001
2 From: Ed Okerson <ed@okerson.com>
3 Date: Mon, 11 Feb 2013 15:46:10 -0600
4 Subject: [PATCH 16/22] Add support for OpenVPN 2.3.0 status files.
6 Fix a bug that breaks this module if a server is running multiple instances of OpenVPN and one instance does not have any clients connected.
8 src/openvpn.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
9 1 file changed, 84 insertions(+), 6 deletions(-)
11 diff --git a/src/openvpn.c b/src/openvpn.c
12 index 2aca414..d2b6f17 100644
16 #define V1STRING "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since\n"
17 #define V2STRING "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t)\n"
18 #define V3STRING "HEADER CLIENT_LIST Common Name Real Address Virtual Address Bytes Received Bytes Sent Connected Since Connected Since (time_t)\n"
19 +#define V4STRING "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t),Username\n"
20 #define VSSTRING "OpenVPN STATISTICS\n"
23 @@ -43,6 +44,7 @@ struct vpn_status_s
24 MULTI1 = 1, /* status-version 1 */
25 MULTI2, /* status-version 2 */
26 MULTI3, /* status-version 3 */
27 + MULTI4, /* status-version 4 */
28 SINGLE = 10 /* currently no versions for single mode, maybe in the future */
31 @@ -452,13 +454,77 @@ static int multi3_read (char *name, FILE *fh)
33 } /* int multi3_read */
35 +/* for reading status version 4 */
36 +static int multi4_read (char *name, FILE *fh)
40 + const int max_fields = STATIC_ARRAY_SIZE (fields);
41 + int fields_num, read = 0;
42 + long long sum_users = 0;
44 + while (fgets (buffer, sizeof (buffer), fh) != NULL)
46 + fields_num = openvpn_strsplit (buffer, fields, max_fields);
48 + /* status file is generated by openvpn/multi.c:multi_print_status()
49 + * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c
51 + * The line we're expecting has 9 fields. We ignore all lines
52 + * with more or less fields.
54 + if (fields_num != 9)
58 + if (strcmp (fields[0], "CLIENT_LIST") != 0)
62 + if (collect_user_count)
63 + /* If so, sum all users, ignore the individuals*/
67 + if (collect_individual_users)
69 + if (new_naming_schema)
71 + /* plugin inst = file name, type inst = fields[1] */
72 + iostats_submit (name, /* vpn instance */
73 + fields[1], /* "Common Name" */
74 + atoll (fields[4]), /* "Bytes Received" */
75 + atoll (fields[5])); /* "Bytes Sent" */
79 + /* plugin inst = fields[1], type inst = "" */
80 + iostats_submit (fields[1], /* "Common Name" */
81 + NULL, /* unused when in multimode */
82 + atoll (fields[4]), /* "Bytes Received" */
83 + atoll (fields[5])); /* "Bytes Sent" */
90 + if (collect_user_count)
92 + numusers_submit(name, name, sum_users);
97 +} /* int multi4_read */
100 static int openvpn_read (void)
104 + int i, vpn_read, read;
107 + vpn_read = read = 0;
109 /* call the right read function for every status entry in the list */
110 for (i = 0; i < vpn_num; i++)
111 @@ -476,23 +542,28 @@ static int openvpn_read (void)
112 switch (vpn_list[i]->version)
115 - read = single_read(vpn_list[i]->name, fh);
116 + vpn_read = single_read(vpn_list[i]->name, fh);
120 - read = multi1_read(vpn_list[i]->name, fh);
121 + vpn_read = multi1_read(vpn_list[i]->name, fh);
125 - read = multi2_read(vpn_list[i]->name, fh);
126 + vpn_read = multi2_read(vpn_list[i]->name, fh);
130 - read = multi3_read(vpn_list[i]->name, fh);
131 + vpn_read = multi3_read(vpn_list[i]->name, fh);
135 + vpn_read = multi4_read(vpn_list[i]->name, fh);
143 return (read ? 0 : -1);
144 @@ -549,6 +620,13 @@ static int version_detect (const char *filename)
148 + /* searching for multi version 4 */
149 + else if (strcmp (buffer, V4STRING) == 0)
151 + DEBUG ("openvpn plugin: found status file version MULTI4");