0
0
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:
james 2008-10-24 09:21:40 +00:00
parent 9bf6e9ac04
commit 5f435d64d7
5 changed files with 153 additions and 29 deletions

View File

@ -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
}
}

View File

@ -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)
{

View File

@ -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

View File

@ -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
View File

@ -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;