@@ -39,6 +39,18 @@ net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx)
{
return 0;
}
+
+static inline void
+net_ctx_reset(openvpn_net_ctx_t *ctx)
+{
+ (void)ctx;
+}
+
+static inline void
+net_ctx_free(openvpn_net_ctx_t *ctx)
+{
+ (void)ctx;
+}
#endif
#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE)
@@ -53,6 +65,20 @@ net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx)
*/
int net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx);
+/**
+ * Release resources allocated by the internal garbage collector
+ *
+ * @param ctx the implementation specific context
+ */
+void net_ctx_reset(openvpn_net_ctx_t *ctx);
+
+/**
+ * Release all resources allocated within the platform specific context object
+ *
+ * @param ctx the implementation specific context to release
+ */
+void net_ctx_free(openvpn_net_ctx_t *ctx);
+
/**
* Bring interface up or down.
*
@@ -43,10 +43,23 @@ net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx)
ctx->es = NULL;
if (c)
ctx->es = c->es;
+ ctx->gc = gc_new();
return 0;
}
+void
+net_ctx_reset(openvpn_net_ctx_t *ctx)
+{
+ gc_reset(&ctx->gc);
+}
+
+void
+net_ctx_free(openvpn_net_ctx_t *ctx)
+{
+ gc_free(&ctx->gc);
+}
+
int
net_iface_up(openvpn_net_ctx_t *ctx, const char *iface, bool up)
{
@@ -82,17 +95,14 @@ net_addr_v4_add(openvpn_net_ctx_t *ctx, const char *iface,
{
struct argv argv = argv_new();
- char *addr_str = (char *)print_in_addr_t(*addr, 0, NULL);
- char *brd_str = (char *)print_in_addr_t(*broadcast, 0, NULL);
+ const char *addr_str = print_in_addr_t(*addr, 0, &ctx->gc);
+ const char *brd_str = print_in_addr_t(*broadcast, 0, &ctx->gc);
argv_printf(&argv, "%s addr add dev %s %s/%d broadcast %s", iproute_path,
iface, addr_str, prefixlen, brd_str);
argv_msg(M_INFO, &argv);
openvpn_execve_check(&argv, ctx->es, S_FATAL, "Linux ip addr add failed");
- free(addr_str);
- free(brd_str);
-
argv_reset(&argv);
return 0;
@@ -103,7 +113,7 @@ net_addr_v6_add(openvpn_net_ctx_t *ctx, const char *iface,
const struct in6_addr *addr, int prefixlen)
{
struct argv argv = argv_new();
- char *addr_str = (char *)print_in6_addr(*addr, 0, NULL);
+ char *addr_str = (char *)print_in6_addr(*addr, 0, &ctx->gc);
argv_printf(&argv, "%s -6 addr add %s/%d dev %s", iproute_path, addr_str,
prefixlen, iface);
@@ -111,8 +121,6 @@ net_addr_v6_add(openvpn_net_ctx_t *ctx, const char *iface,
openvpn_execve_check(&argv, ctx->es, S_FATAL,
"Linux ip -6 addr add failed");
- free(addr_str);
-
argv_reset(&argv);
return 0;
@@ -123,7 +131,7 @@ net_addr_v4_del(openvpn_net_ctx_t *ctx, const char *iface,
const in_addr_t *addr, int prefixlen)
{
struct argv argv = argv_new();
- char *addr_str = (char *)print_in_addr_t(*addr, 0, NULL);
+ const char *addr_str = print_in_addr_t(*addr, 0, &ctx->gc);
argv_printf(&argv, "%s addr del dev %s %s/%d", iproute_path, iface,
addr_str, prefixlen);
@@ -131,8 +139,6 @@ net_addr_v4_del(openvpn_net_ctx_t *ctx, const char *iface,
argv_msg(M_INFO, &argv);
openvpn_execve_check(&argv, ctx->es, 0, "Linux ip addr del failed");
- free(addr_str);
-
argv_reset(&argv);
return 0;
@@ -143,15 +149,13 @@ net_addr_v6_del(openvpn_net_ctx_t *ctx, const char *iface,
const struct in6_addr *addr, int prefixlen)
{
struct argv argv = argv_new();
- char *addr_str = (char *)print_in6_addr(*addr, 0, NULL);
+ char *addr_str = (char *)print_in6_addr(*addr, 0, &ctx->gc);
argv_printf(&argv, "%s -6 addr del %s/%d dev %s", iproute_path,
addr_str, prefixlen, iface);
argv_msg(M_INFO, &argv);
openvpn_execve_check(&argv, ctx->es, 0, "Linux ip -6 addr del failed");
- free(addr_str);
-
argv_reset(&argv);
return 0;
@@ -162,17 +166,14 @@ net_addr_ptp_v4_add(openvpn_net_ctx_t *ctx, const char *iface,
const in_addr_t *local, const in_addr_t *remote)
{
struct argv argv = argv_new();
- char *local_str = (char *)print_in_addr_t(*local, 0, NULL);
- char *remote_str = (char *)print_in_addr_t(*remote, 0, NULL);
+ const char *local_str = print_in_addr_t(*local, 0, &ctx->gc);
+ const char *remote_str = print_in_addr_t(*remote, 0, &ctx->gc);
argv_printf(&argv, "%s addr add dev %s local %s peer %s", iproute_path,
iface, local_str, remote_str);
argv_msg(M_INFO, &argv);
openvpn_execve_check(&argv, ctx->es, S_FATAL, "Linux ip addr add failed");
- free(local_str);
- free(remote_str);
-
argv_reset(&argv);
return 0;
@@ -183,17 +184,14 @@ net_addr_ptp_v4_del(openvpn_net_ctx_t *ctx, const char *iface,
const in_addr_t *local, const in_addr_t *remote)
{
struct argv argv = argv_new();
- char *local_str = (char *)print_in_addr_t(*local, 0, NULL);
- char *remote_str = (char *)print_in_addr_t(*remote, 0, NULL);
+ const char *local_str = print_in_addr_t(*local, 0, &ctx->gc);
+ const char *remote_str = print_in_addr_t(*remote, 0, &ctx->gc);
argv_printf(&argv, "%s addr del dev %s local %s peer %s", iproute_path,
iface, local_str, remote_str);
argv_msg(M_INFO, &argv);
openvpn_execve_check(&argv, ctx->es, 0, "Linux ip addr del failed");
- free(local_str);
- free(remote_str);
-
argv_reset(&argv);
return 0;
@@ -205,7 +203,7 @@ net_route_v4_add(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen,
int metric)
{
struct argv argv = argv_new();
- char *dst_str = (char *)print_in_addr_t(*dst, 0, NULL);
+ const char *dst_str = print_in_addr_t(*dst, 0, &ctx->gc);
argv_printf(&argv, "%s route add %s/%d", iproute_path, dst_str, prefixlen);
@@ -217,18 +215,14 @@ net_route_v4_add(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen,
if (gw)
{
- char *gw_str = (char *)print_in_addr_t(*gw, 0, NULL);
+ const char *gw_str = print_in_addr_t(*gw, 0, &ctx->gc);
argv_printf_cat(&argv, "via %s", gw_str);
-
- free(gw_str);
}
argv_msg(D_ROUTE, &argv);
openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route add command failed");
- free(dst_str);
-
argv_reset(&argv);
return 0;
@@ -240,18 +234,16 @@ net_route_v6_add(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
uint32_t table, int metric)
{
struct argv argv = argv_new();
- char *dst_str = (char *)print_in6_addr(*dst, 0, NULL);
+ char *dst_str = (char *)print_in6_addr(*dst, 0, &ctx->gc);
argv_printf(&argv, "%s -6 route add %s/%d dev %s", iproute_path, dst_str,
prefixlen, iface);
if (gw)
{
- char *gw_str = (char *)print_in6_addr(*gw, 0, NULL);
+ char *gw_str = (char *)print_in6_addr(*gw, 0, &ctx->gc);
argv_printf_cat(&argv, "via %s", gw_str);
-
- free(gw_str);
}
if (metric > 0)
@@ -260,8 +252,6 @@ net_route_v6_add(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
argv_msg(D_ROUTE, &argv);
openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route -6 add command failed");
- free(dst_str);
-
argv_reset(&argv);
return 0;
@@ -273,7 +263,7 @@ net_route_v4_del(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen,
int metric)
{
struct argv argv = argv_new();
- char *dst_str = (char *)print_in_addr_t(*dst, 0, NULL);
+ const char *dst_str = print_in_addr_t(*dst, 0, &ctx->gc);
argv_printf(&argv, "%s route del %s/%d", iproute_path, dst_str, prefixlen);
@@ -283,8 +273,6 @@ net_route_v4_del(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen,
argv_msg(D_ROUTE, &argv);
openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route delete command failed");
- free(dst_str);
-
argv_reset(&argv);
return 0;
@@ -296,18 +284,16 @@ net_route_v6_del(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
uint32_t table, int metric)
{
struct argv argv = argv_new();
- char *dst_str = (char *)print_in6_addr(*dst, 0, NULL);
+ char *dst_str = (char *)print_in6_addr(*dst, 0, &ctx->gc);
argv_printf(&argv, "%s -6 route del %s/%d dev %s", iproute_path, dst_str,
prefixlen, iface);
if (gw)
{
- char *gw_str = (char *)print_in6_addr(*gw, 0, NULL);
+ char *gw_str = (char *)print_in6_addr(*gw, 0, &ctx->gc);
argv_printf_cat(&argv, "via %s", gw_str);
-
- free(gw_str);
}
if (metric > 0)
@@ -316,8 +302,6 @@ net_route_v6_del(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
argv_msg(D_ROUTE, &argv);
openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route -6 del command failed");
- free(dst_str);
-
argv_reset(&argv);
return 0;
@@ -29,6 +29,7 @@ typedef char openvpn_net_iface_t;
struct openvpn_net_ctx
{
struct env_set *es;
+ struct gc_arena gc;
};
typedef struct openvpn_net_ctx openvpn_net_ctx_t;
@@ -540,6 +540,18 @@ net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx)
return 0;
}
+void
+net_ctx_reset(openvpn_net_ctx_t *ctx)
+{
+ (void)ctx;
+}
+
+void
+net_ctx_free(openvpn_net_ctx_t *ctx)
+{
+ (void)ctx;
+}
+
int
net_route_v4_best_gw(openvpn_net_ctx_t *ctx, const in_addr_t *dst,
in_addr_t *best_gw, char *best_iface)
@@ -332,6 +332,7 @@ openvpn_main(int argc, char *argv[])
env_set_destroy(c.es);
uninit_options(&c.options);
gc_reset(&c.gc);
+ net_ctx_free(&c.net_ctx);
}
while (c.sig->signal_received == SIGHUP);
}
@@ -1826,6 +1826,8 @@ done:
}
argv_reset(&argv);
gc_free(&gc);
+ /* release resources potentially allocated during route setup */
+ net_ctx_reset(ctx);
}
@@ -2130,6 +2132,8 @@ done:
}
argv_reset(&argv);
gc_free(&gc);
+ /* release resources potentially allocated during route setup */
+ net_ctx_reset(ctx);
}
static void
@@ -2322,6 +2326,8 @@ done:
r->flags &= ~RT_ADDED;
argv_reset(&argv);
gc_free(&gc);
+ /* release resources potentially allocated during route cleanup */
+ net_ctx_reset(ctx);
}
void
@@ -2548,6 +2554,8 @@ delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt,
argv_reset(&argv);
gc_free(&gc);
+ /* release resources potentially allocated during route cleanup */
+ net_ctx_reset(ctx);
}
/*
@@ -1423,6 +1423,9 @@ do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
{
do_ifconfig_ipv6(tt, ifname, tun_mtu, es, ctx);
}
+
+ /* release resources potentially allocated during interface setup */
+ net_ctx_free(ctx);
}
static void
@@ -2015,6 +2018,8 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
}
gc_free(&gc);
+ /* release resources potentially allocated during undo */
+ net_ctx_reset(ctx);
}
close_tun_generic(tt);