summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorzugz <mbays+tox@sdf.org>2017-01-19 18:51:14 +0100
committerzugz <mbays+tox@sdf.org>2017-01-21 22:08:52 +0100
commitb630121f2f659027e1c9f00cd97087ef34e95677 (patch)
tree7972d498fa05b0955c684c83b79bf12000cb7cf2 /toxcore/DHT.c
parentf185834e9afe83a2bb06e015a3e41b4ac97b48c3 (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.c46
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
788static uint8_t cmp_public_key[CRYPTO_PUBLIC_KEY_SIZE]; 794typedef struct {
795 const uint8_t *base_public_key;
796 Client_data entry;
797} Cmp_data;
798
789static int cmp_dht_entry(const void *a, const void *b) 799static 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
852static void sort_client_list(Client_data *list, unsigned int length, const uint8_t *comp_public_key) 866static 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