diff options
author | Arne Schwabe | 2023-03-24 11:06:40 +0100 |
---|---|---|
committer | Gert Doering | 2023-03-24 11:32:14 +0100 |
commit | 2ac91ea73b76dd17d5cdf78740790ed928e08bff (patch) | |
tree | 71cf61055537f131135f08fcc1ddd9bcca66d970 /src | |
parent | e950ca1b9fca58e97aacedc5c0229856aa1e4e86 (diff) | |
download | openvpn-2ac91ea73b76dd17d5cdf78740790ed928e08bff.zip openvpn-2ac91ea73b76dd17d5cdf78740790ed928e08bff.tar.gz |
Add 'allow-compression stub-only' internally for DCO
This changes the "no" setting of allow-compression to also refuse framing
if DCO is active. This is important for our DCO implementations as these
do not implement framing.
This behaviour surfaced when a commercial VPN provider was pushing
"comp-lzo no" to a client with DCO. While we are technically at fault here
for announcing comp-lzo no support by announcing IV_LZO_STUB=1, the
VPN provider continues to push "comp-lzo no" even in absense of that
flag.
As the new default we default to 'allow-compression no' if DCO is
enabled and to 'allow-compression stub' otherwise.
This will now also bail out if the server pushes a compression setting that
we do not support as mismatching compression is almost never a working
connection. In the case of lz4-v2 and lzo-v2 you might have a connection
that works mostly but some packets will be dropped since they compressed
which is not desirable either since it becomes very hard to debug.
Patch v2: bail out if server pushes an unsupported method. Also include this
bail out logic when OpenVPN is compiled without compression support.
Patch v3: always parse all compression option and move logic to check method
Patch v4: fix for not setting correct default for non-dco
Change-Id: Ibd0c77af24e2214b3055d585dc23a4b06dccd414
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20230324100640.1340535-1-arne@rfc2549.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg26509.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 4117d950788eebfaf6c9b5dde278e3a81b9e805d)
Diffstat (limited to 'src')
-rw-r--r-- | src/openvpn/comp.c | 47 | ||||
-rw-r--r-- | src/openvpn/comp.h | 2 | ||||
-rw-r--r-- | src/openvpn/options.c | 14 |
3 files changed, 43 insertions, 20 deletions
diff --git a/src/openvpn/comp.c b/src/openvpn/comp.c index d6d8029..c7a562f 100644 --- a/src/openvpn/comp.c +++ b/src/openvpn/comp.c @@ -134,36 +134,51 @@ comp_print_stats(const struct compress_context *compctx, struct status_output *s void comp_generate_peer_info_string(const struct compress_options *opt, struct buffer *out) { - if (opt) + if (!opt || opt->flags & COMP_F_ALLOW_NOCOMP_ONLY) + { + return; + } + + bool lzo_avail = false; + if (!(opt->flags & COMP_F_ADVERTISE_STUBS_ONLY)) { - bool lzo_avail = false; - if (!(opt->flags & COMP_F_ADVERTISE_STUBS_ONLY)) - { #if defined(ENABLE_LZ4) - buf_printf(out, "IV_LZ4=1\n"); - buf_printf(out, "IV_LZ4v2=1\n"); + buf_printf(out, "IV_LZ4=1\n"); + buf_printf(out, "IV_LZ4v2=1\n"); #endif #if defined(ENABLE_LZO) - buf_printf(out, "IV_LZO=1\n"); - lzo_avail = true; + buf_printf(out, "IV_LZO=1\n"); + lzo_avail = true; #endif - } - if (!lzo_avail) - { - buf_printf(out, "IV_LZO_STUB=1\n"); - } - buf_printf(out, "IV_COMP_STUB=1\n"); - buf_printf(out, "IV_COMP_STUBv2=1\n"); } + if (!lzo_avail) + { + buf_printf(out, "IV_LZO_STUB=1\n"); + } + buf_printf(out, "IV_COMP_STUB=1\n"); + buf_printf(out, "IV_COMP_STUBv2=1\n"); } bool check_compression_settings_valid(struct compress_options *info, int msglevel) { + /* + * We also allow comp-stub-v2 here as it technically allows escaping of + * weird mac address and IPv5 protocol but practically always is used + * as an way to disable all framing. + */ + if (info->alg != COMP_ALGV2_UNCOMPRESSED && info->alg != COMP_ALG_UNDEF + && (info->flags & COMP_F_ALLOW_NOCOMP_ONLY)) + { + msg(msglevel, "Compression or compression stub framing is not allowed " + "since data-channel offloading is enabled."); + return false; + } + if ((info->flags & COMP_F_ALLOW_STUB_ONLY) && comp_non_stub_enabled(info)) { msg(msglevel, "Compression is not allowed since allow-compression is " - "set to 'no'"); + "set to 'stub-only'"); return false; } #ifndef ENABLE_LZ4 diff --git a/src/openvpn/comp.h b/src/openvpn/comp.h index 8636727..71b350d 100644 --- a/src/openvpn/comp.h +++ b/src/openvpn/comp.h @@ -60,7 +60,7 @@ * we still accept other compressions to be pushed */ #define COMP_F_MIGRATE (1<<5) /* push stub-v2 or comp-lzo no when we see a client with comp-lzo in occ */ #define COMP_F_ALLOW_ASYM (1<<6) /* Compression was explicitly set to allow asymetric compression */ - +#define COMP_F_ALLOW_NOCOMP_ONLY (1<<7) /* Do not allow compression framing (breaks DCO) */ /* * Length of prepended prefix on compressed packets diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 435e1ca..0ccff72 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -3644,10 +3644,12 @@ options_set_backwards_compatible_options(struct options *o) * * Disable compression by default starting with 2.6.0 if no other * compression related option has been explicitly set */ - if (!comp_non_stub_enabled(&o->comp) && !need_compatibility_before(o, 20600) - && (o->comp.flags == 0)) + if (!need_compatibility_before(o, 20600) && (o->comp.flags == 0)) { - o->comp.flags = COMP_F_ALLOW_STUB_ONLY|COMP_F_ADVERTISE_STUBS_ONLY; + if (!comp_non_stub_enabled(&o->comp)) + { + o->comp.flags = COMP_F_ALLOW_STUB_ONLY | COMP_F_ADVERTISE_STUBS_ONLY; + } } #endif } @@ -3749,6 +3751,12 @@ options_postprocess_mutate(struct options *o, struct env_set *es) o->tuntap_options.disable_dco = !dco_check_option(D_DCO, o) || !dco_check_startup_option(D_DCO, o); } +#ifdef USE_COMP + if (dco_enabled(o)) + { + o->comp.flags |= COMP_F_ALLOW_NOCOMP_ONLY; + } +#endif #ifdef _WIN32 if (dco_enabled(o)) |