From 3eb82b2a323d803e9cf2580552fdcefab58827f6 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Sun, 21 Jun 2020 22:26:27 +0200 Subject: [PATCH] Code reorganization --- Makefile.in | 26 +- configure.seed | 4 +- include/edge_utils_win32.h | 34 + .../header_encryption.h | 8 - lzoconf.h => include/lzoconf.h | 0 lzodefs.h => include/lzodefs.h | 0 minilzo.h => include/minilzo.h | 0 n2n.h => include/n2n.h | 155 ++-- include/n2n_define.h | 94 ++ n2n_transforms.h => include/n2n_transforms.h | 0 n2n_wire.h => include/n2n_wire.h | 0 pearson.h => include/pearson.h | 0 .../portable_endian.h | 0 include/random_numbers.h | 38 + speck.h => include/speck.h | 0 twofish.h => include/twofish.h | 0 uthash.h => include/uthash.h | 0 random_numbers.h | 34 - edge.c => src/edge.c | 6 - edge_utils.c => src/edge_utils.c | 859 ++++++++---------- src/edge_utils_win32.c | 49 + .../example_edge_embed.c | 0 .../example_edge_embed_quick_edge_init.c | 1 - example_sn_embed.c => src/example_sn_embed.c | 0 .../header_encryption.c | 12 +- minilzo.c => src/minilzo.c | 0 n2n.c => src/n2n.c | 0 pearson.c => src/pearson.c | 0 random_numbers.c => src/random_numbers.c | 23 +- sn.c => src/sn.c | 0 sn_utils.c => src/sn_utils.c | 0 speck.c => src/speck.c | 0 transform_aes.c => src/transform_aes.c | 2 - transform_cc20.c => src/transform_cc20.c | 2 - transform_null.c => src/transform_null.c | 0 transform_speck.c => src/transform_speck.c | 4 - transform_tf.c => src/transform_tf.c | 7 - tuntap_freebsd.c => src/tuntap_freebsd.c | 0 tuntap_linux.c => src/tuntap_linux.c | 9 +- tuntap_netbsd.c => src/tuntap_netbsd.c | 0 tuntap_osx.c => src/tuntap_osx.c | 0 twofish.c => src/twofish.c | 8 +- wire.c => src/wire.c | 0 tools/Makefile.in | 4 +- 44 files changed, 712 insertions(+), 667 deletions(-) create mode 100644 include/edge_utils_win32.h rename header_encryption.h => include/header_encryption.h (95%) rename lzoconf.h => include/lzoconf.h (100%) rename lzodefs.h => include/lzodefs.h (100%) rename minilzo.h => include/minilzo.h (100%) rename n2n.h => include/n2n.h (69%) create mode 100644 include/n2n_define.h rename n2n_transforms.h => include/n2n_transforms.h (100%) rename n2n_wire.h => include/n2n_wire.h (100%) rename pearson.h => include/pearson.h (100%) rename portable_endian.h => include/portable_endian.h (100%) create mode 100644 include/random_numbers.h rename speck.h => include/speck.h (100%) rename twofish.h => include/twofish.h (100%) rename uthash.h => include/uthash.h (100%) delete mode 100644 random_numbers.h rename edge.c => src/edge.c (99%) rename edge_utils.c => src/edge_utils.c (77%) create mode 100644 src/edge_utils_win32.c rename example_edge_embed.c => src/example_edge_embed.c (100%) rename example_edge_embed_quick_edge_init.c => src/example_edge_embed_quick_edge_init.c (98%) rename example_sn_embed.c => src/example_sn_embed.c (100%) rename header_encryption.c => src/header_encryption.c (93%) rename minilzo.c => src/minilzo.c (100%) rename n2n.c => src/n2n.c (100%) rename pearson.c => src/pearson.c (100%) rename random_numbers.c => src/random_numbers.c (81%) rename sn.c => src/sn.c (100%) rename sn_utils.c => src/sn_utils.c (100%) rename speck.c => src/speck.c (100%) rename transform_aes.c => src/transform_aes.c (99%) rename transform_cc20.c => src/transform_cc20.c (99%) rename transform_null.c => src/transform_null.c (100%) rename transform_speck.c => src/transform_speck.c (98%) rename transform_tf.c => src/transform_tf.c (97%) rename tuntap_freebsd.c => src/tuntap_freebsd.c (100%) rename tuntap_linux.c => src/tuntap_linux.c (98%) rename tuntap_netbsd.c => src/tuntap_netbsd.c (100%) rename tuntap_osx.c => src/tuntap_osx.c (100%) rename twofish.c => src/twofish.c (99%) rename wire.c => src/wire.c (100%) diff --git a/Makefile.in b/Makefile.in index 1bca92c..f243a8d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5,10 +5,7 @@ GIT_COMMITS=@GIT_COMMITS@ ######## -CC?=gcc -DEBUG?=-g3 -OPTIMIZATION?=-O3 #-march=native -WARN?=-Wall +CC=@CC@ #Ultrasparc64 users experiencing SIGBUS should try the following gcc options #(thanks to Robert Gibbon) @@ -16,7 +13,7 @@ PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finlin N2N_OBJS_OPT= LIBS_EDGE_OPT=@N2N_LIBS@ -CFLAGS=@CFLAGS@ +CFLAGS=@CFLAGS@ -I ./include LDFLAGS=@LDFLAGS@ OPENSSL_CFLAGS=$(shell pkg-config openssl; echo $$?) @@ -48,12 +45,9 @@ MAN7DIR=$(MANDIR)/man7 MAN8DIR=$(MANDIR)/man8 N2N_LIB=libn2n.a -N2N_OBJS=n2n.o wire.o minilzo.o twofish.o speck.o \ - edge_utils.o sn_utils.o \ - transform_null.o transform_tf.o transform_aes.o transform_cc20.o transform_speck.o \ - header_encryption.o pearson.o \ - tuntap_freebsd.o tuntap_netbsd.o tuntap_linux.o random_numbers.o \ - tuntap_osx.o +N2N_OBJS=$(patsubst src/%.c, src/%.o, $(wildcard src/*.c)) +N2N_DEPS=$(wildcard include/*.h) $(wildcard src/*.c) Makefile + LIBS_EDGE+=$(LIBS_EDGE_OPT) LIBS_SN= @@ -77,19 +71,19 @@ all: $(APPS) $(DOCS) tools tools: $(N2N_LIB) $(MAKE) -C $@ -edge: edge.c $(N2N_LIB) n2n_wire.h n2n.h Makefile +edge: src/edge.c $(N2N_LIB) $(N2N_DEPS) $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ -supernode: sn.c $(N2N_LIB) n2n.h Makefile +supernode: src/sn.c $(N2N_LIB) $(N2N_DEPS) $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_SN) -o $@ -example_edge_embed_quick_edge_init: example_edge_embed_quick_edge_init.c $(N2N_LIB) n2n.h +example_edge_embed_quick_edge_init: src/example_edge_embed_quick_edge_init.c $(N2N_DEPS) $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ -example_sn_embed: example_sn_embed.c $(N2N_LIB) n2n.h +example_sn_embed: src/example_sn_embed.c $(N2N_DEPS) $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ -example_edge_embed: example_edge_embed.c $(N2N_LIB) n2n.h +example_edge_embed: src/example_edge_embed.c $(N2N_DEPS) $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ %.gz : % diff --git a/configure.seed b/configure.seed index db8c933..f26907e 100644 --- a/configure.seed +++ b/configure.seed @@ -15,6 +15,7 @@ fi N2N_LIBS= +AC_PROG_CC([clang]) AC_CHECK_LIB([zstd], [ZSTD_compress]) if test "x$ac_cv_lib_zstd_ZSTD_compress" != xyes; then @@ -92,6 +93,7 @@ fi DATE=`date +"%Y-%m-%d"` +AC_SUBST(CC) AC_SUBST(CFLAGS) AC_SUBST(LDFLAGS) AC_SUBST(N2N_MAJOR) @@ -104,7 +106,7 @@ AC_SUBST(GIT_RELEASE) AC_SUBST(N2N_DEFINES) AC_SUBST(N2N_LIBS) AC_SUBST(ADDITIONAL_TOOLS) -AC_CONFIG_HEADERS(config.h) +AC_CONFIG_HEADERS(include/config.h) AC_CONFIG_FILES(Makefile) AC_CONFIG_FILES(tools/Makefile) diff --git a/include/edge_utils_win32.h b/include/edge_utils_win32.h new file mode 100644 index 0000000..e82b50d --- /dev/null +++ b/include/edge_utils_win32.h @@ -0,0 +1,34 @@ +/** + * (C) 2007-20 - 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 + * + */ + +#ifdef WIN32 + +#include + +/* Multicast peers discovery disabled due to https://github.com/ntop/n2n/issues/65 */ +#define SKIP_MULTICAST_PEERS_DISCOVERY + +struct tunread_arg { + n2n_edge_t *eee; + int *keep_running; +}; + +extern HANDLE startTunReadThread(struct tunread_arg *arg); + +#endif + diff --git a/header_encryption.h b/include/header_encryption.h similarity index 95% rename from header_encryption.h rename to include/header_encryption.h index 55b017b..6f8bdee 100644 --- a/header_encryption.h +++ b/include/header_encryption.h @@ -16,11 +16,6 @@ * */ -#include - - -#include "n2n.h" -#include "speck.h" /* Header encryption indicators */ @@ -28,15 +23,12 @@ #define HEADER_ENCRYPTION_NONE 1 #define HEADER_ENCRYPTION_ENABLED 2 - uint32_t packet_header_decrypt (uint8_t packet[], uint8_t packet_len, char * community_name, he_context_t * ctx); - int8_t packet_header_decrypt_if_required (uint8_t packet[], uint16_t packet_len, struct sn_community * communities); - int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx); diff --git a/lzoconf.h b/include/lzoconf.h similarity index 100% rename from lzoconf.h rename to include/lzoconf.h diff --git a/lzodefs.h b/include/lzodefs.h similarity index 100% rename from lzodefs.h rename to include/lzodefs.h diff --git a/minilzo.h b/include/minilzo.h similarity index 100% rename from minilzo.h rename to include/minilzo.h diff --git a/n2n.h b/include/n2n.h similarity index 69% rename from n2n.h rename to include/n2n.h index 1cbb6b3..6545143 100644 --- a/n2n.h +++ b/include/n2n.h @@ -64,6 +64,8 @@ #include #include #include +#include +#include #ifndef WIN32 #include @@ -74,6 +76,16 @@ #ifdef __linux__ #define N2N_CAN_NAME_IFACE 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define GRND_NONBLOCK 1 #endif /* #ifdef __linux__ */ #ifdef __FreeBSD__ @@ -83,7 +95,12 @@ #include #include +#if defined (__RDRND__) || defined (__RDSEED__) +#include +#endif + #define ETH_ADDR_LEN 6 + struct ether_hdr { uint8_t dhost[ETH_ADDR_LEN]; @@ -93,10 +110,17 @@ struct ether_hdr typedef struct ether_hdr ether_hdr_t; +#ifdef HAVE_LIBZSTD +#include +#endif + #ifdef __ANDROID_NDK__ #undef N2N_HAVE_DAEMON #undef N2N_HAVE_SETUID #undef N2N_CAN_NAME_IFACE +#include "android/edge_android.h" +#include +#define ARP_PERIOD_INTERVAL (10) /* sec */ #endif /* #ifdef __ANDROID_NDK__ */ #include @@ -106,27 +130,37 @@ typedef struct ether_hdr ether_hdr_t; #include #include #include +#include #include #include +#include #include #include + #include "minilzo.h" +#include "n2n_define.h" #define closesocket(a) close(a) #endif /* #ifndef WIN32 */ #include - #include - #include "uthash.h" +#include "lzoconf.h" #ifdef WIN32 #include "win32/wintap.h" +#include +#else +#include #endif /* #ifdef WIN32 */ #include "n2n_wire.h" #include "n2n_transforms.h" +#include "random_numbers.h" +#include "pearson.h" +#include "portable_endian.h" +#include "speck.h" #ifdef WIN32 #define N2N_IFNAMSIZ 64 @@ -147,43 +181,6 @@ typedef struct tuntap_dev { #define SOCKET int #endif /* #ifndef WIN32 */ -#define QUICKLZ 1 - -/* N2N packet header indicators. */ -#define MSG_TYPE_REGISTER 1 -#define MSG_TYPE_DEREGISTER 2 -#define MSG_TYPE_PACKET 3 -#define MSG_TYPE_REGISTER_ACK 4 -#define MSG_TYPE_REGISTER_SUPER 5 -#define MSG_TYPE_REGISTER_SUPER_ACK 6 -#define MSG_TYPE_REGISTER_SUPER_NAK 7 -#define MSG_TYPE_FEDERATION 8 -#define MSG_TYPE_PEER_INFO 9 -#define MSG_TYPE_QUERY_PEER 10 -#define MSG_TYPE_MAX_TYPE 10 - -/* N2N compression indicators. */ -/* Compression is disabled by default for outgoing packets if no cli - * option is given. All edges are built with decompression support so - * they are able to understand each other (this applies to lzo only). */ -#define N2N_COMPRESSION_ID_NONE 0 /* default, see edge_init_conf_defaults(...) in edge_utils.c */ -#define N2N_COMPRESSION_ID_LZO 1 /* set if '-z1' or '-z' cli option is present, see setOption(...) in edge.c */ -#ifdef N2N_HAVE_ZSTD -#define N2N_COMPRESSION_ID_ZSTD 2 /* set if '-z2' cli option is present, available only if compiled with zstd lib */ -#define ZSTD_COMPRESSION_LEVEL 7 /* 1 (faster) ... 22 (more compression) */ -#endif -// with the next major packet structure update, make '0' = invalid, and '1' = no compression -// '2' = LZO, '3' = ZSTD, ... REVISIT then (also: change all occurences in source). - -#define N2N_COMPRESSION_ID_BITLEN 3 /* number of bits used for encoding compression id in the uppermost - bits of transform_id; will be obsolete as soon as compression gets - its own field in the packet. REVISIT then. */ - -/* forward delcaration of header encryption context, see 'header_encryption.h' */ -typedef struct speck_context_t he_context_t; - -#define DEFAULT_MTU 1290 - /** Uncomment this to enable the MTU check, then try to ssh to generate a fragmented packet. */ /** NOTE: see doc/MTU.md for an explanation on the 1400 value */ //#define MTU_ASSERT_VALUE 1400 @@ -206,17 +203,7 @@ struct peer_info { UT_hash_handle hh; /* makes this structure hashable */ }; -#define HASH_ADD_PEER(head,add) \ - HASH_ADD(hh,head,mac_addr,sizeof(n2n_mac_t),add) -#define HASH_FIND_PEER(head,mac,out) \ - HASH_FIND(hh,head,mac,sizeof(n2n_mac_t),out) -#define N2N_EDGE_SN_HOST_SIZE 48 -#define N2N_EDGE_NUM_SUPERNODES 2 -#define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */ -#define N2N_PATHNAME_MAXLEN 256 -#define N2N_EDGE_MGMT_PORT 5644 - - +typedef struct speck_context_t he_context_t; typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE]; typedef struct n2n_route { @@ -252,39 +239,42 @@ typedef struct n2n_edge n2n_edge_t; /* Opaque, see edge_utils.c */ typedef struct sn_stats { - size_t errors; /* Number of errors encountered. */ - size_t reg_super; /* Number of REGISTER_SUPER requests received. */ - size_t reg_super_nak; /* Number of REGISTER_SUPER requests declined. */ - size_t fwd; /* Number of messages forwarded. */ - size_t broadcast; /* Number of messages broadcast to a community. */ - time_t last_fwd; /* Time when last message was forwarded. */ - time_t last_reg_super; /* Time when last REGISTER_SUPER was received. */ + size_t errors; /* Number of errors encountered. */ + size_t reg_super; /* Number of REGISTER_SUPER requests received. */ + size_t reg_super_nak; /* Number of REGISTER_SUPER requests declined. */ + size_t fwd; /* Number of messages forwarded. */ + size_t broadcast; /* Number of messages broadcast to a community. */ + time_t last_fwd; /* Time when last message was forwarded. */ + time_t last_reg_super; /* Time when last REGISTER_SUPER was received. */ } sn_stats_t; - struct sn_community +struct sn_community { - char community[N2N_COMMUNITY_SIZE]; - uint8_t header_encryption; /* Header encryption indicator. */ - he_context_t *header_encryption_ctx; /* Header encryption cipher context. */ - struct peer_info *edges; /* Link list of registered edges. */ + char community[N2N_COMMUNITY_SIZE]; + uint8_t header_encryption; /* Header encryption indicator. */ + he_context_t *header_encryption_ctx; /* Header encryption cipher context. */ + struct peer_info *edges; /* Link list of registered edges. */ - UT_hash_handle hh; /* makes this structure hashable */ + UT_hash_handle hh; /* makes this structure hashable */ }; - typedef struct n2n_sn +typedef struct n2n_sn { - time_t start_time; /* Used to measure uptime. */ - sn_stats_t stats; - int daemon; /* If non-zero then daemonise. */ - uint16_t lport; /* Local UDP port to bind to. */ - int sock; /* Main socket for UDP traffic with edges. */ - int mgmt_sock; /* management socket. */ - int lock_communities; /* If true, only loaded communities can be used. */ - struct sn_community *communities; + time_t start_time; /* Used to measure uptime. */ + sn_stats_t stats; + int daemon; /* If non-zero then daemonise. */ + uint16_t lport; /* Local UDP port to bind to. */ + int sock; /* Main socket for UDP traffic with edges. */ + int mgmt_sock; /* management socket. */ + int lock_communities; /* If true, only loaded communities can be used. */ + struct sn_community *communities; } n2n_sn_t; /* ************************************** */ +#include "header_encryption.h" +#include "twofish.h" + #ifdef __ANDROID_NDK__ #include #endif /* #ifdef __ANDROID_NDK__ */ @@ -298,21 +288,6 @@ typedef struct sn_stats /* ************************************** */ -#define SUPERNODE_IP "127.0.0.1" -#define SUPERNODE_PORT 1234 - -/* ************************************** */ - -#ifndef max -#define max(a, b) ((a < b) ? b : a) -#endif - -#ifndef min -#define min(a, b) ((a > b) ? b : a) -#endif - -/* ************************************** */ - /* Transop Init Functions */ int n2n_transop_null_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); int n2n_transop_twofish_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); @@ -333,7 +308,7 @@ void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...); /* Tuntap API */ int tuntap_open(tuntap_dev *device, char *dev, const char *address_mode, char *device_ip, - char *device_mask, const char * device_mac, int mtu); + char *device_mask, const char * device_mac, int mtu); int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len); int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len); void tuntap_close(struct tuntap_dev *tuntap); @@ -352,10 +327,10 @@ void print_edge_stats(const n2n_edge_t *eee); /* Sockets */ char* sock_to_cstr( n2n_sock_str_t out, - const n2n_sock_t * sock ); + const n2n_sock_t * sock ); SOCKET open_socket(int local_port, int bind_any); int sock_equal( const n2n_sock_t * a, - const n2n_sock_t * b ); + const n2n_sock_t * b ); /* Operations on peer_info lists. */ size_t purge_peer_list( struct peer_info ** peer_list, diff --git a/include/n2n_define.h b/include/n2n_define.h new file mode 100644 index 0000000..f56297a --- /dev/null +++ b/include/n2n_define.h @@ -0,0 +1,94 @@ +/** + * (C) 2007-20 - 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 + * + */ + +#define QUICKLZ 1 + +/* N2N packet header indicators. */ +#define MSG_TYPE_REGISTER 1 +#define MSG_TYPE_DEREGISTER 2 +#define MSG_TYPE_PACKET 3 +#define MSG_TYPE_REGISTER_ACK 4 +#define MSG_TYPE_REGISTER_SUPER 5 +#define MSG_TYPE_REGISTER_SUPER_ACK 6 +#define MSG_TYPE_REGISTER_SUPER_NAK 7 +#define MSG_TYPE_FEDERATION 8 +#define MSG_TYPE_PEER_INFO 9 +#define MSG_TYPE_QUERY_PEER 10 +#define MSG_TYPE_MAX_TYPE 10 + +#define SOCKET_TIMEOUT_INTERVAL_SECS 10 +#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */ + +#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ +#define TRANSOP_TICK_INTERVAL (10) /* sec */ + +#define ETH_FRAMESIZE 14 +#define IP4_SRCOFFSET 12 +#define IP4_DSTOFFSET 16 +#define IP4_MIN_SIZE 20 +#define UDP_SIZE 8 + +/* 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); + + +/* N2N compression indicators. */ +/* Compression is disabled by default for outgoing packets if no cli + * option is given. All edges are built with decompression support so + * they are able to understand each other (this applies to lzo only). */ +#define N2N_COMPRESSION_ID_NONE 0 /* default, see edge_init_conf_defaults(...) in edge_utils.c */ +#define N2N_COMPRESSION_ID_LZO 1 /* set if '-z1' or '-z' cli option is present, see setOption(...) in edge.c */ +#ifdef N2N_HAVE_ZSTD +#define N2N_COMPRESSION_ID_ZSTD 2 /* set if '-z2' cli option is present, available only if compiled with zstd lib */ +#define ZSTD_COMPRESSION_LEVEL 7 /* 1 (faster) ... 22 (more compression) */ +#endif +// with the next major packet structure update, make '0' = invalid, and '1' = no compression +// '2' = LZO, '3' = ZSTD, ... REVISIT then (also: change all occurences in source). + +#define N2N_COMPRESSION_ID_BITLEN 3 /* number of bits used for encoding compression id in the uppermost + bits of transform_id; will be obsolete as soon as compression gets + its own field in the packet. REVISIT then. */ + +#define DEFAULT_MTU 1290 + +#define HASH_ADD_PEER(head,add) \ + HASH_ADD(hh,head,mac_addr,sizeof(n2n_mac_t),add) +#define HASH_FIND_PEER(head,mac,out) \ + HASH_FIND(hh,head,mac,sizeof(n2n_mac_t),out) +#define N2N_EDGE_SN_HOST_SIZE 48 +#define N2N_EDGE_NUM_SUPERNODES 2 +#define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */ +#define N2N_PATHNAME_MAXLEN 256 +#define N2N_EDGE_MGMT_PORT 5644 + +/* ************************************** */ + +#define SUPERNODE_IP "127.0.0.1" +#define SUPERNODE_PORT 1234 + +/* ************************************** */ + +#ifndef max +#define max(a, b) ((a < b) ? b : a) +#endif + +#ifndef min +#define min(a, b) ((a > b) ? b : a) +#endif + diff --git a/n2n_transforms.h b/include/n2n_transforms.h similarity index 100% rename from n2n_transforms.h rename to include/n2n_transforms.h diff --git a/n2n_wire.h b/include/n2n_wire.h similarity index 100% rename from n2n_wire.h rename to include/n2n_wire.h diff --git a/pearson.h b/include/pearson.h similarity index 100% rename from pearson.h rename to include/pearson.h diff --git a/portable_endian.h b/include/portable_endian.h similarity index 100% rename from portable_endian.h rename to include/portable_endian.h diff --git a/include/random_numbers.h b/include/random_numbers.h new file mode 100644 index 0000000..6271163 --- /dev/null +++ b/include/random_numbers.h @@ -0,0 +1,38 @@ +/** + * (C) 2007-20 - 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 + * + */ + +/* The WIN32 code is still untested and thus commented + #if defined (WIN32) + #include + #endif +*/ + +struct rn_generator_state_t { + uint64_t a, b; +}; + +struct splitmix64_state_t { + uint64_t s; +}; + + +int n2n_srand (uint64_t seed); + +uint64_t n2n_rand (); + +uint64_t n2n_seed (); diff --git a/speck.h b/include/speck.h similarity index 100% rename from speck.h rename to include/speck.h diff --git a/twofish.h b/include/twofish.h similarity index 100% rename from twofish.h rename to include/twofish.h diff --git a/uthash.h b/include/uthash.h similarity index 100% rename from uthash.h rename to include/uthash.h diff --git a/random_numbers.h b/random_numbers.h deleted file mode 100644 index aa0b0a0..0000000 --- a/random_numbers.h +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include - - -#if defined (__linux__) - #include - #include - #define GRND_NONBLOCK 1 -#endif - -#if defined (__RDRND__) || defined (__RDSEED__) - #include -#endif - -/* The WIN32 code is still untested and thus commented -#if defined (WIN32) - #include -#endif */ - - -struct rn_generator_state_t { - uint64_t a, b; -}; - -struct splitmix64_state_t { - uint64_t s; -}; - - -int n2n_srand (uint64_t seed); - -uint64_t n2n_rand (); - -uint64_t n2n_seed (); diff --git a/edge.c b/src/edge.c similarity index 99% rename from edge.c rename to src/edge.c index b15762d..9000a41 100644 --- a/edge.c +++ b/src/edge.c @@ -17,12 +17,6 @@ */ #include "n2n.h" -#include "random_numbers.h" -#ifdef WIN32 -#include -#else -#include -#endif #define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ #define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/ diff --git a/edge_utils.c b/src/edge_utils.c similarity index 77% rename from edge_utils.c rename to src/edge_utils.c index ddea110..f4487c6 100644 --- a/edge_utils.c +++ b/src/edge_utils.c @@ -17,67 +17,24 @@ */ #include "n2n.h" -#include "lzoconf.h" -#include "random_numbers.h" - -#ifdef HAVE_LIBZSTD -#include -#endif - -#ifdef WIN32 -#include -/* Multicast peers discovery disabled due to https://github.com/ntop/n2n/issues/65 */ -#define SKIP_MULTICAST_PEERS_DISCOVERY -#endif - -#ifdef __ANDROID_NDK__ -#include "android/edge_android.h" -#include -#endif /* __ANDROID_NDK__ */ - - -#define SOCKET_TIMEOUT_INTERVAL_SECS 10 -#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */ - -#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ -#define TRANSOP_TICK_INTERVAL (10) /* sec */ - -#ifdef __ANDROID_NDK__ -#define ARP_PERIOD_INTERVAL (10) /* sec */ -#endif - -#ifdef __linux__ -#include -#include -#endif - -#define ETH_FRAMESIZE 14 -#define IP4_SRCOFFSET 12 -#define IP4_DSTOFFSET 16 -#define IP4_MIN_SIZE 20 -#define UDP_SIZE 8 - -/* 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); /* ************************************** */ static const char * supernode_ip(const n2n_edge_t * eee); static void send_register(n2n_edge_t *eee, const n2n_sock_t *remote_peer, const n2n_mac_t peer_mac); static void check_peer_registration_needed(n2n_edge_t * eee, - uint8_t from_supernode, - const n2n_mac_t mac, - const n2n_sock_t * peer); + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer); static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port, uint8_t tos); static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes); static void edge_cleanup_routes(n2n_edge_t *eee); static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn); static void check_known_peer_sock_change(n2n_edge_t * eee, - uint8_t from_supernode, - const n2n_mac_t mac, - const n2n_sock_t * peer, - time_t when); + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer, + time_t when); /* ************************************** */ @@ -184,16 +141,16 @@ static int is_ethMulticast(const void * buf, size_t bufsize) { /* Match 01:00:5E:00:00:00 - 01:00:5E:7F:FF:FF */ if(bufsize >= sizeof(ether_hdr_t)) { - /* copy to aligned memory */ - ether_hdr_t eh; - memcpy(&eh, buf, sizeof(ether_hdr_t)); + /* copy to aligned memory */ + ether_hdr_t eh; + memcpy(&eh, buf, sizeof(ether_hdr_t)); - if((0x01 == eh.dhost[0]) && - (0x00 == eh.dhost[1]) && - (0x5E == eh.dhost[2]) && - (0 == (0x80 & eh.dhost[3]))) - retval = 1; /* This is an ethernet multicast packet [RFC1112]. */ - } + if((0x01 == eh.dhost[0]) && + (0x00 == eh.dhost[1]) && + (0x5E == eh.dhost[2]) && + (0 == (0x80 & eh.dhost[3]))) + retval = 1; /* This is an ethernet multicast packet [RFC1112]. */ + } return retval; } @@ -207,14 +164,14 @@ static int is_ip6_discovery(const void * buf, size_t bufsize) { int retval = 0; if(bufsize >= sizeof(ether_hdr_t)) { - /* copy to aligned memory */ - ether_hdr_t eh; + /* copy to aligned memory */ + ether_hdr_t eh; - memcpy(&eh, buf, sizeof(ether_hdr_t)); + memcpy(&eh, buf, sizeof(ether_hdr_t)); - if((0x33 == eh.dhost[0]) && (0x33 == eh.dhost[1])) - retval = 1; /* This is an IPv6 multicast packet [RFC2464]. */ - } + if((0x33 == eh.dhost[0]) && (0x33 == eh.dhost[1])) + retval = 1; /* This is an IPv6 multicast packet [RFC2464]. */ + } return retval; } @@ -306,11 +263,11 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r goto edge_init_error; } -//edge_init_success: + //edge_init_success: *rv = 0; return(eee); -edge_init_error: + edge_init_error: if(eee) free(eee); *rv = rc; @@ -377,49 +334,49 @@ static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn) { supernode_host = strtok(addr, ":"); if(supernode_host) { - in_addr_t sn_addr; - char *supernode_port = strtok(NULL, ":"); - const struct addrinfo aihints = {0, PF_INET, 0, 0, 0, NULL, NULL, NULL}; - struct addrinfo * ainfo = NULL; - int nameerr; + in_addr_t sn_addr; + char *supernode_port = strtok(NULL, ":"); + const struct addrinfo aihints = {0, PF_INET, 0, 0, 0, NULL, NULL, NULL}; + struct addrinfo * ainfo = NULL; + int nameerr; - if(supernode_port) - sn->port = atoi(supernode_port); - else - traceEvent(TRACE_WARNING, "Bad supernode parameter (-l ) %s %s:%s", - addr, supernode_host, supernode_port); + if(supernode_port) + sn->port = atoi(supernode_port); + else + traceEvent(TRACE_WARNING, "Bad supernode parameter (-l ) %s %s:%s", + addr, supernode_host, supernode_port); - nameerr = getaddrinfo(supernode_host, NULL, &aihints, &ainfo); + nameerr = getaddrinfo(supernode_host, NULL, &aihints, &ainfo); - if(0 == nameerr) - { - struct sockaddr_in * saddr; + if(0 == nameerr) + { + struct sockaddr_in * saddr; - /* ainfo s the head of a linked list if non-NULL. */ - if(ainfo && (PF_INET == ainfo->ai_family)) - { - /* It is definitely and IPv4 address -> sockaddr_in */ - saddr = (struct sockaddr_in *)ainfo->ai_addr; + /* ainfo s the head of a linked list if non-NULL. */ + if(ainfo && (PF_INET == ainfo->ai_family)) + { + /* It is definitely and IPv4 address -> sockaddr_in */ + saddr = (struct sockaddr_in *)ainfo->ai_addr; - memcpy(sn->addr.v4, &(saddr->sin_addr.s_addr), IPV4_SIZE); - sn->family=AF_INET; - } - else - { - /* Should only return IPv4 addresses due to aihints. */ - traceEvent(TRACE_WARNING, "Failed to resolve supernode IPv4 address for %s", supernode_host); - rv = -1; - } + memcpy(sn->addr.v4, &(saddr->sin_addr.s_addr), IPV4_SIZE); + sn->family=AF_INET; + } + else + { + /* Should only return IPv4 addresses due to aihints. */ + traceEvent(TRACE_WARNING, "Failed to resolve supernode IPv4 address for %s", supernode_host); + rv = -1; + } - freeaddrinfo(ainfo); /* free everything allocated by getaddrinfo(). */ - ainfo = NULL; - } else { - traceEvent(TRACE_WARNING, "Failed to resolve supernode host %s, assuming numeric", supernode_host); - sn_addr = inet_addr(supernode_host); /* uint32_t */ - memcpy(sn->addr.v4, &(sn_addr), IPV4_SIZE); - sn->family=AF_INET; - rv = -2; - } + freeaddrinfo(ainfo); /* free everything allocated by getaddrinfo(). */ + ainfo = NULL; + } else { + traceEvent(TRACE_WARNING, "Failed to resolve supernode host %s, assuming numeric", supernode_host); + sn_addr = inet_addr(supernode_host); /* uint32_t */ + memcpy(sn->addr.v4, &(sn_addr), IPV4_SIZE); + sn->family=AF_INET; + rv = -2; + } } else { traceEvent(TRACE_WARNING, "Wrong supernode parameter (-l )"); @@ -440,7 +397,7 @@ static void register_with_local_peers(n2n_edge_t * eee) { if(eee->multicast_joined && eee->conf.allow_p2p) { /* send registration to the local multicast group */ traceEvent(TRACE_DEBUG, "Registering with multicast group %s:%u", - N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT); + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT); send_register(eee, &(eee->multicast_peer), NULL); } #else @@ -464,9 +421,9 @@ static void register_with_local_peers(n2n_edge_t * eee) { * Called from the main loop when Rx a packet for our device mac. */ static void register_with_new_peer(n2n_edge_t * eee, - uint8_t from_supernode, - const n2n_mac_t mac, - const n2n_sock_t * peer) { + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer) { /* REVISIT: purge of pending_peers not yet done. */ struct peer_info * scan; macstr_t mac_buf; @@ -494,7 +451,7 @@ static void register_with_new_peer(n2n_edge_t * eee, /* trace Sending REGISTER */ if(from_supernode) { - /* UDP NAT hole punching through supernode. Send to peer first(punch local UDP hole) + /* UDP NAT hole punching through supernode. Send to peer first(punch local UDP hole) * and then ask supernode to forward. Supernode then ask peer to ack. Some nat device * drop and block ports with incoming UDP packet if out-come traffic does not exist. * So we can alternatively set TTL so that the packet sent to peer never really reaches @@ -514,12 +471,12 @@ static void register_with_new_peer(n2n_edge_t * eee, getsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, (void *)(char *)&curTTL, &lenTTL); setsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, - (void *)(char *)&eee->conf.register_ttl, - sizeof(eee->conf.register_ttl)); + (void *)(char *)&eee->conf.register_ttl, + sizeof(eee->conf.register_ttl)); for (; alter > 0; alter--, sock.port++) - { - send_register(eee, &sock, mac); - } + { + send_register(eee, &sock, mac); + } setsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, (void *)(char *)&curTTL, sizeof(curTTL)); #endif } else { /* eee->conf.register_ttl <= 0 */ @@ -541,9 +498,9 @@ static void register_with_new_peer(n2n_edge_t * eee, /** Update the last_seen time for this peer, or get registered. */ static void check_peer_registration_needed(n2n_edge_t * eee, - uint8_t from_supernode, - const n2n_mac_t mac, - const n2n_sock_t * peer) { + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer) { struct peer_info *scan; HASH_FIND_PEER(eee->known_peers, mac, scan); @@ -572,9 +529,9 @@ static void check_peer_registration_needed(n2n_edge_t * eee, * peer must be a pointer to an element of the pending_peers list. */ static void peer_set_p2p_confirmed(n2n_edge_t * eee, - const n2n_mac_t mac, - const n2n_sock_t * peer, - time_t now) { + const n2n_mac_t mac, + const n2n_sock_t * peer, + time_t now) { struct peer_info *scan; macstr_t mac_buf; n2n_sock_str_t sockbuf; @@ -591,8 +548,8 @@ static void peer_set_p2p_confirmed(n2n_edge_t * eee, scan->last_p2p = now; traceEvent(TRACE_NORMAL, "P2P connection established: %s [%s]", - macaddr_str(mac_buf, mac), - sock_to_cstr(sockbuf, peer)); + macaddr_str(mac_buf, mac), + sock_to_cstr(sockbuf, peer)); traceEvent(TRACE_DEBUG, "=== new peer %s -> %s", macaddr_str(mac_buf, scan->mac_addr), @@ -646,10 +603,10 @@ static n2n_mac_t broadcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /** Check if a known peer socket has changed and possibly register again. */ static void check_known_peer_sock_change(n2n_edge_t * eee, - uint8_t from_supernode, - const n2n_mac_t mac, - const n2n_sock_t * peer, - time_t when) { + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer, + time_t when) { struct peer_info *scan; n2n_sock_str_t sockbuf1; n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */ @@ -669,20 +626,20 @@ static void check_known_peer_sock_change(n2n_edge_t * eee, return; if(!sock_equal(&(scan->sock), peer)) { - if(!from_supernode) { - /* This is a P2P packet */ - traceEvent(TRACE_NORMAL, "Peer changed %s: %s -> %s", - macaddr_str(mac_buf, scan->mac_addr), - sock_to_cstr(sockbuf1, &(scan->sock)), - sock_to_cstr(sockbuf2, peer)); - /* The peer has changed public socket. It can no longer be assumed to be reachable. */ - HASH_DEL(eee->known_peers, scan); - free(scan); + if(!from_supernode) { + /* This is a P2P packet */ + traceEvent(TRACE_NORMAL, "Peer changed %s: %s -> %s", + macaddr_str(mac_buf, scan->mac_addr), + sock_to_cstr(sockbuf1, &(scan->sock)), + sock_to_cstr(sockbuf2, peer)); + /* The peer has changed public socket. It can no longer be assumed to be reachable. */ + HASH_DEL(eee->known_peers, scan); + free(scan); - register_with_new_peer(eee, from_supernode, mac, peer); - } else { - /* Don't worry about what the supernode reports, it could be seeing a different socket. */ - } + register_with_new_peer(eee, from_supernode, mac, peer); + } else { + /* Don't worry about what the supernode reports, it could be seeing a different socket. */ + } } else scan->last_seen = when; } @@ -726,14 +683,14 @@ static void check_join_multicast_group(n2n_edge_t *eee) { if(setsockopt(eee->udp_multicast_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) { traceEvent(TRACE_WARNING, "Failed to bind to local multicast group %s:%u [errno %u]", - N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT, errno); + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT, errno); #ifdef WIN32 traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); #endif } else { traceEvent(TRACE_NORMAL, "Successfully joined multicast group %s:%u", - N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT); + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT); eee->multicast_joined = 1; } } @@ -782,33 +739,33 @@ static void send_register_super(n2n_edge_t * eee, /** Send a QUERY_PEER packet to the current supernode. */ static void send_query_peer( n2n_edge_t * eee, const n2n_mac_t dstMac) { - uint8_t pktbuf[N2N_PKT_BUF_SIZE]; - size_t idx; - n2n_common_t cmn = {0}; - n2n_QUERY_PEER_t query = {{0}}; + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + n2n_common_t cmn = {0}; + n2n_QUERY_PEER_t query = {{0}}; - cmn.ttl=N2N_DEFAULT_TTL; - cmn.pc = n2n_query_peer; - cmn.flags = 0; - memcpy( cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE ); + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_query_peer; + cmn.flags = 0; + memcpy( cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE ); - idx=0; - encode_mac( query.srcMac, &idx, eee->device.mac_addr ); - idx=0; - encode_mac( query.targetMac, &idx, dstMac ); + idx=0; + encode_mac( query.srcMac, &idx, eee->device.mac_addr ); + idx=0; + encode_mac( query.targetMac, &idx, dstMac ); - idx=0; - encode_QUERY_PEER( pktbuf, &idx, &cmn, &query ); + idx=0; + encode_QUERY_PEER( pktbuf, &idx, &cmn, &query ); - traceEvent( TRACE_DEBUG, "send QUERY_PEER to supernode" ); + traceEvent( TRACE_DEBUG, "send QUERY_PEER to supernode" ); - sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) ); + sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) ); } /** Send a REGISTER packet to another edge. */ static void send_register(n2n_edge_t * eee, - const n2n_sock_t * remote_peer, - const n2n_mac_t peer_mac) { + const n2n_sock_t * remote_peer, + const n2n_mac_t peer_mac) { uint8_t pktbuf[N2N_PKT_BUF_SIZE]; size_t idx; /* ssize_t sent; */ @@ -1021,88 +978,88 @@ static int handle_PACKET(n2n_edge_t * eee, rx_transop_id &= (1 << (8*sizeof((uint16_t)rx_transop_id)-N2N_COMPRESSION_ID_BITLEN)) -1; if(rx_transop_id == eee->conf.transop_id) { - uint8_t is_multicast; - eth_payload = decodebuf; - eh = (ether_hdr_t*)eth_payload; - eth_size = eee->transop.rev(&eee->transop, - eth_payload, N2N_PKT_BUF_SIZE, - payload, psize, pkt->srcMac); - ++(eee->transop.rx_cnt); /* stats */ + uint8_t is_multicast; + eth_payload = decodebuf; + eh = (ether_hdr_t*)eth_payload; + 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; - int32_t deflated_len; - switch (rx_compression_id) { - case N2N_COMPRESSION_ID_NONE: - break; // continue afterwards + /* decompress if necessary */ + uint8_t * deflation_buffer = 0; + int32_t deflated_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, (lzo_uint*)&deflated_len, NULL); - break; + case N2N_COMPRESSION_ID_LZO: + deflation_buffer = malloc (N2N_PKT_BUF_SIZE); + lzo1x_decompress (eth_payload, eth_size, deflation_buffer, (lzo_uint*)&deflated_len, NULL); + break; #ifdef N2N_HAVE_ZSTD - case N2N_COMPRESSION_ID_ZSTD: - deflated_len = N2N_PKT_BUF_SIZE; - deflation_buffer = malloc (deflated_len); - deflated_len = (int32_t)ZSTD_decompress (deflation_buffer, deflated_len, eth_payload, eth_size); - if (ZSTD_isError(deflated_len)) { - traceEvent (TRACE_ERROR, "payload decompression failed with zstd error '%s'.", - ZSTD_getErrorName(deflated_len)); - free (deflation_buffer); - return (-1); // cannot help it - } - break; + case N2N_COMPRESSION_ID_ZSTD: + deflated_len = N2N_PKT_BUF_SIZE; + deflation_buffer = malloc (deflated_len); + deflated_len = (int32_t)ZSTD_decompress (deflation_buffer, deflated_len, eth_payload, eth_size); + if (ZSTD_isError(deflated_len)) { + traceEvent (TRACE_ERROR, "payload decompression failed with zstd error '%s'.", + ZSTD_getErrorName(deflated_len)); + free (deflation_buffer); + return (-1); // cannot help it + } + break; #endif - default: - traceEvent (TRACE_ERROR, "payload decompression failed: received packet indicating unsupported %s compression.", - compression_str(rx_compression_id)); - return (-1); // cannot handle it - } + default: + traceEvent (TRACE_ERROR, "payload decompression failed: received packet indicating unsupported %s compression.", + compression_str(rx_compression_id)); + return (-1); // cannot handle it + } - if (rx_compression_id) { - 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); - } + if (rx_compression_id) { + 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); + } - is_multicast = (is_ip6_discovery(eth_payload, eth_size) || is_ethMulticast(eth_payload, eth_size)); + is_multicast = (is_ip6_discovery(eth_payload, eth_size) || is_ethMulticast(eth_payload, eth_size)); - if(eee->conf.drop_multicast && is_multicast) { - traceEvent(TRACE_INFO, "Dropping RX multicast"); - return(-1); - } else if((!eee->conf.allow_routing) && (!is_multicast)) { - /* 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]; - u_int8_t *dst_mac = (u_int8_t*)eth_payload; + if(eee->conf.drop_multicast && is_multicast) { + traceEvent(TRACE_INFO, "Dropping RX multicast"); + return(-1); + } else if((!eee->conf.allow_routing) && (!is_multicast)) { + /* 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]; + u_int8_t *dst_mac = (u_int8_t*)eth_payload; - /* Note: all elements of the_ip are in network order */ - if(!memcmp(dst_mac, broadcast_mac, 6)) - traceEvent(TRACE_DEBUG, "Broadcast packet [%s]", - intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); - else if((*dst != eee->device.ip_addr)) { - /* This is a packet that needs to be routed */ - traceEvent(TRACE_INFO, "Discarding routed packet [%s]", - intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); - return(-1); - } else { - /* This packet is directed to us */ - /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ - } + /* Note: all elements of the_ip are in network order */ + if(!memcmp(dst_mac, broadcast_mac, 6)) + traceEvent(TRACE_DEBUG, "Broadcast packet [%s]", + intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); + else if((*dst != eee->device.ip_addr)) { + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "Discarding routed packet [%s]", + intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); + return(-1); + } else { + /* This packet is directed to us */ + /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ } } - - /* Write ethernet packet to tap device. */ - traceEvent(TRACE_DEBUG, "sending to TAP %u", (unsigned int)eth_size); - data_sent_len = tuntap_write(&(eee->device), eth_payload, eth_size); - - if (data_sent_len == eth_size) - { - retval = 0; - } } + + /* Write ethernet packet to tap device. */ + traceEvent(TRACE_DEBUG, "sending to TAP %u", (unsigned int)eth_size); + data_sent_len = tuntap_write(&(eee->device), eth_payload, eth_size); + + if (data_sent_len == eth_size) + { + retval = 0; + } + } else { traceEvent(TRACE_ERROR, "invalid transop ID: expected %s(%u), got %s(%u)", @@ -1317,8 +1274,8 @@ static int find_peer_destination(n2n_edge_t * eee, if(retval == 0) { memcpy(destination, &(eee->supernode), sizeof(struct sockaddr_in)); traceEvent(TRACE_DEBUG, "P2P Peer [MAC=%02X:%02X:%02X:%02X:%02X:%02X] not found, using supernode", - mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF, - mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF); + mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF, + mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF); check_query_peer_info(eee, now, mac_address); } @@ -1358,8 +1315,8 @@ static int send_packet(n2n_edge_t * eee, } traceEvent(TRACE_INFO, "Tx PACKET to %s (dest=%s) [%u B]", - sock_to_cstr(sockbuf, &destination), - macaddr_str(mac_buf, dstMac), pktlen); + sock_to_cstr(sockbuf, &destination), + macaddr_str(mac_buf, dstMac), pktlen); /* s = */ sendto_sock(eee->udp_sock, pktbuf, pktlen, &destination); @@ -1370,7 +1327,7 @@ static int send_packet(n2n_edge_t * eee, /** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */ static void send_packet2net(n2n_edge_t * eee, - uint8_t *tap_pkt, size_t len) { + uint8_t *tap_pkt, size_t len) { ipstr_t ip_buf; n2n_mac_t destMac; @@ -1432,38 +1389,38 @@ static void send_packet2net(n2n_edge_t * eee, 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; - } - } - break; + 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; + } + } + break; #ifdef N2N_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 - } - break; + 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 + } + break; #endif - default: - break; + default: + break; } if (pkt.compression) { traceEvent (TRACE_DEBUG, "payload compression [%s]: compressed %u bytes to %u bytes\n", - compression_str(pkt.compression), len, compression_len); + compression_str(pkt.compression), len, compression_len); memcpy (tap_pkt, compression_buffer, compression_len); len = compression_len; @@ -1481,11 +1438,11 @@ static void send_packet2net(n2n_edge_t * eee, encode_PACKET(pktbuf, &idx, &cmn, &pkt); idx += eee->transop.fwd(&eee->transop, - pktbuf+idx, N2N_PKT_BUF_SIZE-idx, - tap_pkt, len, pkt.dstMac); + pktbuf+idx, N2N_PKT_BUF_SIZE-idx, + tap_pkt, len, pkt.dstMac); traceEvent(TRACE_DEBUG, "Encode %u B PACKET [%u B data, %u B overhead] transform %u", - (u_int)idx, (u_int)len, (u_int)(idx-len), tx_transop_idx); + (u_int)idx, (u_int)len, (u_int)(idx-len), tx_transop_idx); #ifdef MTU_ASSERT_VALUE { @@ -1517,19 +1474,17 @@ static void readFromTAPSocket(n2n_edge_t * eee) { len = uip_arp_len; memcpy(eth_pkt, uip_arp_buf, MIN(uip_arp_len, N2N_PKT_BUF_SIZE)); traceEvent(TRACE_DEBUG, "ARP reply packet to send"); - } - else - { + } else { #endif /* #ifdef __ANDROID_NDK__ */ - len = tuntap_read( &(eee->device), eth_pkt, N2N_PKT_BUF_SIZE ); + len = tuntap_read( &(eee->device), eth_pkt, N2N_PKT_BUF_SIZE ); #ifdef __ANDROID_NDK__ - } + } #endif /* #ifdef __ANDROID_NDK__ */ if((len <= 0) || (len > N2N_PKT_BUF_SIZE)) { traceEvent(TRACE_WARNING, "read()=%d [%d/%s]", - (signed int)len, errno, strerror(errno)); + (signed int)len, errno, strerror(errno)); } else { @@ -1554,40 +1509,6 @@ static void readFromTAPSocket(n2n_edge_t * eee) { /* ************************************** */ -#ifdef WIN32 - -struct tunread_arg { - n2n_edge_t *eee; - int *keep_running; -}; - -static DWORD* tunReadThread(LPVOID lpArg) { - struct tunread_arg *arg = (struct tunread_arg*)lpArg; - - while(*arg->keep_running) - readFromTAPSocket(arg->eee); - - return((DWORD*)NULL); -} - -/* ************************************** */ - -/** Start a second thread in Windows because TUNTAP interfaces do not expose - * file descriptors. */ -static HANDLE startTunReadThread(struct tunread_arg *arg) { - DWORD dwThreadId; - - return(CreateThread(NULL, /* security attributes */ - 0, /* use default stack size */ - (LPTHREAD_START_ROUTINE)tunReadThread, /* thread function */ - (void*)arg, /* argument to thread function */ - 0, /* thread creation flags */ - &dwThreadId)); /* thread id out */ -} -#endif - -/* ************************************** */ - /** Read a datagram from the main UDP socket to the internet. */ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) { n2n_common_t cmn; /* common fields in the packet header */ @@ -1618,12 +1539,12 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) { #ifdef WIN32 if(WSAGetLastError() != WSAECONNRESET) #endif - { - traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", recvlen, errno, strerror(errno)); + { + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", recvlen, errno, strerror(errno)); #ifdef WIN32 - traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); #endif - } + } return; /* failed to receive data from UDP */ } @@ -1657,174 +1578,174 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) { from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE; if(0 == memcmp(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE)) { - switch(msg_type) { - case MSG_TYPE_PACKET: + switch(msg_type) { + case MSG_TYPE_PACKET: { - /* process PACKET - most frequent so first in list. */ - n2n_PACKET_t pkt; + /* process PACKET - most frequent so first in list. */ + n2n_PACKET_t pkt; - decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx); + decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx); - if(is_valid_peer_sock(&pkt.sock)) - orig_sender = &(pkt.sock); + if(is_valid_peer_sock(&pkt.sock)) + orig_sender = &(pkt.sock); - if(!from_supernode) { - /* This is a P2P packet from the peer. We purge a pending - * registration towards the possibly nat-ted peer address as we now have - * a valid channel. We still use check_peer_registration_needed in - * handle_PACKET to double check this. - */ - traceEvent(TRACE_DEBUG, "Got P2P packet"); - find_and_remove_peer(&eee->pending_peers, pkt.srcMac); - } + if(!from_supernode) { + /* This is a P2P packet from the peer. We purge a pending + * registration towards the possibly nat-ted peer address as we now have + * a valid channel. We still use check_peer_registration_needed in + * handle_PACKET to double check this. + */ + traceEvent(TRACE_DEBUG, "Got P2P packet"); + find_and_remove_peer(&eee->pending_peers, pkt.srcMac); + } - traceEvent(TRACE_INFO, "Rx PACKET from %s (sender=%s) [%u B]", - sock_to_cstr(sockbuf1, &sender), - sock_to_cstr(sockbuf2, orig_sender), - recvlen); + traceEvent(TRACE_INFO, "Rx PACKET from %s (sender=%s) [%u B]", + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender), + recvlen); - handle_PACKET(eee, &cmn, &pkt, orig_sender, udp_buf+idx, recvlen-idx); - break; + handle_PACKET(eee, &cmn, &pkt, orig_sender, udp_buf+idx, recvlen-idx); + break; } - case MSG_TYPE_REGISTER: + case MSG_TYPE_REGISTER: { - /* Another edge is registering with us */ - n2n_REGISTER_t reg; - n2n_mac_t null_mac = { '\0' }; - int via_multicast; + /* Another edge is registering with us */ + n2n_REGISTER_t reg; + n2n_mac_t null_mac = { '\0' }; + int via_multicast; - decode_REGISTER(®, &cmn, udp_buf, &rem, &idx); + decode_REGISTER(®, &cmn, udp_buf, &rem, &idx); - if(is_valid_peer_sock(®.sock)) - orig_sender = &(reg.sock); + if(is_valid_peer_sock(®.sock)) + orig_sender = &(reg.sock); - via_multicast = !memcmp(reg.dstMac, null_mac, 6); + via_multicast = !memcmp(reg.dstMac, null_mac, 6); - if(via_multicast && !memcmp(reg.srcMac, eee->device.mac_addr, 6)) { - traceEvent(TRACE_DEBUG, "Skipping REGISTER from self"); - break; - } - - if(!via_multicast && memcmp(reg.dstMac, eee->device.mac_addr, 6)) { - traceEvent(TRACE_DEBUG, "Skipping REGISTER for other peer"); - break; - } - - if(!from_supernode) { - /* This is a P2P registration from the peer. We purge a pending - * registration towards the possibly nat-ted peer address as we now have - * a valid channel. We still use check_peer_registration_needed below - * to double check this. - */ - traceEvent(TRACE_DEBUG, "Got P2P register"); - find_and_remove_peer(&eee->pending_peers, reg.srcMac); - - /* NOTE: only ACK to peers */ - send_register_ack(eee, orig_sender, ®); - } - - traceEvent(TRACE_INFO, "Rx REGISTER src=%s dst=%s from peer %s (%s)", - macaddr_str(mac_buf1, reg.srcMac), - macaddr_str(mac_buf2, reg.dstMac), - sock_to_cstr(sockbuf1, &sender), - sock_to_cstr(sockbuf2, orig_sender)); - - check_peer_registration_needed(eee, from_supernode, reg.srcMac, orig_sender); + if(via_multicast && !memcmp(reg.srcMac, eee->device.mac_addr, 6)) { + traceEvent(TRACE_DEBUG, "Skipping REGISTER from self"); break; + } + + if(!via_multicast && memcmp(reg.dstMac, eee->device.mac_addr, 6)) { + traceEvent(TRACE_DEBUG, "Skipping REGISTER for other peer"); + break; + } + + if(!from_supernode) { + /* This is a P2P registration from the peer. We purge a pending + * registration towards the possibly nat-ted peer address as we now have + * a valid channel. We still use check_peer_registration_needed below + * to double check this. + */ + traceEvent(TRACE_DEBUG, "Got P2P register"); + find_and_remove_peer(&eee->pending_peers, reg.srcMac); + + /* NOTE: only ACK to peers */ + send_register_ack(eee, orig_sender, ®); + } + + traceEvent(TRACE_INFO, "Rx REGISTER src=%s dst=%s from peer %s (%s)", + macaddr_str(mac_buf1, reg.srcMac), + macaddr_str(mac_buf2, reg.dstMac), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender)); + + check_peer_registration_needed(eee, from_supernode, reg.srcMac, orig_sender); + break; } - case MSG_TYPE_REGISTER_ACK: + case MSG_TYPE_REGISTER_ACK: { - /* Peer edge is acknowledging our register request */ - n2n_REGISTER_ACK_t ra; + /* Peer edge is acknowledging our register request */ + n2n_REGISTER_ACK_t ra; - decode_REGISTER_ACK(&ra, &cmn, udp_buf, &rem, &idx); + decode_REGISTER_ACK(&ra, &cmn, udp_buf, &rem, &idx); - if(is_valid_peer_sock(&ra.sock)) - orig_sender = &(ra.sock); + if(is_valid_peer_sock(&ra.sock)) + orig_sender = &(ra.sock); - traceEvent(TRACE_INFO, "Rx REGISTER_ACK src=%s dst=%s from peer %s (%s)", - macaddr_str(mac_buf1, ra.srcMac), - macaddr_str(mac_buf2, ra.dstMac), - sock_to_cstr(sockbuf1, &sender), - sock_to_cstr(sockbuf2, orig_sender)); + traceEvent(TRACE_INFO, "Rx REGISTER_ACK src=%s dst=%s from peer %s (%s)", + macaddr_str(mac_buf1, ra.srcMac), + macaddr_str(mac_buf2, ra.dstMac), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender)); - peer_set_p2p_confirmed(eee, ra.srcMac, &sender, now); - break; + peer_set_p2p_confirmed(eee, ra.srcMac, &sender, now); + break; } - case MSG_TYPE_REGISTER_SUPER_ACK: + case MSG_TYPE_REGISTER_SUPER_ACK: { - n2n_REGISTER_SUPER_ACK_t ra; + n2n_REGISTER_SUPER_ACK_t ra; - if(eee->sn_wait) - { - decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx); + if(eee->sn_wait) + { + decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx); - if(is_valid_peer_sock(&ra.sock)) - orig_sender = &(ra.sock); + if(is_valid_peer_sock(&ra.sock)) + orig_sender = &(ra.sock); - traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK myMAC=%s [%s] (external %s). Attempts %u", - macaddr_str(mac_buf1, ra.edgeMac), - sock_to_cstr(sockbuf1, &sender), - sock_to_cstr(sockbuf2, orig_sender), - (unsigned int)eee->sup_attempts); + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK myMAC=%s [%s] (external %s). Attempts %u", + macaddr_str(mac_buf1, ra.edgeMac), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender), + (unsigned int)eee->sup_attempts); - if(0 == memcmp(ra.cookie, eee->last_cookie, N2N_COOKIE_SIZE)) - { - if(ra.num_sn > 0) - { - traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK backup supernode at %s", - sock_to_cstr(sockbuf1, &(ra.sn_bak))); - } + if(0 == memcmp(ra.cookie, eee->last_cookie, N2N_COOKIE_SIZE)) + { + if(ra.num_sn > 0) + { + traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK backup supernode at %s", + sock_to_cstr(sockbuf1, &(ra.sn_bak))); + } - eee->last_sup = now; - eee->sn_wait=0; - eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */ + eee->last_sup = now; + eee->sn_wait=0; + eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */ - /* NOTE: the register_interval should be chosen by the edge node - * based on its NAT configuration. */ - //eee->conf.register_interval = ra.lifetime; - } - else - { - traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong or old cookie."); - } - } - else - { - traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER."); - } - break; + /* NOTE: the register_interval should be chosen by the edge node + * based on its NAT configuration. */ + //eee->conf.register_interval = ra.lifetime; + } + else + { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong or old cookie."); + } + } + else + { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER."); + } + break; } case MSG_TYPE_PEER_INFO: { - n2n_PEER_INFO_t pi; - struct peer_info * scan; - decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx ); + n2n_PEER_INFO_t pi; + struct peer_info * scan; + decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx ); - if(!is_valid_peer_sock(&pi.sock)) { - traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]", - sock_to_cstr(sockbuf1, &pi.sock), - macaddr_str(mac_buf1, pi.mac) ); - break; - } + if(!is_valid_peer_sock(&pi.sock)) { + traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]", + sock_to_cstr(sockbuf1, &pi.sock), + macaddr_str(mac_buf1, pi.mac) ); + break; + } - HASH_FIND_PEER(eee->pending_peers, pi.mac, scan); - if (scan) { + HASH_FIND_PEER(eee->pending_peers, pi.mac, scan); + if (scan) { scan->sock = pi.sock; traceEvent(TRACE_INFO, "Rx PEER_INFO for %s: is at %s", macaddr_str(mac_buf1, pi.mac), sock_to_cstr(sockbuf1, &pi.sock)); send_register(eee, &scan->sock, scan->mac_addr); - } else { + } else { traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s", macaddr_str(mac_buf1, pi.mac) ); - } + } - break; - } - default: - /* Not a known message type */ - traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type); - return; - } /* switch(msg_type) */ + break; + } + default: + /* Not a known message type */ + traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type); + return; + } /* switch(msg_type) */ } else if(from_supernode) /* if (community match) */ traceEvent(TRACE_WARNING, "Received packet with unknown community"); else @@ -1919,10 +1840,10 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) { #ifndef SKIP_MULTICAST_PEERS_DISCOVERY if(FD_ISSET(eee->udp_multicast_sock, &socket_mask)) { - /* Read a cooked socket from the internet socket (multicast). Writes on the TAP - * socket. */ - traceEvent(TRACE_DEBUG, "Received packet from multicast socket"); - readFromIPSocket(eee, eee->udp_multicast_sock); + /* Read a cooked socket from the internet socket (multicast). Writes on the TAP + * socket. */ + traceEvent(TRACE_DEBUG, "Received packet from multicast socket"); + readFromIPSocket(eee, eee->udp_multicast_sock); } #endif @@ -1955,7 +1876,7 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) { numPurged += purge_expired_registrations(&eee->pending_peers, &last_purge_pending); if(numPurged > 0) { - traceEvent(TRACE_INFO, "%u peers removed. now: pending=%u, operational=%u", + traceEvent(TRACE_INFO, "%u peers removed. now: pending=%u, operational=%u", numPurged, HASH_COUNT(eee->pending_peers), HASH_COUNT(eee->known_peers)); @@ -2041,7 +1962,7 @@ static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port, if(setsockopt(eee->udp_sock, IPPROTO_IP, IP_MTU_DISCOVER, &sockopt, sizeof(sockopt)) < 0) traceEvent(TRACE_WARNING, "Could not %s PMTU discovery[%d]: %s", - (eee->conf.disable_pmtu_discovery) ? "disable" : "enable", errno, strerror(errno)); + (eee->conf.disable_pmtu_discovery) ? "disable" : "enable", errno, strerror(errno)); else traceEvent(TRACE_DEBUG, "PMTU discovery %s", (eee->conf.disable_pmtu_discovery) ? "disabled" : "enabled"); #endif @@ -2121,14 +2042,14 @@ static char* route_cmd_to_str(int cmd, const n2n_route_t *route, char *buf, size char netbuf[64], gwbuf[64]; switch(cmd) { - case RTM_NEWROUTE: - cmd_str = "Add"; - break; - case RTM_DELROUTE: - cmd_str = "Delete"; - break; - default: - cmd_str = "?"; + case RTM_NEWROUTE: + cmd_str = "Add"; + break; + case RTM_DELROUTE: + cmd_str = "Delete"; + break; + default: + cmd_str = "?"; } addr.s_addr = route->net_addr; @@ -2142,30 +2063,30 @@ static char* route_cmd_to_str(int cmd, const n2n_route_t *route, char *buf, size } /* Adapted from https://olegkutkov.me/2019/08/29/modifying-linux-network-routes-using-netlink/ */ -#define NLMSG_TAIL(nmsg) \ - ((struct rtattr *) (((char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) /* Add new data to rtattr */ static int rtattr_add(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen) { - int len = RTA_LENGTH(alen); - struct rtattr *rta; + int len = RTA_LENGTH(alen); + struct rtattr *rta; - if(NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { - traceEvent(TRACE_ERROR, "rtattr_add error: message exceeded bound of %d\n", maxlen); - return -1; - } + if(NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { + traceEvent(TRACE_ERROR, "rtattr_add error: message exceeded bound of %d\n", maxlen); + return -1; + } - rta = NLMSG_TAIL(n); - rta->rta_type = type; - rta->rta_len = len; + rta = NLMSG_TAIL(n); + rta->rta_type = type; + rta->rta_len = len; - if(alen) - memcpy(RTA_DATA(rta), data, alen); + if(alen) + memcpy(RTA_DATA(rta), data, alen); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); - return 0; + return 0; } static int routectl(int cmd, int flags, n2n_route_t *route, int if_idx) { @@ -2301,7 +2222,7 @@ static int routectl(int cmd, int flags, n2n_route_t *route, int if_idx) { traceEvent(TRACE_DEBUG, route_cmd_to_str(cmd, route, route_buf, sizeof(route_buf))); rv = 0; -out: + out: close(nl_sock); return(rv); @@ -2495,7 +2416,7 @@ int quick_edge_init(char *device_name, char *community_name, edge_term(eee); edge_term_conf(&conf); -quick_edge_init_end: + quick_edge_init_end: tuntap_close(&tuntap); return(rv); } diff --git a/src/edge_utils_win32.c b/src/edge_utils_win32.c new file mode 100644 index 0000000..5f5caba --- /dev/null +++ b/src/edge_utils_win32.c @@ -0,0 +1,49 @@ +/** + * (C) 2007-20 - 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 + * + */ + +#ifdef WIN32 + +#include "edge_utils_win32.h" + +/* ************************************** */ + +static DWORD* tunReadThread(LPVOID lpArg) { + struct tunread_arg *arg = (struct tunread_arg*)lpArg; + + while(*arg->keep_running) + readFromTAPSocket(arg->eee); + + return((DWORD*)NULL); +} + +/* ************************************** */ + +/** Start a second thread in Windows because TUNTAP interfaces do not expose + * file descriptors. */ +HANDLE startTunReadThread(struct tunread_arg *arg) { + DWORD dwThreadId; + + return(CreateThread(NULL, /* security attributes */ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE)tunReadThread, /* thread function */ + (void*)arg, /* argument to thread function */ + 0, /* thread creation flags */ + &dwThreadId)); /* thread id out */ +} +#endif + diff --git a/example_edge_embed.c b/src/example_edge_embed.c similarity index 100% rename from example_edge_embed.c rename to src/example_edge_embed.c diff --git a/example_edge_embed_quick_edge_init.c b/src/example_edge_embed_quick_edge_init.c similarity index 98% rename from example_edge_embed_quick_edge_init.c rename to src/example_edge_embed_quick_edge_init.c index 4618059..39d1cd0 100644 --- a/example_edge_embed_quick_edge_init.c +++ b/src/example_edge_embed_quick_edge_init.c @@ -17,7 +17,6 @@ */ #include "n2n.h" -#include "random_numbers.h" /* This tool demonstrates how to easily embed diff --git a/example_sn_embed.c b/src/example_sn_embed.c similarity index 100% rename from example_sn_embed.c rename to src/example_sn_embed.c diff --git a/header_encryption.c b/src/header_encryption.c similarity index 93% rename from header_encryption.c rename to src/header_encryption.c index 6ce8ab4..ff61588 100644 --- a/header_encryption.c +++ b/src/header_encryption.c @@ -16,17 +16,12 @@ * */ -#include "header_encryption.h" - -#include - -#include "random_numbers.h" -#include "pearson.h" -#include "portable_endian.h" +#include "n2n.h" #define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out) +/* ********************************************************************** */ uint32_t packet_header_decrypt (uint8_t packet[], uint8_t packet_len, char * community_name, he_context_t * ctx) { @@ -58,6 +53,7 @@ uint32_t packet_header_decrypt (uint8_t packet[], uint8_t packet_len, return (0); // unsuccessful } +/* ********************************************************************** */ int8_t packet_header_decrypt_if_required (uint8_t packet[], uint16_t packet_len, struct sn_community *communities) { @@ -113,6 +109,7 @@ int8_t packet_header_decrypt_if_required (uint8_t packet[], uint16_t packet_len, } } +/* ********************************************************************** */ int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx) { uint8_t iv[16]; @@ -134,6 +131,7 @@ int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_ return (0); } +/* ********************************************************************** */ void packet_header_setup_key (char * community_name, he_context_t * ctx) { diff --git a/minilzo.c b/src/minilzo.c similarity index 100% rename from minilzo.c rename to src/minilzo.c diff --git a/n2n.c b/src/n2n.c similarity index 100% rename from n2n.c rename to src/n2n.c diff --git a/pearson.c b/src/pearson.c similarity index 100% rename from pearson.c rename to src/pearson.c diff --git a/random_numbers.c b/src/random_numbers.c similarity index 81% rename from random_numbers.c rename to src/random_numbers.c index 3c2e410..35a7753 100644 --- a/random_numbers.c +++ b/src/random_numbers.c @@ -1,12 +1,29 @@ +/** + * (C) 2007-20 - 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 + * + */ + +#include "n2n.h" + /* The following code offers an alterate pseudo random number generator namely XORSHIFT128+ to use instead of C's rand(). Its performance is on par with C's rand(). */ -#include "random_numbers.h" - - /* The state must be seeded in a way that it is not all zero, choose some arbitrary defaults (in this case: taken from splitmix64) */ static struct rn_generator_state_t rn_current_state = { diff --git a/sn.c b/src/sn.c similarity index 100% rename from sn.c rename to src/sn.c diff --git a/sn_utils.c b/src/sn_utils.c similarity index 100% rename from sn_utils.c rename to src/sn_utils.c diff --git a/speck.c b/src/speck.c similarity index 100% rename from speck.c rename to src/speck.c diff --git a/transform_aes.c b/src/transform_aes.c similarity index 99% rename from transform_aes.c rename to src/transform_aes.c index 40d652a..27eeaaf 100644 --- a/transform_aes.c +++ b/src/transform_aes.c @@ -17,8 +17,6 @@ */ #include "n2n.h" -#include "n2n_transforms.h" -#include "random_numbers.h" #ifdef N2N_HAVE_AES diff --git a/transform_cc20.c b/src/transform_cc20.c similarity index 99% rename from transform_cc20.c rename to src/transform_cc20.c index 90c92b2..44fd70b 100644 --- a/transform_cc20.c +++ b/src/transform_cc20.c @@ -17,8 +17,6 @@ */ #include "n2n.h" -#include "n2n_transforms.h" -#include "random_numbers.h" #ifdef HAVE_OPENSSL_1_1 diff --git a/transform_null.c b/src/transform_null.c similarity index 100% rename from transform_null.c rename to src/transform_null.c diff --git a/transform_speck.c b/src/transform_speck.c similarity index 98% rename from transform_speck.c rename to src/transform_speck.c index 9ae5cd7..ede1378 100644 --- a/transform_speck.c +++ b/src/transform_speck.c @@ -17,10 +17,6 @@ */ #include "n2n.h" -#include "n2n_transforms.h" -#include "speck.h" -#include "random_numbers.h" -#include "pearson.h" #define N2N_SPECK_TRANSFORM_VERSION 1 /* version of the transform encoding */ #define N2N_SPECK_IVEC_SIZE 16 diff --git a/transform_tf.c b/src/transform_tf.c similarity index 97% rename from transform_tf.c rename to src/transform_tf.c index 481e972..a630d51 100644 --- a/transform_tf.c +++ b/src/transform_tf.c @@ -17,13 +17,6 @@ */ #include "n2n.h" -#include "n2n_transforms.h" -#include "twofish.h" -#include "random_numbers.h" -#ifndef _MSC_VER -/* Not included in Visual Studio 2008 */ -#include /* index() */ -#endif #define N2N_TWOFISH_NUM_SA 32 /* space for SAa */ diff --git a/tuntap_freebsd.c b/src/tuntap_freebsd.c similarity index 100% rename from tuntap_freebsd.c rename to src/tuntap_freebsd.c diff --git a/tuntap_linux.c b/src/tuntap_linux.c similarity index 98% rename from tuntap_linux.c rename to src/tuntap_linux.c index 7a5cbb4..94b3766 100644 --- a/tuntap_linux.c +++ b/src/tuntap_linux.c @@ -16,16 +16,9 @@ * */ -#include "n2n.h" - #ifdef __linux__ -#include -#include -#include -#include -#include -#include "random_numbers.h" +#include "n2n.h" /* ********************************** */ diff --git a/tuntap_netbsd.c b/src/tuntap_netbsd.c similarity index 100% rename from tuntap_netbsd.c rename to src/tuntap_netbsd.c diff --git a/tuntap_osx.c b/src/tuntap_osx.c similarity index 100% rename from tuntap_osx.c rename to src/tuntap_osx.c diff --git a/twofish.c b/src/twofish.c similarity index 99% rename from twofish.c rename to src/twofish.c index 7c7b8de..f1e1fbc 100644 --- a/twofish.c +++ b/src/twofish.c @@ -35,13 +35,7 @@ #ifndef __TWOFISH_LIBRARY_SOURCE__ #define __TWOFISH_LIBRARY_SOURCE__ -#include -#include -#include -#include -#include -#include "twofish.h" -#include "random_numbers.h" +#include "n2n.h" /* Fixed 8x8 permutation S-boxes */ static const uint8_t TwoFish_P[2][256] = diff --git a/wire.c b/src/wire.c similarity index 100% rename from wire.c rename to src/wire.c diff --git a/tools/Makefile.in b/tools/Makefile.in index 7df143c..63176f0 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -16,8 +16,8 @@ endif LIBS_EDGE_OPT=@N2N_LIBS@ LIBS_EDGE+=$(LIBS_EDGE_OPT) -HEADERS=../n2n_wire.h ../n2n.h ../twofish.h ../n2n_transforms.h -CFLAGS+=-I.. @CFLAGS@ +HEADERS=$(wildcard include/*.h) +CFLAGS+=-I../include @CFLAGS@ LDFLAGS+=-L.. CFLAGS+=$(DEBUG) $(OPTIMIZATION) $(WARN) LDFLAGS=@LDFLAGS@