mirror of
https://github.com/ntop/n2n.git
synced 2024-09-08 04:01:11 +02:00
moved compression code into transforms (#961)
This commit is contained in:
parent
4b8aaa7f6e
commit
f59c6900a1
|
@ -74,7 +74,7 @@ if(N2N_OPTION_USE_ZSTD)
|
|||
MESSAGE(FATAL_ERROR "libzstd not found.")
|
||||
endif(NOT LIBZSTD)
|
||||
MESSAGE(STATUS "Using libztd.")
|
||||
add_definitions(-DN2N_HAVE_ZSTD)
|
||||
add_definitions(-DHAVE_ZSTD)
|
||||
endif(N2N_OPTION_USE_ZSTD)
|
||||
|
||||
if(N2N_OPTION_USE_PCAPLIB)
|
||||
|
@ -185,6 +185,8 @@ add_library(n2n STATIC
|
|||
src/transform_aes.c
|
||||
src/transform_cc20.c
|
||||
src/transform_speck.c
|
||||
src/transform_lzo.c
|
||||
src/transform_zstd.c
|
||||
src/aes.c
|
||||
src/speck.c
|
||||
src/random_numbers.c
|
||||
|
|
|
@ -34,7 +34,7 @@ AC_ARG_WITH([zstd],
|
|||
AS_IF([test "x$with_zstd" != "xno"],
|
||||
[AC_CHECK_LIB([zstd], [ZSTD_compress],
|
||||
[
|
||||
AC_DEFINE([N2N_HAVE_ZSTD], [1], [Have ZSTD support])
|
||||
AC_DEFINE([HAVE_ZSTD], [1], [Have ZSTD support])
|
||||
N2N_LIBS="-lzstd ${N2N_LIBS}"
|
||||
],
|
||||
[AC_MSG_ERROR([zstd library not found])]
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
#include <syslog.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#ifdef HAVE_LIBZSTD
|
||||
#ifdef HAVE_ZSTD
|
||||
#include <zstd.h>
|
||||
#endif
|
||||
|
||||
|
@ -183,6 +183,10 @@ int n2n_transop_tf_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
|
|||
int n2n_transop_aes_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
|
||||
int n2n_transop_cc20_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
|
||||
int n2n_transop_speck_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
|
||||
int n2n_transop_lzo_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
|
||||
#ifdef HAVE_ZSTD
|
||||
int n2n_transop_zstd_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
|
||||
#endif
|
||||
|
||||
/* Log */
|
||||
void setTraceLevel (int level);
|
||||
|
|
|
@ -715,6 +715,10 @@ struct n2n_edge {
|
|||
size_t sup_attempts; /**< Number of remaining attempts to this supernode. */
|
||||
tuntap_dev device; /**< All about the TUNTAP device */
|
||||
n2n_trans_op_t transop; /**< The transop to use when encoding */
|
||||
n2n_trans_op_t transop_lzo; /**< The transop for LZO compression */
|
||||
#ifdef HAVE_ZSTD
|
||||
n2n_trans_op_t transop_zstd; /**< The transop for ZSTD compression */
|
||||
#endif
|
||||
n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */
|
||||
n2n_edge_callbacks_t cb; /**< API callbacks */
|
||||
void *user_data; /**< Can hold user data */
|
||||
|
|
|
@ -293,7 +293,7 @@ static void help (int level) {
|
|||
printf(" -H | use header encryption, supernode needs fixed community\n");
|
||||
printf(" -z1 ... -z2 | compress outgoing data packets, -z1 = lzo1x,\n"
|
||||
" | "
|
||||
#ifdef N2N_HAVE_ZSTD
|
||||
#ifdef HAVE_ZSTD
|
||||
"-z2 = zstd, "
|
||||
#endif
|
||||
"disabled by default\n");
|
||||
|
@ -383,7 +383,7 @@ static void setPayloadCompression (n2n_edge_conf_t *conf, int compression) {
|
|||
conf->compression = N2N_COMPRESSION_ID_LZO;
|
||||
break;
|
||||
}
|
||||
#ifdef N2N_HAVE_ZSTD
|
||||
#ifdef HAVE_ZSTD
|
||||
case 2: {
|
||||
conf->compression = N2N_COMPRESSION_ID_ZSTD;
|
||||
break;
|
||||
|
|
110
src/edge_utils.c
110
src/edge_utils.c
|
@ -20,9 +20,6 @@
|
|||
#include "network_traffic_filter.h"
|
||||
#include "edge_utils_win32.h"
|
||||
|
||||
/* heap allocation for compression as per lzo example doc */
|
||||
#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
|
||||
static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
|
||||
|
||||
/* ************************************** */
|
||||
|
||||
|
@ -391,13 +388,12 @@ n2n_edge_t* edge_init (const n2n_edge_conf_t *conf, int *rv) {
|
|||
|
||||
pearson_hash_init();
|
||||
|
||||
if(eee->conf.compression == N2N_COMPRESSION_ID_LZO)
|
||||
if(lzo_init() != LZO_E_OK) {
|
||||
traceEvent(TRACE_ERROR, "LZO compression error");
|
||||
goto edge_init_error;
|
||||
}
|
||||
#ifdef N2N_HAVE_ZSTD
|
||||
// zstd does not require initialization. if it were required, this would be a good place
|
||||
// always initialize compression transforms so we can at least decompress
|
||||
rc = n2n_transop_lzo_init(&eee->conf, &eee->transop_lzo);
|
||||
if(rc) goto edge_init_error; /* error message is printed in lzo_init */
|
||||
#ifdef HAVE_ZSTD
|
||||
rc = n2n_transop_zstd_init(&eee->conf, &eee->transop_zstd);
|
||||
if(rc) goto edge_init_error; /* error message is printed in zstd_init */
|
||||
#endif
|
||||
|
||||
traceEvent(TRACE_NORMAL, "number of supernodes in the list: %d\n", HASH_COUNT(eee->conf.supernodes));
|
||||
|
@ -1665,7 +1661,8 @@ static int handle_PACKET (n2n_edge_t * eee,
|
|||
|
||||
/* Handle transform. */
|
||||
{
|
||||
uint8_t decodebuf[N2N_PKT_BUF_SIZE];
|
||||
uint8_t decode_buf[N2N_PKT_BUF_SIZE];
|
||||
uint8_t deflate_buf[N2N_PKT_BUF_SIZE];
|
||||
size_t eth_size;
|
||||
n2n_transform_t rx_transop_id;
|
||||
uint8_t rx_compression_id;
|
||||
|
@ -1675,35 +1672,31 @@ static int handle_PACKET (n2n_edge_t * eee,
|
|||
|
||||
if(rx_transop_id == eee->conf.transop_id) {
|
||||
uint8_t is_multicast;
|
||||
eth_payload = decodebuf;
|
||||
eh = (ether_hdr_t*)eth_payload;
|
||||
// decrypt
|
||||
eth_payload = decode_buf;
|
||||
eth_size = eee->transop.rev(&eee->transop,
|
||||
eth_payload, N2N_PKT_BUF_SIZE,
|
||||
payload, psize, pkt->srcMac);
|
||||
++(eee->transop.rx_cnt); /* stats */
|
||||
|
||||
/* decompress if necessary */
|
||||
uint8_t * deflation_buffer = 0;
|
||||
lzo_uint deflated_len;
|
||||
size_t deflate_len;
|
||||
|
||||
switch(rx_compression_id) {
|
||||
case N2N_COMPRESSION_ID_NONE:
|
||||
break; // continue afterwards
|
||||
|
||||
case N2N_COMPRESSION_ID_LZO:
|
||||
deflation_buffer = malloc(N2N_PKT_BUF_SIZE);
|
||||
lzo1x_decompress(eth_payload, eth_size, deflation_buffer, &deflated_len, NULL);
|
||||
deflate_len = eee->transop_lzo.rev(&eee->transop_lzo,
|
||||
deflate_buf, N2N_PKT_BUF_SIZE,
|
||||
decode_buf, eth_size, pkt->srcMac);
|
||||
break;
|
||||
#ifdef N2N_HAVE_ZSTD
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
case N2N_COMPRESSION_ID_ZSTD:
|
||||
deflated_len = N2N_PKT_BUF_SIZE;
|
||||
deflation_buffer = malloc(deflated_len);
|
||||
deflated_len = ZSTD_decompress(deflation_buffer, deflated_len, eth_payload, eth_size);
|
||||
if(ZSTD_isError(deflated_len)) {
|
||||
traceEvent(TRACE_WARNING, "payload decompression failed with zstd error '%s'.",
|
||||
ZSTD_getErrorName(deflated_len));
|
||||
free(deflation_buffer);
|
||||
return(-1); // cannot help it
|
||||
}
|
||||
deflate_len = eee->transop_zstd.rev(&eee->transop_zstd,
|
||||
deflate_buf, N2N_PKT_BUF_SIZE,
|
||||
decode_buf, eth_size, pkt->srcMac);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -1714,11 +1707,11 @@ static int handle_PACKET (n2n_edge_t * eee,
|
|||
|
||||
if(rx_compression_id != N2N_COMPRESSION_ID_NONE) {
|
||||
traceEvent(TRACE_DEBUG, "payload decompression %s: deflated %u bytes to %u bytes",
|
||||
compression_str(rx_compression_id), eth_size, (int)deflated_len);
|
||||
memcpy(eth_payload,deflation_buffer, deflated_len );
|
||||
eth_size = deflated_len;
|
||||
free(deflation_buffer);
|
||||
compression_str(rx_compression_id), eth_size, (int)deflate_len);
|
||||
eth_payload = deflate_buf;
|
||||
eth_size = deflate_len;
|
||||
}
|
||||
eh = (ether_hdr_t*)eth_payload;
|
||||
|
||||
is_multicast = (is_ip6_discovery(eth_payload, eth_size) || is_ethMulticast(eth_payload, eth_size));
|
||||
|
||||
|
@ -1729,6 +1722,7 @@ static int handle_PACKET (n2n_edge_t * eee,
|
|||
/* Check if it is a routed packet */
|
||||
|
||||
if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + IP4_MIN_SIZE)) {
|
||||
|
||||
uint32_t *dst = (uint32_t*)ð_payload[ETH_FRAMESIZE + IP4_DSTOFFSET];
|
||||
uint8_t *dst_mac = (uint8_t*)eth_payload;
|
||||
|
||||
|
@ -1964,6 +1958,9 @@ void edge_send_packet2net (n2n_edge_t * eee,
|
|||
n2n_mac_t destMac;
|
||||
n2n_common_t cmn;
|
||||
n2n_PACKET_t pkt;
|
||||
uint8_t *enc_src = tap_pkt;
|
||||
size_t enc_len = len;
|
||||
uint8_t compression_buf[N2N_PKT_BUF_SIZE];
|
||||
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
|
||||
size_t idx = 0;
|
||||
n2n_transform_t tx_transop_idx = eee->transop.transform_id;
|
||||
|
@ -2013,35 +2010,33 @@ void edge_send_packet2net (n2n_edge_t * eee,
|
|||
pkt.compression = N2N_COMPRESSION_ID_NONE;
|
||||
|
||||
if(eee->conf.compression) {
|
||||
uint8_t * compression_buffer = NULL;
|
||||
int32_t compression_len;
|
||||
|
||||
switch(eee->conf.compression) {
|
||||
case N2N_COMPRESSION_ID_LZO:
|
||||
compression_buffer = malloc(len + len / 16 + 64 + 3);
|
||||
if(lzo1x_1_compress(tap_pkt, len, compression_buffer, (lzo_uint*)&compression_len, wrkmem) == LZO_E_OK) {
|
||||
if(compression_len < len) {
|
||||
pkt.compression = N2N_COMPRESSION_ID_LZO;
|
||||
}
|
||||
compression_len = eee->transop_lzo.fwd(&eee->transop_lzo,
|
||||
compression_buf, sizeof(compression_buf),
|
||||
tap_pkt, len,
|
||||
pkt.dstMac);
|
||||
|
||||
if((compression_len > 0) && (compression_len < len)) {
|
||||
pkt.compression = N2N_COMPRESSION_ID_LZO;
|
||||
}
|
||||
break;
|
||||
#ifdef N2N_HAVE_ZSTD
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
case N2N_COMPRESSION_ID_ZSTD:
|
||||
compression_len = N2N_PKT_BUF_SIZE + 128;
|
||||
compression_buffer = malloc(compression_len); // leaves enough room, for exact size call compression_len = ZSTD_compressBound (len); (slower)
|
||||
compression_len = (int32_t)ZSTD_compress(compression_buffer, compression_len, tap_pkt, len, ZSTD_COMPRESSION_LEVEL);
|
||||
if(!ZSTD_isError(compression_len)) {
|
||||
if(compression_len < len) {
|
||||
pkt.compression = N2N_COMPRESSION_ID_ZSTD;
|
||||
}
|
||||
} else {
|
||||
traceEvent(TRACE_ERROR, "payload compression failed with zstd error '%s'.",
|
||||
ZSTD_getErrorName(compression_len));
|
||||
free(compression_buffer);
|
||||
// continue with unset without pkt.compression --> will send uncompressed
|
||||
compression_len = eee->transop_zstd.fwd(&eee->transop_zstd,
|
||||
compression_buf, sizeof(compression_buf),
|
||||
tap_pkt, len,
|
||||
pkt.dstMac);
|
||||
|
||||
if((compression_len > 0) && (compression_len < len)) {
|
||||
pkt.compression = N2N_COMPRESSION_ID_ZSTD;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2049,13 +2044,8 @@ void edge_send_packet2net (n2n_edge_t * eee,
|
|||
if(pkt.compression != N2N_COMPRESSION_ID_NONE) {
|
||||
traceEvent(TRACE_DEBUG, "payload compression [%s]: compressed %u bytes to %u bytes\n",
|
||||
compression_str(pkt.compression), len, compression_len);
|
||||
|
||||
memcpy(tap_pkt, compression_buffer, compression_len);
|
||||
len = compression_len;
|
||||
}
|
||||
|
||||
if(compression_buffer) {
|
||||
free(compression_buffer);
|
||||
enc_src = compression_buf;
|
||||
enc_len = compression_len;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2066,7 +2056,7 @@ void edge_send_packet2net (n2n_edge_t * eee,
|
|||
|
||||
idx += eee->transop.fwd(&eee->transop,
|
||||
pktbuf + idx, N2N_PKT_BUF_SIZE - idx,
|
||||
tap_pkt, len, pkt.dstMac);
|
||||
enc_src, enc_len, pkt.dstMac);
|
||||
|
||||
traceEvent(TRACE_DEBUG, "encode PACKET of %u bytes, %u bytes data, %u bytes overhead, transform %u",
|
||||
(u_int)idx, (u_int)len, (u_int)(idx - len), tx_transop_idx);
|
||||
|
@ -2999,6 +2989,10 @@ void edge_term (n2n_edge_t * eee) {
|
|||
clear_peer_list(&eee->known_peers);
|
||||
|
||||
eee->transop.deinit(&eee->transop);
|
||||
eee->transop_lzo.deinit(&eee->transop_lzo);
|
||||
#ifdef HAVE_ZSTD
|
||||
eee->transop_zstd.deinit(&eee->transop_zstd);
|
||||
#endif
|
||||
|
||||
edge_cleanup_routes(eee);
|
||||
|
||||
|
|
133
src/transform_lzo.c
Normal file
133
src/transform_lzo.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
* (C) 2007-21 - ntop.org and contributors
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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; if not see see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "n2n.h"
|
||||
|
||||
|
||||
/* heap allocation for compression as per lzo example doc */
|
||||
#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
|
||||
|
||||
|
||||
typedef struct transop_lzo {
|
||||
HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
|
||||
} transop_lzo_t;
|
||||
|
||||
|
||||
static int transop_deinit_lzo (n2n_trans_op_t *arg) {
|
||||
|
||||
transop_lzo_t *priv = (transop_lzo_t *)arg->priv;
|
||||
|
||||
if(priv)
|
||||
free(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// returns compressed packet length
|
||||
// returns 0 if error occured, the caller would have to use
|
||||
// original, i.e. uncompressed data then
|
||||
static int transop_encode_lzo (n2n_trans_op_t *arg,
|
||||
uint8_t *outbuf,
|
||||
size_t out_len,
|
||||
const uint8_t *inbuf,
|
||||
size_t in_len,
|
||||
const uint8_t *peer_mac) {
|
||||
|
||||
transop_lzo_t *priv = (transop_lzo_t *)arg->priv;
|
||||
lzo_uint compression_len = 0;
|
||||
|
||||
if(in_len > N2N_PKT_BUF_SIZE) {
|
||||
traceEvent(TRACE_ERROR, "encode_lzo inbuf wrong size (%ul) to compress", in_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(out_len < in_len + in_len / 16 + 64 + 3) {
|
||||
traceEvent(TRACE_ERROR, "encode_lzo outbuf too small (%ul) to compress inbuf (%ul)",
|
||||
out_len, in_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(lzo1x_1_compress(inbuf, in_len, outbuf, &compression_len, priv->wrkmem) != LZO_E_OK) {
|
||||
traceEvent(TRACE_ERROR, "encode_lzo compression error");
|
||||
compression_len = 0;
|
||||
}
|
||||
|
||||
return compression_len;
|
||||
}
|
||||
|
||||
|
||||
static int transop_decode_lzo (n2n_trans_op_t *arg,
|
||||
uint8_t *outbuf,
|
||||
size_t out_len,
|
||||
const uint8_t *inbuf,
|
||||
size_t in_len,
|
||||
const uint8_t *peer_mac) {
|
||||
|
||||
lzo_uint deflated_len = N2N_PKT_BUF_SIZE;
|
||||
|
||||
if(in_len > N2N_PKT_BUF_SIZE) {
|
||||
traceEvent(TRACE_ERROR, "decode_lzo inbuf wrong size (%ul) to decompress", in_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lzo1x_decompress(inbuf, in_len, outbuf, &deflated_len, NULL);
|
||||
|
||||
if(deflated_len > N2N_PKT_BUF_SIZE) {
|
||||
traceEvent(TRACE_ERROR, "decode_lzo outbuf wrong size (%ul) decompressed", deflated_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return deflated_len;
|
||||
}
|
||||
|
||||
|
||||
static void transop_tick_lzo (n2n_trans_op_t *arg, time_t now) {
|
||||
|
||||
// no tick action
|
||||
}
|
||||
|
||||
|
||||
// lzo initialization function
|
||||
int n2n_transop_lzo_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
|
||||
|
||||
transop_lzo_t *priv;
|
||||
|
||||
memset(ttt, 0, sizeof(*ttt));
|
||||
ttt->transform_id = N2N_COMPRESSION_ID_LZO;
|
||||
|
||||
ttt->tick = transop_tick_lzo;
|
||||
ttt->deinit = transop_deinit_lzo;
|
||||
ttt->fwd = transop_encode_lzo;
|
||||
ttt->rev = transop_decode_lzo;
|
||||
|
||||
priv = (transop_lzo_t*)calloc(1, sizeof(transop_lzo_t));
|
||||
if(!priv) {
|
||||
traceEvent(TRACE_ERROR, "lzo_init cannot allocate transop_lzo memory");
|
||||
return -1;
|
||||
}
|
||||
ttt->priv = priv;
|
||||
|
||||
if(lzo_init() != LZO_E_OK) {
|
||||
traceEvent(TRACE_ERROR, "lzo_init cannot init lzo compression");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
148
src/transform_zstd.c
Normal file
148
src/transform_zstd.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
/**
|
||||
* (C) 2007-21 - ntop.org and contributors
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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; if not see see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "n2n.h"
|
||||
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
|
||||
|
||||
typedef struct transop_zstd {
|
||||
// no local data
|
||||
} transop_zstd_t;
|
||||
|
||||
|
||||
static int transop_deinit_zstd (n2n_trans_op_t *arg) {
|
||||
|
||||
transop_zstd_t *priv = (transop_zstd_t *)arg->priv;
|
||||
|
||||
if(priv)
|
||||
free(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// returns compressed packet length
|
||||
// returns 0 if error occured, the caller would have to use
|
||||
// original, i.e. uncompressed data then
|
||||
static int transop_encode_zstd (n2n_trans_op_t *arg,
|
||||
uint8_t *outbuf,
|
||||
size_t out_len,
|
||||
const uint8_t *inbuf,
|
||||
size_t in_len,
|
||||
const uint8_t *peer_mac) {
|
||||
|
||||
/* transop_zstd_t *priv = (transop_zstd_t *)arg->priv; */
|
||||
int32_t compression_len = 0;
|
||||
|
||||
if(in_len > N2N_PKT_BUF_SIZE) {
|
||||
traceEvent(TRACE_ERROR, "encode_zstd inbuf wrong size (%ul) to compress", in_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(out_len < in_len + 128) { // 128 leaves enough room,
|
||||
// for exact size call
|
||||
// ZSTD_compressBound(in_len)
|
||||
// which is slower
|
||||
traceEvent(TRACE_ERROR, "encode_zstd outbuf too small (%ul) to compress inbuf (%ul)",
|
||||
out_len, in_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
compression_len = ZSTD_compress(outbuf, out_len, inbuf, in_len, ZSTD_COMPRESSION_LEVEL);
|
||||
if(ZSTD_isError(compression_len)) {
|
||||
traceEvent(TRACE_ERROR, "payload compression failed with zstd error '%s'",
|
||||
ZSTD_getErrorName(compression_len));
|
||||
// we do no return the error code to the caller, just return 0 len
|
||||
// so, any further specific error handling would have to happen right here
|
||||
compression_len = 0;
|
||||
}
|
||||
|
||||
return compression_len;
|
||||
}
|
||||
|
||||
|
||||
static int transop_decode_zstd (n2n_trans_op_t *arg,
|
||||
uint8_t *outbuf,
|
||||
size_t out_len,
|
||||
const uint8_t *inbuf,
|
||||
size_t in_len,
|
||||
const uint8_t *peer_mac) {
|
||||
|
||||
int32_t deflated_len = 0;
|
||||
|
||||
if(in_len > N2N_PKT_BUF_SIZE) {
|
||||
traceEvent(TRACE_ERROR, "decode_zstd inbuf wrong size (%ul) to decompress", in_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
deflated_len = ZSTD_decompress(outbuf, out_len, inbuf, in_len);
|
||||
|
||||
if(ZSTD_isError(deflated_len)) {
|
||||
traceEvent(TRACE_WARNING, "payload decompression failed with zstd error '%s'",
|
||||
ZSTD_getErrorName(deflated_len));
|
||||
return 0; // cannot help it
|
||||
}
|
||||
|
||||
// we should have noticed by memory break or ZSTD complaining about a too small of an out_len
|
||||
if(deflated_len > N2N_PKT_BUF_SIZE) {
|
||||
traceEvent(TRACE_ERROR, "decode_zstd outbuf wrong size (%ul) decompressed", deflated_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return deflated_len;
|
||||
}
|
||||
|
||||
|
||||
static void transop_tick_zstd (n2n_trans_op_t *arg, time_t now) {
|
||||
|
||||
// no tick action
|
||||
}
|
||||
|
||||
|
||||
// zstd initialization function
|
||||
int n2n_transop_zstd_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
|
||||
|
||||
transop_zstd_t *priv;
|
||||
|
||||
memset(ttt, 0, sizeof(*ttt));
|
||||
ttt->transform_id = N2N_COMPRESSION_ID_ZSTD;
|
||||
|
||||
ttt->tick = transop_tick_zstd;
|
||||
ttt->deinit = transop_deinit_zstd;
|
||||
ttt->fwd = transop_encode_zstd;
|
||||
ttt->rev = transop_decode_zstd;
|
||||
|
||||
priv = (transop_zstd_t*)calloc(1, sizeof(transop_zstd_t));
|
||||
if(!priv) {
|
||||
traceEvent(TRACE_ERROR, "zstd_init cannot allocate transop_zstd memory");
|
||||
return -1;
|
||||
}
|
||||
ttt->priv = priv;
|
||||
|
||||
// zstd does not require initialization
|
||||
// if it requires one day, this is the place to do it and eventually throw an error
|
||||
// (see 'transform_lzo.c')
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // HAVE_ZSTD
|
|
@ -223,3 +223,18 @@ speck: output size = 0x236
|
|||
220: 0b c1 51 2e 28 a6 58 96 e2 e7 f2 20 c6 ac 06 05 | Q.( X |
|
||||
230: 39 75 4a 56 cf f8 |9uJV |
|
||||
|
||||
lzo: output size = 0x55
|
||||
000: 03 02 00 03 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456|
|
||||
010: 00 00 00 00 00 00 00 00 00 01 02 03 04 05 00 01 | |
|
||||
020: 02 03 04 05 00 00 0d 00 01 02 03 04 05 06 07 08 | |
|
||||
030: 09 0a 0b 0c 0d 0e 0f 20 00 bc 3c 00 00 02 0c 0d | < |
|
||||
040: 0e 0f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d | |
|
||||
050: 0e 0f 11 00 00 | |
|
||||
|
||||
zstd: output size = 0x47
|
||||
000: 03 02 00 03 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456|
|
||||
010: 00 00 00 00 00 00 00 00 00 01 02 03 04 05 00 01 | |
|
||||
020: 02 03 04 05 00 00 28 b5 2f fd 60 00 01 bd 00 00 | ( / ` |
|
||||
030: 80 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e | |
|
||||
040: 0f 01 00 da 47 9d 4b | G K|
|
||||
|
||||
|
|
|
@ -27,10 +27,6 @@
|
|||
#define DURATION 2.5 // test duration per algorithm
|
||||
#define PACKETS_BEFORE_GETTIME 2047 // do not check time after every packet but after (2 ^ n - 1)
|
||||
|
||||
/* heap allocation for compression as per lzo example doc */
|
||||
#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
|
||||
static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
|
||||
|
||||
|
||||
uint8_t PKT_CONTENT[]={
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
|
||||
|
@ -53,18 +49,20 @@ uint8_t PKT_CONTENT[]={
|
|||
/* Prototypes */
|
||||
static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c );
|
||||
static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf);
|
||||
static void init_compression_for_benchmark(void);
|
||||
static void deinit_compression_for_benchmark(void);
|
||||
static void run_compression_benchmark(void);
|
||||
static void run_hashing_benchmark(void);
|
||||
static void run_ecc_benchmark(void);
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
|
||||
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
|
||||
n2n_trans_op_t transop_null, transop_tf;
|
||||
n2n_trans_op_t transop_aes;
|
||||
n2n_trans_op_t transop_cc20;
|
||||
n2n_trans_op_t transop_lzo;
|
||||
#ifdef HAVE_ZSTD
|
||||
n2n_trans_op_t transop_zstd;
|
||||
#endif
|
||||
|
||||
n2n_trans_op_t transop_speck;
|
||||
n2n_edge_conf_t conf;
|
||||
|
@ -78,12 +76,16 @@ int main(int argc, char * argv[]) {
|
|||
|
||||
pearson_hash_init();
|
||||
|
||||
/* Init transopts */
|
||||
/* Init transops */
|
||||
n2n_transop_null_init(&conf, &transop_null);
|
||||
n2n_transop_tf_init(&conf, &transop_tf);
|
||||
n2n_transop_aes_init(&conf, &transop_aes);
|
||||
n2n_transop_cc20_init(&conf, &transop_cc20);
|
||||
n2n_transop_speck_init(&conf, &transop_speck);
|
||||
n2n_transop_lzo_init(&conf, &transop_lzo);
|
||||
#ifdef HAVE_ZSTD
|
||||
n2n_transop_zstd_init(&conf, &transop_zstd);
|
||||
#endif
|
||||
|
||||
/* Run the tests */
|
||||
run_transop_benchmark("null", &transop_null, &conf, pktbuf);
|
||||
|
@ -91,169 +93,28 @@ int main(int argc, char * argv[]) {
|
|||
run_transop_benchmark("aes", &transop_aes, &conf, pktbuf);
|
||||
run_transop_benchmark("cc20", &transop_cc20, &conf, pktbuf);
|
||||
run_transop_benchmark("speck", &transop_speck, &conf, pktbuf);
|
||||
run_transop_benchmark("lzo1x", &transop_lzo, &conf, pktbuf);
|
||||
#ifdef HAVE_ZSTD
|
||||
run_transop_benchmark("zstd", &transop_zstd, &conf, pktbuf);
|
||||
#endif
|
||||
|
||||
run_ecc_benchmark();
|
||||
|
||||
/* Also for compression (init moved here for ciphers get run before in case of lzo init error) */
|
||||
init_compression_for_benchmark();
|
||||
run_compression_benchmark();
|
||||
|
||||
run_hashing_benchmark();
|
||||
|
||||
|
||||
/* Cleanup */
|
||||
transop_null.deinit(&transop_null);
|
||||
transop_tf.deinit(&transop_tf);
|
||||
transop_aes.deinit(&transop_aes);
|
||||
transop_cc20.deinit(&transop_cc20);
|
||||
transop_speck.deinit(&transop_speck);
|
||||
|
||||
deinit_compression_for_benchmark();
|
||||
|
||||
transop_lzo.deinit(&transop_lzo);
|
||||
#ifdef HAVE_ZSTD
|
||||
transop_zstd.deinit(&transop_zstd);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- compression benchmark --------------------------------------------------------------
|
||||
|
||||
static void init_compression_for_benchmark(void) {
|
||||
|
||||
if(lzo_init() != LZO_E_OK) {
|
||||
traceEvent(TRACE_ERROR, "LZO compression init error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef N2N_HAVE_ZSTD
|
||||
// zstd does not require initialization. if it were required, this would be a good place
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void deinit_compression_for_benchmark(void) {
|
||||
|
||||
// lzo1x does not require de-initialization. if it were required, this would be a good place
|
||||
|
||||
#ifdef N2N_HAVE_ZSTD
|
||||
// zstd does not require de-initialization. if it were required, this would be a good place
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void run_compression_benchmark() {
|
||||
const float target_sec = DURATION;
|
||||
struct timeval t1;
|
||||
struct timeval t2;
|
||||
ssize_t target_usec = target_sec * 1e6;
|
||||
ssize_t tdiff; // microseconds
|
||||
size_t num_packets;
|
||||
float mpps;
|
||||
uint8_t compression_buffer[N2N_PKT_BUF_SIZE]; // size allows enough of a reserve required for compression
|
||||
lzo_uint compression_len = N2N_PKT_BUF_SIZE;
|
||||
uint8_t deflation_buffer[N2N_PKT_BUF_SIZE];
|
||||
int64_t deflated_len;
|
||||
|
||||
// compression
|
||||
printf("{%s}\t%s\t%.1f sec\t(%u bytes)",
|
||||
"lzo1x", "compr", target_sec, (unsigned int)sizeof(PKT_CONTENT));
|
||||
fflush(stdout);
|
||||
tdiff = 0;
|
||||
num_packets = 0;
|
||||
gettimeofday( &t1, NULL );
|
||||
|
||||
while(tdiff < target_usec) {
|
||||
compression_len = N2N_PKT_BUF_SIZE;
|
||||
if(lzo1x_1_compress(PKT_CONTENT, sizeof(PKT_CONTENT), compression_buffer, &compression_len, wrkmem) != LZO_E_OK) {
|
||||
printf("\n\t compression error\n");
|
||||
exit(1);
|
||||
}
|
||||
num_packets++;
|
||||
if (!(num_packets & PACKETS_BEFORE_GETTIME)) {
|
||||
gettimeofday( &t2, NULL );
|
||||
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
|
||||
}
|
||||
}
|
||||
mpps = num_packets / (tdiff / 1e6) / 1e6;
|
||||
printf(" ---> (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n",
|
||||
(unsigned int)compression_len, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT));
|
||||
|
||||
// decompression
|
||||
printf("\t%s\t%.1f sec\t(%u bytes)",
|
||||
"decompr", target_sec, (unsigned int)sizeof(PKT_CONTENT));
|
||||
fflush(stdout);
|
||||
tdiff = 0;
|
||||
num_packets = 0;
|
||||
gettimeofday( &t1, NULL );
|
||||
|
||||
while(tdiff < target_usec) {
|
||||
deflated_len = N2N_PKT_BUF_SIZE;
|
||||
lzo1x_decompress (compression_buffer, compression_len, deflation_buffer, (lzo_uint*)&deflated_len, NULL);
|
||||
num_packets++;
|
||||
if (!(num_packets & PACKETS_BEFORE_GETTIME)) {
|
||||
gettimeofday( &t2, NULL );
|
||||
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
|
||||
}
|
||||
}
|
||||
mpps = num_packets / (tdiff / 1e6) / 1e6;
|
||||
printf(" <--- (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n",
|
||||
(unsigned int)compression_len, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT));
|
||||
if(memcmp(deflation_buffer, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0)
|
||||
printf("\n\tdecompression error\n");
|
||||
printf ("\n");
|
||||
|
||||
#ifdef N2N_HAVE_ZSTD
|
||||
// compression
|
||||
printf("{%s}\t%s\t%.1f sec\t(%u bytes)",
|
||||
"zstd", "compr", target_sec, (unsigned int)sizeof(PKT_CONTENT));
|
||||
fflush(stdout);
|
||||
tdiff = 0;
|
||||
num_packets = 0;
|
||||
gettimeofday( &t1, NULL );
|
||||
while(tdiff < target_usec) {
|
||||
compression_len = N2N_PKT_BUF_SIZE;
|
||||
compression_len = ZSTD_compress(compression_buffer, compression_len, PKT_CONTENT, sizeof(PKT_CONTENT), ZSTD_COMPRESSION_LEVEL) ;
|
||||
if(ZSTD_isError(compression_len)) {
|
||||
printf("\n\t compression error\n");
|
||||
exit(1);
|
||||
}
|
||||
num_packets++;
|
||||
if (!(num_packets & PACKETS_BEFORE_GETTIME)) {
|
||||
gettimeofday( &t2, NULL );
|
||||
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
|
||||
}
|
||||
}
|
||||
mpps = num_packets / (tdiff / 1e6) / 1e6;
|
||||
printf(" ---> (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n",
|
||||
(unsigned int)compression_len, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT));
|
||||
|
||||
// decompression
|
||||
printf("\t%s\t%.1f sec\t(%u bytes)",
|
||||
"decompr", target_sec, (unsigned int)sizeof(PKT_CONTENT));
|
||||
fflush(stdout);
|
||||
tdiff = 0;
|
||||
num_packets = 0;
|
||||
gettimeofday( &t1, NULL );
|
||||
while(tdiff < target_usec) {
|
||||
deflated_len = N2N_PKT_BUF_SIZE;
|
||||
deflated_len = (int32_t)ZSTD_decompress (deflation_buffer, deflated_len, compression_buffer, compression_len);
|
||||
if(ZSTD_isError(deflated_len)) {
|
||||
printf("\n\tdecompression error '%s'\n",
|
||||
ZSTD_getErrorName(deflated_len));
|
||||
exit(1);
|
||||
}
|
||||
num_packets++;
|
||||
if (!(num_packets & PACKETS_BEFORE_GETTIME)) {
|
||||
gettimeofday( &t2, NULL );
|
||||
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
|
||||
}
|
||||
}
|
||||
mpps = num_packets / (tdiff / 1e6) / 1e6;
|
||||
printf(" <--- (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n",
|
||||
(unsigned int)compression_len, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT));
|
||||
if(memcmp(deflation_buffer, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0)
|
||||
printf("\n\tdecompression error\n");
|
||||
printf ("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
// --- hashing benchmark ------------------------------------------------------------------
|
||||
|
||||
static void run_hashing_benchmark(void) {
|
||||
|
@ -331,7 +192,7 @@ static void run_ecc_benchmark(void) {
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
// --- cipher benchmark -------------------------------------------------------------------
|
||||
// --- transop benchmark ------------------------------------------------------------------
|
||||
|
||||
static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf) {
|
||||
n2n_common_t cmn;
|
||||
|
|
|
@ -50,12 +50,16 @@ static void run_transop_benchmark (const char *op_name, n2n_trans_op_t *op_fn, n
|
|||
|
||||
|
||||
int main (int argc, char * argv[]) {
|
||||
|
||||
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
|
||||
n2n_trans_op_t transop_null, transop_tf;
|
||||
n2n_trans_op_t transop_aes;
|
||||
n2n_trans_op_t transop_cc20;
|
||||
|
||||
n2n_trans_op_t transop_speck;
|
||||
n2n_trans_op_t transop_lzo;
|
||||
#ifdef HAVE_ZSTD
|
||||
n2n_trans_op_t transop_zstd;
|
||||
#endif
|
||||
n2n_edge_conf_t conf;
|
||||
|
||||
/* Init configuration */
|
||||
|
@ -76,6 +80,10 @@ int main (int argc, char * argv[]) {
|
|||
n2n_transop_aes_init(&conf, &transop_aes);
|
||||
n2n_transop_cc20_init(&conf, &transop_cc20);
|
||||
n2n_transop_speck_init(&conf, &transop_speck);
|
||||
n2n_transop_lzo_init(&conf, &transop_lzo);
|
||||
#ifdef HAVE_ZSTD
|
||||
n2n_transop_zstd_init(&conf, &transop_zstd);
|
||||
#endif
|
||||
|
||||
/* Run the tests */
|
||||
/* FIXME: interop tests are pretty useless without the expected encrypted buffer data */
|
||||
|
@ -84,6 +92,21 @@ int main (int argc, char * argv[]) {
|
|||
run_transop_benchmark("aes", &transop_aes, &conf, pktbuf);
|
||||
run_transop_benchmark("cc20", &transop_cc20, &conf, pktbuf);
|
||||
run_transop_benchmark("speck", &transop_speck, &conf, pktbuf);
|
||||
run_transop_benchmark("lzo", &transop_lzo, &conf, pktbuf);
|
||||
#ifdef HAVE_ZSTD
|
||||
run_transop_benchmark("zstd", &transop_zstd, &conf, pktbuf);
|
||||
#else
|
||||
// FIXME - output dummy data to the stdout for easy comparison
|
||||
printf("zstd: output size = 0x47\n");
|
||||
printf("000: 03 02 00 03 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456|\n");
|
||||
printf("010: 00 00 00 00 00 00 00 00 00 01 02 03 04 05 00 01 | |\n");
|
||||
printf("020: 02 03 04 05 00 00 28 b5 2f fd 60 00 01 bd 00 00 | ( / ` |\n");
|
||||
printf("030: 80 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e | |\n");
|
||||
printf("040: 0f 01 00 da 47 9d 4b | G K|\n");
|
||||
|
||||
fprintf(stderr, "%s: not compiled - dummy data output\n", "zstd");
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* Cleanup */
|
||||
transop_null.deinit(&transop_null);
|
||||
|
@ -91,11 +114,15 @@ int main (int argc, char * argv[]) {
|
|||
transop_aes.deinit(&transop_aes);
|
||||
transop_cc20.deinit(&transop_cc20);
|
||||
transop_speck.deinit(&transop_speck);
|
||||
transop_lzo.deinit(&transop_lzo);
|
||||
#ifdef HAVE_ZSTD
|
||||
transop_zstd.deinit(&transop_zstd);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- cipher benchmark -------------------------------------------------------------------
|
||||
// --- transop benchmark ------------------------------------------------------------------
|
||||
|
||||
static void run_transop_benchmark (const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf) {
|
||||
n2n_common_t cmn;
|
||||
|
|
Loading…
Reference in New Issue
Block a user