0
0
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:
James Yonan 2010-04-16 07:04:45 +00:00
parent 74fce85ee8
commit 7e1c085d76
6 changed files with 161 additions and 12 deletions

View File

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

View File

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

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

View File

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

View File

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

View File

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