mirror of
https://github.com/OpenVPN/openvpn.git
synced 2024-09-20 03:52:28 +02:00
Management interface performance optimizations:
* Added env-filter MI command to perform filtering on env vars passed through as a part of --management-client-auth * man_write will now try to aggregate output into larger blocks (up to 1024 bytes) for more efficient i/o Version 2.1.1f git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@5557 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
parent
74fce85ee8
commit
7e1c085d76
41
buffer.c
41
buffer.c
@ -945,7 +945,7 @@ buffer_list_push (struct buffer_list *ol, const unsigned char *str)
|
||||
}
|
||||
}
|
||||
|
||||
const struct buffer *
|
||||
struct buffer *
|
||||
buffer_list_peek (struct buffer_list *ol)
|
||||
{
|
||||
if (ol->head)
|
||||
@ -954,6 +954,45 @@ buffer_list_peek (struct buffer_list *ol)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_list_aggregate (struct buffer_list *bl, const size_t max)
|
||||
{
|
||||
if (bl->head)
|
||||
{
|
||||
struct buffer_entry *more = bl->head;
|
||||
size_t size = 0;
|
||||
int count = 0;
|
||||
for (count = 0; more && size <= max; ++count)
|
||||
{
|
||||
size += BLEN(&more->buf);
|
||||
more = more->next;
|
||||
}
|
||||
|
||||
if (count >= 2)
|
||||
{
|
||||
int i;
|
||||
struct buffer_entry *e = bl->head, *f;
|
||||
|
||||
ALLOC_OBJ_CLEAR (f, struct buffer_entry);
|
||||
f->buf.data = malloc (size);
|
||||
check_malloc_return (f->buf.data);
|
||||
f->buf.capacity = size;
|
||||
for (i = 0; e && i < count; ++i)
|
||||
{
|
||||
struct buffer_entry *next = e->next;
|
||||
buf_copy (&f->buf, &e->buf);
|
||||
free_buf (&e->buf);
|
||||
free (e);
|
||||
e = next;
|
||||
}
|
||||
bl->head = f;
|
||||
f->next = more;
|
||||
if (!more)
|
||||
bl->tail = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_list_pop (struct buffer_list *ol)
|
||||
{
|
||||
|
4
buffer.h
4
buffer.h
@ -845,9 +845,11 @@ bool buffer_list_defined (const struct buffer_list *ol);
|
||||
void buffer_list_reset (struct buffer_list *ol);
|
||||
|
||||
void buffer_list_push (struct buffer_list *ol, const unsigned char *str);
|
||||
const struct buffer *buffer_list_peek (struct buffer_list *ol);
|
||||
struct buffer *buffer_list_peek (struct buffer_list *ol);
|
||||
void buffer_list_advance (struct buffer_list *ol, int n);
|
||||
|
||||
void buffer_list_aggregate (struct buffer_list *bl, const size_t max);
|
||||
|
||||
struct buffer_list *buffer_list_file (const char *fn, int max_line_len);
|
||||
|
||||
#endif
|
||||
|
54
init.c
54
init.c
@ -499,6 +499,60 @@ init_static (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUFFER_LIST_AGGREGATE_TEST
|
||||
/* test buffer_list_aggregate function */
|
||||
{
|
||||
static const char *text[] = {
|
||||
"It was a bright cold day in April, ",
|
||||
"and the clocks were striking ",
|
||||
"thirteen. ",
|
||||
"Winston Smith, ",
|
||||
"his chin nuzzled into his breast in an ",
|
||||
"effort to escape the vile wind, ",
|
||||
"slipped quickly through the glass doors ",
|
||||
"of Victory Mansions, though not quickly ",
|
||||
"enough to prevent a swirl of gritty dust from ",
|
||||
"entering along with him."
|
||||
};
|
||||
|
||||
int iter, listcap;
|
||||
for (listcap = 0; listcap < 12; ++listcap)
|
||||
{
|
||||
for (iter = 0; iter < 512; ++iter)
|
||||
{
|
||||
struct buffer_list *bl = buffer_list_new(listcap);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SIZE(text); ++i)
|
||||
buffer_list_push(bl, (unsigned char *)text[i]);
|
||||
}
|
||||
printf("[cap=%d i=%d] *************************\n", listcap, iter);
|
||||
if (!(iter & 8))
|
||||
buffer_list_aggregate(bl, iter/2);
|
||||
if (!(iter & 16))
|
||||
buffer_list_push(bl, (unsigned char *)"Even more text...");
|
||||
buffer_list_aggregate(bl, iter);
|
||||
if (!(iter & 1))
|
||||
buffer_list_push(bl, (unsigned char *)"More text...");
|
||||
{
|
||||
struct buffer *buf;
|
||||
while ((buf = buffer_list_peek(bl)))
|
||||
{
|
||||
int c;
|
||||
printf ("'");
|
||||
while ((c = buf_read_u8(buf)) >= 0)
|
||||
putchar(c);
|
||||
printf ("'\n");
|
||||
buffer_list_advance(bl, 0);
|
||||
}
|
||||
}
|
||||
buffer_list_free(bl);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
71
manage.c
71
manage.c
@ -97,6 +97,7 @@ man_help ()
|
||||
msg (M_CLIENT, "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason");
|
||||
msg (M_CLIENT, " text R and optional client reason text CR");
|
||||
msg (M_CLIENT, "client-kill CID : Kill client instance CID");
|
||||
msg (M_CLIENT, "env-filter [level] : Set env-var filter level");
|
||||
#ifdef MANAGEMENT_PF
|
||||
msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)");
|
||||
#endif
|
||||
@ -935,6 +936,13 @@ man_client_n_clients (struct management *man)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
man_env_filter (struct management *man, const int level)
|
||||
{
|
||||
man->connection.env_filter_level = level;
|
||||
msg (M_CLIENT, "SUCCESS: env_filter_level=%d", level);
|
||||
}
|
||||
|
||||
#ifdef MANAGEMENT_PF
|
||||
|
||||
static void
|
||||
@ -1020,6 +1028,13 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch
|
||||
{
|
||||
man_client_n_clients (man);
|
||||
}
|
||||
else if (streq (p[0], "env-filter"))
|
||||
{
|
||||
int level = 0;
|
||||
if (p[1])
|
||||
level = atoi (p[1]);
|
||||
man_env_filter (man, level);
|
||||
}
|
||||
#endif
|
||||
else if (streq (p[0], "signal"))
|
||||
{
|
||||
@ -1723,13 +1738,15 @@ man_read (struct management *man)
|
||||
static int
|
||||
man_write (struct management *man)
|
||||
{
|
||||
const int max_send = 256;
|
||||
const int size_hint = 1024;
|
||||
int sent = 0;
|
||||
const struct buffer *buf;
|
||||
|
||||
const struct buffer *buf = buffer_list_peek (man->connection.out);
|
||||
buffer_list_aggregate(man->connection.out, size_hint);
|
||||
buf = buffer_list_peek (man->connection.out);
|
||||
if (buf && BLEN (buf))
|
||||
{
|
||||
const int len = min_int (max_send, BLEN (buf));
|
||||
const int len = min_int (size_hint, BLEN (buf));
|
||||
sent = send (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL);
|
||||
if (sent >= 0)
|
||||
{
|
||||
@ -2130,15 +2147,51 @@ management_set_state (struct management *man,
|
||||
|
||||
#ifdef MANAGEMENT_DEF_AUTH
|
||||
|
||||
static bool
|
||||
env_filter_match (const char *env_str, const int env_filter_level)
|
||||
{
|
||||
static const char *env_names[] = {
|
||||
"username=",
|
||||
"password=",
|
||||
"X509_0_CN=",
|
||||
"tls_serial_0=",
|
||||
"untrusted_ip=",
|
||||
"ifconfig_local=",
|
||||
"ifconfig_netmask=",
|
||||
"daemon_start_time=",
|
||||
"daemon_pid=",
|
||||
"dev=",
|
||||
"ifconfig_pool_remote_ip=",
|
||||
"ifconfig_pool_netmask=",
|
||||
"time_duration=",
|
||||
"bytes_sent=",
|
||||
"bytes_received="
|
||||
};
|
||||
if (env_filter_level >= 1)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < SIZE(env_names); ++i)
|
||||
{
|
||||
const char *en = env_names[i];
|
||||
const size_t len = strlen(en);
|
||||
if (strncmp(env_str, en, len) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
man_output_env (const struct env_set *es, const bool tail)
|
||||
man_output_env (const struct env_set *es, const bool tail, const int env_filter_level)
|
||||
{
|
||||
if (es)
|
||||
{
|
||||
struct env_item *e;
|
||||
for (e = es->list; e != NULL; e = e->next)
|
||||
{
|
||||
if (e->string)
|
||||
if (e->string && (!env_filter_level || env_filter_match(e->string, env_filter_level)))
|
||||
msg (M_CLIENT, ">CLIENT:ENV,%s", e->string);
|
||||
}
|
||||
}
|
||||
@ -2156,7 +2209,7 @@ man_output_extra_env (struct management *man)
|
||||
const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
|
||||
setenv_int (es, "n_clients", nclients);
|
||||
}
|
||||
man_output_env (es, false);
|
||||
man_output_env (es, false, man->connection.env_filter_level);
|
||||
gc_free (&gc);
|
||||
}
|
||||
|
||||
@ -2173,7 +2226,7 @@ management_notify_client_needing_auth (struct management *management,
|
||||
mode = "REAUTH";
|
||||
msg (M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id);
|
||||
man_output_extra_env (management);
|
||||
man_output_env (es, true);
|
||||
man_output_env (es, true, management->connection.env_filter_level);
|
||||
mdac->flags |= DAF_INITIAL_AUTH;
|
||||
}
|
||||
}
|
||||
@ -2186,7 +2239,7 @@ management_connection_established (struct management *management,
|
||||
mdac->flags |= DAF_CONNECTION_ESTABLISHED;
|
||||
msg (M_CLIENT, ">CLIENT:ESTABLISHED,%lu", mdac->cid);
|
||||
man_output_extra_env (management);
|
||||
man_output_env (es, true);
|
||||
man_output_env (es, true, management->connection.env_filter_level);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2197,7 +2250,7 @@ management_notify_client_close (struct management *management,
|
||||
if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED))
|
||||
{
|
||||
msg (M_CLIENT, ">CLIENT:DISCONNECT,%lu", mdac->cid);
|
||||
man_output_env (es, true);
|
||||
man_output_env (es, true, management->connection.env_filter_level);
|
||||
mdac->flags |= DAF_CONNECTION_CLOSED;
|
||||
}
|
||||
}
|
||||
|
1
manage.h
1
manage.h
@ -268,6 +268,7 @@ struct man_connection {
|
||||
unsigned long in_extra_cid;
|
||||
unsigned int in_extra_kid;
|
||||
struct buffer_list *in_extra;
|
||||
int env_filter_level;
|
||||
#endif
|
||||
struct event_set *es;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
dnl define the OpenVPN version
|
||||
define(PRODUCT_VERSION,[2.1.1e])
|
||||
define(PRODUCT_VERSION,[2.1.1f])
|
||||
dnl define the TAP version
|
||||
define(PRODUCT_TAP_ID,[tap0901])
|
||||
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])
|
||||
|
Loading…
Reference in New Issue
Block a user