Fixed issue where struct env_set methods that

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
This commit is contained in:
james 2006-11-23 22:05:14 +00:00
parent c589d2814f
commit 2a64816b39
4 changed files with 40 additions and 4 deletions

18
init.c
View file

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

24
misc.c
View file

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

1
misc.h
View file

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

View file

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