summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriphydf <iphydf@users.noreply.github.com>2018-07-12 17:22:20 +0000
committeriphydf <iphydf@users.noreply.github.com>2018-07-12 20:21:42 +0000
commitbeeb9b4335d9ca6f947a52528453753a51f194f3 (patch)
tree242cad42e2e90ebf5ed04283fd79f42f4e3afa60
parentcbda01021c561bd061cb03a1c1bab58199ac2307 (diff)
Style fixes in TCP code; remove MIN and PAIR from util.h.
* Moved PAIR to toxav, where it's used (but really this should die). * Replace most MIN calls with typed `min_*` calls. Didn't replace the ones where the desired semantics are unclear. Moved the MIN macro to the one place where it's still used. * Avoid assignments in `while` loops. Instead, factored out the loop body into a separate `bool`-returning function. * Use named types for callbacks (`_cb` types). * Avoid assignments in `if` conditions. * Removed `MAKE_REALLOC` and expanded its two calls. We can't have templates in C, and this fake templating is ugly and hard to analyse and debug (it expands on a single line). * Moved epoll system include to the .c file, out of the .h file. * Avoid assignments in expressions (`a = b = c;`). * Avoid multiple declarators per struct member declaration. * Fix naming inconsistencies. * Replace `net_to_host` macro with function.
-rw-r--r--CMakeLists.txt1
-rw-r--r--auto_tests/file_transfer_test.c6
-rw-r--r--auto_tests/monolith_test.cc3
-rw-r--r--auto_tests/network_test.c4
-rw-r--r--toxav/BUILD.bazel7
-rw-r--r--toxav/Makefile.inc1
-rw-r--r--toxav/audio.h1
-rw-r--r--toxav/pair.h6
-rw-r--r--toxav/toxav.c4
-rw-r--r--toxav/video.h1
-rw-r--r--toxcore/DHT.c4
-rw-r--r--toxcore/LAN_discovery.c39
-rw-r--r--toxcore/Messenger.c9
-rw-r--r--toxcore/TCP_client.c281
-rw-r--r--toxcore/TCP_client.h43
-rw-r--r--toxcore/TCP_connection.c97
-rw-r--r--toxcore/TCP_connection.h33
-rw-r--r--toxcore/TCP_server.c473
-rw-r--r--toxcore/TCP_server.h22
-rw-r--r--toxcore/crypto_core.c29
-rw-r--r--toxcore/logger.c2
-rw-r--r--toxcore/mono_time.c6
-rw-r--r--toxcore/network.c65
-rw-r--r--toxcore/network.h25
-rw-r--r--toxcore/util.c10
-rw-r--r--toxcore/util.h6
26 files changed, 644 insertions, 534 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9fe1c3c5..1bbff255 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -261,6 +261,7 @@ if(BUILD_TOXAV)
261 toxav/groupav.h 261 toxav/groupav.h
262 toxav/msi.c 262 toxav/msi.c
263 toxav/msi.h 263 toxav/msi.h
264 toxav/pair.h
264 toxav/ring_buffer.c 265 toxav/ring_buffer.c
265 toxav/ring_buffer.h 266 toxav/ring_buffer.h
266 toxav/rtp.c 267 toxav/rtp.c
diff --git a/auto_tests/file_transfer_test.c b/auto_tests/file_transfer_test.c
index c861a3e0..6e8a3c53 100644
--- a/auto_tests/file_transfer_test.c
+++ b/auto_tests/file_transfer_test.c
@@ -286,7 +286,7 @@ static void file_transfer_test(void)
286 printf("after %u iterations: %.2fMiB done\n", (unsigned int)i + 1, (double)size_recv / 1024 / 1024); 286 printf("after %u iterations: %.2fMiB done\n", (unsigned int)i + 1, (double)size_recv / 1024 / 1024);
287 } 287 }
288 288
289 c_sleep(MIN(tox1_interval, MIN(tox2_interval, tox3_interval))); 289 c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval)));
290 } 290 }
291 291
292 ck_assert_msg(file_sending_done, "file sending did not complete after %u iterations: sendf_ok:%u file_recv:%u " 292 ck_assert_msg(file_sending_done, "file sending did not complete after %u iterations: sendf_ok:%u file_recv:%u "
@@ -348,7 +348,7 @@ static void file_transfer_test(void)
348 uint32_t tox2_interval = tox_iteration_interval(tox2); 348 uint32_t tox2_interval = tox_iteration_interval(tox2);
349 uint32_t tox3_interval = tox_iteration_interval(tox3); 349 uint32_t tox3_interval = tox_iteration_interval(tox3);
350 350
351 c_sleep(MIN(tox1_interval, MIN(tox2_interval, tox3_interval))); 351 c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval)));
352 } 352 }
353 353
354 printf("Starting file 0 transfer test.\n"); 354 printf("Starting file 0 transfer test.\n");
@@ -397,7 +397,7 @@ static void file_transfer_test(void)
397 uint32_t tox2_interval = tox_iteration_interval(tox2); 397 uint32_t tox2_interval = tox_iteration_interval(tox2);
398 uint32_t tox3_interval = tox_iteration_interval(tox3); 398 uint32_t tox3_interval = tox_iteration_interval(tox3);
399 399
400 c_sleep(MIN(tox1_interval, MIN(tox2_interval, tox3_interval))); 400 c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval)));
401 } 401 }
402 402
403 printf("file_transfer_test succeeded, took %llu seconds\n", time(nullptr) - cur_time); 403 printf("file_transfer_test succeeded, took %llu seconds\n", time(nullptr) - cur_time);
diff --git a/auto_tests/monolith_test.cc b/auto_tests/monolith_test.cc
index 53b4982e..5c3a1cce 100644
--- a/auto_tests/monolith_test.cc
+++ b/auto_tests/monolith_test.cc
@@ -161,6 +161,9 @@ void check_size(char const *type) {
161 * switch on the PRINT_SIZE above and copy the number into this function. 161 * switch on the PRINT_SIZE above and copy the number into this function.
162 */ 162 */
163int main(int argc, char *argv[]) { 163int main(int argc, char *argv[]) {
164 static_assert(sizeof(uint64_t) >= sizeof(size_t),
165 "Assumption violated: size_t is more than 64 bits wide");
166
164#if defined(__x86_64__) && defined(__LP64__) 167#if defined(__x86_64__) && defined(__LP64__)
165 // toxcore/DHT 168 // toxcore/DHT
166 CHECK_SIZE(Client_data, 496); 169 CHECK_SIZE(Client_data, 496);
diff --git a/auto_tests/network_test.c b/auto_tests/network_test.c
index f9de94f9..dc67e0c0 100644
--- a/auto_tests/network_test.c
+++ b/auto_tests/network_test.c
@@ -144,8 +144,8 @@ START_TEST(test_ip_equal)
144 ip2.ip.v6.uint32[2] = net_htonl(0xFFFF); 144 ip2.ip.v6.uint32[2] = net_htonl(0xFFFF);
145 ip2.ip.v6.uint32[3] = net_htonl(0x7F000001); 145 ip2.ip.v6.uint32[3] = net_htonl(0x7F000001);
146 146
147 ck_assert_msg(IPV6_IPV4_IN_V6(ip2.ip.v6) != 0, 147 ck_assert_msg(ipv6_ipv4_in_v6(ip2.ip.v6) != 0,
148 "IPV6_IPV4_IN_V6(::ffff:127.0.0.1): expected != 0, got 0."); 148 "ipv6_ipv4_in_v6(::ffff:127.0.0.1): expected != 0, got 0.");
149 149
150 res = ip_equal(&ip1, &ip2); 150 res = ip_equal(&ip1, &ip2);
151 ck_assert_msg(res != 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_INET6, ::ffff:127.0.0.1} ): " 151 ck_assert_msg(res != 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_INET6, ::ffff:127.0.0.1} ): "
diff --git a/toxav/BUILD.bazel b/toxav/BUILD.bazel
index dbe57b6c..f6c92b52 100644
--- a/toxav/BUILD.bazel
+++ b/toxav/BUILD.bazel
@@ -55,10 +55,16 @@ cc_test(
55) 55)
56 56
57cc_library( 57cc_library(
58 name = "pair",
59 hdrs = ["pair.h"],
60)
61
62cc_library(
58 name = "audio", 63 name = "audio",
59 srcs = ["audio.c"], 64 srcs = ["audio.c"],
60 hdrs = ["audio.h"], 65 hdrs = ["audio.h"],
61 deps = [ 66 deps = [
67 ":pair",
62 ":public", 68 ":public",
63 ":rtp", 69 ":rtp",
64 "//c-toxcore/toxcore:network", 70 "//c-toxcore/toxcore:network",
@@ -78,6 +84,7 @@ cc_library(
78 ], 84 ],
79 deps = [ 85 deps = [
80 ":audio", 86 ":audio",
87 ":pair",
81 ":public", 88 ":public",
82 "//c-toxcore/toxcore:network", 89 "//c-toxcore/toxcore:network",
83 "@libvpx", 90 "@libvpx",
diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc
index 7b788198..5f6342c0 100644
--- a/toxav/Makefile.inc
+++ b/toxav/Makefile.inc
@@ -16,6 +16,7 @@ libtoxav_la_SOURCES = ../toxav/rtp.h \
16 ../toxav/video.c \ 16 ../toxav/video.c \
17 ../toxav/bwcontroller.h \ 17 ../toxav/bwcontroller.h \
18 ../toxav/bwcontroller.c \ 18 ../toxav/bwcontroller.c \
19 ../toxav/pair.h \
19 ../toxav/ring_buffer.h \ 20 ../toxav/ring_buffer.h \
20 ../toxav/ring_buffer.c \ 21 ../toxav/ring_buffer.c \
21 ../toxav/toxav.h \ 22 ../toxav/toxav.h \
diff --git a/toxav/audio.h b/toxav/audio.h
index 64aa2f12..39d534e0 100644
--- a/toxav/audio.h
+++ b/toxav/audio.h
@@ -24,6 +24,7 @@
24 24
25#include "../toxcore/logger.h" 25#include "../toxcore/logger.h"
26#include "../toxcore/util.h" 26#include "../toxcore/util.h"
27#include "pair.h"
27 28
28#include <opus.h> 29#include <opus.h>
29#include <pthread.h> 30#include <pthread.h>
diff --git a/toxav/pair.h b/toxav/pair.h
new file mode 100644
index 00000000..59ef2b62
--- /dev/null
+++ b/toxav/pair.h
@@ -0,0 +1,6 @@
1#ifndef C_TOXCORE_TOXAV_PAIR_H
2#define C_TOXCORE_TOXAV_PAIR_H
3
4#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; }
5
6#endif // C_TOXCORE_TOXAV_PAIR_H
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 5abe1130..dcffca4d 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -242,6 +242,10 @@ void toxav_iterate(ToxAV *av)
242 ac_iterate(i->audio.second); 242 ac_iterate(i->audio.second);
243 vc_iterate(i->video.second); 243 vc_iterate(i->video.second);
244 244
245 // TODO(iphydf): Find out what MIN-semantics are desired here and
246 // use a min_* function from util.h.
247#define MIN(a,b) (((a)<(b))?(a):(b))
248
245 if (i->msi_call->self_capabilities & msi_CapRAudio && 249 if (i->msi_call->self_capabilities & msi_CapRAudio &&
246 i->msi_call->peer_capabilities & msi_CapSAudio) { 250 i->msi_call->peer_capabilities & msi_CapSAudio) {
247 rc = MIN(i->audio.second->lp_frame_duration, rc); 251 rc = MIN(i->audio.second->lp_frame_duration, rc);
diff --git a/toxav/video.h b/toxav/video.h
index 616a866a..7a0913a0 100644
--- a/toxav/video.h
+++ b/toxav/video.h
@@ -24,6 +24,7 @@
24 24
25#include "../toxcore/logger.h" 25#include "../toxcore/logger.h"
26#include "../toxcore/util.h" 26#include "../toxcore/util.h"
27#include "pair.h"
27 28
28#include <vpx/vpx_decoder.h> 29#include <vpx/vpx_decoder.h>
29#include <vpx/vpx_encoder.h> 30#include <vpx/vpx_encoder.h>
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 3fd3829e..01fcfd66 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -1192,7 +1192,7 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
1192 uint32_t used = 0; 1192 uint32_t used = 0;
1193 1193
1194 /* convert IPv4-in-IPv6 to IPv4 */ 1194 /* convert IPv4-in-IPv6 to IPv4 */
1195 if (net_family_is_ipv6(ip_port.ip.family) && IPV6_IPV4_IN_V6(ip_port.ip.ip.v6)) { 1195 if (net_family_is_ipv6(ip_port.ip.family) && ipv6_ipv4_in_v6(ip_port.ip.ip.v6)) {
1196 ip_port.ip.family = net_family_ipv4; 1196 ip_port.ip.family = net_family_ipv4;
1197 ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3]; 1197 ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3];
1198 } 1198 }
@@ -1272,7 +1272,7 @@ static bool update_client_data(Client_data *array, size_t size, IP_Port ip_port,
1272static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *nodepublic_key) 1272static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *nodepublic_key)
1273{ 1273{
1274 /* convert IPv4-in-IPv6 to IPv4 */ 1274 /* convert IPv4-in-IPv6 to IPv4 */
1275 if (net_family_is_ipv6(ip_port.ip.family) && IPV6_IPV4_IN_V6(ip_port.ip.ip.v6)) { 1275 if (net_family_is_ipv6(ip_port.ip.family) && ipv6_ipv4_in_v6(ip_port.ip.ip.v6)) {
1276 ip_port.ip.family = net_family_ipv4; 1276 ip_port.ip.family = net_family_ipv4;
1277 ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3]; 1277 ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3];
1278 } 1278 }
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index 9552ad05..0b2a8783 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -36,8 +36,11 @@
36 36
37/* TODO: multiple threads might concurrently try to set these, and it isn't clear that this couldn't lead to undesirable 37/* TODO: multiple threads might concurrently try to set these, and it isn't clear that this couldn't lead to undesirable
38 * behaviour. Consider storing the data in per-instance variables instead. */ 38 * behaviour. Consider storing the data in per-instance variables instead. */
39//!TOKSTYLE-
40// No global mutable state in Tokstyle.
39static int broadcast_count = -1; 41static int broadcast_count = -1;
40static IP_Port broadcast_ip_ports[MAX_INTERFACES]; 42static IP_Port broadcast_ip_ports[MAX_INTERFACES];
43//!TOKSTYLE+
41 44
42#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 45#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43 46
@@ -76,9 +79,9 @@ static void fetch_broadcast_info(uint16_t port)
76 int count = 0; 79 int count = 0;
77 IP_Port ip_ports[MAX_INTERFACES]; 80 IP_Port ip_ports[MAX_INTERFACES];
78 81
79 int ret; 82 const int ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
80 83
81 if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { 84 if (ret == NO_ERROR) {
82 IP_ADAPTER_INFO *pAdapter = pAdapterInfo; 85 IP_ADAPTER_INFO *pAdapter = pAdapterInfo;
83 86
84 while (pAdapter) { 87 while (pAdapter) {
@@ -93,7 +96,7 @@ static void fetch_broadcast_info(uint16_t port)
93 uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1; 96 uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1;
94 ip_port->ip.ip.v4.uint32 = net_htonl(broadcast_ip); 97 ip_port->ip.ip.v4.uint32 = net_htonl(broadcast_ip);
95 ip_port->port = port; 98 ip_port->port = port;
96 count++; 99 ++count;
97 100
98 if (count >= MAX_INTERFACES) { 101 if (count >= MAX_INTERFACES) {
99 break; 102 break;
@@ -111,7 +114,7 @@ static void fetch_broadcast_info(uint16_t port)
111 114
112 broadcast_count = count; 115 broadcast_count = count;
113 116
114 for (uint32_t i = 0; i < count; i++) { 117 for (uint32_t i = 0; i < count; ++i) {
115 broadcast_ip_ports[i] = ip_ports[i]; 118 broadcast_ip_ports[i] = ip_ports[i];
116 } 119 }
117} 120}
@@ -149,11 +152,11 @@ static void fetch_broadcast_info(uint16_t port)
149 struct ifreq i_faces[MAX_INTERFACES]; 152 struct ifreq i_faces[MAX_INTERFACES];
150 memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES); 153 memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES);
151 154
152 struct ifconf ifconf; 155 struct ifconf ifc;
153 ifconf.ifc_buf = (char *)i_faces; 156 ifc.ifc_buf = (char *)i_faces;
154 ifconf.ifc_len = sizeof(i_faces); 157 ifc.ifc_len = sizeof(i_faces);
155 158
156 if (ioctl(sock.socket, SIOCGIFCONF, &ifconf) < 0) { 159 if (ioctl(sock.socket, SIOCGIFCONF, &ifc) < 0) {
157 kill_sock(sock); 160 kill_sock(sock);
158 return; 161 return;
159 } 162 }
@@ -165,14 +168,14 @@ static void fetch_broadcast_info(uint16_t port)
165 int count = 0; 168 int count = 0;
166 IP_Port ip_ports[MAX_INTERFACES]; 169 IP_Port ip_ports[MAX_INTERFACES];
167 170
168 /* ifconf.ifc_len is set by the ioctl() to the actual length used; 171 /* ifc.ifc_len is set by the ioctl() to the actual length used;
169 * on usage of the complete array the call should be repeated with 172 * on usage of the complete array the call should be repeated with
170 * a larger array, not done (640kB and 16 interfaces shall be 173 * a larger array, not done (640kB and 16 interfaces shall be
171 * enough, for everybody!) 174 * enough, for everybody!)
172 */ 175 */
173 int n = ifconf.ifc_len / sizeof(struct ifreq); 176 int n = ifc.ifc_len / sizeof(struct ifreq);
174 177
175 for (int i = 0; i < n; i++) { 178 for (int i = 0; i < n; ++i) {
176 /* there are interfaces with are incapable of broadcast */ 179 /* there are interfaces with are incapable of broadcast */
177 if (ioctl(sock.socket, SIOCGIFBRDADDR, &i_faces[i]) < 0) { 180 if (ioctl(sock.socket, SIOCGIFBRDADDR, &i_faces[i]) < 0) {
178 continue; 181 continue;
@@ -198,14 +201,14 @@ static void fetch_broadcast_info(uint16_t port)
198 } 201 }
199 202
200 ip_port->port = port; 203 ip_port->port = port;
201 count++; 204 ++count;
202 } 205 }
203 206
204 kill_sock(sock); 207 kill_sock(sock);
205 208
206 broadcast_count = count; 209 broadcast_count = count;
207 210
208 for (uint32_t i = 0; i < count; i++) { 211 for (uint32_t i = 0; i < count; ++i) {
209 broadcast_ip_ports[i] = ip_ports[i]; 212 broadcast_ip_ports[i] = ip_ports[i];
210 } 213 }
211} 214}
@@ -235,7 +238,7 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, const uint8
235 return 0; 238 return 0;
236 } 239 }
237 240
238 for (int i = 0; i < broadcast_count; i++) { 241 for (int i = 0; i < broadcast_count; ++i) {
239 sendpacket(net, broadcast_ip_ports[i], data, length); 242 sendpacket(net, broadcast_ip_ports[i], data, length);
240 } 243 }
241 244
@@ -259,11 +262,11 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast)
259 ip.ip.v6.uint8[15] = 0x01; 262 ip.ip.v6.uint8[15] = 0x01;
260 } else if (net_family_is_ipv4(family_broadcast)) { 263 } else if (net_family_is_ipv4(family_broadcast)) {
261 ip.family = net_family_ipv6; 264 ip.family = net_family_ipv6;
262 ip.ip.v6 = IP6_BROADCAST; 265 ip.ip.v6 = ip6_broadcast;
263 } 266 }
264 } else if (net_family_is_ipv4(family_socket) && net_family_is_ipv4(family_broadcast)) { 267 } else if (net_family_is_ipv4(family_socket) && net_family_is_ipv4(family_broadcast)) {
265 ip.family = net_family_ipv4; 268 ip.family = net_family_ipv4;
266 ip.ip.v4 = IP4_BROADCAST; 269 ip.ip.v4 = ip4_broadcast;
267 } 270 }
268 271
269 return ip; 272 return ip;
@@ -281,7 +284,7 @@ bool ip_is_local(IP ip)
281 } 284 }
282 } else { 285 } else {
283 /* embedded IPv4-in-IPv6 */ 286 /* embedded IPv4-in-IPv6 */
284 if (IPV6_IPV4_IN_V6(ip.ip.v6)) { 287 if (ipv6_ipv4_in_v6(ip.ip.v6)) {
285 IP ip4; 288 IP ip4;
286 ip4.family = net_family_ipv4; 289 ip4.family = net_family_ipv4;
287 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3]; 290 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
@@ -345,7 +348,7 @@ int ip_is_lan(IP ip)
345 } 348 }
346 349
347 /* embedded IPv4-in-IPv6 */ 350 /* embedded IPv4-in-IPv6 */
348 if (IPV6_IPV4_IN_V6(ip.ip.v6)) { 351 if (ipv6_ipv4_in_v6(ip.ip.v6)) {
349 IP ip4; 352 IP ip4;
350 ip4.family = net_family_ipv4; 353 ip4.family = net_family_ipv4;
351 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3]; 354 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index a5d15a34..416b937c 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -717,7 +717,9 @@ int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf,
717 return -1; 717 return -1;
718 } 718 }
719 719
720 int msglen = MIN(maxlen, m->friendlist[friendnumber].statusmessage_length); 720 // TODO(iphydf): This should be uint16_t and min_u16. If maxlen exceeds
721 // uint16_t's range, it won't affect the result.
722 uint32_t msglen = min_u32(maxlen, m->friendlist[friendnumber].statusmessage_length);
721 723
722 memcpy(buf, m->friendlist[friendnumber].statusmessage, msglen); 724 memcpy(buf, m->friendlist[friendnumber].statusmessage, msglen);
723 memset(buf + msglen, 0, maxlen - msglen); 725 memset(buf + msglen, 0, maxlen - msglen);
@@ -2855,9 +2857,10 @@ static uint32_t friends_list_save(const Messenger *m, uint8_t *data)
2855 memcpy(temp.real_pk, m->friendlist[i].real_pk, CRYPTO_PUBLIC_KEY_SIZE); 2857 memcpy(temp.real_pk, m->friendlist[i].real_pk, CRYPTO_PUBLIC_KEY_SIZE);
2856 2858
2857 if (temp.status < 3) { 2859 if (temp.status < 3) {
2860 // TODO(iphydf): Use uint16_t and min_u16 here.
2858 const size_t friendrequest_length = 2861 const size_t friendrequest_length =
2859 MIN(m->friendlist[i].info_size, 2862 min_u32(m->friendlist[i].info_size,
2860 MIN(SAVED_FRIEND_REQUEST_SIZE, MAX_FRIEND_REQUEST_DATA_SIZE)); 2863 min_u32(SAVED_FRIEND_REQUEST_SIZE, MAX_FRIEND_REQUEST_DATA_SIZE));
2861 memcpy(temp.info, m->friendlist[i].info, friendrequest_length); 2864 memcpy(temp.info, m->friendlist[i].info, friendrequest_length);
2862 2865
2863 temp.info_size = net_htons(m->friendlist[i].info_size); 2866 temp.info_size = net_htons(m->friendlist[i].info_size);
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index 1291d276..381d9b80 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -34,8 +34,15 @@
34#include "mono_time.h" 34#include "mono_time.h"
35#include "util.h" 35#include "util.h"
36 36
37typedef struct TCP_Client_Conn {
38 // TODO(iphydf): Add an enum for this.
39 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
40 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
41 uint32_t number;
42} TCP_Client_Conn;
43
37struct TCP_Client_Connection { 44struct TCP_Client_Connection {
38 TCP_CLIENT_STATUS status; 45 TCP_Client_Status status;
39 Socket sock; 46 Socket sock;
40 uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */ 47 uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */
41 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */ 48 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */
@@ -52,7 +59,8 @@ struct TCP_Client_Connection {
52 uint16_t last_packet_length; 59 uint16_t last_packet_length;
53 uint16_t last_packet_sent; 60 uint16_t last_packet_sent;
54 61
55 TCP_Priority_List *priority_queue_start, *priority_queue_end; 62 TCP_Priority_List *priority_queue_start;
63 TCP_Priority_List *priority_queue_end;
56 64
57 uint64_t kill_at; 65 uint64_t kill_at;
58 66
@@ -62,22 +70,17 @@ struct TCP_Client_Connection {
62 uint64_t ping_response_id; 70 uint64_t ping_response_id;
63 uint64_t ping_request_id; 71 uint64_t ping_request_id;
64 72
65 struct { 73 TCP_Client_Conn connections[NUM_CLIENT_CONNECTIONS];
66 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ 74 tcp_routing_response_cb *response_callback;
67 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
68 uint32_t number;
69 } connections[NUM_CLIENT_CONNECTIONS];
70 int (*response_callback)(void *object, uint8_t connection_id, const uint8_t *public_key);
71 void *response_callback_object; 75 void *response_callback_object;
72 int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status); 76 tcp_routing_status_cb *status_callback;
73 void *status_callback_object; 77 void *status_callback_object;
74 int (*data_callback)(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length, 78 tcp_routing_data_cb *data_callback;
75 void *userdata);
76 void *data_callback_object; 79 void *data_callback_object;
77 int (*oob_data_callback)(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata); 80 tcp_oob_data_cb *oob_data_callback;
78 void *oob_data_callback_object; 81 void *oob_data_callback_object;
79 82
80 int (*onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); 83 tcp_onion_response_cb *onion_callback;
81 void *onion_callback_object; 84 void *onion_callback_object;
82 85
83 /* Can be used by user. */ 86 /* Can be used by user. */
@@ -95,7 +98,7 @@ IP_Port tcp_con_ip_port(const TCP_Client_Connection *con)
95 return con->ip_port; 98 return con->ip_port;
96} 99}
97 100
98TCP_CLIENT_STATUS tcp_con_status(const TCP_Client_Connection *con) 101TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con)
99{ 102{
100 return con->status; 103 return con->status;
101} 104}
@@ -133,7 +136,7 @@ static int connect_sock_to(Socket sock, IP_Port ip_port, TCP_Proxy_Info *proxy_i
133/* return 1 on success. 136/* return 1 on success.
134 * return 0 on failure. 137 * return 0 on failure.
135 */ 138 */
136static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_conn) 139static int proxy_http_generate_connection_request(TCP_Client_Connection *tcp_conn)
137{ 140{
138 char one[] = "CONNECT "; 141 char one[] = "CONNECT ";
139 char two[] = " HTTP/1.1\nHost: "; 142 char two[] = " HTTP/1.1\nHost: ";
@@ -141,20 +144,20 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con
141 144
142 char ip[TOX_INET6_ADDRSTRLEN]; 145 char ip[TOX_INET6_ADDRSTRLEN];
143 146
144 if (!ip_parse_addr(&TCP_conn->ip_port.ip, ip, sizeof(ip))) { 147 if (!ip_parse_addr(&tcp_conn->ip_port.ip, ip, sizeof(ip))) {
145 return 0; 148 return 0;
146 } 149 }
147 150
148 const uint16_t port = net_ntohs(TCP_conn->ip_port.port); 151 const uint16_t port = net_ntohs(tcp_conn->ip_port.port);
149 const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, 152 const int written = snprintf((char *)tcp_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two,
150 ip, port, three); 153 ip, port, three);
151 154
152 if (written < 0 || MAX_PACKET_SIZE < written) { 155 if (written < 0 || MAX_PACKET_SIZE < written) {
153 return 0; 156 return 0;
154 } 157 }
155 158
156 TCP_conn->last_packet_length = written; 159 tcp_conn->last_packet_length = written;
157 TCP_conn->last_packet_sent = 0; 160 tcp_conn->last_packet_sent = 0;
158 161
159 return 1; 162 return 1;
160} 163}
@@ -163,12 +166,12 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con
163 * return 0 if no data received. 166 * return 0 if no data received.
164 * return -1 on failure (connection refused). 167 * return -1 on failure (connection refused).
165 */ 168 */
166static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) 169static int proxy_http_read_connection_response(TCP_Client_Connection *tcp_conn)
167{ 170{
168 char success[] = "200"; 171 char success[] = "200";
169 uint8_t data[16]; // draining works the best if the length is a power of 2 172 uint8_t data[16]; // draining works the best if the length is a power of 2
170 173
171 int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data) - 1); 174 int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data) - 1);
172 175
173 if (ret == -1) { 176 if (ret == -1) {
174 return 0; 177 return 0;
@@ -178,11 +181,11 @@ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn)
178 181
179 if (strstr((char *)data, success)) { 182 if (strstr((char *)data, success)) {
180 // drain all data 183 // drain all data
181 unsigned int data_left = net_socket_data_recv_buffer(TCP_conn->sock); 184 unsigned int data_left = net_socket_data_recv_buffer(tcp_conn->sock);
182 185
183 if (data_left) { 186 if (data_left) {
184 VLA(uint8_t, temp_data, data_left); 187 VLA(uint8_t, temp_data, data_left);
185 read_TCP_packet(TCP_conn->sock, temp_data, data_left); 188 read_TCP_packet(tcp_conn->sock, temp_data, data_left);
186 } 189 }
187 190
188 return 1; 191 return 1;
@@ -191,24 +194,24 @@ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn)
191 return -1; 194 return -1;
192} 195}
193 196
194static void proxy_socks5_generate_handshake(TCP_Client_Connection *TCP_conn) 197static void proxy_socks5_generate_handshake(TCP_Client_Connection *tcp_conn)
195{ 198{
196 TCP_conn->last_packet[0] = 5; /* SOCKSv5 */ 199 tcp_conn->last_packet[0] = 5; /* SOCKSv5 */
197 TCP_conn->last_packet[1] = 1; /* number of authentication methods supported */ 200 tcp_conn->last_packet[1] = 1; /* number of authentication methods supported */
198 TCP_conn->last_packet[2] = 0; /* No authentication */ 201 tcp_conn->last_packet[2] = 0; /* No authentication */
199 202
200 TCP_conn->last_packet_length = 3; 203 tcp_conn->last_packet_length = 3;
201 TCP_conn->last_packet_sent = 0; 204 tcp_conn->last_packet_sent = 0;
202} 205}
203 206
204/* return 1 on success. 207/* return 1 on success.
205 * return 0 if no data received. 208 * return 0 if no data received.
206 * return -1 on failure (connection refused). 209 * return -1 on failure (connection refused).
207 */ 210 */
208static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn) 211static int socks5_read_handshake_response(TCP_Client_Connection *tcp_conn)
209{ 212{
210 uint8_t data[2]; 213 uint8_t data[2];
211 int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); 214 int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data));
212 215
213 if (ret == -1) { 216 if (ret == -1) {
214 return 0; 217 return 0;
@@ -221,41 +224,41 @@ static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn)
221 return -1; 224 return -1;
222} 225}
223 226
224static void proxy_socks5_generate_connection_request(TCP_Client_Connection *TCP_conn) 227static void proxy_socks5_generate_connection_request(TCP_Client_Connection *tcp_conn)
225{ 228{
226 TCP_conn->last_packet[0] = 5; /* SOCKSv5 */ 229 tcp_conn->last_packet[0] = 5; /* SOCKSv5 */
227 TCP_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */ 230 tcp_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */
228 TCP_conn->last_packet[2] = 0; /* reserved, must be 0 */ 231 tcp_conn->last_packet[2] = 0; /* reserved, must be 0 */
229 uint16_t length = 3; 232 uint16_t length = 3;
230 233
231 if (net_family_is_ipv4(TCP_conn->ip_port.ip.family)) { 234 if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
232 TCP_conn->last_packet[3] = 1; /* IPv4 address */ 235 tcp_conn->last_packet[3] = 1; /* IPv4 address */
233 ++length; 236 ++length;
234 memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4)); 237 memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4));
235 length += sizeof(IP4); 238 length += sizeof(IP4);
236 } else { 239 } else {
237 TCP_conn->last_packet[3] = 4; /* IPv6 address */ 240 tcp_conn->last_packet[3] = 4; /* IPv6 address */
238 ++length; 241 ++length;
239 memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6)); 242 memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6));
240 length += sizeof(IP6); 243 length += sizeof(IP6);
241 } 244 }
242 245
243 memcpy(TCP_conn->last_packet + length, &TCP_conn->ip_port.port, sizeof(uint16_t)); 246 memcpy(tcp_conn->last_packet + length, &tcp_conn->ip_port.port, sizeof(uint16_t));
244 length += sizeof(uint16_t); 247 length += sizeof(uint16_t);
245 248
246 TCP_conn->last_packet_length = length; 249 tcp_conn->last_packet_length = length;
247 TCP_conn->last_packet_sent = 0; 250 tcp_conn->last_packet_sent = 0;
248} 251}
249 252
250/* return 1 on success. 253/* return 1 on success.
251 * return 0 if no data received. 254 * return 0 if no data received.
252 * return -1 on failure (connection refused). 255 * return -1 on failure (connection refused).
253 */ 256 */
254static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn) 257static int proxy_socks5_read_connection_response(TCP_Client_Connection *tcp_conn)
255{ 258{
256 if (net_family_is_ipv4(TCP_conn->ip_port.ip.family)) { 259 if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
257 uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; 260 uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)];
258 int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); 261 int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data));
259 262
260 if (ret == -1) { 263 if (ret == -1) {
261 return 0; 264 return 0;
@@ -266,7 +269,7 @@ static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn
266 } 269 }
267 } else { 270 } else {
268 uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; 271 uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)];
269 int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); 272 int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data));
270 273
271 if (ret == -1) { 274 if (ret == -1) {
272 return 0; 275 return 0;
@@ -283,23 +286,23 @@ static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn
283/* return 0 on success. 286/* return 0 on success.
284 * return -1 on failure. 287 * return -1 on failure.
285 */ 288 */
286static int generate_handshake(TCP_Client_Connection *TCP_conn) 289static int generate_handshake(TCP_Client_Connection *tcp_conn)
287{ 290{
288 uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; 291 uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
289 crypto_new_keypair(plain, TCP_conn->temp_secret_key); 292 crypto_new_keypair(plain, tcp_conn->temp_secret_key);
290 random_nonce(TCP_conn->sent_nonce); 293 random_nonce(tcp_conn->sent_nonce);
291 memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, TCP_conn->sent_nonce, CRYPTO_NONCE_SIZE); 294 memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->sent_nonce, CRYPTO_NONCE_SIZE);
292 memcpy(TCP_conn->last_packet, TCP_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); 295 memcpy(tcp_conn->last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
293 random_nonce(TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE); 296 random_nonce(tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE);
294 int len = encrypt_data_symmetric(TCP_conn->shared_key, TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, 297 int len = encrypt_data_symmetric(tcp_conn->shared_key, tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
295 sizeof(plain), TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); 298 sizeof(plain), tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
296 299
297 if (len != sizeof(plain) + CRYPTO_MAC_SIZE) { 300 if (len != sizeof(plain) + CRYPTO_MAC_SIZE) {
298 return -1; 301 return -1;
299 } 302 }
300 303
301 TCP_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE; 304 tcp_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE;
302 TCP_conn->last_packet_sent = 0; 305 tcp_conn->last_packet_sent = 0;
303 return 0; 306 return 0;
304} 307}
305 308
@@ -308,19 +311,19 @@ static int generate_handshake(TCP_Client_Connection *TCP_conn)
308 * return 0 on success. 311 * return 0 on success.
309 * return -1 on failure. 312 * return -1 on failure.
310 */ 313 */
311static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data) 314static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data)
312{ 315{
313 uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; 316 uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
314 int len = decrypt_data_symmetric(TCP_conn->shared_key, data, data + CRYPTO_NONCE_SIZE, 317 int len = decrypt_data_symmetric(tcp_conn->shared_key, data, data + CRYPTO_NONCE_SIZE,
315 TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); 318 TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain);
316 319
317 if (len != sizeof(plain)) { 320 if (len != sizeof(plain)) {
318 return -1; 321 return -1;
319 } 322 }
320 323
321 memcpy(TCP_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); 324 memcpy(tcp_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
322 encrypt_precompute(plain, TCP_conn->temp_secret_key, TCP_conn->shared_key); 325 encrypt_precompute(plain, tcp_conn->temp_secret_key, tcp_conn->shared_key);
323 crypto_memzero(TCP_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE); 326 crypto_memzero(tcp_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE);
324 return 0; 327 return 0;
325} 328}
326 329
@@ -504,15 +507,13 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
504 return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); 507 return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
505} 508}
506 509
507void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, 510void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object)
508 const uint8_t *public_key), void *object)
509{ 511{
510 con->response_callback = response_callback; 512 con->response_callback = response_callback;
511 con->response_callback_object = object; 513 con->response_callback_object = object;
512} 514}
513 515
514void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number, 516void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object)
515 uint8_t connection_id, uint8_t status), void *object)
516{ 517{
517 con->status_callback = status_callback; 518 con->status_callback = status_callback;
518 con->status_callback_object = object; 519 con->status_callback_object = object;
@@ -584,15 +585,13 @@ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32
584 return 0; 585 return 0;
585} 586}
586 587
587void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, 588void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object)
588 uint8_t connection_id, const uint8_t *data, uint16_t length, void *userdata), void *object)
589{ 589{
590 con->data_callback = data_callback; 590 con->data_callback = data_callback;
591 con->data_callback_object = object; 591 con->data_callback_object = object;
592} 592}
593 593
594void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key, 594void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object)
595 const uint8_t *data, uint16_t length, void *userdata), void *object)
596{ 595{
597 con->oob_data_callback = oob_data_callback; 596 con->oob_data_callback = oob_data_callback;
598 con->oob_data_callback_object = object; 597 con->oob_data_callback_object = object;
@@ -623,9 +622,9 @@ static int tcp_send_ping_request(TCP_Client_Connection *con)
623 uint8_t packet[1 + sizeof(uint64_t)]; 622 uint8_t packet[1 + sizeof(uint64_t)];
624 packet[0] = TCP_PACKET_PING; 623 packet[0] = TCP_PACKET_PING;
625 memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); 624 memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t));
626 int ret; 625 const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
627 626
628 if ((ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1)) == 1) { 627 if (ret == 1) {
629 con->ping_request_id = 0; 628 con->ping_request_id = 0;
630 } 629 }
631 630
@@ -645,9 +644,9 @@ static int tcp_send_ping_response(TCP_Client_Connection *con)
645 uint8_t packet[1 + sizeof(uint64_t)]; 644 uint8_t packet[1 + sizeof(uint64_t)];
646 packet[0] = TCP_PACKET_PONG; 645 packet[0] = TCP_PACKET_PONG;
647 memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); 646 memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
648 int ret; 647 const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
649 648
650 if ((ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1)) == 1) { 649 if (ret == 1) {
651 con->ping_response_id = 0; 650 con->ping_response_id = 0;
652 } 651 }
653 652
@@ -681,8 +680,7 @@ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t
681 return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0); 680 return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
682} 681}
683 682
684void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, 683void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object)
685 uint16_t length, void *userdata), void *object)
686{ 684{
687 con->onion_callback = onion_callback; 685 con->onion_callback = onion_callback;
688 con->onion_callback_object = object; 686 con->onion_callback_object = object;
@@ -928,15 +926,35 @@ static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t *
928 return 0; 926 return 0;
929} 927}
930 928
929static bool tcp_process_packet(TCP_Client_Connection *conn, void *userdata)
930{
931 uint8_t packet[MAX_PACKET_SIZE];
932 const int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key,
933 conn->recv_nonce, packet, sizeof(packet));
934
935 if (len == 0) {
936 return false;
937 }
938
939 if (len == -1) {
940 conn->status = TCP_CLIENT_DISCONNECTED;
941 return false;
942 }
943
944 if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) {
945 conn->status = TCP_CLIENT_DISCONNECTED;
946 return false;
947 }
948
949 return true;
950}
951
931static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) 952static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata)
932{ 953{
933 client_send_pending_data(conn); 954 client_send_pending_data(conn);
934 tcp_send_ping_response(conn); 955 tcp_send_ping_response(conn);
935 tcp_send_ping_request(conn); 956 tcp_send_ping_request(conn);
936 957
937 uint8_t packet[MAX_PACKET_SIZE];
938 int len;
939
940 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) { 958 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) {
941 uint64_t ping_id = random_u64(); 959 uint64_t ping_id = random_u64();
942 960
@@ -944,7 +962,8 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata)
944 ++ping_id; 962 ++ping_id;
945 } 963 }
946 964
947 conn->ping_request_id = conn->ping_id = ping_id; 965 conn->ping_request_id = ping_id;
966 conn->ping_id = ping_id;
948 tcp_send_ping_request(conn); 967 tcp_send_ping_request(conn);
949 conn->last_pinged = unix_time(); 968 conn->last_pinged = unix_time();
950 } 969 }
@@ -954,17 +973,9 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata)
954 return 0; 973 return 0;
955 } 974 }
956 975
957 while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, 976 while (tcp_process_packet(conn, userdata)) {
958 conn->recv_nonce, packet, sizeof(packet)))) { 977 // Keep reading until error or out of data.
959 if (len == -1) { 978 continue;
960 conn->status = TCP_CLIENT_DISCONNECTED;
961 break;
962 }
963
964 if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) {
965 conn->status = TCP_CLIENT_DISCONNECTED;
966 break;
967 }
968 } 979 }
969 980
970 return 0; 981 return 0;
@@ -972,102 +983,102 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata)
972 983
973/* Run the TCP connection 984/* Run the TCP connection
974 */ 985 */
975void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata) 986void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata)
976{ 987{
977 unix_time_update(); 988 unix_time_update();
978 989
979 if (TCP_connection->status == TCP_CLIENT_DISCONNECTED) { 990 if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) {
980 return; 991 return;
981 } 992 }
982 993
983 if (TCP_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) { 994 if (tcp_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) {
984 if (client_send_pending_data(TCP_connection) == 0) { 995 if (client_send_pending_data(tcp_connection) == 0) {
985 int ret = proxy_http_read_connection_response(TCP_connection); 996 int ret = proxy_http_read_connection_response(tcp_connection);
986 997
987 if (ret == -1) { 998 if (ret == -1) {
988 TCP_connection->kill_at = 0; 999 tcp_connection->kill_at = 0;
989 TCP_connection->status = TCP_CLIENT_DISCONNECTED; 1000 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
990 } 1001 }
991 1002
992 if (ret == 1) { 1003 if (ret == 1) {
993 generate_handshake(TCP_connection); 1004 generate_handshake(tcp_connection);
994 TCP_connection->status = TCP_CLIENT_CONNECTING; 1005 tcp_connection->status = TCP_CLIENT_CONNECTING;
995 } 1006 }
996 } 1007 }
997 } 1008 }
998 1009
999 if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { 1010 if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) {
1000 if (client_send_pending_data(TCP_connection) == 0) { 1011 if (client_send_pending_data(tcp_connection) == 0) {
1001 int ret = socks5_read_handshake_response(TCP_connection); 1012 int ret = socks5_read_handshake_response(tcp_connection);
1002 1013
1003 if (ret == -1) { 1014 if (ret == -1) {
1004 TCP_connection->kill_at = 0; 1015 tcp_connection->kill_at = 0;
1005 TCP_connection->status = TCP_CLIENT_DISCONNECTED; 1016 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
1006 } 1017 }
1007 1018
1008 if (ret == 1) { 1019 if (ret == 1) {
1009 proxy_socks5_generate_connection_request(TCP_connection); 1020 proxy_socks5_generate_connection_request(tcp_connection);
1010 TCP_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED; 1021 tcp_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED;
1011 } 1022 }
1012 } 1023 }
1013 } 1024 }
1014 1025
1015 if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { 1026 if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) {
1016 if (client_send_pending_data(TCP_connection) == 0) { 1027 if (client_send_pending_data(tcp_connection) == 0) {
1017 int ret = proxy_socks5_read_connection_response(TCP_connection); 1028 int ret = proxy_socks5_read_connection_response(tcp_connection);
1018 1029
1019 if (ret == -1) { 1030 if (ret == -1) {
1020 TCP_connection->kill_at = 0; 1031 tcp_connection->kill_at = 0;
1021 TCP_connection->status = TCP_CLIENT_DISCONNECTED; 1032 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
1022 } 1033 }
1023 1034
1024 if (ret == 1) { 1035 if (ret == 1) {
1025 generate_handshake(TCP_connection); 1036 generate_handshake(tcp_connection);
1026 TCP_connection->status = TCP_CLIENT_CONNECTING; 1037 tcp_connection->status = TCP_CLIENT_CONNECTING;
1027 } 1038 }
1028 } 1039 }
1029 } 1040 }
1030 1041
1031 if (TCP_connection->status == TCP_CLIENT_CONNECTING) { 1042 if (tcp_connection->status == TCP_CLIENT_CONNECTING) {
1032 if (client_send_pending_data(TCP_connection) == 0) { 1043 if (client_send_pending_data(tcp_connection) == 0) {
1033 TCP_connection->status = TCP_CLIENT_UNCONFIRMED; 1044 tcp_connection->status = TCP_CLIENT_UNCONFIRMED;
1034 } 1045 }
1035 } 1046 }
1036 1047
1037 if (TCP_connection->status == TCP_CLIENT_UNCONFIRMED) { 1048 if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) {
1038 uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; 1049 uint8_t data[TCP_SERVER_HANDSHAKE_SIZE];
1039 int len = read_TCP_packet(TCP_connection->sock, data, sizeof(data)); 1050 int len = read_TCP_packet(tcp_connection->sock, data, sizeof(data));
1040 1051
1041 if (sizeof(data) == len) { 1052 if (sizeof(data) == len) {
1042 if (handle_handshake(TCP_connection, data) == 0) { 1053 if (handle_handshake(tcp_connection, data) == 0) {
1043 TCP_connection->kill_at = ~0; 1054 tcp_connection->kill_at = ~0;
1044 TCP_connection->status = TCP_CLIENT_CONFIRMED; 1055 tcp_connection->status = TCP_CLIENT_CONFIRMED;
1045 } else { 1056 } else {
1046 TCP_connection->kill_at = 0; 1057 tcp_connection->kill_at = 0;
1047 TCP_connection->status = TCP_CLIENT_DISCONNECTED; 1058 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
1048 } 1059 }
1049 } 1060 }
1050 } 1061 }
1051 1062
1052 if (TCP_connection->status == TCP_CLIENT_CONFIRMED) { 1063 if (tcp_connection->status == TCP_CLIENT_CONFIRMED) {
1053 do_confirmed_TCP(TCP_connection, userdata); 1064 do_confirmed_TCP(tcp_connection, userdata);
1054 } 1065 }
1055 1066
1056 if (TCP_connection->kill_at <= unix_time()) { 1067 if (tcp_connection->kill_at <= unix_time()) {
1057 TCP_connection->status = TCP_CLIENT_DISCONNECTED; 1068 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
1058 } 1069 }
1059} 1070}
1060 1071
1061/* Kill the TCP connection 1072/* Kill the TCP connection
1062 */ 1073 */
1063void kill_TCP_connection(TCP_Client_Connection *TCP_connection) 1074void kill_TCP_connection(TCP_Client_Connection *tcp_connection)
1064{ 1075{
1065 if (TCP_connection == nullptr) { 1076 if (tcp_connection == nullptr) {
1066 return; 1077 return;
1067 } 1078 }
1068 1079
1069 wipe_priority_list(TCP_connection); 1080 wipe_priority_list(tcp_connection);
1070 kill_sock(TCP_connection->sock); 1081 kill_sock(tcp_connection->sock);
1071 crypto_memzero(TCP_connection, sizeof(TCP_Client_Connection)); 1082 crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection));
1072 free(TCP_connection); 1083 free(tcp_connection);
1073} 1084}
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h
index 96e04d67..8bfe4155 100644
--- a/toxcore/TCP_client.h
+++ b/toxcore/TCP_client.h
@@ -29,18 +29,18 @@
29 29
30#define TCP_CONNECTION_TIMEOUT 10 30#define TCP_CONNECTION_TIMEOUT 10
31 31
32typedef enum { 32typedef enum TCP_Proxy_Type {
33 TCP_PROXY_NONE, 33 TCP_PROXY_NONE,
34 TCP_PROXY_HTTP, 34 TCP_PROXY_HTTP,
35 TCP_PROXY_SOCKS5 35 TCP_PROXY_SOCKS5
36} TCP_PROXY_TYPE; 36} TCP_Proxy_Type;
37 37
38typedef struct { 38typedef struct TCP_Proxy_Info {
39 IP_Port ip_port; 39 IP_Port ip_port;
40 uint8_t proxy_type; // a value from TCP_PROXY_TYPE 40 uint8_t proxy_type; // a value from TCP_PROXY_TYPE
41} TCP_Proxy_Info; 41} TCP_Proxy_Info;
42 42
43typedef enum { 43typedef enum TCP_Client_Status {
44 TCP_CLIENT_NO_STATUS, 44 TCP_CLIENT_NO_STATUS,
45 TCP_CLIENT_PROXY_HTTP_CONNECTING, 45 TCP_CLIENT_PROXY_HTTP_CONNECTING,
46 TCP_CLIENT_PROXY_SOCKS5_CONNECTING, 46 TCP_CLIENT_PROXY_SOCKS5_CONNECTING,
@@ -49,12 +49,13 @@ typedef enum {
49 TCP_CLIENT_UNCONFIRMED, 49 TCP_CLIENT_UNCONFIRMED,
50 TCP_CLIENT_CONFIRMED, 50 TCP_CLIENT_CONFIRMED,
51 TCP_CLIENT_DISCONNECTED, 51 TCP_CLIENT_DISCONNECTED,
52} TCP_CLIENT_STATUS; 52} TCP_Client_Status;
53
53typedef struct TCP_Client_Connection TCP_Client_Connection; 54typedef struct TCP_Client_Connection TCP_Client_Connection;
54 55
55const uint8_t *tcp_con_public_key(const TCP_Client_Connection *con); 56const uint8_t *tcp_con_public_key(const TCP_Client_Connection *con);
56IP_Port tcp_con_ip_port(const TCP_Client_Connection *con); 57IP_Port tcp_con_ip_port(const TCP_Client_Connection *con);
57TCP_CLIENT_STATUS tcp_con_status(const TCP_Client_Connection *con); 58TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con);
58 59
59void *tcp_con_custom_object(const TCP_Client_Connection *con); 60void *tcp_con_custom_object(const TCP_Client_Connection *con);
60uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con); 61uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con);
@@ -68,29 +69,31 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public
68 69
69/* Run the TCP connection 70/* Run the TCP connection
70 */ 71 */
71void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata); 72void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata);
72 73
73/* Kill the TCP connection 74/* Kill the TCP connection
74 */ 75 */
75void kill_TCP_connection(TCP_Client_Connection *TCP_connection); 76void kill_TCP_connection(TCP_Client_Connection *tcp_connection);
77
78typedef int tcp_onion_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata);
76 79
77/* return 1 on success. 80/* return 1 on success.
78 * return 0 if could not send packet. 81 * return 0 if could not send packet.
79 * return -1 on failure (connection must be killed). 82 * return -1 on failure (connection must be killed).
80 */ 83 */
81int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length); 84int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length);
82void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, 85void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object);
83 uint16_t length, void *userdata), void *object); 86
87typedef int tcp_routing_response_cb(void *object, uint8_t connection_id, const uint8_t *public_key);
88typedef int tcp_routing_status_cb(void *object, uint32_t number, uint8_t connection_id, uint8_t status);
84 89
85/* return 1 on success. 90/* return 1 on success.
86 * return 0 if could not send packet. 91 * return 0 if could not send packet.
87 * return -1 on failure (connection must be killed). 92 * return -1 on failure (connection must be killed).
88 */ 93 */
89int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key); 94int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key);
90void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, 95void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object);
91 const uint8_t *public_key), void *object); 96void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object);
92void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number,
93 uint8_t connection_id, uint8_t status), void *object);
94 97
95/* return 1 on success. 98/* return 1 on success.
96 * return 0 if could not send packet. 99 * return 0 if could not send packet.
@@ -107,21 +110,25 @@ int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id);
107 */ 110 */
108int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32_t number); 111int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32_t number);
109 112
113typedef int tcp_routing_data_cb(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data,
114 uint16_t length, void *userdata);
115
110/* return 1 on success. 116/* return 1 on success.
111 * return 0 if could not send packet. 117 * return 0 if could not send packet.
112 * return -1 on failure. 118 * return -1 on failure.
113 */ 119 */
114int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length); 120int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length);
115void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, 121void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object);
116 uint8_t connection_id, const uint8_t *data, uint16_t length, void *userdata), void *object); 122
123typedef int tcp_oob_data_cb(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length,
124 void *userdata);
117 125
118/* return 1 on success. 126/* return 1 on success.
119 * return 0 if could not send packet. 127 * return 0 if could not send packet.
120 * return -1 on failure. 128 * return -1 on failure.
121 */ 129 */
122int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length); 130int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length);
123void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key, 131void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object);
124 const uint8_t *data, uint16_t length, void *userdata), void *object);
125 132
126 133
127#endif 134#endif
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c
index cd1fb565..2d2dd470 100644
--- a/toxcore/TCP_connection.c
+++ b/toxcore/TCP_connection.c
@@ -47,14 +47,13 @@ struct TCP_Connections {
47 TCP_con *tcp_connections; 47 TCP_con *tcp_connections;
48 uint32_t tcp_connections_length; /* Length of tcp_connections array. */ 48 uint32_t tcp_connections_length; /* Length of tcp_connections array. */
49 49
50 int (*tcp_data_callback)(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); 50 tcp_data_cb *tcp_data_callback;
51 void *tcp_data_callback_object; 51 void *tcp_data_callback_object;
52 52
53 int (*tcp_oob_callback)(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, 53 tcp_oob_cb *tcp_oob_callback;
54 const uint8_t *data, uint16_t length, void *userdata);
55 void *tcp_oob_callback_object; 54 void *tcp_oob_callback_object;
56 55
57 int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); 56 tcp_onion_cb *tcp_onion_callback;
58 void *tcp_onion_callback_object; 57 void *tcp_onion_callback_object;
59 58
60 TCP_Proxy_Info proxy_info; 59 TCP_Proxy_Info proxy_info;
@@ -75,28 +74,44 @@ const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c)
75 * return -1 if realloc fails. 74 * return -1 if realloc fails.
76 * return 0 if it succeeds. 75 * return 0 if it succeeds.
77 */ 76 */
78#define MAKE_REALLOC(T) \ 77static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num)
79static int realloc_##T(T **array, size_t num) \ 78{
80{ \ 79 if (!num) {
81 if (!num) { \ 80 free(*array);
82 free(*array); \ 81 *array = nullptr;
83 *array = nullptr; \ 82 return 0;
84 return 0; \ 83 }
85 } \ 84
86 \ 85 TCP_Connection_to *temp_pointer =
87 T *temp_pointer = (T *)realloc(*array, num * sizeof(T)); \ 86 (TCP_Connection_to *)realloc(*array, num * sizeof(TCP_Connection_to));
88 \ 87
89 if (!temp_pointer) { \ 88 if (!temp_pointer) {
90 return -1; \ 89 return -1;
91 } \ 90 }
92 \ 91
93 *array = temp_pointer; \ 92 *array = temp_pointer;
94 \ 93
95 return 0; \ 94 return 0;
96} 95}
97 96
98MAKE_REALLOC(TCP_Connection_to) 97static int realloc_TCP_con(TCP_con **array, size_t num)
99MAKE_REALLOC(TCP_con) 98{
99 if (!num) {
100 free(*array);
101 *array = nullptr;
102 return 0;
103 }
104
105 TCP_con *temp_pointer = (TCP_con *)realloc(*array, num * sizeof(TCP_con));
106
107 if (!temp_pointer) {
108 return -1;
109 }
110
111 *array = temp_pointer;
112
113 return 0;
114}
100 115
101 116
102/* return 1 if the connections_number is not valid. 117/* return 1 if the connections_number is not valid.
@@ -421,8 +436,7 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num
421 436
422/* Set the callback for TCP data packets. 437/* Set the callback for TCP data packets.
423 */ 438 */
424void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, 439void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp_data_callback, void *object)
425 const uint8_t *data, uint16_t length, void *userdata), void *object)
426{ 440{
427 tcp_c->tcp_data_callback = tcp_data_callback; 441 tcp_c->tcp_data_callback = tcp_data_callback;
428 tcp_c->tcp_data_callback_object = object; 442 tcp_c->tcp_data_callback_object = object;
@@ -430,9 +444,7 @@ void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_c
430 444
431/* Set the callback for TCP onion packets. 445/* Set the callback for TCP onion packets.
432 */ 446 */
433void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, 447void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *tcp_oob_callback, void *object)
434 const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length, void *userdata),
435 void *object)
436{ 448{
437 tcp_c->tcp_oob_callback = tcp_oob_callback; 449 tcp_c->tcp_oob_callback = tcp_oob_callback;
438 tcp_c->tcp_oob_callback_object = object; 450 tcp_c->tcp_oob_callback_object = object;
@@ -440,8 +452,7 @@ void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oo
440 452
441/* Set the callback for TCP oob data packets. 453/* Set the callback for TCP oob data packets.
442 */ 454 */
443void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_onion_callback)(void *object, 455void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_cb *tcp_onion_callback, void *object)
444 const uint8_t *data, uint16_t length, void *userdata), void *object)
445{ 456{
446 tcp_c->tcp_onion_callback = tcp_onion_callback; 457 tcp_c->tcp_onion_callback = tcp_onion_callback;
447 tcp_c->tcp_onion_callback_object = object; 458 tcp_c->tcp_onion_callback_object = object;
@@ -915,10 +926,10 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec
915 926
916static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key) 927static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key)
917{ 928{
918 TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; 929 TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
919 TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); 930 TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con);
920 931
921 unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); 932 unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con);
922 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); 933 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
923 934
924 if (!tcp_con) { 935 if (!tcp_con) {
@@ -948,10 +959,10 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
948 959
949static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status) 960static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status)
950{ 961{
951 TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; 962 TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
952 TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); 963 TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con);
953 964
954 unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); 965 unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con);
955 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); 966 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
956 TCP_Connection_to *con_to = get_connection(tcp_c, number); 967 TCP_Connection_to *con_to = get_connection(tcp_c, number);
957 968
@@ -991,10 +1002,10 @@ static int tcp_conn_data_callback(void *object, uint32_t number, uint8_t connect
991 return -1; 1002 return -1;
992 } 1003 }
993 1004
994 TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; 1005 TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
995 TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); 1006 TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con);
996 1007
997 unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); 1008 unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con);
998 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); 1009 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
999 1010
1000 if (!tcp_con) { 1011 if (!tcp_con) {
@@ -1021,10 +1032,10 @@ static int tcp_conn_oob_callback(void *object, const uint8_t *public_key, const
1021 return -1; 1032 return -1;
1022 } 1033 }
1023 1034
1024 TCP_Client_Connection *TCP_client_con = (TCP_Client_Connection *)object; 1035 TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
1025 TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(TCP_client_con); 1036 TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con);
1026 1037
1027 unsigned int tcp_connections_number = tcp_con_custom_uint(TCP_client_con); 1038 unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con);
1028 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); 1039 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
1029 1040
1030 if (!tcp_con) { 1041 if (!tcp_con) {
diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h
index a45129a7..658ee1f4 100644
--- a/toxcore/TCP_connection.h
+++ b/toxcore/TCP_connection.h
@@ -51,20 +51,22 @@
51/* Number of TCP connections used for onion purposes. */ 51/* Number of TCP connections used for onion purposes. */
52#define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS 52#define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS
53 53
54typedef struct { 54typedef struct TCP_Conn_to {
55 uint32_t tcp_connection;
56 unsigned int status;
57 unsigned int connection_id;
58} TCP_Conn_to;
59
60typedef struct TCP_Connection_to {
55 uint8_t status; 61 uint8_t status;
56 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ 62 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */
57 63
58 struct { 64 TCP_Conn_to connections[MAX_FRIEND_TCP_CONNECTIONS];
59 uint32_t tcp_connection;
60 unsigned int status;
61 unsigned int connection_id;
62 } connections[MAX_FRIEND_TCP_CONNECTIONS];
63 65
64 int id; /* id used in callbacks. */ 66 int id; /* id used in callbacks. */
65} TCP_Connection_to; 67} TCP_Connection_to;
66 68
67typedef struct { 69typedef struct TCP_con {
68 uint8_t status; 70 uint8_t status;
69 TCP_Client_Connection *connection; 71 TCP_Client_Connection *connection;
70 uint64_t connected_time; 72 uint64_t connected_time;
@@ -124,21 +126,24 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status);
124int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key, 126int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key,
125 const uint8_t *packet, uint16_t length); 127 const uint8_t *packet, uint16_t length);
126 128
129typedef int tcp_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata);
130
127/* Set the callback for TCP data packets. 131/* Set the callback for TCP data packets.
128 */ 132 */
129void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, 133void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp_data_callback, void *object);
130 const uint8_t *data, uint16_t length, void *userdata), void *object); 134
135typedef int tcp_onion_cb(void *object, const uint8_t *data, uint16_t length, void *userdata);
131 136
132/* Set the callback for TCP onion packets. 137/* Set the callback for TCP onion packets.
133 */ 138 */
134void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_onion_callback)(void *object, 139void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_cb *tcp_onion_callback, void *object);
135 const uint8_t *data, uint16_t length, void *userdata), void *object); 140
141typedef int tcp_oob_cb(void *object, const uint8_t *public_key, unsigned int tcp_connections_number,
142 const uint8_t *data, uint16_t length, void *userdata);
136 143
137/* Set the callback for TCP oob data packets. 144/* Set the callback for TCP oob data packets.
138 */ 145 */
139void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, 146void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *tcp_oob_callback, void *object);
140 const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length, void *userdata),
141 void *object);
142 147
143/* Create a new TCP connection to public_key. 148/* Create a new TCP connection to public_key.
144 * 149 *
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c
index 032b07b3..cc59d088 100644
--- a/toxcore/TCP_server.c
+++ b/toxcore/TCP_server.c
@@ -42,6 +42,21 @@
42#include "mono_time.h" 42#include "mono_time.h"
43#include "util.h" 43#include "util.h"
44 44
45#ifdef TCP_SERVER_USE_EPOLL
46#define TCP_SOCKET_LISTENING 0
47#define TCP_SOCKET_INCOMING 1
48#define TCP_SOCKET_UNCONFIRMED 2
49#define TCP_SOCKET_CONFIRMED 3
50#endif
51
52typedef struct TCP_Secure_Conn {
53 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
54 uint32_t index;
55 // TODO(iphydf): Add an enum for this (same as in TCP_client.c, probably).
56 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
57 uint8_t other_id;
58} TCP_Secure_Conn;
59
45typedef struct TCP_Secure_Connection { 60typedef struct TCP_Secure_Connection {
46 Socket sock; 61 Socket sock;
47 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; 62 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
@@ -49,18 +64,14 @@ typedef struct TCP_Secure_Connection {
49 uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ 64 uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */
50 uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; 65 uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
51 uint16_t next_packet_length; 66 uint16_t next_packet_length;
52 struct { 67 TCP_Secure_Conn connections[NUM_CLIENT_CONNECTIONS];
53 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
54 uint32_t index;
55 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
56 uint8_t other_id;
57 } connections[NUM_CLIENT_CONNECTIONS];
58 uint8_t last_packet[2 + MAX_PACKET_SIZE]; 68 uint8_t last_packet[2 + MAX_PACKET_SIZE];
59 uint8_t status; 69 uint8_t status;
60 uint16_t last_packet_length; 70 uint16_t last_packet_length;
61 uint16_t last_packet_sent; 71 uint16_t last_packet_sent;
62 72
63 TCP_Priority_List *priority_queue_start, *priority_queue_end; 73 TCP_Priority_List *priority_queue_start;
74 TCP_Priority_List *priority_queue_end;
64 75
65 uint64_t identifier; 76 uint64_t identifier;
66 77
@@ -118,74 +129,74 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server)
118 * return -1 if realloc fails. 129 * return -1 if realloc fails.
119 * return 0 if it succeeds. 130 * return 0 if it succeeds.
120 */ 131 */
121static int realloc_connection(TCP_Server *TCP_server, uint32_t num) 132static int realloc_connection(TCP_Server *tcp_server, uint32_t num)
122{ 133{
123 if (num == 0) { 134 if (num == 0) {
124 free(TCP_server->accepted_connection_array); 135 free(tcp_server->accepted_connection_array);
125 TCP_server->accepted_connection_array = nullptr; 136 tcp_server->accepted_connection_array = nullptr;
126 TCP_server->size_accepted_connections = 0; 137 tcp_server->size_accepted_connections = 0;
127 return 0; 138 return 0;
128 } 139 }
129 140
130 if (num == TCP_server->size_accepted_connections) { 141 if (num == tcp_server->size_accepted_connections) {
131 return 0; 142 return 0;
132 } 143 }
133 144
134 TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc( 145 TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc(
135 TCP_server->accepted_connection_array, 146 tcp_server->accepted_connection_array,
136 num * sizeof(TCP_Secure_Connection)); 147 num * sizeof(TCP_Secure_Connection));
137 148
138 if (new_connections == nullptr) { 149 if (new_connections == nullptr) {
139 return -1; 150 return -1;
140 } 151 }
141 152
142 if (num > TCP_server->size_accepted_connections) { 153 if (num > tcp_server->size_accepted_connections) {
143 uint32_t old_size = TCP_server->size_accepted_connections; 154 uint32_t old_size = tcp_server->size_accepted_connections;
144 uint32_t size_new_entries = (num - old_size) * sizeof(TCP_Secure_Connection); 155 uint32_t size_new_entries = (num - old_size) * sizeof(TCP_Secure_Connection);
145 memset(new_connections + old_size, 0, size_new_entries); 156 memset(new_connections + old_size, 0, size_new_entries);
146 } 157 }
147 158
148 TCP_server->accepted_connection_array = new_connections; 159 tcp_server->accepted_connection_array = new_connections;
149 TCP_server->size_accepted_connections = num; 160 tcp_server->size_accepted_connections = num;
150 return 0; 161 return 0;
151} 162}
152 163
153/* return index corresponding to connection with peer on success 164/* return index corresponding to connection with peer on success
154 * return -1 on failure. 165 * return -1 on failure.
155 */ 166 */
156static int get_TCP_connection_index(const TCP_Server *TCP_server, const uint8_t *public_key) 167static int get_TCP_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key)
157{ 168{
158 return bs_list_find(&TCP_server->accepted_key_list, public_key); 169 return bs_list_find(&tcp_server->accepted_key_list, public_key);
159} 170}
160 171
161 172
162static int kill_accepted(TCP_Server *TCP_server, int index); 173static int kill_accepted(TCP_Server *tcp_server, int index);
163 174
164/* Add accepted TCP connection to the list. 175/* Add accepted TCP connection to the list.
165 * 176 *
166 * return index on success 177 * return index on success
167 * return -1 on failure 178 * return -1 on failure
168 */ 179 */
169static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con) 180static int add_accepted(TCP_Server *tcp_server, const TCP_Secure_Connection *con)
170{ 181{
171 int index = get_TCP_connection_index(TCP_server, con->public_key); 182 int index = get_TCP_connection_index(tcp_server, con->public_key);
172 183
173 if (index != -1) { /* If an old connection to the same public key exists, kill it. */ 184 if (index != -1) { /* If an old connection to the same public key exists, kill it. */
174 kill_accepted(TCP_server, index); 185 kill_accepted(tcp_server, index);
175 index = -1; 186 index = -1;
176 } 187 }
177 188
178 if (TCP_server->size_accepted_connections == TCP_server->num_accepted_connections) { 189 if (tcp_server->size_accepted_connections == tcp_server->num_accepted_connections) {
179 if (realloc_connection(TCP_server, TCP_server->size_accepted_connections + 4) == -1) { 190 if (realloc_connection(tcp_server, tcp_server->size_accepted_connections + 4) == -1) {
180 return -1; 191 return -1;
181 } 192 }
182 193
183 index = TCP_server->num_accepted_connections; 194 index = tcp_server->num_accepted_connections;
184 } else { 195 } else {
185 uint32_t i; 196 uint32_t i;
186 197
187 for (i = TCP_server->size_accepted_connections; i != 0; --i) { 198 for (i = tcp_server->size_accepted_connections; i != 0; --i) {
188 if (TCP_server->accepted_connection_array[i - 1].status == TCP_STATUS_NO_STATUS) { 199 if (tcp_server->accepted_connection_array[i - 1].status == TCP_STATUS_NO_STATUS) {
189 index = i - 1; 200 index = i - 1;
190 break; 201 break;
191 } 202 }
@@ -197,16 +208,16 @@ static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con
197 return -1; 208 return -1;
198 } 209 }
199 210
200 if (!bs_list_add(&TCP_server->accepted_key_list, con->public_key, index)) { 211 if (!bs_list_add(&tcp_server->accepted_key_list, con->public_key, index)) {
201 return -1; 212 return -1;
202 } 213 }
203 214
204 memcpy(&TCP_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection)); 215 memcpy(&tcp_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection));
205 TCP_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED; 216 tcp_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED;
206 ++TCP_server->num_accepted_connections; 217 ++tcp_server->num_accepted_connections;
207 TCP_server->accepted_connection_array[index].identifier = ++TCP_server->counter; 218 tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter;
208 TCP_server->accepted_connection_array[index].last_pinged = unix_time(); 219 tcp_server->accepted_connection_array[index].last_pinged = unix_time();
209 TCP_server->accepted_connection_array[index].ping_id = 0; 220 tcp_server->accepted_connection_array[index].ping_id = 0;
210 221
211 return index; 222 return index;
212} 223}
@@ -216,25 +227,25 @@ static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con
216 * return 0 on success 227 * return 0 on success
217 * return -1 on failure 228 * return -1 on failure
218 */ 229 */
219static int del_accepted(TCP_Server *TCP_server, int index) 230static int del_accepted(TCP_Server *tcp_server, int index)
220{ 231{
221 if ((uint32_t)index >= TCP_server->size_accepted_connections) { 232 if ((uint32_t)index >= tcp_server->size_accepted_connections) {
222 return -1; 233 return -1;
223 } 234 }
224 235
225 if (TCP_server->accepted_connection_array[index].status == TCP_STATUS_NO_STATUS) { 236 if (tcp_server->accepted_connection_array[index].status == TCP_STATUS_NO_STATUS) {
226 return -1; 237 return -1;
227 } 238 }
228 239
229 if (!bs_list_remove(&TCP_server->accepted_key_list, TCP_server->accepted_connection_array[index].public_key, index)) { 240 if (!bs_list_remove(&tcp_server->accepted_key_list, tcp_server->accepted_connection_array[index].public_key, index)) {
230 return -1; 241 return -1;
231 } 242 }
232 243
233 crypto_memzero(&TCP_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection)); 244 crypto_memzero(&tcp_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection));
234 --TCP_server->num_accepted_connections; 245 --tcp_server->num_accepted_connections;
235 246
236 if (TCP_server->num_accepted_connections == 0) { 247 if (tcp_server->num_accepted_connections == 0) {
237 realloc_connection(TCP_server, 0); 248 realloc_connection(tcp_server, 0);
238 } 249 }
239 250
240 return 0; 251 return 0;
@@ -505,28 +516,28 @@ static void kill_TCP_secure_connection(TCP_Secure_Connection *con)
505 crypto_memzero(con, sizeof(TCP_Secure_Connection)); 516 crypto_memzero(con, sizeof(TCP_Secure_Connection));
506} 517}
507 518
508static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number); 519static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number);
509 520
510/* Kill an accepted TCP_Secure_Connection 521/* Kill an accepted TCP_Secure_Connection
511 * 522 *
512 * return -1 on failure. 523 * return -1 on failure.
513 * return 0 on success. 524 * return 0 on success.
514 */ 525 */
515static int kill_accepted(TCP_Server *TCP_server, int index) 526static int kill_accepted(TCP_Server *tcp_server, int index)
516{ 527{
517 if ((uint32_t)index >= TCP_server->size_accepted_connections) { 528 if ((uint32_t)index >= tcp_server->size_accepted_connections) {
518 return -1; 529 return -1;
519 } 530 }
520 531
521 uint32_t i; 532 uint32_t i;
522 533
523 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { 534 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
524 rm_connection_index(TCP_server, &TCP_server->accepted_connection_array[index], i); 535 rm_connection_index(tcp_server, &tcp_server->accepted_connection_array[index], i);
525 } 536 }
526 537
527 Socket sock = TCP_server->accepted_connection_array[index].sock; 538 Socket sock = tcp_server->accepted_connection_array[index].sock;
528 539
529 if (del_accepted(TCP_server, index) != 0) { 540 if (del_accepted(tcp_server, index) != 0) {
530 return -1; 541 return -1;
531 } 542 }
532 543
@@ -592,9 +603,9 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data,
592static int read_connection_handshake(TCP_Secure_Connection *con, const uint8_t *self_secret_key) 603static int read_connection_handshake(TCP_Secure_Connection *con, const uint8_t *self_secret_key)
593{ 604{
594 uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE]; 605 uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE];
595 int len = 0; 606 const int len = read_TCP_packet(con->sock, data, TCP_CLIENT_HANDSHAKE_SIZE);
596 607
597 if ((len = read_TCP_packet(con->sock, data, TCP_CLIENT_HANDSHAKE_SIZE)) != -1) { 608 if (len != -1) {
598 return handle_TCP_handshake(con, data, len, self_secret_key); 609 return handle_TCP_handshake(con, data, len, self_secret_key);
599 } 610 }
600 611
@@ -638,11 +649,11 @@ static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id)
638/* return 0 on success. 649/* return 0 on success.
639 * return -1 on failure (connection must be killed). 650 * return -1 on failure (connection must be killed).
640 */ 651 */
641static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key) 652static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key)
642{ 653{
643 uint32_t i; 654 uint32_t i;
644 uint32_t index = ~0; 655 uint32_t index = ~0;
645 TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; 656 TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
646 657
647 /* If person tries to cennect to himself we deny the request*/ 658 /* If person tries to cennect to himself we deny the request*/
648 if (public_key_cmp(con->public_key, public_key) == 0) { 659 if (public_key_cmp(con->public_key, public_key) == 0) {
@@ -687,11 +698,11 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const
687 698
688 con->connections[index].status = 1; 699 con->connections[index].status = 1;
689 memcpy(con->connections[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); 700 memcpy(con->connections[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
690 int other_index = get_TCP_connection_index(TCP_server, public_key); 701 int other_index = get_TCP_connection_index(tcp_server, public_key);
691 702
692 if (other_index != -1) { 703 if (other_index != -1) {
693 uint32_t other_id = ~0; 704 uint32_t other_id = ~0;
694 TCP_Secure_Connection *other_conn = &TCP_server->accepted_connection_array[other_index]; 705 TCP_Secure_Connection *other_conn = &tcp_server->accepted_connection_array[other_index];
695 706
696 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { 707 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
697 if (other_conn->connections[i].status == 1 708 if (other_conn->connections[i].status == 1
@@ -720,23 +731,23 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const
720/* return 0 on success. 731/* return 0 on success.
721 * return -1 on failure (connection must be killed). 732 * return -1 on failure (connection must be killed).
722 */ 733 */
723static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data, 734static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data,
724 uint16_t length) 735 uint16_t length)
725{ 736{
726 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) { 737 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) {
727 return -1; 738 return -1;
728 } 739 }
729 740
730 TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; 741 TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
731 742
732 int other_index = get_TCP_connection_index(TCP_server, public_key); 743 int other_index = get_TCP_connection_index(tcp_server, public_key);
733 744
734 if (other_index != -1) { 745 if (other_index != -1) {
735 VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length); 746 VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length);
736 resp_packet[0] = TCP_PACKET_OOB_RECV; 747 resp_packet[0] = TCP_PACKET_OOB_RECV;
737 memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE); 748 memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE);
738 memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length); 749 memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
739 write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet, 750 write_packet_TCP_secure_connection(&tcp_server->accepted_connection_array[other_index], resp_packet,
740 SIZEOF_VLA(resp_packet), 0); 751 SIZEOF_VLA(resp_packet), 0);
741 } 752 }
742 753
@@ -748,7 +759,7 @@ static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const ui
748 * return -1 on failure. 759 * return -1 on failure.
749 * return 0 on success. 760 * return 0 on success.
750 */ 761 */
751static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number) 762static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number)
752{ 763{
753 if (con_number >= NUM_CLIENT_CONNECTIONS) { 764 if (con_number >= NUM_CLIENT_CONNECTIONS) {
754 return -1; 765 return -1;
@@ -760,15 +771,15 @@ static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *co
760 771
761 if (con->connections[con_number].status == 2) { 772 if (con->connections[con_number].status == 2) {
762 773
763 if (index >= TCP_server->size_accepted_connections) { 774 if (index >= tcp_server->size_accepted_connections) {
764 return -1; 775 return -1;
765 } 776 }
766 777
767 TCP_server->accepted_connection_array[index].connections[other_id].other_id = 0; 778 tcp_server->accepted_connection_array[index].connections[other_id].other_id = 0;
768 TCP_server->accepted_connection_array[index].connections[other_id].index = 0; 779 tcp_server->accepted_connection_array[index].connections[other_id].index = 0;
769 TCP_server->accepted_connection_array[index].connections[other_id].status = 1; 780 tcp_server->accepted_connection_array[index].connections[other_id].status = 1;
770 // TODO(irungentoo): return values? 781 // TODO(irungentoo): return values?
771 send_disconnect_notification(&TCP_server->accepted_connection_array[index], other_id); 782 send_disconnect_notification(&tcp_server->accepted_connection_array[index], other_id);
772 } 783 }
773 784
774 con->connections[con_number].index = 0; 785 con->connections[con_number].index = 0;
@@ -782,14 +793,14 @@ static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *co
782 793
783static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, uint16_t length) 794static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, uint16_t length)
784{ 795{
785 TCP_Server *TCP_server = (TCP_Server *)object; 796 TCP_Server *tcp_server = (TCP_Server *)object;
786 uint32_t index = dest.ip.ip.v6.uint32[0]; 797 uint32_t index = dest.ip.ip.v6.uint32[0];
787 798
788 if (index >= TCP_server->size_accepted_connections) { 799 if (index >= tcp_server->size_accepted_connections) {
789 return 1; 800 return 1;
790 } 801 }
791 802
792 TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[index]; 803 TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[index];
793 804
794 if (con->identifier != dest.ip.ip.v6.uint64[1]) { 805 if (con->identifier != dest.ip.ip.v6.uint64[1]) {
795 return 1; 806 return 1;
@@ -809,13 +820,13 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data,
809/* return 0 on success 820/* return 0 on success
810 * return -1 on failure 821 * return -1 on failure
811 */ 822 */
812static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *data, uint16_t length) 823static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length)
813{ 824{
814 if (length == 0) { 825 if (length == 0) {
815 return -1; 826 return -1;
816 } 827 }
817 828
818 TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; 829 TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
819 830
820 switch (data[0]) { 831 switch (data[0]) {
821 case TCP_PACKET_ROUTING_REQUEST: { 832 case TCP_PACKET_ROUTING_REQUEST: {
@@ -823,7 +834,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
823 return -1; 834 return -1;
824 } 835 }
825 836
826 return handle_TCP_routing_req(TCP_server, con_id, data + 1); 837 return handle_TCP_routing_req(tcp_server, con_id, data + 1);
827 } 838 }
828 839
829 case TCP_PACKET_CONNECTION_NOTIFICATION: { 840 case TCP_PACKET_CONNECTION_NOTIFICATION: {
@@ -839,7 +850,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
839 return -1; 850 return -1;
840 } 851 }
841 852
842 return rm_connection_index(TCP_server, con, data[1] - NUM_RESERVED_PORTS); 853 return rm_connection_index(tcp_server, con, data[1] - NUM_RESERVED_PORTS);
843 } 854 }
844 855
845 case TCP_PACKET_PING: { 856 case TCP_PACKET_PING: {
@@ -878,12 +889,12 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
878 return -1; 889 return -1;
879 } 890 }
880 891
881 return handle_TCP_oob_send(TCP_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE, 892 return handle_TCP_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
882 length - (1 + CRYPTO_PUBLIC_KEY_SIZE)); 893 length - (1 + CRYPTO_PUBLIC_KEY_SIZE));
883 } 894 }
884 895
885 case TCP_PACKET_ONION_REQUEST: { 896 case TCP_PACKET_ONION_REQUEST: {
886 if (TCP_server->onion) { 897 if (tcp_server->onion) {
887 if (length <= 1 + CRYPTO_NONCE_SIZE + ONION_SEND_BASE * 2) { 898 if (length <= 1 + CRYPTO_NONCE_SIZE + ONION_SEND_BASE * 2) {
888 return -1; 899 return -1;
889 } 900 }
@@ -894,7 +905,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
894 source.ip.ip.v6.uint32[0] = con_id; 905 source.ip.ip.v6.uint32[0] = con_id;
895 source.ip.ip.v6.uint32[1] = 0; 906 source.ip.ip.v6.uint32[1] = 0;
896 source.ip.ip.v6.uint64[1] = con->identifier; 907 source.ip.ip.v6.uint64[1] = con->identifier;
897 onion_send_1(TCP_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), source, 908 onion_send_1(tcp_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), source,
898 data + 1); 909 data + 1);
899 } 910 }
900 911
@@ -929,7 +940,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
929 VLA(uint8_t, new_data, length); 940 VLA(uint8_t, new_data, length);
930 memcpy(new_data, data, length); 941 memcpy(new_data, data, length);
931 new_data[0] = other_c_id; 942 new_data[0] = other_c_id;
932 int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length, 0); 943 int ret = write_packet_TCP_secure_connection(&tcp_server->accepted_connection_array[index], new_data, length, 0);
933 944
934 if (ret == -1) { 945 if (ret == -1) {
935 return -1; 946 return -1;
@@ -943,10 +954,10 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
943} 954}
944 955
945 956
946static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection *con, const uint8_t *data, 957static int confirm_TCP_connection(TCP_Server *tcp_server, TCP_Secure_Connection *con, const uint8_t *data,
947 uint16_t length) 958 uint16_t length)
948{ 959{
949 int index = add_accepted(TCP_server, con); 960 int index = add_accepted(tcp_server, con);
950 961
951 if (index == -1) { 962 if (index == -1) {
952 kill_TCP_secure_connection(con); 963 kill_TCP_secure_connection(con);
@@ -955,8 +966,8 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection
955 966
956 crypto_memzero(con, sizeof(TCP_Secure_Connection)); 967 crypto_memzero(con, sizeof(TCP_Secure_Connection));
957 968
958 if (handle_TCP_packet(TCP_server, index, data, length) == -1) { 969 if (handle_TCP_packet(tcp_server, index, data, length) == -1) {
959 kill_accepted(TCP_server, index); 970 kill_accepted(tcp_server, index);
960 return -1; 971 return -1;
961 } 972 }
962 973
@@ -966,7 +977,7 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection
966/* return index on success 977/* return index on success
967 * return -1 on failure 978 * return -1 on failure
968 */ 979 */
969static int accept_connection(TCP_Server *TCP_server, Socket sock) 980static int accept_connection(TCP_Server *tcp_server, Socket sock)
970{ 981{
971 if (!sock_valid(sock)) { 982 if (!sock_valid(sock)) {
972 return -1; 983 return -1;
@@ -982,9 +993,9 @@ static int accept_connection(TCP_Server *TCP_server, Socket sock)
982 return -1; 993 return -1;
983 } 994 }
984 995
985 uint16_t index = TCP_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS; 996 uint16_t index = tcp_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS;
986 997
987 TCP_Secure_Connection *conn = &TCP_server->incoming_connection_queue[index]; 998 TCP_Secure_Connection *conn = &tcp_server->incoming_connection_queue[index];
988 999
989 if (conn->status != TCP_STATUS_NO_STATUS) { 1000 if (conn->status != TCP_STATUS_NO_STATUS) {
990 kill_TCP_secure_connection(conn); 1001 kill_TCP_secure_connection(conn);
@@ -994,7 +1005,7 @@ static int accept_connection(TCP_Server *TCP_server, Socket sock)
994 conn->sock = sock; 1005 conn->sock = sock;
995 conn->next_packet_length = 0; 1006 conn->next_packet_length = 0;
996 1007
997 ++TCP_server->incoming_connection_queue_index; 1008 ++tcp_server->incoming_connection_queue_index;
998 return index; 1009 return index;
999} 1010}
1000 1011
@@ -1107,34 +1118,34 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin
1107} 1118}
1108 1119
1109#ifndef TCP_SERVER_USE_EPOLL 1120#ifndef TCP_SERVER_USE_EPOLL
1110static void do_TCP_accept_new(TCP_Server *TCP_server) 1121static void do_TCP_accept_new(TCP_Server *tcp_server)
1111{ 1122{
1112 uint32_t i; 1123 uint32_t i;
1113 1124
1114 for (i = 0; i < TCP_server->num_listening_socks; ++i) { 1125 for (i = 0; i < tcp_server->num_listening_socks; ++i) {
1115 Socket sock; 1126 Socket sock;
1116 1127
1117 do { 1128 do {
1118 sock = net_accept(TCP_server->socks_listening[i]); 1129 sock = net_accept(tcp_server->socks_listening[i]);
1119 } while (accept_connection(TCP_server, sock) != -1); 1130 } while (accept_connection(tcp_server, sock) != -1);
1120 } 1131 }
1121} 1132}
1122#endif 1133#endif
1123 1134
1124static int do_incoming(TCP_Server *TCP_server, uint32_t i) 1135static int do_incoming(TCP_Server *tcp_server, uint32_t i)
1125{ 1136{
1126 if (TCP_server->incoming_connection_queue[i].status != TCP_STATUS_CONNECTED) { 1137 if (tcp_server->incoming_connection_queue[i].status != TCP_STATUS_CONNECTED) {
1127 return -1; 1138 return -1;
1128 } 1139 }
1129 1140
1130 int ret = read_connection_handshake(&TCP_server->incoming_connection_queue[i], TCP_server->secret_key); 1141 int ret = read_connection_handshake(&tcp_server->incoming_connection_queue[i], tcp_server->secret_key);
1131 1142
1132 if (ret == -1) { 1143 if (ret == -1) {
1133 kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[i]); 1144 kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[i]);
1134 } else if (ret == 1) { 1145 } else if (ret == 1) {
1135 int index_new = TCP_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS; 1146 int index_new = tcp_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS;
1136 TCP_Secure_Connection *conn_old = &TCP_server->incoming_connection_queue[i]; 1147 TCP_Secure_Connection *conn_old = &tcp_server->incoming_connection_queue[i];
1137 TCP_Secure_Connection *conn_new = &TCP_server->unconfirmed_connection_queue[index_new]; 1148 TCP_Secure_Connection *conn_new = &tcp_server->unconfirmed_connection_queue[index_new];
1138 1149
1139 if (conn_new->status != TCP_STATUS_NO_STATUS) { 1150 if (conn_new->status != TCP_STATUS_NO_STATUS) {
1140 kill_TCP_secure_connection(conn_new); 1151 kill_TCP_secure_connection(conn_new);
@@ -1142,7 +1153,7 @@ static int do_incoming(TCP_Server *TCP_server, uint32_t i)
1142 1153
1143 memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection)); 1154 memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection));
1144 crypto_memzero(conn_old, sizeof(TCP_Secure_Connection)); 1155 crypto_memzero(conn_old, sizeof(TCP_Secure_Connection));
1145 ++TCP_server->unconfirmed_connection_queue_index; 1156 ++tcp_server->unconfirmed_connection_queue_index;
1146 1157
1147 return index_new; 1158 return index_new;
1148 } 1159 }
@@ -1150,9 +1161,9 @@ static int do_incoming(TCP_Server *TCP_server, uint32_t i)
1150 return -1; 1161 return -1;
1151} 1162}
1152 1163
1153static int do_unconfirmed(TCP_Server *TCP_server, uint32_t i) 1164static int do_unconfirmed(TCP_Server *tcp_server, uint32_t i)
1154{ 1165{
1155 TCP_Secure_Connection *conn = &TCP_server->unconfirmed_connection_queue[i]; 1166 TCP_Secure_Connection *conn = &tcp_server->unconfirmed_connection_queue[i];
1156 1167
1157 if (conn->status != TCP_STATUS_UNCONFIRMED) { 1168 if (conn->status != TCP_STATUS_UNCONFIRMED) {
1158 return -1; 1169 return -1;
@@ -1171,64 +1182,76 @@ static int do_unconfirmed(TCP_Server *TCP_server, uint32_t i)
1171 return -1; 1182 return -1;
1172 } 1183 }
1173 1184
1174 return confirm_TCP_connection(TCP_server, conn, packet, len); 1185 return confirm_TCP_connection(tcp_server, conn, packet, len);
1175} 1186}
1176 1187
1177static void do_confirmed_recv(TCP_Server *TCP_server, uint32_t i) 1188static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
1178{ 1189{
1179 TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[i]; 1190 TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i];
1180 1191
1181 uint8_t packet[MAX_PACKET_SIZE]; 1192 uint8_t packet[MAX_PACKET_SIZE];
1182 int len; 1193 int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key,
1194 conn->recv_nonce, packet, sizeof(packet));
1183 1195
1184 while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, 1196 if (len == 0) {
1185 conn->recv_nonce, packet, sizeof(packet)))) { 1197 return false;
1186 if (len == -1) { 1198 }
1187 kill_accepted(TCP_server, i);
1188 break;
1189 }
1190 1199
1191 if (handle_TCP_packet(TCP_server, i, packet, len) == -1) { 1200 if (len == -1) {
1192 kill_accepted(TCP_server, i); 1201 kill_accepted(tcp_server, i);
1193 break; 1202 return false;
1194 } 1203 }
1204
1205 if (handle_TCP_packet(tcp_server, i, packet, len) == -1) {
1206 kill_accepted(tcp_server, i);
1207 return false;
1208 }
1209
1210 return true;
1211}
1212
1213static void do_confirmed_recv(TCP_Server *tcp_server, uint32_t i)
1214{
1215 while (tcp_process_secure_packet(tcp_server, i)) {
1216 // Keep reading until an error occurs or there is no more data to read.
1217 continue;
1195 } 1218 }
1196} 1219}
1197 1220
1198#ifndef TCP_SERVER_USE_EPOLL 1221#ifndef TCP_SERVER_USE_EPOLL
1199static void do_TCP_incoming(TCP_Server *TCP_server) 1222static void do_TCP_incoming(TCP_Server *tcp_server)
1200{ 1223{
1201 uint32_t i; 1224 uint32_t i;
1202 1225
1203 for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { 1226 for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
1204 do_incoming(TCP_server, i); 1227 do_incoming(tcp_server, i);
1205 } 1228 }
1206} 1229}
1207 1230
1208static void do_TCP_unconfirmed(TCP_Server *TCP_server) 1231static void do_TCP_unconfirmed(TCP_Server *tcp_server)
1209{ 1232{
1210 uint32_t i; 1233 uint32_t i;
1211 1234
1212 for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { 1235 for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
1213 do_unconfirmed(TCP_server, i); 1236 do_unconfirmed(tcp_server, i);
1214 } 1237 }
1215} 1238}
1216#endif 1239#endif
1217 1240
1218static void do_TCP_confirmed(TCP_Server *TCP_server) 1241static void do_TCP_confirmed(TCP_Server *tcp_server)
1219{ 1242{
1220#ifdef TCP_SERVER_USE_EPOLL 1243#ifdef TCP_SERVER_USE_EPOLL
1221 1244
1222 if (TCP_server->last_run_pinged == unix_time()) { 1245 if (tcp_server->last_run_pinged == unix_time()) {
1223 return; 1246 return;
1224 } 1247 }
1225 1248
1226 TCP_server->last_run_pinged = unix_time(); 1249 tcp_server->last_run_pinged = unix_time();
1227#endif 1250#endif
1228 uint32_t i; 1251 uint32_t i;
1229 1252
1230 for (i = 0; i < TCP_server->size_accepted_connections; ++i) { 1253 for (i = 0; i < tcp_server->size_accepted_connections; ++i) {
1231 TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[i]; 1254 TCP_Secure_Connection *conn = &tcp_server->accepted_connection_array[i];
1232 1255
1233 if (conn->status != TCP_STATUS_CONFIRMED) { 1256 if (conn->status != TCP_STATUS_CONFIRMED) {
1234 continue; 1257 continue;
@@ -1251,14 +1274,14 @@ static void do_TCP_confirmed(TCP_Server *TCP_server)
1251 conn->ping_id = ping_id; 1274 conn->ping_id = ping_id;
1252 } else { 1275 } else {
1253 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) { 1276 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
1254 kill_accepted(TCP_server, i); 1277 kill_accepted(tcp_server, i);
1255 continue; 1278 continue;
1256 } 1279 }
1257 } 1280 }
1258 } 1281 }
1259 1282
1260 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) { 1283 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {
1261 kill_accepted(TCP_server, i); 1284 kill_accepted(tcp_server, i);
1262 continue; 1285 continue;
1263 } 1286 }
1264 1287
@@ -1266,168 +1289,174 @@ static void do_TCP_confirmed(TCP_Server *TCP_server)
1266 1289
1267#ifndef TCP_SERVER_USE_EPOLL 1290#ifndef TCP_SERVER_USE_EPOLL
1268 1291
1269 do_confirmed_recv(TCP_server, i); 1292 do_confirmed_recv(tcp_server, i);
1270 1293
1271#endif 1294#endif
1272 } 1295 }
1273} 1296}
1274 1297
1275#ifdef TCP_SERVER_USE_EPOLL 1298#ifdef TCP_SERVER_USE_EPOLL
1276static void do_TCP_epoll(TCP_Server *TCP_server) 1299static bool tcp_epoll_process(TCP_Server *tcp_server)
1277{ 1300{
1278#define MAX_EVENTS 16 1301#define MAX_EVENTS 16
1279 struct epoll_event events[MAX_EVENTS]; 1302 struct epoll_event events[MAX_EVENTS];
1280 int nfds; 1303 const int nfds = epoll_wait(tcp_server->efd, events, MAX_EVENTS, 0);
1281 1304#undef MAX_EVENTS
1282 while ((nfds = epoll_wait(TCP_server->efd, events, MAX_EVENTS, 0)) > 0) {
1283 int n;
1284 1305
1285 for (n = 0; n < nfds; ++n) { 1306 for (int n = 0; n < nfds; ++n) {
1286 const Socket sock = {(int)(events[n].data.u64 & 0xFFFFFFFF)}; 1307 const Socket sock = {(int)(events[n].data.u64 & 0xFFFFFFFF)};
1287 const int status = (events[n].data.u64 >> 32) & 0xFF; 1308 const int status = (events[n].data.u64 >> 32) & 0xFF;
1288 const int index = events[n].data.u64 >> 40; 1309 const int index = events[n].data.u64 >> 40;
1289 1310
1290 if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (events[n].events & EPOLLRDHUP)) { 1311 if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (events[n].events & EPOLLRDHUP)) {
1291 switch (status) { 1312 switch (status) {
1292 case TCP_SOCKET_LISTENING: { 1313 case TCP_SOCKET_LISTENING: {
1293 //should never happen 1314 // should never happen
1294 break; 1315 break;
1295 } 1316 }
1296
1297 case TCP_SOCKET_INCOMING: {
1298 kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[index]);
1299 break;
1300 }
1301 1317
1302 case TCP_SOCKET_UNCONFIRMED: { 1318 case TCP_SOCKET_INCOMING: {
1303 kill_TCP_secure_connection(&TCP_server->unconfirmed_connection_queue[index]); 1319 kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index]);
1304 break; 1320 break;
1305 } 1321 }
1306 1322
1307 case TCP_SOCKET_CONFIRMED: { 1323 case TCP_SOCKET_UNCONFIRMED: {
1308 kill_accepted(TCP_server, index); 1324 kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index]);
1309 break; 1325 break;
1310 }
1311 } 1326 }
1312 1327
1313 continue; 1328 case TCP_SOCKET_CONFIRMED: {
1329 kill_accepted(tcp_server, index);
1330 break;
1331 }
1314 } 1332 }
1315 1333
1334 continue;
1335 }
1316 1336
1317 if (!(events[n].events & EPOLLIN)) {
1318 continue;
1319 }
1320 1337
1321 switch (status) { 1338 if (!(events[n].events & EPOLLIN)) {
1322 case TCP_SOCKET_LISTENING: { 1339 continue;
1323 //socket is from socks_listening, accept connection 1340 }
1324 while (1) {
1325 Socket sock_new = net_accept(sock);
1326
1327 if (!sock_valid(sock_new)) {
1328 break;
1329 }
1330 1341
1331 int index_new = accept_connection(TCP_server, sock_new); 1342 switch (status) {
1343 case TCP_SOCKET_LISTENING: {
1344 // socket is from socks_listening, accept connection
1345 while (1) {
1346 Socket sock_new = net_accept(sock);
1332 1347
1333 if (index_new == -1) { 1348 if (!sock_valid(sock_new)) {
1334 continue; 1349 break;
1335 } 1350 }
1336 1351
1337 struct epoll_event ev = { 1352 int index_new = accept_connection(tcp_server, sock_new);
1338 .events = EPOLLIN | EPOLLET | EPOLLRDHUP,
1339 .data.u64 = sock_new.socket | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40)
1340 };
1341 1353
1342 if (epoll_ctl(TCP_server->efd, EPOLL_CTL_ADD, sock_new.socket, &ev) == -1) { 1354 if (index_new == -1) {
1343 kill_TCP_secure_connection(&TCP_server->incoming_connection_queue[index_new]); 1355 continue;
1344 continue;
1345 }
1346 } 1356 }
1347 1357
1348 break; 1358 struct epoll_event ev;
1349 }
1350 1359
1351 case TCP_SOCKET_INCOMING: { 1360 ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
1352 int index_new;
1353 1361
1354 if ((index_new = do_incoming(TCP_server, index)) != -1) { 1362 ev.data.u64 = sock_new.socket | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40);
1355 events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP;
1356 events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40);
1357 1363
1358 if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) { 1364 if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.socket, &ev) == -1) {
1359 kill_TCP_secure_connection(&TCP_server->unconfirmed_connection_queue[index_new]); 1365 kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index_new]);
1360 break; 1366 continue;
1361 }
1362 } 1367 }
1363
1364 break;
1365 } 1368 }
1366 1369
1367 case TCP_SOCKET_UNCONFIRMED: { 1370 break;
1368 int index_new; 1371 }
1369 1372
1370 if ((index_new = do_unconfirmed(TCP_server, index)) != -1) { 1373 case TCP_SOCKET_INCOMING: {
1371 events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; 1374 const int index_new = do_incoming(tcp_server, index);
1372 events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40);
1373 1375
1374 if (epoll_ctl(TCP_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) { 1376 if (index_new != -1) {
1375 //remove from confirmed connections 1377 events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP;
1376 kill_accepted(TCP_server, index_new); 1378 events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40);
1377 break;
1378 }
1379 }
1380 1379
1381 break; 1380 if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) {
1381 kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]);
1382 break;
1383 }
1382 } 1384 }
1383 1385
1384 case TCP_SOCKET_CONFIRMED: { 1386 break;
1385 do_confirmed_recv(TCP_server, index); 1387 }
1386 break; 1388
1389 case TCP_SOCKET_UNCONFIRMED: {
1390 const int index_new = do_unconfirmed(tcp_server, index);
1391
1392 if (index_new != -1) {
1393 events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP;
1394 events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40);
1395
1396 if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) {
1397 // remove from confirmed connections
1398 kill_accepted(tcp_server, index_new);
1399 break;
1400 }
1387 } 1401 }
1402
1403 break;
1404 }
1405
1406 case TCP_SOCKET_CONFIRMED: {
1407 do_confirmed_recv(tcp_server, index);
1408 break;
1388 } 1409 }
1389 } 1410 }
1390 } 1411 }
1391 1412
1392#undef MAX_EVENTS 1413 return nfds > 0;
1414}
1415
1416static void do_TCP_epoll(TCP_Server *tcp_server)
1417{
1418 while (tcp_epoll_process(tcp_server)) {
1419 // Keep processing packets until there are no more FDs ready for reading.
1420 continue;
1421 }
1393} 1422}
1394#endif 1423#endif
1395 1424
1396void do_TCP_server(TCP_Server *TCP_server) 1425void do_TCP_server(TCP_Server *tcp_server)
1397{ 1426{
1398 unix_time_update(); 1427 unix_time_update();
1399 1428
1400#ifdef TCP_SERVER_USE_EPOLL 1429#ifdef TCP_SERVER_USE_EPOLL
1401 do_TCP_epoll(TCP_server); 1430 do_TCP_epoll(tcp_server);
1402 1431
1403#else 1432#else
1404 do_TCP_accept_new(TCP_server); 1433 do_TCP_accept_new(tcp_server);
1405 do_TCP_incoming(TCP_server); 1434 do_TCP_incoming(tcp_server);
1406 do_TCP_unconfirmed(TCP_server); 1435 do_TCP_unconfirmed(tcp_server);
1407#endif 1436#endif
1408 1437
1409 do_TCP_confirmed(TCP_server); 1438 do_TCP_confirmed(tcp_server);
1410} 1439}
1411 1440
1412void kill_TCP_server(TCP_Server *TCP_server) 1441void kill_TCP_server(TCP_Server *tcp_server)
1413{ 1442{
1414 uint32_t i; 1443 uint32_t i;
1415 1444
1416 for (i = 0; i < TCP_server->num_listening_socks; ++i) { 1445 for (i = 0; i < tcp_server->num_listening_socks; ++i) {
1417 kill_sock(TCP_server->socks_listening[i]); 1446 kill_sock(tcp_server->socks_listening[i]);
1418 } 1447 }
1419 1448
1420 if (TCP_server->onion) { 1449 if (tcp_server->onion) {
1421 set_callback_handle_recv_1(TCP_server->onion, nullptr, nullptr); 1450 set_callback_handle_recv_1(tcp_server->onion, nullptr, nullptr);
1422 } 1451 }
1423 1452
1424 bs_list_free(&TCP_server->accepted_key_list); 1453 bs_list_free(&tcp_server->accepted_key_list);
1425 1454
1426#ifdef TCP_SERVER_USE_EPOLL 1455#ifdef TCP_SERVER_USE_EPOLL
1427 close(TCP_server->efd); 1456 close(tcp_server->efd);
1428#endif 1457#endif
1429 1458
1430 free(TCP_server->socks_listening); 1459 free(tcp_server->socks_listening);
1431 free(TCP_server->accepted_connection_array); 1460 free(tcp_server->accepted_connection_array);
1432 free(TCP_server); 1461 free(tcp_server);
1433} 1462}
diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h
index c8cbeda0..632a5e79 100644
--- a/toxcore/TCP_server.h
+++ b/toxcore/TCP_server.h
@@ -28,10 +28,6 @@
28#include "list.h" 28#include "list.h"
29#include "onion.h" 29#include "onion.h"
30 30
31#ifdef TCP_SERVER_USE_EPOLL
32#include <sys/epoll.h>
33#endif
34
35#define MAX_INCOMING_CONNECTIONS 256 31#define MAX_INCOMING_CONNECTIONS 256
36 32
37#define TCP_MAX_BACKLOG MAX_INCOMING_CONNECTIONS 33#define TCP_MAX_BACKLOG MAX_INCOMING_CONNECTIONS
@@ -63,25 +59,19 @@
63#define TCP_PING_FREQUENCY 30 59#define TCP_PING_FREQUENCY 30
64#define TCP_PING_TIMEOUT 10 60#define TCP_PING_TIMEOUT 10
65 61
66#ifdef TCP_SERVER_USE_EPOLL 62typedef enum TCP_Status {
67#define TCP_SOCKET_LISTENING 0
68#define TCP_SOCKET_INCOMING 1
69#define TCP_SOCKET_UNCONFIRMED 2
70#define TCP_SOCKET_CONFIRMED 3
71#endif
72
73enum {
74 TCP_STATUS_NO_STATUS, 63 TCP_STATUS_NO_STATUS,
75 TCP_STATUS_CONNECTED, 64 TCP_STATUS_CONNECTED,
76 TCP_STATUS_UNCONFIRMED, 65 TCP_STATUS_UNCONFIRMED,
77 TCP_STATUS_CONFIRMED, 66 TCP_STATUS_CONFIRMED,
78}; 67} TCP_Status;
79 68
80typedef struct TCP_Priority_List TCP_Priority_List; 69typedef struct TCP_Priority_List TCP_Priority_List;
81 70
82struct TCP_Priority_List { 71struct TCP_Priority_List {
83 TCP_Priority_List *next; 72 TCP_Priority_List *next;
84 uint16_t size, sent; 73 uint16_t size;
74 uint16_t sent;
85 uint8_t data[]; 75 uint8_t data[];
86}; 76};
87 77
@@ -97,11 +87,11 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin
97 87
98/* Run the TCP_server 88/* Run the TCP_server
99 */ 89 */
100void do_TCP_server(TCP_Server *TCP_server); 90void do_TCP_server(TCP_Server *tcp_server);
101 91
102/* Kill the TCP server 92/* Kill the TCP server
103 */ 93 */
104void kill_TCP_server(TCP_Server *TCP_server); 94void kill_TCP_server(TCP_Server *tcp_server);
105 95
106/* Read the next two bytes in TCP stream then convert them to 96/* Read the next two bytes in TCP stream then convert them to
107 * length (host byte order). 97 * length (host byte order).
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
index 027f69c3..b9ec23a8 100644
--- a/toxcore/crypto_core.c
+++ b/toxcore/crypto_core.c
@@ -47,42 +47,43 @@
47#endif 47#endif
48 48
49#if CRYPTO_PUBLIC_KEY_SIZE != crypto_box_PUBLICKEYBYTES 49#if CRYPTO_PUBLIC_KEY_SIZE != crypto_box_PUBLICKEYBYTES
50#error CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES 50#error "CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES"
51#endif 51#endif
52 52
53#if CRYPTO_SECRET_KEY_SIZE != crypto_box_SECRETKEYBYTES 53#if CRYPTO_SECRET_KEY_SIZE != crypto_box_SECRETKEYBYTES
54#error CRYPTO_SECRET_KEY_SIZE should be equal to crypto_box_SECRETKEYBYTES 54#error "CRYPTO_SECRET_KEY_SIZE should be equal to crypto_box_SECRETKEYBYTES"
55#endif 55#endif
56 56
57#if CRYPTO_SHARED_KEY_SIZE != crypto_box_BEFORENMBYTES 57#if CRYPTO_SHARED_KEY_SIZE != crypto_box_BEFORENMBYTES
58#error CRYPTO_SHARED_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES 58#error "CRYPTO_SHARED_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES"
59#endif 59#endif
60 60
61#if CRYPTO_SYMMETRIC_KEY_SIZE != crypto_box_BEFORENMBYTES 61#if CRYPTO_SYMMETRIC_KEY_SIZE != crypto_box_BEFORENMBYTES
62#error CRYPTO_SYMMETRIC_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES 62#error "CRYPTO_SYMMETRIC_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES"
63#endif 63#endif
64 64
65#if CRYPTO_MAC_SIZE != crypto_box_MACBYTES 65#if CRYPTO_MAC_SIZE != crypto_box_MACBYTES
66#error CRYPTO_MAC_SIZE should be equal to crypto_box_MACBYTES 66#error "CRYPTO_MAC_SIZE should be equal to crypto_box_MACBYTES"
67#endif 67#endif
68 68
69#if CRYPTO_NONCE_SIZE != crypto_box_NONCEBYTES 69#if CRYPTO_NONCE_SIZE != crypto_box_NONCEBYTES
70#error CRYPTO_NONCE_SIZE should be equal to crypto_box_NONCEBYTES 70#error "CRYPTO_NONCE_SIZE should be equal to crypto_box_NONCEBYTES"
71#endif 71#endif
72 72
73#if CRYPTO_SHA256_SIZE != crypto_hash_sha256_BYTES 73#if CRYPTO_SHA256_SIZE != crypto_hash_sha256_BYTES
74#error CRYPTO_SHA256_SIZE should be equal to crypto_hash_sha256_BYTES 74#error "CRYPTO_SHA256_SIZE should be equal to crypto_hash_sha256_BYTES"
75#endif 75#endif
76 76
77#if CRYPTO_SHA512_SIZE != crypto_hash_sha512_BYTES 77#if CRYPTO_SHA512_SIZE != crypto_hash_sha512_BYTES
78#error CRYPTO_SHA512_SIZE should be equal to crypto_hash_sha512_BYTES 78#error "CRYPTO_SHA512_SIZE should be equal to crypto_hash_sha512_BYTES"
79#endif 79#endif
80 80
81int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
82{
83#if CRYPTO_PUBLIC_KEY_SIZE != 32 81#if CRYPTO_PUBLIC_KEY_SIZE != 32
84#error CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work, 82#error "CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work,"
85#endif 83#endif
84
85int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
86{
86 return crypto_verify_32(pk1, pk2); 87 return crypto_verify_32(pk1, pk2);
87} 88}
88 89
@@ -186,7 +187,7 @@ int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const
186 uint8_t k[crypto_box_BEFORENMBYTES]; 187 uint8_t k[crypto_box_BEFORENMBYTES];
187 encrypt_precompute(public_key, secret_key, k); 188 encrypt_precompute(public_key, secret_key, k);
188 int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted); 189 int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted);
189 crypto_memzero(k, sizeof k); 190 crypto_memzero(k, sizeof(k));
190 return ret; 191 return ret;
191} 192}
192 193
@@ -200,7 +201,7 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const
200 uint8_t k[crypto_box_BEFORENMBYTES]; 201 uint8_t k[crypto_box_BEFORENMBYTES];
201 encrypt_precompute(public_key, secret_key, k); 202 encrypt_precompute(public_key, secret_key, k);
202 int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain); 203 int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain);
203 crypto_memzero(k, sizeof k); 204 crypto_memzero(k, sizeof(k));
204 return ret; 205 return ret;
205} 206}
206 207
@@ -258,7 +259,7 @@ void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num)
258 259
259 for (; i != 0; --i) { 260 for (; i != 0; --i) {
260 carry += (uint_fast16_t) nonce[i - 1] + (uint_fast16_t) num_as_nonce[i - 1]; 261 carry += (uint_fast16_t) nonce[i - 1] + (uint_fast16_t) num_as_nonce[i - 1];
261 nonce[i - 1] = (unsigned char) carry; 262 nonce[i - 1] = (uint8_t)carry;
262 carry >>= 8; 263 carry >>= 8;
263 } 264 }
264} 265}
diff --git a/toxcore/logger.c b/toxcore/logger.c
index d7f84ad1..ac80b194 100644
--- a/toxcore/logger.c
+++ b/toxcore/logger.c
@@ -128,7 +128,7 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l
128 char msg[1024]; 128 char msg[1024];
129 va_list args; 129 va_list args;
130 va_start(args, format); 130 va_start(args, format);
131 vsnprintf(msg, sizeof msg, format, args); 131 vsnprintf(msg, sizeof(msg), format, args);
132 va_end(args); 132 va_end(args);
133 133
134 log->callback(log->context, level, file, line, func, msg, log->userdata); 134 log->callback(log->context, level, file, line, func, msg, log->userdata);
diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c
index 6f54731b..415981d9 100644
--- a/toxcore/mono_time.c
+++ b/toxcore/mono_time.c
@@ -69,7 +69,10 @@ bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_
69} 69}
70 70
71 71
72//!TOKSTYLE-
73// No global mutable state in Tokstyle.
72static Mono_Time global_time; 74static Mono_Time global_time;
75//!TOKSTYLE+
73 76
74/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of 77/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of
75 * unix_time() may fail to increase monotonically with increasing time */ 78 * unix_time() may fail to increase monotonically with increasing time */
@@ -110,10 +113,13 @@ uint64_t current_time_actual(void)
110} 113}
111 114
112 115
116//!TOKSTYLE-
117// No global mutable state in Tokstyle.
113#ifdef OS_WIN32 118#ifdef OS_WIN32
114static uint64_t last_monotime; 119static uint64_t last_monotime;
115static uint64_t add_monotime; 120static uint64_t add_monotime;
116#endif 121#endif
122//!TOKSTYLE+
117 123
118/* return current monotonic time in milliseconds (ms). */ 124/* return current monotonic time in milliseconds (ms). */
119uint64_t current_time_monotonic(void) 125uint64_t current_time_monotonic(void)
diff --git a/toxcore/network.c b/toxcore/network.c
index 24e53c47..bdc6f982 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -44,7 +44,7 @@
44 44
45#ifdef OS_WIN32 45#ifdef OS_WIN32
46#ifndef WINVER 46#ifndef WINVER
47//Windows XP 47// Windows XP
48#define WINVER 0x0501 48#define WINVER 0x0501
49#endif 49#endif
50#endif 50#endif
@@ -185,11 +185,11 @@ static int inet_pton(int family, const char *addrString, void *addrbuf)
185#endif 185#endif
186 186
187#if TOX_INET6_ADDRSTRLEN < INET6_ADDRSTRLEN 187#if TOX_INET6_ADDRSTRLEN < INET6_ADDRSTRLEN
188#error TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN) 188#error "TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN)"
189#endif 189#endif
190 190
191#if TOX_INET_ADDRSTRLEN < INET_ADDRSTRLEN 191#if TOX_INET_ADDRSTRLEN < INET_ADDRSTRLEN
192#error TOX_INET_ADDRSTRLEN should be greater or equal to INET_ADDRSTRLEN (#INET_ADDRSTRLEN) 192#error "TOX_INET_ADDRSTRLEN should be greater or equal to INET_ADDRSTRLEN (#INET_ADDRSTRLEN)"
193#endif 193#endif
194 194
195static int make_proto(int proto); 195static int make_proto(int proto);
@@ -255,8 +255,8 @@ static void fill_addr6(IP6 ip, struct in6_addr *addr)
255#define INADDR_LOOPBACK 0x7f000001 255#define INADDR_LOOPBACK 0x7f000001
256#endif 256#endif
257 257
258const IP4 IP4_BROADCAST = { INADDR_BROADCAST }; 258const IP4 ip4_broadcast = { INADDR_BROADCAST };
259const IP6 IP6_BROADCAST = { 259const IP6 ip6_broadcast = {
260 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } 260 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
261}; 261};
262 262
@@ -274,13 +274,11 @@ IP6 get_ip6_loopback(void)
274 return loopback; 274 return loopback;
275} 275}
276 276
277const Socket net_invalid_socket = { 277#ifndef OS_WIN32
278#ifdef OS_WIN32 278#define INVALID_SOCKET -1
279 (int)INVALID_SOCKET,
280#else
281 -1,
282#endif 279#endif
283}; 280
281const Socket net_invalid_socket = { (int)INVALID_SOCKET };
284 282
285const Family net_family_unspec = {TOX_AF_UNSPEC}; 283const Family net_family_unspec = {TOX_AF_UNSPEC};
286const Family net_family_ipv4 = {TOX_AF_INET}; 284const Family net_family_ipv4 = {TOX_AF_INET};
@@ -421,11 +419,16 @@ int set_socket_dualstack(Socket sock)
421 419
422static uint32_t data_0(uint16_t buflen, const uint8_t *buffer) 420static uint32_t data_0(uint16_t buflen, const uint8_t *buffer)
423{ 421{
424 return buflen > 4 ? net_ntohl(*(const uint32_t *)&buffer[1]) : 0; 422 // TODO(iphydf): Do this differently. Right now this is most likely a
423 // misaligned memory access in reality, and definitely undefined behaviour
424 // in terms of C standard.
425 const uint8_t *const start = buffer + 1;
426 return buflen > 4 ? net_ntohl(*(const uint32_t *)start) : 0;
425} 427}
426static uint32_t data_1(uint16_t buflen, const uint8_t *buffer) 428static uint32_t data_1(uint16_t buflen, const uint8_t *buffer)
427{ 429{
428 return buflen > 7 ? net_ntohl(*(const uint32_t *)&buffer[5]) : 0; 430 const uint8_t *const start = buffer + 5;
431 return buflen > 7 ? net_ntohl(*(const uint32_t *)start) : 0;
429} 432}
430 433
431static void loglogdata(const Logger *log, const char *message, const uint8_t *buffer, 434static void loglogdata(const Logger *log, const char *message, const uint8_t *buffer,
@@ -454,8 +457,8 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu
454 } 457 }
455} 458}
456 459
457typedef struct { 460typedef struct Packet_Handler {
458 packet_handler_callback function; 461 packet_handler_cb *function;
459 void *object; 462 void *object;
460} Packet_Handler; 463} Packet_Handler;
461 464
@@ -537,7 +540,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1
537 return -1; 540 return -1;
538 } 541 }
539 542
540 const int res = sendto(net->sock.socket, (const char *) data, length, 0, (struct sockaddr *)&addr, addrsize); 543 const int res = sendto(net->sock.socket, (const char *)data, length, 0, (struct sockaddr *)&addr, addrsize);
541 544
542 loglogdata(net->log, "O=>", data, length, ip_port, res); 545 loglogdata(net->log, "O=>", data, length, ip_port, res);
543 546
@@ -601,7 +604,7 @@ static int receivepacket(const Logger *log, Socket sock, IP_Port *ip_port, uint8
601 get_ip6(&ip_port->ip.ip.v6, &addr_in6->sin6_addr); 604 get_ip6(&ip_port->ip.ip.v6, &addr_in6->sin6_addr);
602 ip_port->port = addr_in6->sin6_port; 605 ip_port->port = addr_in6->sin6_port;
603 606
604 if (IPV6_IPV4_IN_V6(ip_port->ip.ip.v6)) { 607 if (ipv6_ipv4_in_v6(ip_port->ip.ip.v6)) {
605 ip_port->ip.family = net_family_ipv4; 608 ip_port->ip.family = net_family_ipv4;
606 ip_port->ip.ip.v4.uint32 = ip_port->ip.ip.v6.uint32[3]; 609 ip_port->ip.ip.v4.uint32 = ip_port->ip.ip.v6.uint32[3];
607 } 610 }
@@ -614,7 +617,7 @@ static int receivepacket(const Logger *log, Socket sock, IP_Port *ip_port, uint8
614 return 0; 617 return 0;
615} 618}
616 619
617void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object) 620void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_cb *cb, void *object)
618{ 621{
619 net->packethandlers[byte].function = cb; 622 net->packethandlers[byte].function = cb;
620 net->packethandlers[byte].object = object; 623 net->packethandlers[byte].object = object;
@@ -652,7 +655,10 @@ void networking_poll(Networking_Core *net, void *userdata)
652#include <sodium.h> 655#include <sodium.h>
653#endif 656#endif
654 657
658//!TOKSTYLE-
659// Global mutable state is not allowed in Tokstyle.
655static uint8_t at_startup_ran = 0; 660static uint8_t at_startup_ran = 0;
661//!TOKSTYLE+
656int networking_at_startup(void) 662int networking_at_startup(void)
657{ 663{
658 if (at_startup_ran != 0) { 664 if (at_startup_ran != 0) {
@@ -881,7 +887,7 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
881 *portptr = net_htons(port_to_try); 887 *portptr = net_htons(port_to_try);
882 int tries; 888 int tries;
883 889
884 for (tries = port_from; tries <= port_to; tries++) { 890 for (tries = port_from; tries <= port_to; ++tries) {
885 int res = bind(temp->sock.socket, (struct sockaddr *)&addr, addrsize); 891 int res = bind(temp->sock.socket, (struct sockaddr *)&addr, addrsize);
886 892
887 if (!res) { 893 if (!res) {
@@ -905,7 +911,7 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
905 return temp; 911 return temp;
906 } 912 }
907 913
908 port_to_try++; 914 ++port_to_try;
909 915
910 if (port_to_try > port_to) { 916 if (port_to_try > port_to) {
911 port_to_try = port_from; 917 port_to_try = port_from;
@@ -991,13 +997,13 @@ int ip_equal(const IP *a, const IP *b)
991 997
992 /* different family: check on the IPv6 one if it is the IPv4 one embedded */ 998 /* different family: check on the IPv6 one if it is the IPv4 one embedded */
993 if (net_family_is_ipv4(a->family) && net_family_is_ipv6(b->family)) { 999 if (net_family_is_ipv4(a->family) && net_family_is_ipv6(b->family)) {
994 if (IPV6_IPV4_IN_V6(b->ip.v6)) { 1000 if (ipv6_ipv4_in_v6(b->ip.v6)) {
995 struct in_addr addr_a; 1001 struct in_addr addr_a;
996 fill_addr4(a->ip.v4, &addr_a); 1002 fill_addr4(a->ip.v4, &addr_a);
997 return addr_a.s_addr == b->ip.v6.uint32[3]; 1003 return addr_a.s_addr == b->ip.v6.uint32[3];
998 } 1004 }
999 } else if (net_family_is_ipv6(a->family) && net_family_is_ipv4(b->family)) { 1005 } else if (net_family_is_ipv6(a->family) && net_family_is_ipv4(b->family)) {
1000 if (IPV6_IPV4_IN_V6(a->ip.v6)) { 1006 if (ipv6_ipv4_in_v6(a->ip.v6)) {
1001 struct in_addr addr_b; 1007 struct in_addr addr_b;
1002 fill_addr4(b->ip.v4, &addr_b); 1008 fill_addr4(b->ip.v4, &addr_b);
1003 return a->ip.v6.uint32[3] == addr_b.s_addr; 1009 return a->ip.v6.uint32[3] == addr_b.s_addr;
@@ -1381,12 +1387,12 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
1381 } 1387 }
1382 1388
1383 // Used to avoid malloc parameter overflow 1389 // Used to avoid malloc parameter overflow
1384 const size_t MAX_COUNT = MIN(SIZE_MAX, INT32_MAX) / sizeof(IP_Port); 1390 const size_t max_count = min_u64(SIZE_MAX, INT32_MAX) / sizeof(IP_Port);
1385 int type = make_socktype(tox_type); 1391 int type = make_socktype(tox_type);
1386 struct addrinfo *cur; 1392 struct addrinfo *cur;
1387 size_t count = 0; 1393 size_t count = 0;
1388 1394
1389 for (cur = infos; count < MAX_COUNT && cur != nullptr; cur = cur->ai_next) { 1395 for (cur = infos; count < max_count && cur != nullptr; cur = cur->ai_next) {
1390 if (cur->ai_socktype && type > 0 && cur->ai_socktype != type) { 1396 if (cur->ai_socktype && type > 0 && cur->ai_socktype != type) {
1391 continue; 1397 continue;
1392 } 1398 }
@@ -1395,10 +1401,10 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
1395 continue; 1401 continue;
1396 } 1402 }
1397 1403
1398 count++; 1404 ++count;
1399 } 1405 }
1400 1406
1401 assert(count <= MAX_COUNT); 1407 assert(count <= max_count);
1402 1408
1403 if (count == 0) { 1409 if (count == 0) {
1404 freeaddrinfo(infos); 1410 freeaddrinfo(infos);
@@ -1439,7 +1445,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
1439 1445
1440 ip_port->ip.family = *family; 1446 ip_port->ip.family = *family;
1441 1447
1442 ip_port++; 1448 ++ip_port;
1443 } 1449 }
1444 1450
1445 freeaddrinfo(infos); 1451 freeaddrinfo(infos);
@@ -1621,6 +1627,11 @@ size_t net_unpack_u64(const uint8_t *bytes, uint64_t *v)
1621 return p - bytes; 1627 return p - bytes;
1622} 1628}
1623 1629
1630bool ipv6_ipv4_in_v6(IP6 a)
1631{
1632 return a.uint64[0] == 0 && a.uint32[2] == net_htonl(0xffff);
1633}
1634
1624int net_error(void) 1635int net_error(void)
1625{ 1636{
1626#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 1637#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
diff --git a/toxcore/network.h b/toxcore/network.h
index 8f166c67..7f7cde60 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -98,7 +98,7 @@ size_t net_socket_data_recv_buffer(Socket sock);
98 98
99#define MAX_UDP_PACKET_SIZE 2048 99#define MAX_UDP_PACKET_SIZE 2048
100 100
101typedef enum NET_PACKET_TYPE { 101typedef enum Net_Packet_Type {
102 NET_PACKET_PING_REQUEST = 0x00, /* Ping request packet ID. */ 102 NET_PACKET_PING_REQUEST = 0x00, /* Ping request packet ID. */
103 NET_PACKET_PING_RESPONSE = 0x01, /* Ping response packet ID. */ 103 NET_PACKET_PING_RESPONSE = 0x01, /* Ping response packet ID. */
104 NET_PACKET_GET_NODES = 0x02, /* Get nodes request packet ID. */ 104 NET_PACKET_GET_NODES = 0x02, /* Get nodes request packet ID. */
@@ -127,7 +127,7 @@ typedef enum NET_PACKET_TYPE {
127 BOOTSTRAP_INFO_PACKET_ID = 0xf0, /* Only used for bootstrap nodes */ 127 BOOTSTRAP_INFO_PACKET_ID = 0xf0, /* Only used for bootstrap nodes */
128 128
129 NET_PACKET_MAX = 0xff, /* This type must remain within a single uint8. */ 129 NET_PACKET_MAX = 0xff, /* This type must remain within a single uint8. */
130} NET_PACKET_TYPE; 130} Net_Packet_Type;
131 131
132 132
133#define TOX_PORTRANGE_FROM 33445 133#define TOX_PORTRANGE_FROM 33445
@@ -160,7 +160,7 @@ typedef union IP4 {
160} IP4; 160} IP4;
161 161
162IP4 get_ip4_loopback(void); 162IP4 get_ip4_loopback(void);
163extern const IP4 IP4_BROADCAST; 163extern const IP4 ip4_broadcast;
164 164
165typedef union IP6 { 165typedef union IP6 {
166 uint8_t uint8[16]; 166 uint8_t uint8[16];
@@ -170,15 +170,17 @@ typedef union IP6 {
170} IP6; 170} IP6;
171 171
172IP6 get_ip6_loopback(void); 172IP6 get_ip6_loopback(void);
173extern const IP6 IP6_BROADCAST; 173extern const IP6 ip6_broadcast;
174
175typedef union IP_Union {
176 IP4 v4;
177 IP6 v6;
178} IP_Union;
174 179
175#define IP_DEFINED 180#define IP_DEFINED
176typedef struct IP { 181typedef struct IP {
177 Family family; 182 Family family;
178 union { 183 IP_Union ip;
179 IP4 v4;
180 IP6 v6;
181 } ip;
182} IP; 184} IP;
183 185
184#define IP_PORT_DEFINED 186#define IP_PORT_DEFINED
@@ -203,7 +205,7 @@ size_t net_unpack_u32(const uint8_t *bytes, uint32_t *v);
203size_t net_unpack_u64(const uint8_t *bytes, uint64_t *v); 205size_t net_unpack_u64(const uint8_t *bytes, uint64_t *v);
204 206
205/* Does the IP6 struct a contain an IPv4 address in an IPv6 one? */ 207/* Does the IP6 struct a contain an IPv4 address in an IPv6 one? */
206#define IPV6_IPV4_IN_V6(a) ((a.uint64[0] == 0) && (a.uint32[2] == net_htonl (0xffff))) 208bool ipv6_ipv4_in_v6(IP6 a);
207 209
208#define SIZE_IP4 4 210#define SIZE_IP4 4
209#define SIZE_IP6 16 211#define SIZE_IP6 16
@@ -334,8 +336,7 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra);
334 * Packet data is put into data. 336 * Packet data is put into data.
335 * Packet length is put into length. 337 * Packet length is put into length.
336 */ 338 */
337typedef int (*packet_handler_callback)(void *object, IP_Port ip_port, const uint8_t *data, uint16_t len, 339typedef int packet_handler_cb(void *object, IP_Port ip_port, const uint8_t *data, uint16_t len, void *userdata);
338 void *userdata);
339 340
340typedef struct Networking_Core Networking_Core; 341typedef struct Networking_Core Networking_Core;
341 342
@@ -387,7 +388,7 @@ int set_socket_dualstack(Socket sock);
387int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length); 388int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length);
388 389
389/* Function to call when packet beginning with byte is received. */ 390/* Function to call when packet beginning with byte is received. */
390void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object); 391void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_cb *cb, void *object);
391 392
392/* Call this several times a second. */ 393/* Call this several times a second. */
393void networking_poll(Networking_Core *net, void *userdata); 394void networking_poll(Networking_Core *net, void *userdata);
diff --git a/toxcore/util.c b/toxcore/util.c
index 5ab092ce..f349e8fe 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -66,6 +66,11 @@ void host_to_net(uint8_t *num, uint16_t numbytes)
66#endif 66#endif
67} 67}
68 68
69void net_to_host(uint8_t *num, uint16_t numbytes)
70{
71 host_to_net(num, numbytes);
72}
73
69int create_recursive_mutex(pthread_mutex_t *mutex) 74int create_recursive_mutex(pthread_mutex_t *mutex)
70{ 75{
71 pthread_mutexattr_t attr; 76 pthread_mutexattr_t attr;
@@ -95,6 +100,11 @@ int32_t max_s32(int32_t a, int32_t b)
95 return a > b ? a : b; 100 return a > b ? a : b;
96} 101}
97 102
103uint32_t min_u32(uint32_t a, uint32_t b)
104{
105 return a < b ? a : b;
106}
107
98uint64_t min_u64(uint64_t a, uint64_t b) 108uint64_t min_u64(uint64_t a, uint64_t b)
99{ 109{
100 return a < b ? a : b; 110 return a < b ? a : b;
diff --git a/toxcore/util.h b/toxcore/util.h
index 4c5023cf..76951fff 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -36,20 +36,18 @@
36extern "C" { 36extern "C" {
37#endif 37#endif
38 38
39#define MIN(a,b) (((a)<(b))?(a):(b))
40#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; }
41
42/* id functions */ 39/* id functions */
43bool id_equal(const uint8_t *dest, const uint8_t *src); 40bool id_equal(const uint8_t *dest, const uint8_t *src);
44uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */ 41uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */
45 42
46void host_to_net(uint8_t *num, uint16_t numbytes); 43void host_to_net(uint8_t *num, uint16_t numbytes);
47#define net_to_host(x, y) host_to_net(x, y) 44void net_to_host(uint8_t *num, uint16_t numbytes);
48 45
49/* Returns -1 if failed or 0 if success */ 46/* Returns -1 if failed or 0 if success */
50int create_recursive_mutex(pthread_mutex_t *mutex); 47int create_recursive_mutex(pthread_mutex_t *mutex);
51 48
52int32_t max_s32(int32_t a, int32_t b); 49int32_t max_s32(int32_t a, int32_t b);
50uint32_t min_u32(uint32_t a, uint32_t b);
53uint64_t min_u64(uint64_t a, uint64_t b); 51uint64_t min_u64(uint64_t a, uint64_t b);
54 52
55#ifdef __cplusplus 53#ifdef __cplusplus