mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
Update REGISTER_SUPER_ACK handling on edge (#478)
This commit is contained in:
parent
8e9bf61469
commit
dcbc39c0fb
|
@ -199,11 +199,13 @@ struct peer_info {
|
||||||
n2n_ip_subnet_t dev_addr;
|
n2n_ip_subnet_t dev_addr;
|
||||||
n2n_desc_t dev_desc;
|
n2n_desc_t dev_desc;
|
||||||
n2n_sock_t sock;
|
n2n_sock_t sock;
|
||||||
|
n2n_cookie_t last_cookie;
|
||||||
int timeout;
|
int timeout;
|
||||||
uint8_t purgeable;
|
uint8_t purgeable;
|
||||||
time_t last_seen;
|
time_t last_seen;
|
||||||
time_t last_p2p;
|
time_t last_p2p;
|
||||||
time_t last_sent_query;
|
time_t last_sent_query;
|
||||||
|
time_t ping_time;
|
||||||
uint64_t last_valid_time_stamp;
|
uint64_t last_valid_time_stamp;
|
||||||
char *ip_addr;
|
char *ip_addr;
|
||||||
|
|
||||||
|
@ -271,7 +273,7 @@ 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];
|
struct peer_info *supernodes; /**< List of 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. */
|
||||||
n2n_desc_t dev_desc; /**< The device description (hint) */
|
n2n_desc_t dev_desc; /**< The device description (hint) */
|
||||||
|
@ -309,12 +311,11 @@ struct n2n_edge {
|
||||||
n2n_edge_conf_t conf;
|
n2n_edge_conf_t conf;
|
||||||
|
|
||||||
/* Status */
|
/* Status */
|
||||||
uint8_t sn_idx; /**< Currently active supernode. */
|
struct peer_info *curr_sn; /**< 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_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 */
|
||||||
|
@ -339,6 +340,7 @@ struct n2n_edge {
|
||||||
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 last_sweep; /**< Last time a sweep was performed. */
|
||||||
time_t start_time; /**< For calculating uptime */
|
time_t start_time; /**< For calculating uptime */
|
||||||
|
|
||||||
|
|
||||||
|
@ -503,7 +505,7 @@ int comm_init(struct sn_community *comm, char *cmn);
|
||||||
int sn_init(n2n_sn_t *sss);
|
int sn_init(n2n_sn_t *sss);
|
||||||
void sn_term(n2n_sn_t *sss);
|
void sn_term(n2n_sn_t *sss);
|
||||||
int supernode2sock(n2n_sock_t * sn, const n2n_sn_name_t addrIn);
|
int supernode2sock(n2n_sock_t * sn, const n2n_sn_name_t addrIn);
|
||||||
struct peer_info* add_sn_to_federation_by_mac_or_sock(n2n_sn_t *sss, n2n_sock_t *sock, n2n_mac_t *mac);
|
struct peer_info* add_sn_to_list_by_mac_or_sock(struct peer_info **sn_list, n2n_sock_t *sock, n2n_mac_t *mac, int *skip_add);
|
||||||
int run_sn_loop(n2n_sn_t *sss, int *keep_running);
|
int run_sn_loop(n2n_sn_t *sss, int *keep_running);
|
||||||
int assign_one_ip_subnet(n2n_sn_t *sss, struct sn_community *comm);
|
int assign_one_ip_subnet(n2n_sn_t *sss, struct sn_community *comm);
|
||||||
const char* compression_str(uint8_t cmpr);
|
const char* compression_str(uint8_t cmpr);
|
||||||
|
|
|
@ -30,25 +30,29 @@
|
||||||
#define MSG_TYPE_MAX_TYPE 10
|
#define MSG_TYPE_MAX_TYPE 10
|
||||||
|
|
||||||
/* Max available space to add supernodes' informations (sockets and MACs) in REGISTER_SUPER_ACK
|
/* Max available space to add supernodes' informations (sockets and MACs) in REGISTER_SUPER_ACK
|
||||||
* Field sizes of REGISTER_SUPER_ACK as used in encode/decode fucntions in src/wire.c */
|
* Field sizes of REGISTER_SUPER_ACK as used in encode/decode fucntions in src/wire.c
|
||||||
|
* REVISIT: replace 255 by DEFAULT_MTU as soon as header encryption allows for longer packets to be encrypted. */
|
||||||
#define MAX_AVAILABLE_SPACE_FOR_ENTRIES \
|
#define MAX_AVAILABLE_SPACE_FOR_ENTRIES \
|
||||||
DEFAULT_MTU-(1+1+2+sizeof(n2n_common_t)+sizeof(n2n_cookie_t)+sizeof(n2n_mac_t)+1+2+4+1+sizeof(n2n_sock_t)+1) \
|
(255-(1+1+2+sizeof(n2n_common_t)+sizeof(n2n_cookie_t)+sizeof(n2n_mac_t)+1+2+4+1+sizeof(n2n_sock_t)+1)) \
|
||||||
|
|
||||||
/* Space needed to store socket and MAC address of a supernode */
|
/* Space needed to store socket and MAC address of a supernode */
|
||||||
#define ENTRY_SIZE sizeof(n2n_sock_t)+sizeof(n2n_mac_t)
|
#define ENTRY_SIZE (sizeof(n2n_sock_t)+sizeof(n2n_mac_t))
|
||||||
|
|
||||||
|
#define PURGE_REGISTRATION_FREQUENCY 30
|
||||||
|
#define RE_REG_AND_PURGE_FREQUENCY 10
|
||||||
|
#define REGISTRATION_TIMEOUT 60
|
||||||
|
#define PURGE_FEDERATION_NODE_INTERVAL 90
|
||||||
|
|
||||||
#define SOCKET_TIMEOUT_INTERVAL_SECS 10
|
#define SOCKET_TIMEOUT_INTERVAL_SECS 10
|
||||||
#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */
|
#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */
|
||||||
#define ALLOWED_TIME 20 /* sec, indicates supernodes that are proven to be alive */
|
#define ALLOWED_TIME 20 /* sec, indicates supernodes that are proven to be alive */
|
||||||
#define TEST_TIME (PURGE_FEDERATION_NODE_INTERVAL - ALLOWED_TIME)/2 /* sec, indicates supernodes with unsure status, must be tested to check if they are alive */
|
#define TEST_TIME (PURGE_FEDERATION_NODE_INTERVAL - ALLOWED_TIME)/2 /* sec, indicates supernodes with unsure status, must be tested to check if they are alive */
|
||||||
|
#define MAX_PING_TIME 3000 /* millisec, indicates default value for ping_time field in peer_info structure */
|
||||||
|
#define SWEEP_TIME 30 /* sec, indicates the value after which we have to sort the hash list of supernodes in edges */
|
||||||
|
|
||||||
#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */
|
#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */
|
||||||
#define TRANSOP_TICK_INTERVAL (10) /* sec */
|
#define TRANSOP_TICK_INTERVAL (10) /* sec */
|
||||||
|
|
||||||
#define PURGE_REGISTRATION_FREQUENCY 30
|
|
||||||
#define REGISTRATION_TIMEOUT 60
|
|
||||||
#define PURGE_FEDERATION_NODE_INTERVAL 90
|
|
||||||
|
|
||||||
#define SORT_COMMUNITIES_INTERVAL 90 /* sec. until supernode sorts communities' hash list again */
|
#define SORT_COMMUNITIES_INTERVAL 90 /* sec. until supernode sorts communities' hash list again */
|
||||||
|
|
||||||
#define ETH_FRAMESIZE 14
|
#define ETH_FRAMESIZE 14
|
||||||
|
@ -83,7 +87,7 @@ enum federation{IS_NO_FEDERATION = 0,IS_FEDERATION = 1};
|
||||||
#define COMMUNITY_PURGEABLE 1
|
#define COMMUNITY_PURGEABLE 1
|
||||||
|
|
||||||
/* (un)purgeable supernode indicator */
|
/* (un)purgeable supernode indicator */
|
||||||
enum sn_purge{SN_UNPURGEABLE = 0, SN_PURGEABLE = 1};
|
enum sn_purge{SN_PURGEABLE = 0, SN_UNPURGEABLE = 1};
|
||||||
|
|
||||||
/* Header encryption indicators */
|
/* Header encryption indicators */
|
||||||
#define HEADER_ENCRYPTION_UNKNOWN 0
|
#define HEADER_ENCRYPTION_UNKNOWN 0
|
||||||
|
@ -103,6 +107,9 @@ enum sn_purge{SN_UNPURGEABLE = 0, SN_PURGEABLE = 1};
|
||||||
#define N2N_EDGE_MGMT_PORT 5644
|
#define N2N_EDGE_MGMT_PORT 5644
|
||||||
#define N2N_SN_MGMT_PORT 5645
|
#define N2N_SN_MGMT_PORT 5645
|
||||||
|
|
||||||
|
/* flag used in add_sn_to_list_by_mac_or_sock */
|
||||||
|
enum skip_add{NO_SKIP = 0, SKIP = 1, ADDED = 2};
|
||||||
|
|
||||||
#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */
|
#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */
|
||||||
#define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/
|
#define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/
|
||||||
#define N2N_IF_MODE_SIZE 16 /* static | dhcp */
|
#define N2N_IF_MODE_SIZE 16 /* static | dhcp */
|
||||||
|
|
|
@ -186,6 +186,7 @@ typedef struct n2n_REGISTER_SUPER_NAK
|
||||||
|
|
||||||
typedef struct n2n_PEER_INFO {
|
typedef struct n2n_PEER_INFO {
|
||||||
uint16_t aflags;
|
uint16_t aflags;
|
||||||
|
n2n_mac_t srcMac;
|
||||||
n2n_mac_t mac;
|
n2n_mac_t mac;
|
||||||
n2n_sock_t sock;
|
n2n_sock_t sock;
|
||||||
} n2n_PEER_INFO_t;
|
} n2n_PEER_INFO_t;
|
||||||
|
@ -195,6 +196,7 @@ typedef struct n2n_QUERY_PEER
|
||||||
{
|
{
|
||||||
n2n_mac_t srcMac;
|
n2n_mac_t srcMac;
|
||||||
n2n_mac_t targetMac;
|
n2n_mac_t targetMac;
|
||||||
|
uint8_t req_data; /* data we want the supernode to send back in the answer's payload (e.g. 0 = no payload, 1 = number of connected nodes ...) */
|
||||||
} n2n_QUERY_PEER_t;
|
} n2n_QUERY_PEER_t;
|
||||||
|
|
||||||
typedef struct n2n_buf n2n_buf_t;
|
typedef struct n2n_buf n2n_buf_t;
|
||||||
|
|
20
src/edge.c
20
src/edge.c
|
@ -172,9 +172,11 @@ static void help() {
|
||||||
" | causes connections stall when not properly supported.\n");
|
" | causes connections stall when not properly supported.\n");
|
||||||
#endif
|
#endif
|
||||||
printf("-r | Enable packet forwarding through n2n community.\n");
|
printf("-r | Enable packet forwarding through n2n community.\n");
|
||||||
printf("-A1 | Disable payload encryption. Do not use with key (defaulting to AES then).\n");
|
printf("-A1 | Disable payload encryption. Do not use with key (defaulting to Twofish then).\n");
|
||||||
printf("-A2 ... -A5 or -A | Choose a cipher for payload encryption, requires a key: -A2 = Twofish,\n");
|
printf("-A2 ... -A5 or -A | Choose a cipher for payload encryption, requires a key: -A2 = Twofish (default),\n");
|
||||||
printf(" | -A3 or -A (deprecated) = AES (default), -A4 = ChaCha20, -A5 = Speck-CTR.\n");
|
printf(" | -A3 or -A (deprecated) = AES, "
|
||||||
|
"-A4 = ChaCha20, "
|
||||||
|
"-A5 = Speck-CTR.\n");
|
||||||
printf("-H | Enable full header encryption. Requires supernode with fixed community.\n");
|
printf("-H | Enable full header encryption. Requires supernode with fixed community.\n");
|
||||||
printf("-z1 ... -z2 or -z | Enable compression for outgoing data packets: -z1 or -z = lzo1x"
|
printf("-z1 ... -z2 or -z | Enable compression for outgoing data packets: -z1 or -z = lzo1x"
|
||||||
#ifdef N2N_HAVE_ZSTD
|
#ifdef N2N_HAVE_ZSTD
|
||||||
|
@ -434,6 +436,12 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
|
||||||
case 'p':
|
case 'p':
|
||||||
{
|
{
|
||||||
conf->local_port = atoi(optargument);
|
conf->local_port = atoi(optargument);
|
||||||
|
|
||||||
|
if(conf->local_port == 0){
|
||||||
|
traceEvent(TRACE_WARNING, "Bad local port format");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,9 +843,9 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
if(conf.transop_id == N2N_TRANSFORM_ID_NULL) {
|
if(conf.transop_id == N2N_TRANSFORM_ID_NULL) {
|
||||||
if(conf.encrypt_key) {
|
if(conf.encrypt_key) {
|
||||||
/* make sure that AES is default cipher if key only (and no cipher) is specified */
|
/* make sure that Twofish is default cipher if key only (and no cipher) is specified */
|
||||||
traceEvent(TRACE_WARNING, "Switching to AES as key was provided.");
|
traceEvent(TRACE_WARNING, "Switching to Twofish as key was provided.");
|
||||||
conf.transop_id = N2N_TRANSFORM_ID_AES;
|
conf.transop_id = N2N_TRANSFORM_ID_TWOFISH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
290
src/edge_utils.c
290
src/edge_utils.c
|
@ -63,8 +63,8 @@ int edge_verify_conf(const n2n_edge_conf_t *conf) {
|
||||||
((conf->encrypt_key != NULL) && (conf->transop_id == N2N_TRANSFORM_ID_NULL)))
|
((conf->encrypt_key != NULL) && (conf->transop_id == N2N_TRANSFORM_ID_NULL)))
|
||||||
return(-4);
|
return(-4);
|
||||||
|
|
||||||
if (conf->dev_desc[0] == 0)
|
if(HASH_COUNT(conf->supernodes) == 0)
|
||||||
return (-5);
|
return(-5);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,8 @@ static int is_ip6_discovery(const void * buf, size_t bufsize) {
|
||||||
n2n_edge_t* edge_init(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 = 0;
|
||||||
|
struct peer_info *scan, *tmp;
|
||||||
|
|
||||||
if((rc = edge_verify_conf(conf)) != 0) {
|
if((rc = edge_verify_conf(conf)) != 0) {
|
||||||
traceEvent(TRACE_ERROR, "Invalid configuration");
|
traceEvent(TRACE_ERROR, "Invalid configuration");
|
||||||
|
@ -193,6 +194,8 @@ n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memcpy(&eee->conf, conf, sizeof(*conf));
|
memcpy(&eee->conf, conf, sizeof(*conf));
|
||||||
|
eee->curr_sn = eee->conf.supernodes;
|
||||||
|
//memcpy(&eee->supernode, &(eee->curr_sn->sock), sizeof(n2n_sock_t));
|
||||||
eee->start_time = time(NULL);
|
eee->start_time = time(NULL);
|
||||||
|
|
||||||
eee->known_peers = NULL;
|
eee->known_peers = NULL;
|
||||||
|
@ -211,11 +214,11 @@ n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv) {
|
||||||
// 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<eee->conf.sn_num; ++i)
|
traceEvent(TRACE_NORMAL, "Number of supernodes in the list: %d\n", HASH_COUNT(eee->conf.supernodes));
|
||||||
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (eee->conf.sn_ip_array[i]));
|
HASH_ITER(hh, eee->conf.supernodes, scan, tmp){
|
||||||
|
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (scan->ip_addr));
|
||||||
/* Set the active supernode */
|
i++;
|
||||||
supernode2sock(&(eee->supernode), eee->conf.sn_ip_array[eee->sn_idx]);
|
}
|
||||||
|
|
||||||
/* Set active transop */
|
/* Set active transop */
|
||||||
switch(transop_id) {
|
switch(transop_id) {
|
||||||
|
@ -687,8 +690,73 @@ static void check_join_multicast_group(n2n_edge_t *eee) {
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
|
/** Send a QUERY_PEER packet to the current supernode. */
|
||||||
|
static void send_query_peer( n2n_edge_t * eee,
|
||||||
|
const n2n_mac_t dstMac) {
|
||||||
|
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
|
||||||
|
size_t idx;
|
||||||
|
n2n_common_t cmn = {0};
|
||||||
|
n2n_QUERY_PEER_t query = {{0}};
|
||||||
|
struct peer_info *peer, *tmp;
|
||||||
|
uint8_t tmp_pkt[N2N_PKT_BUF_SIZE];
|
||||||
|
|
||||||
|
cmn.ttl=N2N_DEFAULT_TTL;
|
||||||
|
cmn.pc = n2n_query_peer;
|
||||||
|
cmn.flags = 0;
|
||||||
|
memcpy( cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE );
|
||||||
|
|
||||||
|
idx=0;
|
||||||
|
encode_mac( query.srcMac, &idx, eee->device.mac_addr );
|
||||||
|
|
||||||
|
idx=0;
|
||||||
|
encode_mac( query.targetMac, &idx, dstMac );
|
||||||
|
query.req_data = 0;
|
||||||
|
|
||||||
|
idx=0;
|
||||||
|
|
||||||
|
encode_QUERY_PEER( pktbuf, &idx, &cmn, &query );
|
||||||
|
|
||||||
|
if(memcmp(dstMac, null_mac, sizeof(n2n_mac_t)) != 0){
|
||||||
|
|
||||||
|
traceEvent( TRACE_DEBUG, "send QUERY_PEER to 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
traceEvent( TRACE_DEBUG, "send PING to supernodes" );
|
||||||
|
|
||||||
|
memcpy(tmp_pkt, pktbuf, idx);
|
||||||
|
|
||||||
|
HASH_ITER(hh, eee->conf.supernodes, peer, tmp){
|
||||||
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED){
|
||||||
|
/* Re-encrypt the orginal message again for non-repeating IV. */
|
||||||
|
memcpy(pktbuf, tmp_pkt, idx);
|
||||||
|
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
||||||
|
eee->conf.header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (pktbuf, idx));
|
||||||
|
}
|
||||||
|
sendto_sock( eee->udp_sock, pktbuf, idx, &(peer->sock));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ******************************************************** */
|
||||||
|
|
||||||
|
static int ping_time_sort(struct peer_info *a, struct peer_info *b){
|
||||||
|
// comparison function for sorting supernodes in ascending order of their
|
||||||
|
// ping_time-fields
|
||||||
|
return (a->ping_time - b->ping_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 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) {
|
||||||
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; */
|
||||||
|
@ -704,10 +772,10 @@ static void send_register_super(n2n_edge_t *eee, const n2n_sock_t *supernode, in
|
||||||
cmn.flags = 0;
|
cmn.flags = 0;
|
||||||
memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE);
|
memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE);
|
||||||
|
|
||||||
for (idx = 0; (sn_idx==0) && (idx < N2N_COOKIE_SIZE); ++idx)
|
for (idx = 0; idx < N2N_COOKIE_SIZE; ++idx)
|
||||||
eee->last_cookie[idx] = n2n_rand() % 0xff;
|
eee->curr_sn->last_cookie[idx] = n2n_rand() % 0xff;
|
||||||
|
|
||||||
memcpy(reg.cookie, eee->last_cookie, N2N_COOKIE_SIZE);
|
memcpy(reg.cookie, eee->curr_sn->last_cookie, N2N_COOKIE_SIZE);
|
||||||
reg.dev_addr.net_addr = ntohl(eee->device.ip_addr);
|
reg.dev_addr.net_addr = ntohl(eee->device.ip_addr);
|
||||||
reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask));
|
reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask));
|
||||||
memcpy(reg.dev_desc, eee->conf.dev_desc, N2N_DESC_SIZE);
|
memcpy(reg.dev_desc, eee->conf.dev_desc, N2N_DESC_SIZE);
|
||||||
|
@ -720,47 +788,47 @@ static void send_register_super(n2n_edge_t *eee, const n2n_sock_t *supernode, in
|
||||||
encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®);
|
encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®);
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to %s",
|
traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to %s",
|
||||||
sock_to_cstr(sockbuf, supernode));
|
sock_to_cstr(sockbuf, &(eee->curr_sn->sock)));
|
||||||
|
|
||||||
if (eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if (eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt(pktbuf, idx, eee->conf.header_encryption_ctx,
|
packet_header_encrypt(pktbuf, idx, eee->conf.header_encryption_ctx,
|
||||||
eee->conf.header_iv_ctx,
|
eee->conf.header_iv_ctx,
|
||||||
time_stamp(), pearson_hash_16(pktbuf, idx));
|
time_stamp(), pearson_hash_16(pktbuf, idx));
|
||||||
|
|
||||||
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, supernode);
|
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, &(eee->curr_sn->sock));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************** */
|
|
||||||
|
|
||||||
/** Send a QUERY_PEER packet to the current supernode. */
|
static int sort_supernodes(n2n_edge_t *eee, time_t now){
|
||||||
static void send_query_peer( n2n_edge_t * eee,
|
struct peer_info *scan, *tmp;
|
||||||
const n2n_mac_t dstMac) {
|
|
||||||
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
|
|
||||||
size_t idx;
|
|
||||||
n2n_common_t cmn = {0};
|
|
||||||
n2n_QUERY_PEER_t query = {{0}};
|
|
||||||
|
|
||||||
cmn.ttl=N2N_DEFAULT_TTL;
|
if(eee->curr_sn != eee->conf.supernodes){
|
||||||
cmn.pc = n2n_query_peer;
|
eee->curr_sn = eee->conf.supernodes;
|
||||||
cmn.flags = 0;
|
memcpy(&eee->supernode, &(eee->curr_sn->sock), sizeof(n2n_sock_t));
|
||||||
memcpy( cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE );
|
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS;
|
||||||
|
|
||||||
idx=0;
|
traceEvent(TRACE_INFO, "Registering with supernode [%s][number of supernodes %d][attempts left %u]",
|
||||||
encode_mac( query.srcMac, &idx, eee->device.mac_addr );
|
supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts);
|
||||||
idx=0;
|
|
||||||
encode_mac( query.targetMac, &idx, dstMac );
|
|
||||||
|
|
||||||
idx=0;
|
send_register_super(eee);
|
||||||
encode_QUERY_PEER( pktbuf, &idx, &cmn, &query );
|
eee->sn_wait = 1;
|
||||||
|
}
|
||||||
|
|
||||||
traceEvent( TRACE_DEBUG, "send QUERY_PEER to supernode" );
|
if(now - eee->last_sweep > SWEEP_TIME){
|
||||||
|
if(eee->sn_wait == 0){
|
||||||
|
// this routine gets periodically called
|
||||||
|
// it sorts supernodes in ascending order of their ping_time-fields
|
||||||
|
HASH_SORT(eee->conf.supernodes, ping_time_sort);
|
||||||
|
eee->last_sweep = now;
|
||||||
|
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED){
|
HASH_ITER(hh, eee->conf.supernodes, scan, tmp){
|
||||||
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
scan->ping_time = MAX_PING_TIME;
|
||||||
eee->conf.header_iv_ctx,
|
}
|
||||||
time_stamp (), pearson_hash_16 (pktbuf, idx));
|
}
|
||||||
|
send_query_peer(eee, null_mac);
|
||||||
}
|
}
|
||||||
sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) );
|
|
||||||
|
return 0; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send a REGISTER packet to another edge. */
|
/** Send a REGISTER packet to another edge. */
|
||||||
|
@ -866,7 +934,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.
|
||||||
*/
|
*/
|
||||||
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;
|
struct peer_info *scan, *tmp;
|
||||||
|
|
||||||
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)))) {
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
@ -878,12 +946,10 @@ void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) {
|
||||||
|
|
||||||
if(0 == eee->sup_attempts) {
|
if(0 == eee->sup_attempts) {
|
||||||
/* Give up on that supernode and try the next one. */
|
/* Give up on that supernode and try the next one. */
|
||||||
++(eee->sn_idx);
|
eee->curr_sn->ping_time = MAX_PING_TIME;
|
||||||
|
HASH_SORT(eee->conf.supernodes, ping_time_sort);
|
||||||
if(eee->sn_idx >= eee->conf.sn_num) {
|
eee->curr_sn = eee->conf.supernodes;
|
||||||
/* Got to end of list, go back to the start. Also works for list of one entry. */
|
memcpy(&eee->supernode, &(eee->curr_sn->sock), sizeof(n2n_sock_t));
|
||||||
eee->sn_idx=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
traceEvent(TRACE_WARNING, "Supernode not responding, now trying %s", supernode_ip(eee));
|
traceEvent(TRACE_WARNING, "Supernode not responding, now trying %s", supernode_ip(eee));
|
||||||
|
|
||||||
|
@ -904,16 +970,14 @@ void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) {
|
||||||
else
|
else
|
||||||
--(eee->sup_attempts);
|
--(eee->sup_attempts);
|
||||||
|
|
||||||
for(sn_idx=0; sn_idx<eee->conf.sn_num; sn_idx++) {
|
if(supernode2sock(&(eee->supernode), eee->curr_sn->ip_addr) == 0) {
|
||||||
if(supernode2sock(&(eee->supernode), eee->conf.sn_ip_array[sn_idx]) == 0) {
|
traceEvent(TRACE_INFO, "Registering with supernode [%s][number of supernodes %d][attempts left %u]",
|
||||||
traceEvent(TRACE_INFO, "Registering with supernode [id: %u/%u][%s][attempts left %u]",
|
supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts);
|
||||||
sn_idx+1, eee->conf.sn_num,
|
|
||||||
supernode_ip(eee), (unsigned int)eee->sup_attempts);
|
|
||||||
|
|
||||||
send_register_super(eee, &(eee->supernode), sn_idx);
|
send_register_super(eee);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
register_with_local_peers(eee);
|
register_with_local_peers(eee);
|
||||||
|
|
||||||
eee->sn_wait=1;
|
eee->sn_wait=1;
|
||||||
|
@ -940,7 +1004,7 @@ static void send_deregister(n2n_edge_t * eee,
|
||||||
|
|
||||||
/** Return the IP address of the current supernode in the ring. */
|
/** Return the IP address of the current supernode in the ring. */
|
||||||
static const char * supernode_ip(const n2n_edge_t * eee) {
|
static const char * supernode_ip(const n2n_edge_t * eee) {
|
||||||
return (eee->conf.sn_ip_array)[eee->sn_idx];
|
return (eee->curr_sn->ip_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
@ -1632,9 +1696,6 @@ 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. */
|
||||||
|
@ -1645,7 +1706,6 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */
|
n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */
|
||||||
macstr_t mac_buf1;
|
macstr_t mac_buf1;
|
||||||
macstr_t mac_buf2;
|
macstr_t mac_buf2;
|
||||||
|
|
||||||
uint8_t udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */
|
uint8_t udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */
|
||||||
ssize_t recvlen;
|
ssize_t recvlen;
|
||||||
size_t rem;
|
size_t rem;
|
||||||
|
@ -1680,6 +1740,10 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
|
|
||||||
/* REVISIT: when UDP/IPv6 is supported we will need a flag to indicate which
|
/* REVISIT: when UDP/IPv6 is supported we will need a flag to indicate which
|
||||||
* IP transport version the packet arrived on. May need to UDP sockets. */
|
* IP transport version the packet arrived on. May need to UDP sockets. */
|
||||||
|
|
||||||
|
/* REVISIT: do not endprse use with several supernodes
|
||||||
|
memset(&sender, 0, sizeof(n2n_sock_t)); */
|
||||||
|
|
||||||
sender.family = AF_INET; /* UDP socket was opened PF_INET v4 */
|
sender.family = AF_INET; /* UDP socket was opened PF_INET v4 */
|
||||||
sender.port = ntohs(sender_sock.sin_port);
|
sender.port = ntohs(sender_sock.sin_port);
|
||||||
memcpy(&(sender.addr.v4), &(sender_sock.sin_addr.s_addr), IPV4_SIZE);
|
memcpy(&(sender.addr.v4), &(sender_sock.sin_addr.s_addr), IPV4_SIZE);
|
||||||
|
@ -1850,6 +1914,11 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
char * ip_str = NULL;
|
char * ip_str = NULL;
|
||||||
n2n_REGISTER_SUPER_ACK_t ra;
|
n2n_REGISTER_SUPER_ACK_t ra;
|
||||||
uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
|
uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
|
||||||
|
n2n_sock_t *tmp_sock;
|
||||||
|
n2n_mac_t *tmp_mac;
|
||||||
|
int i;
|
||||||
|
int skip_add;
|
||||||
|
struct peer_info *sn;
|
||||||
|
|
||||||
memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||||
|
|
||||||
|
@ -1887,12 +1956,23 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 == memcmp(ra.cookie, eee->last_cookie, N2N_COOKIE_SIZE))
|
if(0 == memcmp(ra.cookie, eee->curr_sn->last_cookie, N2N_COOKIE_SIZE))
|
||||||
{
|
{
|
||||||
if(ra.num_sn > 0)
|
tmp_sock = (void*)&tmpbuf;
|
||||||
{
|
tmp_mac = (void*)&tmpbuf[sizeof(n2n_sock_t)];
|
||||||
traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK payload contains sockets and MACs of supernodes in the federation.");
|
|
||||||
}
|
for(i=0; i<ra.num_sn; i++){
|
||||||
|
skip_add = NO_SKIP;
|
||||||
|
sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), tmp_sock, tmp_mac, &skip_add);
|
||||||
|
if(skip_add == ADDED){
|
||||||
|
traceEvent(TRACE_NORMAL, "Supernode added to the list of supernodes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* REVISIT: find a more elegant expression to increase following pointers. */
|
||||||
|
tmp_sock = (void*)tmp_sock + ENTRY_SIZE;
|
||||||
|
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t);
|
||||||
|
}
|
||||||
|
|
||||||
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 */
|
||||||
|
@ -1917,6 +1997,8 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
/* NOTE: the register_interval should be chosen by the edge node
|
/* NOTE: the register_interval should be chosen by the edge node
|
||||||
* based on its NAT configuration. */
|
* based on its NAT configuration. */
|
||||||
//eee->conf.register_interval = ra.lifetime;
|
//eee->conf.register_interval = ra.lifetime;
|
||||||
|
|
||||||
|
eee->curr_sn->ping_time = (now - eee->last_register_req)*1000;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1932,6 +2014,8 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
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;
|
||||||
|
int skip_add;
|
||||||
|
|
||||||
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
|
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
|
||||||
|
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
|
@ -1942,24 +2026,35 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_valid_peer_sock(&pi.sock)) {
|
if(!is_valid_peer_sock(&pi.sock)) {
|
||||||
traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]",
|
traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]",
|
||||||
sock_to_cstr(sockbuf1, &pi.sock),
|
sock_to_cstr(sockbuf1, &pi.sock),
|
||||||
macaddr_str(mac_buf1, pi.mac) );
|
macaddr_str(mac_buf1, pi.mac) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
HASH_FIND_PEER(eee->pending_peers, pi.mac, scan);
|
if(memcmp(pi.mac, null_mac, sizeof(n2n_mac_t)) == 0){
|
||||||
if(scan) {
|
skip_add = SKIP;
|
||||||
scan->sock = pi.sock;
|
scan = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &sender, &pi.srcMac, &skip_add);
|
||||||
traceEvent(TRACE_INFO, "Rx PEER_INFO for %s: is at %s",
|
if(scan != NULL){
|
||||||
macaddr_str(mac_buf1, pi.mac),
|
scan->ping_time = (now - eee->last_sweep)*1000;
|
||||||
sock_to_cstr(sockbuf1, &pi.sock));
|
break;
|
||||||
send_register(eee, &scan->sock, scan->mac_addr);
|
}
|
||||||
} else {
|
} else {
|
||||||
traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s",
|
HASH_FIND_PEER(eee->pending_peers, pi.mac, scan);
|
||||||
macaddr_str(mac_buf1, pi.mac) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(scan) {
|
||||||
|
scan->sock = pi.sock;
|
||||||
|
traceEvent(TRACE_INFO, "Rx PEER_INFO for %s: is at %s",
|
||||||
|
macaddr_str(mac_buf1, pi.mac),
|
||||||
|
sock_to_cstr(sockbuf1, &pi.sock));
|
||||||
|
|
||||||
|
send_register(eee, &scan->sock, scan->mac_addr);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s",
|
||||||
|
macaddr_str(mac_buf1, pi.mac) );
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -2111,6 +2206,8 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) {
|
||||||
if (eee->cb.main_loop_period)
|
if (eee->cb.main_loop_period)
|
||||||
eee->cb.main_loop_period(eee, nowTime);
|
eee->cb.main_loop_period(eee, nowTime);
|
||||||
|
|
||||||
|
sort_supernodes(eee, nowTime);
|
||||||
|
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -2494,7 +2591,7 @@ static int edge_init_routes_linux(n2n_edge_t *eee, n2n_route_t *routes, uint16_t
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supernode2sock(&sn, eee->conf.sn_ip_array[0]) < 0)
|
if (supernode2sock(&sn, eee->conf.supernodes->ip_addr) < 0)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
if (sn.family != AF_INET) {
|
if (sn.family != AF_INET) {
|
||||||
|
@ -2635,7 +2732,7 @@ void edge_init_conf_defaults(n2n_edge_conf_t *conf) {
|
||||||
|
|
||||||
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_AES;
|
conf->transop_id = N2N_TRANSFORM_ID_TWOFISH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2655,11 +2752,38 @@ const n2n_edge_conf_t* edge_get_conf(const n2n_edge_t *eee) {
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
int edge_conf_add_supernode(n2n_edge_conf_t *conf, const char *ip_and_port) {
|
int edge_conf_add_supernode(n2n_edge_conf_t *conf, const char *ip_and_port) {
|
||||||
if(conf->sn_num >= N2N_EDGE_NUM_SUPERNODES)
|
struct peer_info *sn;
|
||||||
return(-1);
|
n2n_sock_t *sock;
|
||||||
|
int skip_add;
|
||||||
|
int rv = -1;
|
||||||
|
|
||||||
strncpy((conf->sn_ip_array[conf->sn_num]), ip_and_port, N2N_EDGE_SN_HOST_SIZE);
|
sock = (n2n_sock_t*)calloc(1,sizeof(n2n_sock_t));
|
||||||
traceEvent(TRACE_NORMAL, "Adding supernode[%u] = %s", (unsigned int)conf->sn_num, (conf->sn_ip_array[conf->sn_num]));
|
rv = supernode2sock(sock, ip_and_port);
|
||||||
|
|
||||||
|
if(rv != 0){
|
||||||
|
traceEvent(TRACE_WARNING, "Invalid socket");
|
||||||
|
free(sock);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_add = NO_SKIP;
|
||||||
|
sn = add_sn_to_list_by_mac_or_sock(&(conf->supernodes), sock, (n2n_mac_t *)null_mac, &skip_add);
|
||||||
|
|
||||||
|
if(sn != NULL){
|
||||||
|
sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE);
|
||||||
|
|
||||||
|
if(sn->ip_addr != NULL){
|
||||||
|
strncpy(sn->ip_addr, ip_and_port, N2N_EDGE_SN_HOST_SIZE-1);
|
||||||
|
memcpy(&(sn->sock), sock, sizeof(n2n_sock_t));
|
||||||
|
memcpy(&(sn->mac_addr), null_mac, sizeof(n2n_mac_t));
|
||||||
|
sn->purgeable = SN_UNPURGEABLE;
|
||||||
|
sn->last_valid_time_stamp = initial_time_stamp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sock);
|
||||||
|
|
||||||
|
traceEvent(TRACE_NORMAL, "Adding supernode = %s", sn->ip_addr);
|
||||||
conf->sn_num++;
|
conf->sn_num++;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -2680,7 +2804,7 @@ int quick_edge_init(char *device_name, char *community_name,
|
||||||
/* Setup the configuration */
|
/* Setup the configuration */
|
||||||
edge_init_conf_defaults(&conf);
|
edge_init_conf_defaults(&conf);
|
||||||
conf.encrypt_key = encrypt_key;
|
conf.encrypt_key = encrypt_key;
|
||||||
conf.transop_id = N2N_TRANSFORM_ID_AES;
|
conf.transop_id = N2N_TRANSFORM_ID_TWOFISH;
|
||||||
conf.compression = N2N_COMPRESSION_ID_NONE;
|
conf.compression = N2N_COMPRESSION_ID_NONE;
|
||||||
snprintf((char*)conf.community_name, sizeof(conf.community_name), "%s", community_name);
|
snprintf((char*)conf.community_name, sizeof(conf.community_name), "%s", community_name);
|
||||||
edge_conf_add_supernode(&conf, supernode_ip_address_port);
|
edge_conf_add_supernode(&conf, supernode_ip_address_port);
|
||||||
|
|
42
src/n2n.c
42
src/n2n.c
|
@ -26,6 +26,7 @@
|
||||||
static const uint8_t broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
static const uint8_t broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
static const uint8_t multicast_addr[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */
|
static const uint8_t multicast_addr[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */
|
||||||
static const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */
|
static const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */
|
||||||
|
static const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
|
@ -242,8 +243,9 @@ int supernode2sock(n2n_sock_t * sn, const n2n_sn_name_t addrIn) {
|
||||||
struct addrinfo * ainfo = NULL;
|
struct addrinfo * ainfo = NULL;
|
||||||
int nameerr;
|
int nameerr;
|
||||||
|
|
||||||
if(supernode_port)
|
if(supernode_port){
|
||||||
sn->port = atoi(supernode_port);
|
sn->port = atoi(supernode_port);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
traceEvent(TRACE_WARNING, "Bad supernode parameter (-l <host:port>) %s %s:%s",
|
traceEvent(TRACE_WARNING, "Bad supernode parameter (-l <host:port>) %s %s:%s",
|
||||||
addr, supernode_host, supernode_port);
|
addr, supernode_host, supernode_port);
|
||||||
|
@ -287,6 +289,42 @@ int supernode2sock(n2n_sock_t * sn, const n2n_sn_name_t addrIn) {
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
|
struct peer_info* add_sn_to_list_by_mac_or_sock(struct peer_info **sn_list, n2n_sock_t *sock, n2n_mac_t *mac, int *skip_add){
|
||||||
|
struct peer_info *scan, *tmp, *peer = NULL;
|
||||||
|
|
||||||
|
if(memcmp(mac,null_mac,sizeof(n2n_mac_t)) != 0) { /* not zero MAC */
|
||||||
|
HASH_FIND_PEER(*sn_list, mac, peer);
|
||||||
|
|
||||||
|
//REVISIT: make this dependent from last_seen and update socket
|
||||||
|
}
|
||||||
|
|
||||||
|
if(peer == NULL) { /* zero MAC, search by socket */
|
||||||
|
HASH_ITER(hh,*sn_list,scan,tmp) {
|
||||||
|
if(memcmp(&(scan->sock), sock, sizeof(n2n_sock_t)) == 0) {
|
||||||
|
HASH_DEL(*sn_list, scan);
|
||||||
|
memcpy(&(scan->mac_addr), mac, sizeof(n2n_mac_t));
|
||||||
|
HASH_ADD_PEER(*sn_list, scan);
|
||||||
|
peer = scan;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((peer == NULL) && (*skip_add == NO_SKIP)) {
|
||||||
|
peer = (struct peer_info*)calloc(1,sizeof(struct peer_info));
|
||||||
|
if(peer) {
|
||||||
|
memcpy(&(peer->sock),sock,sizeof(n2n_sock_t));
|
||||||
|
memcpy(&(peer->mac_addr),mac, sizeof(n2n_mac_t));
|
||||||
|
HASH_ADD_PEER(*sn_list, peer);
|
||||||
|
*skip_add = ADDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return peer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************ */
|
||||||
|
|
||||||
uint8_t is_multi_broadcast(const uint8_t * dest_mac) {
|
uint8_t is_multi_broadcast(const uint8_t * dest_mac) {
|
||||||
|
|
||||||
int is_broadcast =(memcmp(broadcast_addr, dest_mac, 6) == 0);
|
int is_broadcast =(memcmp(broadcast_addr, dest_mac, 6) == 0);
|
||||||
|
@ -370,7 +408,7 @@ size_t purge_peer_list(struct peer_info ** peer_list,
|
||||||
size_t retval=0;
|
size_t retval=0;
|
||||||
|
|
||||||
HASH_ITER(hh, *peer_list, scan, tmp) {
|
HASH_ITER(hh, *peer_list, scan, tmp) {
|
||||||
if(scan->last_seen < purge_before) {
|
if(scan->purgeable == SN_PURGEABLE && scan->last_seen < purge_before) {
|
||||||
HASH_DEL(*peer_list, scan);
|
HASH_DEL(*peer_list, scan);
|
||||||
retval++;
|
retval++;
|
||||||
free(scan);
|
free(scan);
|
||||||
|
|
52
src/sn.c
52
src/sn.c
|
@ -195,7 +195,7 @@ static void help() {
|
||||||
|
|
||||||
printf("-p <port> | Set UDP main listen port to <port>\n");
|
printf("-p <port> | Set UDP main listen port to <port>\n");
|
||||||
printf("-c <path> | File containing the allowed communities.\n");
|
printf("-c <path> | File containing the allowed communities.\n");
|
||||||
printf("-l <sn:port> | Supernode IP:port.\n");
|
printf("-l <sn host:port> | Name/IP of a known supernode:port.\n");
|
||||||
#if defined(N2N_HAVE_DAEMON)
|
#if defined(N2N_HAVE_DAEMON)
|
||||||
printf("-f | Run in foreground.\n");
|
printf("-f | Run in foreground.\n");
|
||||||
#endif /* #if defined(N2N_HAVE_DAEMON) */
|
#endif /* #if defined(N2N_HAVE_DAEMON) */
|
||||||
|
@ -224,10 +224,22 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
||||||
switch (optkey) {
|
switch (optkey) {
|
||||||
case 'p': /* local-port */
|
case 'p': /* local-port */
|
||||||
sss->lport = atoi(_optarg);
|
sss->lport = atoi(_optarg);
|
||||||
|
|
||||||
|
if(sss->lport == 0){
|
||||||
|
traceEvent(TRACE_WARNING, "Bad local port format");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't': /* mgmt-port */
|
case 't': /* mgmt-port */
|
||||||
sss->mport = atoi(_optarg);
|
sss->mport = atoi(_optarg);
|
||||||
|
|
||||||
|
if(sss->mport == 0){
|
||||||
|
traceEvent(TRACE_WARNING, "Bad management port format");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l': { /* supernode:port */
|
case 'l': { /* supernode:port */
|
||||||
|
@ -235,44 +247,48 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
||||||
struct peer_info *anchor_sn;
|
struct peer_info *anchor_sn;
|
||||||
size_t length;
|
size_t length;
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
|
int skip_add;
|
||||||
char *double_column = strchr(_optarg, ':');
|
char *double_column = strchr(_optarg, ':');
|
||||||
|
|
||||||
length = strlen(_optarg);
|
length = strlen(_optarg);
|
||||||
if(length >= N2N_EDGE_SN_HOST_SIZE) {
|
if(length >= N2N_EDGE_SN_HOST_SIZE) {
|
||||||
traceEvent(TRACE_WARNING, "Size of -l argument too long: %zu. Maximum size is %d",length,N2N_EDGE_SN_HOST_SIZE);
|
traceEvent(TRACE_WARNING, "Size of -l argument too long: %zu. Maximum size is %d", length, N2N_EDGE_SN_HOST_SIZE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to check the format IP:port */
|
if(!double_column){
|
||||||
if(!double_column) {
|
|
||||||
traceEvent(TRACE_WARNING, "Invalid -l format: ignored");
|
traceEvent(TRACE_WARNING, "Invalid -l format: ignored");
|
||||||
return(-1);
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
socket = (n2n_sock_t *)calloc(1,sizeof(n2n_sock_t));
|
||||||
|
rv = supernode2sock(socket, _optarg);
|
||||||
|
|
||||||
|
if(rv != 0){
|
||||||
|
traceEvent(TRACE_WARNING, "Invalid socket");
|
||||||
|
free(socket);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sss->federation != NULL) {
|
if(sss->federation != NULL) {
|
||||||
socket = (n2n_sock_t *)calloc(1,sizeof(n2n_sock_t));
|
|
||||||
|
|
||||||
anchor_sn = add_sn_to_federation_by_mac_or_sock(sss,socket, (n2n_mac_t*) null_mac);
|
skip_add = NO_SKIP;
|
||||||
|
anchor_sn = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), socket, (n2n_mac_t*) null_mac, &skip_add);
|
||||||
|
|
||||||
if(anchor_sn != NULL){
|
if(anchor_sn != NULL){
|
||||||
anchor_sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE);
|
anchor_sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE);
|
||||||
if(anchor_sn->ip_addr){
|
if(anchor_sn->ip_addr){
|
||||||
strncpy(anchor_sn->ip_addr,_optarg,N2N_EDGE_SN_HOST_SIZE-1);
|
strncpy(anchor_sn->ip_addr,_optarg,N2N_EDGE_SN_HOST_SIZE-1);
|
||||||
rv = supernode2sock(socket,_optarg);
|
memcpy(&(anchor_sn->sock), socket, sizeof(n2n_sock_t));
|
||||||
|
|
||||||
if(rv != 0){
|
|
||||||
traceEvent(TRACE_WARNING, "Invalid socket");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&(anchor_sn->sock), socket, sizeof(n2n_sock_t));
|
|
||||||
memcpy(&(anchor_sn->mac_addr),null_mac,sizeof(n2n_mac_t));
|
memcpy(&(anchor_sn->mac_addr),null_mac,sizeof(n2n_mac_t));
|
||||||
anchor_sn->purgeable = SN_UNPURGEABLE;
|
anchor_sn->purgeable = SN_UNPURGEABLE;
|
||||||
anchor_sn->last_valid_time_stamp = initial_time_stamp();
|
anchor_sn->last_valid_time_stamp = initial_time_stamp();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(socket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,8 +345,10 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 'F': { /* federation name */
|
case 'F': { /* federation name */
|
||||||
snprintf(sss->federation->community, N2N_COMMUNITY_SIZE-1, "*%s" ,_optarg);
|
|
||||||
sss->federation->community[N2N_COMMUNITY_SIZE-1] = '\0';
|
snprintf(sss->federation->community,N2N_COMMUNITY_SIZE-1,"*%s",_optarg);
|
||||||
|
sss->federation->community[N2N_COMMUNITY_SIZE-1] = '\0';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
256
src/sn_utils.c
256
src/sn_utils.c
|
@ -251,6 +251,7 @@ int sn_init(n2n_sn_t *sss) {
|
||||||
sss->federation->header_encryption = HEADER_ENCRYPTION_ENABLED;
|
sss->federation->header_encryption = HEADER_ENCRYPTION_ENABLED;
|
||||||
/*setup the encryption key */
|
/*setup the encryption key */
|
||||||
packet_header_setup_key(sss->federation->community, &(sss->federation->header_encryption_ctx), &(sss->federation->header_iv_ctx));
|
packet_header_setup_key(sss->federation->community, &(sss->federation->header_encryption_ctx), &(sss->federation->header_iv_ctx));
|
||||||
|
sss->federation->edges = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
n2n_srand (n2n_seed());
|
n2n_srand (n2n_seed());
|
||||||
|
@ -511,17 +512,19 @@ static int find_edge_time_stamp_and_verify (struct peer_info * edges,
|
||||||
return ( time_stamp_verify_and_update (stamp, previous_stamp, allow_jitter) );
|
return ( time_stamp_verify_and_update (stamp, previous_stamp, allow_jitter) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *comm, time_t now) {
|
static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *comm, time_t *p_last_re_reg_and_purge, time_t now) {
|
||||||
time_t time;
|
time_t time;
|
||||||
struct peer_info *peer, *tmp;
|
struct peer_info *peer, *tmp;
|
||||||
|
|
||||||
|
if((now - (*p_last_re_reg_and_purge)) < RE_REG_AND_PURGE_FREQUENCY ) return 0;
|
||||||
|
|
||||||
if(comm != NULL) {
|
if(comm != NULL) {
|
||||||
HASH_ITER(hh,comm->edges,peer,tmp) {
|
HASH_ITER(hh,comm->edges,peer,tmp) {
|
||||||
time = now - peer->last_seen;
|
time = now - peer->last_seen;
|
||||||
if(time <= ALLOWED_TIME) continue;
|
if(time <= ALLOWED_TIME) continue;
|
||||||
|
|
||||||
if((time < PURGE_FEDERATION_NODE_INTERVAL)
|
if((time < PURGE_FEDERATION_NODE_INTERVAL)
|
||||||
|| (peer->purgeable == SN_UNPURGEABLE) /* FIX fcarli3 */
|
|| (peer->purgeable == SN_UNPURGEABLE)
|
||||||
) {
|
) {
|
||||||
/* re-regitser (send REGISTER_SUPER) */
|
/* re-regitser (send REGISTER_SUPER) */
|
||||||
uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0};
|
uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0};
|
||||||
|
@ -537,10 +540,10 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
|
||||||
|
|
||||||
cmn.ttl = N2N_DEFAULT_TTL;
|
cmn.ttl = N2N_DEFAULT_TTL;
|
||||||
cmn.pc = n2n_register_super;
|
cmn.pc = n2n_register_super;
|
||||||
cmn.flags = 0;
|
cmn.flags = N2N_FLAGS_FROM_SUPERNODE;
|
||||||
memcpy(cmn.community, comm->community, N2N_COMMUNITY_SIZE);
|
memcpy(cmn.community, comm->community, N2N_COMMUNITY_SIZE);
|
||||||
|
|
||||||
for (idx = 0; idx < N2N_COOKIE_SIZE; ++idx) /* aggiungi sn_idx */
|
for (idx = 0; idx < N2N_COOKIE_SIZE; ++idx)
|
||||||
cookie[idx] = n2n_rand() % 0xff;
|
cookie[idx] = n2n_rand() % 0xff;
|
||||||
|
|
||||||
memcpy(reg.cookie, cookie, N2N_COOKIE_SIZE);
|
memcpy(reg.cookie, cookie, N2N_COOKIE_SIZE);
|
||||||
|
@ -549,7 +552,7 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
|
||||||
reg.auth.scheme = 0; /* No auth yet */
|
reg.auth.scheme = 0; /* No auth yet */
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
encode_mac(reg.edgeMac, &idx, peer->mac_addr);
|
encode_mac(reg.edgeMac, &idx, sss->mac_addr);
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®);
|
encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®);
|
||||||
|
@ -561,12 +564,14 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
|
||||||
comm->header_iv_ctx,
|
comm->header_iv_ctx,
|
||||||
time_stamp(), pearson_hash_16(pktbuf, idx));
|
time_stamp(), pearson_hash_16(pktbuf, idx));
|
||||||
|
|
||||||
/* sent = */ sendto_sock(sss, &(peer->sock), pktbuf, N2N_PKT_BUF_SIZE);
|
/* sent = */ sendto_sock(sss, &(peer->sock), pktbuf, idx);
|
||||||
}
|
}
|
||||||
if(time >= PURGE_FEDERATION_NODE_INTERVAL) purge_expired_registrations(&(comm->edges),&time,PURGE_FEDERATION_NODE_INTERVAL);/* purge not-seen-long-time supernodes*/
|
if(time >= PURGE_FEDERATION_NODE_INTERVAL) purge_expired_registrations(&(comm->edges),&time,PURGE_FEDERATION_NODE_INTERVAL);/* purge not-seen-long-time supernodes*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(*p_last_re_reg_and_purge) = now;
|
||||||
|
|
||||||
return 0; /* OK */
|
return 0; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,46 +740,6 @@ static int sendto_mgmt(n2n_sn_t *sss,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Search for a node in the federation list. If it has to add a new node, it creates a new peer_info and initializes it
|
|
||||||
* Evaluate first the MAC parameter and if it's zero-MAC, then it can skip HASH_FIND_PEER by MAC and search by socket
|
|
||||||
*/
|
|
||||||
struct peer_info* add_sn_to_federation_by_mac_or_sock(n2n_sn_t *sss,n2n_sock_t *sock, n2n_mac_t *mac) {
|
|
||||||
struct peer_info *scan, *tmp, *peer = NULL;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
if(sss->federation != NULL) {
|
|
||||||
if(memcmp(mac,null_mac,sizeof(n2n_mac_t)) != 0) { /* not zero MAC */
|
|
||||||
HASH_FIND_PEER(sss->federation->edges, mac, peer);
|
|
||||||
|
|
||||||
//REVISIT: make this dependent from last_seen and update socket
|
|
||||||
}
|
|
||||||
|
|
||||||
if(peer == NULL) { /* zero MAC, search by socket */
|
|
||||||
HASH_ITER(hh,sss->federation->edges,scan,tmp) {
|
|
||||||
if(memcmp(&(scan->sock), sock, sizeof(n2n_sock_t))) {
|
|
||||||
memcpy(&(scan->mac_addr), sock, sizeof(n2n_mac_t));
|
|
||||||
peer = scan;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(peer == NULL) {
|
|
||||||
peer = (struct peer_info*)calloc(1,sizeof(struct peer_info));
|
|
||||||
if(peer) {
|
|
||||||
memcpy(&(peer->sock),sock,sizeof(n2n_sock_t));
|
|
||||||
memcpy(&(peer->mac_addr),mac, sizeof(n2n_mac_t));
|
|
||||||
HASH_ADD_PEER(sss->federation->edges,peer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return peer;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Examine a datagram and determine what to do with it.
|
/** Examine a datagram and determine what to do with it.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -1058,18 +1023,18 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
n2n_REGISTER_SUPER_ACK_t ack;
|
n2n_REGISTER_SUPER_ACK_t ack;
|
||||||
n2n_common_t cmn2;
|
n2n_common_t cmn2;
|
||||||
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
|
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
|
||||||
uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
|
uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
|
||||||
|
uint8_t *tmp_dst;
|
||||||
size_t encx=0;
|
size_t encx=0;
|
||||||
struct sn_community *fed;
|
struct sn_community *fed;
|
||||||
struct sn_community_regular_expression *re, *tmp_re;
|
struct sn_community_regular_expression *re, *tmp_re;
|
||||||
struct peer_info *peer, *tmp_peer, *p;
|
struct peer_info *peer, *tmp_peer, *p;
|
||||||
int8_t allowed_match = -1;
|
int8_t allowed_match = -1;
|
||||||
uint8_t match = 0;
|
uint8_t match = 0;
|
||||||
int match_length = 0;
|
int match_length = 0;
|
||||||
n2n_ip_subnet_t ipaddr;
|
n2n_ip_subnet_t ipaddr;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
n2n_sock_t *tmp_sock;
|
int skip_add;
|
||||||
n2n_mac_t *tmp_mac;
|
|
||||||
|
|
||||||
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||||
|
|
||||||
|
@ -1079,13 +1044,13 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx);
|
decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
if (comm) {
|
if (comm) {
|
||||||
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp, TIME_STAMP_NO_JITTER)) {
|
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp, TIME_STAMP_NO_JITTER)) {
|
||||||
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error.");
|
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Before we move any further, we need to check if the requested
|
Before we move any further, we need to check if the requested
|
||||||
|
@ -1095,8 +1060,8 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(!comm && sss->lock_communities) {
|
if(!comm && sss->lock_communities) {
|
||||||
HASH_ITER(hh, sss->rules, re, tmp_re) {
|
HASH_ITER(hh, sss->rules, re, tmp_re) {
|
||||||
allowed_match = re_matchp(re->rule, (const char *)cmn.community, &match_length);
|
allowed_match = re_matchp(re->rule, (const char *)cmn.community, &match_length);
|
||||||
|
|
||||||
if( (allowed_match != -1)
|
if( (allowed_match != -1)
|
||||||
&& (match_length == strlen((const char *)cmn.community)) // --- only full matches allowed (remove, if also partial matches wanted)
|
&& (match_length == strlen((const char *)cmn.community)) // --- only full matches allowed (remove, if also partial matches wanted)
|
||||||
|
@ -1112,7 +1077,7 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!comm && (!sss->lock_communities || (match == 1))) {
|
if(!comm && (!sss->lock_communities || (match == 1))) {
|
||||||
|
|
||||||
comm = (struct sn_community*)calloc(1,sizeof(struct sn_community));
|
comm = (struct sn_community*)calloc(1,sizeof(struct sn_community));
|
||||||
|
|
||||||
|
@ -1127,18 +1092,24 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
HASH_ADD_STR(sss->communities, community, comm);
|
HASH_ADD_STR(sss->communities, community, comm);
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "New community: %s", comm->community);
|
traceEvent(TRACE_INFO, "New community: %s", comm->community);
|
||||||
assign_one_ip_subnet(sss, comm);
|
assign_one_ip_subnet(sss, comm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(comm) {
|
if(comm) {
|
||||||
cmn2.ttl = N2N_DEFAULT_TTL;
|
cmn2.ttl = N2N_DEFAULT_TTL;
|
||||||
cmn2.pc = n2n_register_super_ack;
|
cmn2.pc = n2n_register_super_ack;
|
||||||
cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
|
cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
|
||||||
memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t));
|
memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t));
|
||||||
|
|
||||||
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));
|
|
||||||
|
if(comm->is_federation == IS_FEDERATION){
|
||||||
|
memcpy(&(ack.edgeMac), &(sss->mac_addr), sizeof(n2n_mac_t));
|
||||||
|
}else{
|
||||||
|
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) ||
|
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 */)) {
|
((reg.dev_addr.net_addr & 0xFFFF0000) == 0xA9FE0000 /* 169.254.0.0 */)) {
|
||||||
memset(&ipaddr, 0, sizeof(n2n_ip_subnet_t));
|
memset(&ipaddr, 0, sizeof(n2n_ip_subnet_t));
|
||||||
|
@ -1152,37 +1123,36 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
ack.sock.port = ntohs(sender_sock->sin_port);
|
ack.sock.port = ntohs(sender_sock->sin_port);
|
||||||
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);
|
||||||
|
|
||||||
if(from_supernode != comm->is_federation) {
|
if((from_supernode == 0) != (comm->is_federation == IS_NO_FEDERATION)) {
|
||||||
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER: from_supernode value doesn't correspond to the internal federation marking");
|
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER: from_supernode value doesn't correspond to the internal federation marking");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add sender's data to federation (or update it) */
|
/* Add sender's data to federation (or update it) */
|
||||||
if(comm->is_federation == IS_FEDERATION) {
|
if(comm->is_federation == IS_FEDERATION) {
|
||||||
p = add_sn_to_federation_by_mac_or_sock(sss,&(ack.sock),&(reg.edgeMac));
|
skip_add = NO_SKIP;
|
||||||
if(p) p->last_seen = now;
|
p = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(ack.sock), &(reg.edgeMac), &skip_add);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_sock = (void*)tmpbuf;
|
|
||||||
tmp_mac = (void*)tmpbuf + sizeof(n2n_sock_t);
|
|
||||||
|
|
||||||
// REVISIT: consider adding last_seen
|
// REVISIT: consider adding last_seen
|
||||||
|
|
||||||
/* Assembling supernode list for REGISTER_SUPER_ACK payload */
|
/* Assembling supernode list for REGISTER_SUPER_ACK payload */
|
||||||
|
tmp_dst = tmpbuf;
|
||||||
HASH_ITER(hh, sss->federation->edges, peer, tmp_peer) {
|
HASH_ITER(hh, sss->federation->edges, peer, tmp_peer) {
|
||||||
|
if(memcmp(&(peer->sock), &(ack.sock), sizeof(n2n_sock_t)) == 0) continue; /* a supernode doesn't add itself to the payload */
|
||||||
if((now - peer->last_seen) >= ALLOWED_TIME) continue; /* skip long-time-not-seen supernodes */
|
if((now - peer->last_seen) >= ALLOWED_TIME) continue; /* skip long-time-not-seen supernodes */
|
||||||
if(((++num)*ENTRY_SIZE) > MAX_AVAILABLE_SPACE_FOR_ENTRIES) break; /* no more space available in REGISTER_SUPER_ACK payload */
|
if(((++num)*ENTRY_SIZE) > MAX_AVAILABLE_SPACE_FOR_ENTRIES) break; /* no more space available in REGISTER_SUPER_ACK payload */
|
||||||
memcpy((void*)tmpbuf, (void*)&(peer->sock), sizeof(n2n_sock_t));
|
memcpy((void*)tmp_dst, (void*)&(peer->sock), sizeof(n2n_sock_t));
|
||||||
memcpy((void*)tmpbuf, (void*)&(peer->mac_addr), sizeof(n2n_mac_t));
|
tmp_dst += sizeof(n2n_sock_t);
|
||||||
tmp_sock += ENTRY_SIZE;
|
memcpy((void*)tmp_dst, (void*)&(peer->mac_addr), sizeof(n2n_mac_t));
|
||||||
tmp_mac += ENTRY_SIZE;
|
tmp_dst += sizeof(n2n_mac_t);
|
||||||
}
|
}
|
||||||
ack.num_sn = num;
|
ack.num_sn = num;
|
||||||
|
|
||||||
|
|
||||||
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)));
|
||||||
|
|
||||||
if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0) {
|
if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0) {
|
||||||
update_edge(sss, ®, comm, &(ack.sock), now);
|
update_edge(sss, ®, comm, &(ack.sock), now);
|
||||||
|
@ -1192,8 +1162,8 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx,
|
packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx,
|
||||||
comm->header_iv_ctx,
|
comm->header_iv_ctx,
|
||||||
time_stamp (), pearson_hash_16 (ackbuf, encx));
|
time_stamp (), pearson_hash_16 (ackbuf, encx));
|
||||||
|
|
||||||
sendto(sss->sock, ackbuf, encx, 0,
|
sendto(sss->sock, ackbuf, encx, 0,
|
||||||
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
|
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
|
||||||
|
@ -1202,9 +1172,9 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
macaddr_str(mac_buf, reg.edgeMac),
|
macaddr_str(mac_buf, reg.edgeMac),
|
||||||
sock_to_cstr(sockbuf, &(ack.sock)));
|
sock_to_cstr(sockbuf, &(ack.sock)));
|
||||||
} else {
|
} else {
|
||||||
traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'",
|
traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'",
|
||||||
(char*)cmn.community);
|
(char*)cmn.community);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1222,7 +1192,9 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
n2n_mac_t *tmp_mac;
|
n2n_mac_t *tmp_mac;
|
||||||
int i;
|
int i;
|
||||||
uint8_t dec_tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
|
uint8_t dec_tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
|
||||||
|
int skip_add;
|
||||||
|
|
||||||
|
memset(&sender, 0, sizeof(n2n_sock_t));
|
||||||
sender.family = AF_INET;
|
sender.family = AF_INET;
|
||||||
sender.port = ntohs(sender_sock->sin_port);
|
sender.port = ntohs(sender_sock->sin_port);
|
||||||
memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
|
memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
|
||||||
|
@ -1235,7 +1207,7 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(from_supernode != comm->is_federation) {
|
if((from_supernode == 0) != (comm->is_federation == IS_NO_FEDERATION)) {
|
||||||
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK: from_supernode value doesn't correspond to the internal federation marking.");
|
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK: from_supernode value doesn't correspond to the internal federation marking.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1246,9 +1218,9 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
if (comm) {
|
if (comm) {
|
||||||
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, ack.edgeMac, stamp, TIME_STAMP_NO_JITTER)) {
|
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, ack.edgeMac, stamp, TIME_STAMP_NO_JITTER)) {
|
||||||
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to time stamp error.");
|
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to time stamp error.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,27 +1230,30 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
sock_to_cstr(sockbuf2, orig_sender));
|
sock_to_cstr(sockbuf2, orig_sender));
|
||||||
|
|
||||||
if(comm->is_federation == IS_FEDERATION) {
|
if(comm->is_federation == IS_FEDERATION) {
|
||||||
HASH_FIND_PEER(sss->federation->edges, ack.edgeMac, scan);
|
skip_add = SKIP;
|
||||||
|
scan = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &sender, &(ack.edgeMac), &skip_add);
|
||||||
if(scan != NULL) {
|
if(scan != NULL) {
|
||||||
scan->last_seen = now;
|
scan->last_seen = now;
|
||||||
} else {
|
} else {
|
||||||
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to an unknown supernode.");
|
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to an unknown supernode.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_sock = (void*)&(ack.num_sn) + sizeof(ack.num_sn);
|
tmp_sock = (void *)dec_tmpbuf;
|
||||||
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t);
|
tmp_mac = (void*)dec_tmpbuf + sizeof(n2n_sock_t);
|
||||||
|
|
||||||
for(i=0; i<ack.num_sn; i++) {
|
for(i=0; i<ack.num_sn; i++) {
|
||||||
tmp = add_sn_to_federation_by_mac_or_sock(sss,tmp_sock,tmp_mac);
|
skip_add = NO_SKIP;
|
||||||
|
tmp = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), tmp_sock, tmp_mac, &skip_add);
|
||||||
|
|
||||||
if(tmp) {
|
if(skip_add == ADDED) {
|
||||||
tmp->last_seen = now - TEST_TIME;
|
tmp->last_seen = now - TEST_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_sock += ENTRY_SIZE;
|
/* REVISIT: find a more elegant expression to increase following pointers. */
|
||||||
tmp_mac += ENTRY_SIZE;
|
tmp_sock = (void*)tmp_sock + ENTRY_SIZE;
|
||||||
|
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1305,39 +1280,69 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s",
|
if(memcmp(query.targetMac, null_mac, sizeof(n2n_mac_t)) == 0){
|
||||||
macaddr_str( mac_buf, query.srcMac ),
|
traceEvent( TRACE_DEBUG, "Rx PING from %s. Requested data: %d",
|
||||||
macaddr_str( mac_buf2, query.targetMac ) );
|
macaddr_str( mac_buf, query.srcMac ),
|
||||||
|
query.req_data );
|
||||||
|
|
||||||
struct peer_info *scan;
|
cmn2.ttl = N2N_DEFAULT_TTL;
|
||||||
HASH_FIND_PEER(comm->edges, query.targetMac, scan);
|
|
||||||
|
|
||||||
if (scan) {
|
|
||||||
cmn2.ttl = N2N_DEFAULT_TTL;
|
|
||||||
cmn2.pc = n2n_peer_info;
|
cmn2.pc = n2n_peer_info;
|
||||||
cmn2.flags = N2N_FLAGS_FROM_SUPERNODE;
|
cmn2.flags = N2N_FLAGS_FROM_SUPERNODE;
|
||||||
memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) );
|
memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) );
|
||||||
|
|
||||||
pi.aflags = 0;
|
pi.aflags = 0;
|
||||||
memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) );
|
memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) );
|
||||||
pi.sock = scan->sock;
|
memcpy( pi.srcMac, sss->mac_addr, sizeof(n2n_mac_t) );
|
||||||
|
|
||||||
encode_PEER_INFO( encbuf, &encx, &cmn2, &pi );
|
encode_PEER_INFO( encbuf, &encx, &cmn2, &pi );
|
||||||
|
|
||||||
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx,
|
packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx,
|
||||||
comm->header_iv_ctx,
|
comm->header_iv_ctx,
|
||||||
time_stamp (), pearson_hash_16 (encbuf, encx));
|
time_stamp (), pearson_hash_16 (encbuf, encx));
|
||||||
|
|
||||||
sendto( sss->sock, encbuf, encx, 0,
|
sendto( sss->sock, encbuf, encx, 0,
|
||||||
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );
|
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );
|
||||||
|
|
||||||
traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s",
|
traceEvent( TRACE_DEBUG, "Tx PING to %s",
|
||||||
macaddr_str( mac_buf, query.srcMac ) );
|
macaddr_str( mac_buf, query.srcMac ) );
|
||||||
} else {
|
|
||||||
traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s",
|
} else {
|
||||||
macaddr_str( mac_buf, query.targetMac ) );
|
traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s",
|
||||||
}
|
macaddr_str( mac_buf, query.srcMac ),
|
||||||
|
macaddr_str( mac_buf2, query.targetMac ) );
|
||||||
|
|
||||||
|
struct peer_info *scan;
|
||||||
|
HASH_FIND_PEER(comm->edges, query.targetMac, scan);
|
||||||
|
|
||||||
|
if (scan) {
|
||||||
|
cmn2.ttl = N2N_DEFAULT_TTL;
|
||||||
|
cmn2.pc = n2n_peer_info;
|
||||||
|
cmn2.flags = N2N_FLAGS_FROM_SUPERNODE;
|
||||||
|
memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) );
|
||||||
|
|
||||||
|
pi.aflags = 0;
|
||||||
|
memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) );
|
||||||
|
pi.sock = scan->sock;
|
||||||
|
|
||||||
|
encode_PEER_INFO( encbuf, &encx, &cmn2, &pi );
|
||||||
|
|
||||||
|
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
|
packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx,
|
||||||
|
comm->header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (encbuf, encx));
|
||||||
|
|
||||||
|
sendto( sss->sock, encbuf, encx, 0,
|
||||||
|
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );
|
||||||
|
|
||||||
|
traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s",
|
||||||
|
macaddr_str( mac_buf, query.srcMac ) );
|
||||||
|
} else {
|
||||||
|
traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s",
|
||||||
|
macaddr_str( mac_buf, query.targetMac ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1356,6 +1361,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
|
||||||
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE];
|
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE];
|
||||||
time_t last_purge_edges = 0;
|
time_t last_purge_edges = 0;
|
||||||
time_t last_sort_communities = 0;
|
time_t last_sort_communities = 0;
|
||||||
|
time_t last_re_reg_and_purge = 0;
|
||||||
|
|
||||||
sss->start_time = time(NULL);
|
sss->start_time = time(NULL);
|
||||||
|
|
||||||
|
@ -1440,7 +1446,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
|
||||||
traceEvent(TRACE_DEBUG, "timeout");
|
traceEvent(TRACE_DEBUG, "timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
re_register_and_purge_supernodes(sss, sss->federation, now);
|
re_register_and_purge_supernodes(sss, sss->federation, &last_re_reg_and_purge, now);
|
||||||
purge_expired_communities(sss, &last_purge_edges, now);
|
purge_expired_communities(sss, &last_purge_edges, now);
|
||||||
sort_communities (sss, &last_sort_communities, now);
|
sort_communities (sss, &last_sort_communities, now);
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
|
@ -514,6 +514,7 @@ int encode_PEER_INFO(uint8_t *base,
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
retval += encode_common(base, idx, common);
|
retval += encode_common(base, idx, common);
|
||||||
retval += encode_uint16(base, idx, pkt->aflags);
|
retval += encode_uint16(base, idx, pkt->aflags);
|
||||||
|
retval += encode_mac(base, idx, pkt->srcMac);
|
||||||
retval += encode_mac(base, idx, pkt->mac);
|
retval += encode_mac(base, idx, pkt->mac);
|
||||||
retval += encode_sock(base, idx, &pkt->sock);
|
retval += encode_sock(base, idx, &pkt->sock);
|
||||||
|
|
||||||
|
@ -529,6 +530,7 @@ int decode_PEER_INFO(n2n_PEER_INFO_t *pkt,
|
||||||
size_t retval = 0;
|
size_t retval = 0;
|
||||||
memset(pkt, 0, sizeof(n2n_PEER_INFO_t));
|
memset(pkt, 0, sizeof(n2n_PEER_INFO_t));
|
||||||
retval += decode_uint16(&(pkt->aflags), base, rem, idx);
|
retval += decode_uint16(&(pkt->aflags), base, rem, idx);
|
||||||
|
retval += decode_mac(pkt->srcMac, base, rem, idx);
|
||||||
retval += decode_mac(pkt->mac, base, rem, idx);
|
retval += decode_mac(pkt->mac, base, rem, idx);
|
||||||
retval += decode_sock(&pkt->sock, base, rem, idx);
|
retval += decode_sock(&pkt->sock, base, rem, idx);
|
||||||
|
|
||||||
|
@ -545,6 +547,7 @@ int encode_QUERY_PEER( uint8_t * base,
|
||||||
retval += encode_common( base, idx, common );
|
retval += encode_common( base, idx, common );
|
||||||
retval += encode_mac( base, idx, pkt->srcMac );
|
retval += encode_mac( base, idx, pkt->srcMac );
|
||||||
retval += encode_mac( base, idx, pkt->targetMac );
|
retval += encode_mac( base, idx, pkt->targetMac );
|
||||||
|
retval += encode_uint8( base, idx, pkt->req_data);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -559,6 +562,7 @@ int decode_QUERY_PEER( n2n_QUERY_PEER_t * pkt,
|
||||||
memset( pkt, 0, sizeof(n2n_QUERY_PEER_t) );
|
memset( pkt, 0, sizeof(n2n_QUERY_PEER_t) );
|
||||||
retval += decode_mac( pkt->srcMac, base, rem, idx );
|
retval += decode_mac( pkt->srcMac, base, rem, idx );
|
||||||
retval += decode_mac( pkt->targetMac, base, rem, idx );
|
retval += decode_mac( pkt->targetMac, base, rem, idx );
|
||||||
|
retval += decode_uint8( &pkt->req_data, base, rem, idx);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user