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