summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-09-24 17:51:23 -0700
committerirungentoo <irungentoo@gmail.com>2013-09-24 17:51:23 -0700
commit370e36815ed38428d8b68d15e7a4aab8fbd6bf2b (patch)
treee6694ee780d78b67240f8a856f5257fe2c98c1c8 /toxcore/DHT.c
parent7c300370b07ae0afbaaa9bf8c5562930823550c8 (diff)
parent88678e584aaf3956a0c88c80fa65efc505773f7d (diff)
Merge pull request #596 from FullName/ping.moveandclean
moved stuff that belongs into ping.[ch] there
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 bdfe120f..ad4c8a1d 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;
@@ -522,7 +519,6 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint
522 } 519 }
523} 520}
524 521
525/* Same as last function but for get_node requests. */
526static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) 522static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id)
527{ 523{
528 uint32_t i; 524 uint32_t i;
@@ -533,7 +529,7 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id)
533 if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { 529 if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) {
534 pinging = 0; 530 pinging = 0;
535 531
536 if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) 532 if (ping_id != 0 && dht->send_nodes[i].id == ping_id)
537 ++pinging; 533 ++pinging;
538 534
539 if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port)) 535 if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port))
@@ -559,7 +555,7 @@ static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port)
559 if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) { 555 if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) {
560 dht->send_nodes[j].timestamp = temp_time; 556 dht->send_nodes[j].timestamp = temp_time;
561 dht->send_nodes[j].ip_port = ip_port; 557 dht->send_nodes[j].ip_port = ip_port;
562 dht->send_nodes[j].ping_id = ping_id; 558 dht->send_nodes[j].id = ping_id;
563 return ping_id; 559 return ping_id;
564 } 560 }
565 } 561 }
@@ -830,7 +826,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
830 addto_lists(dht, source, packet + 1); 826 addto_lists(dht, source, packet + 1);
831 827
832 for (i = 0; i < num_nodes; ++i) { 828 for (i = 0; i < num_nodes; ++i) {
833 send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); 829 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id);
834 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 830 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
835 } 831 }
836 832
@@ -877,7 +873,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
877 addto_lists(dht, source, packet + 1); 873 addto_lists(dht, source, packet + 1);
878 874
879 for (i = 0; i < num_nodes; ++i) { 875 for (i = 0; i < num_nodes; ++i) {
880 send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); 876 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id);
881 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 877 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
882 } 878 }
883 879
@@ -1006,7 +1002,7 @@ static void do_DHT_friends(DHT *dht)
1006 /* If node is not dead. */ 1002 /* If node is not dead. */
1007 if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { 1003 if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
1008 if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 1004 if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
1009 send_ping_request(dht->ping, dht->c, dht->friends_list[i].client_list[j].ip_port, 1005 send_ping_request(dht->ping, dht->friends_list[i].client_list[j].ip_port,
1010 dht->friends_list[i].client_list[j].client_id ); 1006 dht->friends_list[i].client_list[j].client_id );
1011 dht->friends_list[i].client_list[j].last_pinged = temp_time; 1007 dht->friends_list[i].client_list[j].last_pinged = temp_time;
1012 } 1008 }
@@ -1044,7 +1040,7 @@ static void do_Close(DHT *dht)
1044 /* If node is not dead. */ 1040 /* If node is not dead. */
1045 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { 1041 if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
1046 if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 1042 if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
1047 send_ping_request(dht->ping, dht->c, dht->close_clientlist[i].ip_port, 1043 send_ping_request(dht->ping, dht->close_clientlist[i].ip_port,
1048 dht->close_clientlist[i].client_id ); 1044 dht->close_clientlist[i].client_id );
1049 dht->close_clientlist[i].last_pinged = temp_time; 1045 dht->close_clientlist[i].last_pinged = temp_time;
1050 } 1046 }
@@ -1069,7 +1065,7 @@ static void do_Close(DHT *dht)
1069void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) 1065void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
1070{ 1066{
1071 getnodes(dht, ip_port, public_key, dht->c->self_public_key); 1067 getnodes(dht, ip_port, public_key, dht->c->self_public_key);
1072 send_ping_request(dht->ping, dht->c, ip_port, public_key); 1068 send_ping_request(dht->ping, ip_port, public_key);
1073} 1069}
1074int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, 1070int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
1075 uint16_t port, uint8_t *public_key) 1071 uint16_t port, uint8_t *public_key)
@@ -1386,7 +1382,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
1386 IP_Port pinging; 1382 IP_Port pinging;
1387 ip_copy(&pinging.ip, &ip); 1383 ip_copy(&pinging.ip, &ip);
1388 pinging.port = htons(port); 1384 pinging.port = htons(port);
1389 send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id); 1385 send_ping_request(dht->ping, pinging, dht->friends_list[friend_num].client_id);
1390 } 1386 }
1391 1387
1392 dht->friends_list[friend_num].punching_index = i; 1388 dht->friends_list[friend_num].punching_index = i;
@@ -1432,94 +1428,34 @@ static void do_NAT(DHT *dht)
1432/*----------------------------------------------------------------------------------*/ 1428/*----------------------------------------------------------------------------------*/
1433/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ 1429/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
1434 1430
1435
1436/* Add nodes to the toping list.
1437 * All nodes in this list are pinged every TIME_TOPING seconds
1438 * and are then removed from the list.
1439 * If the list is full the nodes farthest from our client_id are replaced.
1440 * The purpose of this list is to enable quick integration of new nodes into the
1441 * network while preventing amplification attacks.
1442 *
1443 * return 0 if node was added.
1444 * return -1 if node was not added.
1445 */
1446int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port)
1447{
1448 if (!ip_isset(&ip_port.ip))
1449 return -1;
1450
1451 uint32_t i;
1452
1453 for (i = 0; i < MAX_TOPING; ++i) {
1454 if (!ip_isset(&dht->toping[i].ip_port.ip)) {
1455 memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
1456 ipport_copy(&dht->toping[i].ip_port, &ip_port);
1457 return 0;
1458 }
1459 }
1460
1461 for (i = 0; i < MAX_TOPING; ++i) {
1462 if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) {
1463 memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE);
1464 ipport_copy(&dht->toping[i].ip_port, &ip_port);
1465 return 0;
1466 }
1467 }
1468
1469 return -1;
1470}
1471
1472/* Ping all the valid nodes in the toping list every TIME_TOPING seconds.
1473 * This function must be run at least once every TIME_TOPING seconds.
1474 */
1475static void do_toping(DHT *dht)
1476{
1477 uint64_t temp_time = unix_time();
1478
1479 if (!is_timeout(temp_time, dht->last_toping, TIME_TOPING))
1480 return;
1481
1482 dht->last_toping = temp_time;
1483 uint32_t i;
1484
1485 for (i = 0; i < MAX_TOPING; ++i) {
1486 if (!ip_isset(&dht->toping[i].ip_port.ip))
1487 return;
1488
1489 send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id);
1490 ip_reset(&dht->toping[i].ip_port.ip);
1491 }
1492}
1493
1494
1495DHT *new_DHT(Net_Crypto *c) 1431DHT *new_DHT(Net_Crypto *c)
1496{ 1432{
1497 if (c == NULL) 1433 if (c == NULL)
1498 return NULL; 1434 return NULL;
1499 1435
1500 DHT *temp = calloc(1, sizeof(DHT)); 1436 DHT *dht = calloc(1, sizeof(DHT));
1501 1437
1502 if (temp == NULL) 1438 if (dht == NULL)
1503 return NULL; 1439 return NULL;
1504 1440
1505 temp->ping = new_ping(); 1441 dht->ping = new_ping(dht, c);
1506 1442
1507 if (temp->ping == NULL) { 1443 if (dht->ping == NULL) {
1508 kill_DHT(temp); 1444 kill_DHT(dht);
1509 return NULL; 1445 return NULL;
1510 } 1446 }
1511 1447
1512 temp->c = c; 1448 dht->c = c;
1513 networking_registerhandler(c->lossless_udp->net, NET_PACKET_PING_REQUEST, &handle_ping_request, temp); 1449 networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
1514 networking_registerhandler(c->lossless_udp->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, temp); 1450 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht);
1515 networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, temp);
1516 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, temp);
1517#ifdef TOX_ENABLE_IPV6 1451#ifdef TOX_ENABLE_IPV6
1518 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, temp); 1452 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
1519#endif 1453#endif
1520 init_cryptopackets(temp); 1454
1521 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, temp); 1455 init_cryptopackets(dht);
1522 return temp; 1456 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
1457
1458 return dht;
1523} 1459}
1524 1460
1525void do_DHT(DHT *dht) 1461void do_DHT(DHT *dht)
@@ -1527,7 +1463,7 @@ void do_DHT(DHT *dht)
1527 do_Close(dht); 1463 do_Close(dht);
1528 do_DHT_friends(dht); 1464 do_DHT_friends(dht);
1529 do_NAT(dht); 1465 do_NAT(dht);
1530 do_toping(dht); 1466 do_toping(dht->ping);
1531} 1467}
1532void kill_DHT(DHT *dht) 1468void kill_DHT(DHT *dht)
1533{ 1469{