summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorCoren[m] <Break@Ocean>2013-11-17 01:04:49 +0100
committerCoren[m] <Break@Ocean>2013-11-17 01:05:00 +0100
commitb132c92b3ae3aeee293a4e815336cac76c7cfe69 (patch)
tree1878864ea5a27d571ac758bb5ad2875f0b9460a6 /toxcore/DHT.c
parent0d8329b3a9b16cd6089810e61ce958fde00046b8 (diff)
Assoc's array is now allocated dynamically and per default much smaller (320 entries).
id_hash() was not at all working as expected for very small bucket size (when (size / 4) was zero). Simplified to be trivially correct. Also added a used flag on adding an entry, which is set by callers if they have that association in active use. Those get priority over unused entries on collision. Fleshed out test to be at least elementary useful. Each group chat now uses an own, small assoc (80 entries).
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 9730771b..f5d93fc4 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -425,7 +425,9 @@ static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_i
425 list[i] = pairs[i].c2; 425 list[i] = pairs[i].c2;
426} 426}
427 427
428/* Replace the first good node that is further to the comp_client_id than that of the client_id in the list */ 428/* Replace the first good node that is further to the comp_client_id than that of the client_id in the list
429 *
430 * returns 0 when the item was stored, 1 otherwise */
429static int replace_good( Client_data *list, 431static int replace_good( Client_data *list,
430 uint32_t length, 432 uint32_t length,
431 uint8_t *client_id, 433 uint8_t *client_id,
@@ -478,10 +480,12 @@ static int replace_good( Client_data *list,
478 480
479/* Attempt to add client with ip_port and client_id to the friends client list 481/* Attempt to add client with ip_port and client_id to the friends client list
480 * and close_clientlist. 482 * and close_clientlist.
483 *
484 * returns 1+ if the item is used in any list, 0 else
481 */ 485 */
482void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) 486int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
483{ 487{
484 uint32_t i; 488 uint32_t i, used = 0;
485 489
486 /* convert IPv4-in-IPv6 to IPv4 */ 490 /* convert IPv4-in-IPv6 to IPv4 */
487 if ((ip_port.ip.family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&ip_port.ip.ip6.in6_addr)) { 491 if ((ip_port.ip.family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&ip_port.ip.ip6.in6_addr)) {
@@ -495,10 +499,13 @@ void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
495 if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 499 if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
496 if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 500 if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
497 /* If we can't replace bad nodes we try replacing good ones. */ 501 /* If we can't replace bad nodes we try replacing good ones. */
498 replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, 502 if (!replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port,
499 dht->c->self_public_key); 503 dht->c->self_public_key))
500 } 504 used++;
501 } 505 } else
506 used++;
507 } else
508 used++;
502 509
503 for (i = 0; i < dht->num_friends; ++i) { 510 for (i = 0; i < dht->num_friends; ++i) {
504 if (!client_or_ip_port_in_list(dht->friends_list[i].client_list, 511 if (!client_or_ip_port_in_list(dht->friends_list[i].client_list,
@@ -507,17 +514,22 @@ void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
507 if (replace_bad(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 514 if (replace_bad(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
508 client_id, ip_port)) { 515 client_id, ip_port)) {
509 /* If we can't replace bad nodes we try replacing good ones. */ 516 /* If we can't replace bad nodes we try replacing good ones. */
510 replace_good(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 517 if (!replace_good(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
511 client_id, ip_port, dht->friends_list[i].client_id); 518 client_id, ip_port, dht->friends_list[i].client_id))
512 } 519 used++;
513 } 520 } else
521 used++;
522 } else
523 used++;
514 } 524 }
525
526 return used;
515} 527}
516 528
517/* If client_id is a friend or us, update ret_ip_port 529/* If client_id is a friend or us, update ret_ip_port
518 * nodeclient_id is the id of the node that sent us this info. 530 * nodeclient_id is the id of the node that sent us this info.
519 */ 531 */
520static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) 532static int returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id)
521{ 533{
522 uint32_t i, j; 534 uint32_t i, j;
523 uint64_t temp_time = unix_time(); 535 uint64_t temp_time = unix_time();
@@ -539,10 +551,9 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint
539 dht->close_clientlist[i].assoc6.ret_timestamp = temp_time; 551 dht->close_clientlist[i].assoc6.ret_timestamp = temp_time;
540 } 552 }
541 553
542 return; 554 return 1;
543 } 555 }
544 } 556 }
545
546 } else { 557 } else {
547 for (i = 0; i < dht->num_friends; ++i) { 558 for (i = 0; i < dht->num_friends; ++i) {
548 if (id_equal(client_id, dht->friends_list[i].client_id)) { 559 if (id_equal(client_id, dht->friends_list[i].client_id)) {
@@ -556,13 +567,14 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint
556 dht->friends_list[i].client_list[j].assoc6.ret_timestamp = temp_time; 567 dht->friends_list[i].client_list[j].assoc6.ret_timestamp = temp_time;
557 } 568 }
558 569
559 return; 570 return 1;
560 } 571 }
561 } 572 }
562 } 573 }
563 } 574 }
564
565 } 575 }
576
577 return 0;
566} 578}
567 579
568/* checks if ip/port or ping_id are already in the list to get nodes 580/* checks if ip/port or ping_id are already in the list to get nodes
@@ -841,14 +853,15 @@ static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet,
841 return 1; 853 return 1;
842 854
843 /* store the address the *request* was sent to */ 855 /* store the address the *request* was sent to */
844 addto_lists(dht, dht->send_nodes[send_nodes_index - 1].ip_port, packet + 1); 856 int used = addto_lists(dht, dht->send_nodes[send_nodes_index - 1].ip_port, packet + 1);
845 857
846 if (dht->assoc) { 858 if (dht->assoc) {
847 IPPTs ippts; 859 IPPTs ippts;
848 860
849 ippts.ip_port = dht->send_nodes[send_nodes_index - 1].ip_port; 861 ippts.ip_port = dht->send_nodes[send_nodes_index - 1].ip_port;
850 ippts.timestamp = dht->send_nodes[send_nodes_index - 1].timestamp; 862 ippts.timestamp = dht->send_nodes[send_nodes_index - 1].timestamp;
851 Assoc_add_entry(dht->assoc, packet + 1, &ippts, &source); 863
864 Assoc_add_entry(dht->assoc, packet + 1, &ippts, &source, used ? 1 : 0);
852 } 865 }
853 866
854 *num_nodes_out = num_nodes; 867 *num_nodes_out = num_nodes;
@@ -879,13 +892,14 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
879 ipp.port = nodes4_list[i].ip_port.port; 892 ipp.port = nodes4_list[i].ip_port.port;
880 893
881 send_ping_request(dht->ping, ipp, nodes4_list[i].client_id); 894 send_ping_request(dht->ping, ipp, nodes4_list[i].client_id);
882 returnedip_ports(dht, ipp, nodes4_list[i].client_id, packet + 1); 895 int used = returnedip_ports(dht, ipp, nodes4_list[i].client_id, packet + 1);
883 896
884 if (dht->assoc) { 897 if (dht->assoc) {
885 IPPTs ippts; 898 IPPTs ippts;
886 ippts.ip_port = ipp; 899 ippts.ip_port = ipp;
887 ippts.timestamp = 0; 900 ippts.timestamp = 0;
888 Assoc_add_entry(dht->assoc, nodes4_list[i].client_id, &ippts, NULL); 901
902 Assoc_add_entry(dht->assoc, nodes4_list[i].client_id, &ippts, NULL, used ? 1 : 0);
889 } 903 }
890 } 904 }
891 905
@@ -909,13 +923,14 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
909 for (i = 0; i < num_nodes; i++) 923 for (i = 0; i < num_nodes; i++)
910 if (ipport_isset(&nodes_list[i].ip_port)) { 924 if (ipport_isset(&nodes_list[i].ip_port)) {
911 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); 925 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id);
912 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 926 int used = returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
913 927
914 if (dht->assoc) { 928 if (dht->assoc) {
915 IPPTs ippts; 929 IPPTs ippts;
916 ippts.ip_port = nodes_list[i].ip_port; 930 ippts.ip_port = nodes_list[i].ip_port;
917 ippts.timestamp = 0; 931 ippts.timestamp = 0;
918 Assoc_add_entry(dht->assoc, nodes_list[i].client_id, &ippts, NULL); 932
933 Assoc_add_entry(dht->assoc, nodes_list[i].client_id, &ippts, NULL, used ? 1 : 0);
919 } 934 }
920 } 935 }
921 936
@@ -1135,7 +1150,8 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
1135 IPPTs ippts; 1150 IPPTs ippts;
1136 ippts.ip_port = ip_port; 1151 ippts.ip_port = ip_port;
1137 ippts.timestamp = 0; 1152 ippts.timestamp = 0;
1138 Assoc_add_entry(dht->assoc, public_key, &ippts, NULL); 1153
1154 Assoc_add_entry(dht->assoc, public_key, &ippts, NULL, 0);
1139 } 1155 }
1140 1156
1141 getnodes(dht, ip_port, public_key, dht->c->self_public_key); 1157 getnodes(dht, ip_port, public_key, dht->c->self_public_key);
@@ -1609,8 +1625,7 @@ DHT *new_DHT(Net_Crypto *c)
1609 init_cryptopackets(dht); 1625 init_cryptopackets(dht);
1610 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); 1626 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
1611 1627
1612 /* dhtassoc is not mandatory for now */ 1628 dht->assoc = new_Assoc_default(dht->c->self_public_key);
1613 dht->assoc = new_Assoc(dht);
1614 1629
1615 return dht; 1630 return dht;
1616} 1631}