Same chance to all supernodes to be transmitted by REGISTER_SUPER_ACK (#498)

* Same chance for all supernodes to be transmitted with REG_SUPER_ACK

* Update sn_utils.c

* Update random_numbers.h

* Update sn_utils.c

* Update random_numbers.c

* Update sn_utils.c

* Update sn_utils.c
This commit is contained in:
Francesco Carli 2020-11-13 22:12:04 +01:00 committed by GitHub
parent 08ef50e7fc
commit 01f09e693e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 17 deletions

View File

@ -64,5 +64,7 @@ uint64_t n2n_rand ();
uint64_t n2n_seed ();
uint32_t n2n_rand_sqr (uint32_t max_n);
#endif // RND_H

View File

@ -172,3 +172,59 @@ uint64_t n2n_seed (void) {
return ret;
}
/* an integer squrare root approximation
* from https://stackoverflow.com/a/1100591. */
static int ftbl [33] = {0,1,1,2,2,4,5,8,11,16,22,32,45,64,90,128,181,256,362,512,724,1024,1448,2048,2896,4096,5792,8192,11585,16384,23170,32768,46340};
static int ftbl2[32] = { 32768,33276,33776,34269,34755,35235,35708,36174,36635,37090,37540,37984,38423,38858,39287,39712,40132,40548,40960,41367,41771,42170,42566,42959,43347,43733,44115,44493,44869,45241,45611,45977};
static int i_sqrt(int val) {
int cnt = 0;
int t = val;
while(t) {
cnt++;
t>>=1;
}
if(6 >= cnt)
t = (val << (6-cnt));
else
t = (val >> (cnt-6));
return (ftbl[cnt] * ftbl2[t & 31]) >> 15;
}
static int32_t int_sqrt(int val) {
int ret;
ret = i_sqrt (val);
ret += i_sqrt (val - ret * ret) / 16;
return ret;
}
// returns a random number from [0, max_n] with higher probability towards the borders
uint32_t n2n_rand_sqr (uint32_t max_n) {
uint32_t raw_max = 0;
uint32_t raw_rnd = 0;
int32_t ret = 0;
raw_max = (max_n+2) * (max_n+2);
raw_rnd = n2n_rand() % (raw_max);
ret = int_sqrt(raw_rnd) / 2;
ret = (raw_rnd & 1) ? ret : -ret;
ret = max_n / 2 + ret;
if (ret < 0) ret = 0;
if (ret > max_n) ret = max_n;
return ret;
}

View File

@ -120,9 +120,7 @@ static int try_forward(n2n_sn_t * sss,
if(!from_supernode){
/* Forwarding packet to all federated supernodes. */
traceEvent(TRACE_DEBUG, "Unknown MAC. Broadcasting packet to all federated supernodes.");
try_broadcast(sss, NULL, cmn, sss->mac_addr, from_supernode, pktbuf, pktsize);
} else {
traceEvent(TRACE_DEBUG, "try_forward unknown MAC. Dropping the packet.");
/* Not a known MAC so drop. */
@ -385,7 +383,7 @@ static int update_edge(n2n_sn_t *sss,
}
}
}
if (NULL == scan) {
/* Not known */
@ -734,7 +732,7 @@ static int process_mgmt(n2n_sn_t *sss,
}
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"----------------------------------------------------------------------------------------------------\n");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"uptime %lu | ", (now - sss->start_time));
@ -814,7 +812,7 @@ static int process_udp(n2n_sn_t * sss,
n2n_sock_str_t sockbuf;
char buf[32];
struct sn_community *comm, *tmp;
uint64_t stamp;
uint64_t stamp;
const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0}; /* 00:00:00:00:00:00 */
traceEvent(TRACE_DEBUG, "Processing incoming UDP packet [len: %lu][sender: %s:%u]",
@ -1192,8 +1190,8 @@ static int process_udp(n2n_sn_t * sss,
/* Skip random numbers of supernodes before payload assembling, calculating an appropriate random_number.
* That way, all supernodes have a chance to be propagated with REGISTER_SUPER_ACK. */
skip = HASH_COUNT(sss->federation->edges) - (int)(REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE / REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE);
skip = (skip < 0) ? 0 : n2n_rand() % (skip +1);
skip = HASH_COUNT(sss->federation->edges) - (int)(REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE / REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE);
skip = (skip < 0) ? 0 : n2n_rand_sqr(skip);
/* Assembling supernode list for REGISTER_SUPER_ACK payload */
tmp_dst = tmpbuf;
@ -1249,19 +1247,19 @@ static int process_udp(n2n_sn_t * sss,
n2n_REGISTER_SUPER_ACK_t ack;
size_t encx=0;
struct sn_community *fed;
struct peer_info *scan, *tmp;
n2n_sock_str_t sockbuf1;
n2n_sock_str_t sockbuf2;
macstr_t mac_buf1;
n2n_sock_t sender;
n2n_sock_t *orig_sender;
n2n_REGISTER_SUPER_ACK_payload_t *payload;
int i;
uint8_t dec_tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE];
struct peer_info *scan, *tmp;
n2n_sock_str_t sockbuf1;
n2n_sock_str_t sockbuf2;
macstr_t mac_buf1;
n2n_sock_t sender;
n2n_sock_t *orig_sender;
n2n_sock_t *tmp_sock;
n2n_mac_t *tmp_mac;
int i;
uint8_t dec_tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE];
int skip_add;
memset(&sender, 0, sizeof(n2n_sock_t));
sender.family = AF_INET;
sender.port = ntohs(sender_sock->sin_port);
memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE);