diff options
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 112 |
1 files changed, 24 insertions, 88 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 84c00c70..1761f50b 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -56,9 +56,6 @@ | |||
56 | /* Interval in seconds between punching attempts*/ | 56 | /* Interval in seconds between punching attempts*/ |
57 | #define PUNCH_INTERVAL 10 | 57 | #define PUNCH_INTERVAL 10 |
58 | 58 | ||
59 | /* Ping newly announced nodes to ping per TIME_TOPING seconds*/ | ||
60 | #define TIME_TOPING 5 | ||
61 | |||
62 | #define NAT_PING_REQUEST 0 | 59 | #define NAT_PING_REQUEST 0 |
63 | #define NAT_PING_RESPONSE 1 | 60 | #define NAT_PING_RESPONSE 1 |
64 | 61 | ||
@@ -84,7 +81,7 @@ Client_data *DHT_get_close_list(DHT *dht) | |||
84 | * return 1 if client_id1 is closer. | 81 | * return 1 if client_id1 is closer. |
85 | * return 2 if client_id2 is closer. | 82 | * return 2 if client_id2 is closer. |
86 | */ | 83 | */ |
87 | static int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2) | 84 | int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2) |
88 | { | 85 | { |
89 | size_t i; | 86 | size_t i; |
90 | uint8_t distance1, distance2; | 87 | uint8_t distance1, distance2; |
@@ -443,7 +440,6 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint | |||
443 | } | 440 | } |
444 | } | 441 | } |
445 | 442 | ||
446 | /* Same as last function but for get_node requests. */ | ||
447 | static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) | 443 | static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) |
448 | { | 444 | { |
449 | uint32_t i; | 445 | uint32_t i; |
@@ -454,7 +450,7 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) | |||
454 | if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { | 450 | if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { |
455 | pinging = 0; | 451 | pinging = 0; |
456 | 452 | ||
457 | if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) | 453 | if (ping_id != 0 && dht->send_nodes[i].id == ping_id) |
458 | ++pinging; | 454 | ++pinging; |
459 | 455 | ||
460 | if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port)) | 456 | if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port)) |
@@ -480,7 +476,7 @@ static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port) | |||
480 | if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) { | 476 | if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) { |
481 | dht->send_nodes[j].timestamp = temp_time; | 477 | dht->send_nodes[j].timestamp = temp_time; |
482 | dht->send_nodes[j].ip_port = ip_port; | 478 | dht->send_nodes[j].ip_port = ip_port; |
483 | dht->send_nodes[j].ping_id = ping_id; | 479 | dht->send_nodes[j].id = ping_id; |
484 | return ping_id; | 480 | return ping_id; |
485 | } | 481 | } |
486 | } | 482 | } |
@@ -751,7 +747,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
751 | addto_lists(dht, source, packet + 1); | 747 | addto_lists(dht, source, packet + 1); |
752 | 748 | ||
753 | for (i = 0; i < num_nodes; ++i) { | 749 | for (i = 0; i < num_nodes; ++i) { |
754 | send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); | 750 | send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); |
755 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 751 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
756 | } | 752 | } |
757 | 753 | ||
@@ -798,7 +794,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, | |||
798 | addto_lists(dht, source, packet + 1); | 794 | addto_lists(dht, source, packet + 1); |
799 | 795 | ||
800 | for (i = 0; i < num_nodes; ++i) { | 796 | for (i = 0; i < num_nodes; ++i) { |
801 | send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); | 797 | send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); |
802 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 798 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
803 | } | 799 | } |
804 | 800 | ||
@@ -927,7 +923,7 @@ static void do_DHT_friends(DHT *dht) | |||
927 | /* If node is not dead. */ | 923 | /* If node is not dead. */ |
928 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { | 924 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { |
929 | if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { | 925 | if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { |
930 | send_ping_request(dht->ping, dht->c, dht->friends_list[i].client_list[j].ip_port, | 926 | send_ping_request(dht->ping, dht->friends_list[i].client_list[j].ip_port, |
931 | dht->friends_list[i].client_list[j].client_id ); | 927 | dht->friends_list[i].client_list[j].client_id ); |
932 | dht->friends_list[i].client_list[j].last_pinged = temp_time; | 928 | dht->friends_list[i].client_list[j].last_pinged = temp_time; |
933 | } | 929 | } |
@@ -965,7 +961,7 @@ static void do_Close(DHT *dht) | |||
965 | /* If node is not dead. */ | 961 | /* If node is not dead. */ |
966 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { | 962 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { |
967 | if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { | 963 | if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { |
968 | send_ping_request(dht->ping, dht->c, dht->close_clientlist[i].ip_port, | 964 | send_ping_request(dht->ping, dht->close_clientlist[i].ip_port, |
969 | dht->close_clientlist[i].client_id ); | 965 | dht->close_clientlist[i].client_id ); |
970 | dht->close_clientlist[i].last_pinged = temp_time; | 966 | dht->close_clientlist[i].last_pinged = temp_time; |
971 | } | 967 | } |
@@ -990,7 +986,7 @@ static void do_Close(DHT *dht) | |||
990 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) | 986 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) |
991 | { | 987 | { |
992 | getnodes(dht, ip_port, public_key, dht->c->self_public_key); | 988 | getnodes(dht, ip_port, public_key, dht->c->self_public_key); |
993 | send_ping_request(dht->ping, dht->c, ip_port, public_key); | 989 | send_ping_request(dht->ping, ip_port, public_key); |
994 | } | 990 | } |
995 | int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, | 991 | int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, |
996 | uint16_t port, uint8_t *public_key) | 992 | uint16_t port, uint8_t *public_key) |
@@ -1307,7 +1303,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, | |||
1307 | IP_Port pinging; | 1303 | IP_Port pinging; |
1308 | ip_copy(&pinging.ip, &ip); | 1304 | ip_copy(&pinging.ip, &ip); |
1309 | pinging.port = htons(port); | 1305 | pinging.port = htons(port); |
1310 | send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id); | 1306 | send_ping_request(dht->ping, pinging, dht->friends_list[friend_num].client_id); |
1311 | } | 1307 | } |
1312 | 1308 | ||
1313 | dht->friends_list[friend_num].punching_index = i; | 1309 | dht->friends_list[friend_num].punching_index = i; |
@@ -1353,94 +1349,34 @@ static void do_NAT(DHT *dht) | |||
1353 | /*----------------------------------------------------------------------------------*/ | 1349 | /*----------------------------------------------------------------------------------*/ |
1354 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ | 1350 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ |
1355 | 1351 | ||
1356 | |||
1357 | /* Add nodes to the toping list. | ||
1358 | * All nodes in this list are pinged every TIME_TOPING seconds | ||
1359 | * and are then removed from the list. | ||
1360 | * If the list is full the nodes farthest from our client_id are replaced. | ||
1361 | * The purpose of this list is to enable quick integration of new nodes into the | ||
1362 | * network while preventing amplification attacks. | ||
1363 | * | ||
1364 | * return 0 if node was added. | ||
1365 | * return -1 if node was not added. | ||
1366 | */ | ||
1367 | int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) | ||
1368 | { | ||
1369 | if (!ip_isset(&ip_port.ip)) | ||
1370 | return -1; | ||
1371 | |||
1372 | uint32_t i; | ||
1373 | |||
1374 | for (i = 0; i < MAX_TOPING; ++i) { | ||
1375 | if (!ip_isset(&dht->toping[i].ip_port.ip)) { | ||
1376 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); | ||
1377 | ipport_copy(&dht->toping[i].ip_port, &ip_port); | ||
1378 | return 0; | ||
1379 | } | ||
1380 | } | ||
1381 | |||
1382 | for (i = 0; i < MAX_TOPING; ++i) { | ||
1383 | if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) { | ||
1384 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); | ||
1385 | ipport_copy(&dht->toping[i].ip_port, &ip_port); | ||
1386 | return 0; | ||
1387 | } | ||
1388 | } | ||
1389 | |||
1390 | return -1; | ||
1391 | } | ||
1392 | |||
1393 | /* Ping all the valid nodes in the toping list every TIME_TOPING seconds. | ||
1394 | * This function must be run at least once every TIME_TOPING seconds. | ||
1395 | */ | ||
1396 | static void do_toping(DHT *dht) | ||
1397 | { | ||
1398 | uint64_t temp_time = unix_time(); | ||
1399 | |||
1400 | if (!is_timeout(temp_time, dht->last_toping, TIME_TOPING)) | ||
1401 | return; | ||
1402 | |||
1403 | dht->last_toping = temp_time; | ||
1404 | uint32_t i; | ||
1405 | |||
1406 | for (i = 0; i < MAX_TOPING; ++i) { | ||
1407 | if (!ip_isset(&dht->toping[i].ip_port.ip)) | ||
1408 | return; | ||
1409 | |||
1410 | send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id); | ||
1411 | ip_reset(&dht->toping[i].ip_port.ip); | ||
1412 | } | ||
1413 | } | ||
1414 | |||
1415 | |||
1416 | DHT *new_DHT(Net_Crypto *c) | 1352 | DHT *new_DHT(Net_Crypto *c) |
1417 | { | 1353 | { |
1418 | if (c == NULL) | 1354 | if (c == NULL) |
1419 | return NULL; | 1355 | return NULL; |
1420 | 1356 | ||
1421 | DHT *temp = calloc(1, sizeof(DHT)); | 1357 | DHT *dht = calloc(1, sizeof(DHT)); |
1422 | 1358 | ||
1423 | if (temp == NULL) | 1359 | if (dht == NULL) |
1424 | return NULL; | 1360 | return NULL; |
1425 | 1361 | ||
1426 | temp->ping = new_ping(); | 1362 | dht->ping = new_ping(dht, c); |
1427 | 1363 | ||
1428 | if (temp->ping == NULL) { | 1364 | if (dht->ping == NULL) { |
1429 | kill_DHT(temp); | 1365 | kill_DHT(dht); |
1430 | return NULL; | 1366 | return NULL; |
1431 | } | 1367 | } |
1432 | 1368 | ||
1433 | temp->c = c; | 1369 | dht->c = c; |
1434 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_PING_REQUEST, &handle_ping_request, temp); | 1370 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); |
1435 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, temp); | 1371 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); |
1436 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, temp); | ||
1437 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, temp); | ||
1438 | #ifdef TOX_ENABLE_IPV6 | 1372 | #ifdef TOX_ENABLE_IPV6 |
1439 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, temp); | 1373 | networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); |
1440 | #endif | 1374 | #endif |
1441 | init_cryptopackets(temp); | 1375 | |
1442 | cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, temp); | 1376 | init_cryptopackets(dht); |
1443 | return temp; | 1377 | cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); |
1378 | |||
1379 | return dht; | ||
1444 | } | 1380 | } |
1445 | 1381 | ||
1446 | void do_DHT(DHT *dht) | 1382 | void do_DHT(DHT *dht) |
@@ -1448,7 +1384,7 @@ void do_DHT(DHT *dht) | |||
1448 | do_Close(dht); | 1384 | do_Close(dht); |
1449 | do_DHT_friends(dht); | 1385 | do_DHT_friends(dht); |
1450 | do_NAT(dht); | 1386 | do_NAT(dht); |
1451 | do_toping(dht); | 1387 | do_toping(dht->ping); |
1452 | } | 1388 | } |
1453 | void kill_DHT(DHT *dht) | 1389 | void kill_DHT(DHT *dht) |
1454 | { | 1390 | { |