#include "net.h"
#include "netutl.h"
#include "protocol.h"
+#include "random.h"
#include "route.h"
#include "utils.h"
-#include "random.h"
+#include "xalloc.h"
/* The minimum size of a probe is 14 bytes, but since we normally use CBC mode
encryption, we can add a few extra random bytes without increasing the
}
}
+static length_t compress_packet_lz4(uint8_t *dest, length_t dest_len, const uint8_t *source, length_t len) {
#ifdef HAVE_LZ4
-static length_t compress_packet_lz4(uint8_t *dest, const uint8_t *source, length_t len) {
#ifdef HAVE_LZ4_BUILTIN
- return LZ4_compress_fast_extState(&lz4_stream, (const char *) source, (char *) dest, len, MAXSIZE, 0);
+ return LZ4_compress_fast_extState(&lz4_stream, (const char *) source, (char *) dest, len, dest_len, 0);
#else
/* @FIXME: Put this in a better place, and free() it too. */
if(lz4_state == NULL) {
- lz4_state = malloc(LZ4_sizeofState());
- }
-
- if(lz4_state == NULL) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Failed to allocate lz4_state, error: %i", errno);
- return 0;
+ lz4_state = xmalloc(LZ4_sizeofState());
}
- return LZ4_compress_fast_extState(lz4_state, (const char *) source, (char *) dest, len, MAXSIZE, 0);
+ return LZ4_compress_fast_extState(lz4_state, (const char *) source, (char *) dest, len, dest_len, 0);
#endif /* HAVE_LZ4_BUILTIN */
-}
#endif /* HAVE_LZ4 */
+ return 0;
+}
+static length_t compress_packet_lzo(uint8_t *dest, length_t dest_len, const uint8_t *source, length_t len, compression_level_t level) {
#ifdef HAVE_LZO
-static length_t compress_packet_lzo(uint8_t *dest, const uint8_t *source, length_t len, compression_level_t level) {
- lzo_uint lzolen = MAXSIZE;
+ lzo_uint lzolen = dest_len;
int result;
if(level == COMPRESS_LZO_HI) {
if(result == LZO_E_OK) {
return lzolen;
- } else {
- return 0;
}
+
+#endif /* HAVE_LZO */
+
+ return 0;
}
-#endif
-static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, compression_level_t level) {
+static length_t compress_packet_zlib(uint8_t *dest, length_t dest_len, const uint8_t *source, length_t len, compression_level_t level) {
+#ifdef HAVE_ZLIB
+ unsigned long result_len = dest_len;
+
+ if(compress2(dest, &result_len, source, len, level) == Z_OK) {
+ return result_len;
+ }
+
+#endif /* HAVE_ZLIB */
+
+ return 0;
+}
+
+static length_t compress_packet(uint8_t *dest, length_t dest_len, const uint8_t *source, length_t len, compression_level_t level) {
switch(level) {
-#ifdef HAVE_LZ4
case COMPRESS_LZ4:
- return compress_packet_lz4(dest, source, len);
-#endif
-
-#ifdef HAVE_LZO
+ return compress_packet_lz4(dest, dest_len, source, len);
case COMPRESS_LZO_HI:
case COMPRESS_LZO_LO:
- return compress_packet_lzo(dest, source, len, level);
-#endif
-#ifdef HAVE_ZLIB
+ return compress_packet_lzo(dest, dest_len, source, len, level);
case COMPRESS_ZLIB_9:
case COMPRESS_ZLIB_8:
case COMPRESS_ZLIB_3:
case COMPRESS_ZLIB_2:
case COMPRESS_ZLIB_1: {
- unsigned long dest_len = MAXSIZE;
+ return compress_packet_zlib(dest, dest_len, source, len, level);
+ }
- if(compress2(dest, &dest_len, source, len, level) == Z_OK) {
- return dest_len;
+ case COMPRESS_NONE:
+ if(dest_len >= len) {
+ memcpy(dest, source, len);
+ return len;
} else {
return 0;
}
- }
-
-#endif
-
- case COMPRESS_NONE:
- memcpy(dest, source, len);
- return len;
default:
return 0;
}
}
-static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, compression_level_t level) {
+static length_t uncompress_packet(uint8_t *dest, length_t dest_len, const uint8_t *source, length_t len, compression_level_t level) {
switch(level) {
#ifdef HAVE_LZ4
case COMPRESS_LZ4:
- return LZ4_decompress_safe((char *)source, (char *) dest, len, MAXSIZE);
+
+ return LZ4_decompress_safe((char *)source, (char *) dest, len, dest_len);
#endif
#ifdef HAVE_LZO
case COMPRESS_LZO_HI:
case COMPRESS_LZO_LO: {
- lzo_uint dst_len = MAXSIZE;
+ lzo_uint lzo_len = dest_len;
- if(lzo1x_decompress_safe(source, len, dest, &dst_len, NULL) == LZO_E_OK) {
- return dst_len;
+ if(lzo1x_decompress_safe(source, len, dest, &lzo_len, NULL) == LZO_E_OK) {
+ return lzo_len;
} else {
return 0;
}
case COMPRESS_ZLIB_3:
case COMPRESS_ZLIB_2:
case COMPRESS_ZLIB_1: {
- unsigned long destlen = MAXSIZE;
static z_stream stream;
if(stream.next_in) {
stream.next_in = source;
stream.avail_in = len;
stream.next_out = dest;
- stream.avail_out = destlen;
+ stream.avail_out = dest_len;
stream.total_out = 0;
if(inflate(&stream, Z_FINISH) == Z_STREAM_END) {
#endif
case COMPRESS_NONE:
- memcpy(dest, source, len);
- return len;
+ if(dest_len >= len) {
+ memcpy(dest, source, len);
+ return len;
+ } else {
+ return 0;
+ }
default:
return 0;
if(n->incompression != COMPRESS_NONE) {
vpn_packet_t *outpkt = pkt[nextpkt++];
- if(!(outpkt->len = uncompress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->incompression))) {
+ if(!(outpkt->len = uncompress_packet(DATA(outpkt), MAXSIZE - outpkt->offset, DATA(inpkt), inpkt->len, n->incompression))) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Error while uncompressing packet from %s (%s)",
n->name, n->hostname);
return false;
if(n->outcompression != COMPRESS_NONE) {
outpkt.offset = 0;
- length_t len = compress_packet(DATA(&outpkt) + offset, DATA(origpkt) + offset, origpkt->len - offset, n->outcompression);
+ length_t len = compress_packet(DATA(&outpkt) + offset, MAXSIZE - offset, DATA(origpkt) + offset, origpkt->len - offset, n->outcompression);
if(!len) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
if(n->outcompression != COMPRESS_NONE) {
outpkt = pkt[nextpkt++];
- if(!(outpkt->len = compress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->outcompression))) {
+ if(!(outpkt->len = compress_packet(DATA(outpkt), MAXSIZE - outpkt->offset, DATA(inpkt), inpkt->len, n->outcompression))) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)",
n->name, n->hostname);
return;
int offset = (type & PKT_MAC) ? 0 : 14;
if(type & PKT_COMPRESSED) {
- length_t ulen = uncompress_packet(DATA(&inpkt) + offset, (const uint8_t *)data, len, from->incompression);
+ length_t ulen = uncompress_packet(DATA(&inpkt) + offset, MAXSIZE - inpkt.offset, (const uint8_t *)data, len, from->incompression);
if(!ulen) {
return false;