summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Yonan <james@openvpn.net>2010-04-16 07:04:45 +0000
committerJames Yonan <james@openvpn.net>2010-04-16 07:04:45 +0000
commit7e1c085d76ef452373e5e80273e07471582c2ae8 (patch)
tree24015a89e1d5159beb0e7e5360d602457ee95b12
parent74fce85ee80ee5f484b62a3a81e9981e5698f1e1 (diff)
downloadopenvpn-7e1c085d76ef452373e5e80273e07471582c2ae8.tar.gz
openvpn-7e1c085d76ef452373e5e80273e07471582c2ae8.tar.xz
openvpn-7e1c085d76ef452373e5e80273e07471582c2ae8.zip
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
-rw-r--r--buffer.c41
-rw-r--r--buffer.h4
-rw-r--r--init.c54
-rw-r--r--manage.c71
-rw-r--r--manage.h1
-rw-r--r--version.m42
6 files changed, 161 insertions, 12 deletions
diff --git a/buffer.c b/buffer.c
index 485c696..e786b9b 100644
--- a/buffer.c
+++ b/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)
{
diff --git a/buffer.h b/buffer.h
index b046a5c..87bce08 100644
--- a/buffer.h
+++ b/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
diff --git a/init.c b/init.c
index 3748c2e..018541c 100644
--- a/init.c
+++ b/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;
}
diff --git a/manage.c b/manage.c
index bd88c11..e4c092f 100644
--- a/manage.c
+++ b/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;
}
}
diff --git a/manage.h b/manage.h
index e5cbafd..801442e 100644
--- a/manage.h
+++ b/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;
diff --git a/version.m4 b/version.m4
index 0877b9c..e7f1d58 100644
--- a/version.m4
+++ b/version.m4
@@ -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])