1 /* SPDX-License-Identifier: GPL-3.0-or-later
2 * Copyright © 2016-2018 The TokTok team.
3 * Copyright © 2014 Tox project.
4 */
5
6 /*
7 * Implementation of the TCP relay client part of Tox.
8 */
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include "TCP_client.h"
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "mono_time.h"
20 #include "util.h"
21
22 typedef struct TCP_Client_Conn {
23 // TODO(iphydf): Add an enum for this.
24 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
25 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
26 uint32_t number;
27 } TCP_Client_Conn;
28
29 struct TCP_Client_Connection {
30 TCP_Client_Status status;
31 Socket sock;
32 uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */
33 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */
34 IP_Port ip_port; /* The ip and port of the server */
35 TCP_Proxy_Info proxy_info;
36 uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */
37 uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */
38 uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
39 uint16_t next_packet_length;
40
41 uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
42
43 uint8_t last_packet[2 + MAX_PACKET_SIZE];
44 uint16_t last_packet_length;
45 uint16_t last_packet_sent;
46
47 TCP_Priority_List *priority_queue_start;
48 TCP_Priority_List *priority_queue_end;
49
50 uint64_t kill_at;
51
52 uint64_t last_pinged;
53 uint64_t ping_id;
54
55 uint64_t ping_response_id;
56 uint64_t ping_request_id;
57
58 TCP_Client_Conn connections[NUM_CLIENT_CONNECTIONS];
59 tcp_routing_response_cb *response_callback;
60 void *response_callback_object;
61 tcp_routing_status_cb *status_callback;
62 void *status_callback_object;
63 tcp_routing_data_cb *data_callback;
64 void *data_callback_object;
65 tcp_oob_data_cb *oob_data_callback;
66 void *oob_data_callback_object;
67
68 tcp_onion_response_cb *onion_callback;
69 void *onion_callback_object;
70
71 /* Can be used by user. */
72 void *custom_object;
73 uint32_t custom_uint;
74 };
75
tcp_con_public_key(const TCP_Client_Connection * con)76 const uint8_t *tcp_con_public_key(const TCP_Client_Connection *con)
77 {
78 return con->public_key;
79 }
80
tcp_con_ip_port(const TCP_Client_Connection * con)81 IP_Port tcp_con_ip_port(const TCP_Client_Connection *con)
82 {
83 return con->ip_port;
84 }
85
tcp_con_status(const TCP_Client_Connection * con)86 TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con)
87 {
88 return con->status;
89 }
tcp_con_custom_object(const TCP_Client_Connection * con)90 void *tcp_con_custom_object(const TCP_Client_Connection *con)
91 {
92 return con->custom_object;
93 }
tcp_con_custom_uint(const TCP_Client_Connection * con)94 uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con)
95 {
96 return con->custom_uint;
97 }
tcp_con_set_custom_object(TCP_Client_Connection * con,void * object)98 void tcp_con_set_custom_object(TCP_Client_Connection *con, void *object)
99 {
100 con->custom_object = object;
101 }
tcp_con_set_custom_uint(TCP_Client_Connection * con,uint32_t value)102 void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value)
103 {
104 con->custom_uint = value;
105 }
106
107 /* return 1 on success
108 * return 0 on failure
109 */
connect_sock_to(Socket sock,IP_Port ip_port,TCP_Proxy_Info * proxy_info)110 static int connect_sock_to(Socket sock, IP_Port ip_port, TCP_Proxy_Info *proxy_info)
111 {
112 if (proxy_info->proxy_type != TCP_PROXY_NONE) {
113 ip_port = proxy_info->ip_port;
114 }
115
116 /* nonblocking socket, connect will never return success */
117 net_connect(sock, ip_port);
118 return 1;
119 }
120
121 /* return 1 on success.
122 * return 0 on failure.
123 */
proxy_http_generate_connection_request(TCP_Client_Connection * tcp_conn)124 static int proxy_http_generate_connection_request(TCP_Client_Connection *tcp_conn)
125 {
126 char one[] = "CONNECT ";
127 char two[] = " HTTP/1.1\nHost: ";
128 char three[] = "\r\n\r\n";
129
130 char ip[TOX_INET6_ADDRSTRLEN];
131
132 if (!ip_parse_addr(&tcp_conn->ip_port.ip, ip, sizeof(ip))) {
133 return 0;
134 }
135
136 const uint16_t port = net_ntohs(tcp_conn->ip_port.port);
137 const int written = snprintf((char *)tcp_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two,
138 ip, port, three);
139
140 if (written < 0 || MAX_PACKET_SIZE < written) {
141 return 0;
142 }
143
144 tcp_conn->last_packet_length = written;
145 tcp_conn->last_packet_sent = 0;
146
147 return 1;
148 }
149
150 /* return 1 on success.
151 * return 0 if no data received.
152 * return -1 on failure (connection refused).
153 */
proxy_http_read_connection_response(const Logger * logger,TCP_Client_Connection * tcp_conn)154 static int proxy_http_read_connection_response(const Logger *logger, TCP_Client_Connection *tcp_conn)
155 {
156 char success[] = "200";
157 uint8_t data[16]; // draining works the best if the length is a power of 2
158
159 int ret = read_TCP_packet(logger, tcp_conn->sock, data, sizeof(data) - 1);
160
161 if (ret == -1) {
162 return 0;
163 }
164
165 data[sizeof(data) - 1] = 0;
166
167 if (strstr((char *)data, success)) {
168 // drain all data
169 unsigned int data_left = net_socket_data_recv_buffer(tcp_conn->sock);
170
171 if (data_left) {
172 VLA(uint8_t, temp_data, data_left);
173 read_TCP_packet(logger, tcp_conn->sock, temp_data, data_left);
174 }
175
176 return 1;
177 }
178
179 return -1;
180 }
181
proxy_socks5_generate_handshake(TCP_Client_Connection * tcp_conn)182 static void proxy_socks5_generate_handshake(TCP_Client_Connection *tcp_conn)
183 {
184 tcp_conn->last_packet[0] = 5; /* SOCKSv5 */
185 tcp_conn->last_packet[1] = 1; /* number of authentication methods supported */
186 tcp_conn->last_packet[2] = 0; /* No authentication */
187
188 tcp_conn->last_packet_length = 3;
189 tcp_conn->last_packet_sent = 0;
190 }
191
192 /* return 1 on success.
193 * return 0 if no data received.
194 * return -1 on failure (connection refused).
195 */
socks5_read_handshake_response(const Logger * logger,TCP_Client_Connection * tcp_conn)196 static int socks5_read_handshake_response(const Logger *logger, TCP_Client_Connection *tcp_conn)
197 {
198 uint8_t data[2];
199 int ret = read_TCP_packet(logger, tcp_conn->sock, data, sizeof(data));
200
201 if (ret == -1) {
202 return 0;
203 }
204
205 if (data[0] == 5 && data[1] == 0) { // TODO(irungentoo): magic numbers
206 return 1;
207 }
208
209 return -1;
210 }
211
proxy_socks5_generate_connection_request(TCP_Client_Connection * tcp_conn)212 static void proxy_socks5_generate_connection_request(TCP_Client_Connection *tcp_conn)
213 {
214 tcp_conn->last_packet[0] = 5; /* SOCKSv5 */
215 tcp_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */
216 tcp_conn->last_packet[2] = 0; /* reserved, must be 0 */
217 uint16_t length = 3;
218
219 if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
220 tcp_conn->last_packet[3] = 1; /* IPv4 address */
221 ++length;
222 memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4));
223 length += sizeof(IP4);
224 } else {
225 tcp_conn->last_packet[3] = 4; /* IPv6 address */
226 ++length;
227 memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6));
228 length += sizeof(IP6);
229 }
230
231 memcpy(tcp_conn->last_packet + length, &tcp_conn->ip_port.port, sizeof(uint16_t));
232 length += sizeof(uint16_t);
233
234 tcp_conn->last_packet_length = length;
235 tcp_conn->last_packet_sent = 0;
236 }
237
238 /* return 1 on success.
239 * return 0 if no data received.
240 * return -1 on failure (connection refused).
241 */
proxy_socks5_read_connection_response(const Logger * logger,TCP_Client_Connection * tcp_conn)242 static int proxy_socks5_read_connection_response(const Logger *logger, TCP_Client_Connection *tcp_conn)
243 {
244 if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
245 uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)];
246 int ret = read_TCP_packet(logger, tcp_conn->sock, data, sizeof(data));
247
248 if (ret == -1) {
249 return 0;
250 }
251
252 if (data[0] == 5 && data[1] == 0) {
253 return 1;
254 }
255 } else {
256 uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)];
257 int ret = read_TCP_packet(logger, tcp_conn->sock, data, sizeof(data));
258
259 if (ret == -1) {
260 return 0;
261 }
262
263 if (data[0] == 5 && data[1] == 0) {
264 return 1;
265 }
266 }
267
268 return -1;
269 }
270
271 /* return 0 on success.
272 * return -1 on failure.
273 */
generate_handshake(TCP_Client_Connection * tcp_conn)274 static int generate_handshake(TCP_Client_Connection *tcp_conn)
275 {
276 uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
277 crypto_new_keypair(plain, tcp_conn->temp_secret_key);
278 random_nonce(tcp_conn->sent_nonce);
279 memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->sent_nonce, CRYPTO_NONCE_SIZE);
280 memcpy(tcp_conn->last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
281 random_nonce(tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE);
282 int len = encrypt_data_symmetric(tcp_conn->shared_key, tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
283 sizeof(plain), tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
284
285 if (len != sizeof(plain) + CRYPTO_MAC_SIZE) {
286 return -1;
287 }
288
289 tcp_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE;
290 tcp_conn->last_packet_sent = 0;
291 return 0;
292 }
293
294 /* data must be of length TCP_SERVER_HANDSHAKE_SIZE
295 *
296 * return 0 on success.
297 * return -1 on failure.
298 */
handle_handshake(TCP_Client_Connection * tcp_conn,const uint8_t * data)299 static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data)
300 {
301 uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
302 int len = decrypt_data_symmetric(tcp_conn->shared_key, data, data + CRYPTO_NONCE_SIZE,
303 TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain);
304
305 if (len != sizeof(plain)) {
306 return -1;
307 }
308
309 memcpy(tcp_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
310 encrypt_precompute(plain, tcp_conn->temp_secret_key, tcp_conn->shared_key);
311 crypto_memzero(tcp_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE);
312 return 0;
313 }
314
315 /* return 0 if pending data was sent completely
316 * return -1 if it wasn't
317 */
client_send_pending_data_nonpriority(TCP_Client_Connection * con)318 static int client_send_pending_data_nonpriority(TCP_Client_Connection *con)
319 {
320 if (con->last_packet_length == 0) {
321 return 0;
322 }
323
324 const uint16_t left = con->last_packet_length - con->last_packet_sent;
325 const int len = net_send(con->sock, con->last_packet + con->last_packet_sent, left);
326
327 if (len <= 0) {
328 return -1;
329 }
330
331 if (len == left) {
332 con->last_packet_length = 0;
333 con->last_packet_sent = 0;
334 return 0;
335 }
336
337 con->last_packet_sent += len;
338 return -1;
339 }
340
341 /* return 0 if pending data was sent completely
342 * return -1 if it wasn't
343 */
client_send_pending_data(TCP_Client_Connection * con)344 static int client_send_pending_data(TCP_Client_Connection *con)
345 {
346 /* finish sending current non-priority packet */
347 if (client_send_pending_data_nonpriority(con) == -1) {
348 return -1;
349 }
350
351 TCP_Priority_List *p = con->priority_queue_start;
352
353 while (p) {
354 const uint16_t left = p->size - p->sent;
355 const int len = net_send(con->sock, p->data + p->sent, left);
356
357 if (len != left) {
358 if (len > 0) {
359 p->sent += len;
360 }
361
362 break;
363 }
364
365 TCP_Priority_List *pp = p;
366 p = p->next;
367 free(pp);
368 }
369
370 con->priority_queue_start = p;
371
372 if (!p) {
373 con->priority_queue_end = nullptr;
374 return 0;
375 }
376
377 return -1;
378 }
379
380 /* return 0 on failure (only if malloc fails)
381 * return 1 on success
382 */
client_add_priority(TCP_Client_Connection * con,const uint8_t * packet,uint16_t size,uint16_t sent)383 static bool client_add_priority(TCP_Client_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
384 {
385 TCP_Priority_List *p = con->priority_queue_end;
386 TCP_Priority_List *new_list = (TCP_Priority_List *)malloc(sizeof(TCP_Priority_List) + size);
387
388 if (!new_list) {
389 return 0;
390 }
391
392 new_list->next = nullptr;
393 new_list->size = size;
394 new_list->sent = sent;
395 memcpy(new_list->data, packet, size);
396
397 if (p) {
398 p->next = new_list;
399 } else {
400 con->priority_queue_start = new_list;
401 }
402
403 con->priority_queue_end = new_list;
404 return 1;
405 }
406
407 /* return 1 on success.
408 * return 0 if could not send packet.
409 * return -1 on failure (connection must be killed).
410 */
write_packet_TCP_client_secure_connection(TCP_Client_Connection * con,const uint8_t * data,uint16_t length,bool priority)411 static int write_packet_TCP_client_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length,
412 bool priority)
413 {
414 if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) {
415 return -1;
416 }
417
418 bool sendpriority = 1;
419
420 if (client_send_pending_data(con) == -1) {
421 if (priority) {
422 sendpriority = 0;
423 } else {
424 return 0;
425 }
426 }
427
428 VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
429
430 uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
431 memcpy(packet, &c_length, sizeof(uint16_t));
432 int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
433
434 if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) {
435 return -1;
436 }
437
438 if (priority) {
439 len = sendpriority ? net_send(con->sock, packet, SIZEOF_VLA(packet)) : 0;
440
441 if (len <= 0) {
442 len = 0;
443 }
444
445 increment_nonce(con->sent_nonce);
446
447 if ((unsigned int)len == SIZEOF_VLA(packet)) {
448 return 1;
449 }
450
451 return client_add_priority(con, packet, SIZEOF_VLA(packet), len);
452 }
453
454 len = net_send(con->sock, packet, SIZEOF_VLA(packet));
455
456 if (len <= 0) {
457 return 0;
458 }
459
460 increment_nonce(con->sent_nonce);
461
462 if ((unsigned int)len == SIZEOF_VLA(packet)) {
463 return 1;
464 }
465
466 memcpy(con->last_packet, packet, SIZEOF_VLA(packet));
467 con->last_packet_length = SIZEOF_VLA(packet);
468 con->last_packet_sent = len;
469 return 1;
470 }
471
472 /* return 1 on success.
473 * return 0 if could not send packet.
474 * return -1 on failure (connection must be killed).
475 */
send_routing_request(TCP_Client_Connection * con,uint8_t * public_key)476 int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
477 {
478 uint8_t packet[1 + CRYPTO_PUBLIC_KEY_SIZE];
479 packet[0] = TCP_PACKET_ROUTING_REQUEST;
480 memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
481 return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
482 }
483
routing_response_handler(TCP_Client_Connection * con,tcp_routing_response_cb * response_callback,void * object)484 void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object)
485 {
486 con->response_callback = response_callback;
487 con->response_callback_object = object;
488 }
489
routing_status_handler(TCP_Client_Connection * con,tcp_routing_status_cb * status_callback,void * object)490 void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object)
491 {
492 con->status_callback = status_callback;
493 con->status_callback_object = object;
494 }
495
496 static int tcp_send_ping_response(TCP_Client_Connection *con);
497 static int tcp_send_ping_request(TCP_Client_Connection *con);
498
499 /* return 1 on success.
500 * return 0 if could not send packet.
501 * return -1 on failure.
502 */
send_data(TCP_Client_Connection * con,uint8_t con_id,const uint8_t * data,uint16_t length)503 int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length)
504 {
505 if (con_id >= NUM_CLIENT_CONNECTIONS) {
506 return -1;
507 }
508
509 if (con->connections[con_id].status != 2) {
510 return -1;
511 }
512
513 if (tcp_send_ping_response(con) == 0 || tcp_send_ping_request(con) == 0) {
514 return 0;
515 }
516
517 VLA(uint8_t, packet, 1 + length);
518 packet[0] = con_id + NUM_RESERVED_PORTS;
519 memcpy(packet + 1, data, length);
520 return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
521 }
522
523 /* return 1 on success.
524 * return 0 if could not send packet.
525 * return -1 on failure.
526 */
send_oob_packet(TCP_Client_Connection * con,const uint8_t * public_key,const uint8_t * data,uint16_t length)527 int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length)
528 {
529 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) {
530 return -1;
531 }
532
533 VLA(uint8_t, packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length);
534 packet[0] = TCP_PACKET_OOB_SEND;
535 memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
536 memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
537 return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
538 }
539
540
541 /* Set the number that will be used as an argument in the callbacks related to con_id.
542 *
543 * When not set by this function, the number is -1.
544 *
545 * return 0 on success.
546 * return -1 on failure.
547 */
set_tcp_connection_number(TCP_Client_Connection * con,uint8_t con_id,uint32_t number)548 int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32_t number)
549 {
550 if (con_id >= NUM_CLIENT_CONNECTIONS) {
551 return -1;
552 }
553
554 if (con->connections[con_id].status == 0) {
555 return -1;
556 }
557
558 con->connections[con_id].number = number;
559 return 0;
560 }
561
routing_data_handler(TCP_Client_Connection * con,tcp_routing_data_cb * data_callback,void * object)562 void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object)
563 {
564 con->data_callback = data_callback;
565 con->data_callback_object = object;
566 }
567
oob_data_handler(TCP_Client_Connection * con,tcp_oob_data_cb * oob_data_callback,void * object)568 void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object)
569 {
570 con->oob_data_callback = oob_data_callback;
571 con->oob_data_callback_object = object;
572 }
573
574 /* return 1 on success.
575 * return 0 if could not send packet.
576 * return -1 on failure (connection must be killed).
577 */
client_send_disconnect_notification(TCP_Client_Connection * con,uint8_t id)578 static int client_send_disconnect_notification(TCP_Client_Connection *con, uint8_t id)
579 {
580 uint8_t packet[1 + 1];
581 packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
582 packet[1] = id;
583 return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
584 }
585
586 /* return 1 on success.
587 * return 0 if could not send packet.
588 * return -1 on failure (connection must be killed).
589 */
tcp_send_ping_request(TCP_Client_Connection * con)590 static int tcp_send_ping_request(TCP_Client_Connection *con)
591 {
592 if (!con->ping_request_id) {
593 return 1;
594 }
595
596 uint8_t packet[1 + sizeof(uint64_t)];
597 packet[0] = TCP_PACKET_PING;
598 memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t));
599 const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
600
601 if (ret == 1) {
602 con->ping_request_id = 0;
603 }
604
605 return ret;
606 }
607
608 /* return 1 on success.
609 * return 0 if could not send packet.
610 * return -1 on failure (connection must be killed).
611 */
tcp_send_ping_response(TCP_Client_Connection * con)612 static int tcp_send_ping_response(TCP_Client_Connection *con)
613 {
614 if (!con->ping_response_id) {
615 return 1;
616 }
617
618 uint8_t packet[1 + sizeof(uint64_t)];
619 packet[0] = TCP_PACKET_PONG;
620 memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
621 const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
622
623 if (ret == 1) {
624 con->ping_response_id = 0;
625 }
626
627 return ret;
628 }
629
630 /* return 1 on success.
631 * return 0 if could not send packet.
632 * return -1 on failure (connection must be killed).
633 */
send_disconnect_request(TCP_Client_Connection * con,uint8_t con_id)634 int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id)
635 {
636 if (con_id >= NUM_CLIENT_CONNECTIONS) {
637 return -1;
638 }
639
640 con->connections[con_id].status = 0;
641 con->connections[con_id].number = 0;
642 return client_send_disconnect_notification(con, con_id + NUM_RESERVED_PORTS);
643 }
644
645 /* return 1 on success.
646 * return 0 if could not send packet.
647 * return -1 on failure (connection must be killed).
648 */
send_onion_request(TCP_Client_Connection * con,const uint8_t * data,uint16_t length)649 int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length)
650 {
651 VLA(uint8_t, packet, 1 + length);
652 packet[0] = TCP_PACKET_ONION_REQUEST;
653 memcpy(packet + 1, data, length);
654 return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
655 }
656
onion_response_handler(TCP_Client_Connection * con,tcp_onion_response_cb * onion_callback,void * object)657 void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object)
658 {
659 con->onion_callback = onion_callback;
660 con->onion_callback_object = object;
661 }
662
663 /* Create new TCP connection to ip_port/public_key
664 */
new_TCP_connection(const Mono_Time * mono_time,IP_Port ip_port,const uint8_t * public_key,const uint8_t * self_public_key,const uint8_t * self_secret_key,TCP_Proxy_Info * proxy_info)665 TCP_Client_Connection *new_TCP_connection(const Mono_Time *mono_time, IP_Port ip_port, const uint8_t *public_key,
666 const uint8_t *self_public_key, const uint8_t *self_secret_key, TCP_Proxy_Info *proxy_info)
667 {
668 if (networking_at_startup() != 0) {
669 return nullptr;
670 }
671
672 if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
673 return nullptr;
674 }
675
676 TCP_Proxy_Info default_proxyinfo;
677
678 if (proxy_info == nullptr) {
679 default_proxyinfo.proxy_type = TCP_PROXY_NONE;
680 proxy_info = &default_proxyinfo;
681 }
682
683 Family family = ip_port.ip.family;
684
685 if (proxy_info->proxy_type != TCP_PROXY_NONE) {
686 family = proxy_info->ip_port.ip.family;
687 }
688
689 Socket sock = net_socket(family, TOX_SOCK_STREAM, TOX_PROTO_TCP);
690
691 if (!sock_valid(sock)) {
692 return nullptr;
693 }
694
695 if (!set_socket_nosigpipe(sock)) {
696 kill_sock(sock);
697 return nullptr;
698 }
699
700 if (!(set_socket_nonblock(sock) && connect_sock_to(sock, ip_port, proxy_info))) {
701 kill_sock(sock);
702 return nullptr;
703 }
704
705 TCP_Client_Connection *temp = (TCP_Client_Connection *)calloc(sizeof(TCP_Client_Connection), 1);
706
707 if (temp == nullptr) {
708 kill_sock(sock);
709 return nullptr;
710 }
711
712 temp->sock = sock;
713 memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
714 memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
715 encrypt_precompute(temp->public_key, self_secret_key, temp->shared_key);
716 temp->ip_port = ip_port;
717 temp->proxy_info = *proxy_info;
718
719 switch (proxy_info->proxy_type) {
720 case TCP_PROXY_HTTP:
721 temp->status = TCP_CLIENT_PROXY_HTTP_CONNECTING;
722 proxy_http_generate_connection_request(temp);
723 break;
724
725 case TCP_PROXY_SOCKS5:
726 temp->status = TCP_CLIENT_PROXY_SOCKS5_CONNECTING;
727 proxy_socks5_generate_handshake(temp);
728 break;
729
730 case TCP_PROXY_NONE:
731 temp->status = TCP_CLIENT_CONNECTING;
732
733 if (generate_handshake(temp) == -1) {
734 kill_sock(sock);
735 free(temp);
736 return nullptr;
737 }
738
739 break;
740 }
741
742 temp->kill_at = mono_time_get(mono_time) + TCP_CONNECTION_TIMEOUT;
743
744 return temp;
745 }
746
747 /* return 0 on success
748 * return -1 on failure
749 */
handle_TCP_client_packet(TCP_Client_Connection * conn,const uint8_t * data,uint16_t length,void * userdata)750 static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length, void *userdata)
751 {
752 if (length <= 1) {
753 return -1;
754 }
755
756 switch (data[0]) {
757 case TCP_PACKET_ROUTING_RESPONSE: {
758 if (length != 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE) {
759 return -1;
760 }
761
762 if (data[1] < NUM_RESERVED_PORTS) {
763 return 0;
764 }
765
766 uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
767
768 if (conn->connections[con_id].status != 0) {
769 return 0;
770 }
771
772 conn->connections[con_id].status = 1;
773 conn->connections[con_id].number = -1;
774 memcpy(conn->connections[con_id].public_key, data + 2, CRYPTO_PUBLIC_KEY_SIZE);
775
776 if (conn->response_callback) {
777 conn->response_callback(conn->response_callback_object, con_id, conn->connections[con_id].public_key);
778 }
779
780 return 0;
781 }
782
783 case TCP_PACKET_CONNECTION_NOTIFICATION: {
784 if (length != 1 + 1) {
785 return -1;
786 }
787
788 if (data[1] < NUM_RESERVED_PORTS) {
789 return -1;
790 }
791
792 uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
793
794 if (conn->connections[con_id].status != 1) {
795 return 0;
796 }
797
798 conn->connections[con_id].status = 2;
799
800 if (conn->status_callback) {
801 conn->status_callback(conn->status_callback_object, conn->connections[con_id].number, con_id,
802 conn->connections[con_id].status);
803 }
804
805 return 0;
806 }
807
808 case TCP_PACKET_DISCONNECT_NOTIFICATION: {
809 if (length != 1 + 1) {
810 return -1;
811 }
812
813 if (data[1] < NUM_RESERVED_PORTS) {
814 return -1;
815 }
816
817 uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
818
819 if (conn->connections[con_id].status == 0) {
820 return 0;
821 }
822
823 if (conn->connections[con_id].status != 2) {
824 return 0;
825 }
826
827 conn->connections[con_id].status = 1;
828
829 if (conn->status_callback) {
830 conn->status_callback(conn->status_callback_object, conn->connections[con_id].number, con_id,
831 conn->connections[con_id].status);
832 }
833
834 return 0;
835 }
836
837 case TCP_PACKET_PING: {
838 if (length != 1 + sizeof(uint64_t)) {
839 return -1;
840 }
841
842 uint64_t ping_id;
843 memcpy(&ping_id, data + 1, sizeof(uint64_t));
844 conn->ping_response_id = ping_id;
845 tcp_send_ping_response(conn);
846 return 0;
847 }
848
849 case TCP_PACKET_PONG: {
850 if (length != 1 + sizeof(uint64_t)) {
851 return -1;
852 }
853
854 uint64_t ping_id;
855 memcpy(&ping_id, data + 1, sizeof(uint64_t));
856
857 if (ping_id) {
858 if (ping_id == conn->ping_id) {
859 conn->ping_id = 0;
860 }
861
862 return 0;
863 }
864
865 return -1;
866 }
867
868 case TCP_PACKET_OOB_RECV: {
869 if (length <= 1 + CRYPTO_PUBLIC_KEY_SIZE) {
870 return -1;
871 }
872
873 if (conn->oob_data_callback) {
874 conn->oob_data_callback(conn->oob_data_callback_object, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
875 length - (1 + CRYPTO_PUBLIC_KEY_SIZE), userdata);
876 }
877
878 return 0;
879 }
880
881 case TCP_PACKET_ONION_RESPONSE: {
882 conn->onion_callback(conn->onion_callback_object, data + 1, length - 1, userdata);
883 return 0;
884 }
885
886 default: {
887 if (data[0] < NUM_RESERVED_PORTS) {
888 return -1;
889 }
890
891 uint8_t con_id = data[0] - NUM_RESERVED_PORTS;
892
893 if (conn->data_callback) {
894 conn->data_callback(conn->data_callback_object, conn->connections[con_id].number, con_id, data + 1, length - 1,
895 userdata);
896 }
897 }
898 }
899
900 return 0;
901 }
902
tcp_process_packet(const Logger * logger,TCP_Client_Connection * conn,void * userdata)903 static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn, void *userdata)
904 {
905 uint8_t packet[MAX_PACKET_SIZE];
906 const int len = read_packet_TCP_secure_connection(logger, conn->sock, &conn->next_packet_length, conn->shared_key,
907 conn->recv_nonce, packet, sizeof(packet));
908
909 if (len == 0) {
910 return false;
911 }
912
913 if (len == -1) {
914 conn->status = TCP_CLIENT_DISCONNECTED;
915 return false;
916 }
917
918 if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) {
919 conn->status = TCP_CLIENT_DISCONNECTED;
920 return false;
921 }
922
923 return true;
924 }
925
do_confirmed_TCP(const Logger * logger,TCP_Client_Connection * conn,const Mono_Time * mono_time,void * userdata)926 static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, const Mono_Time *mono_time,
927 void *userdata)
928 {
929 client_send_pending_data(conn);
930 tcp_send_ping_response(conn);
931 tcp_send_ping_request(conn);
932
933 if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) {
934 uint64_t ping_id = random_u64();
935
936 if (!ping_id) {
937 ++ping_id;
938 }
939
940 conn->ping_request_id = ping_id;
941 conn->ping_id = ping_id;
942 tcp_send_ping_request(conn);
943 conn->last_pinged = mono_time_get(mono_time);
944 }
945
946 if (conn->ping_id && mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_TIMEOUT)) {
947 conn->status = TCP_CLIENT_DISCONNECTED;
948 return 0;
949 }
950
951 while (tcp_process_packet(logger, conn, userdata)) {
952 // Keep reading until error or out of data.
953 continue;
954 }
955
956 return 0;
957 }
958
959 /* Run the TCP connection
960 */
do_TCP_connection(const Logger * logger,Mono_Time * mono_time,TCP_Client_Connection * tcp_connection,void * userdata)961 void do_TCP_connection(const Logger *logger, Mono_Time *mono_time, TCP_Client_Connection *tcp_connection,
962 void *userdata)
963 {
964 if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) {
965 return;
966 }
967
968 if (tcp_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) {
969 if (client_send_pending_data(tcp_connection) == 0) {
970 int ret = proxy_http_read_connection_response(logger, tcp_connection);
971
972 if (ret == -1) {
973 tcp_connection->kill_at = 0;
974 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
975 }
976
977 if (ret == 1) {
978 generate_handshake(tcp_connection);
979 tcp_connection->status = TCP_CLIENT_CONNECTING;
980 }
981 }
982 }
983
984 if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) {
985 if (client_send_pending_data(tcp_connection) == 0) {
986 int ret = socks5_read_handshake_response(logger, tcp_connection);
987
988 if (ret == -1) {
989 tcp_connection->kill_at = 0;
990 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
991 }
992
993 if (ret == 1) {
994 proxy_socks5_generate_connection_request(tcp_connection);
995 tcp_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED;
996 }
997 }
998 }
999
1000 if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) {
1001 if (client_send_pending_data(tcp_connection) == 0) {
1002 int ret = proxy_socks5_read_connection_response(logger, tcp_connection);
1003
1004 if (ret == -1) {
1005 tcp_connection->kill_at = 0;
1006 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
1007 }
1008
1009 if (ret == 1) {
1010 generate_handshake(tcp_connection);
1011 tcp_connection->status = TCP_CLIENT_CONNECTING;
1012 }
1013 }
1014 }
1015
1016 if (tcp_connection->status == TCP_CLIENT_CONNECTING) {
1017 if (client_send_pending_data(tcp_connection) == 0) {
1018 tcp_connection->status = TCP_CLIENT_UNCONFIRMED;
1019 }
1020 }
1021
1022 if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) {
1023 uint8_t data[TCP_SERVER_HANDSHAKE_SIZE];
1024 int len = read_TCP_packet(logger, tcp_connection->sock, data, sizeof(data));
1025
1026 if (sizeof(data) == len) {
1027 if (handle_handshake(tcp_connection, data) == 0) {
1028 tcp_connection->kill_at = -1;
1029 tcp_connection->status = TCP_CLIENT_CONFIRMED;
1030 } else {
1031 tcp_connection->kill_at = 0;
1032 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
1033 }
1034 }
1035 }
1036
1037 if (tcp_connection->status == TCP_CLIENT_CONFIRMED) {
1038 do_confirmed_TCP(logger, tcp_connection, mono_time, userdata);
1039 }
1040
1041 if (tcp_connection->kill_at <= mono_time_get(mono_time)) {
1042 tcp_connection->status = TCP_CLIENT_DISCONNECTED;
1043 }
1044 }
1045
1046 /* Kill the TCP connection
1047 */
kill_TCP_connection(TCP_Client_Connection * tcp_connection)1048 void kill_TCP_connection(TCP_Client_Connection *tcp_connection)
1049 {
1050 if (tcp_connection == nullptr) {
1051 return;
1052 }
1053
1054 wipe_priority_list(tcp_connection->priority_queue_start);
1055 kill_sock(tcp_connection->sock);
1056 crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection));
1057 free(tcp_connection);
1058 }
1059