diff options
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 203ffa4c..d28c1ecf 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -600,6 +600,48 @@ int get_close_nodes(const DHT *dht, const uint8_t *client_id, Node_format *nodes | |||
600 | #endif | 600 | #endif |
601 | } | 601 | } |
602 | 602 | ||
603 | static uint8_t cmp_public_key[crypto_box_PUBLICKEYBYTES]; | ||
604 | static int cmp_dht_entry(const void *a, const void *b) | ||
605 | { | ||
606 | Client_data entry1, entry2; | ||
607 | memcpy(&entry1, a, sizeof(Client_data)); | ||
608 | memcpy(&entry2, b, sizeof(Client_data)); | ||
609 | int t1 = is_timeout(entry1.assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(entry1.assoc6.timestamp, BAD_NODE_TIMEOUT); | ||
610 | int t2 = is_timeout(entry2.assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(entry2.assoc6.timestamp, BAD_NODE_TIMEOUT); | ||
611 | |||
612 | if (t1 && t2) | ||
613 | return 0; | ||
614 | |||
615 | if (t1) | ||
616 | return -1; | ||
617 | |||
618 | if (t2) | ||
619 | return 1; | ||
620 | |||
621 | t1 = hardening_correct(&entry1.assoc4.hardening) != HARDENING_ALL_OK | ||
622 | && hardening_correct(&entry1.assoc6.hardening) != HARDENING_ALL_OK; | ||
623 | t2 = hardening_correct(&entry2.assoc4.hardening) != HARDENING_ALL_OK | ||
624 | && hardening_correct(&entry2.assoc6.hardening) != HARDENING_ALL_OK; | ||
625 | |||
626 | if (t1 != t2) { | ||
627 | if (t1) | ||
628 | return -1; | ||
629 | |||
630 | if (t2) | ||
631 | return 1; | ||
632 | } | ||
633 | |||
634 | int close = id_closest(cmp_public_key, entry1.client_id, entry2.client_id); | ||
635 | |||
636 | if (close == 1) | ||
637 | return 1; | ||
638 | |||
639 | if (close == 2) | ||
640 | return -1; | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
603 | /* Replace a first bad (or empty) node with this one | 645 | /* Replace a first bad (or empty) node with this one |
604 | * or replace a possibly bad node (tests failed or not done yet) | 646 | * or replace a possibly bad node (tests failed or not done yet) |
605 | * that is further than any other in the list | 647 | * that is further than any other in the list |
@@ -622,40 +664,15 @@ static int replace_all( Client_data *list, | |||
622 | if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6)) | 664 | if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6)) |
623 | return 0; | 665 | return 0; |
624 | 666 | ||
625 | uint32_t i, replace = ~0, bad = ~0, possibly_bad = ~0, good = ~0; | 667 | _Bool replace = 0; |
626 | 668 | ||
627 | for (i = 0; i < length; ++i) { | 669 | memcpy(cmp_public_key, comp_client_id, crypto_box_PUBLICKEYBYTES); |
628 | 670 | qsort(list, length, sizeof(Client_data), cmp_dht_entry); | |
629 | Client_data *client = &list[i]; | ||
630 | |||
631 | if (is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && | ||
632 | is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) { | ||
633 | // "bad" node | ||
634 | bad = i; | ||
635 | break; | ||
636 | } else if (hardening_correct(&client->assoc4.hardening) != HARDENING_ALL_OK && | ||
637 | hardening_correct(&client->assoc6.hardening) != HARDENING_ALL_OK) { | ||
638 | // "possibly bad" node | ||
639 | if (possibly_bad == (uint32_t)~0 || | ||
640 | id_closest(comp_client_id, list[possibly_bad].client_id, list[i].client_id) == 1) | ||
641 | possibly_bad = i; | ||
642 | } else { | ||
643 | // "good" node | ||
644 | if (good == (uint32_t)~0 || | ||
645 | id_closest(comp_client_id, list[good].client_id, list[i].client_id) == 1) | ||
646 | good = i; | ||
647 | } | ||
648 | } | ||
649 | 671 | ||
650 | if (bad != (uint32_t)~0) | 672 | Client_data *client = &list[0]; |
651 | replace = bad; | ||
652 | else if (possibly_bad != (uint32_t)~0) | ||
653 | replace = possibly_bad; | ||
654 | else if (good != (uint32_t)~0 && id_closest(comp_client_id, list[good].client_id, client_id) == 2) | ||
655 | replace = good; | ||
656 | 673 | ||
657 | if (replace != (uint32_t)~0) { | 674 | if ((is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) |
658 | Client_data *client = &list[replace]; | 675 | || (id_closest(comp_client_id, client->client_id, client_id) == 2)) { |
659 | IPPTsPng *ipptp_write = NULL; | 676 | IPPTsPng *ipptp_write = NULL; |
660 | IPPTsPng *ipptp_clear = NULL; | 677 | IPPTsPng *ipptp_clear = NULL; |
661 | 678 | ||