mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
Added DHCP function embedded in sn.
1. Automatically assign IP addresses to the edge through the DHCP function that comes with sn, the default IP address pool is 172.17.12.0/24. 2. The -d parameter is added to sn, and the IP address pool of the embedded DHCP can be customized. 3. Now edge does not need to add -a and -s parameters to automatically obtain the IP address. 4. The IP automatically obtained by the cross-community edge can be the same, because the communities are isolated from each other and do not interfere with each other. 5. On the management side of sn (127.0.0.1:5645), you can now view the IP address of the tutap adapter of each edge. 6. Fix many bugs that have a certain chance of causing memory leaks. 7. Note: This version is not fully compatible with the previous version.
This commit is contained in:
parent
96c05490e9
commit
92dfa67e22
168
include/n2n.h
168
include/n2n.h
|
@ -36,8 +36,6 @@
|
||||||
|
|
||||||
/* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */
|
/* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "win32/n2n_win32.h"
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include "config.h" /* Visual C++ */
|
#include "config.h" /* Visual C++ */
|
||||||
#else
|
#else
|
||||||
|
@ -171,12 +169,13 @@ typedef struct ether_hdr ether_hdr_t;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
typedef struct tuntap_dev {
|
typedef struct tuntap_dev {
|
||||||
int fd;
|
int fd;
|
||||||
int if_idx;
|
int if_idx;
|
||||||
uint8_t mac_addr[6];
|
n2n_mac_t mac_addr;
|
||||||
uint32_t ip_addr, device_mask;
|
uint32_t ip_addr;
|
||||||
uint16_t mtu;
|
uint32_t device_mask;
|
||||||
char dev_name[N2N_IFNAMSIZ];
|
uint16_t mtu;
|
||||||
|
char dev_name[N2N_IFNAMSIZ];
|
||||||
} tuntap_dev;
|
} tuntap_dev;
|
||||||
|
|
||||||
#define SOCKET int
|
#define SOCKET int
|
||||||
|
@ -192,26 +191,31 @@ typedef char ipstr_t[32];
|
||||||
/** Common type used to hold stringified MAC addresses. */
|
/** Common type used to hold stringified MAC addresses. */
|
||||||
#define N2N_MACSTR_SIZE 32
|
#define N2N_MACSTR_SIZE 32
|
||||||
typedef char macstr_t[N2N_MACSTR_SIZE];
|
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];
|
||||||
|
|
||||||
|
|
||||||
struct peer_info {
|
struct peer_info {
|
||||||
n2n_mac_t mac_addr;
|
n2n_mac_t mac_addr;
|
||||||
n2n_sock_t sock;
|
n2n_ip_subnet_t dev_addr;
|
||||||
int timeout;
|
n2n_sock_t sock;
|
||||||
time_t last_seen;
|
int timeout;
|
||||||
time_t last_p2p;
|
time_t last_seen;
|
||||||
time_t last_sent_query;
|
time_t last_p2p;
|
||||||
uint64_t last_valid_time_stamp;
|
time_t last_sent_query;
|
||||||
|
uint64_t last_valid_time_stamp;
|
||||||
|
|
||||||
UT_hash_handle hh; /* makes this structure hashable */
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct speck_context_t he_context_t;
|
typedef struct speck_context_t he_context_t;
|
||||||
typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE];
|
typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE];
|
||||||
|
|
||||||
typedef struct n2n_route {
|
typedef struct n2n_route {
|
||||||
in_addr_t net_addr;
|
in_addr_t net_addr;
|
||||||
int net_bitlen;
|
uint8_t net_bitlen;
|
||||||
in_addr_t gateway;
|
in_addr_t gateway;
|
||||||
} n2n_route_t;
|
} n2n_route_t;
|
||||||
|
|
||||||
typedef struct n2n_edge n2n_edge_t;
|
typedef struct n2n_edge n2n_edge_t;
|
||||||
|
@ -253,8 +257,8 @@ typedef struct n2n_edge_callbacks {
|
||||||
typedef struct n2n_tuntap_priv_config {
|
typedef struct n2n_tuntap_priv_config {
|
||||||
char tuntap_dev_name[N2N_IFNAMSIZ];
|
char tuntap_dev_name[N2N_IFNAMSIZ];
|
||||||
char ip_mode[N2N_IF_MODE_SIZE];
|
char ip_mode[N2N_IF_MODE_SIZE];
|
||||||
char ip_addr[N2N_NETMASK_STR_SIZE];
|
dec_ip_str_t ip_addr;
|
||||||
char netmask[N2N_NETMASK_STR_SIZE];
|
dec_ip_str_t netmask;
|
||||||
char device_mac[N2N_MACNAMSIZ];
|
char device_mac[N2N_MACNAMSIZ];
|
||||||
int mtu;
|
int mtu;
|
||||||
uint8_t got_s;
|
uint8_t got_s;
|
||||||
|
@ -267,30 +271,32 @@ typedef struct n2n_tuntap_priv_config {
|
||||||
|
|
||||||
/* *************************************************** */
|
/* *************************************************** */
|
||||||
|
|
||||||
|
|
||||||
typedef struct n2n_edge_conf {
|
typedef struct n2n_edge_conf {
|
||||||
n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES];
|
n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES];
|
||||||
n2n_route_t *routes; /**< Networks to route through n2n */
|
n2n_route_t *routes; /**< Networks to route through n2n */
|
||||||
n2n_community_t community_name; /**< The community. 16 full octets. */
|
n2n_community_t community_name; /**< The community. 16 full octets. */
|
||||||
uint8_t header_encryption; /**< Header encryption indicator. */
|
uint8_t header_encryption; /**< Header encryption indicator. */
|
||||||
he_context_t *header_encryption_ctx; /**< Header encryption cipher context. */
|
he_context_t *header_encryption_ctx; /**< Header encryption cipher context. */
|
||||||
he_context_t *header_iv_ctx; /**< Header IV ecnryption cipher context, REMOVE as soon as seperte fileds for checksum and replay protection available */
|
he_context_t *header_iv_ctx; /**< Header IV ecnryption cipher context, REMOVE as soon as seperte fileds for checksum and replay protection available */
|
||||||
n2n_transform_t transop_id; /**< The transop to use. */
|
n2n_transform_t transop_id; /**< The transop to use. */
|
||||||
uint16_t compression; /**< Compress outgoing data packets before encryption */
|
uint16_t compression; /**< Compress outgoing data packets before encryption */
|
||||||
uint16_t num_routes; /**< Number of routes in routes */
|
uint16_t num_routes; /**< Number of routes in routes */
|
||||||
uint8_t dyn_ip_mode; /**< Interface IP address is dynamically allocated, eg. DHCP. */
|
uint8_t tuntap_ip_mode; /**< Interface IP address allocated mode, eg. DHCP. */
|
||||||
uint8_t allow_routing; /**< Accept packet no to interface address. */
|
uint8_t allow_routing; /**< Accept packet no to interface address. */
|
||||||
uint8_t drop_multicast; /**< Multicast ethernet addresses. */
|
uint8_t drop_multicast; /**< Multicast ethernet addresses. */
|
||||||
uint8_t disable_pmtu_discovery; /**< Disable the Path MTU discovery. */
|
uint8_t disable_pmtu_discovery; /**< Disable the Path MTU discovery. */
|
||||||
uint8_t allow_p2p; /**< Allow P2P connection */
|
uint8_t allow_p2p; /**< Allow P2P connection */
|
||||||
uint8_t sn_num; /**< Number of supernode addresses defined. */
|
uint8_t sn_num; /**< Number of supernode addresses defined. */
|
||||||
uint8_t tos; /** TOS for sent packets */
|
uint8_t tos; /** TOS for sent packets */
|
||||||
char *encrypt_key;
|
char *encrypt_key;
|
||||||
int register_interval; /**< Interval for supernode registration, also used for UDP NAT hole punching. */
|
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. */
|
int register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */
|
||||||
int local_port;
|
int local_port;
|
||||||
int mgmt_port;
|
int mgmt_port;
|
||||||
} n2n_edge_conf_t;
|
} n2n_edge_conf_t;
|
||||||
|
|
||||||
|
|
||||||
struct n2n_edge_stats {
|
struct n2n_edge_stats {
|
||||||
uint32_t tx_p2p;
|
uint32_t tx_p2p;
|
||||||
uint32_t rx_p2p;
|
uint32_t rx_p2p;
|
||||||
|
@ -304,44 +310,45 @@ struct n2n_edge {
|
||||||
n2n_edge_conf_t conf;
|
n2n_edge_conf_t conf;
|
||||||
|
|
||||||
/* Status */
|
/* Status */
|
||||||
uint8_t sn_idx; /**< Currently active supernode. */
|
uint8_t sn_idx; /**< Currently active supernode. */
|
||||||
uint8_t sn_wait; /**< Whether we are waiting for a supernode response. */
|
uint8_t sn_wait; /**< Whether we are waiting for a supernode response. */
|
||||||
size_t sup_attempts; /**< Number of remaining attempts to this supernode. */
|
size_t sup_attempts; /**< Number of remaining attempts to this supernode. */
|
||||||
tuntap_dev device; /**< All about the TUNTAP device */
|
tuntap_dev device; /**< All about the TUNTAP device */
|
||||||
n2n_trans_op_t transop; /**< The transop to use when encoding */
|
n2n_trans_op_t transop; /**< The transop to use when encoding */
|
||||||
n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */
|
n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */
|
||||||
n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */
|
n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */
|
||||||
n2n_edge_callbacks_t cb; /**< API callbacks */
|
n2n_edge_callbacks_t cb; /**< API callbacks */
|
||||||
void *user_data; /**< Can hold user data */
|
void *user_data; /**< Can hold user data */
|
||||||
uint64_t sn_last_valid_time_stamp;/*< last valid time stamp from supernode */
|
uint64_t sn_last_valid_time_stamp;/**< last valid time stamp from supernode */
|
||||||
|
|
||||||
/* Sockets */
|
/* Sockets */
|
||||||
n2n_sock_t supernode;
|
n2n_sock_t supernode;
|
||||||
int udp_sock;
|
int udp_sock;
|
||||||
int udp_mgmt_sock; /**< socket for status info. */
|
int udp_mgmt_sock; /**< socket for status info. */
|
||||||
|
|
||||||
#ifndef SKIP_MULTICAST_PEERS_DISCOVERY
|
#ifndef SKIP_MULTICAST_PEERS_DISCOVERY
|
||||||
n2n_sock_t multicast_peer; /**< Multicast peer group (for local edges) */
|
n2n_sock_t multicast_peer; /**< Multicast peer group (for local edges) */
|
||||||
int udp_multicast_sock; /**< socket for local multicast registrations. */
|
int udp_multicast_sock; /**< socket for local multicast registrations. */
|
||||||
int multicast_joined; /**< 1 if the group has been joined.*/
|
int multicast_joined; /**< 1 if the group has been joined.*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Peers */
|
/* Peers */
|
||||||
struct peer_info * known_peers; /**< Edges we are connected to. */
|
struct peer_info * known_peers; /**< Edges we are connected to. */
|
||||||
struct peer_info * pending_peers; /**< Edges we have tried to register with. */
|
struct peer_info * pending_peers; /**< Edges we have tried to register with. */
|
||||||
|
|
||||||
/* Timers */
|
/* Timers */
|
||||||
time_t last_register_req; /**< Check if time to re-register with super*/
|
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_p2p; /**< Last time p2p traffic was received. */
|
||||||
time_t last_sup; /**< Last time a packet arrived from supernode. */
|
time_t last_sup; /**< Last time a packet arrived from supernode. */
|
||||||
time_t start_time; /**< For calculating uptime */
|
time_t start_time; /**< For calculating uptime */
|
||||||
|
|
||||||
/* Statistics */
|
|
||||||
struct n2n_edge_stats stats;
|
struct n2n_edge_stats stats; /**< Statistics */
|
||||||
/* Tuntap config */
|
|
||||||
n2n_tuntap_priv_config_t tuntap_priv_conf;
|
n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct sn_stats
|
typedef struct sn_stats
|
||||||
{
|
{
|
||||||
size_t errors; /* Number of errors encountered. */
|
size_t errors; /* Number of errors encountered. */
|
||||||
|
@ -365,21 +372,21 @@ struct sn_community
|
||||||
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. */
|
||||||
time_t start_time; /* Used to measure uptime. */
|
sn_stats_t stats;
|
||||||
sn_stats_t stats;
|
int daemon; /* If non-zero then daemonise. */
|
||||||
int daemon; /* If non-zero then daemonise. */
|
uint16_t lport; /* Local UDP port to bind to. */
|
||||||
uint16_t lport; /* Local UDP port to bind to. */
|
uint16_t mport; /* Management UDP port to bind to. */
|
||||||
uint16_t mport; /* Management UDP port to bind to. */
|
int sock; /* Main socket for UDP traffic with edges. */
|
||||||
int sock; /* Main socket for UDP traffic with edges. */
|
int mgmt_sock; /* management socket. */
|
||||||
int mgmt_sock; /* management socket. */
|
n2n_ip_subnet_t dhcp_addr; /* Address range of dhcp service. */
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
uid_t userid;
|
uid_t userid;
|
||||||
gid_t groupid;
|
gid_t groupid;
|
||||||
#endif
|
#endif
|
||||||
int lock_communities; /* If true, only loaded communities can be used. */
|
int lock_communities; /* If true, only loaded communities can be used. */
|
||||||
struct sn_community *communities;
|
struct sn_community *communities;
|
||||||
} n2n_sn_t;
|
} n2n_sn_t;
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
@ -426,6 +433,8 @@ void tuntap_get_address(struct tuntap_dev *tuntap);
|
||||||
|
|
||||||
/* Utils */
|
/* Utils */
|
||||||
char* intoa(uint32_t addr, char* buf, uint16_t buf_len);
|
char* intoa(uint32_t addr, char* buf, uint16_t buf_len);
|
||||||
|
uint32_t bitlen2mask(uint8_t bitlen);
|
||||||
|
uint8_t mask2bitlen(uint32_t mask);
|
||||||
char* macaddr_str(macstr_t buf, const n2n_mac_t mac);
|
char* macaddr_str(macstr_t buf, const n2n_mac_t mac);
|
||||||
int str2mac( uint8_t * outmac /* 6 bytes */, const char * s );
|
int str2mac( uint8_t * outmac /* 6 bytes */, const char * s );
|
||||||
uint8_t is_multi_broadcast(const uint8_t * dest_mac);
|
uint8_t is_multi_broadcast(const uint8_t * dest_mac);
|
||||||
|
@ -438,6 +447,7 @@ void print_edge_stats(const n2n_edge_t *eee);
|
||||||
/* Sockets */
|
/* Sockets */
|
||||||
char* sock_to_cstr( n2n_sock_str_t out,
|
char* sock_to_cstr( n2n_sock_str_t out,
|
||||||
const n2n_sock_t * sock );
|
const n2n_sock_t * sock );
|
||||||
|
char * ip_subnet_to_str(dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr);
|
||||||
SOCKET open_socket(int local_port, int bind_any);
|
SOCKET open_socket(int local_port, int bind_any);
|
||||||
int sock_equal( const n2n_sock_t * a,
|
int sock_equal( const n2n_sock_t * a,
|
||||||
const n2n_sock_t * b );
|
const n2n_sock_t * b );
|
||||||
|
@ -461,7 +471,9 @@ const n2n_edge_conf_t* edge_get_conf(const n2n_edge_t *eee);
|
||||||
void edge_term_conf(n2n_edge_conf_t *conf);
|
void edge_term_conf(n2n_edge_conf_t *conf);
|
||||||
|
|
||||||
/* Public functions */
|
/* Public functions */
|
||||||
n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *rv);
|
n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv);
|
||||||
|
void update_supernode_reg(n2n_edge_t * eee, time_t nowTime);
|
||||||
|
void readFromIPSocket(n2n_edge_t * eee, int in_sock);
|
||||||
void edge_term(n2n_edge_t *eee);
|
void edge_term(n2n_edge_t *eee);
|
||||||
void edge_set_callbacks(n2n_edge_t *eee, const n2n_edge_callbacks_t *callbacks);
|
void edge_set_callbacks(n2n_edge_t *eee, const n2n_edge_callbacks_t *callbacks);
|
||||||
void edge_set_userdata(n2n_edge_t *eee, void *user_data);
|
void edge_set_userdata(n2n_edge_t *eee, void *user_data);
|
||||||
|
|
|
@ -97,6 +97,15 @@
|
||||||
#define N2N_SN_PKTBUF_SIZE 2048
|
#define N2N_SN_PKTBUF_SIZE 2048
|
||||||
|
|
||||||
|
|
||||||
|
/* The way TUNTAP allocated IP. */
|
||||||
|
#define TUNTAP_IP_MODE_SN_ASSIGN 0
|
||||||
|
#define TUNTAP_IP_MODE_STATIC 1
|
||||||
|
#define TUNTAP_IP_MODE_DHCP 2
|
||||||
|
|
||||||
|
/* Default network segment of the dhcp service provided by sn. */
|
||||||
|
#define N2N_SN_DHCP_NET_ADDR_DEFAULT "172.17.12.0"
|
||||||
|
#define N2N_SN_DHCP_NET_BIT_DEFAULT 24
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
#define SUPERNODE_IP "127.0.0.1"
|
#define SUPERNODE_IP "127.0.0.1"
|
||||||
|
|
|
@ -20,19 +20,10 @@
|
||||||
#define N2N_WIRE_H_
|
#define N2N_WIRE_H_
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#ifndef _MSC_VER
|
||||||
#if defined(WIN32)
|
/* Not included in Visual Studio 2008 */
|
||||||
#include "win32/n2n_win32.h"
|
|
||||||
|
|
||||||
#if defined(__MINGW32__)
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif /* #ifdef __MINGW32__ */
|
#endif
|
||||||
|
|
||||||
#else /* #if defined(WIN32) */
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/socket.h> /* AF_INET and AF_INET6 */
|
|
||||||
#endif /* #if defined(WIN32) */
|
|
||||||
|
|
||||||
#define N2N_PKT_VERSION 2
|
#define N2N_PKT_VERSION 2
|
||||||
#define N2N_DEFAULT_TTL 2 /* can be forwarded twice at most */
|
#define N2N_DEFAULT_TTL 2 /* can be forwarded twice at most */
|
||||||
|
@ -51,6 +42,13 @@ typedef uint8_t n2n_cookie_t[N2N_COOKIE_SIZE];
|
||||||
|
|
||||||
typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */
|
typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include "win32/n2n_win32.h"
|
||||||
|
#else /* #if defined(WIN32) */
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h> /* AF_INET and AF_INET6 */
|
||||||
|
#endif /* #if defined(WIN32) */
|
||||||
|
|
||||||
typedef enum n2n_pc
|
typedef enum n2n_pc
|
||||||
{
|
{
|
||||||
n2n_ping=0, /* Not used */
|
n2n_ping=0, /* Not used */
|
||||||
|
@ -86,6 +84,12 @@ typedef enum n2n_pc
|
||||||
#define N2N_EINVAL -3
|
#define N2N_EINVAL -3
|
||||||
#define N2N_ENOSPACE -4
|
#define N2N_ENOSPACE -4
|
||||||
|
|
||||||
|
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
|
typedef struct n2n_sock
|
||||||
{
|
{
|
||||||
uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */
|
uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */
|
||||||
|
@ -117,18 +121,18 @@ typedef struct n2n_common
|
||||||
|
|
||||||
typedef struct n2n_REGISTER
|
typedef struct n2n_REGISTER
|
||||||
{
|
{
|
||||||
n2n_cookie_t cookie; /* Link REGISTER and REGISTER_ACK */
|
n2n_cookie_t cookie; /**< Link REGISTER and REGISTER_ACK */
|
||||||
n2n_mac_t srcMac; /* MAC of registering party */
|
n2n_mac_t srcMac; /**< MAC of registering party */
|
||||||
n2n_mac_t dstMac; /* MAC of target edge */
|
n2n_mac_t dstMac; /**< MAC of target edge */
|
||||||
n2n_sock_t sock; /* REVISIT: unused? */
|
n2n_sock_t sock; /**< REVISIT: unused? */
|
||||||
} n2n_REGISTER_t;
|
} n2n_REGISTER_t;
|
||||||
|
|
||||||
typedef struct n2n_REGISTER_ACK
|
typedef struct n2n_REGISTER_ACK
|
||||||
{
|
{
|
||||||
n2n_cookie_t cookie; /* Return cookie from REGISTER */
|
n2n_cookie_t cookie; /**< Return cookie from REGISTER */
|
||||||
n2n_mac_t srcMac; /* MAC of acknowledging party (supernode or edge) */
|
n2n_mac_t srcMac; /**< MAC of acknowledging party (supernode or edge) */
|
||||||
n2n_mac_t dstMac; /* Reflected MAC of registering edge from REGISTER */
|
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_sock_t sock; /**< Supernode's view of edge socket (IP Addr, port) */
|
||||||
} n2n_REGISTER_ACK_t;
|
} n2n_REGISTER_ACK_t;
|
||||||
|
|
||||||
typedef struct n2n_PACKET
|
typedef struct n2n_PACKET
|
||||||
|
@ -141,30 +145,30 @@ typedef struct n2n_PACKET
|
||||||
} n2n_PACKET_t;
|
} n2n_PACKET_t;
|
||||||
|
|
||||||
/* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */
|
/* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */
|
||||||
typedef struct n2n_REGISTER_SUPER
|
typedef struct n2n_REGISTER_SUPER {
|
||||||
{
|
n2n_cookie_t cookie; /**< Link REGISTER_SUPER and REGISTER_SUPER_ACK */
|
||||||
n2n_cookie_t cookie; /* Link REGISTER_SUPER and REGISTER_SUPER_ACK */
|
n2n_mac_t edgeMac; /**< MAC to register with edge sending socket */
|
||||||
n2n_mac_t edgeMac; /* MAC to register with edge sending socket */
|
n2n_ip_subnet_t dev_addr; /**< IP address of the tuntap adapter. */
|
||||||
n2n_auth_t auth; /* Authentication scheme and tokens */
|
n2n_auth_t auth; /**< Authentication scheme and tokens */
|
||||||
} n2n_REGISTER_SUPER_t;
|
} 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 edgeMac; /* MAC registered to edge sending socket */
|
|
||||||
uint16_t lifetime; /* How long the registration will live */
|
|
||||||
n2n_sock_t sock; /* Sending sockets associated with edgeMac */
|
|
||||||
|
|
||||||
/* The packet format provides additional supernode definitions here.
|
/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */
|
||||||
* uint8_t count, then for each count there is one
|
typedef struct n2n_REGISTER_SUPER_ACK {
|
||||||
* n2n_sock_t.
|
n2n_cookie_t cookie; /**< Return cookie from REGISTER_SUPER */
|
||||||
*/
|
n2n_mac_t edgeMac; /**< MAC registered to edge sending socket */
|
||||||
uint8_t num_sn; /* Number of supernodes that were send
|
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 edgeMac */
|
||||||
|
|
||||||
|
/** 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. If
|
* even if we cannot store them all. If
|
||||||
* non-zero then sn_bak is valid. */
|
* non-zero then sn_bak is valid. */
|
||||||
n2n_sock_t sn_bak; /* Socket of the first backup supernode */
|
n2n_sock_t sn_bak; /**< Socket of the first backup supernode */
|
||||||
|
|
||||||
} n2n_REGISTER_SUPER_ACK_t;
|
} n2n_REGISTER_SUPER_ACK_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -174,13 +178,14 @@ typedef struct n2n_REGISTER_SUPER_NAK
|
||||||
n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */
|
n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */
|
||||||
} n2n_REGISTER_SUPER_NAK_t;
|
} n2n_REGISTER_SUPER_NAK_t;
|
||||||
|
|
||||||
typedef struct n2n_PEER_INFO
|
|
||||||
{
|
typedef struct n2n_PEER_INFO {
|
||||||
uint16_t aflags;
|
uint16_t aflags;
|
||||||
n2n_mac_t mac;
|
n2n_mac_t mac;
|
||||||
n2n_sock_t sock;
|
n2n_sock_t sock;
|
||||||
} n2n_PEER_INFO_t;
|
} n2n_PEER_INFO_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct n2n_QUERY_PEER
|
typedef struct n2n_QUERY_PEER
|
||||||
{
|
{
|
||||||
n2n_mac_t srcMac;
|
n2n_mac_t srcMac;
|
||||||
|
|
76
src/edge.c
76
src/edge.c
|
@ -450,7 +450,7 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
|
||||||
char cidr_net[64], gateway[64];
|
char cidr_net[64], gateway[64];
|
||||||
n2n_route_t route;
|
n2n_route_t route;
|
||||||
|
|
||||||
if(sscanf(optargument, "%63[^/]/%d:%63s", cidr_net, &route.net_bitlen, gateway) != 3) {
|
if(sscanf(optargument, "%63[^/]/%hhd:%63s", cidr_net, &route.net_bitlen, gateway) != 3) {
|
||||||
traceEvent(TRACE_WARNING, "Bad cidr/gateway format '%d'. See -h.", optargument);
|
traceEvent(TRACE_WARNING, "Bad cidr/gateway format '%d'. See -h.", optargument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -818,7 +818,6 @@ int main(int argc, char* argv[]) {
|
||||||
#else
|
#else
|
||||||
snprintf(ec.tuntap_dev_name, sizeof(ec.tuntap_dev_name), "edge0");
|
snprintf(ec.tuntap_dev_name, sizeof(ec.tuntap_dev_name), "edge0");
|
||||||
#endif
|
#endif
|
||||||
snprintf(ec.ip_mode, sizeof(ec.ip_mode), "static");
|
|
||||||
snprintf(ec.netmask, sizeof(ec.netmask), "255.255.255.0");
|
snprintf(ec.netmask, sizeof(ec.netmask), "255.255.255.0");
|
||||||
|
|
||||||
if((argc >= 2) && (argv[1][0] != '-')) {
|
if((argc >= 2) && (argv[1][0] != '-')) {
|
||||||
|
@ -861,21 +860,6 @@ int main(int argc, char* argv[]) {
|
||||||
/* Random seed */
|
/* Random seed */
|
||||||
n2n_srand (n2n_seed());
|
n2n_srand (n2n_seed());
|
||||||
|
|
||||||
if(0 == strcmp("dhcp", ec.ip_mode)) {
|
|
||||||
traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled.");
|
|
||||||
|
|
||||||
conf.dyn_ip_mode = 1;
|
|
||||||
} else
|
|
||||||
traceEvent(TRACE_NORMAL, "ip_mode='%s'", ec.ip_mode);
|
|
||||||
|
|
||||||
if(!(
|
|
||||||
#ifdef __linux__
|
|
||||||
(ec.tuntap_dev_name[0] != 0) &&
|
|
||||||
#endif
|
|
||||||
(ec.ip_addr[0] != 0)
|
|
||||||
))
|
|
||||||
help();
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
/* If running suid root then we need to setuid before using the force. */
|
/* If running suid root then we need to setuid before using the force. */
|
||||||
if(setuid(0) != 0)
|
if(setuid(0) != 0)
|
||||||
|
@ -886,17 +870,51 @@ int main(int argc, char* argv[]) {
|
||||||
if(conf.encrypt_key && !strcmp((char*)conf.community_name, conf.encrypt_key))
|
if(conf.encrypt_key && !strcmp((char*)conf.community_name, conf.encrypt_key))
|
||||||
traceEvent(TRACE_WARNING, "Community and encryption key must differ, otherwise security will be compromised");
|
traceEvent(TRACE_WARNING, "Community and encryption key must differ, otherwise security will be compromised");
|
||||||
|
|
||||||
if(tuntap_open(&tuntap, ec.tuntap_dev_name, ec.ip_mode, ec.ip_addr, ec.netmask, ec.device_mac, ec.mtu) < 0)
|
if((eee = edge_init(&conf, &rc)) == NULL) {
|
||||||
exit(1);
|
|
||||||
|
|
||||||
if((eee = edge_init(&tuntap, &conf, &rc)) == NULL) {
|
|
||||||
traceEvent(TRACE_ERROR, "Failed in edge_init");
|
traceEvent(TRACE_ERROR, "Failed in edge_init");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memcpy(&(eee->tuntap_priv_conf), &ec, sizeof(ec));
|
memcpy(&(eee->tuntap_priv_conf), &ec, sizeof(ec));
|
||||||
|
|
||||||
|
if ((0 == strcmp("static", eee->tuntap_priv_conf.ip_mode)) ||
|
||||||
|
((eee->tuntap_priv_conf.ip_mode[0] == '\0') && (eee->tuntap_priv_conf.ip_addr[0] != '\0'))) {
|
||||||
|
traceEvent(TRACE_NORMAL, "Use manually set IP address.");
|
||||||
|
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_STATIC;
|
||||||
|
} else if (0 == strcmp("dhcp", eee->tuntap_priv_conf.ip_mode)) {
|
||||||
|
traceEvent(TRACE_NORMAL, "Obtain IP from other edge DHCP services.");
|
||||||
|
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_DHCP;
|
||||||
|
} else {
|
||||||
|
traceEvent(TRACE_NORMAL, "Automatically assign IP address by supernode.");
|
||||||
|
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN;
|
||||||
|
do {
|
||||||
|
fd_set socket_mask;
|
||||||
|
struct timeval wait_time;
|
||||||
|
|
||||||
|
update_supernode_reg(eee, time(NULL));
|
||||||
|
FD_ZERO(&socket_mask);
|
||||||
|
FD_SET(eee->udp_sock, &socket_mask);
|
||||||
|
wait_time.tv_sec = SOCKET_TIMEOUT_INTERVAL_SECS;
|
||||||
|
wait_time.tv_usec = 0;
|
||||||
|
|
||||||
|
if (select(eee->udp_sock + 1, &socket_mask, NULL, NULL, &wait_time) > 0) {
|
||||||
|
if (FD_ISSET(eee->udp_sock, &socket_mask)) {
|
||||||
|
readFromIPSocket(eee, eee->udp_sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (eee->sn_wait);
|
||||||
|
eee->last_register_req = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tuntap_open(&tuntap, eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode,
|
||||||
|
eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask,
|
||||||
|
eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu) < 0) exit(1);
|
||||||
|
traceEvent(TRACE_NORMAL, "Local tuntap IP: %s, Mask: %s",
|
||||||
|
eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask);
|
||||||
|
memcpy(&eee->device, &tuntap, sizeof(tuntap));
|
||||||
|
// hexdump((unsigned char*)&tuntap,sizeof(tuntap_dev));
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if(ec.daemon) {
|
if(eee->tuntap_priv_conf.daemon) {
|
||||||
setUseSyslog(1); /* traceEvent output now goes to syslog. */
|
setUseSyslog(1); /* traceEvent output now goes to syslog. */
|
||||||
daemonize();
|
daemonize();
|
||||||
}
|
}
|
||||||
|
@ -919,13 +937,13 @@ int main(int argc, char* argv[]) {
|
||||||
#endif
|
#endif
|
||||||
#endif /* HAVE_LIBCAP */
|
#endif /* HAVE_LIBCAP */
|
||||||
|
|
||||||
if((ec.userid != 0) || (ec.groupid != 0)) {
|
if((eee->tuntap_priv_conf.userid != 0) || (eee->tuntap_priv_conf.groupid != 0)) {
|
||||||
traceEvent(TRACE_NORMAL, "Dropping privileges to uid=%d, gid=%d",
|
traceEvent(TRACE_NORMAL, "Dropping privileges to uid=%d, gid=%d",
|
||||||
(signed int)ec.userid, (signed int)ec.groupid);
|
(signed int)eee->tuntap_priv_conf.userid, (signed int)eee->tuntap_priv_conf.groupid);
|
||||||
|
|
||||||
/* Finished with the need for root privileges. Drop to unprivileged user. */
|
/* Finished with the need for root privileges. Drop to unprivileged user. */
|
||||||
if((setgid(ec.groupid) != 0)
|
if((setgid(eee->tuntap_priv_conf.groupid) != 0)
|
||||||
|| (setuid(ec.userid) != 0)) {
|
|| (setuid(eee->tuntap_priv_conf.userid) != 0)) {
|
||||||
traceEvent(TRACE_ERROR, "Unable to drop privileges [%u/%s]", errno, strerror(errno));
|
traceEvent(TRACE_ERROR, "Unable to drop privileges [%u/%s]", errno, strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -961,10 +979,8 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
edge_term(eee);
|
edge_term(eee);
|
||||||
edge_term_conf(&conf);
|
edge_term_conf(&eee->conf);
|
||||||
tuntap_close(&tuntap);
|
tuntap_close(&eee->device);
|
||||||
|
|
||||||
if(conf.encrypt_key) free(conf.encrypt_key);
|
|
||||||
|
|
||||||
return(rc);
|
return(rc);
|
||||||
}
|
}
|
||||||
|
|
148
src/edge_utils.c
148
src/edge_utils.c
|
@ -167,7 +167,7 @@ static int is_ip6_discovery(const void * buf, size_t bufsize) {
|
||||||
*
|
*
|
||||||
* This also initialises the NULL transform operation opstruct.
|
* This also initialises the NULL transform operation opstruct.
|
||||||
*/
|
*/
|
||||||
n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *rv) {
|
n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv) {
|
||||||
n2n_transform_t transop_id = conf->transop_id;
|
n2n_transform_t transop_id = conf->transop_id;
|
||||||
n2n_edge_t *eee = calloc(1, sizeof(n2n_edge_t));
|
n2n_edge_t *eee = calloc(1, sizeof(n2n_edge_t));
|
||||||
int rc = -1, i;
|
int rc = -1, i;
|
||||||
|
@ -187,7 +187,6 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memcpy(&eee->conf, conf, sizeof(*conf));
|
memcpy(&eee->conf, conf, sizeof(*conf));
|
||||||
memcpy(&eee->device, dev, sizeof(*dev));
|
|
||||||
eee->start_time = time(NULL);
|
eee->start_time = time(NULL);
|
||||||
|
|
||||||
eee->known_peers = NULL;
|
eee->known_peers = NULL;
|
||||||
|
@ -207,11 +206,11 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r
|
||||||
// zstd does not require initialization. if it were required, this would be a good place
|
// zstd does not require initialization. if it were required, this would be a good place
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(i=0; i<conf->sn_num; ++i)
|
for(i=0; i<eee->conf.sn_num; ++i)
|
||||||
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (conf->sn_ip_array[i]));
|
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (eee->conf.sn_ip_array[i]));
|
||||||
|
|
||||||
/* Set the active supernode */
|
/* Set the active supernode */
|
||||||
supernode2addr(&(eee->supernode), conf->sn_ip_array[eee->sn_idx]);
|
supernode2addr(&(eee->supernode), eee->conf.sn_ip_array[eee->sn_idx]);
|
||||||
|
|
||||||
/* Set active transop */
|
/* Set active transop */
|
||||||
switch(transop_id) {
|
switch(transop_id) {
|
||||||
|
@ -243,18 +242,18 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r
|
||||||
/* Set the key schedule (context) for header encryption if enabled */
|
/* Set the key schedule (context) for header encryption if enabled */
|
||||||
if(conf->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
if(conf->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
traceEvent(TRACE_NORMAL, "Header encryption is enabled.");
|
traceEvent(TRACE_NORMAL, "Header encryption is enabled.");
|
||||||
packet_header_setup_key ((char *)(conf->community_name), &(eee->conf.header_encryption_ctx),&(eee->conf.header_iv_ctx));
|
packet_header_setup_key ((char *)(eee->conf.community_name), &(eee->conf.header_encryption_ctx),&(eee->conf.header_iv_ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(eee->transop.no_encryption)
|
if(eee->transop.no_encryption)
|
||||||
traceEvent(TRACE_WARNING, "Encryption is disabled in edge");
|
traceEvent(TRACE_WARNING, "Encryption is disabled in edge");
|
||||||
|
|
||||||
if(edge_init_sockets(eee, conf->local_port, conf->mgmt_port, conf->tos) < 0) {
|
if(edge_init_sockets(eee, eee->conf.local_port, eee->conf.mgmt_port, eee->conf.tos) < 0) {
|
||||||
traceEvent(TRACE_ERROR, "socket setup failed");
|
traceEvent(TRACE_ERROR, "socket setup failed");
|
||||||
goto edge_init_error;
|
goto edge_init_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(edge_init_routes(eee, conf->routes, conf->num_routes) < 0) {
|
if(edge_init_routes(eee, eee->conf.routes, eee->conf.num_routes) < 0) {
|
||||||
traceEvent(TRACE_ERROR, "routes setup failed");
|
traceEvent(TRACE_ERROR, "routes setup failed");
|
||||||
goto edge_init_error;
|
goto edge_init_error;
|
||||||
}
|
}
|
||||||
|
@ -389,7 +388,7 @@ static const int definitely_from_supernode = 1;
|
||||||
* and verify it (and also update, if applicable).
|
* and verify it (and also update, if applicable).
|
||||||
*/
|
*/
|
||||||
static int find_peer_time_stamp_and_verify (n2n_edge_t * eee,
|
static int find_peer_time_stamp_and_verify (n2n_edge_t * eee,
|
||||||
int from_supernode, n2n_mac_t mac,
|
int from_supernode, const n2n_mac_t mac,
|
||||||
uint64_t stamp) {
|
uint64_t stamp) {
|
||||||
|
|
||||||
uint64_t * previous_stamp = NULL;
|
uint64_t * previous_stamp = NULL;
|
||||||
|
@ -628,8 +627,8 @@ int is_empty_ip_address(const n2n_sock_t * sock) {
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
static n2n_mac_t broadcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
static const n2n_mac_t broadcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
static n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0};
|
static const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
/** Check if a known peer socket has changed and possibly register again.
|
/** Check if a known peer socket has changed and possibly register again.
|
||||||
*/
|
*/
|
||||||
|
@ -736,41 +735,44 @@ static void check_join_multicast_group(n2n_edge_t *eee) {
|
||||||
|
|
||||||
/** Send a REGISTER_SUPER packet to the current supernode. */
|
/** Send a REGISTER_SUPER packet to the current supernode. */
|
||||||
static void send_register_super(n2n_edge_t *eee, const n2n_sock_t *supernode, int sn_idx) {
|
static void send_register_super(n2n_edge_t *eee, const n2n_sock_t *supernode, int sn_idx) {
|
||||||
uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0};
|
uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0};
|
||||||
size_t idx;
|
size_t idx;
|
||||||
/* ssize_t sent; */
|
/* ssize_t sent; */
|
||||||
n2n_common_t cmn;
|
n2n_common_t cmn;
|
||||||
n2n_REGISTER_SUPER_t reg;
|
n2n_REGISTER_SUPER_t reg;
|
||||||
n2n_sock_str_t sockbuf;
|
n2n_sock_str_t sockbuf;
|
||||||
|
|
||||||
memset(&cmn, 0, sizeof(cmn));
|
memset(&cmn, 0, sizeof(cmn));
|
||||||
memset(®, 0, sizeof(reg));
|
memset(®, 0, sizeof(reg));
|
||||||
cmn.ttl=N2N_DEFAULT_TTL;
|
|
||||||
cmn.pc = n2n_register_super;
|
|
||||||
cmn.flags = 0;
|
|
||||||
memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE);
|
|
||||||
|
|
||||||
for (idx = 0; (sn_idx==0) && (idx < N2N_COOKIE_SIZE); ++idx)
|
cmn.ttl = N2N_DEFAULT_TTL;
|
||||||
eee->last_cookie[idx] = n2n_rand() % 0xff;
|
cmn.pc = n2n_register_super;
|
||||||
|
cmn.flags = 0;
|
||||||
|
memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE);
|
||||||
|
|
||||||
memcpy(reg.cookie, eee->last_cookie, N2N_COOKIE_SIZE);
|
for (idx = 0; (sn_idx==0) && (idx < N2N_COOKIE_SIZE); ++idx)
|
||||||
reg.auth.scheme=0; /* No auth yet */
|
eee->last_cookie[idx] = n2n_rand() % 0xff;
|
||||||
|
|
||||||
idx=0;
|
memcpy(reg.cookie, eee->last_cookie, N2N_COOKIE_SIZE);
|
||||||
encode_mac(reg.edgeMac, &idx, eee->device.mac_addr);
|
reg.dev_addr.net_addr = ntohl(eee->device.ip_addr);
|
||||||
|
reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask));
|
||||||
|
reg.auth.scheme = 0; /* No auth yet */
|
||||||
|
|
||||||
idx=0;
|
idx = 0;
|
||||||
encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®);
|
encode_mac(reg.edgeMac, &idx, eee->device.mac_addr);
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to %s",
|
idx = 0;
|
||||||
sock_to_cstr(sockbuf, supernode));
|
encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®);
|
||||||
|
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to %s",
|
||||||
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
sock_to_cstr(sockbuf, supernode));
|
||||||
eee->conf.header_iv_ctx,
|
|
||||||
time_stamp (), pearson_hash_16 (pktbuf, idx));
|
|
||||||
|
|
||||||
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, supernode);
|
if (eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
|
packet_header_encrypt(pktbuf, idx, eee->conf.header_encryption_ctx,
|
||||||
|
eee->conf.header_iv_ctx,
|
||||||
|
time_stamp(), pearson_hash_16(pktbuf, idx));
|
||||||
|
|
||||||
|
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, supernode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
@ -904,7 +906,7 @@ static void send_register_ack(n2n_edge_t * eee,
|
||||||
*
|
*
|
||||||
* This is frequently called by the main loop.
|
* This is frequently called by the main loop.
|
||||||
*/
|
*/
|
||||||
static void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) {
|
void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) {
|
||||||
u_int sn_idx;
|
u_int sn_idx;
|
||||||
|
|
||||||
if(eee->sn_wait && (nowTime > (eee->last_register_req + (eee->conf.register_interval/10)))) {
|
if(eee->sn_wait && (nowTime > (eee->last_register_req + (eee->conf.register_interval/10)))) {
|
||||||
|
@ -1588,7 +1590,7 @@ void edge_read_from_tap(n2n_edge_t * eee) {
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
/** Read a datagram from the main UDP socket to the internet. */
|
/** Read a datagram from the main UDP socket to the internet. */
|
||||||
static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
n2n_common_t cmn; /* common fields in the packet header */
|
n2n_common_t cmn; /* common fields in the packet header */
|
||||||
|
|
||||||
n2n_sock_str_t sockbuf1;
|
n2n_sock_str_t sockbuf1;
|
||||||
|
@ -1750,14 +1752,14 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
* to double check this.
|
* to double check this.
|
||||||
*/
|
*/
|
||||||
traceEvent(TRACE_DEBUG, "Got P2P register");
|
traceEvent(TRACE_DEBUG, "Got P2P register");
|
||||||
traceEvent(TRACE_NORMAL, "[P2P] Rx REGISTER from %s", sock_to_cstr(sockbuf1, &sender));
|
traceEvent(TRACE_INFO, "[P2P] Rx REGISTER from %s", sock_to_cstr(sockbuf1, &sender));
|
||||||
find_and_remove_peer(&eee->pending_peers, reg.srcMac);
|
find_and_remove_peer(&eee->pending_peers, reg.srcMac);
|
||||||
|
|
||||||
/* NOTE: only ACK to peers */
|
/* NOTE: only ACK to peers */
|
||||||
send_register_ack(eee, orig_sender, ®);
|
send_register_ack(eee, orig_sender, ®);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
traceEvent(TRACE_NORMAL, "[PsP] Rx REGISTER src=%s dst=%s from sn=%s (edge:%s)",
|
traceEvent(TRACE_INFO, "[PsP] Rx REGISTER src=%s dst=%s from sn=%s (edge:%s)",
|
||||||
macaddr_str(mac_buf1, reg.srcMac), macaddr_str(mac_buf2, reg.dstMac),
|
macaddr_str(mac_buf1, reg.srcMac), macaddr_str(mac_buf2, reg.dstMac),
|
||||||
sock_to_cstr(sockbuf1, &sender), sock_to_cstr(sockbuf2, orig_sender));
|
sock_to_cstr(sockbuf1, &sender), sock_to_cstr(sockbuf2, orig_sender));
|
||||||
}
|
}
|
||||||
|
@ -1793,7 +1795,13 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
}
|
}
|
||||||
case MSG_TYPE_REGISTER_SUPER_ACK:
|
case MSG_TYPE_REGISTER_SUPER_ACK:
|
||||||
{
|
{
|
||||||
// Indicates successful connection between the edge and SN nodes
|
in_addr_t net;
|
||||||
|
char * ip_str = NULL;
|
||||||
|
n2n_REGISTER_SUPER_ACK_t ra;
|
||||||
|
|
||||||
|
memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||||
|
|
||||||
|
// Indicates successful connection between the edge and SN nodes
|
||||||
static int bTrace = 1;
|
static int bTrace = 1;
|
||||||
if (bTrace)
|
if (bTrace)
|
||||||
{
|
{
|
||||||
|
@ -1801,7 +1809,6 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
bTrace = 0;
|
bTrace = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n2n_REGISTER_SUPER_ACK_t ra;
|
|
||||||
|
|
||||||
if(eee->sn_wait)
|
if(eee->sn_wait)
|
||||||
{
|
{
|
||||||
|
@ -1839,6 +1846,20 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
eee->last_sup = now;
|
eee->last_sup = now;
|
||||||
eee->sn_wait=0;
|
eee->sn_wait=0;
|
||||||
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */
|
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */
|
||||||
|
if (eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_SN_ASSIGN) {
|
||||||
|
if ((ra.dev_addr.net_addr != 0) && (ra.dev_addr.net_bitlen != 0)) {
|
||||||
|
net = htonl(ra.dev_addr.net_addr);
|
||||||
|
if ((ip_str = inet_ntoa(*(struct in_addr *) &net)) != NULL) {
|
||||||
|
strncpy(eee->tuntap_priv_conf.ip_addr, ip_str,
|
||||||
|
N2N_NETMASK_STR_SIZE);
|
||||||
|
}
|
||||||
|
net = htonl(bitlen2mask(ra.dev_addr.net_bitlen));
|
||||||
|
if ((ip_str = inet_ntoa(*(struct in_addr *) &net)) != NULL) {
|
||||||
|
strncpy(eee->tuntap_priv_conf.netmask, ip_str,
|
||||||
|
N2N_NETMASK_STR_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(eee->cb.sn_registration_updated)
|
if(eee->cb.sn_registration_updated)
|
||||||
eee->cb.sn_registration_updated(eee, now, &sender);
|
eee->cb.sn_registration_updated(eee, now, &sender);
|
||||||
|
@ -1857,7 +1878,8 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER.");
|
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER.");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} case MSG_TYPE_PEER_INFO: {
|
}
|
||||||
|
case MSG_TYPE_PEER_INFO: {
|
||||||
n2n_PEER_INFO_t pi;
|
n2n_PEER_INFO_t pi;
|
||||||
struct peer_info * scan;
|
struct peer_info * scan;
|
||||||
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
|
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
|
||||||
|
@ -2024,7 +2046,7 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) {
|
||||||
HASH_COUNT(eee->known_peers));
|
HASH_COUNT(eee->known_peers));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(eee->conf.dyn_ip_mode &&
|
if((eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_DHCP) &&
|
||||||
((nowTime - lastIfaceCheck) > IFACE_UPDATE_INTERVAL)) {
|
((nowTime - lastIfaceCheck) > IFACE_UPDATE_INTERVAL)) {
|
||||||
uint32_t old_ip = eee->device.ip_addr;
|
uint32_t old_ip = eee->device.ip_addr;
|
||||||
|
|
||||||
|
@ -2535,28 +2557,30 @@ static void edge_cleanup_routes(n2n_edge_t *eee) {
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
void edge_init_conf_defaults(n2n_edge_conf_t *conf) {
|
void edge_init_conf_defaults(n2n_edge_conf_t *conf) {
|
||||||
memset(conf, 0, sizeof(*conf));
|
memset(conf, 0, sizeof(*conf));
|
||||||
|
|
||||||
conf->local_port = 0 /* any port */;
|
conf->local_port = 0 /* any port */;
|
||||||
conf->mgmt_port = N2N_EDGE_MGMT_PORT; /* 5644 by default */
|
conf->mgmt_port = N2N_EDGE_MGMT_PORT; /* 5644 by default */
|
||||||
conf->transop_id = N2N_TRANSFORM_ID_NULL;
|
conf->transop_id = N2N_TRANSFORM_ID_NULL;
|
||||||
conf->header_encryption = HEADER_ENCRYPTION_NONE;
|
conf->header_encryption = HEADER_ENCRYPTION_NONE;
|
||||||
conf->compression = N2N_COMPRESSION_ID_NONE;
|
conf->compression = N2N_COMPRESSION_ID_NONE;
|
||||||
conf->drop_multicast = 1;
|
conf->drop_multicast = 1;
|
||||||
conf->allow_p2p = 1;
|
conf->allow_p2p = 1;
|
||||||
conf->disable_pmtu_discovery = 1;
|
conf->disable_pmtu_discovery = 1;
|
||||||
conf->register_interval = REGISTER_SUPER_INTERVAL_DFL;
|
conf->register_interval = REGISTER_SUPER_INTERVAL_DFL;
|
||||||
|
conf->tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN;
|
||||||
|
|
||||||
if(getenv("N2N_KEY")) {
|
if (getenv("N2N_KEY")) {
|
||||||
conf->encrypt_key = strdup(getenv("N2N_KEY"));
|
conf->encrypt_key = strdup(getenv("N2N_KEY"));
|
||||||
conf->transop_id = N2N_TRANSFORM_ID_TWOFISH;
|
conf->transop_id = N2N_TRANSFORM_ID_TWOFISH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
void edge_term_conf(n2n_edge_conf_t *conf) {
|
void edge_term_conf(n2n_edge_conf_t *conf) {
|
||||||
if(conf->routes) free(conf->routes);
|
if (conf->routes) free(conf->routes);
|
||||||
|
if (conf->encrypt_key) free(conf->encrypt_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
@ -2608,7 +2632,7 @@ int quick_edge_init(char *device_name, char *community_name,
|
||||||
return(-2);
|
return(-2);
|
||||||
|
|
||||||
/* Init edge */
|
/* Init edge */
|
||||||
if((eee = edge_init(&tuntap, &conf, &rv)) == NULL)
|
if((eee = edge_init(&conf, &rv)) == NULL)
|
||||||
goto quick_edge_init_end;
|
goto quick_edge_init_end;
|
||||||
|
|
||||||
rv = run_edge_loop(eee, keep_on_running);
|
rv = run_edge_loop(eee, keep_on_running);
|
||||||
|
|
|
@ -33,7 +33,7 @@ int main()
|
||||||
snprintf((char *)conf.community_name, sizeof(conf.community_name), "%s", "mycommunity"); // Community to connect to
|
snprintf((char *)conf.community_name, sizeof(conf.community_name), "%s", "mycommunity"); // Community to connect to
|
||||||
conf.disable_pmtu_discovery = 1; // Whether to disable the path MTU discovery
|
conf.disable_pmtu_discovery = 1; // Whether to disable the path MTU discovery
|
||||||
conf.drop_multicast = 0; // Whether to disable multicast
|
conf.drop_multicast = 0; // Whether to disable multicast
|
||||||
conf.dyn_ip_mode = 0; // Whether the IP address is set dynamically (see IP mode; 0 if static, 1 if dynamic)
|
conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; // How to set the IP address
|
||||||
conf.encrypt_key = "mysecret"; // Secret to decrypt & encrypt with
|
conf.encrypt_key = "mysecret"; // Secret to decrypt & encrypt with
|
||||||
conf.local_port = 0; // What port to use (0 = any port)
|
conf.local_port = 0; // What port to use (0 = any port)
|
||||||
conf.mgmt_port = N2N_EDGE_MGMT_PORT; // Edge management port (5644 by default)
|
conf.mgmt_port = N2N_EDGE_MGMT_PORT; // Edge management port (5644 by default)
|
||||||
|
@ -59,7 +59,7 @@ int main()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
eee = edge_init(&tuntap, &conf, &rc);
|
eee = edge_init(&conf, &rc);
|
||||||
if (eee == NULL)
|
if (eee == NULL)
|
||||||
{
|
{
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
58
src/n2n.c
58
src/n2n.c
|
@ -185,6 +185,29 @@ char* intoa(uint32_t /* host order */ addr, char* buf, uint16_t buf_len) {
|
||||||
return(retStr);
|
return(retStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Convert subnet prefix bit length to host order subnet mask. */
|
||||||
|
uint32_t bitlen2mask(uint8_t bitlen) {
|
||||||
|
uint8_t i;
|
||||||
|
uint32_t mask = 0;
|
||||||
|
for (i = 1; i <= bitlen; ++i) {
|
||||||
|
mask |= 1 << (32 - i);
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Convert host order subnet mask to subnet prefix bit length. */
|
||||||
|
uint8_t mask2bitlen(uint32_t mask) {
|
||||||
|
uint8_t i, bitlen = 0;
|
||||||
|
for (i = 0; i < 32; ++i) {
|
||||||
|
if ((mask << i) & 0x80000000) ++bitlen;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
return bitlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *********************************************** */
|
/* *********************************************** */
|
||||||
|
|
||||||
char * macaddr_str(macstr_t buf,
|
char * macaddr_str(macstr_t buf,
|
||||||
|
@ -231,21 +254,21 @@ char* msg_type2str(uint16_t msg_type) {
|
||||||
|
|
||||||
/* *********************************************** */
|
/* *********************************************** */
|
||||||
|
|
||||||
void hexdump(const uint8_t * buf, size_t len)
|
void hexdump(const uint8_t *buf, size_t len) {
|
||||||
{
|
size_t i;
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if(0 == len) { return; }
|
if (0 == len) { return; }
|
||||||
|
|
||||||
for(i=0; i<len; i++)
|
printf("-----------------------------------------------\n");
|
||||||
{
|
for (i = 0; i < len; i++) {
|
||||||
if((i > 0) &&((i % 16) == 0)) { printf("\n"); }
|
if ((i > 0) && ((i % 16) == 0)) { printf("\n"); }
|
||||||
printf("%02X ", buf[i] & 0xFF);
|
printf("%02X ", buf[i] & 0xFF);
|
||||||
}
|
}
|
||||||
|
printf("\n");
|
||||||
printf("\n");
|
printf("-----------------------------------------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *********************************************** */
|
/* *********************************************** */
|
||||||
|
|
||||||
void print_n2n_version() {
|
void print_n2n_version() {
|
||||||
|
@ -360,6 +383,17 @@ extern char * sock_to_cstr(n2n_sock_str_t out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *ip_subnet_to_str(dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr) {
|
||||||
|
snprintf(buf, sizeof(dec_ip_bit_str_t), "%hhu.%hhu.%hhu.%hhu/%hhu",
|
||||||
|
(uint8_t) ((ipaddr->net_addr >> 24) & 0xFF),
|
||||||
|
(uint8_t) ((ipaddr->net_addr >> 16) & 0xFF),
|
||||||
|
(uint8_t) ((ipaddr->net_addr >> 8) & 0xFF),
|
||||||
|
(uint8_t) (ipaddr->net_addr & 0xFF),
|
||||||
|
ipaddr->net_bitlen);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* @return 1 if the two sockets are equivalent. */
|
/* @return 1 if the two sockets are equivalent. */
|
||||||
int sock_equal(const n2n_sock_t * a,
|
int sock_equal(const n2n_sock_t * a,
|
||||||
const n2n_sock_t * b) {
|
const n2n_sock_t * b) {
|
||||||
|
@ -383,7 +417,7 @@ int sock_equal(const n2n_sock_t * a,
|
||||||
|
|
||||||
/* *********************************************** */
|
/* *********************************************** */
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__)
|
#if defined(WIN32)
|
||||||
int gettimeofday(struct timeval *tp, void *tzp) {
|
int gettimeofday(struct timeval *tp, void *tzp) {
|
||||||
time_t clock;
|
time_t clock;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
159
src/sn.c
159
src/sn.c
|
@ -92,100 +92,137 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) {
|
||||||
|
|
||||||
/** Help message to print if the command line arguments are not valid. */
|
/** Help message to print if the command line arguments are not valid. */
|
||||||
static void help() {
|
static void help() {
|
||||||
print_n2n_version();
|
print_n2n_version();
|
||||||
|
|
||||||
printf("supernode <config file> (see supernode.conf)\n"
|
printf("supernode <config file> (see supernode.conf)\n"
|
||||||
"or\n"
|
"or\n"
|
||||||
);
|
);
|
||||||
printf("supernode ");
|
printf("supernode ");
|
||||||
printf("-l <local port> ");
|
printf("-l <local port> ");
|
||||||
printf("-c <path> ");
|
printf("-c <path> ");
|
||||||
#if defined(N2N_HAVE_DAEMON)
|
#if defined(N2N_HAVE_DAEMON)
|
||||||
printf("[-f] ");
|
printf("[-f] ");
|
||||||
#endif
|
#endif
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
printf("[-u <uid> -g <gid>] ");
|
printf("[-u <uid> -g <gid>] ");
|
||||||
#endif /* ifndef WIN32 */
|
#endif /* ifndef WIN32 */
|
||||||
printf("[-t <mgmt port>] ");
|
printf("[-t <mgmt port>] ");
|
||||||
printf("[-v] ");
|
printf("[-d <net/bit>] ");
|
||||||
printf("\n\n");
|
printf("[-v] ");
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
printf("-l <port>\tSet UDP main listen port to <port>\n");
|
printf("-l <port> | Set UDP main listen port to <port>\n");
|
||||||
printf("-c <path>\tFile containing the allowed communities.\n");
|
printf("-c <path> | File containing the allowed communities.\n");
|
||||||
#if defined(N2N_HAVE_DAEMON)
|
#if defined(N2N_HAVE_DAEMON)
|
||||||
printf("-f \tRun in foreground.\n");
|
printf("-f | Run in foreground.\n");
|
||||||
#endif /* #if defined(N2N_HAVE_DAEMON) */
|
#endif /* #if defined(N2N_HAVE_DAEMON) */
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
printf("-u <UID>\tUser ID (numeric) to use when privileges are dropped.\n");
|
printf("-u <UID> | User ID (numeric) to use when privileges are dropped.\n");
|
||||||
printf("-g <GID>\tGroup ID (numeric) to use when privileges are dropped.\n");
|
printf("-g <GID> | Group ID (numeric) to use when privileges are dropped.\n");
|
||||||
#endif /* ifndef WIN32 */
|
#endif /* ifndef WIN32 */
|
||||||
printf("-t <port>\tManagement UDP Port (for multiple supernodes on a machine).\n");
|
printf("-t <port> | Management UDP Port (for multiple supernodes on a machine).\n");
|
||||||
printf("-v \tIncrease verbosity. Can be used multiple times.\n");
|
printf("-d <net/bit> | Subnet that provides dhcp service for edge. eg. -d 172.17.12.0/24\n");
|
||||||
printf("-h \tThis help message.\n");
|
printf("-v | Increase verbosity. Can be used multiple times.\n");
|
||||||
printf("\n");
|
printf("-h | This help message.\n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *************************************************** */
|
/* *************************************************** */
|
||||||
|
|
||||||
static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
||||||
//traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : "");
|
//traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : "");
|
||||||
|
|
||||||
switch(optkey) {
|
switch (optkey) {
|
||||||
case 'l': /* local-port */
|
case 'l': /* local-port */
|
||||||
sss->lport = atoi(_optarg);
|
sss->lport = atoi(_optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't': /* mgmt-port */
|
case 't': /* mgmt-port */
|
||||||
sss->mport = atoi(_optarg);
|
sss->mport = atoi(_optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'd': {
|
||||||
|
dec_ip_str_t ip_str = {'\0'};
|
||||||
|
in_addr_t net;
|
||||||
|
uint8_t bitlen;
|
||||||
|
|
||||||
|
if (sscanf(_optarg, "%15[^/]/%hhu", ip_str, &bitlen) != 2) {
|
||||||
|
traceEvent(TRACE_WARNING, "Bad net/bit format '%s'. See -h.", _optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
net = inet_addr(ip_str);
|
||||||
|
if ((net < 0) || (net == INADDR_NONE) || (net == INADDR_ANY)) {
|
||||||
|
traceEvent(TRACE_WARNING, "Bad network '%s' in '%s', Use default: '%s/%d'",
|
||||||
|
ip_str, _optarg,
|
||||||
|
N2N_SN_DHCP_NET_ADDR_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitlen > 32) {
|
||||||
|
traceEvent(TRACE_WARNING, "Bad prefix '%hhu' in '%s', Use default: '%s/%d'",
|
||||||
|
bitlen, _optarg,
|
||||||
|
N2N_SN_DHCP_NET_ADDR_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
traceEvent(TRACE_NORMAL, "The subnet of DHCP service is: '%s/%hhu'.", ip_str, bitlen);
|
||||||
|
|
||||||
|
sss->dhcp_addr.net_addr = ntohl(net);
|
||||||
|
sss->dhcp_addr.net_bitlen = bitlen;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
case 'u': /* unprivileged uid */
|
case 'u': /* unprivileged uid */
|
||||||
sss->userid = atoi(_optarg);
|
sss->userid = atoi(_optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g': /* unprivileged uid */
|
case 'g': /* unprivileged uid */
|
||||||
sss->groupid = atoi(_optarg);
|
sss->groupid = atoi(_optarg);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 'c': /* community file */
|
case 'c': /* community file */
|
||||||
load_allowed_sn_community(sss, _optarg);
|
load_allowed_sn_community(sss, _optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f': /* foreground */
|
case 'f': /* foreground */
|
||||||
sss->daemon = 0;
|
sss->daemon = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h': /* help */
|
case 'h': /* help */
|
||||||
help();
|
help();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v': /* verbose */
|
case 'v': /* verbose */
|
||||||
setTraceLevel(getTraceLevel() + 1);
|
setTraceLevel(getTraceLevel() + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored.", (char)optkey);
|
traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored.", (char) optkey);
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *********************************************** */
|
/* *********************************************** */
|
||||||
|
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{ "communities", required_argument, NULL, 'c' },
|
{"communities", required_argument, NULL, 'c'},
|
||||||
{ "foreground", no_argument, NULL, 'f' },
|
{"foreground", no_argument, NULL, 'f'},
|
||||||
{ "local-port", required_argument, NULL, 'l' },
|
{"local-port", required_argument, NULL, 'l'},
|
||||||
{ "mgmt-port", required_argument, NULL, 't' },
|
{"mgmt-port", required_argument, NULL, 't'},
|
||||||
{ "help" , no_argument, NULL, 'h' },
|
{"dhcp", required_argument, NULL, 'd'},
|
||||||
{ "verbose", no_argument, NULL, 'v' },
|
{"help", no_argument, NULL, 'h'},
|
||||||
{ NULL, 0, NULL, 0 }
|
{"verbose", no_argument, NULL, 'v'},
|
||||||
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* *************************************************** */
|
/* *************************************************** */
|
||||||
|
@ -194,7 +231,7 @@ static const struct option long_options[] = {
|
||||||
static int loadFromCLI(int argc, char * const argv[], n2n_sn_t *sss) {
|
static int loadFromCLI(int argc, char * const argv[], n2n_sn_t *sss) {
|
||||||
u_char c;
|
u_char c;
|
||||||
|
|
||||||
while((c = getopt_long(argc, argv, "fl:u:g:t:c:vh",
|
while((c = getopt_long(argc, argv, "fl:u:g:t:d:c:vh",
|
||||||
long_options, NULL)) != '?') {
|
long_options, NULL)) != '?') {
|
||||||
if(c == 255) break;
|
if(c == 255) break;
|
||||||
setOption(c, optarg, sss);
|
setOption(c, optarg, sss);
|
||||||
|
|
295
src/sn_utils.c
295
src/sn_utils.c
|
@ -47,7 +47,7 @@ static int try_broadcast(n2n_sn_t * sss,
|
||||||
static uint16_t reg_lifetime(n2n_sn_t *sss);
|
static uint16_t reg_lifetime(n2n_sn_t *sss);
|
||||||
|
|
||||||
static int update_edge(n2n_sn_t *sss,
|
static int update_edge(n2n_sn_t *sss,
|
||||||
const n2n_mac_t edgeMac,
|
const n2n_REGISTER_SUPER_t* reg,
|
||||||
struct sn_community *comm,
|
struct sn_community *comm,
|
||||||
const n2n_sock_t *sender_sock,
|
const n2n_sock_t *sender_sock,
|
||||||
time_t now);
|
time_t now);
|
||||||
|
@ -204,23 +204,25 @@ static int try_broadcast(n2n_sn_t * sss,
|
||||||
|
|
||||||
|
|
||||||
/** Initialise the supernode structure */
|
/** Initialise the supernode structure */
|
||||||
int sn_init(n2n_sn_t *sss)
|
int sn_init(n2n_sn_t *sss) {
|
||||||
{
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
initWin32();
|
initWin32();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pearson_hash_init();
|
pearson_hash_init();
|
||||||
|
|
||||||
memset(sss, 0, sizeof(n2n_sn_t));
|
memset(sss, 0, sizeof(n2n_sn_t));
|
||||||
|
|
||||||
sss->daemon = 1; /* By defult run as a daemon. */
|
sss->daemon = 1; /* By defult run as a daemon. */
|
||||||
sss->lport = N2N_SN_LPORT_DEFAULT;
|
sss->lport = N2N_SN_LPORT_DEFAULT;
|
||||||
sss->mport = N2N_SN_MGMT_PORT;
|
sss->mport = N2N_SN_MGMT_PORT;
|
||||||
sss->sock = -1;
|
sss->sock = -1;
|
||||||
sss->mgmt_sock = -1;
|
sss->mgmt_sock = -1;
|
||||||
|
sss->dhcp_addr.net_addr = inet_addr(N2N_SN_DHCP_NET_ADDR_DEFAULT);
|
||||||
|
sss->dhcp_addr.net_addr = ntohl(sss->dhcp_addr.net_addr);
|
||||||
|
sss->dhcp_addr.net_bitlen = N2N_SN_DHCP_NET_BIT_DEFAULT;
|
||||||
|
|
||||||
return 0; /* OK */
|
return 0; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Deinitialise the supernode structure and deallocate any memory owned by
|
/** Deinitialise the supernode structure and deallocate any memory owned by
|
||||||
|
@ -265,61 +267,101 @@ static uint16_t reg_lifetime(n2n_sn_t *sss)
|
||||||
/** Update the edge table with the details of the edge which contacted the
|
/** Update the edge table with the details of the edge which contacted the
|
||||||
* supernode. */
|
* supernode. */
|
||||||
static int update_edge(n2n_sn_t *sss,
|
static int update_edge(n2n_sn_t *sss,
|
||||||
const n2n_mac_t edgeMac,
|
const n2n_REGISTER_SUPER_t* reg,
|
||||||
struct sn_community *comm,
|
struct sn_community *comm,
|
||||||
const n2n_sock_t *sender_sock,
|
const n2n_sock_t *sender_sock,
|
||||||
time_t now)
|
time_t now) {
|
||||||
{
|
macstr_t mac_buf;
|
||||||
macstr_t mac_buf;
|
n2n_sock_str_t sockbuf;
|
||||||
n2n_sock_str_t sockbuf;
|
struct peer_info *scan;
|
||||||
struct peer_info *scan;
|
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "update_edge for %s [%s]",
|
traceEvent(TRACE_DEBUG, "update_edge for %s [%s]",
|
||||||
macaddr_str(mac_buf, edgeMac),
|
macaddr_str(mac_buf, reg->edgeMac),
|
||||||
sock_to_cstr(sockbuf, sender_sock));
|
sock_to_cstr(sockbuf, sender_sock));
|
||||||
|
|
||||||
HASH_FIND_PEER(comm->edges, edgeMac, scan);
|
HASH_FIND_PEER(comm->edges, reg->edgeMac, scan);
|
||||||
|
|
||||||
if (NULL == scan)
|
if (NULL == scan) {
|
||||||
{
|
/* Not known */
|
||||||
/* Not known */
|
|
||||||
|
|
||||||
scan = (struct peer_info *)calloc(1,
|
scan = (struct peer_info *) calloc(1,
|
||||||
sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */
|
sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */
|
||||||
|
|
||||||
memcpy(&(scan->mac_addr), edgeMac, sizeof(n2n_mac_t));
|
memcpy(&(scan->mac_addr), reg->edgeMac, sizeof(n2n_mac_t));
|
||||||
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
|
scan->dev_addr.net_addr = reg->dev_addr.net_addr;
|
||||||
scan->last_valid_time_stamp = initial_time_stamp ();
|
scan->dev_addr.net_bitlen = reg->dev_addr.net_bitlen;
|
||||||
|
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
|
||||||
|
scan->last_valid_time_stamp = initial_time_stamp();
|
||||||
|
|
||||||
HASH_ADD_PEER(comm->edges, scan);
|
HASH_ADD_PEER(comm->edges, scan);
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "update_edge created %s ==> %s",
|
traceEvent(TRACE_INFO, "update_edge created %s ==> %s",
|
||||||
macaddr_str(mac_buf, edgeMac),
|
macaddr_str(mac_buf, reg->edgeMac),
|
||||||
sock_to_cstr(sockbuf, sender_sock));
|
sock_to_cstr(sockbuf, sender_sock));
|
||||||
}
|
} else {
|
||||||
else
|
/* Known */
|
||||||
{
|
if (!sock_equal(sender_sock, &(scan->sock))) {
|
||||||
/* Known */
|
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
|
||||||
if (!sock_equal(sender_sock, &(scan->sock)))
|
|
||||||
{
|
|
||||||
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
|
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "update_edge updated %s ==> %s",
|
traceEvent(TRACE_INFO, "update_edge updated %s ==> %s",
|
||||||
macaddr_str(mac_buf, edgeMac),
|
macaddr_str(mac_buf, reg->edgeMac),
|
||||||
sock_to_cstr(sockbuf, sender_sock));
|
sock_to_cstr(sockbuf, sender_sock));
|
||||||
}
|
} else {
|
||||||
else
|
traceEvent(TRACE_DEBUG, "update_edge unchanged %s ==> %s",
|
||||||
{
|
macaddr_str(mac_buf, reg->edgeMac),
|
||||||
traceEvent(TRACE_DEBUG, "update_edge unchanged %s ==> %s",
|
sock_to_cstr(sockbuf, sender_sock));
|
||||||
macaddr_str(mac_buf, edgeMac),
|
}
|
||||||
sock_to_cstr(sockbuf, sender_sock));
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scan->last_seen = now;
|
scan->last_seen = now;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static signed int peer_tap_ip_sort(struct peer_info *a, struct peer_info *b) {
|
||||||
|
uint32_t a_host_id = a->dev_addr.net_addr & (~bitlen2mask(a->dev_addr.net_bitlen));
|
||||||
|
uint32_t b_host_id = b->dev_addr.net_addr & (~bitlen2mask(b->dev_addr.net_bitlen));
|
||||||
|
return ((signed int)a_host_id - (signed int)b_host_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** The IP address assigned to the edge by the DHCP function of sn. */
|
||||||
|
static int assign_one_ip_addr(n2n_sn_t *sss,
|
||||||
|
struct sn_community *comm,
|
||||||
|
n2n_ip_subnet_t *ipaddr) {
|
||||||
|
struct peer_info *peer, *tmpPeer;
|
||||||
|
uint32_t net_id, mask, max_host, host_id = 1;
|
||||||
|
dec_ip_bit_str_t ip_bit_str = {'\0'};
|
||||||
|
|
||||||
|
mask = bitlen2mask(sss->dhcp_addr.net_bitlen);
|
||||||
|
net_id = sss->dhcp_addr.net_addr & mask;
|
||||||
|
max_host = ~mask;
|
||||||
|
|
||||||
|
HASH_SORT(comm->edges, peer_tap_ip_sort);
|
||||||
|
HASH_ITER(hh, comm->edges, peer, tmpPeer) {
|
||||||
|
if ((peer->dev_addr.net_addr & bitlen2mask(peer->dev_addr.net_bitlen)) == net_id) {
|
||||||
|
if (host_id >= max_host) {
|
||||||
|
traceEvent(TRACE_WARNING, "No assignable IP to edge tap adapter.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (peer->dev_addr.net_addr == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((peer->dev_addr.net_addr & max_host) == host_id) {
|
||||||
|
++host_id;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ipaddr->net_addr = net_id | host_id;
|
||||||
|
ipaddr->net_bitlen = sss->dhcp_addr.net_bitlen;
|
||||||
|
|
||||||
|
traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ipaddr));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*
|
*
|
||||||
* For a given packet, find the apporopriate internal last valid time stamp for lookup
|
* For a given packet, find the apporopriate internal last valid time stamp for lookup
|
||||||
|
@ -409,89 +451,89 @@ static int process_mgmt(n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr_in *sender_sock,
|
||||||
const uint8_t *mgmt_buf,
|
const uint8_t *mgmt_buf,
|
||||||
size_t mgmt_size,
|
size_t mgmt_size,
|
||||||
time_t now)
|
time_t now) {
|
||||||
{
|
char resbuf[N2N_SN_PKTBUF_SIZE];
|
||||||
char resbuf[N2N_SN_PKTBUF_SIZE];
|
size_t ressize = 0;
|
||||||
size_t ressize = 0;
|
uint32_t num_edges = 0;
|
||||||
uint32_t num_edges = 0;
|
uint32_t num = 0;
|
||||||
uint32_t num = 0;
|
struct sn_community *community, *tmp;
|
||||||
struct sn_community *community, *tmp;
|
struct peer_info *peer, *tmpPeer;
|
||||||
struct peer_info * peer, *tmpPeer;
|
macstr_t mac_buf;
|
||||||
macstr_t mac_buf;
|
n2n_sock_str_t sockbuf;
|
||||||
n2n_sock_str_t sockbuf;
|
dec_ip_bit_str_t ip_bit_str = {'\0'};
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "process_mgmt");
|
traceEvent(TRACE_DEBUG, "process_mgmt");
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"----------------\n");
|
"\tid tun_tap MAC edge last_seen\n");
|
||||||
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
|
"-------------------------------------------------------------------------------------\n");
|
||||||
|
HASH_ITER(hh, sss->communities, community, tmp) {
|
||||||
|
num_edges += HASH_COUNT(community->edges);
|
||||||
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
|
"community: %s\n", community->community);
|
||||||
|
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
||||||
|
ressize = 0;
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
num = 0;
|
||||||
"uptime %lu\n", (now - sss->start_time));
|
HASH_ITER(hh, community->edges, peer, tmpPeer) {
|
||||||
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
|
"\t%-4u %-18s %-17s %-21s %lu\n",
|
||||||
|
++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr),
|
||||||
|
macaddr_str(mac_buf, peer->mac_addr),
|
||||||
|
sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen);
|
||||||
|
|
||||||
HASH_ITER(hh, sss->communities, community, tmp)
|
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
||||||
{
|
ressize = 0;
|
||||||
num_edges += HASH_COUNT(community->edges);
|
}
|
||||||
}
|
}
|
||||||
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
|
"-------------------------------------------------------------------------------------\n");
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"edges %u\n",
|
"uptime %lu | ", (now - sss->start_time));
|
||||||
num_edges);
|
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"errors %u\n",
|
"edges %u | ",
|
||||||
(unsigned int)sss->stats.errors);
|
num_edges);
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"reg_sup %u\n",
|
"reg_sup %u | ",
|
||||||
(unsigned int)sss->stats.reg_super);
|
(unsigned int) sss->stats.reg_super);
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"reg_nak %u\n",
|
"reg_nak %u | ",
|
||||||
(unsigned int)sss->stats.reg_super_nak);
|
(unsigned int) sss->stats.reg_super_nak);
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"fwd %u\n",
|
"errors %u \n",
|
||||||
(unsigned int)sss->stats.fwd);
|
(unsigned int) sss->stats.errors);
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"broadcast %u\n",
|
"fwd %u | ",
|
||||||
(unsigned int)sss->stats.broadcast);
|
(unsigned int) sss->stats.fwd);
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"last fwd %lu sec ago\n",
|
"broadcast %u | ",
|
||||||
(long unsigned int)(now - sss->stats.last_fwd));
|
(unsigned int) sss->stats.broadcast);
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"last reg %lu sec ago\n",
|
"cur_cmnts %u\n", HASH_COUNT(sss->communities));
|
||||||
(long unsigned int)(now - sss->stats.last_reg_super));
|
|
||||||
|
|
||||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"cur_cmnts %u\n", HASH_COUNT(sss->communities));
|
"last fwd %lu sec ago\n",
|
||||||
HASH_ITER(hh, sss->communities, community, tmp) {
|
(long unsigned int) (now - sss->stats.last_fwd));
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
|
||||||
"community: %s\n", community->community);
|
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize);
|
|
||||||
ressize = 0;
|
|
||||||
|
|
||||||
num = 0;
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
HASH_ITER(hh, community->edges, peer, tmpPeer) {
|
"last reg %lu sec ago\n\n",
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
(long unsigned int) (now - sss->stats.last_reg_super));
|
||||||
"\t[id: %u][MAC: %s][edge: %s][last seen: %lu sec ago]\n",
|
|
||||||
++num, macaddr_str(mac_buf, peer->mac_addr),
|
|
||||||
sock_to_cstr(sockbuf, &(peer->sock)), now-peer->last_seen);
|
|
||||||
|
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize);
|
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
||||||
ressize = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
return 0;
|
||||||
"\n");
|
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int sendto_mgmt(n2n_sn_t *sss,
|
static int sendto_mgmt(n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr_in *sender_sock,
|
||||||
const uint8_t *mgmt_buf,
|
const uint8_t *mgmt_buf,
|
||||||
|
@ -528,6 +570,7 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
char buf[32];
|
char buf[32];
|
||||||
struct sn_community *comm, *tmp;
|
struct sn_community *comm, *tmp;
|
||||||
uint64_t stamp;
|
uint64_t stamp;
|
||||||
|
const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0}; /* 00:00:00:00:00:00 */
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "Processing incoming UDP packet [len: %lu][sender: %s:%u]",
|
traceEvent(TRACE_DEBUG, "Processing incoming UDP packet [len: %lu][sender: %s:%u]",
|
||||||
udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)),
|
udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)),
|
||||||
|
@ -791,6 +834,9 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
n2n_common_t cmn2;
|
n2n_common_t cmn2;
|
||||||
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
|
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
|
||||||
size_t encx=0;
|
size_t encx=0;
|
||||||
|
n2n_ip_subnet_t ipaddr;
|
||||||
|
|
||||||
|
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||||
|
|
||||||
/* Edge requesting registration with us. */
|
/* Edge requesting registration with us. */
|
||||||
sss->stats.last_reg_super=now;
|
sss->stats.last_reg_super=now;
|
||||||
|
@ -836,6 +882,12 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
memcpy(&(ack.cookie), &(reg.cookie), sizeof(n2n_cookie_t));
|
memcpy(&(ack.cookie), &(reg.cookie), sizeof(n2n_cookie_t));
|
||||||
memcpy(ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t));
|
memcpy(ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t));
|
||||||
|
if ((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xFFFFFFFF) || (reg.dev_addr.net_bitlen == 0) ||
|
||||||
|
((reg.dev_addr.net_addr & 0xFFFF0000) == 0xA9FE0000 /* 169.254.0.0 */)) {
|
||||||
|
assign_one_ip_addr(sss, comm, &ipaddr);
|
||||||
|
ack.dev_addr.net_addr = ipaddr.net_addr;
|
||||||
|
ack.dev_addr.net_bitlen = ipaddr.net_bitlen;
|
||||||
|
}
|
||||||
ack.lifetime = reg_lifetime(sss);
|
ack.lifetime = reg_lifetime(sss);
|
||||||
|
|
||||||
ack.sock.family = AF_INET;
|
ack.sock.family = AF_INET;
|
||||||
|
@ -843,13 +895,14 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
|
memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
|
||||||
|
|
||||||
ack.num_sn=0; /* No backup */
|
ack.num_sn=0; /* No backup */
|
||||||
memset(&(ack.sn_bak), 0, sizeof(n2n_sock_t));
|
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]",
|
traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]",
|
||||||
macaddr_str(mac_buf, reg.edgeMac),
|
macaddr_str(mac_buf, reg.edgeMac),
|
||||||
sock_to_cstr(sockbuf, &(ack.sock)));
|
sock_to_cstr(sockbuf, &(ack.sock)));
|
||||||
|
|
||||||
update_edge(sss, reg.edgeMac, comm, &(ack.sock), now);
|
if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0){
|
||||||
|
update_edge(sss, ®, comm, &(ack.sock), now);
|
||||||
|
}
|
||||||
|
|
||||||
encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack);
|
encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack);
|
||||||
|
|
||||||
|
|
256
src/wire.c
256
src/wire.c
|
@ -289,130 +289,135 @@ int decode_REGISTER( n2n_REGISTER_t * reg,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encode_REGISTER_SUPER( uint8_t * base,
|
|
||||||
size_t * idx,
|
|
||||||
const n2n_common_t * common,
|
|
||||||
const n2n_REGISTER_SUPER_t * reg )
|
|
||||||
{
|
|
||||||
int retval=0;
|
|
||||||
retval += encode_common( base, idx, common );
|
|
||||||
retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE );
|
|
||||||
retval += encode_mac( base, idx, reg->edgeMac );
|
|
||||||
retval += encode_uint16( base, idx, 0 ); /* NULL auth scheme */
|
|
||||||
retval += encode_uint16( base, idx, 0 ); /* No auth data */
|
|
||||||
|
|
||||||
return retval;
|
int encode_REGISTER_SUPER(uint8_t *base,
|
||||||
|
size_t *idx,
|
||||||
|
const n2n_common_t *common,
|
||||||
|
const n2n_REGISTER_SUPER_t *reg) {
|
||||||
|
int retval = 0;
|
||||||
|
retval += encode_common(base, idx, common);
|
||||||
|
retval += encode_buf(base, idx, reg->cookie, N2N_COOKIE_SIZE);
|
||||||
|
retval += encode_mac(base, idx, reg->edgeMac);
|
||||||
|
retval += encode_uint32(base, idx, reg->dev_addr.net_addr);
|
||||||
|
retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen);
|
||||||
|
retval += encode_uint16(base, idx, 0); /* NULL auth scheme */
|
||||||
|
retval += encode_uint16(base, idx, 0); /* No auth data */
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * reg,
|
|
||||||
const n2n_common_t * cmn, /* info on how to interpret it */
|
int decode_REGISTER_SUPER(n2n_REGISTER_SUPER_t *reg,
|
||||||
const uint8_t * base,
|
const n2n_common_t *cmn, /* info on how to interpret it */
|
||||||
size_t * rem,
|
const uint8_t *base,
|
||||||
size_t * idx )
|
size_t *rem,
|
||||||
{
|
size_t *idx) {
|
||||||
size_t retval=0;
|
size_t retval = 0;
|
||||||
memset( reg, 0, sizeof(n2n_REGISTER_SUPER_t) );
|
memset(reg, 0, sizeof(n2n_REGISTER_SUPER_t));
|
||||||
retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx );
|
retval += decode_buf(reg->cookie, N2N_COOKIE_SIZE, base, rem, idx);
|
||||||
retval += decode_mac( reg->edgeMac, base, rem, idx );
|
retval += decode_mac(reg->edgeMac, base, rem, idx);
|
||||||
retval += decode_uint16( &(reg->auth.scheme), base, rem, idx );
|
retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx);
|
||||||
retval += decode_uint16( &(reg->auth.toksize), base, rem, idx );
|
retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx);
|
||||||
retval += decode_buf( reg->auth.token, reg->auth.toksize, base, rem, idx );
|
retval += decode_uint16(&(reg->auth.scheme), base, rem, idx);
|
||||||
return retval;
|
retval += decode_uint16(&(reg->auth.toksize), base, rem, idx);
|
||||||
|
retval += decode_buf(reg->auth.token, reg->auth.toksize, base, rem, idx);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encode_REGISTER_ACK( uint8_t * base,
|
|
||||||
size_t * idx,
|
|
||||||
const n2n_common_t * common,
|
|
||||||
const n2n_REGISTER_ACK_t * reg )
|
|
||||||
{
|
|
||||||
int retval=0;
|
|
||||||
retval += encode_common( base, idx, common );
|
|
||||||
retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE );
|
|
||||||
retval += encode_mac( base, idx, reg->dstMac );
|
|
||||||
retval += encode_mac( base, idx, reg->srcMac );
|
|
||||||
|
|
||||||
/* The socket in REGISTER_ACK is the socket from which the REGISTER
|
int encode_REGISTER_ACK(uint8_t *base,
|
||||||
* arrived. This is sent back to the sender so it knows what its public
|
size_t *idx,
|
||||||
* socket is. */
|
const n2n_common_t *common,
|
||||||
if ( 0 != reg->sock.family )
|
const n2n_REGISTER_ACK_t *reg) {
|
||||||
{
|
int retval = 0;
|
||||||
retval += encode_sock( base, idx, &(reg->sock) );
|
retval += encode_common(base, idx, common);
|
||||||
}
|
retval += encode_buf(base, idx, reg->cookie, N2N_COOKIE_SIZE);
|
||||||
|
retval += encode_mac(base, idx, reg->dstMac);
|
||||||
|
retval += encode_mac(base, idx, reg->srcMac);
|
||||||
|
|
||||||
return retval;
|
/* The socket in REGISTER_ACK is the socket from which the REGISTER
|
||||||
|
* arrived. This is sent back to the sender so it knows what its public
|
||||||
|
* socket is. */
|
||||||
|
if (0 != reg->sock.family) {
|
||||||
|
retval += encode_sock(base, idx, &(reg->sock));
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int decode_REGISTER_ACK( n2n_REGISTER_ACK_t * reg,
|
|
||||||
const n2n_common_t * cmn, /* info on how to interpret it */
|
|
||||||
const uint8_t * base,
|
|
||||||
size_t * rem,
|
|
||||||
size_t * idx )
|
|
||||||
{
|
|
||||||
size_t retval=0;
|
|
||||||
memset( reg, 0, sizeof(n2n_REGISTER_ACK_t) );
|
|
||||||
retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx );
|
|
||||||
retval += decode_mac( reg->dstMac, base, rem, idx );
|
|
||||||
retval += decode_mac( reg->srcMac, base, rem, idx );
|
|
||||||
|
|
||||||
/* The socket in REGISTER_ACK is the socket from which the REGISTER
|
int decode_REGISTER_ACK(n2n_REGISTER_ACK_t *reg,
|
||||||
* arrived. This is sent back to the sender so it knows what its public
|
const n2n_common_t *cmn, /* info on how to interpret it */
|
||||||
* socket is. */
|
const uint8_t *base,
|
||||||
if ( cmn->flags & N2N_FLAGS_SOCKET )
|
size_t *rem,
|
||||||
{
|
size_t *idx) {
|
||||||
retval += decode_sock( &(reg->sock), base, rem, idx );
|
size_t retval = 0;
|
||||||
}
|
memset(reg, 0, sizeof(n2n_REGISTER_ACK_t));
|
||||||
|
retval += decode_buf(reg->cookie, N2N_COOKIE_SIZE, base, rem, idx);
|
||||||
|
retval += decode_mac(reg->dstMac, base, rem, idx);
|
||||||
|
retval += decode_mac(reg->srcMac, base, rem, idx);
|
||||||
|
|
||||||
return retval;
|
/* The socket in REGISTER_ACK is the socket from which the REGISTER
|
||||||
|
* arrived. This is sent back to the sender so it knows what its public
|
||||||
|
* socket is. */
|
||||||
|
if (cmn->flags & N2N_FLAGS_SOCKET) {
|
||||||
|
retval += decode_sock(&(reg->sock), base, rem, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encode_REGISTER_SUPER_ACK( uint8_t * base,
|
|
||||||
size_t * idx,
|
|
||||||
const n2n_common_t * common,
|
|
||||||
const n2n_REGISTER_SUPER_ACK_t * reg )
|
|
||||||
{
|
|
||||||
int retval=0;
|
|
||||||
retval += encode_common( base, idx, common );
|
|
||||||
retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE );
|
|
||||||
retval += encode_mac( base, idx, reg->edgeMac );
|
|
||||||
retval += encode_uint16( base, idx, reg->lifetime );
|
|
||||||
retval += encode_sock( base, idx, &(reg->sock) );
|
|
||||||
retval += encode_uint8( base, idx, reg->num_sn );
|
|
||||||
if ( reg->num_sn > 0 )
|
|
||||||
{
|
|
||||||
/* We only support 0 or 1 at this stage */
|
|
||||||
retval += encode_sock( base, idx, &(reg->sn_bak) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
int encode_REGISTER_SUPER_ACK(uint8_t *base,
|
||||||
|
size_t *idx,
|
||||||
|
const n2n_common_t *common,
|
||||||
|
const n2n_REGISTER_SUPER_ACK_t *reg) {
|
||||||
|
int retval = 0;
|
||||||
|
retval += encode_common(base, idx, common);
|
||||||
|
retval += encode_buf(base, idx, reg->cookie, N2N_COOKIE_SIZE);
|
||||||
|
retval += encode_mac(base, idx, reg->edgeMac);
|
||||||
|
retval += encode_uint32(base, idx, reg->dev_addr.net_addr);
|
||||||
|
retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen);
|
||||||
|
retval += encode_uint16(base, idx, reg->lifetime);
|
||||||
|
retval += encode_sock(base, idx, &(reg->sock));
|
||||||
|
retval += encode_uint8(base, idx, reg->num_sn);
|
||||||
|
if (reg->num_sn > 0) {
|
||||||
|
/* We only support 0 or 1 at this stage */
|
||||||
|
retval += encode_sock(base, idx, &(reg->sn_bak));
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg,
|
|
||||||
const n2n_common_t * cmn, /* info on how to interpret it */
|
|
||||||
const uint8_t * base,
|
|
||||||
size_t * rem,
|
|
||||||
size_t * idx )
|
|
||||||
{
|
|
||||||
size_t retval=0;
|
|
||||||
|
|
||||||
memset( reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t) );
|
int decode_REGISTER_SUPER_ACK(n2n_REGISTER_SUPER_ACK_t *reg,
|
||||||
retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx );
|
const n2n_common_t *cmn, /* info on how to interpret it */
|
||||||
retval += decode_mac( reg->edgeMac, base, rem, idx );
|
const uint8_t *base,
|
||||||
retval += decode_uint16( &(reg->lifetime), base, rem, idx );
|
size_t *rem,
|
||||||
|
size_t *idx) {
|
||||||
|
size_t retval = 0;
|
||||||
|
|
||||||
/* Socket is mandatory in this message type */
|
memset(reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||||
retval += decode_sock( &(reg->sock), base, rem, idx );
|
retval += decode_buf(reg->cookie, N2N_COOKIE_SIZE, base, rem, idx);
|
||||||
|
retval += decode_mac(reg->edgeMac, base, rem, idx);
|
||||||
|
retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx);
|
||||||
|
retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx);
|
||||||
|
retval += decode_uint16(&(reg->lifetime), base, rem, idx);
|
||||||
|
|
||||||
/* Following the edge socket are an array of backup supernodes. */
|
/* Socket is mandatory in this message type */
|
||||||
retval += decode_uint8( &(reg->num_sn), base, rem, idx );
|
retval += decode_sock(&(reg->sock), base, rem, idx);
|
||||||
if ( reg->num_sn > 0 )
|
|
||||||
{
|
|
||||||
/* We only support 0 or 1 at this stage */
|
|
||||||
retval += decode_sock( &(reg->sn_bak), base, rem, idx );
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
/* Following the edge socket are an array of backup supernodes. */
|
||||||
|
retval += decode_uint8(&(reg->num_sn), base, rem, idx);
|
||||||
|
if (reg->num_sn > 0) {
|
||||||
|
/* We only support 0 or 1 at this stage */
|
||||||
|
retval += decode_sock(&(reg->sn_bak), base, rem, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int fill_sockaddr( struct sockaddr * addr,
|
int fill_sockaddr( struct sockaddr * addr,
|
||||||
size_t addrlen,
|
size_t addrlen,
|
||||||
const n2n_sock_t * sock )
|
const n2n_sock_t * sock )
|
||||||
|
@ -475,35 +480,36 @@ int decode_PACKET( n2n_PACKET_t * pkt,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encode_PEER_INFO( uint8_t * base,
|
|
||||||
size_t * idx,
|
|
||||||
const n2n_common_t * common,
|
|
||||||
const n2n_PEER_INFO_t * pkt )
|
|
||||||
{
|
|
||||||
int retval=0;
|
|
||||||
retval += encode_common( base, idx, common );
|
|
||||||
retval += encode_uint16( base, idx, pkt->aflags );
|
|
||||||
retval += encode_mac( base, idx, pkt->mac );
|
|
||||||
retval += encode_sock( base, idx, &pkt->sock );
|
|
||||||
|
|
||||||
return retval;
|
int encode_PEER_INFO(uint8_t *base,
|
||||||
|
size_t *idx,
|
||||||
|
const n2n_common_t *common,
|
||||||
|
const n2n_PEER_INFO_t *pkt) {
|
||||||
|
int retval = 0;
|
||||||
|
retval += encode_common(base, idx, common);
|
||||||
|
retval += encode_uint16(base, idx, pkt->aflags);
|
||||||
|
retval += encode_mac(base, idx, pkt->mac);
|
||||||
|
retval += encode_sock(base, idx, &pkt->sock);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int decode_PEER_INFO( n2n_PEER_INFO_t * pkt,
|
|
||||||
const n2n_common_t * cmn, /* info on how to interpret it */
|
|
||||||
const uint8_t * base,
|
|
||||||
size_t * rem,
|
|
||||||
size_t * idx )
|
|
||||||
{
|
|
||||||
size_t retval=0;
|
|
||||||
memset( pkt, 0, sizeof(n2n_PEER_INFO_t) );
|
|
||||||
retval += decode_uint16( &(pkt->aflags), base, rem, idx );
|
|
||||||
retval += decode_mac( pkt->mac, base, rem, idx );
|
|
||||||
retval += decode_sock( &pkt->sock, base, rem, idx );
|
|
||||||
|
|
||||||
return retval;
|
int decode_PEER_INFO(n2n_PEER_INFO_t *pkt,
|
||||||
|
const n2n_common_t *cmn, /* info on how to interpret it */
|
||||||
|
const uint8_t *base,
|
||||||
|
size_t *rem,
|
||||||
|
size_t *idx) {
|
||||||
|
size_t retval = 0;
|
||||||
|
memset(pkt, 0, sizeof(n2n_PEER_INFO_t));
|
||||||
|
retval += decode_uint16(&(pkt->aflags), base, rem, idx);
|
||||||
|
retval += decode_mac(pkt->mac, base, rem, idx);
|
||||||
|
retval += decode_sock(&pkt->sock, base, rem, idx);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int encode_QUERY_PEER( uint8_t * base,
|
int encode_QUERY_PEER( uint8_t * base,
|
||||||
size_t * idx,
|
size_t * idx,
|
||||||
const n2n_common_t * common,
|
const n2n_common_t * common,
|
||||||
|
|
|
@ -98,13 +98,14 @@ struct ip {
|
||||||
/* ************************************* */
|
/* ************************************* */
|
||||||
|
|
||||||
typedef struct tuntap_dev {
|
typedef struct tuntap_dev {
|
||||||
HANDLE device_handle;
|
HANDLE device_handle;
|
||||||
char *device_name;
|
char *device_name;
|
||||||
char *ifName;
|
char *ifName;
|
||||||
OVERLAPPED overlap_read, overlap_write;
|
OVERLAPPED overlap_read, overlap_write;
|
||||||
uint8_t mac_addr[6];
|
n2n_mac_t mac_addr;
|
||||||
uint32_t ip_addr, device_mask;
|
uint32_t ip_addr;
|
||||||
unsigned int mtu;
|
uint32_t device_mask;
|
||||||
|
unsigned int mtu;
|
||||||
} tuntap_dev;
|
} tuntap_dev;
|
||||||
|
|
||||||
#define index(a, b) strchr(a, b)
|
#define index(a, b) strchr(a, b)
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
/* winconfig.h. Win32 replacement for file generated from config.h.in by configure. */
|
/* winconfig.h. Win32 replacement for file generated from config.h.in by configure. */
|
||||||
|
|
||||||
/* OS name */
|
/* OS name */
|
||||||
|
#ifndef PACKAGE_OSNAME
|
||||||
#define PACKAGE_OSNAME N2N_OSNAME
|
#define PACKAGE_OSNAME N2N_OSNAME
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
/* Define to the version of this package. */
|
||||||
|
#ifndef PACKAGE_VERSION
|
||||||
#define PACKAGE_VERSION N2N_VERSION
|
#define PACKAGE_VERSION N2N_VERSION
|
||||||
|
#endif
|
||||||
|
#ifndef GIT_RELEASE
|
||||||
#define GIT_RELEASE N2N_VERSION
|
#define GIT_RELEASE N2N_VERSION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user