summaryrefslogtreecommitdiff
path: root/src/openvpn/lzo.h
blob: 472204d05f8297292a2d8cee4733ab816466699c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program (see the file COPYING included with this
 *  distribution); if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef OPENVPN_LZO_H
#define OPENVPN_LZO_H


/**
 * @file
 * Data Channel Compression module header file.
 */


#ifdef ENABLE_LZO

/**
 * @addtogroup compression
 * @{
 */

#ifndef ENABLE_LZO_STUB
#if defined(HAVE_LZO_LZOUTIL_H)
#include "lzo/lzoutil.h"
#elif defined(HAVE_LZOUTIL_H)
#include "lzoutil.h"
#endif
#if defined(HAVE_LZO_LZO1X_H)
#include "lzo/lzo1x.h"
#elif defined(HAVE_LZO1X_H)
#include "lzo1x.h"
#endif
#endif

#include "buffer.h"
#include "mtu.h"
#include "common.h"
#include "status.h"

/**************************************************************************/
/** @name Bit-flags which control data channel packet compression *//******/
/** @{ */
#define LZO_SELECTED   (1<<0)   /**< Bit-flag indicating that compression
                                 *   of data channel packets is enabled. */
#define LZO_ON         (1<<1)   /**< Bit-flag indicating that compression
                                 *   of data channel packets is active. */
#define LZO_ADAPTIVE   (1<<2)   /**< Bit-flag indicating that adaptive
                                 *   compression of data channel packets
                                 *   has been selected. */
/** @} name Bit-flags which control data channel packet compression *//****/

/**************************************************************************/
/** @name LZO library interface defines *//** @{ *//***********************/
#ifndef ENABLE_LZO_STUB
#define LZO_COMPRESS    lzo1x_1_15_compress
                                /**< LZO library compression function.
                                 *
                                 *   Use \c lzo1x_1_15_compress because it
                                 *   is described as faster than the
                                 *   standard routine, although it does
                                 *   need a bit more memory. */
#define LZO_WORKSPACE	LZO1X_1_15_MEM_COMPRESS
                                /**< The size in bytes of the memory
                                 *   %buffer required by the LZO library
                                 *   compression algorithm. */
#define LZO_DECOMPRESS  lzo1x_decompress_safe
                                /**< LZO library decompression function.
                                 *
                                 *   Use safe decompress because it
                                 *   includes checks for possible %buffer
                                 *   overflows. If speed is essential and
                                 *   you will always be using a MAC to
                                 *   verify the integrity of incoming
                                 *   packets, you might want to consider
                                 *   using the non-safe version. */
#endif /* ENABLE_LZO_STUB */
/** @} name LZO library interface *//**************************************/


/**************************************************************************/
/** @name Miscellaneous compression defines *//** @{ *//*******************/
#define LZO_EXTRA_BUFFER(len) ((len)/8 + 128 + 3)
                                /**< LZO 2.0 worst-case size expansion. */
#ifndef ENABLE_LZO_STUB
#define COMPRESS_THRESHOLD 100  /**< Minimum packet size to attempt
                                 *   compression. */
#endif /* ENABLE_LZO_STUB */
/** @} name Miscellaneous compression defines *//**************************/


/**************************************************************************/
/** @name Compression header defines *//** @{ *//**************************/
#define LZO_PREFIX_LEN 1        /**< Length in bytes of prepended
                                 *   compression header. */
#define YES_COMPRESS 0x66       /**< Single-byte compression header
                                 *   indicating this packet has been
                                 *   compressed. */
#define NO_COMPRESS  0xFA       /**< Single-byte compression header
                                 *   indicating this packet has not been
                                 *   compressed. */
/** @} name Compression header defines *//*********************************/

/**************************************************************************/
/** @name Adaptive compression defines *//** @{ *//************************/
#ifndef ENABLE_LZO_STUB
#define AC_SAMP_SEC    2        /**< Number of seconds in a sample period. */
#define AC_MIN_BYTES   1000     /**< Minimum number of bytes a sample
                                 *   period must contain for it to be
                                 *   evaluated. */
#define AC_SAVE_PCT    5        /**< Minimum size reduction percentage
                                 *   below which compression will be
                                 *   turned off. */
#define AC_OFF_SEC     60       /**< Seconds to wait after compression has
                                 *   been turned off before retesting. */
#endif /* ENABLE_LZO_STUB */
/** @} name Adaptive compression defines *//*******************************/

#ifndef ENABLE_LZO_STUB

/**
 * Adaptive compression state.
 */
struct lzo_adaptive_compress {
  bool compress_state;
  time_t next;
  int n_total;
  int n_comp;
};

#endif /* ENABLE_LZO_STUB */


/**
 * State for the compression and decompression routines.
 *
 * This structure contains compression module state, such as whether
 * compression is enabled and the status of the adaptive compression
 * routines.  It also contains an allocated working buffer.
 *
 * One of these compression workspace structures is maintained for each
 * VPN tunnel.
 */
struct lzo_compress_workspace
{
  bool defined;
  unsigned int flags;
#ifndef ENABLE_LZO_STUB
  lzo_voidp wmem;
  int wmem_size;
  struct lzo_adaptive_compress ac;

  /* statistics */
  counter_type pre_decompress;
  counter_type post_decompress;
  counter_type pre_compress;
  counter_type post_compress;
#endif
};


/**************************************************************************/
/** @name Functions for initialization and cleanup *//** @{ *//************/

/**
 * Adjust %frame parameters for data channel payload compression.
 *
 * Data channel packet compression requires a single-byte header to
 * indicate whether a packet has been compressed or not. The packet
 * handling buffers must also allow for worst-case payload compression
 * where the compressed content size is actually larger than the original
 * content size. This function adjusts the parameters of a given frame
 * structure to include the header and allow for worst-case compression
 * expansion.
 *
 * @param frame        - The frame structure to adjust.
 */
void lzo_adjust_frame_parameters(struct frame *frame);

/**
 * Initialize a compression workspace structure.
 *
 * This function initializes the given workspace structure \a lzowork.
 * This includes allocating a work buffer for internal use and setting its
 * flags to the given value of \a flags.
 *
 * This function also initializes the lzo library.
 *
 * @param lzowork      - A pointer to the workspace structure to
 *                       initialize.
 * @param flags        - The initial flags to set in the workspace
 *                       structure.
 */
void lzo_compress_init (struct lzo_compress_workspace *lzowork, unsigned int flags);

/**
 * Cleanup a compression workspace structure.
 *
 * This function cleans up the given workspace structure \a lzowork.  This
 * includes freeing the structure's internal work buffer.
 *
 * @param lzowork      - A pointer to the workspace structure to clean up.
 */
void lzo_compress_uninit (struct lzo_compress_workspace *lzowork);

/**
 * Set a workspace structure's flags.
 *
 * @param lzowork      - The workspace structure of which to modify the
 *                       flags.
 * @param flags        - The new value to assign to the workspace
 *                       structure's flags.
 */
void lzo_modify_flags (struct lzo_compress_workspace *lzowork, unsigned int flags);

/** @} name Functions for initialization and cleanup *//*******************/


/**************************************************************************/
/** @name Function for packets to be sent to a remote OpenVPN peer *//*****/
/** @{ */

/**
 * Process an outgoing packet according to a VPN tunnel's settings.
 * @ingroup compression
 *
 * This function processes the packet contained in \a buf.  Its behavior
 * depends on the settings contained within \a lzowork.  If compression is
 * enabled and active, this function compresses the packet.  After
 * compression, the size of the uncompressed and compressed packets are
 * compared, and the smallest is used.
 *
 * This function prepends a one-byte header indicating whether the packet
 * was or was not compressed, so as to let the peer know how to handle the
 * packet.
 *
 * If an error occurs during processing, an error message is logged and
 * the length of \a buf is set to zero.
 *
 * @param buf          - A pointer to the buffer containing the outgoing
 *                       packet.  This pointer will be modified to point
 *                       to the processed packet on return.
 * @param work         - A preallocated working buffer.
 * @param lzowork      - The compression workspace structure associated
 *                       with this VPN tunnel.
 * @param frame        - The frame parameters of this tunnel.
 *
 * @return Void.\n  On return, \a buf will point to a buffer containing
 *     the processed, possibly compressed, packet data with a compression
 *     header prepended.
 */
void lzo_compress (struct buffer *buf, struct buffer work,
		   struct lzo_compress_workspace *lzowork,
		   const struct frame* frame);

/** @} name Function for packets to be sent to a remote OpenVPN peer *//***/


/**************************************************************************/
/** @name Function for packets received from a remote OpenVPN peer *//*****/
/** @{ */

/**
 * Inspect an incoming packet and decompress if it is compressed.
 *
 * This function inspects the incoming packet contained in \a buf.  If its
 * one-byte compression header indicates that it was compressed (i.e. \c
 * YES_COMPRESS), then it will be decompressed.  If its header indicates
 * that it was not compressed (i.e. \c NO_COMPRESS), then the buffer is
 * not modified except for removing the compression header.
 *
 * If an error occurs during processing, for example if the compression
 * header has a value other than \c YES_COMPRESS or \c NO_COMPRESS, then
 * the error is logged and the length of \a buf is set to zero.
 *
 * @param buf          - A pointer to the buffer containing the incoming
 *                       packet.  This pointer will be modified to point
 *                       to the processed packet on return.
 * @param work         - A preallocated working buffer.
 * @param lzowork      - The compression workspace structure associated
 *                       with this VPN tunnel.
 * @param frame        - The frame parameters of this tunnel.
 *
 * @return Void.\n  On return, \a buf will point to a buffer containing
 *     the uncompressed packet data and the one-byte compression header
 *     will have been removed.
 */
void lzo_decompress (struct buffer *buf, struct buffer work,
		     struct lzo_compress_workspace *lzowork,
		     const struct frame* frame);

/** @} name Function for packets received from a remote OpenVPN peer *//***/


/**************************************************************************/
/** @name Utility functions *//** @{ *//***********************************/

/**
 * Print statistics on compression and decompression performance.
 *
 * @param lzo_compwork - The workspace structure from which to get the
 *                       statistics.
 * @param so           - The status output structure to which to write the
 *                       statistics.
 */
void lzo_print_stats (const struct lzo_compress_workspace *lzo_compwork, struct status_output *so);

/**
 * Check whether compression is enabled for a workspace structure.
 *
 * @param lzowork      - The workspace structure to check.
 *
 * @return true if compression is enabled; false otherwise.
 */
static inline bool
lzo_defined (const struct lzo_compress_workspace *lzowork)
{
  return lzowork->defined;
}

/** @} name Utility functions *//******************************************/


/** @} addtogroup compression */


#endif /* ENABLE_LZO */
#endif