From patchwork Sun Aug 4 23:25:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 794 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.28.255.1]) by backend30.mail.ord1d.rsapps.net with LMTP id cEMcCLH2R13tZgAAIUCqbw for ; Mon, 05 Aug 2019 05:28:17 -0400 Received: from proxy3.mail.ord1c.rsapps.net ([172.28.255.1]) by director7.mail.ord1d.rsapps.net with LMTP id 4OKyB7H2R12UBAAAovjBpQ ; Mon, 05 Aug 2019 05:28:17 -0400 Received: from smtp34.gate.ord1c ([172.28.255.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy3.mail.ord1c.rsapps.net with LMTP id 4L+jB7H2R120HQAANIxBXg ; Mon, 05 Aug 2019 05:28:17 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp34.gate.ord1c.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 5aac94ea-b763-11e9-8147-545200247500-1-1 Received: from [216.105.38.7] ([216.105.38.7:41876] helo=lists.sourceforge.net) by smtp34.gate.ord1c.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 56/7C-29355-0B6F74D5; Mon, 05 Aug 2019 05:28:16 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1huZHB-00041t-VW; Mon, 05 Aug 2019 09:27:33 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1huZHA-00041R-LC for openvpn-devel@lists.sourceforge.net; Mon, 05 Aug 2019 09:27:32 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Htf/b03B0/ox/MV8TLNeBHTHsPBl2B7YCIMruXE2wgk=; b=Bq3ElfYjomlMXuBr5bzXZRLTaz 2wCYLxBZ8qzrc+r+aWhXCQ+OUF8riYmr+dYJfDG3wY5gJ0yxTRqJWu6qFmjHyoJf/hzQrNvXYhFp6 AgN5bAUJgm9Aup9OfGROldvSKUG1lxJO+XM5woR0o+MfxedOn1XSdiBTSBN9UiOANIow=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Htf/b03B0/ox/MV8TLNeBHTHsPBl2B7YCIMruXE2wgk=; b=jfkr/DxDKNt7UnR82yr3jfUfyV AL1MUKTl3+zAQuXukPibjqeX6eVI5j9ZwBwWpstX4TDdxajJN77WTQ7eqtG16IYjW7uc60LVi6bKN rk4wIiwlpMS1QLTlmel9wE/S4gLizBXlmYOUOnA3rpCXoc7wc+Z33drsb6QlJ2D5Tvjg=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-4.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) id 1huZH8-00B3W5-SX for openvpn-devel@lists.sourceforge.net; Mon, 05 Aug 2019 09:27:32 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 5 Aug 2019 11:25:26 +0200 Message-Id: <20190805092529.9467-4-a@unstable.cc> In-Reply-To: <20190805092529.9467-1-a@unstable.cc> References: <20190805092529.9467-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [5.148.176.60 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1huZH8-00B3W5-SX Subject: [Openvpn-devel] [PATCH 3/6] networking: extend API for better memory management X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Antonio Quartulli Networking backend implementations may need to allocate dynamic resources that require an explicit free/release. Since these cleanup are perfomed not very often, and only at specific times, it makes sense to have the upper layer signal when it's the right time to do so, by means of a new API call. For this purpose two news APIs have been implemented: - net_ctx_free() to release all backend specific resources. Expected to be called at application cleanup time; - net_ctx_reset() to let backends release temporary resources (i.e. reset garbage collectors). To be invoked after routines that are expected to allocate memory (i.e. tun setup or shutdown). In this patch related implementations for iproute2 and sitnl are also provided. Signed-off-by: Antonio Quartulli --- src/openvpn/networking.h | 26 +++++++++++ src/openvpn/networking_iproute2.c | 74 ++++++++++++------------------- src/openvpn/networking_iproute2.h | 1 + src/openvpn/networking_sitnl.c | 12 +++++ src/openvpn/openvpn.c | 1 + src/openvpn/route.c | 8 ++++ src/openvpn/tun.c | 5 +++ 7 files changed, 82 insertions(+), 45 deletions(-) diff --git a/src/openvpn/networking.h b/src/openvpn/networking.h index cf967116..4075ed73 100644 --- a/src/openvpn/networking.h +++ b/src/openvpn/networking.h @@ -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. * diff --git a/src/openvpn/networking_iproute2.c b/src/openvpn/networking_iproute2.c index 5db9a78b..f06af724 100644 --- a/src/openvpn/networking_iproute2.c +++ b/src/openvpn/networking_iproute2.c @@ -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); + char *addr_str = (char *)print_in_addr_t(*addr, 0, &ctx->gc); + char *brd_str = (char *)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); + char *addr_str = (char *)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); + char *local_str = (char *)print_in_addr_t(*local, 0, &ctx->gc); + char *remote_str = (char *)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); + char *local_str = (char *)print_in_addr_t(*local, 0, &ctx->gc); + char *remote_str = (char *)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); + char *dst_str = (char *)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); + char *gw_str = (char *)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); + char *dst_str = (char *)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; diff --git a/src/openvpn/networking_iproute2.h b/src/openvpn/networking_iproute2.h index 47b50a9f..24c605db 100644 --- a/src/openvpn/networking_iproute2.h +++ b/src/openvpn/networking_iproute2.h @@ -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; diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c index 21563905..976ecd28 100644 --- a/src/openvpn/networking_sitnl.c +++ b/src/openvpn/networking_sitnl.c @@ -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) diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c index fb02b3de..a58d5075 100644 --- a/src/openvpn/openvpn.c +++ b/src/openvpn/openvpn.c @@ -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); } diff --git a/src/openvpn/route.c b/src/openvpn/route.c index bf036689..2d53c459 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -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); } /* diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 8f8f7c6c..e66e69bf 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -1435,6 +1435,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 @@ -2027,6 +2030,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);