summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorCoren[m] <Break@Ocean>2013-09-21 15:39:15 +0200
committerCoren[m] <Break@Ocean>2013-09-21 15:39:15 +0200
commit88678e584aaf3956a0c88c80fa65efc505773f7d (patch)
treec20a7a2d364280275ff8788f79723613fcd706b4 /toxcore/DHT.c
parent20b6900fb181f71eca4577a5f1e1f5f3ecd6a28b (diff)
moved stuff that belongs into ping.[ch] there
DHT.*, ping.*: - moved stuff from struct DHT into struct PING: toping, last_toping - moved functions add_toping(), do_toping() - made id_closest() publicly accessible - send_ping_request(): killed (Net_Crypto *c) parameter in favor of copying it into (PING *) on new_ping() group_chats.c: - killed local 1:1 copy in favor of DHT.c::id_closest()
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c112
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 */
87static int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2) 84int 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. */
447static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) 443static 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)
990void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) 986void 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}
995int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, 991int 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 */
1367int 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 */
1396static 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
1416DHT *new_DHT(Net_Crypto *c) 1352DHT *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
1446void do_DHT(DHT *dht) 1382void 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}
1453void kill_DHT(DHT *dht) 1389void kill_DHT(DHT *dht)
1454{ 1390{