Dynamically allocate memory for nodes stored in DHT in order to reduce memory usage.

This commit is contained in:
irungentoo 2016-07-11 12:30:48 -04:00
parent c7399d06a9
commit b53d6f932c
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
2 changed files with 247 additions and 111 deletions

View File

@ -388,16 +388,37 @@ static int alloc_buckets(DHT_Bucket *bucket)
unsigned int i, b0_ind = 0, b1_ind = 0;
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
if (!is_timeout(bucket->client_list[i].timestamp, BAD_NODE_TIMEOUT)) {
int bit = get_bit_at(bucket->client_list[i].public_key, bucket->deepness);
if (bucket->client_list) {
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
if (!is_timeout(bucket->client_list[i].timestamp, BAD_NODE_TIMEOUT)) {
int bit = get_bit_at(bucket->client_list[i].public_key, bucket->deepness);
if (bit == 0) {
memcpy(&b0->client_list[b0_ind], &bucket->client_list[i], sizeof(Client_data));
++b0_ind;
} else if (bit == 1) {
memcpy(&b1->client_list[b1_ind], &bucket->client_list[i], sizeof(Client_data));
++b1_ind;
if (bit == 0) {
if (!b0->client_list)
b0->client_list = calloc(DHT_BUCKET_NODES, sizeof(Client_data));
if (b0->client_list) {
memcpy(&b0->client_list[b0_ind], &bucket->client_list[i], sizeof(Client_data));
++b0_ind;
} else {
free(bucket->client_list[i].ret_ip);
bucket->client_list[i].ret_ip = 0;
}
} else if (bit == 1) {
if (!b1->client_list)
b1->client_list = calloc(DHT_BUCKET_NODES, sizeof(Client_data));
if (b1->client_list) {
memcpy(&b1->client_list[b1_ind], &bucket->client_list[i], sizeof(Client_data));
++b1_ind;
} else {
free(bucket->client_list[i].ret_ip);
bucket->client_list[i].ret_ip = 0;
}
}
} else {
free(bucket->client_list[i].ret_ip);
bucket->client_list[i].ret_ip = 0;
}
}
}
@ -420,7 +441,8 @@ static int alloc_buckets(DHT_Bucket *bucket)
bucket->public_key = 0;
bucket->friend_key = 0;
memset(bucket->client_list, 0, sizeof(bucket->client_list));
free(bucket->client_list);
bucket->client_list = 0;
return 0;
} else {
@ -430,12 +452,36 @@ static int alloc_buckets(DHT_Bucket *bucket)
}
}
static void free_client_list_ret_ips(Client_data *client_list, unsigned int length)
{
unsigned int i;
for (i = 0; i < length; ++i) {
free(client_list[i].ret_ip);
client_list[i].ret_ip = 0;
}
}
static void free_client_list(Client_data *client_list)
{
if (client_list) {
free_client_list_ret_ips(client_list, DHT_BUCKET_NODES);
free(client_list);
}
}
static void recursive_free_buckets(DHT_Bucket *bucket)
{
if (bucket) {
recursive_free_buckets(bucket->buckets[0]);
recursive_free_buckets(bucket->buckets[1]);
if (bucket->buckets[0])
free_client_list(bucket->buckets[0]->client_list);
if (bucket->buckets[1])
free_client_list(bucket->buckets[1]->client_list);
free(bucket->buckets[0]);
free(bucket->buckets[1]);
@ -449,6 +495,7 @@ static void recursive_free_buckets(DHT_Bucket *bucket)
void free_buckets(DHT_Bucket *bucket)
{
recursive_free_buckets(bucket);
free_client_list(bucket->client_list);
memset(bucket, 0, sizeof(DHT_Bucket));
}
@ -500,6 +547,18 @@ static int recursive_DHT_bucket_add_node(DHT_Bucket *bucket, const uint8_t *publ
unsigned int i, store_index = DHT_BUCKET_NODES, furthest_index = DHT_BUCKET_NODES,
furthest = crypto_box_PUBLICKEYBYTES * 8;
if (!bucket->client_list) {
if (pretend) {
return 0;
}
bucket->client_list = calloc(DHT_BUCKET_NODES, sizeof(Client_data));
}
if (!bucket->client_list) {
return -1;
}
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
Client_data *client = &bucket->client_list[i];
@ -518,6 +577,7 @@ static int recursive_DHT_bucket_add_node(DHT_Bucket *bucket, const uint8_t *publ
if (bucket->public_key) {
unsigned int dist = bit_by_bit_cmp(bucket->searched_public_key, client->public_key);
if (dist < furthest) {
furthest = dist;
furthest_index = i;
@ -538,6 +598,7 @@ static int recursive_DHT_bucket_add_node(DHT_Bucket *bucket, const uint8_t *publ
}
Client_data *client = &bucket->client_list[store_index];
free(client->ret_ip);
memset(client, 0, sizeof(Client_data));
id_copy(client->public_key, public_key);
client->ip_port = ip_port;
@ -576,6 +637,14 @@ int DHT_bucket_add_node(DHT_Bucket *bucket, const uint8_t *public_key, IP_Port i
static _Bool add_to_ret_ip_list(Client_data *client, const uint8_t *node_public_key, const uint8_t *public_key,
IP_Port ret_ip_port, uint64_t timestamp)
{
if (!client->ret_ip) {
client->ret_ip = calloc(DHT_BUCKET_NODES, sizeof(Ret_IP));
}
if (!client->ret_ip) {
return 0;
}
uint8_t pk_bak[crypto_box_PUBLICKEYBYTES];
IP_Port ip_port_bak;
uint64_t timestamp_bak;
@ -583,13 +652,13 @@ static _Bool add_to_ret_ip_list(Client_data *client, const uint8_t *node_public_
unsigned int i, length = DHT_BUCKET_NODES;
for (i = 0; i < length; ++i) {
if (id_closest(node_public_key, client->ret[i].pk, public_key) == 2) {
id_copy(pk_bak, client->ret[i].pk);
ip_port_bak = client->ret[i].ip_port;
timestamp_bak = client->ret[i].timestamp;
id_copy(client->ret[i].pk, public_key);
client->ret[i].ip_port = ret_ip_port;
client->ret[i].timestamp = timestamp;
if (id_closest(node_public_key, client->ret_ip[i].pk, public_key) == 2) {
id_copy(pk_bak, client->ret_ip[i].pk);
ip_port_bak = client->ret_ip[i].ip_port;
timestamp_bak = client->ret_ip[i].timestamp;
id_copy(client->ret_ip[i].pk, public_key);
client->ret_ip[i].ip_port = ret_ip_port;
client->ret_ip[i].timestamp = timestamp;
if (i != (length - 1))
add_to_ret_ip_list(client, node_public_key, pk_bak, ip_port_bak, timestamp_bak);
@ -612,41 +681,45 @@ static int recursive_DHT_bucket_set_node_ret_ip_port(DHT_Bucket *bucket, const u
if (bucket->empty) {
return recursive_DHT_bucket_set_node_ret_ip_port(bucket->buckets[bit], node_public_key, public_key, ret_ip_port);
} else {
unsigned int i, j;
if (bucket->client_list) {
unsigned int i, j;
for (i = 0; (i < DHT_BUCKET_NODES); ++i) {
Client_data *client = &bucket->client_list[i];
for (i = 0; (i < DHT_BUCKET_NODES); ++i) {
Client_data *client = &bucket->client_list[i];
if (!is_timeout(client->timestamp, BAD_NODE_TIMEOUT)) {
if (id_equal(client->public_key, node_public_key)) {
uint64_t smallest_timestamp = ~0;
unsigned int index_dht = DHT_BUCKET_NODES;
if (!is_timeout(client->timestamp, BAD_NODE_TIMEOUT)) {
if (id_equal(client->public_key, node_public_key)) {
uint64_t smallest_timestamp = ~0;
unsigned int index_dht = DHT_BUCKET_NODES;
for (j = 0; j < DHT_BUCKET_NODES; ++j) {
if (id_equal(public_key, client->ret[j].pk)) {
client->ret[j].ip_port = ret_ip_port;
client->ret[j].timestamp = unix_time();
return 0;
if (client->ret_ip) {
for (j = 0; j < DHT_BUCKET_NODES; ++j) {
if (id_equal(public_key, client->ret_ip[j].pk)) {
client->ret_ip[j].ip_port = ret_ip_port;
client->ret_ip[j].timestamp = unix_time();
return 0;
}
if (smallest_timestamp > client->ret_ip[j].timestamp) {
index_dht = j;
smallest_timestamp = client->ret_ip[j].timestamp;
}
}
}
if (smallest_timestamp > client->ret[j].timestamp) {
index_dht = j;
smallest_timestamp = client->ret[j].timestamp;
if (index_dht < DHT_BUCKET_NODES && is_timeout(smallest_timestamp, BAD_NODE_TIMEOUT * 2)) {
id_copy(client->ret_ip[index_dht].pk, public_key);
client->ret_ip[index_dht].ip_port = ret_ip_port;
client->ret_ip[index_dht].timestamp = unix_time();
} else {
if (add_to_ret_ip_list(client, node_public_key, public_key, ret_ip_port, unix_time()))
return 0;
return -1;
}
return 0;
}
if (index_dht < DHT_BUCKET_NODES && is_timeout(smallest_timestamp, BAD_NODE_TIMEOUT * 2)) {
id_copy(client->ret[index_dht].pk, public_key);
client->ret[index_dht].ip_port = ret_ip_port;
client->ret[index_dht].timestamp = unix_time();
} else {
if (add_to_ret_ip_list(client, node_public_key, public_key, ret_ip_port, unix_time()))
return 0;
return -1;
}
return 0;
}
}
}
@ -662,7 +735,7 @@ static int DHT_bucket_set_node_ret_ip_port(DHT_Bucket *bucket, const uint8_t *no
}
static int recursive_DHT_bucket_get_nodes(const DHT_Bucket *bucket, Client_data *nodes, unsigned int number,
const uint8_t *public_key, _Bool friend_ok)
const uint8_t *public_key, _Bool friend_ok, _Bool ret_ips)
{
int bit = get_bit_at(public_key, bucket->deepness);
@ -670,14 +743,14 @@ static int recursive_DHT_bucket_get_nodes(const DHT_Bucket *bucket, Client_data
return -1;
if (bucket->empty) {
int ret = recursive_DHT_bucket_get_nodes(bucket->buckets[bit], nodes, number, public_key, friend_ok);
int ret = recursive_DHT_bucket_get_nodes(bucket->buckets[bit], nodes, number, public_key, friend_ok, ret_ips);
if (ret < 0)
return -1;
if (ret < number) {
number -= ret;
int ret1 = recursive_DHT_bucket_get_nodes(bucket->buckets[!bit], nodes, number, public_key, friend_ok);
int ret1 = recursive_DHT_bucket_get_nodes(bucket->buckets[!bit], nodes, number, public_key, friend_ok, ret_ips);
if (ret < 0)
return -1;
@ -693,10 +766,23 @@ static int recursive_DHT_bucket_get_nodes(const DHT_Bucket *bucket, Client_data
unsigned int i, counter = 0;
for (i = 0; (i < DHT_BUCKET_NODES) && (counter < number); ++i) {
if (!is_timeout(bucket->client_list[i].timestamp, BAD_NODE_TIMEOUT)) {
memcpy(&nodes[number - (counter + 1)], &bucket->client_list[i], sizeof(Client_data));
++counter;
if (bucket->client_list) {
for (i = 0; (i < DHT_BUCKET_NODES) && (counter < number); ++i) {
if (!is_timeout(bucket->client_list[i].timestamp, BAD_NODE_TIMEOUT)) {
memcpy(&nodes[number - (counter + 1)], &bucket->client_list[i], sizeof(Client_data));
if (ret_ips && nodes[number - (counter + 1)].ret_ip) {
Ret_IP *ret_ip = nodes[number - (counter + 1)].ret_ip;
nodes[number - (counter + 1)].ret_ip = calloc(DHT_BUCKET_NODES, sizeof(Ret_IP));
if (nodes[number - (counter + 1)].ret_ip)
memcpy(nodes[number - (counter + 1)].ret_ip, ret_ip, DHT_BUCKET_NODES * sizeof(Ret_IP));
} else {
nodes[number - (counter + 1)].ret_ip = 0;
}
++counter;
}
}
}
@ -706,9 +792,12 @@ static int recursive_DHT_bucket_get_nodes(const DHT_Bucket *bucket, Client_data
int DHT_bucket_get_nodes(const DHT_Bucket *bucket, Client_data *nodes, unsigned int number, const uint8_t *public_key,
_Bool friend_ok)
_Bool friend_ok, _Bool ret_ips)
{
return recursive_DHT_bucket_get_nodes(bucket, nodes, number, public_key, friend_ok);
if (!nodes)
return -1;
return recursive_DHT_bucket_get_nodes(bucket, nodes, number, public_key, friend_ok, ret_ips);
}
static int dealloc_buckets(DHT_Bucket *bucket)
@ -724,7 +813,7 @@ static int dealloc_buckets(DHT_Bucket *bucket)
/* pk doesn't matter, want any nodes from both lower buckets. */
uint8_t pk[crypto_box_PUBLICKEYBYTES] = {0};
int ret = recursive_DHT_bucket_get_nodes(bucket, bucket->client_list, DHT_BUCKET_NODES, pk, 1);
int ret = recursive_DHT_bucket_get_nodes(bucket, bucket->client_list, DHT_BUCKET_NODES, pk, 1, 1);
recursive_free_buckets(bucket);
bucket->empty = 0;
@ -796,15 +885,17 @@ static int recursive_do_ping_nodes(DHT *dht, DHT_Bucket *bucket, uint8_t *key)
search_key = bucket->searched_public_key;
}
unsigned int i;
if (bucket->client_list) {
unsigned int i;
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
Client_data *client = &bucket->client_list[i];
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
Client_data *client = &bucket->client_list[i];
if (!is_timeout(client->timestamp, BAD_NODE_TIMEOUT)) {
if (is_timeout(client->last_pinged, PING_INTERVAL)) {
getnodes(dht, client->ip_port, client->public_key, search_key, NULL);
client->last_pinged = unix_time();
if (!is_timeout(client->timestamp, BAD_NODE_TIMEOUT)) {
if (is_timeout(client->last_pinged, PING_INTERVAL)) {
getnodes(dht, client->ip_port, client->public_key, search_key, NULL);
client->last_pinged = unix_time();
}
}
}
}
@ -830,9 +921,9 @@ static int do_ping_nodes(DHT *dht, DHT_Bucket *bucket)
* return 1 if true.
* return 0 if false.
*/
static int client_in_nodelist(const Node_format *list, uint16_t length, const uint8_t *public_key)
_Bool client_in_nodelist(const Node_format *list, uint16_t length, const uint8_t *public_key)
{
uint32_t i;
unsigned int i;
for (i = 0; i < length; ++i) {
if (id_equal(list[i].public_key, public_key))
@ -847,7 +938,7 @@ static int client_in_nodelist(const Node_format *list, uint16_t length, const ui
*/
static int friend_number(const DHT *dht, const uint8_t *public_key)
{
uint32_t i;
unsigned int i;
for (i = 0; i < dht->num_friends; ++i) {
if (id_equal(dht->friends_list[i].public_key, public_key))
@ -892,21 +983,21 @@ int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *node
Client_data client_data[DHT_BUCKET_NODES * 3] = {0};
if (sa_family == AF_INET) {
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, 0, 0);
} else if (sa_family == AF_INET6) {
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0, 0);
} else {
if (rand() % 2) {
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, 0, 0);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0, 0);
} else {
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, DHT_BUCKET_NODES, public_key, 0, 0);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0, 0);
}
}
if (is_LAN) {
DHT_bucket_get_nodes(&dht->bucket_lan, client_data + (DHT_BUCKET_NODES * 2), DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_lan, client_data + (DHT_BUCKET_NODES * 2), DHT_BUCKET_NODES, public_key, 0, 0);
}
unsigned int i, num_nodes = 0;
@ -1461,14 +1552,14 @@ int DHT_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port)
return -1;
if (rand() % 2) {
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, 1);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 1);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, 1, 0);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 1, 0);
} else {
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, DHT_BUCKET_NODES, public_key, 1);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 1);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, DHT_BUCKET_NODES, public_key, 1, 0);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 1, 0);
}
DHT_bucket_get_nodes(&dht->bucket_lan, client_data + (DHT_BUCKET_NODES * 2), DHT_BUCKET_NODES, public_key, 1);
DHT_bucket_get_nodes(&dht->bucket_lan, client_data + (DHT_BUCKET_NODES * 2), DHT_BUCKET_NODES, public_key, 1, 0);
unsigned int i;
@ -1534,9 +1625,9 @@ int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packe
if (friend_number(dht, public_key) == -1)
return -1;
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_lan, client_data + (DHT_BUCKET_NODES * 2), DHT_BUCKET_NODES, public_key, 0);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, 0, 0);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0, 0);
DHT_bucket_get_nodes(&dht->bucket_lan, client_data + (DHT_BUCKET_NODES * 2), DHT_BUCKET_NODES, public_key, 0, 0);
unsigned int i;
@ -1555,11 +1646,13 @@ static _Bool get_ret_ip_port(Client_data *client, const uint8_t *public_key, IP_
{
unsigned int i;
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
if (client->ret[i].timestamp != 0 && !is_timeout(client->ret[i].timestamp, BAD_NODE_TIMEOUT * 2)
&& id_equal(client->ret[i].pk, public_key)) {
*ip_port = client->ret[i].ip_port;
return 1;
if (client->ret_ip) {
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
if (client->ret_ip[i].timestamp != 0 && !is_timeout(client->ret_ip[i].timestamp, BAD_NODE_TIMEOUT * 2)
&& id_equal(client->ret_ip[i].pk, public_key)) {
*ip_port = client->ret_ip[i].ip_port;
return 1;
}
}
}
@ -1590,7 +1683,7 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n
bucket = &dht->bucket_v4;
}
DHT_bucket_get_nodes(bucket, client_data, (DHT_BUCKET_NODES * 2), friend->public_key, 1);
DHT_bucket_get_nodes(bucket, client_data, (DHT_BUCKET_NODES * 2), friend->public_key, 1, 1);
unsigned int i, count = 0;
IP_Port ip_ports[(DHT_BUCKET_NODES * 2)];
@ -1599,14 +1692,17 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n
unsigned int index = i - 1;
if (client_data[index].timestamp != 0) {
if (id_equal(client_data[index].public_key, friend->public_key))
return 0;
if (id_equal(client_data[index].public_key, friend->public_key)) {
count = 0;
break;
}
if (get_ret_ip_port(&client_data[index], friend->public_key, &ip_ports[count]))
++count;
}
}
free_client_list_ret_ips(client_data, (DHT_BUCKET_NODES * 2));
memcpy(ip_portlist, ip_ports, sizeof(IP_Port) * count);
return count;
}
@ -1627,10 +1723,10 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_pk, const uint8_t *pack
if (friend_number(dht, friend_pk) == -1)
return 0;
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, (DHT_BUCKET_NODES * 2), friend_pk, 1);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + (DHT_BUCKET_NODES * 2), (DHT_BUCKET_NODES * 2), friend_pk, 1);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, (DHT_BUCKET_NODES * 2), friend_pk, 1, 1);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + (DHT_BUCKET_NODES * 2), (DHT_BUCKET_NODES * 2), friend_pk, 1, 1);
DHT_bucket_get_nodes(&dht->bucket_lan, client_data + ((DHT_BUCKET_NODES * 2) * 2), (DHT_BUCKET_NODES * 2), friend_pk,
1);
1, 1);
unsigned int i, count = 0, r = rand();
@ -1648,19 +1744,19 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_pk, const uint8_t *pack
}
}
if (count != num_to_send)
return 0;
unsigned int sent = 0;
for (i = 0; i < count; ++i) {
int retval = sendpacket(dht->net, ip_ports[i], packet, length);
if (count == num_to_send) {
for (i = 0; i < count; ++i) {
int retval = sendpacket(dht->net, ip_ports[i], packet, length);
if ((unsigned int)retval == length) {
++sent;
if ((unsigned int)retval == length) {
++sent;
}
}
}
free_client_list_ret_ips(client_data, (DHT_BUCKET_NODES * 2) * 3);
return sent;
}
@ -1903,11 +1999,11 @@ static uint16_t list_nodes(const DHT *dht, uint8_t *public_key, Node_format *nod
Client_data client_data[DHT_BUCKET_NODES * 2] = {0};
if (rand() % 2) {
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, friend_ok);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, friend_ok);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, DHT_BUCKET_NODES, public_key, friend_ok, 0);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, friend_ok, 0);
} else {
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, DHT_BUCKET_NODES, public_key, friend_ok);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, friend_ok);
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, DHT_BUCKET_NODES, public_key, friend_ok, 0);
DHT_bucket_get_nodes(&dht->bucket_v4, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, friend_ok, 0);
}
unsigned int i, num_nodes = 0, r = rand();
@ -2301,10 +2397,10 @@ int DHT_non_lan_connected(const DHT *dht)
{
Client_data cd;
if (DHT_bucket_get_nodes(&dht->bucket_v4, &cd, 1, dht->self_public_key, 1) == 1)
if (DHT_bucket_get_nodes(&dht->bucket_v4, &cd, 1, dht->self_public_key, 1, 0) == 1)
return 1;
if (DHT_bucket_get_nodes(&dht->bucket_v6, &cd, 1, dht->self_public_key, 1) == 1)
if (DHT_bucket_get_nodes(&dht->bucket_v6, &cd, 1, dht->self_public_key, 1, 0) == 1)
return 1;
return 0;
@ -2322,7 +2418,7 @@ int DHT_isconnected(const DHT *dht)
Client_data cd;
if (DHT_bucket_get_nodes(&dht->bucket_lan, &cd, 1, dht->self_public_key, 1) == 1)
if (DHT_bucket_get_nodes(&dht->bucket_lan, &cd, 1, dht->self_public_key, 1, 0) == 1)
return 1;
return 0;

View File

@ -67,6 +67,13 @@ void to_net_family(IP *ip);
/* return 0 on success, -1 on failure. */
int to_host_family(IP *ip);
typedef struct {
uint8_t pk[crypto_box_PUBLICKEYBYTES];
IP_Port ip_port;
uint64_t timestamp;
} Ret_IP;
typedef struct {
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
@ -74,11 +81,7 @@ typedef struct {
uint64_t timestamp;
uint64_t last_pinged;
struct {
uint8_t pk[crypto_box_PUBLICKEYBYTES];
IP_Port ip_port;
uint64_t timestamp;
} ret[DHT_BUCKET_NODES];
Ret_IP *ret_ip;
} Client_data;
@ -112,7 +115,7 @@ typedef struct DHT_Bucket {
_Bool friend_key;
uint8_t searched_public_key[crypto_box_PUBLICKEYBYTES];
Client_data client_list[DHT_BUCKET_NODES];
Client_data *client_list;
struct DHT_Bucket *buckets[2];
} DHT_Bucket;
@ -230,6 +233,43 @@ typedef struct {
} DHT;
/*----------------------------------------------------------------------------------*/
/* Check if client with public_key is already in node format list of length length.
*
* return 1 if true.
* return 0 if false.
*/
_Bool client_in_nodelist(const Node_format *list, uint16_t length, const uint8_t *public_key);
/* Get number nodes from bucket closest to public_key.
*
* Return number of nodes put in nodes.
* Return -1 on failure, 0 if bucket is empty.
*/
int DHT_bucket_get_nodes(const DHT_Bucket *bucket, Client_data *nodes, unsigned int number, const uint8_t *public_key,
_Bool friend_ok, _Bool ret_ips);
/* Add a search key to the DHT bucket.
*
* Return 0 on success.
* Return -1 on failure.
*/
int DHT_bucket_add_key(DHT_Bucket *bucket, const uint8_t *public_key, _Bool friend_key);
/* Add a node to the DHT bucket. pretend can be set to true in order to see if a node will be added and not discarded.
*
* Return 0 on success.
* Return -1 on failure.
*/
int DHT_bucket_add_node(DHT_Bucket *bucket, const uint8_t *public_key, IP_Port ip_port, _Bool pretend);
/* Free the bucket structure.
*/
void free_buckets(DHT_Bucket *bucket);
/*----------------------------------------------------------------------------------*/
/* Shared key generations are costly, it is therefor smart to store commonly used
* ones so that they can re used later without being computed again.
*