]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Fixed issue where struct env_set methods that
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Thu, 23 Nov 2006 22:05:14 +0000 (22:05 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Thu, 23 Nov 2006 22:05:14 +0000 (22:05 +0000)
change the value of an existing name=value pair
would delay the freeing of the memory held by
the previous name=value pair until the underlying
client instance object is closed.

This could cause a server that handles long-term
client connections, resulting in many periodic calls
to verify_callback, to needlessly grow the env_set
memory allocation until the underlying client instance
object is closed.

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@1493 e7ae566f-a301-0410-adde-c780ea21d3b5

init.c
misc.c
misc.h
openvpn.h

diff --git a/init.c b/init.c
index 244f03cfa7f7f4cc5c13cf1e9622ba6098edd9c3..2cff87c2c2b501d3e12c6bda9b57f5dbf86d5333 100644 (file)
--- a/init.c
+++ b/init.c
@@ -2272,10 +2272,22 @@ do_close_ifconfig_pool_persist (struct context *c)
 static void
 do_inherit_env (struct context *c, const struct env_set *src)
 {
-  c->c2.es = env_set_create (&c->c2.gc);
+  c->c2.es = env_set_create (NULL);
+  c->c2.es_owned = true;
   env_set_inherit (c->c2.es, src);
 }
 
+static void
+do_env_set_destroy (struct context *c)
+{
+  if (c->c2.es && c->c2.es_owned)
+    {
+      env_set_destroy (c->c2.es);
+      c->c2.es = NULL;
+      c->c2.es_owned = false;
+    }
+}
+
 /*
  * Fast I/O setup.  Fast I/O is an optimization which only works
  * if all of the following are true:
@@ -2798,6 +2810,9 @@ close_instance (struct context *c)
        /* close --ifconfig-pool-persist obj */
        do_close_ifconfig_pool_persist (c);
 
+       /* free up environmental variable store */
+       do_env_set_destroy (c);
+
        /* garbage collect */
        gc_free (&c->c2.gc);
       }
@@ -2922,6 +2937,7 @@ inherit_context_top (struct context *dest,
   dest->c2.event_set_owned = false;
   dest->c2.link_socket_owned = false;
   dest->c2.buffers_owned = false;
+  dest->c2.es_owned = false;
 
   dest->c2.event_set = NULL;
   if (src->options.proto == PROTO_UDPv4)
diff --git a/misc.c b/misc.c
index c6423fa806d9d656d2bb62e058be904667cc6845..a42ef24ea065a88e323372d8d5399547dc0e1610 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -690,13 +690,13 @@ add_env_item (char *str, const bool do_alloc, struct env_item **list, struct gc_
 static bool
 env_set_del_nolock (struct env_set *es, const char *str)
 {
-  return remove_env_item (str, false, &es->list);
+  return remove_env_item (str, es->gc == NULL, &es->list);
 }
 
 static void
 env_set_add_nolock (struct env_set *es, const char *str)
 {
-  remove_env_item (str, false, &es->list);  
+  remove_env_item (str, es->gc == NULL, &es->list);  
   add_env_item ((char *)str, true, &es->list, es->gc);
 }
 
@@ -704,7 +704,6 @@ struct env_set *
 env_set_create (struct gc_arena *gc)
 {
   struct env_set *es;
-  ASSERT (gc);
   mutex_lock_static (L_ENV_SET);
   ALLOC_OBJ_CLEAR_GC (es, struct env_set, gc);
   es->list = NULL;
@@ -713,6 +712,25 @@ env_set_create (struct gc_arena *gc)
   return es;
 }
 
+void
+env_set_destroy (struct env_set *es)
+{
+  mutex_lock_static (L_ENV_SET);
+  if (es && es->gc == NULL)
+    {
+      struct env_item *e = es->list;
+      while (e)
+       {
+         struct env_item *next = e->next;
+         free (e->string);
+         free (e);
+         e = next;
+       }
+      free (es);
+    }
+  mutex_unlock_static (L_ENV_SET);
+}
+
 bool
 env_set_del (struct env_set *es, const char *str)
 {
diff --git a/misc.h b/misc.h
index ac761857b5b26bcfc306f20074fc5b2a56217acf..d626dfefc9dadedc6bb20e39a03a15d9358e0750 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -168,6 +168,7 @@ void setenv_del (struct env_set *es, const char *name);
 /* struct env_set functions */
 
 struct env_set *env_set_create (struct gc_arena *gc);
+void env_set_destroy (struct env_set *es);
 bool env_set_del (struct env_set *es, const char *str);
 void env_set_add (struct env_set *es, const char *str);
 
index 2b6cf1461a6321ef45dc7cd1fc82002b7f8451b9..0cdab624c2010e62c45020942fad18dcaa8045d2 100644 (file)
--- a/openvpn.h
+++ b/openvpn.h
@@ -403,6 +403,7 @@ struct context_2
 
   /* environmental variables to pass to scripts */
   struct env_set *es;
+  bool es_owned;
 
   /* don't wait for TUN/TAP/UDP to be ready to accept write */
   bool fast_io;