OpenVPN
compstub.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-2025 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, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#if defined(USE_COMP)
30
31#include "comp.h"
32#include "error.h"
33#include "otime.h"
34
35#include "memdbg.h"
36
37static void
38stub_compress_init(struct compress_context *compctx)
39{
40}
41
42static void
43stub_compress_uninit(struct compress_context *compctx)
44{
45}
46
47static void
48stub_compress(struct buffer *buf, struct buffer work, struct compress_context *compctx,
49 const struct frame *frame)
50{
51 if (buf->len <= 0)
52 {
53 return;
54 }
55 if (compctx->flags & COMP_F_SWAP)
56 {
57 uint8_t *head = BPTR(buf);
58 uint8_t *tail = BEND(buf);
59 ASSERT(buf_safe(buf, 1));
60 ++buf->len;
61
62 /* move head byte of payload to tail */
63 *tail = *head;
64 *head = NO_COMPRESS_BYTE_SWAP;
65 }
66 else
67 {
68 uint8_t *header = buf_prepend(buf, 1);
69 *header = NO_COMPRESS_BYTE;
70 }
71}
72
73static void
74stub_decompress(struct buffer *buf, struct buffer work, struct compress_context *compctx,
75 const struct frame *frame)
76{
77 uint8_t c;
78 if (buf->len <= 0)
79 {
80 return;
81 }
82 if (compctx->flags & COMP_F_SWAP)
83 {
84 uint8_t *head = BPTR(buf);
85 c = *head;
86 --buf->len;
87 *head = *BEND(buf);
88 if (c != NO_COMPRESS_BYTE_SWAP)
89 {
90 dmsg(D_COMP_ERRORS, "Bad compression stub (swap) decompression header byte: %d", c);
91 buf->len = 0;
92 }
93 }
94 else
95 {
96 c = *BPTR(buf);
97 ASSERT(buf_advance(buf, 1));
98 if (c != NO_COMPRESS_BYTE)
99 {
100 dmsg(D_COMP_ERRORS, "Bad compression stub decompression header byte: %d", c);
101 buf->len = 0;
102 }
103 }
104}
105
106
107static void
108stubv2_compress(struct buffer *buf, struct buffer work, struct compress_context *compctx,
109 const struct frame *frame)
110{
111 if (buf->len <= 0)
112 {
113 return;
114 }
115
116 compv2_escape_data_ifneeded(buf);
117}
118
119static void
120stubv2_decompress(struct buffer *buf, struct buffer work, struct compress_context *compctx,
121 const struct frame *frame)
122{
123 if (buf->len <= 0)
124 {
125 return;
126 }
127
128 uint8_t *head = BPTR(buf);
129
130 /* no compression or packet to short*/
131 if (head[0] != COMP_ALGV2_INDICATOR_BYTE)
132 {
133 return;
134 }
135
136 /* compression header (0x50) is present */
137 buf_advance(buf, 1);
138
139 /* Packet buffer too short (only 1 byte) */
140 if (buf->len <= 0)
141 {
142 return;
143 }
144
145 head = BPTR(buf);
146 buf_advance(buf, 1);
147
148 if (head[0] != COMP_ALGV2_UNCOMPRESSED_BYTE)
149 {
150 dmsg(D_COMP_ERRORS, "Bad compression stubv2 decompression header byte: %d", *head);
151 buf->len = 0;
152 return;
153 }
154}
155
156const struct compress_alg compv2_stub_alg = { "stubv2", stub_compress_init, stub_compress_uninit,
157 stubv2_compress, stubv2_decompress };
158
159const struct compress_alg comp_stub_alg = { "stub", stub_compress_init, stub_compress_uninit,
160 stub_compress, stub_decompress };
161#endif /* USE_STUB */
#define BEND(buf)
Definition buffer.h:124
#define BPTR(buf)
Definition buffer.h:123
static bool buf_safe(const struct buffer *buf, size_t len)
Definition buffer.h:518
static bool buf_advance(struct buffer *buf, int size)
Definition buffer.h:616
static uint8_t * buf_prepend(struct buffer *buf, int size)
Definition buffer.h:604
#define COMP_F_SWAP
initial command byte is swapped with last byte in buffer to preserve payload alignment
Definition comp.h:40
#define D_COMP_ERRORS
Definition errlevel.h:60
#define dmsg(flags,...)
Definition error.h:170
#define ASSERT(x)
Definition error.h:217
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Packet geometry parameters.
Definition mtu.h:103