mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Dynamically allocate memory for nodes stored in DHT in order to reduce memory usage.
This commit is contained in:
parent
c7399d06a9
commit
b53d6f932c
306
toxcore/DHT.c
306
toxcore/DHT.c
|
@ -388,16 +388,37 @@ static int alloc_buckets(DHT_Bucket *bucket)
|
||||||
|
|
||||||
unsigned int i, b0_ind = 0, b1_ind = 0;
|
unsigned int i, b0_ind = 0, b1_ind = 0;
|
||||||
|
|
||||||
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
|
if (bucket->client_list) {
|
||||||
if (!is_timeout(bucket->client_list[i].timestamp, BAD_NODE_TIMEOUT)) {
|
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
|
||||||
int bit = get_bit_at(bucket->client_list[i].public_key, bucket->deepness);
|
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) {
|
if (bit == 0) {
|
||||||
memcpy(&b0->client_list[b0_ind], &bucket->client_list[i], sizeof(Client_data));
|
if (!b0->client_list)
|
||||||
++b0_ind;
|
b0->client_list = calloc(DHT_BUCKET_NODES, sizeof(Client_data));
|
||||||
} else if (bit == 1) {
|
|
||||||
memcpy(&b1->client_list[b1_ind], &bucket->client_list[i], sizeof(Client_data));
|
if (b0->client_list) {
|
||||||
++b1_ind;
|
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->public_key = 0;
|
||||||
bucket->friend_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;
|
return 0;
|
||||||
} else {
|
} 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)
|
static void recursive_free_buckets(DHT_Bucket *bucket)
|
||||||
{
|
{
|
||||||
if (bucket) {
|
if (bucket) {
|
||||||
recursive_free_buckets(bucket->buckets[0]);
|
recursive_free_buckets(bucket->buckets[0]);
|
||||||
recursive_free_buckets(bucket->buckets[1]);
|
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[0]);
|
||||||
free(bucket->buckets[1]);
|
free(bucket->buckets[1]);
|
||||||
|
|
||||||
|
@ -449,6 +495,7 @@ static void recursive_free_buckets(DHT_Bucket *bucket)
|
||||||
void free_buckets(DHT_Bucket *bucket)
|
void free_buckets(DHT_Bucket *bucket)
|
||||||
{
|
{
|
||||||
recursive_free_buckets(bucket);
|
recursive_free_buckets(bucket);
|
||||||
|
free_client_list(bucket->client_list);
|
||||||
memset(bucket, 0, sizeof(DHT_Bucket));
|
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,
|
unsigned int i, store_index = DHT_BUCKET_NODES, furthest_index = DHT_BUCKET_NODES,
|
||||||
furthest = crypto_box_PUBLICKEYBYTES * 8;
|
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) {
|
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
|
||||||
Client_data *client = &bucket->client_list[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) {
|
if (bucket->public_key) {
|
||||||
unsigned int dist = bit_by_bit_cmp(bucket->searched_public_key, client->public_key);
|
unsigned int dist = bit_by_bit_cmp(bucket->searched_public_key, client->public_key);
|
||||||
|
|
||||||
if (dist < furthest) {
|
if (dist < furthest) {
|
||||||
furthest = dist;
|
furthest = dist;
|
||||||
furthest_index = i;
|
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];
|
Client_data *client = &bucket->client_list[store_index];
|
||||||
|
free(client->ret_ip);
|
||||||
memset(client, 0, sizeof(Client_data));
|
memset(client, 0, sizeof(Client_data));
|
||||||
id_copy(client->public_key, public_key);
|
id_copy(client->public_key, public_key);
|
||||||
client->ip_port = ip_port;
|
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,
|
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)
|
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];
|
uint8_t pk_bak[crypto_box_PUBLICKEYBYTES];
|
||||||
IP_Port ip_port_bak;
|
IP_Port ip_port_bak;
|
||||||
uint64_t timestamp_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;
|
unsigned int i, length = DHT_BUCKET_NODES;
|
||||||
|
|
||||||
for (i = 0; i < length; ++i) {
|
for (i = 0; i < length; ++i) {
|
||||||
if (id_closest(node_public_key, client->ret[i].pk, public_key) == 2) {
|
if (id_closest(node_public_key, client->ret_ip[i].pk, public_key) == 2) {
|
||||||
id_copy(pk_bak, client->ret[i].pk);
|
id_copy(pk_bak, client->ret_ip[i].pk);
|
||||||
ip_port_bak = client->ret[i].ip_port;
|
ip_port_bak = client->ret_ip[i].ip_port;
|
||||||
timestamp_bak = client->ret[i].timestamp;
|
timestamp_bak = client->ret_ip[i].timestamp;
|
||||||
id_copy(client->ret[i].pk, public_key);
|
id_copy(client->ret_ip[i].pk, public_key);
|
||||||
client->ret[i].ip_port = ret_ip_port;
|
client->ret_ip[i].ip_port = ret_ip_port;
|
||||||
client->ret[i].timestamp = timestamp;
|
client->ret_ip[i].timestamp = timestamp;
|
||||||
|
|
||||||
if (i != (length - 1))
|
if (i != (length - 1))
|
||||||
add_to_ret_ip_list(client, node_public_key, pk_bak, ip_port_bak, timestamp_bak);
|
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) {
|
if (bucket->empty) {
|
||||||
return recursive_DHT_bucket_set_node_ret_ip_port(bucket->buckets[bit], node_public_key, public_key, ret_ip_port);
|
return recursive_DHT_bucket_set_node_ret_ip_port(bucket->buckets[bit], node_public_key, public_key, ret_ip_port);
|
||||||
} else {
|
} else {
|
||||||
unsigned int i, j;
|
if (bucket->client_list) {
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0; (i < DHT_BUCKET_NODES); ++i) {
|
for (i = 0; (i < DHT_BUCKET_NODES); ++i) {
|
||||||
Client_data *client = &bucket->client_list[i];
|
Client_data *client = &bucket->client_list[i];
|
||||||
|
|
||||||
if (!is_timeout(client->timestamp, BAD_NODE_TIMEOUT)) {
|
if (!is_timeout(client->timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
if (id_equal(client->public_key, node_public_key)) {
|
if (id_equal(client->public_key, node_public_key)) {
|
||||||
uint64_t smallest_timestamp = ~0;
|
uint64_t smallest_timestamp = ~0;
|
||||||
unsigned int index_dht = DHT_BUCKET_NODES;
|
unsigned int index_dht = DHT_BUCKET_NODES;
|
||||||
|
|
||||||
for (j = 0; j < DHT_BUCKET_NODES; ++j) {
|
if (client->ret_ip) {
|
||||||
if (id_equal(public_key, client->ret[j].pk)) {
|
for (j = 0; j < DHT_BUCKET_NODES; ++j) {
|
||||||
client->ret[j].ip_port = ret_ip_port;
|
if (id_equal(public_key, client->ret_ip[j].pk)) {
|
||||||
client->ret[j].timestamp = unix_time();
|
client->ret_ip[j].ip_port = ret_ip_port;
|
||||||
return 0;
|
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) {
|
if (index_dht < DHT_BUCKET_NODES && is_timeout(smallest_timestamp, BAD_NODE_TIMEOUT * 2)) {
|
||||||
index_dht = j;
|
id_copy(client->ret_ip[index_dht].pk, public_key);
|
||||||
smallest_timestamp = client->ret[j].timestamp;
|
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,
|
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);
|
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;
|
return -1;
|
||||||
|
|
||||||
if (bucket->empty) {
|
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)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ret < number) {
|
if (ret < number) {
|
||||||
number -= ret;
|
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)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -693,10 +766,23 @@ static int recursive_DHT_bucket_get_nodes(const DHT_Bucket *bucket, Client_data
|
||||||
|
|
||||||
unsigned int i, counter = 0;
|
unsigned int i, counter = 0;
|
||||||
|
|
||||||
for (i = 0; (i < DHT_BUCKET_NODES) && (counter < number); ++i) {
|
if (bucket->client_list) {
|
||||||
if (!is_timeout(bucket->client_list[i].timestamp, BAD_NODE_TIMEOUT)) {
|
for (i = 0; (i < DHT_BUCKET_NODES) && (counter < number); ++i) {
|
||||||
memcpy(&nodes[number - (counter + 1)], &bucket->client_list[i], sizeof(Client_data));
|
if (!is_timeout(bucket->client_list[i].timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
++counter;
|
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,
|
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)
|
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. */
|
/* pk doesn't matter, want any nodes from both lower buckets. */
|
||||||
uint8_t pk[crypto_box_PUBLICKEYBYTES] = {0};
|
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);
|
recursive_free_buckets(bucket);
|
||||||
bucket->empty = 0;
|
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;
|
search_key = bucket->searched_public_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int i;
|
if (bucket->client_list) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
|
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
|
||||||
Client_data *client = &bucket->client_list[i];
|
Client_data *client = &bucket->client_list[i];
|
||||||
|
|
||||||
if (!is_timeout(client->timestamp, BAD_NODE_TIMEOUT)) {
|
if (!is_timeout(client->timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
if (is_timeout(client->last_pinged, PING_INTERVAL)) {
|
if (is_timeout(client->last_pinged, PING_INTERVAL)) {
|
||||||
getnodes(dht, client->ip_port, client->public_key, search_key, NULL);
|
getnodes(dht, client->ip_port, client->public_key, search_key, NULL);
|
||||||
client->last_pinged = unix_time();
|
client->last_pinged = unix_time();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -830,9 +921,9 @@ static int do_ping_nodes(DHT *dht, DHT_Bucket *bucket)
|
||||||
* return 1 if true.
|
* return 1 if true.
|
||||||
* return 0 if false.
|
* 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) {
|
for (i = 0; i < length; ++i) {
|
||||||
if (id_equal(list[i].public_key, public_key))
|
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)
|
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) {
|
for (i = 0; i < dht->num_friends; ++i) {
|
||||||
if (id_equal(dht->friends_list[i].public_key, public_key))
|
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};
|
Client_data client_data[DHT_BUCKET_NODES * 3] = {0};
|
||||||
|
|
||||||
if (sa_family == AF_INET) {
|
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) {
|
} 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 {
|
} else {
|
||||||
if (rand() % 2) {
|
if (rand() % 2) {
|
||||||
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);
|
||||||
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 {
|
} else {
|
||||||
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, 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);
|
DHT_bucket_get_nodes(&dht->bucket_v4, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_LAN) {
|
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;
|
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;
|
return -1;
|
||||||
|
|
||||||
if (rand() % 2) {
|
if (rand() % 2) {
|
||||||
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, 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);
|
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, 1, 0);
|
||||||
} else {
|
} else {
|
||||||
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, 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);
|
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;
|
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)
|
if (friend_number(dht, public_key) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
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);
|
||||||
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);
|
||||||
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;
|
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;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
|
if (client->ret_ip) {
|
||||||
if (client->ret[i].timestamp != 0 && !is_timeout(client->ret[i].timestamp, BAD_NODE_TIMEOUT * 2)
|
for (i = 0; i < DHT_BUCKET_NODES; ++i) {
|
||||||
&& id_equal(client->ret[i].pk, public_key)) {
|
if (client->ret_ip[i].timestamp != 0 && !is_timeout(client->ret_ip[i].timestamp, BAD_NODE_TIMEOUT * 2)
|
||||||
*ip_port = client->ret[i].ip_port;
|
&& id_equal(client->ret_ip[i].pk, public_key)) {
|
||||||
return 1;
|
*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;
|
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;
|
unsigned int i, count = 0;
|
||||||
IP_Port ip_ports[(DHT_BUCKET_NODES * 2)];
|
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;
|
unsigned int index = i - 1;
|
||||||
|
|
||||||
if (client_data[index].timestamp != 0) {
|
if (client_data[index].timestamp != 0) {
|
||||||
if (id_equal(client_data[index].public_key, friend->public_key))
|
if (id_equal(client_data[index].public_key, friend->public_key)) {
|
||||||
return 0;
|
count = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (get_ret_ip_port(&client_data[index], friend->public_key, &ip_ports[count]))
|
if (get_ret_ip_port(&client_data[index], friend->public_key, &ip_ports[count]))
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_client_list_ret_ips(client_data, (DHT_BUCKET_NODES * 2));
|
||||||
memcpy(ip_portlist, ip_ports, sizeof(IP_Port) * count);
|
memcpy(ip_portlist, ip_ports, sizeof(IP_Port) * count);
|
||||||
return 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)
|
if (friend_number(dht, friend_pk) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DHT_bucket_get_nodes(&dht->bucket_v4, client_data, (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);
|
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,
|
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();
|
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;
|
unsigned int sent = 0;
|
||||||
|
|
||||||
for (i = 0; i < count; ++i) {
|
if (count == num_to_send) {
|
||||||
int retval = sendpacket(dht->net, ip_ports[i], packet, length);
|
for (i = 0; i < count; ++i) {
|
||||||
|
int retval = sendpacket(dht->net, ip_ports[i], packet, length);
|
||||||
|
|
||||||
if ((unsigned int)retval == length) {
|
if ((unsigned int)retval == length) {
|
||||||
++sent;
|
++sent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_client_list_ret_ips(client_data, (DHT_BUCKET_NODES * 2) * 3);
|
||||||
return sent;
|
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};
|
Client_data client_data[DHT_BUCKET_NODES * 2] = {0};
|
||||||
|
|
||||||
if (rand() % 2) {
|
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_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);
|
DHT_bucket_get_nodes(&dht->bucket_v6, client_data + DHT_BUCKET_NODES, DHT_BUCKET_NODES, public_key, friend_ok, 0);
|
||||||
} else {
|
} else {
|
||||||
DHT_bucket_get_nodes(&dht->bucket_v6, client_data, 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);
|
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();
|
unsigned int i, num_nodes = 0, r = rand();
|
||||||
|
@ -2301,10 +2397,10 @@ int DHT_non_lan_connected(const DHT *dht)
|
||||||
{
|
{
|
||||||
Client_data cd;
|
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;
|
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 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2322,7 +2418,7 @@ int DHT_isconnected(const DHT *dht)
|
||||||
|
|
||||||
Client_data cd;
|
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 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -67,6 +67,13 @@ void to_net_family(IP *ip);
|
||||||
/* return 0 on success, -1 on failure. */
|
/* return 0 on success, -1 on failure. */
|
||||||
int to_host_family(IP *ip);
|
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 {
|
typedef struct {
|
||||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
|
|
||||||
|
@ -74,11 +81,7 @@ typedef struct {
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
uint64_t last_pinged;
|
uint64_t last_pinged;
|
||||||
|
|
||||||
struct {
|
Ret_IP *ret_ip;
|
||||||
uint8_t pk[crypto_box_PUBLICKEYBYTES];
|
|
||||||
IP_Port ip_port;
|
|
||||||
uint64_t timestamp;
|
|
||||||
} ret[DHT_BUCKET_NODES];
|
|
||||||
|
|
||||||
} Client_data;
|
} Client_data;
|
||||||
|
|
||||||
|
@ -112,7 +115,7 @@ typedef struct DHT_Bucket {
|
||||||
_Bool friend_key;
|
_Bool friend_key;
|
||||||
uint8_t searched_public_key[crypto_box_PUBLICKEYBYTES];
|
uint8_t searched_public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
|
|
||||||
Client_data client_list[DHT_BUCKET_NODES];
|
Client_data *client_list;
|
||||||
struct DHT_Bucket *buckets[2];
|
struct DHT_Bucket *buckets[2];
|
||||||
} DHT_Bucket;
|
} DHT_Bucket;
|
||||||
|
|
||||||
|
@ -230,6 +233,43 @@ typedef struct {
|
||||||
} DHT;
|
} 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
|
/* 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.
|
* ones so that they can re used later without being computed again.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue
Block a user