/* * 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-2012 OpenVPN Technologies, Inc. * * 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 */ /* * Generic compression support. Currently we support * LZO 2 and LZ4. */ #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 */ #define COMP_ALG_SNAPPY 3 /* Snappy algorithm (no longer supported) */ #define COMP_ALG_LZ4 4 /* LZ4 algorithm */ /* 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 */ /* * Length of prepended prefix on compressed packets */ #define COMP_PREFIX_LEN 1 /* * Prefix bytes */ #define NO_COMPRESS_BYTE 0xFA #define NO_COMPRESS_BYTE_SWAP 0xFB /* to maintain payload alignment, replace this byte with last byte of packet */ /* * Compress worst case size expansion (for any algorithm) * * LZO: len + len/8 + 128 + 3 * Snappy: len + len/6 + 32 * LZ4: len + len/255 + 16 (LZ4_COMPRESSBOUND(len)) */ #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 { 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); }; /* * Headers for each compression implementation */ #ifdef ENABLE_LZO #include "lzo.h" #endif #ifdef ENABLE_LZ4 #include "comp-lz4.h" #endif /* * Information that basically identifies a compression * algorithm and related flags. */ struct compress_options { int alg; unsigned int flags; }; /* * Workspace union of all supported compression algorithms */ union compress_workspace_union { #ifdef ENABLE_LZO struct lzo_compress_workspace lzo; #endif #ifdef ENABLE_LZ4 struct lz4_workspace lz4; #endif }; /* * Context for active compression session */ struct compress_context { 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; }; extern const struct compress_alg comp_stub_alg; 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); void comp_add_to_extra_buffer(struct frame *frame); void comp_print_stats (const struct compress_context *compctx, struct status_output *so); void comp_generate_peer_info_string(const struct compress_options *opt, struct buffer *out); static inline bool comp_enabled(const struct compress_options *info) { return info->alg != COMP_ALG_UNDEF; } static inline bool comp_unswapped_prefix(const struct compress_options *info) { return !(info->flags & COMP_F_SWAP); } #endif /* USE_COMP */ #endif