summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c104
1 files changed, 71 insertions, 33 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 919655a2..2d3d6ffe 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -207,7 +207,7 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_
207 } 207 }
208 208
209 if (ipv6 == 0) { 209 if (ipv6 == 0) {
210 uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + CLIENT_ID_SIZE; 210 uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES;
211 211
212 if (packed_length + size > length) 212 if (packed_length + size > length)
213 return -1; 213 return -1;
@@ -215,10 +215,10 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_
215 data[packed_length] = net_family; 215 data[packed_length] = net_family;
216 memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip4, sizeof(IP4)); 216 memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip4, sizeof(IP4));
217 memcpy(data + packed_length + 1 + sizeof(IP4), &nodes[i].ip_port.port, sizeof(uint16_t)); 217 memcpy(data + packed_length + 1 + sizeof(IP4), &nodes[i].ip_port.port, sizeof(uint16_t));
218 memcpy(data + packed_length + 1 + sizeof(IP4) + sizeof(uint16_t), nodes[i].client_id, CLIENT_ID_SIZE); 218 memcpy(data + packed_length + 1 + sizeof(IP4) + sizeof(uint16_t), nodes[i].public_key, crypto_box_PUBLICKEYBYTES);
219 packed_length += size; 219 packed_length += size;
220 } else if (ipv6 == 1) { 220 } else if (ipv6 == 1) {
221 uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + CLIENT_ID_SIZE; 221 uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES;
222 222
223 if (packed_length + size > length) 223 if (packed_length + size > length)
224 return -1; 224 return -1;
@@ -226,7 +226,7 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_
226 data[packed_length] = net_family; 226 data[packed_length] = net_family;
227 memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip6, sizeof(IP6)); 227 memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip6, sizeof(IP6));
228 memcpy(data + packed_length + 1 + sizeof(IP6), &nodes[i].ip_port.port, sizeof(uint16_t)); 228 memcpy(data + packed_length + 1 + sizeof(IP6), &nodes[i].ip_port.port, sizeof(uint16_t));
229 memcpy(data + packed_length + 1 + sizeof(IP6) + sizeof(uint16_t), nodes[i].client_id, CLIENT_ID_SIZE); 229 memcpy(data + packed_length + 1 + sizeof(IP6) + sizeof(uint16_t), nodes[i].public_key, crypto_box_PUBLICKEYBYTES);
230 packed_length += size; 230 packed_length += size;
231 } else { 231 } else {
232 return -1; 232 return -1;
@@ -275,7 +275,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
275 } 275 }
276 276
277 if (ipv6 == 0) { 277 if (ipv6 == 0) {
278 uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + CLIENT_ID_SIZE; 278 uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES;
279 279
280 if (len_processed + size > length) 280 if (len_processed + size > length)
281 return -1; 281 return -1;
@@ -283,11 +283,11 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
283 nodes[num].ip_port.ip.family = host_family; 283 nodes[num].ip_port.ip.family = host_family;
284 memcpy(&nodes[num].ip_port.ip.ip4, data + len_processed + 1, sizeof(IP4)); 284 memcpy(&nodes[num].ip_port.ip.ip4, data + len_processed + 1, sizeof(IP4));
285 memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP4), sizeof(uint16_t)); 285 memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP4), sizeof(uint16_t));
286 memcpy(nodes[num].client_id, data + len_processed + 1 + sizeof(IP4) + sizeof(uint16_t), CLIENT_ID_SIZE); 286 memcpy(nodes[num].public_key, data + len_processed + 1 + sizeof(IP4) + sizeof(uint16_t), crypto_box_PUBLICKEYBYTES);
287 len_processed += size; 287 len_processed += size;
288 ++num; 288 ++num;
289 } else if (ipv6 == 1) { 289 } else if (ipv6 == 1) {
290 uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + CLIENT_ID_SIZE; 290 uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES;
291 291
292 if (len_processed + size > length) 292 if (len_processed + size > length)
293 return -1; 293 return -1;
@@ -295,7 +295,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
295 nodes[num].ip_port.ip.family = host_family; 295 nodes[num].ip_port.ip.family = host_family;
296 memcpy(&nodes[num].ip_port.ip.ip6, data + len_processed + 1, sizeof(IP6)); 296 memcpy(&nodes[num].ip_port.ip.ip6, data + len_processed + 1, sizeof(IP6));
297 memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP6), sizeof(uint16_t)); 297 memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP6), sizeof(uint16_t));
298 memcpy(nodes[num].client_id, data + len_processed + 1 + sizeof(IP6) + sizeof(uint16_t), CLIENT_ID_SIZE); 298 memcpy(nodes[num].public_key, data + len_processed + 1 + sizeof(IP6) + sizeof(uint16_t), crypto_box_PUBLICKEYBYTES);
299 len_processed += size; 299 len_processed += size;
300 ++num; 300 ++num;
301 } else { 301 } else {
@@ -397,12 +397,12 @@ static int client_or_ip_port_in_list(Client_data *list, uint16_t length, const u
397 * return 1 if true. 397 * return 1 if true.
398 * return 0 if false. 398 * return 0 if false.
399 */ 399 */
400static int client_in_nodelist(const Node_format *list, uint16_t length, const uint8_t *client_id) 400static int client_in_nodelist(const Node_format *list, uint16_t length, const uint8_t *public_key)
401{ 401{
402 uint32_t i; 402 uint32_t i;
403 403
404 for (i = 0; i < length; ++i) { 404 for (i = 0; i < length; ++i) {
405 if (id_equal(list[i].client_id, client_id)) 405 if (id_equal(list[i].public_key, public_key))
406 return 1; 406 return 1;
407 } 407 }
408 408
@@ -484,9 +484,9 @@ static void get_close_nodes_inner(const uint8_t *client_id, Node_format *nodes_l
484 continue; 484 continue;
485 485
486 if (num_nodes < MAX_SENT_NODES) { 486 if (num_nodes < MAX_SENT_NODES) {
487 memcpy(nodes_list[num_nodes].client_id, 487 memcpy(nodes_list[num_nodes].public_key,
488 client->client_id, 488 client->client_id,
489 CLIENT_ID_SIZE ); 489 crypto_box_PUBLICKEYBYTES );
490 490
491 nodes_list[num_nodes].ip_port = ipptp->ip_port; 491 nodes_list[num_nodes].ip_port = ipptp->ip_port;
492 num_nodes++; 492 num_nodes++;
@@ -497,14 +497,14 @@ static void get_close_nodes_inner(const uint8_t *client_id, Node_format *nodes_l
497 */ 497 */
498 for (j = 0; j < MAX_SENT_NODES; ++j) { 498 for (j = 0; j < MAX_SENT_NODES; ++j) {
499 closest = id_closest( client_id, 499 closest = id_closest( client_id,
500 nodes_list[j].client_id, 500 nodes_list[j].public_key,
501 client->client_id ); 501 client->client_id );
502 502
503 /* second client_id is closer than current: change to it */ 503 /* second client_id is closer than current: change to it */
504 if (closest == 2) { 504 if (closest == 2) {
505 memcpy( nodes_list[j].client_id, 505 memcpy( nodes_list[j].public_key,
506 client->client_id, 506 client->client_id,
507 CLIENT_ID_SIZE); 507 crypto_box_PUBLICKEYBYTES);
508 508
509 nodes_list[j].ip_port = ipptp->ip_port; 509 nodes_list[j].ip_port = ipptp->ip_port;
510 break; 510 break;
@@ -583,7 +583,7 @@ int get_close_nodes(const DHT *dht, const uint8_t *client_id, Node_format *nodes
583 Client_data *client = result[i]; 583 Client_data *client = result[i];
584 584
585 if (client) { 585 if (client) {
586 id_copy(nodes_list[num_returned].client_id, client->client_id); 586 id_copy(nodes_list[num_returned].public_key, client->client_id);
587 587
588 if (sa_family == AF_INET) 588 if (sa_family == AF_INET)
589 if (ipport_isset(&client->assoc4.ip_port)) { 589 if (ipport_isset(&client->assoc4.ip_port)) {
@@ -647,6 +647,21 @@ static int cmp_dht_entry(const void *a, const void *b)
647 return 0; 647 return 0;
648} 648}
649 649
650/* Is it ok to store node with client_id in client.
651 *
652 * return 0 if node can't be stored.
653 * return 1 if it can.
654 */
655static unsigned int store_node_ok(const Client_data *client, const uint8_t *client_id, const uint8_t *comp_client_id)
656{
657 if ((is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT))
658 || (id_closest(comp_client_id, client->client_id, client_id) == 2)) {
659 return 1;
660 } else {
661 return 0;
662 }
663}
664
650/* Replace a first bad (or empty) node with this one 665/* Replace a first bad (or empty) node with this one
651 * or replace a possibly bad node (tests failed or not done yet) 666 * or replace a possibly bad node (tests failed or not done yet)
652 * that is further than any other in the list 667 * that is further than any other in the list
@@ -674,8 +689,7 @@ static int replace_all( Client_data *list,
674 689
675 Client_data *client = &list[0]; 690 Client_data *client = &list[0];
676 691
677 if ((is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) 692 if (store_node_ok(client, client_id, comp_client_id)) {
678 || (id_closest(comp_client_id, client->client_id, client_id) == 2)) {
679 IPPTsPng *ipptp_write = NULL; 693 IPPTsPng *ipptp_write = NULL;
680 IPPTsPng *ipptp_clear = NULL; 694 IPPTsPng *ipptp_clear = NULL;
681 695
@@ -704,6 +718,29 @@ static int replace_all( Client_data *list,
704 return 0; 718 return 0;
705} 719}
706 720
721/* Check if the node obtained with a get_nodes with client_id should be pinged.
722 * NOTE: for best results call it after addto_lists;
723 *
724 * return 0 if the node should not be pinged.
725 * return 1 if it should.
726 */
727static unsigned int ping_node_from_getnodes_ok(DHT *dht, const uint8_t *client_id)
728{
729 if (store_node_ok(&dht->close_clientlist[0], client_id, dht->self_public_key)) {
730 return 1;
731 }
732
733 unsigned int i;
734
735 for (i = 0; i < dht->num_friends; ++i) {
736 if (store_node_ok(&dht->friends_list[i].client_list[0], client_id, dht->self_public_key)) {
737 return 1;
738 }
739 }
740
741 return 0;
742}
743
707/* Attempt to add client with ip_port and client_id to the friends client list 744/* Attempt to add client with ip_port and client_id to the friends client list
708 * and close_clientlist. 745 * and close_clientlist.
709 * 746 *
@@ -860,7 +897,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const
860 uint8_t plain_message[sizeof(Node_format) * 2] = {0}; 897 uint8_t plain_message[sizeof(Node_format) * 2] = {0};
861 898
862 Node_format receiver; 899 Node_format receiver;
863 memcpy(receiver.client_id, public_key, CLIENT_ID_SIZE); 900 memcpy(receiver.public_key, public_key, CLIENT_ID_SIZE);
864 receiver.ip_port = ip_port; 901 receiver.ip_port = ip_port;
865 memcpy(plain_message, &receiver, sizeof(receiver)); 902 memcpy(plain_message, &receiver, sizeof(receiver));
866 903
@@ -1004,7 +1041,7 @@ static uint8_t sent_getnode_to_node(DHT *dht, const uint8_t *client_id, IP_Port
1004 Node_format test; 1041 Node_format test;
1005 memcpy(&test, data, sizeof(Node_format)); 1042 memcpy(&test, data, sizeof(Node_format));
1006 1043
1007 if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0) 1044 if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.public_key, client_id, CLIENT_ID_SIZE) != 0)
1008 return 0; 1045 return 0;
1009 1046
1010 return 1; 1047 return 1;
@@ -1091,9 +1128,10 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa
1091 uint32_t i; 1128 uint32_t i;
1092 1129
1093 for (i = 0; i < num_nodes; i++) { 1130 for (i = 0; i < num_nodes; i++) {
1094 if (ipport_isset(&plain_nodes[i].ip_port)) { 1131 if (ipport_isset(&plain_nodes[i].ip_port) && (LAN_ip(plain_nodes[i].ip_port.ip) == 0
1095 send_ping_request(dht->ping, plain_nodes[i].ip_port, plain_nodes[i].client_id); 1132 || ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key))) {
1096 returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].client_id, packet + 1); 1133 send_ping_request(dht->ping, plain_nodes[i].ip_port, plain_nodes[i].public_key);
1134 returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1);
1097 } 1135 }
1098 } 1136 }
1099 1137
@@ -1847,7 +1885,7 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8
1847 uint8_t data[HARDREQ_DATA_SIZE] = {0}; 1885 uint8_t data[HARDREQ_DATA_SIZE] = {0};
1848 data[0] = type; 1886 data[0] = type;
1849 memcpy(data + 1, contents, length); 1887 memcpy(data + 1, contents, length);
1850 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data, 1888 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->public_key, data,
1851 sizeof(data), CRYPTO_PACKET_HARDENING); 1889 sizeof(data), CRYPTO_PACKET_HARDENING);
1852 1890
1853 if (len == -1) 1891 if (len == -1)
@@ -1877,7 +1915,7 @@ static int send_hardening_getnode_res(const DHT *dht, const Node_format *sendto,
1877 data[0] = CHECK_TYPE_GETNODE_RES; 1915 data[0] = CHECK_TYPE_GETNODE_RES;
1878 memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); 1916 memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE);
1879 memcpy(data + 1 + CLIENT_ID_SIZE, nodes_data, nodes_data_length); 1917 memcpy(data + 1 + CLIENT_ID_SIZE, nodes_data, nodes_data_length);
1880 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data, 1918 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->public_key, data,
1881 sizeof(data), CRYPTO_PACKET_HARDENING); 1919 sizeof(data), CRYPTO_PACKET_HARDENING);
1882 1920
1883 if (len == -1) 1921 if (len == -1)
@@ -1914,12 +1952,12 @@ static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num)
1914 uint32_t i; 1952 uint32_t i;
1915 1953
1916 for (i = 0; i < num; ++i) { 1954 for (i = 0; i < num; ++i) {
1917 if (id_equal(nodes[i].client_id, dht->self_public_key)) { 1955 if (id_equal(nodes[i].public_key, dht->self_public_key)) {
1918 ++counter; 1956 ++counter;
1919 continue; 1957 continue;
1920 } 1958 }
1921 1959
1922 IPPTsPng *temp = get_closelist_IPPTsPng(dht, nodes[i].client_id, nodes[i].ip_port.ip.family); 1960 IPPTsPng *temp = get_closelist_IPPTsPng(dht, nodes[i].public_key, nodes[i].ip_port.ip.family);
1923 1961
1924 if (temp) { 1962 if (temp) {
1925 if (!is_timeout(temp->timestamp, BAD_NODE_TIMEOUT)) { 1963 if (!is_timeout(temp->timestamp, BAD_NODE_TIMEOUT)) {
@@ -1952,10 +1990,10 @@ static int handle_hardening(void *object, IP_Port source, const uint8_t *source_
1952 1990
1953 Node_format node, tocheck_node; 1991 Node_format node, tocheck_node;
1954 node.ip_port = source; 1992 node.ip_port = source;
1955 memcpy(node.client_id, source_pubkey, CLIENT_ID_SIZE); 1993 memcpy(node.public_key, source_pubkey, crypto_box_PUBLICKEYBYTES);
1956 memcpy(&tocheck_node, packet + 1, sizeof(Node_format)); 1994 memcpy(&tocheck_node, packet + 1, sizeof(Node_format));
1957 1995
1958 if (getnodes(dht, tocheck_node.ip_port, tocheck_node.client_id, packet + 1 + sizeof(Node_format), &node) == -1) 1996 if (getnodes(dht, tocheck_node.ip_port, tocheck_node.public_key, packet + 1 + sizeof(Node_format), &node) == -1)
1959 return 1; 1997 return 1;
1960 1998
1961 return 0; 1999 return 0;
@@ -2052,7 +2090,7 @@ uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
2052 } 2090 }
2053 2091
2054 if (assoc != NULL) { 2092 if (assoc != NULL) {
2055 memcpy(nodes[count].client_id, list[i - 1].client_id, CLIENT_ID_SIZE); 2093 memcpy(nodes[count].public_key, list[i - 1].client_id, CLIENT_ID_SIZE);
2056 nodes[count].ip_port = assoc->ip_port; 2094 nodes[count].ip_port = assoc->ip_port;
2057 ++count; 2095 ++count;
2058 2096
@@ -2091,16 +2129,16 @@ void do_hardening(DHT *dht)
2091 if (!ipport_isset(&rand_node.ip_port)) 2129 if (!ipport_isset(&rand_node.ip_port))
2092 continue; 2130 continue;
2093 2131
2094 if (id_equal(client_id, rand_node.client_id)) 2132 if (id_equal(client_id, rand_node.public_key))
2095 continue; 2133 continue;
2096 2134
2097 Node_format to_test; 2135 Node_format to_test;
2098 to_test.ip_port = cur_iptspng->ip_port; 2136 to_test.ip_port = cur_iptspng->ip_port;
2099 memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE); 2137 memcpy(to_test.public_key, client_id, crypto_box_PUBLICKEYBYTES);
2100 2138
2101 //TODO: The search id should maybe not be ours? 2139 //TODO: The search id should maybe not be ours?
2102 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) { 2140 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) {
2103 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE); 2141 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.public_key, crypto_box_PUBLICKEYBYTES);
2104 cur_iptspng->hardening.send_nodes_timestamp = unix_time(); 2142 cur_iptspng->hardening.send_nodes_timestamp = unix_time();
2105 } 2143 }
2106 } 2144 }