Browse Source

Handle REGISTER_SUPER from other supernodes (#443)

* Handle REGISTER_SUPER from other supernodes

* Update wire.c
pull/445/head
francesco_carli 4 years ago
committed by GitHub
parent
commit
d9e2a0091a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      include/n2n_define.h
  2. 1
      include/n2n_wire.h
  3. 33
      src/sn_utils.c
  4. 4
      src/wire.c

10
include/n2n_define.h

@ -29,8 +29,18 @@
#define MSG_TYPE_QUERY_PEER 10 #define MSG_TYPE_QUERY_PEER 10
#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
* Field sizes of REGISTER_SUPER_ACK as used in encode/decode fucntions in src/wire.c */
#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) \
/* Space needed to store socket and MAC address of a supernode */
#define ENTRY_SIZE sizeof(n2n_sock_t)+sizeof(n2n_mac_t)
#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 TEST_TIME (SORT_COMMUNITIES_INTERVAL - ALLOWED_TIME)/2 /* sec, indicates supernodes with unsure status, must be tested to check if they are alive */
#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 */

1
include/n2n_wire.h

@ -170,6 +170,7 @@ typedef struct n2n_REGISTER_SUPER_ACK {
* even if we cannot store them all. If * even if we cannot store them all. If
* non-zero then sn_bak is valid. */ * non-zero then sn_bak is valid. */
n2n_sock_t sn_bak; /**< Socket of the first backup supernode */ n2n_sock_t sn_bak; /**< Socket of the first backup supernode */
n2n_mac_t mac_addr;
} n2n_REGISTER_SUPER_ACK_t; } n2n_REGISTER_SUPER_ACK_t;

33
src/sn_utils.c

@ -941,15 +941,25 @@ static int process_udp(n2n_sn_t * sss,
n2n_common_t cmn2; n2n_common_t cmn2;
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE]; uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
size_t encx=0; size_t encx=0;
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;
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;
n2n_sock_t *tmp_sock;
n2n_mac_t *tmp_mac;
if(from_supernode != comm->is_federation){
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER: from_supernode value doesn't correspond to the internal federation marking");
return -1;
}
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
/* Edge requesting registration with us. */ /* Edge/supernode requesting registration with us. */
sss->stats.last_reg_super=now; sss->stats.last_reg_super=now;
++(sss->stats.reg_super); ++(sss->stats.reg_super);
decode_REGISTER_SUPER(&reg, &cmn, udp_buf, &rem, &idx); decode_REGISTER_SUPER(&reg, &cmn, udp_buf, &rem, &idx);
@ -1008,6 +1018,7 @@ static int process_udp(n2n_sn_t * sss,
} }
if(comm) { if(comm) {
HASH_FIND_COMMUNITY(sss->communities, sss->federation, fed);
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;
@ -1028,9 +1039,23 @@ 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);
ack.num_sn=0; /* No backup */ if(fed != NULL){
HASH_FIND_PEER(fed->edges, reg.edgeMac, p);
p->last_seen = now;
tmp_sock = &(ack.sn_bak);
tmp_mac = &(ack.mac_addr);
HASH_ITER(hh, fed->edges, peer, tmp_peer){
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 */
memcpy(tmp_sock, &(scan->sock), sizeof(n2n_sock_t));
memcpy(tmp_mac, &(scan->mac_addr), sizeof(n2n_mac_t));
tmp_sock += sizeof(n2n_mac_t);
tmp_mac += sizeof(n2n_sock_t);
}
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)));

4
src/wire.c

@ -408,6 +408,7 @@ int encode_REGISTER_SUPER_ACK(uint8_t *base,
if (reg->num_sn > 0) { if (reg->num_sn > 0) {
/* We only support 0 or 1 at this stage */ /* We only support 0 or 1 at this stage */
retval += encode_sock(base, idx, &(reg->sn_bak)); retval += encode_sock(base, idx, &(reg->sn_bak));
retval += encode_mac(base, idx, reg->mac_addr);
} }
return retval; return retval;
@ -436,7 +437,8 @@ int decode_REGISTER_SUPER_ACK(n2n_REGISTER_SUPER_ACK_t *reg,
if (reg->num_sn > 0) { if (reg->num_sn > 0) {
/* We only support 0 or 1 at this stage */ /* We only support 0 or 1 at this stage */
retval += decode_sock(&(reg->sn_bak), base, rem, idx); retval += decode_sock(&(reg->sn_bak), base, rem, idx);
} retval += decode_mac(reg->mac_addr, base, rem, idx);
}
return retval; return retval;
} }

Loading…
Cancel
Save