|
@ -455,6 +455,27 @@ static int update_edge (n2n_sn_t *sss, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** checks if a certain ip address is still available, i.e. not used by any other edge of a given community */ |
|
|
|
|
|
static int ip_addr_available (struct sn_community *comm, n2n_ip_subnet_t *ip_addr) { |
|
|
|
|
|
|
|
|
|
|
|
int success = 1; |
|
|
|
|
|
struct peer_info *peer, *tmp_peer; |
|
|
|
|
|
|
|
|
|
|
|
// prerequisite: list of peers is sorted according to peer's tap ip address
|
|
|
|
|
|
HASH_ITER(hh, comm->edges, peer, tmp_peer) { |
|
|
|
|
|
if(peer->dev_addr.net_addr > ip_addr->net_addr) { |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
if(peer->dev_addr.net_addr == ip_addr->net_addr) { |
|
|
|
|
|
success = 0; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return success; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static signed int peer_tap_ip_sort (struct peer_info *a, struct peer_info *b) { |
|
|
static signed int peer_tap_ip_sort (struct peer_info *a, struct peer_info *b) { |
|
|
|
|
|
|
|
|
uint32_t a_host_id = a->dev_addr.net_addr & (~bitlen2mask(a->dev_addr.net_bitlen)); |
|
|
uint32_t a_host_id = a->dev_addr.net_addr & (~bitlen2mask(a->dev_addr.net_bitlen)); |
|
@ -465,40 +486,54 @@ static signed int peer_tap_ip_sort (struct peer_info *a, struct peer_info *b) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** The IP address assigned to the edge by the auto ip address function of sn. */ |
|
|
/** The IP address assigned to the edge by the auto ip address function of sn. */ |
|
|
static int assign_one_ip_addr (struct sn_community *comm, |
|
|
static int assign_one_ip_addr (struct sn_community *comm, n2n_desc_t dev_desc, n2n_ip_subnet_t *ip_addr) { |
|
|
n2n_ip_subnet_t *ipaddr) { |
|
|
|
|
|
|
|
|
|
|
|
struct peer_info *peer, *tmpPeer; |
|
|
struct peer_info *peer, *tmp_peer; |
|
|
uint32_t net_id, mask, max_host, host_id = 1; |
|
|
uint32_t tmp, success, net_id, mask, max_host, host_id = 1; |
|
|
dec_ip_bit_str_t ip_bit_str = {'\0'}; |
|
|
dec_ip_bit_str_t ip_bit_str = {'\0'}; |
|
|
|
|
|
|
|
|
mask = bitlen2mask(comm->auto_ip_net.net_bitlen); |
|
|
mask = bitlen2mask(comm->auto_ip_net.net_bitlen); |
|
|
net_id = comm->auto_ip_net.net_addr & mask; |
|
|
net_id = comm->auto_ip_net.net_addr & mask; |
|
|
max_host = ~mask; |
|
|
max_host = ~mask; |
|
|
|
|
|
|
|
|
|
|
|
// sorting is a prerequisite for more efficient availabilitiy check
|
|
|
HASH_SORT(comm->edges, peer_tap_ip_sort); |
|
|
HASH_SORT(comm->edges, peer_tap_ip_sort); |
|
|
HASH_ITER(hh, comm->edges, peer, tmpPeer) { |
|
|
|
|
|
if((peer->dev_addr.net_addr & bitlen2mask(peer->dev_addr.net_bitlen)) == net_id) { |
|
|
// first proposal derived from hash of mac address
|
|
|
if(host_id >= max_host) { |
|
|
tmp = pearson_hash_32(dev_desc, sizeof(n2n_desc_t)) & max_host; |
|
|
traceEvent(TRACE_WARNING, "No assignable IP to edge tap adapter."); |
|
|
if(tmp == 0) tmp++; /* avoid 0 host */ |
|
|
return -1; |
|
|
if(tmp == max_host) tmp--; /* avoid broadcast address */ |
|
|
|
|
|
tmp |= net_id; |
|
|
|
|
|
|
|
|
|
|
|
// candidate
|
|
|
|
|
|
ip_addr->net_bitlen = comm->auto_ip_net.net_bitlen; |
|
|
|
|
|
|
|
|
|
|
|
// check for availability starting from proposal, then downwards, ...
|
|
|
|
|
|
for(host_id = tmp; host_id > net_id; host_id--) { |
|
|
|
|
|
ip_addr->net_addr = host_id; |
|
|
|
|
|
success = ip_addr_available(comm, ip_addr); |
|
|
|
|
|
if(success) { |
|
|
|
|
|
break; |
|
|
} |
|
|
} |
|
|
if(peer->dev_addr.net_addr == 0) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
} |
|
|
if((peer->dev_addr.net_addr & max_host) == host_id) { |
|
|
// ... then upwards
|
|
|
++host_id; |
|
|
if(!success) { |
|
|
} else { |
|
|
for(host_id = tmp + 1; host_id < (net_id + max_host); host_id++) { |
|
|
|
|
|
ip_addr->net_addr = host_id; |
|
|
|
|
|
success = ip_addr_available(comm, ip_addr); |
|
|
|
|
|
if(success) { |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
ipaddr->net_addr = net_id | host_id; |
|
|
|
|
|
ipaddr->net_bitlen = comm->auto_ip_net.net_bitlen; |
|
|
|
|
|
|
|
|
|
|
|
traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ipaddr)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(success) { |
|
|
|
|
|
traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ip_addr)); |
|
|
return 0; |
|
|
return 0; |
|
|
|
|
|
} else { |
|
|
|
|
|
traceEvent(TRACE_WARNING, "No assignable IP to edge tap adapter."); |
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1234,7 +1269,7 @@ static int process_udp (n2n_sn_t * sss, |
|
|
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)); |
|
|
assign_one_ip_addr(comm, &ipaddr); |
|
|
assign_one_ip_addr(comm, reg.dev_desc, &ipaddr); |
|
|
ack.dev_addr.net_addr = ipaddr.net_addr; |
|
|
ack.dev_addr.net_addr = ipaddr.net_addr; |
|
|
ack.dev_addr.net_bitlen = ipaddr.net_bitlen; |
|
|
ack.dev_addr.net_bitlen = ipaddr.net_bitlen; |
|
|
} |
|
|
} |
|
|