Attention is currently required from: d12fk, plaisthos. Hello flichtenheld, plaisthos,
I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/838?usp=email to look at the new patch set (#2). Change subject: dns: apply settings via script on unixoid systems ...................................................................... dns: apply settings via script on unixoid systems This introduces a new script hook, the dns-script and implements such a script for a few popular systems (and a default for the not so popular ones). Like the name suggests this script is soleley for dealing with modifying how names are resolved when the VPN pushes some --dns settings. The default dns script is part of the distribution and is installed with openvpn. You can change the path the script is located at as a compile time option, defaults to libexecdir. There's also a new runtime option --dns-script, which can run a custom script. Change-Id: Ifbe4ffb44d3bfcaa50adb38cacb3436fcdc71b10 Signed-off-by: Heiko Hund <he...@ist.eigentlich.net> --- M .gitignore M CMakeLists.txt M configure.ac M distro/Makefile.am A distro/dns-scripts/Makefile.am A distro/dns-scripts/haikuos_file-dns-updown.sh A distro/dns-scripts/openresolv-dns-updown.sh A distro/dns-scripts/resolvconf_file-dns-updown.sh A distro/dns-scripts/systemd-dns-updown.sh M src/openvpn/Makefile.am M src/openvpn/dns.c M src/openvpn/dns.h M src/openvpn/options.c 13 files changed, 396 insertions(+), 3 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/38/838/2 diff --git a/.gitignore b/.gitignore index db8bb73..04523af 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ /doc/doxygen/latex/ /doc/doxygen/openvpn.doxyfile distro/systemd/*.service +distro/dns-scripts/dns-updown sample/sample-keys/sample-ca/ vendor/cmocka_build vendor/dist diff --git a/CMakeLists.txt b/CMakeLists.txt index ca58cd7..249f7bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ option(ENABLE_PKCS11 "BUILD with pkcs11-helper" ON) option(USE_WERROR "Treat compiler warnings as errors (-Werror)" ON) +set(DNS_UPDOWN_PATH "/usr/libexec/openvpn/dns-updown" CACHE STRING "Default location for the DNS up/down script") set(PLUGIN_DIR /usr/local/lib/openvpn/plugins CACHE FILEPATH "Location of the plugin directory") # Create machine readable compile commands @@ -565,6 +566,8 @@ add_library_deps(openvpn) +target_compile_options(openvpn PRIVATE -DDNS_UPDOWN_PATH=\"${DNS_UPDOWN_PATH}\") + if(MINGW) target_compile_options(openvpn PRIVATE -municode -UUNICODE) target_link_options(openvpn PRIVATE -municode) diff --git a/configure.ac b/configure.ac index 9777e36..45d3ac1 100644 --- a/configure.ac +++ b/configure.ac @@ -315,37 +315,50 @@ plugindir="\${libdir}/openvpn/plugins" fi +AC_ARG_VAR([SCRIPTDIR], [Path of script directory @<:@default=PKGLIBEXECDIR@:>@]) +if test -n "${SCRIPTDIR}"; then + scriptdir="${SCRIPTDIR}" +else + scriptdir="\${pkglibexecdir}" +fi + AC_DEFINE_UNQUOTED([TARGET_ALIAS], ["${host}"], [A string representing our host]) -AM_CONDITIONAL([TARGET_LINUX], [false]) +AM_CONDITIONAL([ENABLE_DNS_SCRIPT],[true]) case "$host" in *-*-linux*) AC_DEFINE([TARGET_LINUX], [1], [Are we running on Linux?]) - AM_CONDITIONAL([TARGET_LINUX], [true]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["L"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["systemd"]) have_sitnl="yes" pkg_config_required="yes" ;; *-*-solaris*) AC_DEFINE([TARGET_SOLARIS], [1], [Are we running on Solaris?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["S"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"]) CPPFLAGS="$CPPFLAGS -D_XPG4_2" test -x /bin/bash && SHELL="/bin/bash" ;; *-*-openbsd*) AC_DEFINE([TARGET_OPENBSD], [1], [Are we running on OpenBSD?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["O"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"]) ;; *-*-freebsd*) AC_DEFINE([TARGET_FREEBSD], [1], [Are we running on FreeBSD?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["F"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["openresolv"]) ;; *-*-netbsd*) AC_DEFINE([TARGET_NETBSD], [1], [Are we running NetBSD?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["N"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["openresolv"]) ;; *-*-darwin*) AC_DEFINE([TARGET_DARWIN], [1], [Are we running on Mac OS X?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["M"], [Target prefix]) + AM_CONDITIONAL([ENABLE_DNS_SCRIPT],[false]) + AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"]) have_tap_header="yes" ac_cv_type_struct_in_pktinfo=no ;; @@ -353,6 +366,8 @@ AC_DEFINE([TARGET_WIN32], [1], [Are we running WIN32?]) AC_DEFINE([ENABLE_DCO], [1], [DCO is always enabled on Windows]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["W"], [Target prefix]) + AM_CONDITIONAL([ENABLE_DNS_SCRIPT],[false]) + AC_SUBST([DNS_UPDOWN_TYPE], ["windows"]) CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN" CPPFLAGS="${CPPFLAGS} -DNTDDI_VERSION=NTDDI_VISTA -D_WIN32_WINNT=_WIN32_WINNT_VISTA" WIN32=yes @@ -360,10 +375,12 @@ *-*-dragonfly*) AC_DEFINE([TARGET_DRAGONFLY], [1], [Are we running on DragonFlyBSD?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["D"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["openresolv"]) ;; *-aix*) AC_DEFINE([TARGET_AIX], [1], [Are we running AIX?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["A"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"]) ROUTE="/usr/sbin/route" have_tap_header="yes" ac_cv_header_net_if_h="no" # exists, but breaks things @@ -371,10 +388,12 @@ *-*-haiku*) AC_DEFINE([TARGET_HAIKU], [1], [Are we running Haiku?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["H"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["haikuos_file"]) LIBS="${LIBS} -lnetwork" ;; *) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["X"], [Target prefix]) + AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"]) have_tap_header="yes" ;; esac @@ -1505,6 +1524,7 @@ sampledir="\$(docdir)/sample" AC_SUBST([plugindir]) +AC_SUBST([scriptdir]) AC_SUBST([sampledir]) AC_SUBST([systemdunitdir]) @@ -1541,6 +1561,7 @@ Makefile distro/Makefile distro/systemd/Makefile + distro/dns-scripts/Makefile doc/Makefile doc/doxygen/Makefile doc/doxygen/openvpn.doxyfile diff --git a/distro/Makefile.am b/distro/Makefile.am index 7a588da..b8fb85b 100644 --- a/distro/Makefile.am +++ b/distro/Makefile.am @@ -13,3 +13,7 @@ $(srcdir)/Makefile.in SUBDIRS = systemd + +if ENABLE_DNS_SCRIPT +SUBDIRS += dns-scripts +endif diff --git a/distro/dns-scripts/Makefile.am b/distro/dns-scripts/Makefile.am new file mode 100644 index 0000000..ec7bfde --- /dev/null +++ b/distro/dns-scripts/Makefile.am @@ -0,0 +1,28 @@ +# +# OpenVPN -- An application to securely tunnel IP networks +# over a single UDP port, with support for SSL/TLS-based +# session authentication and key exchange, +# packet encryption, packet authentication, and +# packet compression. +# +# Copyright (C) 2002-2024 OpenVPN Inc <sa...@openvpn.net> +# + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in + +EXTRA_DIST = \ + systemd-dns-updown.sh \ + openresolv-dns-updown.sh \ + haikuos_file-dns-updown.sh \ + resolvconf_file-dns-updown.sh + +script_SCRIPTS = \ + dns-updown + +CLEANFILES = $(script_SCRIPTS) + +dns-updown: @dns_updown_t...@-dns-updown.sh + cp ${srcdir}/@dns_updown_t...@-dns-updown.sh $@ + +all: $(script_SCRIPTS) diff --git a/distro/dns-scripts/haikuos_file-dns-updown.sh b/distro/dns-scripts/haikuos_file-dns-updown.sh new file mode 100644 index 0000000..bf7ea87 --- /dev/null +++ b/distro/dns-scripts/haikuos_file-dns-updown.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# Simple OpenVPN up/down script for modifying Haiku OS resolv.conf +# (C) Copyright 2024 OpenVPN Inc <sa...@openvpn.net> +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Example env from openvpn (most are not applied): +# +# dns_search_domain_1 mycorp.in +# dns_search_domain_2 eu.mycorp.com +# dns_server_1_address_1 192.168.99.254 +# dns_server_1_address_2 fd00::99:53 +# dns_server_1_port_1 53 +# dns_server_1_port_2 53 +# dns_server_1_resolve_domain_1 mycorp.in +# dns_server_1_resolve_domain_2 eu.mycorp.com +# dns_server_1_dnssec true +# dns_server_1_transport DoH +# dns_server_1_sni dns.mycorp.in +# + +set -e +u + +conf=/boot/system/settings/network/resolv.conf +test -e "$conf" || exit 1 +test -z "${dns_vars_file}" || . "${dns_vars_file}" +case "${script_type}" in +dns-up) + text="### openvpn ${dev} begin ###\n" + text="${text}nameserver $dns_server_1_address_1\n" + test -z "$dns_server_1_address_2" || + text="${text}nameserver $dns_server_1_address_2\n" + test -z "$dns_server_1_address_3" || + text="${text}nameserver $dns_server_1_address_3\n" + + test -z "$dns_search_domain_1" || { + for i in $(seq 1 6); do + eval domains=\"$domains\$dns_search_domain_${i} \" || break + done + text="${text}search $domains\n" + } + text="${text}### openvpn ${dev} end ###" + + sed -i "1i${text}" "$conf" + ;; +dns-down) + sed -i "/### openvpn ${dev} begin ###/,/### openvpn ${dev} end ###/d" "$conf" + ;; +esac diff --git a/distro/dns-scripts/openresolv-dns-updown.sh b/distro/dns-scripts/openresolv-dns-updown.sh new file mode 100644 index 0000000..12d742d --- /dev/null +++ b/distro/dns-scripts/openresolv-dns-updown.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Simple OpenVPN up/down script for openresolv integration +# (C) Copyright 2016 Baptiste Daroussin +# 2024 OpenVPN Inc <sa...@openvpn.net> +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Example env from openvpn (most are not applied): +# +# dns_search_domain_1 mycorp.in +# dns_search_domain_2 eu.mycorp.com +# dns_server_1_address_1 192.168.99.254 +# dns_server_1_address_2 fd00::99:53 +# dns_server_1_port_1 53 +# dns_server_1_port_2 53 +# dns_server_1_resolve_domain_1 mycorp.in +# dns_server_1_resolve_domain_2 eu.mycorp.com +# dns_server_1_dnssec true +# dns_server_1_transport DoH +# dns_server_1_sni dns.mycorp.in +# + +set -e +u +[ -z "${dns_vars_file}" ] || . "${dns_vars_file}" +: ${script_type:=dns-down} +case "${script_type}" in +dns-up) + { + i=1 + maxns=3 + while :; do + maxns=$((maxns - 1)) + [ $maxns -gt 0 ] || break + eval option=\"\$dns_server_1_address_${i}\" || break + [ "${option}" ] || break + i=$((i + 1)) + echo "nameserver ${option}" + done + i=1 + maxdom=6 + while :; do + maxdom=$((maxdom - 1)) + [ $maxdom -gt 0 ] || break + eval option=\"\$dns_search_domain_${i}\" || break + [ "${option}" ] || break + i=$((i + 1)) + echo "search ${option}" + done + } | /sbin/resolvconf -a "${dev}" + ;; +dns-down) + /sbin/resolvconf -d "${dev}" -f + ;; +esac diff --git a/distro/dns-scripts/resolvconf_file-dns-updown.sh b/distro/dns-scripts/resolvconf_file-dns-updown.sh new file mode 100644 index 0000000..e3bcf0d --- /dev/null +++ b/distro/dns-scripts/resolvconf_file-dns-updown.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# Simple OpenVPN up/down script for modifying /etc/resolv.conf +# (C) Copyright 2024 OpenVPN Inc <sa...@openvpn.net> +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Example env from openvpn (most are not applied): +# +# dns_search_domain_1 mycorp.in +# dns_search_domain_2 eu.mycorp.com +# dns_server_1_address_1 192.168.99.254 +# dns_server_1_address_2 fd00::99:53 +# dns_server_1_port_1 53 +# dns_server_1_port_2 53 +# dns_server_1_resolve_domain_1 mycorp.in +# dns_server_1_resolve_domain_2 eu.mycorp.com +# dns_server_1_dnssec true +# dns_server_1_transport DoH +# dns_server_1_sni dns.mycorp.in +# + +set -e +u + +conf=/etc/resolv.conf +test -e "$conf" || exit 1 +test -z "${dns_vars_file}" || . "${dns_vars_file}" +case "${script_type}" in +dns-up) + text="### openvpn ${dev} begin ###\n" + text="${text}nameserver $dns_server_1_address_1\n" + test -z "$dns_server_1_address_2" || + text="${text}nameserver $dns_server_1_address_2\n" + test -z "$dns_server_1_address_3" || + text="${text}nameserver $dns_server_1_address_3\n" + + test -z "$dns_search_domain_1" || { + for i in $(seq 1 6); do + eval domains=\"$domains\$dns_search_domain_${i} \" || break + done + text="${text}search $domains\n" + } + text="${text}### openvpn ${dev} end ###" + + sed -i "1i${text}" "$conf" + ;; +dns-down) + sed -i "/### openvpn ${dev} begin ###/,/### openvpn ${dev} end ###/d" "$conf" + ;; +esac diff --git a/distro/dns-scripts/systemd-dns-updown.sh b/distro/dns-scripts/systemd-dns-updown.sh new file mode 100644 index 0000000..4b459f5 --- /dev/null +++ b/distro/dns-scripts/systemd-dns-updown.sh @@ -0,0 +1,128 @@ +#!/bin/bash +# +# dns-updown - add/remove openvpn provided DNS information +# +# Copyright (C) 2024 OpenVPN Inc <sa...@openvpn.net> +# +# SPDX-License-Identifier: GPL-2.0 +# +# Add/remove openvpn DNS settings from the env into/from +# the system. Supported backends in this order: +# +# * systemd-resolved +# * resolvconf +# +# Example env from openvpn (not all are always applied): +# +# dns_search_domain_1 mycorp.in +# dns_search_domain_2 eu.mycorp.com +# dns_server_1_address_1 192.168.99.254 +# dns_server_1_address_2 fd00::99:53 +# dns_server_1_port_1 53 +# dns_server_1_port_2 53 +# dns_server_1_resolve_domain_1 mycorp.in +# dns_server_1_resolve_domain_2 eu.mycorp.com +# dns_server_1_dnssec true +# dns_server_1_transport DoH +# dns_server_1_sni dns.mycorp.in +# + +[ -z "${dns_vars_file}" ] || . "${dns_vars_file}" + +function do_resolved_servers { + local sni="" + [ "$dns_server_1_transport" = "DoT" ] && sni="#$dns_server_1_sni" + + local addrs="" + for addr_var in ${!dns_server_1_address_*}; do + local port_var="${addr_var/address/port}" + local addr="${!addr_var}" + if [ -n "${!port_var}" ]; then + if [[ "$addr" =~ : ]]; then + addr="[$addr]" + fi + addrs+="${addr}:${!port_var}${sni} " + else + addrs+="${addr}${sni} " + fi + done + + resolvectl dns "$dev" $addrs +} + +function do_resolved_domains { + local list="" + for domain_var in ${!dns_search_domain_*}; do + list+="${!domain_var} " + done + if [ -z "${!dns_server_1_resolve_domain_*}" ]; then + resolvectl default-route "$dev" true + list+="~." + else + resolvectl default-route "$dev" false + for domain_var in ${!dns_server_1_resolve_domain_*}; do + [[ "$list" =~ (^| )"${!domain_var}"( |$) ]] && continue + list+="~${!domain_var} " + done + fi + + resolvectl domain "$dev" $list +} + +function do_resolved_dnssec { + if [ "$dns_server_1_dnssec" = "optional" ]; then + resolvectl dnssec "$dev" allow-downgrade + elif [ "$dns_server_1_dnssec" = "yes" ]; then + resolvectl dnssec "$dev" true + else + resolvectl dnssec "$dev" false + fi +} + +function do_resolved_dnsovertls { + if [ "$dns_server_1_transport" = "DoT" ]; then + resolvectl dnsovertls "$dev" true + else + resolvectl dnsovertls "$dev" false + fi +} + +function do_resolved { + [[ "$(readlink /etc/resolv.conf)" =~ systemd ]] || return 1 + + if [ "$script_type" = "dns-up" ]; then + do_resolved_servers + do_resolved_domains + do_resolved_dnssec + do_resolved_dnsovertls + else + resolvectl revert "$dev" + fi + + return 0 +} + +function do_resolvconf { + [ -x /sbin/resolvconf ] || return 1 + + if [ "$script_type" = "dns-up" ]; then + local domains="" + for domain_var in ${!dns_search_domain_*}; do + domains+="${!domain_var} " + done + { + local maxns=3 + for addr_var in ${!dns_server_1_address_*}; do + [ $((maxns--)) -gt 0 ] || break + echo "nameserver ${!addr_var}" + done + [ -z "$domains" ] || echo "search $domains" + } | /sbin/resolvconf -a "$dev" + else + /sbin/resolvconf -d "$dev" + fi + + return 0 +} + +do_resolved || do_resolvconf diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index ecb2bcf..d8beabd 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -30,7 +30,8 @@ $(OPTIONAL_LZ4_CFLAGS) \ $(OPTIONAL_PKCS11_HELPER_CFLAGS) \ $(OPTIONAL_INOTIFY_CFLAGS) \ - -DPLUGIN_LIBDIR=\"${plugindir}\" + -DPLUGIN_LIBDIR=\"${plugindir}\" \ + -DDNS_UPDOWN_PATH=\"${scriptdir}/dns-updown\" if WIN32 # we want unicode entry point but not the macro diff --git a/src/openvpn/dns.c b/src/openvpn/dns.c index 4528a9c..2f21ed5 100644 --- a/src/openvpn/dns.c +++ b/src/openvpn/dns.c @@ -30,6 +30,7 @@ #include "dns.h" #include "socket.h" #include "options.h" +#include "run_command.h" #ifdef _WIN32 #include "win32.h" @@ -262,6 +263,7 @@ clone.search_domains = clone_dns_domains(o->search_domains, gc); clone.servers = clone_dns_servers(o->servers, gc); clone.servers_prepull = clone_dns_servers(o->servers_prepull, gc); + clone.script = o->script; return clone; } @@ -519,6 +521,42 @@ send_msg_iservice(o->msg_channel, &nrpt, sizeof(nrpt), &ack, "DNS"); } +#else /* ifdef _WIN32 */ + +static void +script_env_set(bool up, const struct dns_options *o, const struct tuntap *tt, struct env_set *es) +{ + setenv_str(es, "dev", tt->actual_name); + setenv_str(es, "script_type", up ? "dns-up" : "dns-down"); + setenv_dns_options(o, es); +} + +static int +do_run_up_down_script(bool up, const struct dns_options *o, const struct tuntap *tt) +{ + struct gc_arena gc = gc_new(); + struct argv argv = argv_new(); + struct env_set *es = env_set_create(&gc); + + script_env_set(up, o, tt, es); + + argv_printf(&argv, "%s", o->script); + argv_msg(M_INFO, &argv); + int res = openvpn_run_script(&argv, es, S_FATAL|S_EXITCODE, "dns script"); + + argv_free(&argv); + gc_free(&gc); + return res; +} + +static void +run_up_down_script(bool up, struct options *o, const struct tuntap *tt) +{ + int status; + status = do_run_up_down_script(up, &o->dns_options, tt); + msg(M_INFO, "dns script exited with status %d", status); +} + #endif /* _WIN32 */ void @@ -637,5 +675,7 @@ #ifdef _WIN32 run_up_down_service(up, o, tt); +#else + run_up_down_script(up, o, tt); #endif /* ifdef _WIN32 */ } diff --git a/src/openvpn/dns.h b/src/openvpn/dns.h index f24e30b..39a3393 100644 --- a/src/openvpn/dns.h +++ b/src/openvpn/dns.h @@ -73,6 +73,7 @@ struct dns_server *servers_prepull; struct dns_server *servers; struct gc_arena gc; + const char *script; }; /** diff --git a/src/openvpn/options.c b/src/openvpn/options.c index cc723ca..319f370 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -907,6 +907,8 @@ #ifndef ENABLE_DCO o->disable_dco = true; #endif /* ENABLE_DCO */ + + o->dns_options.script = DNS_UPDOWN_PATH; } void @@ -8073,6 +8075,15 @@ to->ip_win32_defined = true; } #endif /* ifdef _WIN32 */ + else if (streq(p[0], "dns-script") && p[1]) + { + VERIFY_PERMISSION(OPT_P_SCRIPT); + if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT)) + { + goto err; + } + set_user_script(options, &options->dns_options.script, p[1], p[0], false); + } else if (streq(p[0], "dns") && p[1]) { VERIFY_PERMISSION(OPT_P_DHCPDNS); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/838?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: Ifbe4ffb44d3bfcaa50adb38cacb3436fcdc71b10 Gerrit-Change-Number: 838 Gerrit-PatchSet: 2 Gerrit-Owner: d12fk <he...@openvpn.net> Gerrit-Reviewer: flichtenheld <fr...@lichtenheld.com> Gerrit-Reviewer: plaisthos <arne-open...@rfc2549.org> Gerrit-CC: openvpn-devel <openvpn-devel@lists.sourceforge.net> Gerrit-Attention: plaisthos <arne-open...@rfc2549.org> Gerrit-Attention: d12fk <he...@openvpn.net> Gerrit-MessageType: newpatchset
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel