]> git.ipfire.org Git - thirdparty/openvpn.git/blame - src/openvpn/comp.c
Update Copyright statements to 2024
[thirdparty/openvpn.git] / src / openvpn / comp.c
CommitLineData
38d96bd7
JY
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
b25c6d7e 8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
38d96bd7
JY
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
caa54ac3
DS
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38d96bd7
JY
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
38d96bd7
JY
26#endif
27
28#include "syshead.h"
29
38d96bd7
JY
30#include "comp.h"
31#include "error.h"
a8170dd0
AS
32
33#ifdef USE_COMP
34
38d96bd7
JY
35#include "otime.h"
36
37#include "memdbg.h"
38
39struct compress_context *
40comp_init(const struct compress_options *opt)
41{
81d882d5
DS
42 struct compress_context *compctx = NULL;
43 switch (opt->alg)
38d96bd7 44 {
81d882d5
DS
45 case COMP_ALG_STUB:
46 ALLOC_OBJ_CLEAR(compctx, struct compress_context);
47 compctx->flags = opt->flags;
48 compctx->alg = comp_stub_alg;
49 break;
50
51 case COMP_ALGV2_UNCOMPRESSED:
52 ALLOC_OBJ_CLEAR(compctx, struct compress_context);
53 compctx->flags = opt->flags;
54 compctx->alg = compv2_stub_alg;
55 break;
56
38d96bd7 57#ifdef ENABLE_LZO
81d882d5
DS
58 case COMP_ALG_LZO:
59 ALLOC_OBJ_CLEAR(compctx, struct compress_context);
60 compctx->flags = opt->flags;
61 compctx->alg = lzo_alg;
62 break;
63
38d96bd7 64#endif
40efb635 65#ifdef ENABLE_LZ4
81d882d5
DS
66 case COMP_ALG_LZ4:
67 ALLOC_OBJ_CLEAR(compctx, struct compress_context);
68 compctx->flags = opt->flags;
69 compctx->alg = lz4_alg;
70 break;
71
72 case COMP_ALGV2_LZ4:
73 ALLOC_OBJ_CLEAR(compctx, struct compress_context);
74 compctx->flags = opt->flags;
75 compctx->alg = lz4v2_alg;
76 break;
38d96bd7
JY
77#endif
78 }
81d882d5
DS
79 if (compctx)
80 {
81 (*compctx->alg.compress_init)(compctx);
82 }
67b3de98 83
81d882d5 84 return compctx;
38d96bd7
JY
85}
86
a75bb2e4
AS
87/* In the v2 compression schemes, an uncompressed packet has
88 * has no opcode in front, unless the first byte is 0x50. In this
89 * case the packet needs to be escaped */
90void
81d882d5 91compv2_escape_data_ifneeded(struct buffer *buf)
a75bb2e4 92{
81d882d5 93 uint8_t *head = BPTR(buf);
a75bb2e4 94 if (head[0] != COMP_ALGV2_INDICATOR_BYTE)
81d882d5
DS
95 {
96 return;
97 }
a75bb2e4
AS
98
99 /* Header is 0x50 */
100 ASSERT(buf_prepend(buf, 2));
101
81d882d5 102 head = BPTR(buf);
a75bb2e4
AS
103 head[0] = COMP_ALGV2_INDICATOR_BYTE;
104 head[1] = COMP_ALGV2_UNCOMPRESSED;
105}
106
107
38d96bd7
JY
108void
109comp_uninit(struct compress_context *compctx)
110{
81d882d5 111 if (compctx)
38d96bd7 112 {
81d882d5
DS
113 (*compctx->alg.compress_uninit)(compctx);
114 free(compctx);
38d96bd7
JY
115 }
116}
117
38d96bd7 118void
81d882d5 119comp_print_stats(const struct compress_context *compctx, struct status_output *so)
38d96bd7 120{
81d882d5 121 if (compctx)
38d96bd7 122 {
81d882d5
DS
123 status_printf(so, "pre-compress bytes," counter_format, compctx->pre_compress);
124 status_printf(so, "post-compress bytes," counter_format, compctx->post_compress);
125 status_printf(so, "pre-decompress bytes," counter_format, compctx->pre_decompress);
126 status_printf(so, "post-decompress bytes," counter_format, compctx->post_decompress);
38d96bd7
JY
127 }
128}
129
130/*
131 * Tell our peer which compression algorithms we support.
132 */
133void
134comp_generate_peer_info_string(const struct compress_options *opt, struct buffer *out)
135{
4117d950
AS
136 if (!opt || opt->flags & COMP_F_ALLOW_NOCOMP_ONLY)
137 {
138 return;
139 }
140
141 bool lzo_avail = false;
142 if (!(opt->flags & COMP_F_ADVERTISE_STUBS_ONLY))
38d96bd7 143 {
40efb635 144#if defined(ENABLE_LZ4)
4117d950
AS
145 buf_printf(out, "IV_LZ4=1\n");
146 buf_printf(out, "IV_LZ4v2=1\n");
40efb635 147#endif
38d96bd7 148#if defined(ENABLE_LZO)
4117d950
AS
149 buf_printf(out, "IV_LZO=1\n");
150 lzo_avail = true;
38d96bd7 151#endif
38d96bd7 152 }
4117d950
AS
153 if (!lzo_avail)
154 {
155 buf_printf(out, "IV_LZO_STUB=1\n");
156 }
157 buf_printf(out, "IV_COMP_STUB=1\n");
158 buf_printf(out, "IV_COMP_STUBv2=1\n");
38d96bd7 159}
a8170dd0 160#endif /* USE_COMP */
38d96bd7 161
e86bc8b2
AS
162bool
163check_compression_settings_valid(struct compress_options *info, int msglevel)
164{
4117d950
AS
165 /*
166 * We also allow comp-stub-v2 here as it technically allows escaping of
167 * weird mac address and IPv5 protocol but practically always is used
168 * as an way to disable all framing.
169 */
170 if (info->alg != COMP_ALGV2_UNCOMPRESSED && info->alg != COMP_ALG_UNDEF
171 && (info->flags & COMP_F_ALLOW_NOCOMP_ONLY))
172 {
a8170dd0 173#ifdef USE_COMP
4117d950
AS
174 msg(msglevel, "Compression or compression stub framing is not allowed "
175 "since data-channel offloading is enabled.");
a8170dd0
AS
176#else
177 msg(msglevel, "Compression or compression stub framing is not allowed "
178 "since OpenVPN was built without compression support.");
179#endif
4117d950
AS
180 return false;
181 }
182
e86bc8b2
AS
183 if ((info->flags & COMP_F_ALLOW_STUB_ONLY) && comp_non_stub_enabled(info))
184 {
185 msg(msglevel, "Compression is not allowed since allow-compression is "
4117d950 186 "set to 'stub-only'");
e86bc8b2
AS
187 return false;
188 }
189#ifndef ENABLE_LZ4
190 if (info->alg == COMP_ALGV2_LZ4 || info->alg == COMP_ALG_LZ4)
191 {
192 msg(msglevel, "OpenVPN is compiled without LZ4 support. Requested "
193 "compression cannot be enabled.");
194 return false;
195 }
196#endif
197#ifndef ENABLE_LZO
4076d24f 198 if (info->alg == COMP_ALG_LZO)
e86bc8b2
AS
199 {
200 msg(msglevel, "OpenVPN is compiled without LZO support. Requested "
201 "compression cannot be enabled.");
202 return false;
203 }
204#endif
205 return true;
206}