diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2013-05-03 10:20:54 +0200 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2013-05-03 10:20:54 +0200 | 
| commit | 240d3a0cbdc46e4ed08d1015a2d4f1ca52bbdd55 (patch) | |
| tree | 638fc6d01acc724a90a25eb3e069eef826919ee7 /openvpn/src | |
| parent | 0106121c24783a83ec4c816e660abed212c92fd9 (diff) | |
Add snappy library. In preparation for upcoming snappy support of OpenVPN
Diffstat (limited to 'openvpn/src')
| -rw-r--r-- | openvpn/src/openvpn/Makefile.am | 4 | ||||
| -rw-r--r-- | openvpn/src/openvpn/forward.c | 12 | ||||
| -rw-r--r-- | openvpn/src/openvpn/init.c | 100 | ||||
| -rw-r--r-- | openvpn/src/openvpn/lzo.c | 154 | ||||
| -rw-r--r-- | openvpn/src/openvpn/lzo.h | 222 | ||||
| -rw-r--r-- | openvpn/src/openvpn/openvpn.h | 16 | ||||
| -rw-r--r-- | openvpn/src/openvpn/options.c | 100 | ||||
| -rw-r--r-- | openvpn/src/openvpn/options.h | 7 | ||||
| -rw-r--r-- | openvpn/src/openvpn/sig.c | 6 | ||||
| -rw-r--r-- | openvpn/src/openvpn/ssl.c | 86 | ||||
| -rw-r--r-- | openvpn/src/openvpn/ssl_common.h | 5 | ||||
| -rw-r--r-- | openvpn/src/openvpn/syshead.h | 7 | 
12 files changed, 287 insertions, 432 deletions
| diff --git a/openvpn/src/openvpn/Makefile.am b/openvpn/src/openvpn/Makefile.am index 5d38628d..70e19c2c 100644 --- a/openvpn/src/openvpn/Makefile.am +++ b/openvpn/src/openvpn/Makefile.am @@ -26,6 +26,7 @@ AM_CFLAGS = \  	$(TAP_CFLAGS) \  	$(OPTIONAL_CRYPTO_CFLAGS) \  	$(OPTIONAL_LZO_CFLAGS) \ +	$(OPTIONAL_SNAPPY_CFLAGS) \  	$(OPTIONAL_PKCS11_HELPER_CFLAGS)  if WIN32  # we want unicode entry point but not the macro @@ -41,6 +42,7 @@ openvpn_SOURCES = \  	circ_list.h \  	clinat.c clinat.h \  	common.h \ +	comp.c comp.h compstub.c \  	crypto.c crypto.h crypto_backend.h \  	crypto_openssl.c crypto_openssl.h \  	crypto_polarssl.c crypto_polarssl.h \ @@ -98,6 +100,7 @@ openvpn_SOURCES = \  	session_id.c session_id.h \  	shaper.c shaper.h \  	sig.c sig.h \ +	snappy.c snappy.h \  	socket.c socket.h \  	socks.c socks.h \  	ssl.c ssl.h  ssl_backend.h \ @@ -116,6 +119,7 @@ openvpn_LDADD = \  	$(top_builddir)/src/compat/libcompat.la \  	$(SOCKETS_LIBS) \  	$(OPTIONAL_LZO_LIBS) \ +	$(OPTIONAL_SNAPPY_LIBS) \  	$(OPTIONAL_PKCS11_HELPER_LIBS) \  	$(OPTIONAL_CRYPTO_LIBS) \  	$(OPTIONAL_SELINUX_LIBS) \ diff --git a/openvpn/src/openvpn/forward.c b/openvpn/src/openvpn/forward.c index 9e9c406c..9fcae11b 100644 --- a/openvpn/src/openvpn/forward.c +++ b/openvpn/src/openvpn/forward.c @@ -444,10 +444,10 @@ encrypt_sign (struct context *c, bool comp_frag)    if (comp_frag)      { -#ifdef ENABLE_LZO +#ifdef USE_COMP        /* Compress the packet. */ -      if (lzo_defined (&c->c2.lzo_compwork)) -	lzo_compress (&c->c2.buf, b->lzo_compress_buf, &c->c2.lzo_compwork, &c->c2.frame); +      if (c->c2.comp_context) +	(*c->c2.comp_context->alg.compress)(&c->c2.buf, b->compress_buf, c->c2.comp_context, &c->c2.frame);  #endif  #ifdef ENABLE_FRAGMENT        if (c->c2.fragment) @@ -846,10 +846,10 @@ process_incoming_link (struct context *c)  	fragment_incoming (c->c2.fragment, &c->c2.buf, &c->c2.frame_fragment);  #endif -#ifdef ENABLE_LZO +#ifdef USE_COMP        /* decompress the incoming packet */ -      if (lzo_defined (&c->c2.lzo_compwork)) -	lzo_decompress (&c->c2.buf, c->c2.buffers->lzo_decompress_buf, &c->c2.lzo_compwork, &c->c2.frame); +      if (c->c2.comp_context) +	(*c->c2.comp_context->alg.decompress)(&c->c2.buf, c->c2.buffers->decompress_buf, c->c2.comp_context, &c->c2.frame);  #endif  #ifdef PACKET_TRUNCATION_CHECK diff --git a/openvpn/src/openvpn/init.c b/openvpn/src/openvpn/init.c index be2ca9df..4af79657 100644 --- a/openvpn/src/openvpn/init.c +++ b/openvpn/src/openvpn/init.c @@ -1783,14 +1783,12 @@ do_deferred_options (struct context *c, const unsigned int found)      }  #endif -#ifdef ENABLE_LZO +#ifdef USE_COMP    if (found & OPT_P_COMP)      { -      if (lzo_defined (&c->c2.lzo_compwork)) -	{ -	  msg (D_PUSH, "OPTIONS IMPORT: LZO parms modified"); -	  lzo_modify_flags (&c->c2.lzo_compwork, c->options.lzo); -	} +      msg (D_PUSH, "OPTIONS IMPORT: compression parms modified"); +      comp_uninit (c->c2.comp_context); +      c->c2.comp_context = comp_init (&c->options.comp);      }  #endif @@ -2279,6 +2277,10 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)  #endif  #endif +#ifdef USE_COMP +  to.comp_options = options->comp; +#endif +    /* TLS handshake authentication (--tls-auth) */    if (options->tls_auth_file)      { @@ -2361,30 +2363,50 @@ do_init_crypto (struct context *c, const unsigned int flags)  static void  do_init_frame (struct context *c)  { -#ifdef ENABLE_LZO +#ifdef USE_COMP    /* -   * Initialize LZO compression library. +   * modify frame parameters if compression is enabled     */ -  if (c->options.lzo & LZO_SELECTED) +  if (comp_enabled(&c->options.comp))      { -      lzo_adjust_frame_parameters (&c->c2.frame); +      comp_add_to_extra_frame (&c->c2.frame); +#if !defined(ENABLE_SNAPPY)        /* -       * LZO usage affects buffer alignment. +       * Compression usage affects buffer alignment when non-swapped algs +       * such as LZO is used. +       * Newer algs like Snappy and comp-stub with COMP_F_SWAP don't need +       * any special alignment because of the control-byte swap approach. +       * LZO alignment (on the other hand) is problematic because +       * the presence of the control byte means that either the output of +       * decryption must be written to an unaligned buffer, or the input +       * to compression (or packet dispatch if packet is uncompressed) +       * must be read from an unaligned buffer. +       * This code tries to align the input to compression (or packet +       * dispatch if packet is uncompressed) at the cost of requiring +       * decryption output to be written to an unaligned buffer, so +       * it's more of a tradeoff than an optimal solution and we don't +       * include it when we are doing a modern build with Snappy. +       * Strictly speaking, on the server it would be better to execute +       * this code for every connection after we decide the compression +       * method, but currently the frame code doesn't appear to be +       * flexible enough for this, since the frame is already established +       * before it is known which compression options will be pushed.         */ -      if (CIPHER_ENABLED (c)) +      if (comp_unswapped_prefix (&c->options.comp) && CIPHER_ENABLED (c))  	{ -	  frame_add_to_align_adjust (&c->c2.frame, LZO_PREFIX_LEN); +	  frame_add_to_align_adjust (&c->c2.frame, COMP_PREFIX_LEN);  	  frame_or_align_flags (&c->c2.frame,  				FRAME_HEADROOM_MARKER_FRAGMENT  				|FRAME_HEADROOM_MARKER_DECRYPT);  	} +#endif  #ifdef ENABLE_FRAGMENT -      lzo_adjust_frame_parameters (&c->c2.frame_fragment_omit);	/* omit LZO frame delta from final frame_fragment */ +      comp_add_to_extra_frame (&c->c2.frame_fragment_omit); /* omit compression frame delta from final frame_fragment */  #endif      } -#endif /* ENABLE_LZO */ +#endif /* USE_COMP */  #ifdef ENABLE_SOCKS    /* @@ -2413,6 +2435,17 @@ do_init_frame (struct context *c)     */    frame_finalize_options (c, NULL); +#ifdef USE_COMP +  /* +   * Modify frame parameters if compression is compiled in. +   * Should be called after frame_finalize_options. +   */ +  comp_add_to_extra_buffer (&c->c2.frame); +#ifdef ENABLE_FRAGMENT +  comp_add_to_extra_buffer (&c->c2.frame_fragment_omit); /* omit compression frame delta from final frame_fragment */ +#endif +#endif /* USE_COMP */ +  #ifdef ENABLE_FRAGMENT    /*     * Set frame parameter for fragment code.  This is necessary because @@ -2538,9 +2571,9 @@ init_context_buffers (const struct frame *frame)    b->decrypt_buf = alloc_buf (BUF_SIZE (frame));  #endif -#ifdef ENABLE_LZO -  b->lzo_compress_buf = alloc_buf (BUF_SIZE (frame)); -  b->lzo_decompress_buf = alloc_buf (BUF_SIZE (frame)); +#ifdef USE_COMP +  b->compress_buf = alloc_buf (BUF_SIZE (frame)); +  b->decompress_buf = alloc_buf (BUF_SIZE (frame));  #endif    return b; @@ -2555,9 +2588,9 @@ free_context_buffers (struct context_buffers *b)        free_buf (&b->read_tun_buf);        free_buf (&b->aux_buf); -#ifdef ENABLE_LZO -      free_buf (&b->lzo_compress_buf); -      free_buf (&b->lzo_decompress_buf); +#ifdef USE_COMP +      free_buf (&b->compress_buf); +      free_buf (&b->decompress_buf);  #endif  #ifdef ENABLE_CRYPTO @@ -3402,10 +3435,10 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int        goto sig;    } -#ifdef ENABLE_LZO -  /* initialize LZO compression library. */ -  if ((options->lzo & LZO_SELECTED) && (c->mode == CM_P2P || child)) -    lzo_compress_init (&c->c2.lzo_compwork, options->lzo); +#ifdef USE_COMP +  /* initialize compression library. */ +  if (comp_enabled(&options->comp) && (c->mode == CM_P2P || child)) +    c->c2.comp_context = comp_init (&options->comp);  #endif    /* initialize MTU variables */ @@ -3519,9 +3552,12 @@ close_instance (struct context *c)  	/* if xinetd/inetd mode, don't allow restart */  	do_close_check_if_restart_permitted (c); -#ifdef ENABLE_LZO -	if (lzo_defined (&c->c2.lzo_compwork)) -	  lzo_compress_uninit (&c->c2.lzo_compwork); +#ifdef USE_COMP +	if (c->c2.comp_context) +	  { +	    comp_uninit (c->c2.comp_context); +	    c->c2.comp_context = NULL; +	  }  #endif  	/* free buffers */ @@ -3645,6 +3681,10 @@ inherit_context_child (struct context *dest,        dest->c2.link_socket_info->lsa = &dest->c1.link_socket_addr;        dest->c2.link_socket_info->connection_established = false;      } + +#ifdef USE_COMP +  dest->c2.comp_context = NULL; +#endif  }  void @@ -3693,6 +3733,10 @@ inherit_context_top (struct context *dest,    dest->c2.event_set = NULL;    if (proto_is_dgram(src->options.ce.proto))      do_event_set_init (dest, false); + +#ifdef USE_COMP +  dest->c2.comp_context = NULL; +#endif  }  void diff --git a/openvpn/src/openvpn/lzo.c b/openvpn/src/openvpn/lzo.c index 195b8194..daa02ed0 100644 --- a/openvpn/src/openvpn/lzo.c +++ b/openvpn/src/openvpn/lzo.c @@ -34,15 +34,17 @@  #include "syshead.h" -#ifdef ENABLE_LZO +#if defined(ENABLE_LZO) -#include "lzo.h" +#include "comp.h"  #include "error.h"  #include "otime.h"  #include "memdbg.h" -#ifndef ENABLE_LZO_STUB +/* Initial command byte to tell our peer if we compressed */ +#define LZO_COMPRESS_BYTE 0x66 +  /**   * Perform adaptive compression housekeeping.   * @@ -97,101 +99,69 @@ lzo_adaptive_compress_data (struct lzo_adaptive_compress *ac, int n_total, int n    ac->n_comp += n_comp;  } -#endif /* ENABLE_LZO_STUB */ - -void lzo_adjust_frame_parameters (struct frame *frame) -{ -  /* Leave room for our one-byte compressed/didn't-compress prefix byte. */ -  frame_add_to_extra_frame (frame, LZO_PREFIX_LEN); - -  /* Leave room for compression buffer to expand in worst case scenario -     where data is totally uncompressible */ -  frame_add_to_extra_buffer (frame, LZO_EXTRA_BUFFER (EXPANDED_SIZE(frame))); -} - -void -lzo_compress_init (struct lzo_compress_workspace *lzowork, unsigned int flags) +static void +lzo_compress_init (struct compress_context *compctx)  { -  CLEAR (*lzowork); - -  lzowork->flags = flags; -#ifndef ENABLE_LZO_STUB -  lzowork->wmem_size = LZO_WORKSPACE; - +  msg (D_INIT_MEDIUM, "LZO compression initializing"); +  ASSERT(!(compctx->flags & COMP_F_SWAP)); +  compctx->wu.lzo.wmem_size = LZO_WORKSPACE;    if (lzo_init () != LZO_E_OK)      msg (M_FATAL, "Cannot initialize LZO compression library"); -  lzowork->wmem = (lzo_voidp) lzo_malloc (lzowork->wmem_size); -  check_malloc_return (lzowork->wmem); -  msg (D_INIT_MEDIUM, "LZO compression initialized"); -#else -  msg (D_INIT_MEDIUM, "LZO stub compression initialized"); -#endif -  lzowork->defined = true; +  compctx->wu.lzo.wmem = (lzo_voidp) lzo_malloc (compctx->wu.lzo.wmem_size); +  check_malloc_return (compctx->wu.lzo.wmem);  } -void -lzo_compress_uninit (struct lzo_compress_workspace *lzowork) +static void +lzo_compress_uninit (struct compress_context *compctx)  { -  if (lzowork) -    { -      ASSERT (lzowork->defined); -#ifndef ENABLE_LZO_STUB -      lzo_free (lzowork->wmem); -      lzowork->wmem = NULL; -#endif -      lzowork->defined = false; -    } +  lzo_free (compctx->wu.lzo.wmem); +  compctx->wu.lzo.wmem = NULL;  }  static inline bool -lzo_compression_enabled (struct lzo_compress_workspace *lzowork) +lzo_compression_enabled (struct compress_context *compctx)  { -#ifndef ENABLE_LZO_STUB -  if ((lzowork->flags & (LZO_SELECTED|LZO_ON)) == (LZO_SELECTED|LZO_ON)) +  if (compctx->flags & COMP_F_ASYM) +    return false; +  else      { -      if (lzowork->flags & LZO_ADAPTIVE) -	return lzo_adaptive_compress_test (&lzowork->ac); +      if (compctx->flags & COMP_F_ADAPTIVE) +	return lzo_adaptive_compress_test (&compctx->wu.lzo.ac);        else  	return true;      } -#endif -  return false;  } -void +static void  lzo_compress (struct buffer *buf, struct buffer work, -	      struct lzo_compress_workspace *lzowork, +	      struct compress_context *compctx,  	      const struct frame* frame)  { -#ifndef ENABLE_LZO_STUB    lzo_uint zlen = 0;    int err;    bool compressed = false; -#endif - -  ASSERT (lzowork->defined);    if (buf->len <= 0)      return; -#ifndef ENABLE_LZO_STUB    /*     * In order to attempt compression, length must be at least COMPRESS_THRESHOLD,     * and our adaptive level must give the OK.     */ -  if (buf->len >= COMPRESS_THRESHOLD && lzo_compression_enabled (lzowork)) +  if (buf->len >= COMPRESS_THRESHOLD && lzo_compression_enabled (compctx))      { +      const size_t ps = PAYLOAD_SIZE (frame);        ASSERT (buf_init (&work, FRAME_HEADROOM (frame))); -      ASSERT (buf_safe (&work, LZO_EXTRA_BUFFER (PAYLOAD_SIZE (frame)))); +      ASSERT (buf_safe (&work, ps + COMP_EXTRA_BUFFER (ps))); -      if (!(buf->len <= PAYLOAD_SIZE (frame))) +      if (buf->len > ps)  	{  	  dmsg (D_COMP_ERRORS, "LZO compression buffer overflow");  	  buf->len = 0;  	  return;  	} -      err = LZO_COMPRESS (BPTR (buf), BLEN (buf), BPTR (&work), &zlen, lzowork->wmem); +      err = LZO_COMPRESS (BPTR (buf), BLEN (buf), BPTR (&work), &zlen, compctx->wu.lzo.wmem);        if (err != LZO_E_OK)  	{  	  dmsg (D_COMP_ERRORS, "LZO compression error: %d", err); @@ -203,43 +173,38 @@ lzo_compress (struct buffer *buf, struct buffer work,        work.len = zlen;        compressed = true; -      dmsg (D_COMP, "compress %d -> %d", buf->len, work.len); -      lzowork->pre_compress += buf->len; -      lzowork->post_compress += work.len; +      dmsg (D_COMP, "LZO compress %d -> %d", buf->len, work.len); +      compctx->pre_compress += buf->len; +      compctx->post_compress += work.len;        /* tell adaptive level about our success or lack thereof in getting any size reduction */ -      if (lzowork->flags & LZO_ADAPTIVE) -	lzo_adaptive_compress_data (&lzowork->ac, buf->len, work.len); +      if (compctx->flags & COMP_F_ADAPTIVE) +	lzo_adaptive_compress_data (&compctx->wu.lzo.ac, buf->len, work.len);      }    /* did compression save us anything ? */    if (compressed && work.len < buf->len)      {        uint8_t *header = buf_prepend (&work, 1); -      *header = YES_COMPRESS; +      *header = LZO_COMPRESS_BYTE;        *buf = work;      }    else -#endif      {        uint8_t *header = buf_prepend (buf, 1); -      *header = NO_COMPRESS; +      *header = NO_COMPRESS_BYTE;      }  } -void +static void  lzo_decompress (struct buffer *buf, struct buffer work, -		struct lzo_compress_workspace *lzowork, +		struct compress_context *compctx,  		const struct frame* frame)  { -#ifndef ENABLE_LZO_STUB    lzo_uint zlen = EXPANDED_SIZE (frame);    int err; -#endif    uint8_t c;		/* flag indicating whether or not our peer compressed */ -  ASSERT (lzowork->defined); -    if (buf->len <= 0)      return; @@ -248,12 +213,11 @@ lzo_decompress (struct buffer *buf, struct buffer work,    c = *BPTR (buf);    ASSERT (buf_advance (buf, 1)); -  if (c == YES_COMPRESS)	/* packet was compressed */ +  if (c == LZO_COMPRESS_BYTE)	/* packet was compressed */      { -#ifndef ENABLE_LZO_STUB        ASSERT (buf_safe (&work, zlen));        err = LZO_DECOMPRESS (BPTR (buf), BLEN (buf), BPTR (&work), &zlen, -			    lzowork->wmem); +			    compctx->wu.lzo.wmem);        if (err != LZO_E_OK)  	{  	  dmsg (D_COMP_ERRORS, "LZO decompression error: %d", err); @@ -264,18 +228,13 @@ lzo_decompress (struct buffer *buf, struct buffer work,        ASSERT (buf_safe (&work, zlen));        work.len = zlen; -      dmsg (D_COMP, "decompress %d -> %d", buf->len, work.len); -      lzowork->pre_decompress += buf->len; -      lzowork->post_decompress += work.len; +      dmsg (D_COMP, "LZO decompress %d -> %d", buf->len, work.len); +      compctx->pre_decompress += buf->len; +      compctx->post_decompress += work.len;        *buf = work; -#else -      dmsg (D_COMP_ERRORS, "LZO decompression error: LZO capability not compiled"); -      buf->len = 0; -      return; -#endif      } -  else if (c == NO_COMPRESS)	/* packet was not compressed */ +  else if (c == NO_COMPRESS_BYTE)	/* packet was not compressed */      {        ;      } @@ -286,24 +245,13 @@ lzo_decompress (struct buffer *buf, struct buffer work,      }  } -void -lzo_modify_flags (struct lzo_compress_workspace *lzowork, unsigned int flags) -{ -  ASSERT (lzowork->defined); -  lzowork->flags = flags; -} - -void lzo_print_stats (const struct lzo_compress_workspace *lzo_compwork, struct status_output *so) -{ -  ASSERT (lzo_compwork->defined); - -#ifndef ENABLE_LZO_STUB -  status_printf (so, "pre-compress bytes," counter_format, lzo_compwork->pre_compress); -  status_printf (so, "post-compress bytes," counter_format, lzo_compwork->post_compress); -  status_printf (so, "pre-decompress bytes," counter_format, lzo_compwork->pre_decompress); -  status_printf (so, "post-decompress bytes," counter_format, lzo_compwork->post_decompress); -#endif -} +const struct compress_alg lzo_alg = { +  "lzo", +  lzo_compress_init, +  lzo_compress_uninit, +  lzo_compress, +  lzo_decompress +};  #else  static void dummy(void) {} diff --git a/openvpn/src/openvpn/lzo.h b/openvpn/src/openvpn/lzo.h index 472204d0..f33e587a 100644 --- a/openvpn/src/openvpn/lzo.h +++ b/openvpn/src/openvpn/lzo.h @@ -32,14 +32,13 @@   */ -#ifdef ENABLE_LZO +#if defined(ENABLE_LZO)  /**   * @addtogroup compression   * @{   */ -#ifndef ENABLE_LZO_STUB  #if defined(HAVE_LZO_LZOUTIL_H)  #include "lzo/lzoutil.h"  #elif defined(HAVE_LZOUTIL_H) @@ -50,28 +49,16 @@  #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 *//****/ +extern const struct compress_alg lzo_alg;  /**************************************************************************/  /** @name LZO library interface defines *//** @{ *//***********************/ -#ifndef ENABLE_LZO_STUB  #define LZO_COMPRESS    lzo1x_1_15_compress                                  /**< LZO library compression function.                                   * @@ -93,36 +80,11 @@                                   *   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 @@ -132,11 +94,8 @@                                   *   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.   */ @@ -147,8 +106,6 @@ struct lzo_adaptive_compress {    int n_comp;  }; -#endif /* ENABLE_LZO_STUB */ -  /**   * State for the compression and decompression routines. @@ -162,186 +119,13 @@ struct lzo_adaptive_compress {   */  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 /* ENABLE_LZO && USE_COMP */  #endif diff --git a/openvpn/src/openvpn/openvpn.h b/openvpn/src/openvpn/openvpn.h index bdfa6852..606a4f59 100644 --- a/openvpn/src/openvpn/openvpn.h +++ b/openvpn/src/openvpn/openvpn.h @@ -31,7 +31,7 @@  #include "crypto.h"  #include "ssl.h"  #include "packet_id.h" -#include "lzo.h" +#include "comp.h"  #include "tun.h"  #include "interval.h"  #include "status.h" @@ -104,10 +104,10 @@ struct context_buffers    struct buffer decrypt_buf;  #endif -  /* workspace buffers for LZO compression */ -#ifdef ENABLE_LZO -  struct buffer lzo_compress_buf; -  struct buffer lzo_decompress_buf; +  /* workspace buffers for compression */ +#ifdef USE_COMP +  struct buffer compress_buf; +  struct buffer decompress_buf;  #endif    /* @@ -372,9 +372,9 @@ struct context_2  #endif /* ENABLE_CRYPTO */ -#ifdef ENABLE_LZO -  struct lzo_compress_workspace lzo_compwork; -                                /**< Compression workspace used by the +#ifdef USE_COMP +  struct compress_context *comp_context; +                                /**< Compression context used by the                                   *   \link compression Data Channel                                   *   Compression module\endlink. */  #endif diff --git a/openvpn/src/openvpn/options.c b/openvpn/src/openvpn/options.c index db1cb33a..7dba31a7 100644 --- a/openvpn/src/openvpn/options.c +++ b/openvpn/src/openvpn/options.c @@ -84,13 +84,17 @@ const char title_string[] =  #endif /* defined(ENABLE_CRYPTO_POLARSSL) */  #endif /* ENABLE_SSL */  #endif /* ENABLE_CRYPTO */ +#ifdef USE_COMP  #ifdef ENABLE_LZO -#ifdef ENABLE_LZO_STUB -  " [LZO (STUB)]" -#else    " [LZO]"  #endif +#ifdef ENABLE_SNAPPY +  " [SNAPPY]" +#endif +#ifdef ENABLE_COMP_STUB +  " [COMP_STUB]"  #endif +#endif /* USE_COMP */  #if EPOLL    " [EPOLL]"  #endif @@ -362,12 +366,15 @@ static const char usage_message[] =  #ifdef ENABLE_DEBUG    "--gremlin mask  : Special stress testing mode (for debugging only).\n"  #endif -#ifdef ENABLE_LZO -  "--comp-lzo      : Use fast LZO compression -- may add up to 1 byte per\n" +#if defined(USE_COMP) +  "--compress alg  : Use compression algorithm alg\n" +#if defined(ENABLE_LZO) +  "--comp-lzo      : Use LZO compression -- may add up to 1 byte per\n"    "                  packet for uncompressible data.\n"    "--comp-noadapt  : Don't use adaptive compression when --comp-lzo\n"    "                  is specified.\n"  #endif +#endif  #ifdef ENABLE_MANAGEMENT    "--management ip port [pass] : Enable a TCP server on ip:port to handle\n"    "                  management functions.  pass is a password file\n" @@ -1512,8 +1519,9 @@ show_settings (const struct options *o)    SHOW_BOOL (fast_io); -#ifdef ENABLE_LZO -  SHOW_INT (lzo); +#ifdef USE_COMP +  SHOW_INT (comp.alg); +  SHOW_INT (comp.flags);  #endif    SHOW_STR (route_script); @@ -2852,6 +2860,7 @@ pre_pull_restore (struct options *o)   *                 the other end of the connection]   *   * --comp-lzo + * --compress alg   * --fragment   *   * Crypto Options: @@ -2933,9 +2942,9 @@ options_string (const struct options *o,        tt = NULL;      } -#ifdef ENABLE_LZO -  if (o->lzo & LZO_SELECTED) -    buf_printf (&out, ",comp-lzo"); +#ifdef USE_COMP +  if (o->comp.alg != COMP_ALG_UNDEF) +    buf_printf (&out, ",comp-lzo"); /* for compatibility, this simply indicates that compression context is active, not necessarily LZO per-se */  #endif  #ifdef ENABLE_FRAGMENT @@ -6039,18 +6048,31 @@ add_option (struct options *options,        options->passtos = true;      }  #endif -#ifdef ENABLE_LZO +#if defined(USE_COMP)    else if (streq (p[0], "comp-lzo"))      {        VERIFY_PERMISSION (OPT_P_COMP); -      if (p[1]) + +#if defined(ENABLE_LZO) +      if (p[1] && streq (p[1], "no")) +#endif +	{ +	  options->comp.alg = COMP_ALG_STUB; +	  options->comp.flags = 0; +	} +#if defined(ENABLE_LZO) +      else if (p[1])  	{  	  if (streq (p[1], "yes")) -	    options->lzo = LZO_SELECTED|LZO_ON; -	  else if (streq (p[1], "no")) -	    options->lzo = LZO_SELECTED; +	    { +	      options->comp.alg = COMP_ALG_LZO; +	      options->comp.flags = 0; +	    }  	  else if (streq (p[1], "adaptive")) -	    options->lzo = LZO_SELECTED|LZO_ON|LZO_ADAPTIVE; +	    { +	      options->comp.alg = COMP_ALG_LZO; +	      options->comp.flags = COMP_F_ADAPTIVE; +	    }  	  else  	    {  	      msg (msglevel, "bad comp-lzo option: %s -- must be 'yes', 'no', or 'adaptive'", p[1]); @@ -6058,14 +6080,54 @@ add_option (struct options *options,  	    }  	}        else -	options->lzo = LZO_SELECTED|LZO_ON|LZO_ADAPTIVE; +	{ +	  options->comp.alg = COMP_ALG_LZO; +	  options->comp.flags = COMP_F_ADAPTIVE; +	} +#endif      }    else if (streq (p[0], "comp-noadapt"))      {        VERIFY_PERMISSION (OPT_P_COMP); -      options->lzo &= ~LZO_ADAPTIVE; +      options->comp.flags &= ~COMP_F_ADAPTIVE; +    } +  else if (streq (p[0], "compress")) +    { +      VERIFY_PERMISSION (OPT_P_COMP); +      if (p[1]) +	{ +	  if (streq (p[1], "stub")) +	    { +	      options->comp.alg = COMP_ALG_STUB; +	      options->comp.flags = (COMP_F_SWAP|COMP_F_ADVERTISE_STUBS_ONLY); +	    } +#if defined(ENABLE_LZO) +	  else if (streq (p[1], "lzo")) +	    { +	      options->comp.alg = COMP_ALG_LZO; +	      options->comp.flags = 0; +	    } +#endif +#if defined(ENABLE_SNAPPY) +	  else if (streq (p[1], "snappy")) +	    { +	      options->comp.alg = COMP_ALG_SNAPPY; +	      options->comp.flags = COMP_F_SWAP; +	    } +#endif +	  else +	    { +	      msg (msglevel, "bad comp option: %s", p[1]); +	      goto err; +	    } +	} +      else +	{ +	  options->comp.alg = COMP_ALG_STUB; +	  options->comp.flags = COMP_F_SWAP; +	}      } -#endif /* ENABLE_LZO */ +#endif /* USE_COMP */  #ifdef ENABLE_CRYPTO    else if (streq (p[0], "show-ciphers"))      { diff --git a/openvpn/src/openvpn/options.h b/openvpn/src/openvpn/options.h index e5de2f10..56359357 100644 --- a/openvpn/src/openvpn/options.h +++ b/openvpn/src/openvpn/options.h @@ -39,7 +39,7 @@  #include "plugin.h"  #include "manage.h"  #include "proxy.h" -#include "lzo.h" +#include "comp.h"  #include "pushlist.h"  #include "clinat.h" @@ -316,9 +316,8 @@ struct options    /* optimize TUN/TAP/UDP writes */    bool fast_io; -#ifdef ENABLE_LZO -  /* LZO_x flags from lzo.h */ -  unsigned int lzo; +#ifdef USE_COMP +  struct compress_options comp;  #endif    /* buffer sizes */ diff --git a/openvpn/src/openvpn/sig.c b/openvpn/src/openvpn/sig.c index 7ddfd0ed..90e39a42 100644 --- a/openvpn/src/openvpn/sig.c +++ b/openvpn/src/openvpn/sig.c @@ -279,9 +279,9 @@ print_status (const struct context *c, struct status_output *so)    status_printf (so, "TCP/UDP read bytes," counter_format, c->c2.link_read_bytes);    status_printf (so, "TCP/UDP write bytes," counter_format, c->c2.link_write_bytes);    status_printf (so, "Auth read bytes," counter_format, c->c2.link_read_bytes_auth); -#ifdef ENABLE_LZO -  if (lzo_defined (&c->c2.lzo_compwork)) -    lzo_print_stats (&c->c2.lzo_compwork, so); +#ifdef USE_COMP +  if (c->c2.comp_context) +    comp_print_stats (c->c2.comp_context, so);  #endif  #ifdef PACKET_TRUNCATION_CHECK    status_printf (so, "TUN read truncations," counter_format, c->c2.n_trunc_tun_read); diff --git a/openvpn/src/openvpn/ssl.c b/openvpn/src/openvpn/ssl.c index b3673864..7e261e75 100644 --- a/openvpn/src/openvpn/ssl.c +++ b/openvpn/src/openvpn/ssl.c @@ -1775,66 +1775,68 @@ push_peer_info(struct buffer *buf, struct tls_session *session)    bool ret = false;  #ifdef ENABLE_PUSH_PEER_INFO -  if (session->opt->push_peer_info) /* write peer info */ -    { -      struct env_set *es = session->opt->es; -      struct env_item *e; -      struct buffer out = alloc_buf_gc (512*3, &gc); +  { +    struct env_set *es = session->opt->es; +    struct env_item *e; +    struct buffer out = alloc_buf_gc (512*3, &gc); -      /* push version */ -      buf_printf (&out, "IV_VER=%s\n", PACKAGE_VERSION); +    /* push version */ +    buf_printf (&out, "IV_VER=%s\n", PACKAGE_VERSION); -      /* push platform */ +    /* push platform */  #if defined(TARGET_LINUX) -      buf_printf (&out, "IV_PLAT=linux\n"); +    buf_printf (&out, "IV_PLAT=linux\n");  #elif defined(TARGET_SOLARIS) -      buf_printf (&out, "IV_PLAT=solaris\n"); +    buf_printf (&out, "IV_PLAT=solaris\n");  #elif defined(TARGET_OPENBSD) -      buf_printf (&out, "IV_PLAT=openbsd\n"); +    buf_printf (&out, "IV_PLAT=openbsd\n");  #elif defined(TARGET_DARWIN) -      buf_printf (&out, "IV_PLAT=mac\n"); +    buf_printf (&out, "IV_PLAT=mac\n");  #elif defined(TARGET_NETBSD) -      buf_printf (&out, "IV_PLAT=netbsd\n"); +    buf_printf (&out, "IV_PLAT=netbsd\n");  #elif defined(TARGET_FREEBSD) -      buf_printf (&out, "IV_PLAT=freebsd\n"); +    buf_printf (&out, "IV_PLAT=freebsd\n");  #elif defined(TARGET_ANDROID) -      buf_printf(&out, "IV_PLAT=android\n"); +    buf_printf (&out, "IV_PLAT=android\n");  #elif defined(WIN32) -      buf_printf (&out, "IV_PLAT=win\n"); +    buf_printf (&out, "IV_PLAT=win\n");  #endif -      /* push mac addr */ -      { -	struct route_gateway_info rgi; -	get_default_gateway (&rgi); -	if (rgi.flags & RGI_HWADDR_DEFINED) -	  buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (rgi.hwaddr, 6, 0, 1, ":", &gc)); -      } - -      /* push LZO status */ -#ifdef ENABLE_LZO_STUB -      buf_printf (&out, "IV_LZO_STUB=1\n"); +    /* push compression status */ +#ifdef USE_COMP +    comp_generate_peer_info_string(&session->opt->comp_options, &out);  #endif -      /* push env vars that begin with UV_ */ -      for (e=es->list; e != NULL; e=e->next) +    if (session->opt->push_peer_info) +      { +	/* push mac addr */  	{ -	  if (e->string) -	    { -	      if (!strncmp(e->string, "UV_", 3) && buf_safe(&out, strlen(e->string)+1)) -		buf_printf (&out, "%s\n", e->string); -	    } +	  struct route_gateway_info rgi; +	  get_default_gateway (&rgi); +	  if (rgi.flags & RGI_HWADDR_DEFINED) +	    buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (rgi.hwaddr, 6, 0, 1, ":", &gc));  	} -      if (!write_string(buf, BSTR(&out), -1)) -	goto error; -    } -  else +	/* push env vars that begin with UV_ */ +	for (e=es->list; e != NULL; e=e->next) +	  { +	    if (e->string) +	      { +		if (!strncmp(e->string, "UV_", 3) && buf_safe(&out, strlen(e->string)+1)) +		  buf_printf (&out, "%s\n", e->string); +	      } +	  } +      } + +    if (!write_string(buf, BSTR(&out), -1)) +      goto error; +  } +#else +  { +    if (!write_empty_string (buf)) /* no peer info */ +      goto error; +  }  #endif -    { -      if (!write_empty_string (buf)) /* no peer info */ -	goto error; -    }    ret = true;   error: diff --git a/openvpn/src/openvpn/ssl_common.h b/openvpn/src/openvpn/ssl_common.h index c62294f5..47dbefbe 100644 --- a/openvpn/src/openvpn/ssl_common.h +++ b/openvpn/src/openvpn/ssl_common.h @@ -285,6 +285,11 @@ struct tls_options    struct env_set *es;    const struct plugin_list *plugins; +  /* compression parms */ +#ifdef USE_COMP +  struct compress_options comp_options; +#endif +    /* configuration file boolean options */  # define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0)  # define SSLF_USERNAME_AS_COMMON_NAME  (1<<1) diff --git a/openvpn/src/openvpn/syshead.h b/openvpn/src/openvpn/syshead.h index 0c3e4ee5..2be11159 100644 --- a/openvpn/src/openvpn/syshead.h +++ b/openvpn/src/openvpn/syshead.h @@ -720,6 +720,13 @@ socket_defined (const socket_descriptor_t sd)  #define ENABLE_CLIENT_NAT  /* + * Compression support + */ +#if defined(ENABLE_SNAPPY) || defined(ENABLE_LZO) || defined(ENABLE_COMP_STUB) +#define USE_COMP +#endif + +/*   * Enable --memstats option   */  #ifdef TARGET_LINUX | 
