mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
Packet forwarding between supernodes (#486)
* Packet forwarding between supernodes * Update wire.c
This commit is contained in:
parent
4bad6a7625
commit
e65fd984d7
|
@ -32,23 +32,25 @@
|
||||||
/* 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. */
|
* 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 REG_SUPER_ACK_PAYLOAD_SPACE \
|
||||||
(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)) \
|
(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 REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE (sizeof(n2n_sock_t)+sizeof(n2n_mac_t))
|
||||||
|
|
||||||
#define PURGE_REGISTRATION_FREQUENCY 30
|
#define PURGE_REGISTRATION_FREQUENCY 30
|
||||||
#define RE_REG_AND_PURGE_FREQUENCY 10
|
#define RE_REG_AND_PURGE_FREQUENCY 10
|
||||||
#define REGISTRATION_TIMEOUT 60
|
#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 MAX_PING_TIME 3000 /* millisec, indicates default value for ping_time field in peer_info structure */
|
||||||
#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 SWEEP_TIME 30 /* sec, indicates the value after which we have to sort the hash list of supernodes in edges */
|
||||||
#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 LAST_SEEN_SN_ACTIVE 20 /* sec, indicates supernodes that are proven to be active */
|
||||||
|
#define LAST_SEEN_SN_INACTIVE 90 /* sec, indicates supernodes that are proven to be inactive: they will be purged */
|
||||||
|
#define LAST_SEEN_SN_NEW (LAST_SEEN_SN_INACTIVE - LAST_SEEN_SN_ACTIVE)/2 /* sec, indicates supernodes with unsure status, must be tested to check if they are active */
|
||||||
|
|
||||||
|
|
||||||
#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 */
|
||||||
|
@ -108,7 +110,7 @@ enum sn_purge{SN_PURGEABLE = 0, SN_UNPURGEABLE = 1};
|
||||||
#define N2N_SN_MGMT_PORT 5645
|
#define N2N_SN_MGMT_PORT 5645
|
||||||
|
|
||||||
/* flag used in add_sn_to_list_by_mac_or_sock */
|
/* flag used in add_sn_to_list_by_mac_or_sock */
|
||||||
enum skip_add{NO_SKIP = 0, SKIP = 1, ADDED = 2};
|
enum skip_add{SN_ADD = 0, SN_ADD_SKIP = 1, SN_ADD_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*/
|
||||||
|
|
|
@ -195,6 +195,7 @@ typedef struct n2n_PEER_INFO {
|
||||||
typedef struct n2n_QUERY_PEER
|
typedef struct n2n_QUERY_PEER
|
||||||
{
|
{
|
||||||
n2n_mac_t srcMac;
|
n2n_mac_t srcMac;
|
||||||
|
n2n_sock_t sock;
|
||||||
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 ...) */
|
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;
|
||||||
|
|
|
@ -1956,12 +1956,12 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
in_addr_t net;
|
in_addr_t net;
|
||||||
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_sock_t *tmp_sock;
|
||||||
n2n_mac_t *tmp_mac;
|
n2n_mac_t *tmp_mac;
|
||||||
int i;
|
int i;
|
||||||
int skip_add;
|
int skip_add;
|
||||||
struct peer_info *sn;
|
struct peer_info *sn;
|
||||||
|
|
||||||
memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||||
|
|
||||||
|
@ -2005,10 +2005,10 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
tmp_mac = (void*)&tmpbuf[sizeof(n2n_sock_t)];
|
tmp_mac = (void*)&tmpbuf[sizeof(n2n_sock_t)];
|
||||||
|
|
||||||
for(i=0; i<ra.num_sn; i++){
|
for(i=0; i<ra.num_sn; i++){
|
||||||
skip_add = NO_SKIP;
|
skip_add = SN_ADD;
|
||||||
sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), tmp_sock, tmp_mac, &skip_add);
|
sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), tmp_sock, tmp_mac, &skip_add);
|
||||||
|
|
||||||
if(skip_add == ADDED){
|
if(skip_add == SN_ADD_ADDED){
|
||||||
sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE);
|
sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE);
|
||||||
if(sn->ip_addr != NULL){
|
if(sn->ip_addr != NULL){
|
||||||
inet_ntop(tmp_sock->family,
|
inet_ntop(tmp_sock->family,
|
||||||
|
@ -2085,7 +2085,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(memcmp(pi.mac, null_mac, sizeof(n2n_mac_t)) == 0){
|
if(memcmp(pi.mac, null_mac, sizeof(n2n_mac_t)) == 0){
|
||||||
skip_add = SKIP;
|
skip_add = SN_ADD_SKIP;
|
||||||
scan = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &sender, &pi.srcMac, &skip_add);
|
scan = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &sender, &pi.srcMac, &skip_add);
|
||||||
if(scan != NULL){
|
if(scan != NULL){
|
||||||
scan->ping_time = (now - eee->last_sweep)*1000;
|
scan->ping_time = (now - eee->last_sweep)*1000;
|
||||||
|
@ -2818,7 +2818,7 @@ int edge_conf_add_supernode(n2n_edge_conf_t *conf, const char *ip_and_port) {
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_add = NO_SKIP;
|
skip_add = SN_ADD;
|
||||||
sn = add_sn_to_list_by_mac_or_sock(&(conf->supernodes), sock, (n2n_mac_t *)null_mac, &skip_add);
|
sn = add_sn_to_list_by_mac_or_sock(&(conf->supernodes), sock, (n2n_mac_t *)null_mac, &skip_add);
|
||||||
|
|
||||||
if(sn != NULL){
|
if(sn != NULL){
|
||||||
|
|
|
@ -301,21 +301,21 @@ struct peer_info* add_sn_to_list_by_mac_or_sock(struct peer_info **sn_list, n2n_
|
||||||
if(peer == NULL) { /* zero MAC, search by socket */
|
if(peer == NULL) { /* zero MAC, search by socket */
|
||||||
HASH_ITER(hh,*sn_list,scan,tmp) {
|
HASH_ITER(hh,*sn_list,scan,tmp) {
|
||||||
if(memcmp(&(scan->sock), sock, sizeof(n2n_sock_t)) == 0) {
|
if(memcmp(&(scan->sock), sock, sizeof(n2n_sock_t)) == 0) {
|
||||||
HASH_DEL(*sn_list, scan);
|
HASH_DEL(*sn_list, scan);
|
||||||
memcpy(&(scan->mac_addr), mac, sizeof(n2n_mac_t));
|
memcpy(&(scan->mac_addr), mac, sizeof(n2n_mac_t));
|
||||||
HASH_ADD_PEER(*sn_list, scan);
|
HASH_ADD_PEER(*sn_list, scan);
|
||||||
peer = scan;
|
peer = scan;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((peer == NULL) && (*skip_add == NO_SKIP)) {
|
if((peer == NULL) && (*skip_add == SN_ADD)) {
|
||||||
peer = (struct peer_info*)calloc(1,sizeof(struct peer_info));
|
peer = (struct peer_info*)calloc(1,sizeof(struct peer_info));
|
||||||
if(peer) {
|
if(peer) {
|
||||||
memcpy(&(peer->sock),sock,sizeof(n2n_sock_t));
|
memcpy(&(peer->sock),sock,sizeof(n2n_sock_t));
|
||||||
memcpy(&(peer->mac_addr),mac, sizeof(n2n_mac_t));
|
memcpy(&(peer->mac_addr),mac, sizeof(n2n_mac_t));
|
||||||
HASH_ADD_PEER(*sn_list, peer);
|
HASH_ADD_PEER(*sn_list, peer);
|
||||||
*skip_add = ADDED;
|
*skip_add = SN_ADD_ADDED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
src/sn.c
2
src/sn.c
|
@ -276,7 +276,7 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
||||||
|
|
||||||
if(sss->federation != NULL) {
|
if(sss->federation != NULL) {
|
||||||
|
|
||||||
skip_add = NO_SKIP;
|
skip_add = SN_ADD;
|
||||||
anchor_sn = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), socket, (n2n_mac_t*) null_mac, &skip_add);
|
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){
|
||||||
|
|
202
src/sn_utils.c
202
src/sn_utils.c
|
@ -25,7 +25,8 @@ static int try_forward(n2n_sn_t * sss,
|
||||||
const n2n_common_t * cmn,
|
const n2n_common_t * cmn,
|
||||||
const n2n_mac_t dstMac,
|
const n2n_mac_t dstMac,
|
||||||
const uint8_t * pktbuf,
|
const uint8_t * pktbuf,
|
||||||
size_t pktsize);
|
size_t pktsize,
|
||||||
|
uint8_t from_supernode);
|
||||||
|
|
||||||
static ssize_t sendto_sock(n2n_sn_t *sss,
|
static ssize_t sendto_sock(n2n_sn_t *sss,
|
||||||
const n2n_sock_t *sock,
|
const n2n_sock_t *sock,
|
||||||
|
@ -42,7 +43,8 @@ static int try_broadcast(n2n_sn_t * sss,
|
||||||
const n2n_common_t * cmn,
|
const n2n_common_t * cmn,
|
||||||
const n2n_mac_t srcMac,
|
const n2n_mac_t srcMac,
|
||||||
const uint8_t * pktbuf,
|
const uint8_t * pktbuf,
|
||||||
size_t pktsize);
|
size_t pktsize,
|
||||||
|
uint8_t from_supernode);
|
||||||
|
|
||||||
static uint16_t reg_lifetime(n2n_sn_t *sss);
|
static uint16_t reg_lifetime(n2n_sn_t *sss);
|
||||||
|
|
||||||
|
@ -81,7 +83,8 @@ static int try_forward(n2n_sn_t * sss,
|
||||||
const n2n_common_t * cmn,
|
const n2n_common_t * cmn,
|
||||||
const n2n_mac_t dstMac,
|
const n2n_mac_t dstMac,
|
||||||
const uint8_t * pktbuf,
|
const uint8_t * pktbuf,
|
||||||
size_t pktsize)
|
size_t pktsize,
|
||||||
|
uint8_t from_supernode)
|
||||||
{
|
{
|
||||||
struct peer_info * scan;
|
struct peer_info * scan;
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
|
@ -114,10 +117,15 @@ static int try_forward(n2n_sn_t * sss,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
traceEvent(TRACE_DEBUG, "try_forward unknown MAC");
|
if(!from_supernode){
|
||||||
|
/* Forwarding packet to all federated supernodes. */
|
||||||
/* Not a known MAC so drop. */
|
traceEvent(TRACE_DEBUG, "Unknown MAC. Broadcasting packet to all federated supernodes.");
|
||||||
return(-2);
|
try_broadcast(sss, NULL, cmn, sss->mac_addr, pktbuf, pktsize, from_supernode);
|
||||||
|
} else {
|
||||||
|
traceEvent(TRACE_DEBUG, "try_forward unknown MAC. Dropping the packet.");
|
||||||
|
/* Not a known MAC so drop. */
|
||||||
|
return(-2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -167,7 +175,8 @@ static int try_broadcast(n2n_sn_t * sss,
|
||||||
const n2n_common_t * cmn,
|
const n2n_common_t * cmn,
|
||||||
const n2n_mac_t srcMac,
|
const n2n_mac_t srcMac,
|
||||||
const uint8_t * pktbuf,
|
const uint8_t * pktbuf,
|
||||||
size_t pktsize)
|
size_t pktsize,
|
||||||
|
uint8_t from_supernode)
|
||||||
{
|
{
|
||||||
struct peer_info *scan, *tmp;
|
struct peer_info *scan, *tmp;
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
|
@ -175,32 +184,63 @@ static int try_broadcast(n2n_sn_t * sss,
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "try_broadcast");
|
traceEvent(TRACE_DEBUG, "try_broadcast");
|
||||||
|
|
||||||
HASH_ITER(hh, comm->edges, scan, tmp) {
|
/* We have to make sure that a broadcast reaches the other supernodes and edges
|
||||||
if(memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t)) != 0) {
|
* connected to them. try_broadcast needs a from_supernode parameter: if set
|
||||||
/* REVISIT: exclude if the destination socket is where the packet came from. */
|
* do forward to edges of community only. If unset. forward to all locally known
|
||||||
|
* nodes and all supernodes */
|
||||||
|
|
||||||
|
if (!from_supernode) {
|
||||||
|
HASH_ITER(hh, sss->federation->edges, scan, tmp) {
|
||||||
int data_sent_len;
|
int data_sent_len;
|
||||||
|
|
||||||
data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize);
|
data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize);
|
||||||
|
|
||||||
if(data_sent_len != pktsize)
|
if(data_sent_len != pktsize)
|
||||||
{
|
{
|
||||||
++(sss->stats.errors);
|
++(sss->stats.errors);
|
||||||
traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s",
|
traceEvent(TRACE_WARNING, "multicast %lu to supernode [%s] %s failed %s",
|
||||||
|
pktsize,
|
||||||
|
sock_to_cstr(sockbuf, &(scan->sock)),
|
||||||
|
macaddr_str(mac_buf, scan->mac_addr),
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++(sss->stats.broadcast);
|
||||||
|
traceEvent(TRACE_DEBUG, "multicast %lu to supernode [%s] %s",
|
||||||
|
pktsize,
|
||||||
|
sock_to_cstr(sockbuf, &(scan->sock)),
|
||||||
|
macaddr_str(mac_buf, scan->mac_addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(comm){
|
||||||
|
HASH_ITER(hh, comm->edges, scan, tmp) {
|
||||||
|
if(memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t)) != 0) {
|
||||||
|
/* REVISIT: exclude if the destination socket is where the packet came from. */
|
||||||
|
int data_sent_len;
|
||||||
|
|
||||||
|
data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize);
|
||||||
|
|
||||||
|
if(data_sent_len != pktsize){
|
||||||
|
++(sss->stats.errors);
|
||||||
|
traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s",
|
||||||
pktsize,
|
pktsize,
|
||||||
sock_to_cstr(sockbuf, &(scan->sock)),
|
sock_to_cstr(sockbuf, &(scan->sock)),
|
||||||
macaddr_str(mac_buf, scan->mac_addr),
|
macaddr_str(mac_buf, scan->mac_addr),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
++(sss->stats.broadcast);
|
||||||
|
traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s",
|
||||||
|
pktsize,
|
||||||
|
sock_to_cstr(sockbuf, &(scan->sock)),
|
||||||
|
macaddr_str(mac_buf, scan->mac_addr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
++(sss->stats.broadcast);
|
|
||||||
traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s",
|
|
||||||
pktsize,
|
|
||||||
sock_to_cstr(sockbuf, &(scan->sock)),
|
|
||||||
macaddr_str(mac_buf, scan->mac_addr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +291,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;
|
sss->federation->edges = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
n2n_srand (n2n_seed());
|
n2n_srand (n2n_seed());
|
||||||
|
@ -534,9 +574,9 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
|
||||||
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 <= LAST_SEEN_SN_ACTIVE) continue;
|
||||||
|
|
||||||
if((time < PURGE_FEDERATION_NODE_INTERVAL)
|
if((time < LAST_SEEN_SN_INACTIVE)
|
||||||
|| (peer->purgeable == SN_UNPURGEABLE)
|
|| (peer->purgeable == SN_UNPURGEABLE)
|
||||||
) {
|
) {
|
||||||
/* re-regitser (send REGISTER_SUPER) */
|
/* re-regitser (send REGISTER_SUPER) */
|
||||||
|
@ -579,7 +619,7 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
|
||||||
|
|
||||||
/* sent = */ sendto_sock(sss, &(peer->sock), pktbuf, idx);
|
/* 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 >= LAST_SEEN_SN_INACTIVE) purge_expired_registrations(&(comm->edges), &time, LAST_SEEN_SN_INACTIVE);/* purge not-seen-long-time supernodes*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,7 +732,7 @@ static int process_mgmt(n2n_sn_t *sss,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"--------------------------------------------------------------------------------------------------\n");
|
"----------------------------------------------------------------------------------------------------\n");
|
||||||
|
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"uptime %lu | ", (now - sss->start_time));
|
"uptime %lu | ", (now - sss->start_time));
|
||||||
|
@ -955,9 +995,9 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
/* Common section to forward the final product. */
|
/* Common section to forward the final product. */
|
||||||
if(unicast)
|
if(unicast)
|
||||||
try_forward(sss, comm, &cmn, pkt.dstMac, rec_buf, encx);
|
try_forward(sss, comm, &cmn, pkt.dstMac, rec_buf, encx, from_supernode);
|
||||||
else
|
else
|
||||||
try_broadcast(sss, comm, &cmn, pkt.srcMac, rec_buf, encx);
|
try_broadcast(sss, comm, &cmn, pkt.srcMac, rec_buf, encx, from_supernode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MSG_TYPE_REGISTER:
|
case MSG_TYPE_REGISTER:
|
||||||
|
@ -1022,7 +1062,7 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
comm->header_iv_ctx,
|
comm->header_iv_ctx,
|
||||||
time_stamp (), pearson_hash_16 (rec_buf, encx));
|
time_stamp (), pearson_hash_16 (rec_buf, encx));
|
||||||
|
|
||||||
try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */
|
try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx, from_supernode); /* unicast only */
|
||||||
} else
|
} else
|
||||||
traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination");
|
traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination");
|
||||||
break;
|
break;
|
||||||
|
@ -1036,17 +1076,17 @@ 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[REG_SUPER_ACK_PAYLOAD_SPACE];
|
||||||
uint8_t *tmp_dst;
|
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;
|
||||||
int skip_add;
|
int skip_add;
|
||||||
|
|
||||||
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||||
|
@ -1117,9 +1157,9 @@ 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));
|
||||||
|
|
||||||
if(comm->is_federation == IS_FEDERATION){
|
if(comm->is_federation == IS_FEDERATION){
|
||||||
memcpy(&(ack.edgeMac), &(sss->mac_addr), sizeof(n2n_mac_t));
|
memcpy(&(ack.edgeMac), &(sss->mac_addr), sizeof(n2n_mac_t));
|
||||||
}else{
|
} else {
|
||||||
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) ||
|
if ((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xFFFFFFFF) || (reg.dev_addr.net_bitlen == 0) ||
|
||||||
|
@ -1142,7 +1182,7 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
/* 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) {
|
||||||
skip_add = NO_SKIP;
|
skip_add = SN_ADD;
|
||||||
p = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(ack.sock), &(reg.edgeMac), &skip_add);
|
p = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(ack.sock), &(reg.edgeMac), &skip_add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,8 +1192,8 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
tmp_dst = tmpbuf;
|
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(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) >= LAST_SEEN_SN_ACTIVE) 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)*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE) > REG_SUPER_ACK_PAYLOAD_SPACE) break; /* no more space available in REGISTER_SUPER_ACK payload */
|
||||||
memcpy((void*)tmp_dst, (void*)&(peer->sock), sizeof(n2n_sock_t));
|
memcpy((void*)tmp_dst, (void*)&(peer->sock), sizeof(n2n_sock_t));
|
||||||
tmp_dst += sizeof(n2n_sock_t);
|
tmp_dst += sizeof(n2n_sock_t);
|
||||||
memcpy((void*)tmp_dst, (void*)&(peer->mac_addr), sizeof(n2n_mac_t));
|
memcpy((void*)tmp_dst, (void*)&(peer->mac_addr), sizeof(n2n_mac_t));
|
||||||
|
@ -1194,19 +1234,19 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
n2n_REGISTER_SUPER_ACK_t ack;
|
n2n_REGISTER_SUPER_ACK_t ack;
|
||||||
size_t encx=0;
|
size_t encx=0;
|
||||||
struct sn_community *fed;
|
struct sn_community *fed;
|
||||||
struct peer_info *scan, *tmp_peer;
|
struct peer_info *scan, *tmp;
|
||||||
n2n_sock_str_t sockbuf1;
|
n2n_sock_str_t sockbuf1;
|
||||||
n2n_sock_str_t sockbuf2;
|
n2n_sock_str_t sockbuf2;
|
||||||
macstr_t mac_buf1;
|
macstr_t mac_buf1;
|
||||||
n2n_sock_t sender;
|
n2n_sock_t sender;
|
||||||
n2n_sock_t *orig_sender;
|
n2n_sock_t *orig_sender;
|
||||||
n2n_sock_t *tmp_sock;
|
n2n_sock_t *tmp_sock;
|
||||||
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[REG_SUPER_ACK_PAYLOAD_SPACE];
|
||||||
int skip_add;
|
int skip_add;
|
||||||
|
|
||||||
memset(&sender, 0, sizeof(n2n_sock_t));
|
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);
|
||||||
|
@ -1243,7 +1283,7 @@ 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) {
|
||||||
skip_add = SKIP;
|
skip_add = SN_ADD_SKIP;
|
||||||
scan = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &sender, &(ack.edgeMac), &skip_add);
|
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;
|
||||||
|
@ -1257,15 +1297,15 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
tmp_mac = (void*)dec_tmpbuf + 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++) {
|
||||||
skip_add = NO_SKIP;
|
skip_add = SN_ADD;
|
||||||
tmp_peer = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), tmp_sock, tmp_mac, &skip_add);
|
tmp = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), tmp_sock, tmp_mac, &skip_add);
|
||||||
|
|
||||||
if(skip_add == ADDED) {
|
if(skip_add == SN_ADD_ADDED) {
|
||||||
tmp_peer->last_seen = now - TEST_TIME;
|
tmp->last_seen = now - LAST_SEEN_SN_NEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* REVISIT: find a more elegant expression to increase following pointers. */
|
/* REVISIT: find a more elegant expression to increase following pointers. */
|
||||||
tmp_sock = (void*)tmp_sock + ENTRY_SIZE;
|
tmp_sock = (void*)tmp_sock + REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE;
|
||||||
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t);
|
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1278,10 +1318,11 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
n2n_common_t cmn2;
|
n2n_common_t cmn2;
|
||||||
n2n_PEER_INFO_t pi;
|
n2n_PEER_INFO_t pi;
|
||||||
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;
|
||||||
|
uint8_t *rec_buf; /* either udp_buf or encbuf */
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -1370,14 +1411,41 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
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,
|
if(cmn.flags & N2N_FLAGS_SOCKET){
|
||||||
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );
|
sendto_sock(sss, &query.sock, encbuf, encx);
|
||||||
|
} else {
|
||||||
traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s",
|
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 ) );
|
macaddr_str( mac_buf, query.srcMac ) );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s",
|
|
||||||
macaddr_str( mac_buf, query.targetMac ) );
|
if(from_supernode){
|
||||||
|
traceEvent( TRACE_DEBUG, "QUERY_PEER on unknown edge from supernode %s. Dropping the packet.",
|
||||||
|
macaddr_str( mac_buf, query.srcMac ) );
|
||||||
|
} else {
|
||||||
|
traceEvent( TRACE_DEBUG, "QUERY_PEER from unknown edge %s. Forwarding to all other supernodes.",
|
||||||
|
macaddr_str( mac_buf, query.srcMac ) );
|
||||||
|
|
||||||
|
memcpy(&cmn2, &cmn, sizeof(n2n_common_t));
|
||||||
|
|
||||||
|
/* We are going to add socket even if it was not there before */
|
||||||
|
cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
|
||||||
|
query.sock.family = AF_INET;
|
||||||
|
query.sock.port = ntohs(sender_sock->sin_port);
|
||||||
|
memcpy(query.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
|
||||||
|
|
||||||
|
encode_QUERY_PEER( encbuf, &encx, &cmn2, &query );
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
try_broadcast(sss, NULL, &cmn, query.srcMac, encbuf, encx, from_supernode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -410,7 +410,7 @@ int encode_REGISTER_SUPER_ACK(uint8_t *base,
|
||||||
retval += encode_uint16(base, idx, reg->lifetime);
|
retval += encode_uint16(base, idx, reg->lifetime);
|
||||||
retval += encode_sock(base, idx, &(reg->sock));
|
retval += encode_sock(base, idx, &(reg->sock));
|
||||||
retval += encode_uint8(base, idx, reg->num_sn);
|
retval += encode_uint8(base, idx, reg->num_sn);
|
||||||
retval += encode_buf(base, idx, tmpbuf, (reg->num_sn*ENTRY_SIZE));
|
retval += encode_buf(base, idx, tmpbuf, (reg->num_sn*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE));
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -436,7 +436,7 @@ int decode_REGISTER_SUPER_ACK(n2n_REGISTER_SUPER_ACK_t *reg,
|
||||||
|
|
||||||
/* Following the edge socket are an array of backup supernodes. */
|
/* Following the edge socket are an array of backup supernodes. */
|
||||||
retval += decode_uint8(&(reg->num_sn), base, rem, idx);
|
retval += decode_uint8(&(reg->num_sn), base, rem, idx);
|
||||||
retval += decode_buf(tmpbuf, (reg->num_sn*ENTRY_SIZE), base, rem, idx);
|
retval += decode_buf(tmpbuf, (reg->num_sn*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE), base, rem, idx);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user