src/openvpn/comp.h
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 */