]>
Commit | Line | Data |
---|---|---|
2056dd30 AM |
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. | |
5 | ||
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. | |
7 | --- | |
8 | src/openvpn.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- | |
9 | 1 file changed, 84 insertions(+), 6 deletions(-) | |
10 | ||
11 | diff --git a/src/openvpn.c b/src/openvpn.c | |
12 | index 2aca414..d2b6f17 100644 | |
13 | --- a/src/openvpn.c | |
14 | +++ b/src/openvpn.c | |
15 | @@ -32,6 +32,7 @@ | |
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" | |
21 | ||
22 | ||
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 */ | |
29 | } version; | |
30 | char *name; | |
31 | @@ -452,13 +454,77 @@ static int multi3_read (char *name, FILE *fh) | |
32 | return (read); | |
33 | } /* int multi3_read */ | |
34 | ||
35 | +/* for reading status version 4 */ | |
36 | +static int multi4_read (char *name, FILE *fh) | |
37 | +{ | |
38 | + char buffer[1024]; | |
39 | + char *fields[11]; | |
40 | + const int max_fields = STATIC_ARRAY_SIZE (fields); | |
41 | + int fields_num, read = 0; | |
42 | + long long sum_users = 0; | |
43 | + | |
44 | + while (fgets (buffer, sizeof (buffer), fh) != NULL) | |
45 | + { | |
46 | + fields_num = openvpn_strsplit (buffer, fields, max_fields); | |
47 | + | |
48 | + /* status file is generated by openvpn/multi.c:multi_print_status() | |
49 | + * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c | |
50 | + * | |
51 | + * The line we're expecting has 9 fields. We ignore all lines | |
52 | + * with more or less fields. | |
53 | + */ | |
54 | + if (fields_num != 9) | |
55 | + continue; | |
56 | + | |
57 | + | |
58 | + if (strcmp (fields[0], "CLIENT_LIST") != 0) | |
59 | + continue; | |
60 | + | |
61 | + | |
62 | + if (collect_user_count) | |
63 | + /* If so, sum all users, ignore the individuals*/ | |
64 | + { | |
65 | + sum_users += 1; | |
66 | + } | |
67 | + if (collect_individual_users) | |
68 | + { | |
69 | + if (new_naming_schema) | |
70 | + { | |
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" */ | |
76 | + } | |
77 | + else | |
78 | + { | |
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" */ | |
84 | + } | |
85 | + } | |
86 | + | |
87 | + read = 1; | |
88 | + } | |
89 | + | |
90 | + if (collect_user_count) | |
91 | + { | |
92 | + numusers_submit(name, name, sum_users); | |
93 | + read = 1; | |
94 | + } | |
95 | + | |
96 | + return (read); | |
97 | +} /* int multi4_read */ | |
98 | + | |
99 | /* read callback */ | |
100 | static int openvpn_read (void) | |
101 | { | |
102 | FILE *fh; | |
103 | - int i, read; | |
104 | + int i, vpn_read, read; | |
105 | ||
106 | - read = 0; | |
107 | + vpn_read = read = 0; | |
108 | ||
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) | |
113 | { | |
114 | case SINGLE: | |
115 | - read = single_read(vpn_list[i]->name, fh); | |
116 | + vpn_read = single_read(vpn_list[i]->name, fh); | |
117 | break; | |
118 | ||
119 | case MULTI1: | |
120 | - read = multi1_read(vpn_list[i]->name, fh); | |
121 | + vpn_read = multi1_read(vpn_list[i]->name, fh); | |
122 | break; | |
123 | ||
124 | case MULTI2: | |
125 | - read = multi2_read(vpn_list[i]->name, fh); | |
126 | + vpn_read = multi2_read(vpn_list[i]->name, fh); | |
127 | break; | |
128 | ||
129 | case MULTI3: | |
130 | - read = multi3_read(vpn_list[i]->name, fh); | |
131 | + vpn_read = multi3_read(vpn_list[i]->name, fh); | |
132 | + break; | |
133 | + | |
134 | + case MULTI4: | |
135 | + vpn_read = multi4_read(vpn_list[i]->name, fh); | |
136 | break; | |
137 | } | |
138 | ||
139 | fclose (fh); | |
140 | + read += vpn_read; | |
141 | } | |
142 | ||
143 | return (read ? 0 : -1); | |
144 | @@ -549,6 +620,13 @@ static int version_detect (const char *filename) | |
145 | version = MULTI3; | |
146 | break; | |
147 | } | |
148 | + /* searching for multi version 4 */ | |
149 | + else if (strcmp (buffer, V4STRING) == 0) | |
150 | + { | |
151 | + DEBUG ("openvpn plugin: found status file version MULTI4"); | |
152 | + version = MULTI4; | |
153 | + break; | |
154 | + } | |
155 | } | |
156 | ||
157 | if (version == 0) | |
158 | -- | |
159 | 1.9.3 | |
160 |