moved compression code into transforms (#961)

This commit is contained in:
Logan oos Even 2022-02-21 10:09:06 +01:00 committed by GitHub
parent 4b8aaa7f6e
commit f59c6900a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 411 additions and 223 deletions

View File

@ -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

View File

@ -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])]

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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*)&eth_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
View 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
View 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

View File

@ -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|

View File

@ -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;

View File

@ -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;