Skip to content

Commit f59c690

Browse files
authored
moved compression code into transforms (ntop#961)
1 parent 4b8aaa7 commit f59c690

11 files changed

+411
-223
lines changed

CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ if(N2N_OPTION_USE_ZSTD)
7474
MESSAGE(FATAL_ERROR "libzstd not found.")
7575
endif(NOT LIBZSTD)
7676
MESSAGE(STATUS "Using libztd.")
77-
add_definitions(-DN2N_HAVE_ZSTD)
77+
add_definitions(-DHAVE_ZSTD)
7878
endif(N2N_OPTION_USE_ZSTD)
7979

8080
if(N2N_OPTION_USE_PCAPLIB)
@@ -185,6 +185,8 @@ add_library(n2n STATIC
185185
src/transform_aes.c
186186
src/transform_cc20.c
187187
src/transform_speck.c
188+
src/transform_lzo.c
189+
src/transform_zstd.c
188190
src/aes.c
189191
src/speck.c
190192
src/random_numbers.c

configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ AC_ARG_WITH([zstd],
3434
AS_IF([test "x$with_zstd" != "xno"],
3535
[AC_CHECK_LIB([zstd], [ZSTD_compress],
3636
[
37-
AC_DEFINE([N2N_HAVE_ZSTD], [1], [Have ZSTD support])
37+
AC_DEFINE([HAVE_ZSTD], [1], [Have ZSTD support])
3838
N2N_LIBS="-lzstd ${N2N_LIBS}"
3939
],
4040
[AC_MSG_ERROR([zstd library not found])]

include/n2n.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
#include <syslog.h>
104104
#include <sys/wait.h>
105105

106-
#ifdef HAVE_LIBZSTD
106+
#ifdef HAVE_ZSTD
107107
#include <zstd.h>
108108
#endif
109109

@@ -183,6 +183,10 @@ int n2n_transop_tf_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
183183
int n2n_transop_aes_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
184184
int n2n_transop_cc20_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
185185
int n2n_transop_speck_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
186+
int n2n_transop_lzo_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
187+
#ifdef HAVE_ZSTD
188+
int n2n_transop_zstd_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
189+
#endif
186190

187191
/* Log */
188192
void setTraceLevel (int level);

include/n2n_typedefs.h

+4
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,10 @@ struct n2n_edge {
715715
size_t sup_attempts; /**< Number of remaining attempts to this supernode. */
716716
tuntap_dev device; /**< All about the TUNTAP device */
717717
n2n_trans_op_t transop; /**< The transop to use when encoding */
718+
n2n_trans_op_t transop_lzo; /**< The transop for LZO compression */
719+
#ifdef HAVE_ZSTD
720+
n2n_trans_op_t transop_zstd; /**< The transop for ZSTD compression */
721+
#endif
718722
n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */
719723
n2n_edge_callbacks_t cb; /**< API callbacks */
720724
void *user_data; /**< Can hold user data */

src/edge.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ static void help (int level) {
293293
printf(" -H | use header encryption, supernode needs fixed community\n");
294294
printf(" -z1 ... -z2 | compress outgoing data packets, -z1 = lzo1x,\n"
295295
" | "
296-
#ifdef N2N_HAVE_ZSTD
296+
#ifdef HAVE_ZSTD
297297
"-z2 = zstd, "
298298
#endif
299299
"disabled by default\n");
@@ -383,7 +383,7 @@ static void setPayloadCompression (n2n_edge_conf_t *conf, int compression) {
383383
conf->compression = N2N_COMPRESSION_ID_LZO;
384384
break;
385385
}
386-
#ifdef N2N_HAVE_ZSTD
386+
#ifdef HAVE_ZSTD
387387
case 2: {
388388
conf->compression = N2N_COMPRESSION_ID_ZSTD;
389389
break;

src/edge_utils.c

+52-58
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
#include "network_traffic_filter.h"
2121
#include "edge_utils_win32.h"
2222

23-
/* heap allocation for compression as per lzo example doc */
24-
#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
25-
static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
2623

2724
/* ************************************** */
2825

@@ -391,13 +388,12 @@ n2n_edge_t* edge_init (const n2n_edge_conf_t *conf, int *rv) {
391388

392389
pearson_hash_init();
393390

394-
if(eee->conf.compression == N2N_COMPRESSION_ID_LZO)
395-
if(lzo_init() != LZO_E_OK) {
396-
traceEvent(TRACE_ERROR, "LZO compression error");
397-
goto edge_init_error;
398-
}
399-
#ifdef N2N_HAVE_ZSTD
400-
// zstd does not require initialization. if it were required, this would be a good place
391+
// always initialize compression transforms so we can at least decompress
392+
rc = n2n_transop_lzo_init(&eee->conf, &eee->transop_lzo);
393+
if(rc) goto edge_init_error; /* error message is printed in lzo_init */
394+
#ifdef HAVE_ZSTD
395+
rc = n2n_transop_zstd_init(&eee->conf, &eee->transop_zstd);
396+
if(rc) goto edge_init_error; /* error message is printed in zstd_init */
401397
#endif
402398

403399
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,
16651661

16661662
/* Handle transform. */
16671663
{
1668-
uint8_t decodebuf[N2N_PKT_BUF_SIZE];
1664+
uint8_t decode_buf[N2N_PKT_BUF_SIZE];
1665+
uint8_t deflate_buf[N2N_PKT_BUF_SIZE];
16691666
size_t eth_size;
16701667
n2n_transform_t rx_transop_id;
16711668
uint8_t rx_compression_id;
@@ -1675,35 +1672,31 @@ static int handle_PACKET (n2n_edge_t * eee,
16751672

16761673
if(rx_transop_id == eee->conf.transop_id) {
16771674
uint8_t is_multicast;
1678-
eth_payload = decodebuf;
1679-
eh = (ether_hdr_t*)eth_payload;
1675+
// decrypt
1676+
eth_payload = decode_buf;
16801677
eth_size = eee->transop.rev(&eee->transop,
16811678
eth_payload, N2N_PKT_BUF_SIZE,
16821679
payload, psize, pkt->srcMac);
16831680
++(eee->transop.rx_cnt); /* stats */
16841681

16851682
/* decompress if necessary */
1686-
uint8_t * deflation_buffer = 0;
1687-
lzo_uint deflated_len;
1683+
size_t deflate_len;
1684+
16881685
switch(rx_compression_id) {
16891686
case N2N_COMPRESSION_ID_NONE:
16901687
break; // continue afterwards
16911688

16921689
case N2N_COMPRESSION_ID_LZO:
1693-
deflation_buffer = malloc(N2N_PKT_BUF_SIZE);
1694-
lzo1x_decompress(eth_payload, eth_size, deflation_buffer, &deflated_len, NULL);
1690+
deflate_len = eee->transop_lzo.rev(&eee->transop_lzo,
1691+
deflate_buf, N2N_PKT_BUF_SIZE,
1692+
decode_buf, eth_size, pkt->srcMac);
16951693
break;
1696-
#ifdef N2N_HAVE_ZSTD
1694+
1695+
#ifdef HAVE_ZSTD
16971696
case N2N_COMPRESSION_ID_ZSTD:
1698-
deflated_len = N2N_PKT_BUF_SIZE;
1699-
deflation_buffer = malloc(deflated_len);
1700-
deflated_len = ZSTD_decompress(deflation_buffer, deflated_len, eth_payload, eth_size);
1701-
if(ZSTD_isError(deflated_len)) {
1702-
traceEvent(TRACE_WARNING, "payload decompression failed with zstd error '%s'.",
1703-
ZSTD_getErrorName(deflated_len));
1704-
free(deflation_buffer);
1705-
return(-1); // cannot help it
1706-
}
1697+
deflate_len = eee->transop_zstd.rev(&eee->transop_zstd,
1698+
deflate_buf, N2N_PKT_BUF_SIZE,
1699+
decode_buf, eth_size, pkt->srcMac);
17071700
break;
17081701
#endif
17091702
default:
@@ -1714,11 +1707,11 @@ static int handle_PACKET (n2n_edge_t * eee,
17141707

17151708
if(rx_compression_id != N2N_COMPRESSION_ID_NONE) {
17161709
traceEvent(TRACE_DEBUG, "payload decompression %s: deflated %u bytes to %u bytes",
1717-
compression_str(rx_compression_id), eth_size, (int)deflated_len);
1718-
memcpy(eth_payload,deflation_buffer, deflated_len );
1719-
eth_size = deflated_len;
1720-
free(deflation_buffer);
1710+
compression_str(rx_compression_id), eth_size, (int)deflate_len);
1711+
eth_payload = deflate_buf;
1712+
eth_size = deflate_len;
17211713
}
1714+
eh = (ether_hdr_t*)eth_payload;
17221715

17231716
is_multicast = (is_ip6_discovery(eth_payload, eth_size) || is_ethMulticast(eth_payload, eth_size));
17241717

@@ -1729,6 +1722,7 @@ static int handle_PACKET (n2n_edge_t * eee,
17291722
/* Check if it is a routed packet */
17301723

17311724
if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + IP4_MIN_SIZE)) {
1725+
17321726
uint32_t *dst = (uint32_t*)&eth_payload[ETH_FRAMESIZE + IP4_DSTOFFSET];
17331727
uint8_t *dst_mac = (uint8_t*)eth_payload;
17341728

@@ -1964,6 +1958,9 @@ void edge_send_packet2net (n2n_edge_t * eee,
19641958
n2n_mac_t destMac;
19651959
n2n_common_t cmn;
19661960
n2n_PACKET_t pkt;
1961+
uint8_t *enc_src = tap_pkt;
1962+
size_t enc_len = len;
1963+
uint8_t compression_buf[N2N_PKT_BUF_SIZE];
19671964
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
19681965
size_t idx = 0;
19691966
n2n_transform_t tx_transop_idx = eee->transop.transform_id;
@@ -2013,49 +2010,42 @@ void edge_send_packet2net (n2n_edge_t * eee,
20132010
pkt.compression = N2N_COMPRESSION_ID_NONE;
20142011

20152012
if(eee->conf.compression) {
2016-
uint8_t * compression_buffer = NULL;
20172013
int32_t compression_len;
20182014

20192015
switch(eee->conf.compression) {
20202016
case N2N_COMPRESSION_ID_LZO:
2021-
compression_buffer = malloc(len + len / 16 + 64 + 3);
2022-
if(lzo1x_1_compress(tap_pkt, len, compression_buffer, (lzo_uint*)&compression_len, wrkmem) == LZO_E_OK) {
2023-
if(compression_len < len) {
2024-
pkt.compression = N2N_COMPRESSION_ID_LZO;
2025-
}
2017+
compression_len = eee->transop_lzo.fwd(&eee->transop_lzo,
2018+
compression_buf, sizeof(compression_buf),
2019+
tap_pkt, len,
2020+
pkt.dstMac);
2021+
2022+
if((compression_len > 0) && (compression_len < len)) {
2023+
pkt.compression = N2N_COMPRESSION_ID_LZO;
20262024
}
20272025
break;
2028-
#ifdef N2N_HAVE_ZSTD
2026+
2027+
#ifdef HAVE_ZSTD
20292028
case N2N_COMPRESSION_ID_ZSTD:
2030-
compression_len = N2N_PKT_BUF_SIZE + 128;
2031-
compression_buffer = malloc(compression_len); // leaves enough room, for exact size call compression_len = ZSTD_compressBound (len); (slower)
2032-
compression_len = (int32_t)ZSTD_compress(compression_buffer, compression_len, tap_pkt, len, ZSTD_COMPRESSION_LEVEL);
2033-
if(!ZSTD_isError(compression_len)) {
2034-
if(compression_len < len) {
2035-
pkt.compression = N2N_COMPRESSION_ID_ZSTD;
2036-
}
2037-
} else {
2038-
traceEvent(TRACE_ERROR, "payload compression failed with zstd error '%s'.",
2039-
ZSTD_getErrorName(compression_len));
2040-
free(compression_buffer);
2041-
// continue with unset without pkt.compression --> will send uncompressed
2029+
compression_len = eee->transop_zstd.fwd(&eee->transop_zstd,
2030+
compression_buf, sizeof(compression_buf),
2031+
tap_pkt, len,
2032+
pkt.dstMac);
2033+
2034+
if((compression_len > 0) && (compression_len < len)) {
2035+
pkt.compression = N2N_COMPRESSION_ID_ZSTD;
20422036
}
20432037
break;
20442038
#endif
2039+
20452040
default:
20462041
break;
20472042
}
20482043

20492044
if(pkt.compression != N2N_COMPRESSION_ID_NONE) {
20502045
traceEvent(TRACE_DEBUG, "payload compression [%s]: compressed %u bytes to %u bytes\n",
20512046
compression_str(pkt.compression), len, compression_len);
2052-
2053-
memcpy(tap_pkt, compression_buffer, compression_len);
2054-
len = compression_len;
2055-
}
2056-
2057-
if(compression_buffer) {
2058-
free(compression_buffer);
2047+
enc_src = compression_buf;
2048+
enc_len = compression_len;
20592049
}
20602050
}
20612051

@@ -2066,7 +2056,7 @@ void edge_send_packet2net (n2n_edge_t * eee,
20662056

20672057
idx += eee->transop.fwd(&eee->transop,
20682058
pktbuf + idx, N2N_PKT_BUF_SIZE - idx,
2069-
tap_pkt, len, pkt.dstMac);
2059+
enc_src, enc_len, pkt.dstMac);
20702060

20712061
traceEvent(TRACE_DEBUG, "encode PACKET of %u bytes, %u bytes data, %u bytes overhead, transform %u",
20722062
(u_int)idx, (u_int)len, (u_int)(idx - len), tx_transop_idx);
@@ -2999,6 +2989,10 @@ void edge_term (n2n_edge_t * eee) {
29992989
clear_peer_list(&eee->known_peers);
30002990

30012991
eee->transop.deinit(&eee->transop);
2992+
eee->transop_lzo.deinit(&eee->transop_lzo);
2993+
#ifdef HAVE_ZSTD
2994+
eee->transop_zstd.deinit(&eee->transop_zstd);
2995+
#endif
30022996

30032997
edge_cleanup_routes(eee);
30042998

0 commit comments

Comments
 (0)