diff options
author | Coren[m] <Break@Ocean> | 2013-11-17 01:04:49 +0100 |
---|---|---|
committer | Coren[m] <Break@Ocean> | 2013-11-17 01:05:00 +0100 |
commit | b132c92b3ae3aeee293a4e815336cac76c7cfe69 (patch) | |
tree | 1878864ea5a27d571ac758bb5ad2875f0b9460a6 /toxcore/DHT.c | |
parent | 0d8329b3a9b16cd6089810e61ce958fde00046b8 (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.c | 65 |
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 */ | ||
429 | static int replace_good( Client_data *list, | 431 | static 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 | */ |
482 | void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) | 486 | int 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 | */ |
520 | static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) | 532 | static 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 | } |