diff options
author | sudden6 <sudden6@gmx.at> | 2019-09-07 00:02:26 +0200 |
---|---|---|
committer | sudden6 <sudden6@gmx.at> | 2019-12-23 23:48:15 +0100 |
commit | 6338cb46ad99dbc2806976aefabbf2e98476ebda (patch) | |
tree | 07789a78fe147e8ffb183e38968cf5398fd4cd71 | |
parent | abfd90d25b38581db1e831ba5d1aba35c2d8147a (diff) |
fix invalid use of mutex
- Moving a pthread_mutex in memory (e.g. via realloc()) is undefined
behavior.
- add a state for allocated but not yet used crypto connections
- change crypto_connection_status signature
-rw-r--r-- | toxcore/Messenger.c | 2 | ||||
-rw-r--r-- | toxcore/net_crypto.c | 187 | ||||
-rw-r--r-- | toxcore/net_crypto.h | 16 |
3 files changed, 116 insertions, 89 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index ae2d1d3b..2dccd4a8 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -458,6 +458,8 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber) | |||
458 | bool direct_connected = 0; | 458 | bool direct_connected = 0; |
459 | unsigned int num_online_relays = 0; | 459 | unsigned int num_online_relays = 0; |
460 | int crypt_conn_id = friend_connection_crypt_connection_id(m->fr_c, m->friendlist[friendnumber].friendcon_id); | 460 | int crypt_conn_id = friend_connection_crypt_connection_id(m->fr_c, m->friendlist[friendnumber].friendcon_id); |
461 | |||
462 | // FIXME(sudden6): handle return value | ||
461 | crypto_connection_status(m->net_crypto, crypt_conn_id, &direct_connected, &num_online_relays); | 463 | crypto_connection_status(m->net_crypto, crypt_conn_id, &direct_connected, &num_online_relays); |
462 | 464 | ||
463 | if (direct_connected) { | 465 | if (direct_connected) { |
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 3ace3bea..da525a1f 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -48,6 +48,18 @@ typedef struct Packets_Array { | |||
48 | uint32_t buffer_end; /* packet numbers in array: {buffer_start, buffer_end) */ | 48 | uint32_t buffer_end; /* packet numbers in array: {buffer_start, buffer_end) */ |
49 | } Packets_Array; | 49 | } Packets_Array; |
50 | 50 | ||
51 | typedef enum Crypto_Conn_State { | ||
52 | CRYPTO_CONN_FREE = 0, /* the connection slot is free; this value is 0 so it is valid after | ||
53 | * crypto_memzero(...) of the parent struct | ||
54 | */ | ||
55 | CRYPTO_CONN_NO_CONNECTION, /* the connection is allocated, but not yet used */ | ||
56 | CRYPTO_CONN_COOKIE_REQUESTING, /* we are sending cookie request packets */ | ||
57 | CRYPTO_CONN_HANDSHAKE_SENT, /* we are sending handshake packets */ | ||
58 | CRYPTO_CONN_NOT_CONFIRMED, /* we are sending handshake packets; | ||
59 | * we have received one from the other, but no data */ | ||
60 | CRYPTO_CONN_ESTABLISHED, /* the connection is established */ | ||
61 | } Crypto_Conn_State; | ||
62 | |||
51 | typedef struct Crypto_Connection { | 63 | typedef struct Crypto_Connection { |
52 | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ | 64 | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ |
53 | uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ | 65 | uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ |
@@ -56,14 +68,7 @@ typedef struct Crypto_Connection { | |||
56 | uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private key for this session. */ | 68 | uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private key for this session. */ |
57 | uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ | 69 | uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ |
58 | uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. */ | 70 | uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. */ |
59 | /** | 71 | Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ |
60 | * 0 if no connection, | ||
61 | * 1 we are sending cookie request packets, | ||
62 | * 2 if we are sending handshake packets, | ||
63 | * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), | ||
64 | * 4 if the connection is established. | ||
65 | */ | ||
66 | Crypto_Conn_State status; | ||
67 | uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ | 72 | uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ |
68 | uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ | 73 | uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ |
69 | 74 | ||
@@ -125,7 +130,8 @@ typedef struct Crypto_Connection { | |||
125 | 130 | ||
126 | uint8_t maximum_speed_reached; | 131 | uint8_t maximum_speed_reached; |
127 | 132 | ||
128 | pthread_mutex_t mutex; | 133 | /* Must be a pointer, because the struct is moved in memory */ |
134 | pthread_mutex_t *mutex; | ||
129 | 135 | ||
130 | dht_pk_cb *dht_pk_callback; | 136 | dht_pk_cb *dht_pk_callback; |
131 | void *dht_pk_callback_object; | 137 | void *dht_pk_callback_object; |
@@ -193,7 +199,9 @@ static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_conn | |||
193 | return 1; | 199 | return 1; |
194 | } | 200 | } |
195 | 201 | ||
196 | if (c->crypto_connections[crypt_connection_id].status == CRYPTO_CONN_NO_CONNECTION) { | 202 | const Crypto_Conn_State status = c->crypto_connections[crypt_connection_id].status; |
203 | |||
204 | if (status == CRYPTO_CONN_NO_CONNECTION || status == CRYPTO_CONN_FREE) { | ||
197 | return 1; | 205 | return 1; |
198 | } | 206 | } |
199 | 207 | ||
@@ -680,21 +688,23 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t | |||
680 | 688 | ||
681 | int direct_send_attempt = 0; | 689 | int direct_send_attempt = 0; |
682 | 690 | ||
683 | pthread_mutex_lock(&conn->mutex); | 691 | pthread_mutex_lock(conn->mutex); |
684 | IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); | 692 | IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); |
685 | 693 | ||
686 | // TODO(irungentoo): on bad networks, direct connections might not last indefinitely. | 694 | // TODO(irungentoo): on bad networks, direct connections might not last indefinitely. |
687 | if (!net_family_is_unspec(ip_port.ip.family)) { | 695 | if (!net_family_is_unspec(ip_port.ip.family)) { |
688 | bool direct_connected = 0; | 696 | bool direct_connected = 0; |
697 | |||
698 | // FIXME(sudden6): handle return value | ||
689 | crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr); | 699 | crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr); |
690 | 700 | ||
691 | if (direct_connected) { | 701 | if (direct_connected) { |
692 | if ((uint32_t)sendpacket(dht_get_net(c->dht), ip_port, data, length) == length) { | 702 | if ((uint32_t)sendpacket(dht_get_net(c->dht), ip_port, data, length) == length) { |
693 | pthread_mutex_unlock(&conn->mutex); | 703 | pthread_mutex_unlock(conn->mutex); |
694 | return 0; | 704 | return 0; |
695 | } | 705 | } |
696 | 706 | ||
697 | pthread_mutex_unlock(&conn->mutex); | 707 | pthread_mutex_unlock(conn->mutex); |
698 | return -1; | 708 | return -1; |
699 | } | 709 | } |
700 | 710 | ||
@@ -710,18 +720,18 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t | |||
710 | } | 720 | } |
711 | } | 721 | } |
712 | 722 | ||
713 | pthread_mutex_unlock(&conn->mutex); | 723 | pthread_mutex_unlock(conn->mutex); |
714 | pthread_mutex_lock(&c->tcp_mutex); | 724 | pthread_mutex_lock(&c->tcp_mutex); |
715 | int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length); | 725 | int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length); |
716 | pthread_mutex_unlock(&c->tcp_mutex); | 726 | pthread_mutex_unlock(&c->tcp_mutex); |
717 | 727 | ||
718 | pthread_mutex_lock(&conn->mutex); | 728 | pthread_mutex_lock(conn->mutex); |
719 | 729 | ||
720 | if (ret == 0) { | 730 | if (ret == 0) { |
721 | conn->last_tcp_sent = current_time_monotonic(c->mono_time); | 731 | conn->last_tcp_sent = current_time_monotonic(c->mono_time); |
722 | } | 732 | } |
723 | 733 | ||
724 | pthread_mutex_unlock(&conn->mutex); | 734 | pthread_mutex_unlock(conn->mutex); |
725 | 735 | ||
726 | if (ret == 0 || direct_send_attempt) { | 736 | if (ret == 0 || direct_send_attempt) { |
727 | return 0; | 737 | return 0; |
@@ -1073,19 +1083,19 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ | |||
1073 | return -1; | 1083 | return -1; |
1074 | } | 1084 | } |
1075 | 1085 | ||
1076 | pthread_mutex_lock(&conn->mutex); | 1086 | pthread_mutex_lock(conn->mutex); |
1077 | VLA(uint8_t, packet, 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); | 1087 | VLA(uint8_t, packet, 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); |
1078 | packet[0] = NET_PACKET_CRYPTO_DATA; | 1088 | packet[0] = NET_PACKET_CRYPTO_DATA; |
1079 | memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); | 1089 | memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); |
1080 | const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); | 1090 | const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); |
1081 | 1091 | ||
1082 | if (len + 1 + sizeof(uint16_t) != SIZEOF_VLA(packet)) { | 1092 | if (len + 1 + sizeof(uint16_t) != SIZEOF_VLA(packet)) { |
1083 | pthread_mutex_unlock(&conn->mutex); | 1093 | pthread_mutex_unlock(conn->mutex); |
1084 | return -1; | 1094 | return -1; |
1085 | } | 1095 | } |
1086 | 1096 | ||
1087 | increment_nonce(conn->sent_nonce); | 1097 | increment_nonce(conn->sent_nonce); |
1088 | pthread_mutex_unlock(&conn->mutex); | 1098 | pthread_mutex_unlock(conn->mutex); |
1089 | 1099 | ||
1090 | return send_packet_to(c, crypt_connection_id, packet, SIZEOF_VLA(packet)); | 1100 | return send_packet_to(c, crypt_connection_id, packet, SIZEOF_VLA(packet)); |
1091 | } | 1101 | } |
@@ -1172,9 +1182,9 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons | |||
1172 | dt.sent_time = 0; | 1182 | dt.sent_time = 0; |
1173 | dt.length = length; | 1183 | dt.length = length; |
1174 | memcpy(dt.data, data, length); | 1184 | memcpy(dt.data, data, length); |
1175 | pthread_mutex_lock(&conn->mutex); | 1185 | pthread_mutex_lock(conn->mutex); |
1176 | int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt); | 1186 | int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt); |
1177 | pthread_mutex_unlock(&conn->mutex); | 1187 | pthread_mutex_unlock(conn->mutex); |
1178 | 1188 | ||
1179 | if (packet_num == -1) { | 1189 | if (packet_num == -1) { |
1180 | return -1; | 1190 | return -1; |
@@ -1578,9 +1588,9 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const | |||
1578 | } | 1588 | } |
1579 | 1589 | ||
1580 | while (1) { | 1590 | while (1) { |
1581 | pthread_mutex_lock(&conn->mutex); | 1591 | pthread_mutex_lock(conn->mutex); |
1582 | int ret = read_data_beg_buffer(c->log, &conn->recv_array, &dt); | 1592 | int ret = read_data_beg_buffer(c->log, &conn->recv_array, &dt); |
1583 | pthread_mutex_unlock(&conn->mutex); | 1593 | pthread_mutex_unlock(conn->mutex); |
1584 | 1594 | ||
1585 | if (ret == -1) { | 1595 | if (ret == -1) { |
1586 | break; | 1596 | break; |
@@ -1748,12 +1758,6 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) | |||
1748 | */ | 1758 | */ |
1749 | static int create_crypto_connection(Net_Crypto *c) | 1759 | static int create_crypto_connection(Net_Crypto *c) |
1750 | { | 1760 | { |
1751 | for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { | ||
1752 | if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) { | ||
1753 | return i; | ||
1754 | } | ||
1755 | } | ||
1756 | |||
1757 | while (1) { /* TODO(irungentoo): is this really the best way to do this? */ | 1761 | while (1) { /* TODO(irungentoo): is this really the best way to do this? */ |
1758 | pthread_mutex_lock(&c->connections_mutex); | 1762 | pthread_mutex_lock(&c->connections_mutex); |
1759 | 1763 | ||
@@ -1766,21 +1770,42 @@ static int create_crypto_connection(Net_Crypto *c) | |||
1766 | 1770 | ||
1767 | int id = -1; | 1771 | int id = -1; |
1768 | 1772 | ||
1769 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == 0) { | 1773 | for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { |
1770 | id = c->crypto_connections_length; | 1774 | if (c->crypto_connections[i].status == CRYPTO_CONN_FREE) { |
1771 | ++c->crypto_connections_length; | 1775 | id = i; |
1772 | memset(&c->crypto_connections[id], 0, sizeof(Crypto_Connection)); | 1776 | break; |
1777 | } | ||
1778 | } | ||
1779 | |||
1780 | if (id == -1) { | ||
1781 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == 0) { | ||
1782 | id = c->crypto_connections_length; | ||
1783 | ++c->crypto_connections_length; | ||
1784 | memset(&c->crypto_connections[id], 0, sizeof(Crypto_Connection)); | ||
1785 | } | ||
1786 | } | ||
1787 | |||
1788 | if (id != -1) { | ||
1773 | // Memsetting float/double to 0 is non-portable, so we explicitly set them to 0 | 1789 | // Memsetting float/double to 0 is non-portable, so we explicitly set them to 0 |
1774 | c->crypto_connections[id].packet_recv_rate = 0; | 1790 | c->crypto_connections[id].packet_recv_rate = 0; |
1775 | c->crypto_connections[id].packet_send_rate = 0; | 1791 | c->crypto_connections[id].packet_send_rate = 0; |
1776 | c->crypto_connections[id].last_packets_left_rem = 0; | 1792 | c->crypto_connections[id].last_packets_left_rem = 0; |
1777 | c->crypto_connections[id].packet_send_rate_requested = 0; | 1793 | c->crypto_connections[id].packet_send_rate_requested = 0; |
1778 | c->crypto_connections[id].last_packets_left_requested_rem = 0; | 1794 | c->crypto_connections[id].last_packets_left_requested_rem = 0; |
1795 | c->crypto_connections[id].mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); | ||
1796 | |||
1797 | if (c->crypto_connections[id].mutex == nullptr) { | ||
1798 | pthread_mutex_unlock(&c->connections_mutex); | ||
1799 | return -1; | ||
1800 | } | ||
1779 | 1801 | ||
1780 | if (pthread_mutex_init(&c->crypto_connections[id].mutex, nullptr) != 0) { | 1802 | if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { |
1803 | free(c->crypto_connections[id].mutex); | ||
1781 | pthread_mutex_unlock(&c->connections_mutex); | 1804 | pthread_mutex_unlock(&c->connections_mutex); |
1782 | return -1; | 1805 | return -1; |
1783 | } | 1806 | } |
1807 | |||
1808 | c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; | ||
1784 | } | 1809 | } |
1785 | 1810 | ||
1786 | pthread_mutex_unlock(&c->connections_mutex); | 1811 | pthread_mutex_unlock(&c->connections_mutex); |
@@ -1794,21 +1819,29 @@ static int create_crypto_connection(Net_Crypto *c) | |||
1794 | */ | 1819 | */ |
1795 | static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) | 1820 | static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) |
1796 | { | 1821 | { |
1797 | if (crypt_connection_id_not_valid(c, crypt_connection_id)) { | 1822 | if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) { |
1823 | return -1; | ||
1824 | } | ||
1825 | |||
1826 | if (c->crypto_connections == nullptr) { | ||
1827 | return -1; | ||
1828 | } | ||
1829 | |||
1830 | const Crypto_Conn_State status = c->crypto_connections[crypt_connection_id].status; | ||
1831 | |||
1832 | if (status == CRYPTO_CONN_FREE) { | ||
1798 | return -1; | 1833 | return -1; |
1799 | } | 1834 | } |
1800 | 1835 | ||
1801 | uint32_t i; | 1836 | uint32_t i; |
1802 | 1837 | ||
1803 | /* Keep mutex, only destroy it when connection is realloced out. */ | 1838 | pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); |
1804 | pthread_mutex_t mutex = c->crypto_connections[crypt_connection_id].mutex; | 1839 | free(c->crypto_connections[crypt_connection_id].mutex); |
1805 | crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); | 1840 | crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); |
1806 | c->crypto_connections[crypt_connection_id].mutex = mutex; | ||
1807 | 1841 | ||
1842 | /* check if we can resize the connections array */ | ||
1808 | for (i = c->crypto_connections_length; i != 0; --i) { | 1843 | for (i = c->crypto_connections_length; i != 0; --i) { |
1809 | if (c->crypto_connections[i - 1].status == CRYPTO_CONN_NO_CONNECTION) { | 1844 | if (c->crypto_connections[i - 1].status != CRYPTO_CONN_FREE) { |
1810 | pthread_mutex_destroy(&c->crypto_connections[i - 1].mutex); | ||
1811 | } else { | ||
1812 | break; | 1845 | break; |
1813 | } | 1846 | } |
1814 | } | 1847 | } |
@@ -1829,10 +1862,12 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) | |||
1829 | static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key) | 1862 | static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key) |
1830 | { | 1863 | { |
1831 | for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { | 1864 | for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { |
1832 | if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION) { | 1865 | if (crypt_connection_id_not_valid(c, i)) { |
1833 | if (public_key_cmp(public_key, c->crypto_connections[i].public_key) == 0) { | 1866 | continue; |
1834 | return i; | 1867 | } |
1835 | } | 1868 | |
1869 | if (public_key_cmp(public_key, c->crypto_connections[i].public_key) == 0) { | ||
1870 | return i; | ||
1836 | } | 1871 | } |
1837 | } | 1872 | } |
1838 | 1873 | ||
@@ -1975,6 +2010,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) | |||
1975 | Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; | 2010 | Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; |
1976 | 2011 | ||
1977 | if (n_c->cookie_length != COOKIE_LENGTH) { | 2012 | if (n_c->cookie_length != COOKIE_LENGTH) { |
2013 | wipe_crypto_connection(c, crypt_connection_id); | ||
1978 | return -1; | 2014 | return -1; |
1979 | } | 2015 | } |
1980 | 2016 | ||
@@ -1983,6 +2019,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) | |||
1983 | pthread_mutex_unlock(&c->tcp_mutex); | 2019 | pthread_mutex_unlock(&c->tcp_mutex); |
1984 | 2020 | ||
1985 | if (connection_number_tcp == -1) { | 2021 | if (connection_number_tcp == -1) { |
2022 | wipe_crypto_connection(c, crypt_connection_id); | ||
1986 | return -1; | 2023 | return -1; |
1987 | } | 2024 | } |
1988 | 2025 | ||
@@ -1999,7 +2036,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) | |||
1999 | pthread_mutex_lock(&c->tcp_mutex); | 2036 | pthread_mutex_lock(&c->tcp_mutex); |
2000 | kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); | 2037 | kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); |
2001 | pthread_mutex_unlock(&c->tcp_mutex); | 2038 | pthread_mutex_unlock(&c->tcp_mutex); |
2002 | conn->status = CRYPTO_CONN_NO_CONNECTION; | 2039 | wipe_crypto_connection(c, crypt_connection_id); |
2003 | return -1; | 2040 | return -1; |
2004 | } | 2041 | } |
2005 | 2042 | ||
@@ -2039,6 +2076,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u | |||
2039 | pthread_mutex_unlock(&c->tcp_mutex); | 2076 | pthread_mutex_unlock(&c->tcp_mutex); |
2040 | 2077 | ||
2041 | if (connection_number_tcp == -1) { | 2078 | if (connection_number_tcp == -1) { |
2079 | wipe_crypto_connection(c, crypt_connection_id); | ||
2042 | return -1; | 2080 | return -1; |
2043 | } | 2081 | } |
2044 | 2082 | ||
@@ -2062,7 +2100,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u | |||
2062 | pthread_mutex_lock(&c->tcp_mutex); | 2100 | pthread_mutex_lock(&c->tcp_mutex); |
2063 | kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); | 2101 | kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); |
2064 | pthread_mutex_unlock(&c->tcp_mutex); | 2102 | pthread_mutex_unlock(&c->tcp_mutex); |
2065 | conn->status = CRYPTO_CONN_NO_CONNECTION; | 2103 | wipe_crypto_connection(c, crypt_connection_id); |
2066 | return -1; | 2104 | return -1; |
2067 | } | 2105 | } |
2068 | 2106 | ||
@@ -2259,19 +2297,24 @@ static void do_tcp(Net_Crypto *c, void *userdata) | |||
2259 | continue; | 2297 | continue; |
2260 | } | 2298 | } |
2261 | 2299 | ||
2262 | if (conn->status == CRYPTO_CONN_ESTABLISHED) { | 2300 | if (conn->status != CRYPTO_CONN_ESTABLISHED) { |
2263 | bool direct_connected = 0; | 2301 | continue; |
2264 | crypto_connection_status(c, i, &direct_connected, nullptr); | 2302 | } |
2265 | 2303 | ||
2266 | if (direct_connected) { | 2304 | bool direct_connected = 0; |
2267 | pthread_mutex_lock(&c->tcp_mutex); | 2305 | |
2268 | set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0); | 2306 | if (!crypto_connection_status(c, i, &direct_connected, nullptr)) { |
2269 | pthread_mutex_unlock(&c->tcp_mutex); | 2307 | continue; |
2270 | } else { | 2308 | } |
2271 | pthread_mutex_lock(&c->tcp_mutex); | 2309 | |
2272 | set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1); | 2310 | if (direct_connected) { |
2273 | pthread_mutex_unlock(&c->tcp_mutex); | 2311 | pthread_mutex_lock(&c->tcp_mutex); |
2274 | } | 2312 | set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0); |
2313 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2314 | } else { | ||
2315 | pthread_mutex_lock(&c->tcp_mutex); | ||
2316 | set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1); | ||
2317 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2275 | } | 2318 | } |
2276 | } | 2319 | } |
2277 | } | 2320 | } |
@@ -2425,7 +2468,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet | |||
2425 | return -1; | 2468 | return -1; |
2426 | } | 2469 | } |
2427 | 2470 | ||
2428 | pthread_mutex_lock(&conn->mutex); | 2471 | pthread_mutex_lock(conn->mutex); |
2429 | 2472 | ||
2430 | if (net_family_is_ipv4(source.ip.family)) { | 2473 | if (net_family_is_ipv4(source.ip.family)) { |
2431 | conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time); | 2474 | conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time); |
@@ -2433,7 +2476,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet | |||
2433 | conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time); | 2476 | conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time); |
2434 | } | 2477 | } |
2435 | 2478 | ||
2436 | pthread_mutex_unlock(&conn->mutex); | 2479 | pthread_mutex_unlock(conn->mutex); |
2437 | return 0; | 2480 | return 0; |
2438 | } | 2481 | } |
2439 | 2482 | ||
@@ -2542,6 +2585,7 @@ static void send_crypto_packets(Net_Crypto *c) | |||
2542 | (CONGESTION_QUEUE_ARRAY_SIZE * CONGESTION_LAST_SENT_ARRAY_SIZE); | 2585 | (CONGESTION_QUEUE_ARRAY_SIZE * CONGESTION_LAST_SENT_ARRAY_SIZE); |
2543 | 2586 | ||
2544 | bool direct_connected = 0; | 2587 | bool direct_connected = 0; |
2588 | /* return value can be ignored since the `if` above ensures the connection is established */ | ||
2545 | crypto_connection_status(c, i, &direct_connected, nullptr); | 2589 | crypto_connection_status(c, i, &direct_connected, nullptr); |
2546 | 2590 | ||
2547 | /* When switching from TCP to UDP, don't change the packet send rate for CONGESTION_EVENT_TIMEOUT ms. */ | 2591 | /* When switching from TCP to UDP, don't change the packet send rate for CONGESTION_EVENT_TIMEOUT ms. */ |
@@ -2824,10 +2868,10 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t | |||
2824 | int ret = -1; | 2868 | int ret = -1; |
2825 | 2869 | ||
2826 | if (conn) { | 2870 | if (conn) { |
2827 | pthread_mutex_lock(&conn->mutex); | 2871 | pthread_mutex_lock(conn->mutex); |
2828 | uint32_t buffer_start = conn->recv_array.buffer_start; | 2872 | uint32_t buffer_start = conn->recv_array.buffer_start; |
2829 | uint32_t buffer_end = conn->send_array.buffer_end; | 2873 | uint32_t buffer_end = conn->send_array.buffer_end; |
2830 | pthread_mutex_unlock(&conn->mutex); | 2874 | pthread_mutex_unlock(conn->mutex); |
2831 | ret = send_data_packet_helper(c, crypt_connection_id, buffer_start, buffer_end, data, length); | 2875 | ret = send_data_packet_helper(c, crypt_connection_id, buffer_start, buffer_end, data, length); |
2832 | } | 2876 | } |
2833 | 2877 | ||
@@ -2881,18 +2925,13 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) | |||
2881 | return ret; | 2925 | return ret; |
2882 | } | 2926 | } |
2883 | 2927 | ||
2884 | /* return one of CRYPTO_CONN_* values indicating the state of the connection. | 2928 | bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, |
2885 | * | 2929 | unsigned int *online_tcp_relays) |
2886 | * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. | ||
2887 | * sets online_tcp_relays to the number of connected tcp relays this connection has. | ||
2888 | */ | ||
2889 | Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, | ||
2890 | unsigned int *online_tcp_relays) | ||
2891 | { | 2930 | { |
2892 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | 2931 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
2893 | 2932 | ||
2894 | if (conn == nullptr) { | 2933 | if (conn == nullptr) { |
2895 | return CRYPTO_CONN_NO_CONNECTION; | 2934 | return false; |
2896 | } | 2935 | } |
2897 | 2936 | ||
2898 | if (direct_connected) { | 2937 | if (direct_connected) { |
@@ -2913,7 +2952,7 @@ Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connec | |||
2913 | *online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp); | 2952 | *online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp); |
2914 | } | 2953 | } |
2915 | 2954 | ||
2916 | return conn->status; | 2955 | return true; |
2917 | } | 2956 | } |
2918 | 2957 | ||
2919 | void new_keys(Net_Crypto *c) | 2958 | void new_keys(Net_Crypto *c) |
@@ -3002,10 +3041,6 @@ static void kill_timedout(Net_Crypto *c, void *userdata) | |||
3002 | continue; | 3041 | continue; |
3003 | } | 3042 | } |
3004 | 3043 | ||
3005 | if (conn->status == CRYPTO_CONN_NO_CONNECTION) { | ||
3006 | continue; | ||
3007 | } | ||
3008 | |||
3009 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT | 3044 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT |
3010 | || conn->status == CRYPTO_CONN_NOT_CONFIRMED) { | 3045 | || conn->status == CRYPTO_CONN_NOT_CONFIRMED) { |
3011 | if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) { | 3046 | if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) { |
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 45e1a05e..6917301b 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h | |||
@@ -81,16 +81,6 @@ | |||
81 | #define PACKET_ID_REJOIN_CONFERENCE 100 | 81 | #define PACKET_ID_REJOIN_CONFERENCE 100 |
82 | #define PACKET_ID_LOSSY_CONFERENCE 199 | 82 | #define PACKET_ID_LOSSY_CONFERENCE 199 |
83 | 83 | ||
84 | /*** Crypto connections. ***/ | ||
85 | |||
86 | typedef enum Crypto_Conn_State { | ||
87 | CRYPTO_CONN_NO_CONNECTION = 0, | ||
88 | CRYPTO_CONN_COOKIE_REQUESTING = 1, // send cookie request packets | ||
89 | CRYPTO_CONN_HANDSHAKE_SENT = 2, // send handshake packets | ||
90 | CRYPTO_CONN_NOT_CONFIRMED = 3, // send handshake packets, we have received one from the other | ||
91 | CRYPTO_CONN_ESTABLISHED = 4, | ||
92 | } Crypto_Conn_State; | ||
93 | |||
94 | /* Maximum size of receiving and sending packet buffers. */ | 84 | /* Maximum size of receiving and sending packet buffers. */ |
95 | #define CRYPTO_PACKET_BUFFER_SIZE 32768 // Must be a power of 2 | 85 | #define CRYPTO_PACKET_BUFFER_SIZE 32768 // Must be a power of 2 |
96 | 86 | ||
@@ -319,13 +309,13 @@ unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, u | |||
319 | */ | 309 | */ |
320 | int crypto_kill(Net_Crypto *c, int crypt_connection_id); | 310 | int crypto_kill(Net_Crypto *c, int crypt_connection_id); |
321 | 311 | ||
322 | /* return one of CRYPTO_CONN_* values indicating the state of the connection. | 312 | /* return true if connection is valid, false otherwise |
323 | * | 313 | * |
324 | * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. | 314 | * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. |
325 | * sets online_tcp_relays to the number of connected tcp relays this connection has. | 315 | * sets online_tcp_relays to the number of connected tcp relays this connection has. |
326 | */ | 316 | */ |
327 | Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, | 317 | bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected, |
328 | unsigned int *online_tcp_relays); | 318 | unsigned int *online_tcp_relays); |
329 | 319 | ||
330 | /* Generate our public and private keys. | 320 | /* Generate our public and private keys. |
331 | * Only call this function the first time the program starts. | 321 | * Only call this function the first time the program starts. |