]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Management interface performance optimizations:
authorJames Yonan <james@openvpn.net>
Fri, 16 Apr 2010 07:04:45 +0000 (07:04 +0000)
committerJames Yonan <james@openvpn.net>
Fri, 16 Apr 2010 07:04:45 +0000 (07:04 +0000)
* 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

buffer.c
buffer.h
init.c
manage.c
manage.h
version.m4

index 485c696a058f75f57de7eae8bc6a86fa20c29ec5..e786b9b2defe73eb64ed72826b9ef323f3a68b57 100644 (file)
--- 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)
 {
index b046a5cf571f2102a9cc57df6dc387c3bd78f544..87bce08504d63a5596db199a6c83a554a2fd4f72 100644 (file)
--- 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 3748c2e3dd4adbf51a4205a4d406061ea3a7a0d5..018541c96c2a88b12db8efa57cd1b3d07c6c387d 100644 (file)
--- 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;
 }
 
index bd88c11c22d1fd63a3e9d795f1fcb33d4d71efa5..e4c092fb6b3c3be525347ff7e15da7ffdb5d8a60 100644 (file)
--- 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;
     }
 }
index e5cbafdaf0abe0454bc79ef44dcc6ecf3433c94e..801442ed153903187d3b0cf6a8b10ebdf8090dec 100644 (file)
--- 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;
 
index 0877b9c6ed5f56742123e8435b087fc61f5cc4a7..e7f1d583268b889a3e60b6e957245c1aab7aaf58 100644 (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])