diff options
author | zugz <mbays+tox@sdf.org> | 2017-01-19 18:51:14 +0100 |
---|---|---|
committer | zugz <mbays+tox@sdf.org> | 2017-01-21 22:08:52 +0100 |
commit | b630121f2f659027e1c9f00cd97087ef34e95677 (patch) | |
tree | 7972d498fa05b0955c684c83b79bf12000cb7cf2 /toxcore/DHT.c | |
parent | f185834e9afe83a2bb06e015a3e41b4ac97b48c3 (diff) |
reduce thread-unsafe use of static variables
- rework ip_ntoa() to avoid use of static variables
- rework sort_client_list() to avoid use of static variables
- move static 'lastdump' into Messenger struct
- rework ID2String() to avoid use of static variables; rename to id_to_string()
- fetch_broadcast_info(): attempt to mitigate risks from concurrent execution
- current_time_monotonic(): attempt to mitigate risks from concurrent execution
- comment on non-thread-safety of unix_time_update
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 776313ca..f82c1061 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -538,9 +538,12 @@ static int client_or_ip_port_in_list(Logger *log, Client_data *list, uint16_t le | |||
538 | if (ip_port.ip.family == AF_INET) { | 538 | if (ip_port.ip.family == AF_INET) { |
539 | 539 | ||
540 | if (!ipport_equal(&list[i].assoc4.ip_port, &ip_port)) { | 540 | if (!ipport_equal(&list[i].assoc4.ip_port, &ip_port)) { |
541 | char ip_str[IP_NTOA_LEN]; | ||
541 | LOGGER_TRACE(log, "coipil[%u]: switching ipv4 from %s:%u to %s:%u", i, | 542 | LOGGER_TRACE(log, "coipil[%u]: switching ipv4 from %s:%u to %s:%u", i, |
542 | ip_ntoa(&list[i].assoc4.ip_port.ip), ntohs(list[i].assoc4.ip_port.port), | 543 | ip_ntoa(&list[i].assoc4.ip_port.ip, ip_str, sizeof(ip_str)), |
543 | ip_ntoa(&ip_port.ip), ntohs(ip_port.port)); | 544 | ntohs(list[i].assoc4.ip_port.port), |
545 | ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)), | ||
546 | ntohs(ip_port.port)); | ||
544 | } | 547 | } |
545 | 548 | ||
546 | if (LAN_ip(list[i].assoc4.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) { | 549 | if (LAN_ip(list[i].assoc4.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) { |
@@ -552,9 +555,12 @@ static int client_or_ip_port_in_list(Logger *log, Client_data *list, uint16_t le | |||
552 | } else if (ip_port.ip.family == AF_INET6) { | 555 | } else if (ip_port.ip.family == AF_INET6) { |
553 | 556 | ||
554 | if (!ipport_equal(&list[i].assoc6.ip_port, &ip_port)) { | 557 | if (!ipport_equal(&list[i].assoc6.ip_port, &ip_port)) { |
558 | char ip_str[IP_NTOA_LEN]; | ||
555 | LOGGER_TRACE(log, "coipil[%u]: switching ipv6 from %s:%u to %s:%u", i, | 559 | LOGGER_TRACE(log, "coipil[%u]: switching ipv6 from %s:%u to %s:%u", i, |
556 | ip_ntoa(&list[i].assoc6.ip_port.ip), ntohs(list[i].assoc6.ip_port.port), | 560 | ip_ntoa(&list[i].assoc6.ip_port.ip, ip_str, sizeof(ip_str)), |
557 | ip_ntoa(&ip_port.ip), ntohs(ip_port.port)); | 561 | ntohs(list[i].assoc6.ip_port.port), |
562 | ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)), | ||
563 | ntohs(ip_port.port)); | ||
558 | } | 564 | } |
559 | 565 | ||
560 | if (LAN_ip(list[i].assoc6.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) { | 566 | if (LAN_ip(list[i].assoc6.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) { |
@@ -785,12 +791,20 @@ int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *node | |||
785 | return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, is_LAN, want_good); | 791 | return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, is_LAN, want_good); |
786 | } | 792 | } |
787 | 793 | ||
788 | static uint8_t cmp_public_key[CRYPTO_PUBLIC_KEY_SIZE]; | 794 | typedef struct { |
795 | const uint8_t *base_public_key; | ||
796 | Client_data entry; | ||
797 | } Cmp_data; | ||
798 | |||
789 | static int cmp_dht_entry(const void *a, const void *b) | 799 | static int cmp_dht_entry(const void *a, const void *b) |
790 | { | 800 | { |
791 | Client_data entry1, entry2; | 801 | Cmp_data cmp1, cmp2; |
792 | memcpy(&entry1, a, sizeof(Client_data)); | 802 | memcpy(&cmp1, a, sizeof(Cmp_data)); |
793 | memcpy(&entry2, b, sizeof(Client_data)); | 803 | memcpy(&cmp2, b, sizeof(Cmp_data)); |
804 | Client_data entry1 = cmp1.entry; | ||
805 | Client_data entry2 = cmp2.entry; | ||
806 | const uint8_t *cmp_public_key = cmp1.base_public_key; | ||
807 | |||
794 | int t1 = is_timeout(entry1.assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(entry1.assoc6.timestamp, BAD_NODE_TIMEOUT); | 808 | int t1 = is_timeout(entry1.assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(entry1.assoc6.timestamp, BAD_NODE_TIMEOUT); |
795 | int t2 = is_timeout(entry2.assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(entry2.assoc6.timestamp, BAD_NODE_TIMEOUT); | 809 | int t2 = is_timeout(entry2.assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(entry2.assoc6.timestamp, BAD_NODE_TIMEOUT); |
796 | 810 | ||
@@ -851,8 +865,20 @@ static unsigned int store_node_ok(const Client_data *client, const uint8_t *publ | |||
851 | 865 | ||
852 | static void sort_client_list(Client_data *list, unsigned int length, const uint8_t *comp_public_key) | 866 | static void sort_client_list(Client_data *list, unsigned int length, const uint8_t *comp_public_key) |
853 | { | 867 | { |
854 | memcpy(cmp_public_key, comp_public_key, CRYPTO_PUBLIC_KEY_SIZE); | 868 | // Pass comp_public_key to qsort with each Client_data entry, so the |
855 | qsort(list, length, sizeof(Client_data), cmp_dht_entry); | 869 | // comparison function cmp_dht_entry can use it as the base of comparison. |
870 | Cmp_data cmp_list[length]; | ||
871 | |||
872 | for (uint32_t i = 0; i < length; i++) { | ||
873 | cmp_list[i].base_public_key = comp_public_key; | ||
874 | cmp_list[i].entry = list[i]; | ||
875 | } | ||
876 | |||
877 | qsort(cmp_list, length, sizeof(Cmp_data), cmp_dht_entry); | ||
878 | |||
879 | for (uint32_t i = 0; i < length; i++) { | ||
880 | list[i] = cmp_list[i].entry; | ||
881 | } | ||
856 | } | 882 | } |
857 | 883 | ||
858 | /* Replace a first bad (or empty) node with this one | 884 | /* Replace a first bad (or empty) node with this one |