mirror of
https://github.com/OpenVPN/openvpn.git
synced 2024-09-20 03:52:28 +02:00
Extended Management Interface "bytecount" command
to work when OpenVPN is running as a server. Documented Management Interface "bytecount" command in management/management-notes.txt. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3452 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
parent
9bf6e9ac04
commit
5f435d64d7
16
forward.c
16
forward.c
@ -707,12 +707,17 @@ process_incoming_link (struct context *c)
|
||||
c->c2.original_recv_size = c->c2.buf.len;
|
||||
#ifdef ENABLE_MANAGEMENT
|
||||
if (management)
|
||||
management_bytes_in (management, c->c2.buf.len);
|
||||
{
|
||||
management_bytes_in (management, c->c2.buf.len);
|
||||
#ifdef MANAGEMENT_DEF_AUTH
|
||||
management_bytes_server (management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
c->c2.original_recv_size = 0;
|
||||
|
||||
|
||||
#ifdef ENABLE_DEBUG
|
||||
/* take action to corrupt packet if we are in gremlin test mode */
|
||||
if (c->options.gremlin) {
|
||||
@ -1100,7 +1105,12 @@ process_outgoing_link (struct context *c)
|
||||
c->c2.link_write_bytes += size;
|
||||
#ifdef ENABLE_MANAGEMENT
|
||||
if (management)
|
||||
management_bytes_out (management, size);
|
||||
{
|
||||
management_bytes_out (management, size);
|
||||
#ifdef MANAGEMENT_DEF_AUTH
|
||||
management_bytes_server (management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
27
manage.c
27
manage.c
@ -367,11 +367,15 @@ man_status (struct management *man, const int version, struct status_output *so)
|
||||
static void
|
||||
man_bytecount (struct management *man, const int update_seconds)
|
||||
{
|
||||
man->connection.bytecount_update_seconds = update_seconds;
|
||||
if (update_seconds >= 0)
|
||||
man->connection.bytecount_update_seconds = update_seconds;
|
||||
else
|
||||
man->connection.bytecount_update_seconds = 0;
|
||||
msg (M_CLIENT, "SUCCESS: bytecount interval changed");
|
||||
}
|
||||
|
||||
void
|
||||
man_bytecount_output (struct management *man)
|
||||
man_bytecount_output_client (struct management *man)
|
||||
{
|
||||
char in[32];
|
||||
char out[32];
|
||||
@ -382,6 +386,25 @@ man_bytecount_output (struct management *man)
|
||||
man->connection.bytecount_last_update = now;
|
||||
}
|
||||
|
||||
#ifdef MANAGEMENT_DEF_AUTH
|
||||
|
||||
void
|
||||
man_bytecount_output_server (struct management *man,
|
||||
const counter_type *bytes_in_total,
|
||||
const counter_type *bytes_out_total,
|
||||
struct man_def_auth_context *mdac)
|
||||
{
|
||||
char in[32];
|
||||
char out[32];
|
||||
/* do in a roundabout way to work around possible mingw or mingw-glibc bug */
|
||||
openvpn_snprintf (in, sizeof (in), counter_format, *bytes_in_total);
|
||||
openvpn_snprintf (out, sizeof (out), counter_format, *bytes_out_total);
|
||||
msg (M_CLIENT, ">BYTECOUNT_CLI:%lu,%s,%s", mdac->cid, in, out);
|
||||
mdac->bytecount_last_update = now;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
man_kill (struct management *man, const char *victim)
|
||||
{
|
||||
|
56
manage.h
56
manage.h
@ -51,6 +51,8 @@ struct man_def_auth_context {
|
||||
unsigned int flags;
|
||||
|
||||
unsigned int mda_key_id_counter;
|
||||
|
||||
time_t bytecount_last_update;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -143,6 +145,10 @@ log_history_capacity (const struct log_history *h)
|
||||
struct management_callback
|
||||
{
|
||||
void *arg;
|
||||
|
||||
# define MCF_SERVER (1<<0) /* is OpenVPN being run as a server? */
|
||||
unsigned int flags;
|
||||
|
||||
void (*status) (void *arg, const int version, struct status_output *so);
|
||||
void (*show_net) (void *arg, const int msglevel);
|
||||
int (*kill_by_cn) (void *arg, const char *common_name);
|
||||
@ -432,31 +438,65 @@ void management_auth_failure (struct management *man, const char *type);
|
||||
* These functions drive the bytecount in/out counters.
|
||||
*/
|
||||
|
||||
void man_bytecount_output (struct management *man);
|
||||
void man_bytecount_output_client (struct management *man);
|
||||
|
||||
static inline void
|
||||
man_bytecount_possible_output (struct management *man)
|
||||
man_bytecount_possible_output_client (struct management *man)
|
||||
{
|
||||
if (man->connection.bytecount_update_seconds > 0
|
||||
&& now >= man->connection.bytecount_last_update
|
||||
+ man->connection.bytecount_update_seconds)
|
||||
man_bytecount_output (man);
|
||||
man_bytecount_output_client (man);
|
||||
}
|
||||
|
||||
static inline void
|
||||
management_bytes_out_client (struct management *man, const int size)
|
||||
{
|
||||
man->persist.bytes_out += size;
|
||||
man_bytecount_possible_output_client (man);
|
||||
}
|
||||
|
||||
static inline void
|
||||
management_bytes_in_client (struct management *man, const int size)
|
||||
{
|
||||
man->persist.bytes_in += size;
|
||||
man_bytecount_possible_output_client (man);
|
||||
}
|
||||
|
||||
static inline void
|
||||
management_bytes_out (struct management *man, const int size)
|
||||
{
|
||||
man->persist.bytes_out += size;
|
||||
man_bytecount_possible_output (man);
|
||||
if (!(man->persist.callback.flags & MCF_SERVER))
|
||||
management_bytes_out_client (man, size);
|
||||
}
|
||||
|
||||
static inline void
|
||||
management_bytes_in (struct management *man, const int size)
|
||||
{
|
||||
man->persist.bytes_in += size;
|
||||
man_bytecount_possible_output (man);
|
||||
if (!(man->persist.callback.flags & MCF_SERVER))
|
||||
management_bytes_in_client (man, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef MANAGEMENT_DEF_AUTH
|
||||
|
||||
static inline void
|
||||
management_bytes_server (struct management *man,
|
||||
const counter_type *bytes_in_total,
|
||||
const counter_type *bytes_out_total,
|
||||
struct man_def_auth_context *mdac)
|
||||
{
|
||||
void man_bytecount_output_server (struct management *man,
|
||||
const counter_type *bytes_in_total,
|
||||
const counter_type *bytes_out_total,
|
||||
struct man_def_auth_context *mdac);
|
||||
|
||||
if (man->connection.bytecount_update_seconds > 0
|
||||
&& now >= mdac->bytecount_last_update + man->connection.bytecount_update_seconds
|
||||
&& (mdac->flags & (DAF_CONNECTION_ESTABLISHED|DAF_CONNECTION_CLOSED)) == DAF_CONNECTION_ESTABLISHED)
|
||||
man_bytecount_output_server (man, bytes_in_total, bytes_out_total, mdac);
|
||||
}
|
||||
|
||||
#endif /* MANAGEMENT_DEF_AUTH */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -3,26 +3,24 @@ OpenVPN Management Interface Notes
|
||||
|
||||
The OpenVPN Management interface allows OpenVPN to
|
||||
be administratively controlled from an external program via
|
||||
a TCP socket.
|
||||
a TCP or unix domain socket.
|
||||
|
||||
The interface has been specifically designed for GUI developers
|
||||
and those who would like to programmatically or remotely control
|
||||
an OpenVPN daemon.
|
||||
The interface has been specifically designed for developers
|
||||
who would like to programmatically or remotely control
|
||||
an OpenVPN daemon, and can be used when OpenVPN is running
|
||||
as a client or server.
|
||||
|
||||
The management interface is implemented using a client/server TCP
|
||||
connection, where OpenVPN will listen on a provided IP address
|
||||
and port for incoming management client connections.
|
||||
connection or unix domain socket where OpenVPN will listen on a
|
||||
provided IP address and port for incoming management client connections.
|
||||
|
||||
The management protocol is currently cleartext without an explicit
|
||||
security layer. For this reason, it is recommended that the
|
||||
management interface either listen on localhost (127.0.0.1)
|
||||
or on the local VPN address. It's possible to remotely connect
|
||||
to the management interface over the VPN itself, though some
|
||||
capabilities will be limited in this mode, such as the ability
|
||||
to provide private key passwords.
|
||||
|
||||
Future versions of the management interface may allow out-of-band
|
||||
connections (i.e. not over the VPN) and secured with SSL/TLS.
|
||||
management interface either listen on a unix domain socket,
|
||||
localhost (127.0.0.1), or on the local VPN address. It's possible
|
||||
to remotely connect to the management interface over the VPN itself,
|
||||
though some capabilities will be limited in this mode, such as the
|
||||
ability to provide private key passwords.
|
||||
|
||||
The management interface is enabled in the OpenVPN
|
||||
configuration file using the following directive:
|
||||
@ -39,6 +37,44 @@ a telnet client which understands "raw" mode).
|
||||
Once connected to the management port, you can use
|
||||
the "help" command to list all commands.
|
||||
|
||||
COMMAND -- bytecount
|
||||
--------------------
|
||||
|
||||
The bytecount command is used to request real-time notification
|
||||
of OpenVPN bandwidth usage.
|
||||
|
||||
Command syntax:
|
||||
|
||||
bytecount n (where n > 0) -- set up automatic notification of
|
||||
bandwidth usage once every n seconds
|
||||
bytecount 0 -- turn off bytecount notifications
|
||||
|
||||
If OpenVPN is running as a client, the bytecount notification
|
||||
will look like this:
|
||||
|
||||
>BYTECOUNT:{BYTES_IN},{BYTES_OUT}
|
||||
|
||||
BYTES_IN is the number of bytes that have been received from
|
||||
the server and BYTES_OUT is the number of bytes that have been
|
||||
sent to the server.
|
||||
|
||||
If OpenVPN is running as a server, the bytecount notification
|
||||
will look like this:
|
||||
|
||||
>BYTECOUNT_CLI:{CID},{BYTES_IN},{BYTES_OUT}
|
||||
|
||||
CID is the Client ID, BYTES_IN is the number of bytes that have
|
||||
been received from the client and BYTES_OUT is the number of
|
||||
bytes that have been sent to the client.
|
||||
|
||||
Note that when the bytecount command is used on the server, every
|
||||
connected client will report its bandwidth numbers once every n
|
||||
seconds.
|
||||
|
||||
When the client disconnects, the final bandwidth numbers will be
|
||||
placed in the 'bytes_received' and 'bytes_sent' environmental variables
|
||||
as included in the >CLIENT:DISCONNECT notification.
|
||||
|
||||
COMMAND -- echo
|
||||
---------------
|
||||
|
||||
@ -661,6 +697,14 @@ column and are immediately followed by a type keyword
|
||||
indicating the type of real-time message. The following
|
||||
types are currently defined:
|
||||
|
||||
BYTECOUNT -- Real-time bandwidth usage notification, as enabled
|
||||
by "bytecount" command when OpenVPN is running as
|
||||
a client.
|
||||
|
||||
BYTECOUNT_CLI -- Real-time bandwidth usage notification per-client,
|
||||
as enabled by "bytecount" command when OpenVPN is
|
||||
running as a server.
|
||||
|
||||
CLIENT -- Notification of client connections and disconnections
|
||||
on an OpenVPN server. Enabled when OpenVPN is started
|
||||
with the --management-client-auth option. CLIENT
|
||||
|
11
multi.c
11
multi.c
@ -436,6 +436,13 @@ multi_del_iroutes (struct multi_context *m,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setenv_stats (struct context *c)
|
||||
{
|
||||
setenv_counter (c->c2.es, "bytes_received", c->c2.link_read_bytes);
|
||||
setenv_counter (c->c2.es, "bytes_sent", c->c2.link_write_bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
multi_client_disconnect_setenv (struct multi_context *m,
|
||||
struct multi_instance *mi)
|
||||
@ -444,8 +451,7 @@ multi_client_disconnect_setenv (struct multi_context *m,
|
||||
setenv_trusted (mi->context.c2.es, get_link_socket_info (&mi->context));
|
||||
|
||||
/* setenv stats */
|
||||
setenv_counter (mi->context.c2.es, "bytes_received", mi->context.c2.link_read_bytes);
|
||||
setenv_counter (mi->context.c2.es, "bytes_sent", mi->context.c2.link_write_bytes);
|
||||
setenv_stats (&mi->context);
|
||||
|
||||
/* setenv connection duration */
|
||||
{
|
||||
@ -2583,6 +2589,7 @@ init_management_callback_multi (struct multi_context *m)
|
||||
struct management_callback cb;
|
||||
CLEAR (cb);
|
||||
cb.arg = m;
|
||||
cb.flags = MCF_SERVER;
|
||||
cb.status = management_callback_status;
|
||||
cb.show_net = management_show_net_callback;
|
||||
cb.kill_by_cn = management_callback_kill_by_cn;
|
||||
|
Loading…
Reference in New Issue
Block a user