OpenVPN
comp.c
Go to the documentation of this file.
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 *
8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
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 *
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.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "syshead.h"
29
30#include "comp.h"
31#include "error.h"
32
33#ifdef USE_COMP
34
35#include "otime.h"
36
37#include "memdbg.h"
38
39struct compress_context *
40comp_init(const struct compress_options *opt)
41{
42 struct compress_context *compctx = NULL;
43 switch (opt->alg)
44 {
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
52 ALLOC_OBJ_CLEAR(compctx, struct compress_context);
53 compctx->flags = opt->flags;
54 compctx->alg = compv2_stub_alg;
55 break;
56
57#ifdef ENABLE_LZO
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
64#endif
65#ifdef ENABLE_LZ4
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;
77#endif
78 }
79 if (compctx)
80 {
81 (*compctx->alg.compress_init)(compctx);
82 }
83
84 return compctx;
85}
86
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
91compv2_escape_data_ifneeded(struct buffer *buf)
92{
93 uint8_t *head = BPTR(buf);
94 if (head[0] != COMP_ALGV2_INDICATOR_BYTE)
95 {
96 return;
97 }
98
99 /* Header is 0x50 */
100 ASSERT(buf_prepend(buf, 2));
101
102 head = BPTR(buf);
103 head[0] = COMP_ALGV2_INDICATOR_BYTE;
104 head[1] = COMP_ALGV2_UNCOMPRESSED;
105}
106
107
108void
109comp_uninit(struct compress_context *compctx)
110{
111 if (compctx)
112 {
113 (*compctx->alg.compress_uninit)(compctx);
114 free(compctx);
115 }
116}
117
118void
119comp_print_stats(const struct compress_context *compctx, struct status_output *so)
120{
121 if (compctx)
122 {
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);
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{
136 if (!opt || opt->flags & COMP_F_ALLOW_NOCOMP_ONLY)
137 {
138 return;
139 }
140
141 bool lzo_avail = false;
143 {
144#if defined(ENABLE_LZ4)
145 buf_printf(out, "IV_LZ4=1\n");
146 buf_printf(out, "IV_LZ4v2=1\n");
147#endif
148#if defined(ENABLE_LZO)
149 buf_printf(out, "IV_LZO=1\n");
150 lzo_avail = true;
151#endif
152 }
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");
159}
160#endif /* USE_COMP */
161
162bool
164{
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 {
173#ifdef USE_COMP
174 msg(msglevel, "Compression or compression stub framing is not allowed "
175 "since data-channel offloading is enabled.");
176#else
177 msg(msglevel, "Compression or compression stub framing is not allowed "
178 "since OpenVPN was built without compression support.");
179#endif
180 return false;
181 }
182
184 {
185 msg(msglevel, "Compression is not allowed since allow-compression is "
186 "set to 'stub-only'");
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
198 if (info->alg == COMP_ALG_LZO)
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}
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
#define BPTR(buf)
Definition buffer.h:124
static uint8_t * buf_prepend(struct buffer *buf, int size)
Definition buffer.h:606
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1060
#define counter_format
Definition common.h:31
bool check_compression_settings_valid(struct compress_options *info, int msglevel)
Checks if the compression settings are valid.
Definition comp.c:163
#define COMP_F_ALLOW_STUB_ONLY
Definition comp.h:41
#define COMP_ALG_LZ4
Definition comp.h:51
#define COMP_ALGV2_LZ4
Definition comp.h:56
#define COMP_F_ALLOW_NOCOMP_ONLY
Definition comp.h:44
#define COMP_ALGV2_UNCOMPRESSED
Definition comp.h:55
#define COMP_ALG_STUB
Definition comp.h:48
#define COMP_ALG_LZO
Definition comp.h:49
#define COMP_F_ADVERTISE_STUBS_ONLY
Definition comp.h:40
static bool comp_non_stub_enabled(const struct compress_options *info)
Definition comp.h:73
#define COMP_ALG_UNDEF
Definition comp.h:47
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
void status_printf(struct status_output *so, const char *format,...)
Definition status.c:222
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
unsigned int flags
Definition comp.h:69