From: Gert Doering Date: Fri, 30 Dec 2011 20:08:49 +0000 (+0100) Subject: Fix build-up of duplicate IPv6 routes on reconnect. X-Git-Tag: v2.3-alpha1~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9140223643f7d9bdfd2214304a7bd6ab4b662f97;p=thirdparty%2Fopenvpn.git Fix build-up of duplicate IPv6 routes on reconnect. options.c: extend pre_pull_save() and pre_pull_restore() to save/restore options->routes_ipv6 as well options.h: add routes_ipv6 to "struct options_pre_pull" route.h, route.c: add clone_route_ipv6_option_list() and copy_route_ipv6_option_list() helper functions Signed-off-by: Gert Doering Acked-by: David Sommerseth Signed-off-by: David Sommerseth --- diff --git a/options.c b/options.c index 736495e48..a186276b3 100644 --- a/options.c +++ b/options.c @@ -2778,6 +2778,11 @@ pre_pull_save (struct options *o) o->pre_pull->routes = clone_route_option_list(o->routes, &o->gc); o->pre_pull->routes_defined = true; } + if (o->routes_ipv6) + { + o->pre_pull->routes_ipv6 = clone_route_ipv6_option_list(o->routes_ipv6, &o->gc); + o->pre_pull->routes_ipv6_defined = true; + } #ifdef ENABLE_CLIENT_NAT if (o->client_nat) { @@ -2806,6 +2811,14 @@ pre_pull_restore (struct options *o) else o->routes = NULL; + if (pp->routes_ipv6_defined) + { + rol6_check_alloc (o); + copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6); + } + else + o->routes_ipv6 = NULL; + #ifdef ENABLE_CLIENT_NAT if (pp->client_nat_defined) { diff --git a/options.h b/options.h index 06c4dcbd4..03fd19706 100644 --- a/options.h +++ b/options.h @@ -68,6 +68,9 @@ struct options_pre_pull bool routes_defined; struct route_option_list *routes; + bool routes_ipv6_defined; + struct route_ipv6_option_list *routes_ipv6; + #ifdef ENABLE_CLIENT_NAT bool client_nat_defined; struct client_nat_option_list *client_nat; diff --git a/route.c b/route.c index be23a899f..1f0b09677 100644 --- a/route.c +++ b/route.c @@ -108,6 +108,15 @@ clone_route_option_list (const struct route_option_list *src, struct gc_arena *a return ret; } +struct route_ipv6_option_list * +clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a) +{ + const size_t rl_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list)); + struct route_ipv6_option_list *ret = gc_malloc (rl_size, false, a); + memcpy (ret, src, rl_size); + return ret; +} + void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src) { @@ -117,6 +126,16 @@ copy_route_option_list (struct route_option_list *dest, const struct route_optio memcpy (dest, src, src_size); } +void +copy_route_ipv6_option_list (struct route_ipv6_option_list *dest, + const struct route_ipv6_option_list *src) +{ + const size_t src_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list)); + if (src->n > dest->capacity) + msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src->n, dest->capacity); + memcpy (dest, src, src_size); +} + struct route_list * new_route_list (const int max_routes, struct gc_arena *a) { diff --git a/route.h b/route.h index 995347889..58c7ef437 100644 --- a/route.h +++ b/route.h @@ -211,7 +211,10 @@ struct route_option_list *new_route_option_list (const int max_routes, struct gc struct route_ipv6_option_list *new_route_ipv6_option_list (const int max_routes, struct gc_arena *a); struct route_option_list *clone_route_option_list (const struct route_option_list *src, struct gc_arena *a); +struct route_ipv6_option_list *clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a); void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src); +void copy_route_ipv6_option_list (struct route_ipv6_option_list *dest, + const struct route_ipv6_option_list *src); struct route_list *new_route_list (const int max_routes, struct gc_arena *a); struct route_ipv6_list *new_route_ipv6_list (const int max_routes, struct gc_arena *a);