diff --git a/toxcore/DHT.c b/toxcore/DHT.c index ca815844..a958938d 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -63,7 +63,7 @@ #define NAT_PING_RESPONSE 1 /* Number of get node requests to send to quickly find close nodes. */ -#define MAX_BOOTSTRAP_TIMES 20 +#define MAX_BOOTSTRAP_TIMES 0 /* Compares pk1 and pk2 with pk. * @@ -778,35 +778,83 @@ static int replace_all( Client_data *list, return 0; } +static _Bool is_pk_in_client_list(Client_data *list, unsigned int client_list_length, const uint8_t *public_key, + IP_Port ip_port) +{ + unsigned int i; + + for (i = 0; i < client_list_length; ++i) { + if ((ip_port.ip.family == AF_INET && !is_timeout(list[i].assoc4.timestamp, BAD_NODE_TIMEOUT)) + || (ip_port.ip.family == AF_INET6 && !is_timeout(list[i].assoc6.timestamp, BAD_NODE_TIMEOUT))) { + if (memcmp(list[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + return 1; + } + } + } + + return 0; +} + /* Check if the node obtained with a get_nodes with public_key should be pinged. * NOTE: for best results call it after addto_lists; * * return 0 if the node should not be pinged. * return 1 if it should. */ -static unsigned int ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key) +static unsigned int ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, IP_Port ip_port) { + _Bool ret = 0; + if (store_node_ok(&dht->close_clientlist[1], public_key, dht->self_public_key)) { - return 1; + ret = 1; } if (store_node_ok(&dht->close_clientlist[0], public_key, dht->self_public_key)) { - return 1; + ret = 1; + } + + if (ret && !client_in_nodelist(dht->to_bootstrap, dht->num_to_bootstrap, public_key) + && !is_pk_in_client_list(dht->close_clientlist, LCLIENT_LIST, public_key, ip_port)) { + if (dht->num_to_bootstrap < MAX_SENT_NODES) { + memcpy(dht->to_bootstrap[dht->num_to_bootstrap].public_key, public_key, crypto_box_PUBLICKEYBYTES); + dht->to_bootstrap[dht->num_to_bootstrap].ip_port = ip_port; + ++dht->num_to_bootstrap; + } else { + //TODO: ipv6 vs v4 + add_to_list(dht->to_bootstrap, MAX_SENT_NODES, public_key, ip_port, dht->self_public_key); + } } unsigned int i; for (i = 0; i < dht->num_friends; ++i) { - if (store_node_ok(&dht->friends_list[i].client_list[1], public_key, dht->friends_list[i].public_key)) { - return 1; + _Bool store_ok = 0; + + DHT_Friend *friend = &dht->friends_list[i]; + + if (store_node_ok(&friend->client_list[1], public_key, friend->public_key)) { + store_ok = 1; } - if (store_node_ok(&dht->friends_list[i].client_list[0], public_key, dht->friends_list[i].public_key)) { - return 1; + if (store_node_ok(&friend->client_list[0], public_key, friend->public_key)) { + store_ok = 1; + } + + if (store_ok && !client_in_nodelist(friend->to_bootstrap, friend->num_to_bootstrap, public_key) + && !is_pk_in_client_list(friend->client_list, MAX_FRIEND_CLIENTS, public_key, ip_port)) { + if (friend->num_to_bootstrap < MAX_SENT_NODES) { + memcpy(friend->to_bootstrap[friend->num_to_bootstrap].public_key, public_key, crypto_box_PUBLICKEYBYTES); + friend->to_bootstrap[friend->num_to_bootstrap].ip_port = ip_port; + ++friend->num_to_bootstrap; + } else { + add_to_list(friend->to_bootstrap, MAX_SENT_NODES, public_key, ip_port, friend->public_key); + } + + ret = 1; } } - return 0; + return ret; } /* Attempt to add client with ip_port and public_key to the friends client list @@ -1197,9 +1245,9 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa uint32_t i; for (i = 0; i < num_nodes; i++) { - if (ipport_isset(&plain_nodes[i].ip_port) && (LAN_ip(plain_nodes[i].ip_port.ip) == 0 - || ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key))) { - send_ping_request(dht->ping, plain_nodes[i].ip_port, plain_nodes[i].public_key); + + if (ipport_isset(&plain_nodes[i].ip_port)) { + ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key, plain_nodes[i].ip_port); returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1); } } @@ -1491,6 +1539,14 @@ static void do_DHT_friends(DHT *dht) */ static void do_Close(DHT *dht) { + unsigned int i; + + for (i = 0; i < dht->num_to_bootstrap; ++i) { + getnodes(dht, dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key, NULL); + } + + dht->num_to_bootstrap = 0; + uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times); diff --git a/toxcore/DHT.h b/toxcore/DHT.h index c83ca073..4ae99049 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -231,6 +231,9 @@ typedef struct { uint64_t last_run; Cryptopacket_Handles cryptopackethandlers[256]; + + Node_format to_bootstrap[MAX_SENT_NODES]; + unsigned int num_to_bootstrap; } DHT; /*----------------------------------------------------------------------------------*/