mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
DHT improvements.
Feed better nodes to onion, bootstrap off close clients when DHT friend is added.
This commit is contained in:
parent
ae801b3257
commit
22b1ebb46e
|
@ -1253,37 +1253,7 @@ int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void
|
|||
if (lock_count)
|
||||
*lock_count = lock_num + 1;
|
||||
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
|
||||
if (dht->assoc) {
|
||||
/* get up to MAX_FRIEND_CLIENTS connectable nodes */
|
||||
DHT_Friend *friend = &dht->friends_list[dht->num_friends - 1];
|
||||
|
||||
Assoc_close_entries close_entries;
|
||||
memset(&close_entries, 0, sizeof(close_entries));
|
||||
close_entries.wanted_id = public_key;
|
||||
close_entries.count_good = MAX_FRIEND_CLIENTS / 2;
|
||||
close_entries.count = MAX_FRIEND_CLIENTS;
|
||||
close_entries.result = calloc(MAX_FRIEND_CLIENTS, sizeof(*close_entries.result));
|
||||
|
||||
uint8_t i, found = Assoc_get_close_entries(dht->assoc, &close_entries);
|
||||
|
||||
for (i = 0; i < found; i++)
|
||||
memcpy(&friend->client_list[i], close_entries.result[i], sizeof(*close_entries.result[i]));
|
||||
|
||||
if (found) {
|
||||
/* send getnodes to the "best" entry */
|
||||
Client_data *client = &friend->client_list[0];
|
||||
|
||||
if (ipport_isset(&client->assoc4.ip_port))
|
||||
getnodes(dht, client->assoc4.ip_port, client->public_key, friend->public_key, NULL);
|
||||
|
||||
if (ipport_isset(&client->assoc6.ip_port))
|
||||
getnodes(dht, client->assoc6.ip_port, client->public_key, friend->public_key, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
friend->num_to_bootstrap = get_close_nodes(dht, friend->public_key, friend->to_bootstrap, 0, 1, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1464,11 +1434,20 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
|||
*/
|
||||
static void do_DHT_friends(DHT *dht)
|
||||
{
|
||||
uint32_t i;
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < dht->num_friends; ++i)
|
||||
do_ping_and_sendnode_requests(dht, &dht->friends_list[i].lastgetnode, dht->friends_list[i].public_key,
|
||||
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &dht->friends_list[i].bootstrap_times);
|
||||
for (i = 0; i < dht->num_friends; ++i) {
|
||||
DHT_Friend *friend = &dht->friends_list[i];
|
||||
|
||||
for (j = 0; j < friend->num_to_bootstrap; ++j) {
|
||||
getnodes(dht, friend->to_bootstrap[j].ip_port, friend->to_bootstrap[j].public_key, friend->public_key, NULL);
|
||||
}
|
||||
|
||||
friend->num_to_bootstrap = 0;
|
||||
|
||||
do_ping_and_sendnode_requests(dht, &friend->lastgetnode, friend->public_key, friend->client_list, MAX_FRIEND_CLIENTS,
|
||||
&friend->bootstrap_times);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ping each client in the close nodes list every PING_INTERVAL seconds.
|
||||
|
@ -2151,17 +2130,16 @@ Node_format random_node(DHT *dht, sa_family_t sa_family)
|
|||
*
|
||||
* return the number of nodes.
|
||||
*/
|
||||
uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
|
||||
uint16_t list_nodes(Client_data *list, unsigned int length, Node_format *nodes, uint16_t max_num)
|
||||
{
|
||||
if (max_num == 0)
|
||||
return 0;
|
||||
|
||||
uint16_t count = 0;
|
||||
Client_data *list = dht->close_clientlist;
|
||||
|
||||
uint32_t i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = LCLIENT_LIST; i != 0; --i) {
|
||||
for (i = length; i != 0; --i) {
|
||||
IPPTsPng *assoc = NULL;
|
||||
|
||||
if (!is_timeout(list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT))
|
||||
|
@ -2187,6 +2165,38 @@ uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
|
|||
return count;
|
||||
}
|
||||
|
||||
/* Put up to max_num nodes in nodes from the random friends.
|
||||
*
|
||||
* return the number of nodes.
|
||||
*/
|
||||
uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
|
||||
{
|
||||
if (max_num == 0)
|
||||
return 0;
|
||||
|
||||
uint16_t count = 0;
|
||||
unsigned int i, r = rand();
|
||||
|
||||
for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
|
||||
count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, nodes + count,
|
||||
max_num - count);
|
||||
|
||||
if (count >= max_num)
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Put up to max_num nodes in nodes from the closelist.
|
||||
*
|
||||
* return the number of nodes.
|
||||
*/
|
||||
uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
|
||||
{
|
||||
return list_nodes(dht->close_clientlist, LCLIENT_LIST, nodes, max_num);
|
||||
}
|
||||
|
||||
void do_hardening(DHT *dht)
|
||||
{
|
||||
uint32_t i;
|
||||
|
@ -2321,7 +2331,11 @@ DHT *new_DHT(Networking_Core *net)
|
|||
for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
|
||||
uint8_t random_key_bytes[crypto_box_PUBLICKEYBYTES];
|
||||
randombytes(random_key_bytes, sizeof(random_key_bytes));
|
||||
DHT_addfriend(dht, random_key_bytes, 0, 0, 0, 0);
|
||||
|
||||
if (DHT_addfriend(dht, random_key_bytes, 0, 0, 0, 0) != 0) {
|
||||
kill_DHT(dht);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return dht;
|
||||
|
|
|
@ -123,6 +123,12 @@ typedef struct {
|
|||
|
||||
#define DHT_FRIEND_MAX_LOCKS 32
|
||||
|
||||
typedef struct {
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
IP_Port ip_port;
|
||||
}
|
||||
Node_format;
|
||||
|
||||
typedef struct {
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
Client_data client_list[MAX_FRIEND_CLIENTS];
|
||||
|
@ -142,14 +148,10 @@ typedef struct {
|
|||
int32_t number;
|
||||
} callbacks[DHT_FRIEND_MAX_LOCKS];
|
||||
|
||||
Node_format to_bootstrap[MAX_SENT_NODES];
|
||||
unsigned int num_to_bootstrap;
|
||||
} DHT_Friend;
|
||||
|
||||
typedef struct {
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
IP_Port ip_port;
|
||||
}
|
||||
Node_format;
|
||||
|
||||
/* Return packet size of packed node with ip_family on success.
|
||||
* Return -1 on failure.
|
||||
*/
|
||||
|
@ -311,6 +313,12 @@ int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *node
|
|||
uint8_t is_LAN, uint8_t want_good);
|
||||
|
||||
|
||||
/* Put up to max_num nodes in nodes from the random friends.
|
||||
*
|
||||
* return the number of nodes.
|
||||
*/
|
||||
uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
|
||||
|
||||
/* Put up to max_num nodes in nodes from the closelist.
|
||||
*
|
||||
* return the number of nodes.
|
||||
|
|
|
@ -1209,16 +1209,14 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
|
|||
|
||||
static void populate_path_nodes(Onion_Client *onion_c)
|
||||
{
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint32_t random_num = rand();
|
||||
memcpy(public_key, &random_num, sizeof(random_num));
|
||||
Node_format nodes_list[MAX_FRIEND_CLIENTS];
|
||||
|
||||
unsigned int num_nodes = randfriends_nodes(onion_c->dht, nodes_list, MAX_FRIEND_CLIENTS);
|
||||
|
||||
unsigned int num_nodes = get_close_nodes(onion_c->dht, public_key, nodes_list, (rand() % 2) ? AF_INET : AF_INET6, 1, 0);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_nodes; ++i) {
|
||||
onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
|
||||
int r = onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1415,7 +1413,7 @@ static int onion_isconnected(const Onion_Client *onion_c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define ONION_CONNECTION_SECONDS 2
|
||||
#define ONION_CONNECTION_SECONDS 3
|
||||
|
||||
/* return 0 if we are not connected to the network.
|
||||
* return 1 if we are connected with TCP only.
|
||||
|
@ -1441,8 +1439,6 @@ void do_onion_client(Onion_Client *onion_c)
|
|||
if (onion_c->last_run == unix_time())
|
||||
return;
|
||||
|
||||
populate_path_nodes(onion_c);
|
||||
|
||||
do_announce(onion_c);
|
||||
|
||||
if (onion_isconnected(onion_c)) {
|
||||
|
@ -1461,6 +1457,7 @@ void do_onion_client(Onion_Client *onion_c)
|
|||
_Bool UDP_connected = DHT_non_lan_connected(onion_c->dht);
|
||||
|
||||
if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) {
|
||||
populate_path_nodes(onion_c);
|
||||
set_tcp_onion_status(onion_c->c->tcp_c, !UDP_connected);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user