/**
* ( C ) 2007 - 22 - 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/>
*
*/
# ifndef _N2N_TYPEDEFS_H_
# define _N2N_TYPEDEFS_H_
# include <stdbool.h>
# include <stdint.h> // for uint8_t and friends
# ifndef WIN32
# include <arpa/inet.h> // for in_addr_t
# endif
# include <uthash.h>
# include <n2n_define.h>
typedef uint8_t n2n_community_t [ N2N_COMMUNITY_SIZE ] ;
typedef uint8_t n2n_private_public_key_t [ N2N_PRIVATE_PUBLIC_KEY_SIZE ] ;
typedef uint8_t n2n_mac_t [ N2N_MAC_SIZE ] ;
typedef uint32_t n2n_cookie_t ;
typedef uint8_t n2n_desc_t [ N2N_DESC_SIZE ] ;
typedef char n2n_sock_str_t [ N2N_SOCKBUF_SIZE ] ; /* tracing string buffer */
# if defined(_MSC_VER) || defined(__MINGW32__)
# include "getopt.h"
/* Other Win environments are expected to support stdint.h */
/* stdint.h typedefs (C99) (not present in Visual Studio) */
typedef unsigned int uint32_t ;
typedef unsigned short uint16_t ;
typedef unsigned char uint8_t ;
# ifndef __MINGW32__
typedef int ssize_t ;
# endif
typedef unsigned long in_addr_t ;
# include "n2n_win32.h"
// FIXME - the above include is from a different subdir
# endif /* #if defined(_MSC_VER) || defined(__MINGW32__) */
# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
# include <machine/endian.h>
# endif
# ifdef __OpenBSD__
# include <endian.h>
# define __BYTE_ORDER BYTE_ORDER
# if BYTE_ORDER == LITTLE_ENDIAN
# ifndef __LITTLE_ENDIAN__
# define __LITTLE_ENDIAN__
# endif /* __LITTLE_ENDIAN__ */
# else
# define __BIG_ENDIAN__
# endif /* BYTE_ORDER */
# endif /* __OPENBSD__ */
# if __BYTE_ORDER == __LITTLE_ENDIAN
# ifndef __LITTLE_ENDIAN__
# define __LITTLE_ENDIAN__
# endif
# else
# ifndef __BIG_ENDIAN__
# define __BIG_ENDIAN__
# endif
# endif
# ifdef WIN32
# ifndef __LITTLE_ENDIAN__
# define __LITTLE_ENDIAN__ 1
# endif
# endif
# if !(defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__))
# if defined(__mips__)
# undef __LITTLE_ENDIAN__
# undef __LITTLE_ENDIAN
# define __BIG_ENDIAN__
# endif
/* Everything else */
# if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__))
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define __LITTLE_ENDIAN__
# else
# define __BIG_ENDIAN__
# endif
# endif
# endif
/* *************************************** */
# ifdef __GNUC__
# define PACK_STRUCT __attribute__((__packed__))
# else
# define PACK_STRUCT
# endif
# if defined(_MSC_VER) || defined(__MINGW32__)
# pragma pack(push,1)
# endif
# include <time.h>
// those are definitely not typedefs (with a view to the filename) but neither are they defines
static const n2n_mac_t broadcast_mac = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ;
static const n2n_mac_t multicast_mac = { 0x01 , 0x00 , 0x5E , 0x00 , 0x00 , 0x00 } ; /* First 3 bytes are meaningful */
static const n2n_mac_t ipv6_multicast_mac = { 0x33 , 0x33 , 0x00 , 0x00 , 0x00 , 0x00 } ; /* First 2 bytes are meaningful */
static const n2n_mac_t null_mac = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
# define ETH_ADDR_LEN 6
struct ether_hdr {
uint8_t dhost [ ETH_ADDR_LEN ] ;
uint8_t shost [ ETH_ADDR_LEN ] ;
uint16_t type ; /* higher layer protocol encapsulated */
} PACK_STRUCT ;
typedef struct ether_hdr ether_hdr_t ;
struct n2n_iphdr {
# if defined(__LITTLE_ENDIAN__)
uint8_t ihl : 4 , version : 4 ;
# elif defined(__BIG_ENDIAN__)
uint8_t version : 4 , ihl : 4 ;
# else
# error "Byte order must be defined"
# endif
uint8_t tos ;
uint16_t tot_len ;
uint16_t id ;
uint16_t frag_off ;
uint8_t ttl ;
uint8_t protocol ;
uint16_t check ;
uint32_t saddr ;
uint32_t daddr ;
} PACK_STRUCT ;
struct n2n_tcphdr {
uint16_t source ;
uint16_t dest ;
uint32_t seq ;
uint32_t ack_seq ;
# if defined(__LITTLE_ENDIAN__)
uint16_t res1 : 4 , doff : 4 , fin : 1 , syn : 1 , rst : 1 , psh : 1 , ack : 1 , urg : 1 , ece : 1 , cwr : 1 ;
# elif defined(__BIG_ENDIAN__)
uint16_t doff : 4 , res1 : 4 , cwr : 1 , ece : 1 , urg : 1 , ack : 1 , psh : 1 , rst : 1 , syn : 1 , fin : 1 ;
# else
# error "Byte order must be defined"
# endif
uint16_t window ;
uint16_t check ;
uint16_t urg_ptr ;
} PACK_STRUCT ;
struct n2n_udphdr {
uint16_t source ;
uint16_t dest ;
uint16_t len ;
uint16_t check ;
} PACK_STRUCT ;
# if defined(_MSC_VER) || defined(__MINGW32__)
# pragma pack(pop)
# endif
typedef struct port_range {
uint16_t start_port ; // range contain 'start_port' self
uint16_t end_port ; // range contain 'end_port' self
} port_range_t ;
typedef struct filter_rule_key {
in_addr_t src_net_cidr ;
uint8_t src_net_bit_len ;
port_range_t src_port_range ;
in_addr_t dst_net_cidr ;
uint8_t dst_net_bit_len ;
port_range_t dst_port_range ;
uint8_t bool_tcp_configured ;
uint8_t bool_udp_configured ;
uint8_t bool_icmp_configured ;
} filter_rule_key_t ;
typedef struct filter_rule {
filter_rule_key_t key ;
uint8_t bool_accept_icmp ;
uint8_t bool_accept_udp ;
uint8_t bool_accept_tcp ;
UT_hash_handle hh ; /* makes this structure hashable */
} filter_rule_t ;
/** 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
/** Common type used to hold stringified IP addresses. */
typedef char ipstr_t [ INET_ADDRSTRLEN ] ;
/** Common type used to hold stringified MAC addresses. */
# define N2N_MACSTR_SIZE 32
typedef char macstr_t [ N2N_MACSTR_SIZE ] ;
typedef char dec_ip_str_t [ N2N_NETMASK_STR_SIZE ] ;
typedef char dec_ip_bit_str_t [ N2N_NETMASK_STR_SIZE + 4 ] ;
typedef char devstr_t [ N2N_IFNAMSIZ ] ;
# ifndef WIN32
typedef struct tuntap_dev {
int fd ;
int if_idx ;
n2n_mac_t mac_addr ;
uint32_t ip_addr ;
uint32_t device_mask ;
uint16_t mtu ;
devstr_t dev_name ;
} tuntap_dev ;
# define SOCKET int
# else /* #ifndef WIN32 */
typedef u_short sa_family_t ;
# endif /* #ifndef WIN32 */
typedef struct speck_context_t he_context_t ;
typedef char n2n_sn_name_t [ N2N_EDGE_SN_HOST_SIZE ] ;
typedef enum n2n_pc {
n2n_ping = 0 , /* Not used */
n2n_register = 1 , /* Register edge to edge */
n2n_deregister = 2 , /* Deregister this edge */
n2n_packet = 3 , /* PACKET data content */
n2n_register_ack = 4 , /* ACK of a registration from edge to edge */
n2n_register_super = 5 , /* Register edge to supernode */
n2n_unregister_super = 6 , /* Deregister edge from supernode */
n2n_register_super_ack = 7 , /* ACK from supernode to edge */
n2n_register_super_nak = 8 , /* NAK from supernode to edge - registration refused */
n2n_federation = 9 , /* Not used by edge */
n2n_peer_info = 10 , /* Send info on a peer from sn to edge */
n2n_query_peer = 11 , /* ask supernode for info on a peer */
n2n_re_register_super = 12 /* ask edge to re-register with supernode */
} n2n_pc_t ;
# define N2N_FLAGS_OPTIONS 0x0080
# define N2N_FLAGS_SOCKET 0x0040
# define N2N_FLAGS_FROM_SUPERNODE 0x0020
/* The bits in flag that are the packet type */
# define N2N_FLAGS_TYPE_MASK 0x001f /* 0 - 31 */
# define N2N_FLAGS_BITS_MASK 0xffe0
# define IPV4_SIZE 4
# define IPV6_SIZE 16
# define N2N_AUTH_MAX_TOKEN_SIZE 48 /* max token size in bytes */
# define N2N_AUTH_CHALLENGE_SIZE 16 /* challenge always is of same size as dynamic key */
# define N2N_AUTH_ID_TOKEN_SIZE 16
# define N2N_AUTH_PW_TOKEN_SIZE (N2N_PRIVATE_PUBLIC_KEY_SIZE + N2N_AUTH_CHALLENGE_SIZE)
# define N2N_EUNKNOWN -1
# define N2N_ENOTIMPL -2
# define N2N_EINVAL -3
# define N2N_ENOSPACE -4
# define N2N_VERSION_STRING_SIZE 20
typedef char n2n_version_t [ N2N_VERSION_STRING_SIZE ] ;
# define SN_SELECTION_STRATEGY_LOAD 1
# define SN_SELECTION_STRATEGY_RTT 2
# define SN_SELECTION_STRATEGY_MAC 3
typedef struct n2n_ip_subnet {
uint32_t net_addr ; /* Host order IP address. */
uint8_t net_bitlen ; /* Subnet prefix. */
} n2n_ip_subnet_t ;
typedef struct n2n_sock {
uint8_t family ; /* AF_INET, AF_INET6 or AF_INVALID (-1, a custom #define);
mind that AF_UNSPEC ( 0 ) means auto IPv4 or IPv6 */
uint8_t type ; /* for later use, usually SOCK_STREAM (1) or SOCK_DGRAM (2) */
uint16_t port ; /* host order */
union {
uint8_t v6 [ IPV6_SIZE ] ; /* byte sequence */
uint8_t v4 [ IPV4_SIZE ] ; /* byte sequence */
} addr ;
} n2n_sock_t ;
typedef enum {
n2n_auth_none = 0 ,
n2n_auth_simple_id = 1 ,
n2n_auth_user_password = 2
} n2n_auth_scheme_t ;
typedef enum {
update_edge_no_change = 0 ,
update_edge_sock_change = 1 ,
update_edge_new_sn = 2 ,
update_edge_auth_fail = - 1
} update_edge_ret_value_t ;
typedef struct n2n_auth {
uint16_t scheme ; /* What kind of auth */
uint16_t token_size ; /* Size of auth token */
uint8_t token [ N2N_AUTH_MAX_TOKEN_SIZE ] ; /* Auth data interpreted based on scheme */
} n2n_auth_t ;
typedef struct n2n_common {
/* NOTE: wire representation is different! */
/* int version; */
uint8_t ttl ;
uint8_t pc ;
uint16_t flags ;
n2n_community_t community ;
} n2n_common_t ;
typedef struct n2n_REGISTER {
n2n_cookie_t cookie ; /**< Link REGISTER and REGISTER_ACK */
n2n_mac_t srcMac ; /**< MAC of registering party */
n2n_mac_t dstMac ; /**< MAC of target edge */
n2n_sock_t sock ; /**< Supernode's view of edge socket OR edge's preferred local socket */
n2n_ip_subnet_t dev_addr ; /**< IP address of the tuntap adapter. */
n2n_desc_t dev_desc ; /**< Hint description correlated with the edge */
} n2n_REGISTER_t ;
typedef struct n2n_REGISTER_ACK {
n2n_cookie_t cookie ; /**< Return cookie from REGISTER */
n2n_mac_t srcMac ; /**< MAC of acknowledging party (supernode or edge) */
n2n_mac_t dstMac ; /**< Reflected MAC of registering edge from REGISTER */
n2n_sock_t sock ; /**< Supernode's view of edge socket (IP Addr, port) */
} n2n_REGISTER_ACK_t ;
typedef struct n2n_PACKET {
n2n_mac_t srcMac ;
n2n_mac_t dstMac ;
n2n_sock_t sock ;
uint8_t transform ;
uint8_t compression ;
} n2n_PACKET_t ;
/* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */
typedef struct n2n_REGISTER_SUPER {
n2n_cookie_t cookie ; /**< Link REGISTER_SUPER and REGISTER_SUPER_ACK */
n2n_mac_t edgeMac ; /**< MAC to register with edge sending socket */
n2n_sock_t sock ; /**< Sending socket associated with edgeMac */
n2n_ip_subnet_t dev_addr ; /**< IP address of the tuntap adapter. */
n2n_desc_t dev_desc ; /**< Hint description correlated with the edge */
n2n_auth_t auth ; /**< Authentication scheme and tokens */
uint32_t key_time ; /**< key time for dynamic key, used between federatred supernodes only */
} n2n_REGISTER_SUPER_t ;
/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */
typedef struct n2n_REGISTER_SUPER_ACK {
n2n_cookie_t cookie ; /**< Return cookie from REGISTER_SUPER */
n2n_mac_t srcMac ; /**< MAC of answering supernode */
n2n_ip_subnet_t dev_addr ; /**< Assign an IP address to the tuntap adapter of edge. */
uint16_t lifetime ; /**< How long the registration will live */
n2n_sock_t sock ; /**< Sending sockets associated with edge */
n2n_auth_t auth ; /**< Authentication scheme and tokens */
/** The packet format provides additional supernode definitions here.
* uint8_t count , then for each count there is one
* n2n_sock_t .
*/
uint8_t num_sn ; /**< Number of supernodes that were send
* even if we cannot store them all . */
uint32_t key_time ; /**< key time for dynamic key, used between federatred supernodes only */
} n2n_REGISTER_SUPER_ACK_t ;
/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */
typedef struct n2n_REGISTER_SUPER_NAK {
n2n_cookie_t cookie ; /* Return cookie from REGISTER_SUPER */
n2n_mac_t srcMac ;
n2n_auth_t auth ; /* Authentication scheme and tokens */
} n2n_REGISTER_SUPER_NAK_t ;
/* REGISTER_SUPER_ACK may contain extra payload (their number given by num_sn)
* of following type describing a ( nother ) supernode */
typedef struct n2n_REGISTER_SUPER_ACK_payload {
// REVISIT: interim for bugfix (https://github.com/ntop/n2n/issues/1029)
// remove with 4.0
uint8_t sock [ sizeof ( uint16_t ) + sizeof ( uint16_t ) + IPV6_SIZE ] ; /**< socket of supernode */
n2n_mac_t mac ; /**< MAC of supernode */
} n2n_REGISTER_SUPER_ACK_payload_t ;
/* Linked with n2n_unregister_super in n2n_pc_t. */
typedef struct n2n_UNREGISTER_SUPER {
n2n_auth_t auth ;
n2n_mac_t srcMac ;
} n2n_UNREGISTER_SUPER_t ;
typedef struct n2n_PEER_INFO {
uint16_t aflags ;
n2n_mac_t srcMac ;
n2n_mac_t mac ;
n2n_sock_t sock ;
n2n_sock_t preferred_sock ;
uint32_t load ;
n2n_version_t version ;
time_t uptime ;
} n2n_PEER_INFO_t ;
typedef struct n2n_QUERY_PEER {
uint16_t aflags ;
n2n_mac_t srcMac ;
n2n_sock_t sock ;
n2n_mac_t targetMac ;
} n2n_QUERY_PEER_t ;
typedef struct n2n_buf n2n_buf_t ;
struct peer_info {
n2n_mac_t mac_addr ;
n2n_ip_subnet_t dev_addr ;
n2n_desc_t dev_desc ;
n2n_sock_t sock ;
SOCKET socket_fd ;
n2n_sock_t preferred_sock ;
n2n_cookie_t last_cookie ;
n2n_auth_t auth ;
int timeout ;
bool purgeable ;
time_t last_seen ;
time_t last_p2p ;
time_t last_sent_query ;
SN_SELECTION_CRITERION_DATA_TYPE selection_criterion ;
uint64_t last_valid_time_stamp ;
char * ip_addr ;
uint8_t local ;
time_t uptime ;
n2n_version_t version ;
UT_hash_handle hh ; /* makes this structure hashable */
} ;
typedef struct peer_info peer_info_t ;
# ifdef HAVE_BRIDGING_SUPPORT
struct host_info {
n2n_mac_t mac_addr ;
n2n_mac_t edge_addr ;
time_t last_seen ;
UT_hash_handle hh ; /* makes this structure hashable */
} ;
# endif
typedef struct n2n_edge n2n_edge_t ;
/* *************************************************** */
typedef enum {
N2N_ACCEPT = 0 ,
N2N_DROP = 1
} n2n_verdict ;
/* *************************************************** */
typedef enum {
FPP_UNKNOWN = 0 ,
FPP_ARP = 1 ,
FPP_TCP = 2 ,
FPP_UDP = 3 ,
FPP_ICMP = 4 ,
FPP_IGMP = 5
} filter_packet_proto ;
typedef struct packet_address_proto_info {
in_addr_t src_ip ;
uint16_t src_port ;
in_addr_t dst_ip ;
uint16_t dst_port ;
filter_packet_proto proto ;
} packet_address_proto_info_t ;
typedef struct filter_rule_pair_cache {
packet_address_proto_info_t key ;
uint8_t bool_allow_traffic ;
uint32_t active_count ;
UT_hash_handle hh ; /* makes this structure hashable */
} filter_rule_pair_cache_t ;
struct network_traffic_filter ;
typedef struct network_traffic_filter network_traffic_filter_t ;
struct network_traffic_filter {
n2n_verdict ( * filter_packet_from_peer ) ( network_traffic_filter_t * filter , n2n_edge_t * eee ,
const n2n_sock_t * peer , uint8_t * payload , uint16_t payload_size ) ;
n2n_verdict ( * filter_packet_from_tap ) ( network_traffic_filter_t * filter , n2n_edge_t * eee , uint8_t * payload , uint16_t payload_size ) ;
filter_rule_t * rules ;
filter_rule_pair_cache_t * connections_rule_cache ;
uint32_t work_count_scene_last_clear ;
} ;
/* *************************************************** */
/* Callbacks allow external programs to attach functions in response to
* N2N events . */
typedef struct n2n_edge_callbacks {
/* The supernode registration has been updated */
void ( * sn_registration_updated ) ( n2n_edge_t * eee , time_t now , const n2n_sock_t * sn ) ;
/* A packet has been received from a peer. N2N_DROP can be returned to
* drop the packet . The packet payload can be modified . This only allows
* the packet size to be reduced */
n2n_verdict ( * packet_from_peer ) ( n2n_edge_t * eee , const n2n_sock_t * peer , uint8_t * payload , uint16_t * payload_size ) ;
/* A packet has been received from the TAP interface. N2N_DROP can be
* returned to drop the packet . The packet payload can be modified .
* This only allows the packet size to be reduced */
n2n_verdict ( * packet_from_tap ) ( n2n_edge_t * eee , uint8_t * payload , uint16_t * payload_size ) ;
/* Called whenever the IP address of the TAP interface changes. */
void ( * ip_address_changed ) ( n2n_edge_t * eee , uint32_t old_ip , uint32_t new_ip ) ;
/* Called periodically in the main loop. */
void ( * main_loop_period ) ( n2n_edge_t * eee , time_t now ) ;
/* Called when a new socket to supernode is created. */
void ( * sock_opened ) ( n2n_edge_t * eee ) ;
} n2n_edge_callbacks_t ;
typedef struct n2n_tuntap_priv_config {
devstr_t tuntap_dev_name ;
char ip_mode [ N2N_IF_MODE_SIZE ] ;
dec_ip_str_t ip_addr ;
dec_ip_str_t netmask ;
char device_mac [ N2N_MACNAMSIZ ] ;
int mtu ;
int metric ;
uint8_t daemon ;
# ifndef WIN32
uid_t userid ;
gid_t groupid ;
# endif
} n2n_tuntap_priv_config_t ;
/* *************************************************** */
typedef enum n2n_transform {
N2N_TRANSFORM_ID_INVAL = 0 ,
N2N_TRANSFORM_ID_NULL = 1 ,
N2N_TRANSFORM_ID_TWOFISH = 2 ,
N2N_TRANSFORM_ID_AES = 3 ,
N2N_TRANSFORM_ID_CHACHA20 = 4 ,
N2N_TRANSFORM_ID_SPECK = 5 ,
} n2n_transform_t ;
struct n2n_trans_op ; /* Circular definition */
typedef int ( * n2n_transdeinit_f ) ( struct n2n_trans_op * arg ) ;
typedef void ( * n2n_transtick_f ) ( struct n2n_trans_op * arg , time_t now ) ;
typedef int ( * n2n_transform_f ) ( struct n2n_trans_op * arg ,
uint8_t * outbuf ,
size_t out_len ,
const uint8_t * inbuf ,
size_t in_len ,
const n2n_mac_t peer_mac ) ;
/** Holds the info associated with a data transform plugin.
*
* When a packet arrives the transform ID is extracted . This defines the code
* to use to decode the packet content . The transform code then decodes the
* packet and consults its internal key lookup .
*/
typedef struct n2n_trans_op {
void * priv ; /* opaque data. Key schedule goes here. */
uint8_t no_encryption ; /* 1 if this transop does not perform encryption */
n2n_transform_t transform_id ;
size_t tx_cnt ;
size_t rx_cnt ;
n2n_transdeinit_f deinit ; /* destructor function */
n2n_transtick_f tick ; /* periodic maintenance */
n2n_transform_f fwd ; /* encode a payload */
n2n_transform_f rev ; /* decode a payload */
} n2n_trans_op_t ;
/* *************************************************** */
typedef struct n2n_resolve_ip_sock {
char * org_ip ; /* pointer to original ip/named address string (used read only) */
n2n_sock_t sock ; /* resolved socket */
n2n_sock_t * org_sock ; /* pointer to original socket where 'sock' gets copied to from time to time */
int error_code ; /* result of last resolution attempt */
UT_hash_handle hh ; /* makes this structure hashable */
} n2n_resolve_ip_sock_t ;
// structure to hold resolver thread's parameters
typedef struct n2n_resolve_parameter {
n2n_resolve_ip_sock_t * list ; /* pointer to list of to be resolved nodes */
uint8_t changed ; /* indicates a change */
# ifdef HAVE_PTHREAD
pthread_t id ; /* thread id */
pthread_mutex_t access ; /* mutex for shared access */
# endif
uint8_t request ; /* flags main thread's need for intermediate resolution */
time_t check_interval ; /* interval to checik resolover results */
time_t last_checked ; /* last time the resolver results were cheked */
time_t last_resolved ; /* last time the resolver completed */
} n2n_resolve_parameter_t ;
/* *************************************************** */
typedef struct n2n_edge_conf {
struct peer_info * supernodes ; /**< List of supernodes */
n2n_community_t community_name ; /**< The community. 16 full octets. */
n2n_desc_t dev_desc ; /**< The device description (hint) */
n2n_private_public_key_t * public_key ; /**< edge's public key (for user/password based authentication) */
n2n_private_public_key_t * shared_secret ; /**< shared secret derived from federation public key, username and password */
he_context_t * shared_secret_ctx ; /**< context holding the roundkeys derived from shared secret */
n2n_private_public_key_t * federation_public_key ; /**< federation public key provided by command line */
uint8_t header_encryption ; /**< Header encryption indicator. */
he_context_t * header_encryption_ctx_static ; /**< Header encryption cipher context. */
he_context_t * header_encryption_ctx_dynamic ; /**< Header encryption cipher context. */
he_context_t * header_iv_ctx_static ; /**< Header IV ecnryption cipher context, REMOVE as soon as separate fileds for checksum and replay protection available */
he_context_t * header_iv_ctx_dynamic ; /**< Header IV ecnryption cipher context, REMOVE as soon as separate fileds for checksum and replay protection available */
n2n_transform_t transop_id ; /**< The transop to use. */
uint8_t compression ; /**< Compress outgoing data packets before encryption */
uint8_t tuntap_ip_mode ; /**< Interface IP address allocated mode, eg. DHCP. */
uint8_t allow_routing ; /**< Accept packet no to interface address. */
uint8_t drop_multicast ; /**< Multicast ethernet addresses. */
uint8_t disable_pmtu_discovery ; /**< Disable the Path MTU discovery. */
uint8_t allow_p2p ; /**< Allow P2P connection */
uint8_t sn_num ; /**< Number of supernode addresses defined. */
uint8_t tos ; /** TOS for sent packets */
char * encrypt_key ;
int register_interval ; /**< Interval for supernode registration, also used for UDP NAT hole punching. */
int register_ttl ; /**< TTL for registration packet when UDP NAT hole punching through supernode. */
in_addr_t bind_address ; /**< The address to bind to if provided */
n2n_sock_t preferred_sock ; /**< propagated local sock for better p2p in LAN (-e) */
uint8_t preferred_sock_auto ; /**< indicates desired auto detect for preferred sock */
int local_port ;
int mgmt_port ;
uint8_t connect_tcp ; /** connection to supernode 0 = UDP; 1 = TCP */
n2n_auth_t auth ;
filter_rule_t * network_traffic_filter_rules ;
int metric ; /**< Network interface metric (Windows only). */
uint8_t sn_selection_strategy ; /**< encodes currently chosen supernode selection strategy. */
uint8_t number_max_sn_pings ; /**< Number of maximum concurrently allowed supernode pings. */
uint64_t mgmt_password_hash ; /**< contains hash of managament port password. */
} n2n_edge_conf_t ;
struct n2n_edge_stats {
uint32_t tx_p2p ;
uint32_t rx_p2p ;
uint32_t tx_sup ;
uint32_t rx_sup ;
uint32_t tx_sup_broadcast ;
uint32_t rx_sup_broadcast ;
} ;
struct n2n_edge {
n2n_edge_conf_t conf ;
/* Status */
bool * keep_running ; /**< Pointer to edge loop stop/go flag */
struct peer_info * curr_sn ; /**< Currently active supernode. */
uint8_t sn_wait ; /**< Whether we are waiting for a supernode response. */
uint8_t sn_pong ; /**< Whether we have seen a PONG since last time reset. */
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_edge_callbacks_t cb ; /**< API callbacks */
void * user_data ; /**< Can hold user data */
SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_common_data ;
/* Sockets */
/* supernode socket is in eee->curr_sn->sock (of type n2n_sock_t) */
int sock ;
int close_socket_counter ; /**< counter for close-event before re-opening */
int udp_mgmt_sock ; /**< socket for status info. */
# ifndef SKIP_MULTICAST_PEERS_DISCOVERY
n2n_sock_t multicast_peer ; /**< Multicast peer group (for local edges) */
int udp_multicast_sock ; /**< socket for local multicast registrations. */
int multicast_joined ; /**< 1 if the group has been joined.*/
# endif
/* Peers */
struct peer_info * known_peers ; /**< Edges we are connected to. */
struct peer_info * pending_peers ; /**< Edges we have tried to register with. */
# ifdef HAVE_BRIDGING_SUPPORT
struct host_info * known_hosts ; /**< hosts we know. */
# endif
/* Timers */
time_t last_register_req ; /**< Check if time to re-register with super*/
time_t last_p2p ; /**< Last time p2p traffic was received. */
time_t last_sup ; /**< Last time a packet arrived from supernode. */
time_t last_sweep ; /**< Last time a sweep was performed. */
time_t start_time ; /**< For calculating uptime */
struct n2n_edge_stats stats ; /**< Statistics */
n2n_resolve_parameter_t * resolve_parameter ; /**< Pointer to name resolver's parameter block */
uint8_t resolution_request ; /**< Flag an immediate DNS resolution request */
n2n_tuntap_priv_config_t tuntap_priv_conf ; /**< Tuntap config */
network_traffic_filter_t * network_traffic_filter ;
} ;
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. */
} sn_stats_t ;
typedef struct node_supernode_association {
n2n_mac_t mac ; /* mac address of an edge */
socklen_t sock_len ; /* amount of actually used space (of the following) */
union {
struct sockaddr sock ; /* network order socket of that edge's supernode */
struct sockaddr_storage sas ; /* the actual memory for it, sockaddr can be too small */
} ;
time_t last_seen ; /* time mark to keep track of purging requirements */
UT_hash_handle hh ; /* makes this structure hashable */
} node_supernode_association_t ;
typedef struct sn_user {
n2n_private_public_key_t public_key ;
n2n_private_public_key_t shared_secret ;
he_context_t * shared_secret_ctx ;
n2n_desc_t name ;
UT_hash_handle hh ;
} sn_user_t ;
struct sn_community {
char community [ N2N_COMMUNITY_SIZE ] ;
uint8_t is_federation ; /* if not-zero, then the current community is the federation of supernodes */
bool purgeable ; /* indicates purgeable community (fixed-name, predetermined (-c parameter) communties usually are unpurgeable) */
uint8_t header_encryption ; /* Header encryption indicator. */
he_context_t * header_encryption_ctx_static ; /* Header encryption cipher context. */
he_context_t * header_encryption_ctx_dynamic ; /* Header encryption cipher context. */
he_context_t * header_iv_ctx_static ; /* Header IV encryption cipher context, REMOVE as soon as separate fields for checksum and replay protection available */
he_context_t * header_iv_ctx_dynamic ; /* Header IV encryption cipher context, REMOVE as soon as separate fields for checksum and replay protection available */
uint8_t dynamic_key [ N2N_AUTH_CHALLENGE_SIZE ] ; /* dynamic key */
struct peer_info * edges ; /* Link list of registered edges. */
node_supernode_association_t * assoc ; /* list of other edges from this community and their supernodes */
sn_user_t * allowed_users ; /* list of allowed users */
int64_t number_enc_packets ; /* Number of encrypted packets handled so far, required for sorting from time to time */
n2n_ip_subnet_t auto_ip_net ; /* Address range of auto ip address service. */
UT_hash_handle hh ; /* makes this structure hashable */
} ;
/* Typedef'd pointer to get abstract datatype. */
typedef struct regex_t * re_t ;
struct sn_community_regular_expression {
re_t rule ; /* compiles regular expression */
UT_hash_handle hh ; /* makes this structure hashable */
} ;
typedef struct n2n_tcp_connection {
int socket_fd ; /* file descriptor for tcp socket */
socklen_t sock_len ; /* amount of actually used space (of the following) */
union {
struct sockaddr sock ; /* network order socket */
struct sockaddr_storage sas ; /* memory for it, can be longer than sockaddr */
} ;
uint16_t expected ; /* number of bytes expected to be read */
uint16_t position ; /* current position in the buffer */
uint8_t buffer [ N2N_PKT_BUF_SIZE + sizeof ( uint16_t ) ] ; /* buffer for data collected from tcp socket incl. prepended length */
uint8_t inactive ; /* connection not be handled if set, already closed and to be deleted soon */
UT_hash_handle hh ; /* makes this structure hashable */
} n2n_tcp_connection_t ;
typedef struct n2n_sn {
bool * keep_running ; /* Pointer to sn loop stop/go flag */
time_t start_time ; /* Used to measure uptime. */
n2n_version_t version ; /* version string sent to edges along with PEER_INFO a.k.a. PONG */
sn_stats_t stats ;
int daemon ; /* If non-zero then daemonise. */
n2n_mac_t mac_addr ;
in_addr_t bind_address ; /* The address to bind to if provided */
uint16_t lport ; /* Local UDP port to bind to. */
uint16_t mport ; /* Management UDP port to bind to. */
int sock ; /* Main socket for UDP traffic with edges. */
int tcp_sock ; /* auxiliary socket for optional TCP connections */
n2n_tcp_connection_t * tcp_connections ; /* list of established TCP connections */
int mgmt_sock ; /* management socket. */
n2n_ip_subnet_t min_auto_ip_net ; /* Address range of auto_ip service. */
n2n_ip_subnet_t max_auto_ip_net ; /* Address range of auto_ip service. */
# ifndef WIN32
uid_t userid ;
gid_t groupid ;
# endif
int lock_communities ; /* If true, only loaded and matching communities can be used. */
char * community_file ;
struct sn_community * communities ;
struct sn_community_regular_expression * rules ;
struct sn_community * federation ;
n2n_private_public_key_t private_key ; /* private federation key derived from federation name */
n2n_auth_t auth ;
uint32_t dynamic_key_time ; /* UTC time of last dynamic key generation (second accuracy) */
uint8_t override_spoofing_protection ; /* set if overriding MAC/IP spoofing protection (cli option '-M') */
n2n_resolve_parameter_t * resolve_parameter ; /*Pointer to name resolver's parameter block */
uint64_t mgmt_password_hash ; /* contains hash of managament port password */
} n2n_sn_t ;
/* *************************************************** */
# endif /* _N2N_TYPEDEFS_H_ */