38d96bd7 |
/*
* 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.
* |
49979459 |
* Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> |
38d96bd7 |
*
* 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.
* |
caa54ac3 |
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
38d96bd7 |
*/
/*
* Generic compression support. Currently we support |
9403e3f4 |
* LZO 2 and LZ4. |
38d96bd7 |
*/
#ifndef OPENVPN_COMP_H
#define OPENVPN_COMP_H
#ifdef USE_COMP
#include "buffer.h"
#include "mtu.h"
#include "common.h"
#include "status.h"
/* algorithms */
#define COMP_ALG_UNDEF 0
#define COMP_ALG_STUB 1 /* support compression command byte and framing without actual compression */
#define COMP_ALG_LZO 2 /* LZO algorithm */ |
9403e3f4 |
#define COMP_ALG_SNAPPY 3 /* Snappy algorithm (no longer supported) */ |
40efb635 |
#define COMP_ALG_LZ4 4 /* LZ4 algorithm */ |
38d96bd7 |
|
a75bb2e4 |
/* algorithm v2 */
#define COMP_ALGV2_UNCOMPRESSED 10 |
81d882d5 |
#define COMP_ALGV2_LZ4 11 |
a75bb2e4 |
/* |
81d882d5 |
#define COMP_ALGV2_LZO 12
#define COMP_ALGV2_SNAPPY 13
*/ |
a75bb2e4 |
|
38d96bd7 |
/* Compression flags */
#define COMP_F_ADAPTIVE (1<<0) /* COMP_ALG_LZO only */
#define COMP_F_ASYM (1<<1) /* only downlink is compressed, not uplink */
#define COMP_F_SWAP (1<<2) /* initial command byte is swapped with last byte in buffer to preserve payload alignment */
#define COMP_F_ADVERTISE_STUBS_ONLY (1<<3) /* tell server that we only support compression stubs */
|
a75bb2e4 |
|
38d96bd7 |
/*
* Length of prepended prefix on compressed packets
*/
#define COMP_PREFIX_LEN 1
/*
* Prefix bytes
*/ |
a75bb2e4 |
/* V1 on wire codes */
/* Initial command byte to tell our peer if we compressed */
#define LZO_COMPRESS_BYTE 0x66
#define LZ4_COMPRESS_BYTE 0x69 |
38d96bd7 |
#define NO_COMPRESS_BYTE 0xFA
#define NO_COMPRESS_BYTE_SWAP 0xFB /* to maintain payload alignment, replace this byte with last byte of packet */
|
a75bb2e4 |
/* V2 on wire code */ |
81d882d5 |
#define COMP_ALGV2_INDICATOR_BYTE 0x50
#define COMP_ALGV2_UNCOMPRESSED_BYTE 0
#define COMP_ALGV2_LZ4_BYTE 1
#define COMP_ALGV2_LZO_BYTE 2
#define COMP_ALGV2_SNAPPY_BYTE 3 |
a75bb2e4 |
|
38d96bd7 |
/*
* Compress worst case size expansion (for any algorithm)
*
* LZO: len + len/8 + 128 + 3
* Snappy: len + len/6 + 32 |
40efb635 |
* LZ4: len + len/255 + 16 (LZ4_COMPRESSBOUND(len)) |
38d96bd7 |
*/
#define COMP_EXTRA_BUFFER(len) ((len)/6 + 128 + 3 + COMP_PREFIX_LEN)
/*
* Don't try to compress any packet smaller than this.
*/
#define COMPRESS_THRESHOLD 100
/* Forward declaration of compression context */
struct compress_context;
/*
* Virtual methods and other static info for each compression algorithm
*/
struct compress_alg
{ |
81d882d5 |
const char *name;
void (*compress_init)(struct compress_context *compctx);
void (*compress_uninit)(struct compress_context *compctx);
void (*compress)(struct buffer *buf, struct buffer work,
struct compress_context *compctx,
const struct frame *frame);
void (*decompress)(struct buffer *buf, struct buffer work,
struct compress_context *compctx,
const struct frame *frame); |
38d96bd7 |
};
/*
* Headers for each compression implementation
*/
#ifdef ENABLE_LZO
#include "lzo.h"
#endif
|
40efb635 |
#ifdef ENABLE_LZ4
#include "comp-lz4.h"
#endif
|
38d96bd7 |
/*
* Information that basically identifies a compression
* algorithm and related flags.
*/
struct compress_options
{ |
81d882d5 |
int alg;
unsigned int flags; |
38d96bd7 |
};
/*
* Workspace union of all supported compression algorithms
*/
union compress_workspace_union
{
#ifdef ENABLE_LZO |
81d882d5 |
struct lzo_compress_workspace lzo; |
38d96bd7 |
#endif |
40efb635 |
#ifdef ENABLE_LZ4 |
81d882d5 |
struct lz4_workspace lz4; |
40efb635 |
#endif |
38d96bd7 |
};
/*
* Context for active compression session
*/
struct compress_context
{ |
81d882d5 |
unsigned int flags;
struct compress_alg alg;
union compress_workspace_union wu;
/* statistics */
counter_type pre_decompress;
counter_type post_decompress;
counter_type pre_compress;
counter_type post_compress; |
38d96bd7 |
};
extern const struct compress_alg comp_stub_alg; |
a75bb2e4 |
extern const struct compress_alg compv2_stub_alg; |
38d96bd7 |
struct compress_context *comp_init(const struct compress_options *opt);
void comp_uninit(struct compress_context *compctx);
void comp_add_to_extra_frame(struct frame *frame); |
81d882d5 |
|
38d96bd7 |
void comp_add_to_extra_buffer(struct frame *frame);
|
81d882d5 |
void comp_print_stats(const struct compress_context *compctx, struct status_output *so); |
38d96bd7 |
void comp_generate_peer_info_string(const struct compress_options *opt, struct buffer *out);
|
81d882d5 |
void compv2_escape_data_ifneeded(struct buffer *buf); |
a75bb2e4 |
|
38d96bd7 |
static inline bool
comp_enabled(const struct compress_options *info)
{ |
81d882d5 |
return info->alg != COMP_ALG_UNDEF; |
38d96bd7 |
}
static inline bool
comp_unswapped_prefix(const struct compress_options *info)
{ |
81d882d5 |
return !(info->flags & COMP_F_SWAP); |
38d96bd7 |
}
#endif /* USE_COMP */ |
81d882d5 |
#endif /* ifndef OPENVPN_COMP_H */ |