summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxcore/Messenger.c64
-rw-r--r--toxcore/Messenger.h13
-rw-r--r--toxcore/TCP_client.c2
-rw-r--r--toxcore/TCP_client.h4
-rw-r--r--toxcore/TCP_connection.c480
-rw-r--r--toxcore/TCP_connection.h57
-rw-r--r--toxcore/crypto_core.c22
-rw-r--r--toxcore/crypto_core.h4
-rw-r--r--toxcore/friend_connection.c179
-rw-r--r--toxcore/friend_connection.h22
-rw-r--r--toxcore/net_crypto.c875
-rw-r--r--toxcore/net_crypto.h66
-rw-r--r--toxcore/onion.c4
-rw-r--r--toxcore/onion_client.c15
-rw-r--r--toxcore/onion_client.h2
-rw-r--r--toxcore/tox.h6
16 files changed, 925 insertions, 890 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index fefc3b17..fd17ab98 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -433,14 +433,19 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber)
433 return -1; 433 return -1;
434 434
435 if (m->friendlist[friendnumber].status == FRIEND_ONLINE) { 435 if (m->friendlist[friendnumber].status == FRIEND_ONLINE) {
436 uint8_t direct_connected = 0; 436 _Bool direct_connected = 0;
437 unsigned int num_online_relays = 0;
437 crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, 438 crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c,
438 m->friendlist[friendnumber].friendcon_id), &direct_connected); 439 m->friendlist[friendnumber].friendcon_id), &direct_connected, &num_online_relays);
439 440
440 if (direct_connected) { 441 if (direct_connected) {
441 return CONNECTION_UDP; 442 return CONNECTION_UDP;
442 } else { 443 } else {
443 return CONNECTION_TCP; 444 if (num_online_relays) {
445 return CONNECTION_TCP;
446 } else {
447 return CONNECTION_UNKNOWN;
448 }
444 } 449 }
445 } else { 450 } else {
446 return CONNECTION_NONE; 451 return CONNECTION_NONE;
@@ -493,10 +498,6 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con
493 498
494 uint32_t msg_id = ++m->friendlist[friendnumber].message_id; 499 uint32_t msg_id = ++m->friendlist[friendnumber].message_id;
495 500
496 if (msg_id == 0) {
497 msg_id = ++m->friendlist[friendnumber].message_id; // Otherwise, false error
498 }
499
500 add_receipt(m, friendnumber, packet_num, msg_id); 501 add_receipt(m, friendnumber, packet_num, msg_id);
501 502
502 if (message_id) 503 if (message_id)
@@ -753,25 +754,6 @@ static int send_user_istyping(const Messenger *m, int32_t friendnumber, uint8_t
753 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0); 754 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0);
754} 755}
755 756
756static int send_relays(const Messenger *m, int32_t friendnumber)
757{
758 Node_format nodes[MAX_SHARED_RELAYS];
759 uint8_t data[1024];
760 int n, length;
761
762 n = copy_connected_tcp_relays(m->net_crypto, nodes, MAX_SHARED_RELAYS);
763 length = pack_nodes(data, sizeof(data), nodes, n);
764
765 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_SHARE_RELAYS, data, length, 0);
766
767 if (ret == 1)
768 m->friendlist[friendnumber].share_relays_lastsent = unix_time();
769
770 return ret;
771}
772
773
774
775static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length) 757static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length)
776{ 758{
777 if (friend_not_valid(m, friendnumber)) 759 if (friend_not_valid(m, friendnumber))
@@ -874,6 +856,14 @@ static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber)
874 if (ret == -1) 856 if (ret == -1)
875 return; 857 return;
876 858
859 if (ret == CONNECTION_UNKNOWN) {
860 if (last_connection_udp_tcp == CONNECTION_UDP) {
861 return;
862 } else {
863 ret = CONNECTION_TCP;
864 }
865 }
866
877 if (last_connection_udp_tcp != ret) { 867 if (last_connection_udp_tcp != ret) {
878 if (m->friend_connectionstatuschange) 868 if (m->friend_connectionstatuschange)
879 m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata); 869 m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata);
@@ -1350,7 +1340,7 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
1350 if (m->friendlist[friendnumber].status != FRIEND_ONLINE) 1340 if (m->friendlist[friendnumber].status != FRIEND_ONLINE)
1351 return -2; 1341 return -2;
1352 1342
1353 if (filenumber > MAX_CONCURRENT_FILE_PIPES) 1343 if (filenumber >= MAX_CONCURRENT_FILE_PIPES)
1354 return -3; 1344 return -3;
1355 1345
1356 struct File_Transfers *ft = &m->friendlist[friendnumber].file_sending[filenumber]; 1346 struct File_Transfers *ft = &m->friendlist[friendnumber].file_sending[filenumber];
@@ -2178,22 +2168,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2178 break; 2168 break;
2179 } 2169 }
2180 2170
2181 case PACKET_ID_SHARE_RELAYS: {
2182 Node_format nodes[MAX_SHARED_RELAYS];
2183 int n;
2184
2185 if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data, data_length, 1)) == -1)
2186 break;
2187
2188 int i;
2189
2190 for (i = 0; i < n; i++) {
2191 add_tcp_relay(m->net_crypto, nodes[i].ip_port, nodes[i].public_key);
2192 }
2193
2194 break;
2195 }
2196
2197 default: { 2171 default: {
2198 handle_custom_lossless_packet(object, i, temp, len); 2172 handle_custom_lossless_packet(object, i, temp, len);
2199 break; 2173 break;
@@ -2251,10 +2225,6 @@ void do_friends(Messenger *m)
2251 m->friendlist[i].user_istyping_sent = 1; 2225 m->friendlist[i].user_istyping_sent = 1;
2252 } 2226 }
2253 2227
2254 if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) {
2255 send_relays(m, i);
2256 }
2257
2258 check_friend_tcp_udp(m, i); 2228 check_friend_tcp_udp(m, i);
2259 do_receipts(m, i); 2229 do_receipts(m, i);
2260 do_reqchunk_filecb(m, i); 2230 do_reqchunk_filecb(m, i);
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 63fb2820..5221e639 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -42,8 +42,7 @@ enum {
42 MESSAGE_ACTION 42 MESSAGE_ACTION
43}; 43};
44 44
45/* NOTE: Packet ids below 20 must never be used. */ 45/* NOTE: Packet ids below 24 must never be used. */
46#define PACKET_ID_SHARE_RELAYS 23
47#define PACKET_ID_ONLINE 24 46#define PACKET_ID_ONLINE 24
48#define PACKET_ID_OFFLINE 25 47#define PACKET_ID_OFFLINE 25
49#define PACKET_ID_NICKNAME 48 48#define PACKET_ID_NICKNAME 48
@@ -62,9 +61,6 @@ enum {
62#define PACKET_ID_MESSAGE_GROUPCHAT 99 61#define PACKET_ID_MESSAGE_GROUPCHAT 99
63#define PACKET_ID_LOSSY_GROUPCHAT 199 62#define PACKET_ID_LOSSY_GROUPCHAT 199
64 63
65/* Max number of tcp relays sent to friends */
66#define MAX_SHARED_RELAYS 16
67
68/* All packets starting with a byte in this range can be used for anything. */ 64/* All packets starting with a byte in this range can be used for anything. */
69#define PACKET_ID_LOSSLESS_RANGE_START 160 65#define PACKET_ID_LOSSLESS_RANGE_START 160
70#define PACKET_ID_LOSSLESS_RANGE_SIZE 32 66#define PACKET_ID_LOSSLESS_RANGE_SIZE 32
@@ -110,13 +106,11 @@ enum {
110/* Default start timeout in seconds between friend requests. */ 106/* Default start timeout in seconds between friend requests. */
111#define FRIENDREQUEST_TIMEOUT 5; 107#define FRIENDREQUEST_TIMEOUT 5;
112 108
113/* Interval between the sending of tcp relay information */
114#define FRIEND_SHARE_RELAYS_INTERVAL (5 * 60)
115
116enum { 109enum {
117 CONNECTION_NONE, 110 CONNECTION_NONE,
118 CONNECTION_TCP, 111 CONNECTION_TCP,
119 CONNECTION_UDP 112 CONNECTION_UDP,
113 CONNECTION_UNKNOWN
120}; 114};
121 115
122/* USERSTATUS - 116/* USERSTATUS -
@@ -199,7 +193,6 @@ typedef struct {
199 uint32_t message_id; // a semi-unique id used in read receipts. 193 uint32_t message_id; // a semi-unique id used in read receipts.
200 uint32_t friendrequest_nospam; // The nospam number used in the friend request. 194 uint32_t friendrequest_nospam; // The nospam number used in the friend request.
201 uint64_t last_seen_time; 195 uint64_t last_seen_time;
202 uint64_t share_relays_lastsent;
203 uint8_t last_connection_udp_tcp; 196 uint8_t last_connection_udp_tcp;
204 struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES]; 197 struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES];
205 unsigned int num_sending_files; 198 unsigned int num_sending_files;
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index d89b157c..1bd11a1d 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -87,7 +87,7 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con
87 const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, 87 const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two,
88 ip, port, three); 88 ip, port, three);
89 89
90 if (written < 0) { 90 if (written < 0 || MAX_PACKET_SIZE < written) {
91 return 0; 91 return 0;
92 } 92 }
93 93
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h
index d4d18a4b..722430e0 100644
--- a/toxcore/TCP_client.h
+++ b/toxcore/TCP_client.h
@@ -78,10 +78,6 @@ typedef struct {
78 uint64_t ping_response_id; 78 uint64_t ping_response_id;
79 uint64_t ping_request_id; 79 uint64_t ping_request_id;
80 80
81 //TODO: remove
82 void *net_crypto_pointer;
83 uint32_t net_crypto_location;
84
85 struct { 81 struct {
86 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ 82 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
87 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 83 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c
index e11e1318..fe39dc52 100644
--- a/toxcore/TCP_connection.c
+++ b/toxcore/TCP_connection.c
@@ -26,6 +26,7 @@
26#endif 26#endif
27 27
28#include "TCP_connection.h" 28#include "TCP_connection.h"
29#include "util.h"
29 30
30/* Set the size of the array to num. 31/* Set the size of the array to num.
31 * 32 *
@@ -212,6 +213,8 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
212 unsigned int i; 213 unsigned int i;
213 int ret = -1; 214 int ret = -1;
214 215
216 _Bool limit_reached = 0;
217
215 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 218 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
216 uint32_t tcp_con_num = con_to->connections[i].tcp_connection; 219 uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
217 uint8_t status = con_to->connections[i].status; 220 uint8_t status = con_to->connections[i].status;
@@ -227,6 +230,10 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
227 230
228 ret = send_data(tcp_con->connection, connection_id, packet, length); 231 ret = send_data(tcp_con->connection, connection_id, packet, length);
229 232
233 if (ret == 0) {
234 limit_reached = 1;
235 }
236
230 if (ret == 1) { 237 if (ret == 1) {
231 break; 238 break;
232 } 239 }
@@ -235,7 +242,10 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
235 242
236 if (ret == 1) { 243 if (ret == 1) {
237 return 0; 244 return 0;
238 } else { 245 } else if (!limit_reached) {
246 ret = 0;
247
248 /* Send oob packets to all relays tied to the connection. */
239 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 249 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
240 uint32_t tcp_con_num = con_to->connections[i].tcp_connection; 250 uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
241 uint8_t status = con_to->connections[i].status; 251 uint8_t status = con_to->connections[i].status;
@@ -249,19 +259,19 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
249 continue; 259 continue;
250 } 260 }
251 261
252 ret = send_oob_packet(tcp_con->connection, con_to->public_key, packet, length); 262 if (send_oob_packet(tcp_con->connection, con_to->public_key, packet, length) == 1) {
253 263 ret += 1;
254 if (ret == 1) {
255 break;
256 } 264 }
257 } 265 }
258 } 266 }
259 267
260 if (ret == 1) { 268 if (ret >= 1) {
261 return 0; 269 return 0;
262 } else { 270 } else {
263 return -1; 271 return -1;
264 } 272 }
273 } else {
274 return -1;
265 } 275 }
266} 276}
267 277
@@ -273,13 +283,15 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
273 * return TCP connection number on success. 283 * return TCP connection number on success.
274 * return -1 on failure. 284 * return -1 on failure.
275 */ 285 */
276int get_random_tcp_conn_number(TCP_Connections *tcp_c) 286int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c)
277{ 287{
278 unsigned int i, r = rand(); 288 unsigned int i, r = rand();
279 289
280 for (i = 0; i < tcp_c->tcp_connections_length; ++i) { 290 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
281 if (tcp_c->tcp_connections[(i + r) % tcp_c->tcp_connections_length].status == TCP_CONN_CONNECTED) { 291 unsigned int index = ((i + r) % tcp_c->tcp_connections_length);
282 return ((i + r) % tcp_c->tcp_connections_length); 292
293 if (tcp_c->tcp_connections[index].onion && tcp_c->tcp_connections[index].status == TCP_CONN_CONNECTED) {
294 return index;
283 } 295 }
284 } 296 }
285 297
@@ -321,6 +333,9 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num
321 if (!tcp_con) 333 if (!tcp_con)
322 return -1; 334 return -1;
323 335
336 if (tcp_con->status != TCP_CONN_CONNECTED)
337 return -1;
338
324 int ret = send_oob_packet(tcp_con->connection, public_key, packet, length); 339 int ret = send_oob_packet(tcp_con->connection, public_key, packet, length);
325 340
326 if (ret == 1) 341 if (ret == 1)
@@ -392,8 +407,14 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela
392 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 407 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
393 408
394 if (tcp_con) { 409 if (tcp_con) {
395 if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { 410 if (tcp_con->status == TCP_CONN_SLEEPING) {
396 return i; 411 if (memcmp(tcp_con->relay_pk, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
412 return i;
413 }
414 } else {
415 if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
416 return i;
417 }
397 } 418 }
398 } 419 }
399 } 420 }
@@ -451,14 +472,86 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
451 send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id); 472 send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id);
452 } 473 }
453 474
454 --tcp_con->lock_count; 475 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
476 --tcp_con->lock_count;
477
478 if (con_to->status == TCP_CONN_SLEEPING) {
479 --tcp_con->sleep_count;
480 }
481 }
455 } 482 }
456 } 483 }
457 484
458 return wipe_connection(tcp_c, connections_number); 485 return wipe_connection(tcp_c, connections_number);
459} 486}
460 487
461static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connections_number) 488/* Set connection status.
489 *
490 * status of 1 means we are using the connection.
491 * status of 0 means we are not using it.
492 *
493 * Unused tcp connections will be disconnected from but kept in case they are needed.
494 *
495 * return 0 on success.
496 * return -1 on failure.
497 */
498int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status)
499{
500 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
501
502 if (!con_to)
503 return -1;
504
505 if (status) {
506 /* Conection is unsleeping. */
507 if (con_to->status != TCP_CONN_SLEEPING)
508 return -1;
509
510 unsigned int i;
511
512 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
513 if (con_to->connections[i].tcp_connection) {
514 unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
515 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
516
517 if (!tcp_con)
518 continue;
519
520 if (tcp_con->status == TCP_CONN_SLEEPING) {
521 tcp_con->unsleep = 1;
522 }
523 }
524 }
525
526 con_to->status = TCP_CONN_VALID;
527 return 0;
528 } else {
529 /* Conection is going to sleep. */
530 if (con_to->status != TCP_CONN_VALID)
531 return -1;
532
533 unsigned int i;
534
535 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
536 if (con_to->connections[i].tcp_connection) {
537 unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
538 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
539
540 if (!tcp_con)
541 continue;
542
543 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
544 ++tcp_con->sleep_count;
545 }
546 }
547 }
548
549 con_to->status = TCP_CONN_SLEEPING;
550 return 0;
551 }
552}
553
554static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
462{ 555{
463 unsigned int i; 556 unsigned int i;
464 557
@@ -474,7 +567,7 @@ static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connectio
474/* return index on success. 567/* return index on success.
475 * return -1 on failure. 568 * return -1 on failure.
476 */ 569 */
477static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, int tcp_connections_number) 570static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
478{ 571{
479 unsigned int i; 572 unsigned int i;
480 573
@@ -496,7 +589,7 @@ static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, int tcp_connect
496/* return index on success. 589/* return index on success.
497 * return -1 on failure. 590 * return -1 on failure.
498 */ 591 */
499static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, int tcp_connections_number) 592static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
500{ 593{
501 unsigned int i; 594 unsigned int i;
502 595
@@ -512,16 +605,39 @@ static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, int tcp_connec
512 return -1; 605 return -1;
513} 606}
514 607
608/* return number of online connections on success.
609 * return -1 on failure.
610 */
611static unsigned int online_tcp_connection_from_conn(TCP_Connection_to *con_to)
612{
613 unsigned int i, count = 0;
614
615 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
616 if (con_to->connections[i].tcp_connection) {
617 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
618 ++count;
619 }
620 }
621 }
622
623 return count;
624}
625
515/* return index on success. 626/* return index on success.
516 * return -1 on failure. 627 * return -1 on failure.
517 */ 628 */
518static int set_tcp_connection_status(TCP_Connection_to *con_to, int tcp_connections_number, unsigned int status, 629static int set_tcp_connection_status(TCP_Connection_to *con_to, unsigned int tcp_connections_number,
519 uint8_t connection_id) 630 unsigned int status, uint8_t connection_id)
520{ 631{
521 unsigned int i; 632 unsigned int i;
522 633
523 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 634 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
524 if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) { 635 if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) {
636
637 if (con_to->connections[i].status == status) {
638 return -1;
639 }
640
525 con_to->connections[i].status = status; 641 con_to->connections[i].status = status;
526 con_to->connections[i].connection_id = connection_id; 642 con_to->connections[i].connection_id = connection_id;
527 return i; 643 return i;
@@ -553,11 +669,130 @@ static int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections
553 } 669 }
554 } 670 }
555 671
672 if (tcp_con->onion) {
673 --tcp_c->onion_num_conns;
674 }
675
556 kill_TCP_connection(tcp_con->connection); 676 kill_TCP_connection(tcp_con->connection);
557 677
558 return wipe_tcp_connection(tcp_c, tcp_connections_number); 678 return wipe_tcp_connection(tcp_c, tcp_connections_number);
559} 679}
560 680
681static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
682{
683 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
684
685 if (!tcp_con)
686 return -1;
687
688 if (tcp_con->status == TCP_CONN_SLEEPING)
689 return -1;
690
691 IP_Port ip_port = tcp_con->connection->ip_port;
692 uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
693 memcpy(relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES);
694 kill_TCP_connection(tcp_con->connection);
695 tcp_con->connection = new_TCP_connection(ip_port, relay_pk, tcp_c->dht->self_public_key, tcp_c->dht->self_secret_key,
696 &tcp_c->proxy_info);
697
698 if (!tcp_con->connection) {
699 kill_tcp_relay_connection(tcp_c, tcp_connections_number);
700 return -1;
701 }
702
703 unsigned int i;
704
705 for (i = 0; i < tcp_c->connections_length; ++i) {
706 TCP_Connection_to *con_to = get_connection(tcp_c, i);
707
708 if (con_to) {
709 set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
710 }
711 }
712
713 if (tcp_con->onion) {
714 --tcp_c->onion_num_conns;
715 tcp_con->onion = 0;
716 }
717
718 tcp_con->lock_count = 0;
719 tcp_con->sleep_count = 0;
720 tcp_con->connected_time = 0;
721 tcp_con->status = TCP_CONN_VALID;
722 tcp_con->unsleep = 0;
723
724 return 0;
725}
726
727static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
728{
729 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
730
731 if (!tcp_con)
732 return -1;
733
734 if (tcp_con->status != TCP_CONN_CONNECTED)
735 return -1;
736
737 if (tcp_con->lock_count != tcp_con->sleep_count)
738 return -1;
739
740 tcp_con->ip_port = tcp_con->connection->ip_port;
741 memcpy(tcp_con->relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES);
742
743 kill_TCP_connection(tcp_con->connection);
744 tcp_con->connection = NULL;
745
746 unsigned int i;
747
748 for (i = 0; i < tcp_c->connections_length; ++i) {
749 TCP_Connection_to *con_to = get_connection(tcp_c, i);
750
751 if (con_to) {
752 set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
753 }
754 }
755
756 if (tcp_con->onion) {
757 --tcp_c->onion_num_conns;
758 tcp_con->onion = 0;
759 }
760
761 tcp_con->lock_count = 0;
762 tcp_con->sleep_count = 0;
763 tcp_con->connected_time = 0;
764 tcp_con->status = TCP_CONN_SLEEPING;
765 tcp_con->unsleep = 0;
766
767 return 0;
768}
769
770static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
771{
772 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
773
774 if (!tcp_con)
775 return -1;
776
777 if (tcp_con->status != TCP_CONN_SLEEPING)
778 return -1;
779
780 tcp_con->connection = new_TCP_connection(tcp_con->ip_port, tcp_con->relay_pk, tcp_c->dht->self_public_key,
781 tcp_c->dht->self_secret_key, &tcp_c->proxy_info);
782
783 if (!tcp_con->connection) {
784 kill_tcp_relay_connection(tcp_c, tcp_connections_number);
785 return -1;
786 }
787
788 tcp_con->lock_count = 0;
789 tcp_con->sleep_count = 0;
790 tcp_con->connected_time = 0;
791 tcp_con->status = TCP_CONN_VALID;
792 tcp_con->unsleep = 0;
793 return 0;
794}
795
561/* Send a TCP routing request. 796/* Send a TCP routing request.
562 * 797 *
563 * return 0 on success. 798 * return 0 on success.
@@ -570,6 +805,9 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec
570 if (!tcp_con) 805 if (!tcp_con)
571 return -1; 806 return -1;
572 807
808 if (tcp_con->status == TCP_CONN_SLEEPING)
809 return -1;
810
573 if (send_routing_request(tcp_con->connection, public_key) != 1) 811 if (send_routing_request(tcp_con->connection, public_key) != 1)
574 return -1; 812 return -1;
575 813
@@ -592,8 +830,6 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
592 if (connections_number == -1) 830 if (connections_number == -1)
593 return -1; 831 return -1;
594 832
595 set_tcp_connection_number(tcp_con->connection, connection_id, connections_number);
596
597 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); 833 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
598 834
599 if (con_to == NULL) 835 if (con_to == NULL)
@@ -602,6 +838,8 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
602 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) 838 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1)
603 return -1; 839 return -1;
604 840
841 set_tcp_connection_number(tcp_con->connection, connection_id, connections_number);
842
605 return 0; 843 return 0;
606} 844}
607 845
@@ -621,10 +859,20 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection
621 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) 859 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1)
622 return -1; 860 return -1;
623 861
862 --tcp_con->lock_count;
863
864 if (con_to->status == TCP_CONN_SLEEPING) {
865 --tcp_con->sleep_count;
866 }
624 } else if (status == 2) { 867 } else if (status == 2) {
625 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1) 868 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1)
626 return -1; 869 return -1;
627 870
871 ++tcp_con->lock_count;
872
873 if (con_to->status == TCP_CONN_SLEEPING) {
874 ++tcp_con->sleep_count;
875 }
628 } 876 }
629 877
630 return 0; 878 return 0;
@@ -673,11 +921,13 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8
673 /* TODO: optimize */ 921 /* TODO: optimize */
674 int connections_number = find_tcp_connection_to(tcp_c, public_key); 922 int connections_number = find_tcp_connection_to(tcp_c, public_key);
675 923
676 if (connections_number == -1) { 924 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
925
926 if (con_to && tcp_connection_in_conn(con_to, tcp_connections_number)) {
927 return tcp_data_callback(object, connections_number, 0, data, length);
928 } else {
677 if (tcp_c->tcp_oob_callback) 929 if (tcp_c->tcp_oob_callback)
678 tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length); 930 tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length);
679 } else {
680 return tcp_data_callback(object, connections_number, 0, data, length);
681 } 931 }
682 932
683 return 0; 933 return 0;
@@ -725,20 +975,35 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe
725 if (!tcp_con) 975 if (!tcp_con)
726 return -1; 976 return -1;
727 977
728 unsigned int i; 978 unsigned int i, sent = 0;
729 979
730 for (i = 0; i < tcp_c->connections_length; ++i) { 980 for (i = 0; i < tcp_c->connections_length; ++i) {
731 TCP_Connection_to *con_to = get_connection(tcp_c, i); 981 TCP_Connection_to *con_to = get_connection(tcp_c, i);
732 982
733 if (con_to) { 983 if (con_to) {
734 if (tcp_connection_in_conn(con_to, tcp_connections_number)) { 984 if (tcp_connection_in_conn(con_to, tcp_connections_number)) {
735 send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); 985 if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) {
986 ++sent;
987 }
736 } 988 }
737 } 989 }
738 } 990 }
739 991
740 tcp_relay_set_callbacks(tcp_c, tcp_connections_number); 992 tcp_relay_set_callbacks(tcp_c, tcp_connections_number);
741 tcp_con->status = TCP_CONN_CONNECTED; 993 tcp_con->status = TCP_CONN_CONNECTED;
994
995 /* If this connection isn't used by any connection, we don't need to wait for them to come online. */
996 if (sent) {
997 tcp_con->connected_time = unix_time();
998 } else {
999 tcp_con->connected_time = 0;
1000 }
1001
1002 if (tcp_c->onion_status && tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) {
1003 tcp_con->onion = 1;
1004 ++tcp_c->onion_num_conns;
1005 }
1006
742 return 0; 1007 return 0;
743} 1008}
744 1009
@@ -807,13 +1072,17 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb
807 if (!tcp_con) 1072 if (!tcp_con)
808 return -1; 1073 return -1;
809 1074
1075 if (con_to->status != TCP_CONN_SLEEPING && tcp_con->status == TCP_CONN_SLEEPING) {
1076 tcp_con->unsleep = 1;
1077 }
1078
810 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) 1079 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1)
811 return -1; 1080 return -1;
812 1081
813 ++tcp_con->lock_count;
814
815 if (tcp_con->status == TCP_CONN_CONNECTED) { 1082 if (tcp_con->status == TCP_CONN_CONNECTED) {
816 send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); 1083 if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) {
1084 tcp_con->connected_time = unix_time();
1085 }
817 } 1086 }
818 1087
819 return 0; 1088 return 0;
@@ -836,22 +1105,38 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
836 if (tcp_connections_number != -1) { 1105 if (tcp_connections_number != -1) {
837 return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number); 1106 return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number);
838 } else { 1107 } else {
839 int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); 1108 if (online_tcp_connection_from_conn(con_to) >= RECOMMENDED_FRIEND_TCP_CONNECTIONS) {
840
841 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) {
842 return -1; 1109 return -1;
843 } 1110 }
844 1111
1112 int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk);
1113
845 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); 1114 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
846 1115
847 if (!tcp_con) 1116 if (!tcp_con)
848 return -1; 1117 return -1;
849 1118
850 ++tcp_con->lock_count; 1119 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) {
1120 return -1;
1121 }
1122
851 return 0; 1123 return 0;
852 } 1124 }
853} 1125}
854 1126
1127/* return number of online tcp relays tied to the connection on success.
1128 * return 0 on failure.
1129 */
1130unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number)
1131{
1132 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
1133
1134 if (!con_to)
1135 return 0;
1136
1137 return online_tcp_connection_from_conn(con_to);
1138}
1139
855/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays. 1140/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
856 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. 1141 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
857 * 1142 *
@@ -860,10 +1145,10 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
860 */ 1145 */
861unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num) 1146unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num)
862{ 1147{
863 unsigned int i, copied = 0; 1148 unsigned int i, copied = 0, r = rand();
864 1149
865 for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) { 1150 for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) {
866 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1151 TCP_con *tcp_con = get_tcp_connection(tcp_c, (i + r) % tcp_c->tcp_connections_length);
867 1152
868 if (!tcp_con) { 1153 if (!tcp_con) {
869 continue; 1154 continue;
@@ -886,7 +1171,74 @@ unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_
886 return copied; 1171 return copied;
887} 1172}
888 1173
889TCP_Connections *new_tcp_connections(DHT *dht) 1174/* Set if we want TCP_connection to allocate some connection for onion use.
1175 *
1176 * If status is 1, allocate some connections. if status is 0, don't.
1177 *
1178 * return 0 on success.
1179 * return -1 on failure.
1180 */
1181int set_tcp_onion_status(TCP_Connections *tcp_c, _Bool status)
1182{
1183 if (tcp_c->onion_status == status)
1184 return -1;
1185
1186 if (status) {
1187 unsigned int i;
1188
1189 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1190 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1191
1192 if (tcp_con) {
1193 if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion) {
1194 ++tcp_c->onion_num_conns;
1195 tcp_con->onion = 1;
1196 }
1197 }
1198
1199 if (tcp_c->onion_num_conns >= NUM_ONION_TCP_CONNECTIONS)
1200 break;
1201 }
1202
1203 if (tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) {
1204 unsigned int wakeup = NUM_ONION_TCP_CONNECTIONS - tcp_c->onion_num_conns;
1205
1206 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1207 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1208
1209 if (tcp_con) {
1210 if (tcp_con->status == TCP_CONN_SLEEPING) {
1211 tcp_con->unsleep = 1;
1212 }
1213 }
1214
1215 if (!wakeup)
1216 break;
1217 }
1218 }
1219
1220 tcp_c->onion_status = 1;
1221 } else {
1222 unsigned int i;
1223
1224 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1225 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1226
1227 if (tcp_con) {
1228 if (tcp_con->onion) {
1229 --tcp_c->onion_num_conns;
1230 tcp_con->onion = 0;
1231 }
1232 }
1233 }
1234
1235 tcp_c->onion_status = 0;
1236 }
1237
1238 return 0;
1239}
1240
1241TCP_Connections *new_tcp_connections(DHT *dht, TCP_Proxy_Info *proxy_info)
890{ 1242{
891 if (dht == NULL) 1243 if (dht == NULL)
892 return NULL; 1244 return NULL;
@@ -897,6 +1249,8 @@ TCP_Connections *new_tcp_connections(DHT *dht)
897 return NULL; 1249 return NULL;
898 1250
899 temp->dht = dht; 1251 temp->dht = dht;
1252 temp->proxy_info = *proxy_info;
1253
900 return temp; 1254 return temp;
901} 1255}
902 1256
@@ -908,18 +1262,35 @@ static void do_tcp_conns(TCP_Connections *tcp_c)
908 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1262 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
909 1263
910 if (tcp_con) { 1264 if (tcp_con) {
911 do_TCP_connection(tcp_con->connection); 1265 if (tcp_con->status != TCP_CONN_SLEEPING) {
1266 do_TCP_connection(tcp_con->connection);
912 1267
913 /* callbacks can change TCP connection address. */ 1268 /* callbacks can change TCP connection address. */
914 tcp_con = get_tcp_connection(tcp_c, i); 1269 tcp_con = get_tcp_connection(tcp_c, i);
915 1270
916 if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { 1271 if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) {
917 kill_tcp_relay_connection(tcp_c, i); 1272 if (tcp_con->status == TCP_CONN_CONNECTED) {
918 continue; 1273 reconnect_tcp_relay_connection(tcp_c, i);
1274 } else {
1275 kill_tcp_relay_connection(tcp_c, i);
1276 }
1277
1278 continue;
1279 }
1280
1281 if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) {
1282 tcp_relay_on_online(tcp_c, i);
1283 }
1284
1285 if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion && tcp_con->lock_count
1286 && tcp_con->lock_count == tcp_con->sleep_count
1287 && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
1288 sleep_tcp_relay_connection(tcp_c, i);
1289 }
919 } 1290 }
920 1291
921 if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) { 1292 if (tcp_con->status == TCP_CONN_SLEEPING && tcp_con->unsleep) {
922 tcp_relay_on_online(tcp_c, i); 1293 unsleep_tcp_relay_connection(tcp_c, i);
923 } 1294 }
924 } 1295 }
925 } 1296 }
@@ -927,27 +1298,42 @@ static void do_tcp_conns(TCP_Connections *tcp_c)
927 1298
928static void kill_nonused_tcp(TCP_Connections *tcp_c) 1299static void kill_nonused_tcp(TCP_Connections *tcp_c)
929{ 1300{
930 unsigned int i, num_online = 0; 1301 if (tcp_c->tcp_connections_length == 0)
1302 return;
1303
1304 unsigned int i, num_online = 0, num_kill = 0, to_kill[tcp_c->tcp_connections_length];
931 1305
932 for (i = 0; i < tcp_c->tcp_connections_length; ++i) { 1306 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
933 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1307 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
934 1308
935 if (tcp_con) { 1309 if (tcp_con) {
936 if (tcp_con->status == TCP_CONN_CONNECTED) { 1310 if (tcp_con->status == TCP_CONN_CONNECTED) {
937 if (!tcp_con->lock_count && num_online >= MAX_FRIEND_TCP_CONNECTIONS) { 1311 if (!tcp_con->onion && !tcp_con->lock_count && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
938 kill_tcp_relay_connection(tcp_c, i); 1312 to_kill[num_kill] = i;
939 continue; 1313 ++num_kill;
940 } 1314 }
941 1315
942 ++num_online; 1316 ++num_online;
943 } 1317 }
944 } 1318 }
945 } 1319 }
1320
1321 if (num_online <= RECOMMENDED_FRIEND_TCP_CONNECTIONS) {
1322 return;
1323 } else {
1324 unsigned int n = num_online - RECOMMENDED_FRIEND_TCP_CONNECTIONS;
1325
1326 if (n < num_kill)
1327 num_kill = n;
1328 }
1329
1330 for (i = 0; i < num_kill; ++i) {
1331 kill_tcp_relay_connection(tcp_c, to_kill[i]);
1332 }
946} 1333}
947 1334
948void do_tcp_connections(TCP_Connections *tcp_c) 1335void do_tcp_connections(TCP_Connections *tcp_c)
949{ 1336{
950 //TODO reconnect to TCP relays if disconnects happen.
951 do_tcp_conns(tcp_c); 1337 do_tcp_conns(tcp_c);
952 kill_nonused_tcp(tcp_c); 1338 kill_nonused_tcp(tcp_c);
953} 1339}
diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h
index 2c86304f..29fbdee0 100644
--- a/toxcore/TCP_connection.h
+++ b/toxcore/TCP_connection.h
@@ -28,14 +28,28 @@
28 28
29#define TCP_CONN_NONE 0 29#define TCP_CONN_NONE 0
30#define TCP_CONN_VALID 1 30#define TCP_CONN_VALID 1
31
32/* NOTE: only used by TCP_con */
31#define TCP_CONN_CONNECTED 2 33#define TCP_CONN_CONNECTED 2
32 34
35/* Connection is not connected but can be quickly reconnected in case it is needed. */
36#define TCP_CONN_SLEEPING 3
37
33#define TCP_CONNECTIONS_STATUS_NONE 0 38#define TCP_CONNECTIONS_STATUS_NONE 0
34#define TCP_CONNECTIONS_STATUS_REGISTERED 1 39#define TCP_CONNECTIONS_STATUS_REGISTERED 1
35#define TCP_CONNECTIONS_STATUS_ONLINE 2 40#define TCP_CONNECTIONS_STATUS_ONLINE 2
36 41
37#define MAX_FRIEND_TCP_CONNECTIONS 4 42#define MAX_FRIEND_TCP_CONNECTIONS 6
43
44/* Time until connection to friend gets killed (if it doesn't get locked withing that time) */
45#define TCP_CONNECTION_ANNOUNCE_TIMEOUT (TCP_CONNECTION_TIMEOUT)
38 46
47/* The amount of recommended connections for each friend
48 NOTE: Must be at most (MAX_FRIEND_TCP_CONNECTIONS / 2) */
49#define RECOMMENDED_FRIEND_TCP_CONNECTIONS (MAX_FRIEND_TCP_CONNECTIONS / 2)
50
51/* Number of TCP connections used for onion purposes. */
52#define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS
39 53
40typedef struct { 54typedef struct {
41 uint8_t status; 55 uint8_t status;
@@ -53,7 +67,15 @@ typedef struct {
53typedef struct { 67typedef struct {
54 uint8_t status; 68 uint8_t status;
55 TCP_Client_Connection *connection; 69 TCP_Client_Connection *connection;
70 uint64_t connected_time;
56 uint32_t lock_count; 71 uint32_t lock_count;
72 uint32_t sleep_count;
73 _Bool onion;
74
75 /* Only used when connection is sleeping. */
76 IP_Port ip_port;
77 uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
78 _Bool unsleep; /* set to 1 to unsleep connection. */
57} TCP_con; 79} TCP_con;
58 80
59typedef struct { 81typedef struct {
@@ -76,6 +98,9 @@ typedef struct {
76 void *tcp_onion_callback_object; 98 void *tcp_onion_callback_object;
77 99
78 TCP_Proxy_Info proxy_info; 100 TCP_Proxy_Info proxy_info;
101
102 _Bool onion_status;
103 uint16_t onion_num_conns;
79} TCP_Connections; 104} TCP_Connections;
80 105
81/* Send a packet to the TCP connection. 106/* Send a packet to the TCP connection.
@@ -93,7 +118,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
93 * return TCP connection number on success. 118 * return TCP connection number on success.
94 * return -1 on failure. 119 * return -1 on failure.
95 */ 120 */
96int get_random_tcp_conn_number(TCP_Connections *tcp_c); 121int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c);
97 122
98/* Send an onion packet via the TCP relay corresponding to tcp_connections_number. 123/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
99 * 124 *
@@ -103,6 +128,15 @@ int get_random_tcp_conn_number(TCP_Connections *tcp_c);
103int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data, 128int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data,
104 uint16_t length); 129 uint16_t length);
105 130
131/* Set if we want TCP_connection to allocate some connection for onion use.
132 *
133 * If status is 1, allocate some connections. if status is 0, don't.
134 *
135 * return 0 on success.
136 * return -1 on failure.
137 */
138int set_tcp_onion_status(TCP_Connections *tcp_c, _Bool status);
139
106/* Send an oob packet via the TCP relay corresponding to tcp_connections_number. 140/* Send an oob packet via the TCP relay corresponding to tcp_connections_number.
107 * 141 *
108 * return 0 on success. 142 * return 0 on success.
@@ -140,6 +174,23 @@ int new_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key, int
140 */ 174 */
141int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number); 175int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number);
142 176
177/* Set connection status.
178 *
179 * status of 1 means we are using the connection.
180 * status of 0 means we are not using it.
181 *
182 * Unused tcp connections will be disconnected from but kept in case they are needed.
183 *
184 * return 0 on success.
185 * return -1 on failure.
186 */
187int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status);
188
189/* return number of online tcp relays tied to the connection on success.
190 * return 0 on failure.
191 */
192unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number);
193
143/* Add a TCP relay tied to a connection. 194/* Add a TCP relay tied to a connection.
144 * 195 *
145 * NOTE: This can only be used during the tcp_oob_callback. 196 * NOTE: This can only be used during the tcp_oob_callback.
@@ -172,7 +223,7 @@ int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t
172 */ 223 */
173unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num); 224unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num);
174 225
175TCP_Connections *new_tcp_connections(DHT *dht); 226TCP_Connections *new_tcp_connections(DHT *dht, TCP_Proxy_Info *proxy_info);
176void do_tcp_connections(TCP_Connections *tcp_c); 227void do_tcp_connections(TCP_Connections *tcp_c);
177void kill_tcp_connections(TCP_Connections *tcp_c); 228void kill_tcp_connections(TCP_Connections *tcp_c);
178 229
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
index a364084a..418edcad 100644
--- a/toxcore/crypto_core.c
+++ b/toxcore/crypto_core.c
@@ -29,26 +29,16 @@
29 29
30#include "crypto_core.h" 30#include "crypto_core.h"
31 31
32#if crypto_box_PUBLICKEYBYTES != 32
33#error crypto_box_PUBLICKEYBYTES is required to be 32 bytes for public_key_cmp to work,
34#endif
32 35
33/* Use this instead of memcmp; not vulnerable to timing attacks. 36/* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks.
34 returns 0 if both mem locations of length are equal, 37 returns 0 if both mem locations of length are equal,
35 return -1 if they are not. */ 38 return -1 if they are not. */
36int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length) 39int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
37{ 40{
38 if (length == 16) { 41 return crypto_verify_32(pk1, pk2);
39 return crypto_verify_16(mem1, mem2);
40 } else if (length == 32) {
41 return crypto_verify_32(mem1, mem2);
42 }
43
44 unsigned int check = 0;
45 size_t i;
46
47 for (i = 0; i < length; ++i) {
48 check |= mem1[i] ^ mem2[i];
49 }
50
51 return (1 & ((check - 1) >> 8)) - 1;
52} 42}
53 43
54/* return a random number. 44/* return a random number.
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h
index decc7fb9..d7306a8a 100644
--- a/toxcore/crypto_core.h
+++ b/toxcore/crypto_core.h
@@ -40,10 +40,10 @@
40 40
41#define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES) 41#define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES)
42 42
43/* Use this instead of memcmp; not vulnerable to timing attacks. 43/* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks.
44 returns 0 if both mem locations of length are equal, 44 returns 0 if both mem locations of length are equal,
45 return -1 if they are not. */ 45 return -1 if they are not. */
46int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length); 46int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2);
47 47
48/* return a random number. 48/* return a random number.
49 * 49 *
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c
index 074021da..892048ad 100644
--- a/toxcore/friend_connection.c
+++ b/toxcore/friend_connection.c
@@ -146,6 +146,95 @@ int getfriend_conn_id_pk(Friend_Connections *fr_c, const uint8_t *real_pk)
146 return -1; 146 return -1;
147} 147}
148 148
149/* Add a TCP relay associated to the friend.
150 *
151 * return -1 on failure.
152 * return 0 on success.
153 */
154int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key)
155{
156 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
157
158 if (!friend_con)
159 return -1;
160
161 unsigned int i;
162
163 uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS;
164
165 for (i = 0; i < FRIEND_MAX_STORED_TCP_RELAYS; ++i) {
166 if (friend_con->tcp_relays[i].ip_port.ip.family != 0
167 && memcmp(friend_con->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
168 memset(&friend_con->tcp_relays[i], 0, sizeof(Node_format));
169 }
170 }
171
172 friend_con->tcp_relays[index].ip_port = ip_port;
173 memcpy(friend_con->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES);
174 ++friend_con->tcp_relay_counter;
175
176 return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key);
177}
178
179/* Connect to number saved relays for friend. */
180static void connect_to_saved_tcp_relays(Friend_Connections *fr_c, int friendcon_id, unsigned int number)
181{
182 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
183
184 if (!friend_con)
185 return;
186
187 unsigned int i;
188
189 for (i = 0; (i < FRIEND_MAX_STORED_TCP_RELAYS) && (number != 0); ++i) {
190 uint16_t index = (friend_con->tcp_relay_counter - (i + 1)) % FRIEND_MAX_STORED_TCP_RELAYS;
191
192 if (friend_con->tcp_relays[index].ip_port.ip.family) {
193 if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->tcp_relays[index].ip_port,
194 friend_con->tcp_relays[index].public_key) == 0) {
195 --number;
196 }
197 }
198 }
199}
200
201static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id)
202{
203 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
204
205 if (!friend_con)
206 return 0;
207
208 Node_format nodes[MAX_SHARED_RELAYS];
209 uint8_t data[1024];
210 int n, length;
211
212 n = copy_connected_tcp_relays(fr_c->net_crypto, nodes, MAX_SHARED_RELAYS);
213
214 unsigned int i;
215
216 for (i = 0; i < n; ++i) {
217 /* Associated the relays being sent with this connection.
218 On receiving the peer will do the same which will establish the connection. */
219 friend_add_tcp_relay(fr_c, friendcon_id, nodes[i].ip_port, nodes[i].public_key);
220 }
221
222 length = pack_nodes(data + 1, sizeof(data) - 1, nodes, n);
223
224 if (length <= 0)
225 return 0;
226
227 data[0] = PACKET_ID_SHARE_RELAYS;
228 ++length;
229
230 if (write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, data, length, 0) != -1) {
231 friend_con->share_relays_lastsent = unix_time();
232 return 1;
233 }
234
235 return 0;
236}
237
149/* callback for recv TCP relay nodes. */ 238/* callback for recv TCP relay nodes. */
150static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key) 239static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key)
151{ 240{
@@ -156,7 +245,7 @@ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_por
156 return -1; 245 return -1;
157 246
158 if (friend_con->crypt_connection_id != -1) { 247 if (friend_con->crypt_connection_id != -1) {
159 return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key); 248 return friend_add_tcp_relay(fr_c, number, ip_port, public_key);
160 } else { 249 } else {
161 return add_tcp_relay(fr_c->net_crypto, ip_port, public_key); 250 return add_tcp_relay(fr_c->net_crypto, ip_port, public_key);
162 } 251 }
@@ -181,19 +270,14 @@ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port)
181 friend_con->dht_ip_port_lastrecv = unix_time(); 270 friend_con->dht_ip_port_lastrecv = unix_time();
182} 271}
183 272
184/* Callback for dht public key changes. */ 273static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key)
185static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key)
186{ 274{
187 Friend_Connections *fr_c = object; 275 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
188 Friend_Conn *friend_con = get_conn(fr_c, number);
189 276
190 if (!friend_con) 277 if (!friend_con)
191 return; 278 return;
192 279
193 friend_con->dht_ping_lastrecv = unix_time(); 280 friend_con->dht_pk_lastrecv = unix_time();
194
195 if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
196 return;
197 281
198 if (friend_con->dht_lock) { 282 if (friend_con->dht_lock) {
199 if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) { 283 if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) {
@@ -204,16 +288,32 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub
204 friend_con->dht_lock = 0; 288 friend_con->dht_lock = 0;
205 } 289 }
206 290
207 DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, object, number, &friend_con->dht_lock); 291 DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, fr_c, friendcon_id, &friend_con->dht_lock);
292 memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES);
293}
208 294
209 if (friend_con->crypt_connection_id == -1) { 295/* Callback for dht public key changes. */
210 friend_new_connection(fr_c, number); 296static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key)
297{
298 Friend_Connections *fr_c = object;
299 Friend_Conn *friend_con = get_conn(fr_c, number);
300
301 if (!friend_con)
302 return;
303
304 if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
305 return;
306
307 change_dht_pk(fr_c, number, dht_public_key);
308
309 /* if pk changed, create a new connection.*/
310 if (friend_con->crypt_connection_id != -1) {
311 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id);
312 friend_con->crypt_connection_id = -1;
211 } 313 }
212 314
213 set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, dht_public_key); 315 friend_new_connection(fr_c, number);
214 onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key); 316 onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);
215
216 memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES);
217} 317}
218 318
219static int handle_status(void *object, int number, uint8_t status) 319static int handle_status(void *object, int number, uint8_t status)
@@ -230,11 +330,12 @@ static int handle_status(void *object, int number, uint8_t status)
230 call_cb = 1; 330 call_cb = 1;
231 friend_con->status = FRIENDCONN_STATUS_CONNECTED; 331 friend_con->status = FRIENDCONN_STATUS_CONNECTED;
232 friend_con->ping_lastrecv = unix_time(); 332 friend_con->ping_lastrecv = unix_time();
333 friend_con->share_relays_lastsent = 0;
233 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); 334 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status);
234 } else { /* Went offline. */ 335 } else { /* Went offline. */
235 if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) { 336 if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) {
236 call_cb = 1; 337 call_cb = 1;
237 friend_con->dht_ping_lastrecv = unix_time(); 338 friend_con->dht_pk_lastrecv = unix_time();
238 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); 339 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status);
239 } 340 }
240 341
@@ -263,18 +364,30 @@ static int handle_packet(void *object, int number, uint8_t *data, uint16_t lengt
263 Friend_Connections *fr_c = object; 364 Friend_Connections *fr_c = object;
264 Friend_Conn *friend_con = get_conn(fr_c, number); 365 Friend_Conn *friend_con = get_conn(fr_c, number);
265 366
367 if (!friend_con)
368 return -1;
369
266 if (data[0] == PACKET_ID_FRIEND_REQUESTS) { 370 if (data[0] == PACKET_ID_FRIEND_REQUESTS) {
267 if (fr_c->fr_request_callback) 371 if (fr_c->fr_request_callback)
268 fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length); 372 fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length);
269 373
270 return 0; 374 return 0;
271 } 375 } else if (data[0] == PACKET_ID_ALIVE) {
376 friend_con->ping_lastrecv = unix_time();
377 return 0;
378 } else if (data[0] == PACKET_ID_SHARE_RELAYS) {
379 Node_format nodes[MAX_SHARED_RELAYS];
380 int n;
272 381
273 if (!friend_con) 382 if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data + 1, length - 1, 1)) == -1)
274 return -1; 383 return -1;
384
385 int j;
386
387 for (j = 0; j < n; j++) {
388 friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key);
389 }
275 390
276 if (data[0] == PACKET_ID_ALIVE) {
277 friend_con->ping_lastrecv = unix_time();
278 return 0; 391 return 0;
279 } 392 }
280 393
@@ -333,6 +446,11 @@ static int handle_new_connections(void *object, New_Connection *n_c)
333 return -1; 446 return -1;
334 447
335 int id = accept_crypto_connection(fr_c->net_crypto, n_c); 448 int id = accept_crypto_connection(fr_c->net_crypto, n_c);
449
450 if (id == -1) {
451 return -1;
452 }
453
336 connection_status_handler(fr_c->net_crypto, id, &handle_status, fr_c, friendcon_id); 454 connection_status_handler(fr_c->net_crypto, id, &handle_status, fr_c, friendcon_id);
337 connection_data_handler(fr_c->net_crypto, id, &handle_packet, fr_c, friendcon_id); 455 connection_data_handler(fr_c->net_crypto, id, &handle_packet, fr_c, friendcon_id);
338 connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id); 456 connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id);
@@ -345,7 +463,9 @@ static int handle_new_connections(void *object, New_Connection *n_c)
345 friend_con->dht_ip_port_lastrecv = unix_time(); 463 friend_con->dht_ip_port_lastrecv = unix_time();
346 } 464 }
347 465
348 dht_pk_callback(fr_c, friendcon_id, n_c->dht_public_key); 466 if (memcmp(friend_con->dht_temp_pk, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES) != 0) {
467 change_dht_pk(fr_c, friendcon_id, n_c->dht_public_key);
468 }
349 469
350 nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id); 470 nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id);
351 return 0; 471 return 0;
@@ -365,7 +485,12 @@ static int friend_new_connection(Friend_Connections *fr_c, int friendcon_id)
365 return -1; 485 return -1;
366 } 486 }
367 487
368 int id = new_crypto_connection(fr_c->net_crypto, friend_con->real_public_key); 488 /* If dht_temp_pk does not contains a pk. */
489 if (!friend_con->dht_lock) {
490 return -1;
491 }
492
493 int id = new_crypto_connection(fr_c->net_crypto, friend_con->real_public_key, friend_con->dht_temp_pk);
369 494
370 if (id == -1) 495 if (id == -1)
371 return -1; 496 return -1;
@@ -647,7 +772,7 @@ void do_friend_connections(Friend_Connections *fr_c)
647 772
648 if (friend_con) { 773 if (friend_con) {
649 if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) { 774 if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) {
650 if (friend_con->dht_ping_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) { 775 if (friend_con->dht_pk_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) {
651 if (friend_con->dht_lock) { 776 if (friend_con->dht_lock) {
652 DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); 777 DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock);
653 friend_con->dht_lock = 0; 778 friend_con->dht_lock = 0;
@@ -660,8 +785,8 @@ void do_friend_connections(Friend_Connections *fr_c)
660 785
661 if (friend_con->dht_lock) { 786 if (friend_con->dht_lock) {
662 if (friend_new_connection(fr_c, i) == 0) { 787 if (friend_new_connection(fr_c, i) == 0) {
663 set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_temp_pk);
664 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port); 788 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port);
789 connect_to_saved_tcp_relays(fr_c, i, (MAX_FRIEND_TCP_CONNECTIONS / 2)); /* Only fill it half up. */
665 } 790 }
666 } 791 }
667 792
@@ -670,6 +795,10 @@ void do_friend_connections(Friend_Connections *fr_c)
670 send_ping(fr_c, i); 795 send_ping(fr_c, i);
671 } 796 }
672 797
798 if (friend_con->share_relays_lastsent + SHARE_RELAYS_INTERVAL < temp_time) {
799 send_relays(fr_c, i);
800 }
801
673 if (friend_con->ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { 802 if (friend_con->ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) {
674 /* If we stopped receiving ping packets, kill it. */ 803 /* If we stopped receiving ping packets, kill it. */
675 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id); 804 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id);
diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h
index b814eb0c..60b62646 100644
--- a/toxcore/friend_connection.h
+++ b/toxcore/friend_connection.h
@@ -36,6 +36,7 @@
36#define GROUPCHAT_CALLBACK_INDEX 1 36#define GROUPCHAT_CALLBACK_INDEX 1
37 37
38#define PACKET_ID_ALIVE 16 38#define PACKET_ID_ALIVE 16
39#define PACKET_ID_SHARE_RELAYS 17
39#define PACKET_ID_FRIEND_REQUESTS 18 40#define PACKET_ID_FRIEND_REQUESTS 18
40 41
41/* Interval between the sending of ping packets. */ 42/* Interval between the sending of ping packets. */
@@ -47,6 +48,14 @@
47/* Time before friend is removed from the DHT after last hearing about him. */ 48/* Time before friend is removed from the DHT after last hearing about him. */
48#define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT 49#define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT
49 50
51#define FRIEND_MAX_STORED_TCP_RELAYS (MAX_FRIEND_TCP_CONNECTIONS * 4)
52
53/* Max number of tcp relays sent to friends */
54#define MAX_SHARED_RELAYS (RECOMMENDED_FRIEND_TCP_CONNECTIONS)
55
56/* Interval between the sending of tcp relay information */
57#define SHARE_RELAYS_INTERVAL (5 * 60)
58
50 59
51enum { 60enum {
52 FRIENDCONN_STATUS_NONE, 61 FRIENDCONN_STATUS_NONE,
@@ -61,12 +70,13 @@ typedef struct {
61 uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES]; 70 uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES];
62 uint16_t dht_lock; 71 uint16_t dht_lock;
63 IP_Port dht_ip_port; 72 IP_Port dht_ip_port;
64 uint64_t dht_ping_lastrecv, dht_ip_port_lastrecv; 73 uint64_t dht_pk_lastrecv, dht_ip_port_lastrecv;
65 74
66 int onion_friendnum; 75 int onion_friendnum;
67 int crypt_connection_id; 76 int crypt_connection_id;
68 77
69 uint64_t ping_lastrecv, ping_lastsent; 78 uint64_t ping_lastrecv, ping_lastsent;
79 uint64_t share_relays_lastsent;
70 80
71 struct { 81 struct {
72 int (*status_callback)(void *object, int id, uint8_t status); 82 int (*status_callback)(void *object, int id, uint8_t status);
@@ -83,6 +93,9 @@ typedef struct {
83 } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS]; 93 } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS];
84 94
85 uint16_t lock_count; 95 uint16_t lock_count;
96
97 Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS];
98 uint16_t tcp_relay_counter;
86} Friend_Conn; 99} Friend_Conn;
87 100
88 101
@@ -127,6 +140,13 @@ int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, Friend_Con
127 */ 140 */
128void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk); 141void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk);
129 142
143/* Add a TCP relay associated to the friend.
144 *
145 * return -1 on failure.
146 * return 0 on success.
147 */
148int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key);
149
130/* Set the callbacks for the friend connection. 150/* Set the callbacks for the friend connection.
131 * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array. 151 * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array.
132 * 152 *
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 3e596a5f..ab0fb03a 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -35,7 +35,16 @@
35 35
36static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id) 36static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id)
37{ 37{
38 return (uint32_t)crypt_connection_id >= c->crypto_connections_length; 38 if ((uint32_t)crypt_connection_id >= c->crypto_connections_length)
39 return 1;
40
41 if (c->crypto_connections == NULL)
42 return 1;
43
44 if (c->crypto_connections[crypt_connection_id].status == CRYPTO_CONN_NO_CONNECTION)
45 return 1;
46
47 return 0;
39} 48}
40 49
41/* cookie timeout in seconds */ 50/* cookie timeout in seconds */
@@ -206,8 +215,7 @@ static int udp_handle_cookie_request(void *object, IP_Port source, const uint8_t
206 215
207/* Handle the cookie request packet (for TCP) 216/* Handle the cookie request packet (for TCP)
208 */ 217 */
209static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, 218static int tcp_handle_cookie_request(Net_Crypto *c, int connections_number, const uint8_t *packet, uint16_t length)
210 const uint8_t *packet, uint16_t length)
211{ 219{
212 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 220 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
213 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 221 uint8_t shared_key[crypto_box_BEFORENMBYTES];
@@ -221,15 +229,13 @@ static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection
221 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) 229 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
222 return -1; 230 return -1;
223 231
224 if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1) 232 int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data));
225 return -1; 233 return ret;
226
227 return 0;
228} 234}
229 235
230/* Handle the cookie request packet (for TCP oob packets) 236/* Handle the cookie request packet (for TCP oob packets)
231 */ 237 */
232static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, 238static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number,
233 const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) 239 const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length)
234{ 240{
235 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 241 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
@@ -247,10 +253,8 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connect
247 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) 253 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
248 return -1; 254 return -1;
249 255
250 if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1) 256 int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, data, sizeof(data));
251 return -1; 257 return ret;
252
253 return 0;
254} 258}
255 259
256/* Handle a cookie response packet of length encrypted with shared_key. 260/* Handle a cookie response packet of length encrypted with shared_key.
@@ -346,7 +350,7 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
346 return -1; 350 return -1;
347 351
348 if (expected_real_pk) 352 if (expected_real_pk)
349 if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0) 353 if (public_key_cmp(cookie_plain, expected_real_pk) != 0)
350 return -1; 354 return -1;
351 355
352 uint8_t cookie_hash[crypto_hash_sha512_BYTES]; 356 uint8_t cookie_hash[crypto_hash_sha512_BYTES];
@@ -400,12 +404,17 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
400 404
401 //TODO: on bad networks, direct connections might not last indefinitely. 405 //TODO: on bad networks, direct connections might not last indefinitely.
402 if (conn->ip_port.ip.family != 0) { 406 if (conn->ip_port.ip.family != 0) {
403 uint8_t direct_connected = 0; 407 _Bool direct_connected = 0;
404 crypto_connection_status(c, crypt_connection_id, &direct_connected); 408 crypto_connection_status(c, crypt_connection_id, &direct_connected, NULL);
405 409
406 if (direct_connected && (uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) { 410 if (direct_connected) {
407 pthread_mutex_unlock(&conn->mutex); 411 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) {
408 return 0; 412 pthread_mutex_unlock(&conn->mutex);
413 return 0;
414 } else {
415 pthread_mutex_unlock(&conn->mutex);
416 return -1;
417 }
409 } 418 }
410 419
411 //TODO: a better way of sending packets directly to confirm the others ip. 420 //TODO: a better way of sending packets directly to confirm the others ip.
@@ -413,61 +422,14 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
413 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) 422 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length)
414 direct_send_attempt = 1; 423 direct_send_attempt = 1;
415 } 424 }
416
417 } 425 }
418 426
419 pthread_mutex_unlock(&conn->mutex); 427 pthread_mutex_unlock(&conn->mutex);
428 pthread_mutex_lock(&c->tcp_mutex);
429 int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
430 pthread_mutex_unlock(&c->tcp_mutex);
420 431
421 //TODO: detect and kill bad relays. 432 if (ret == 0 || direct_send_attempt) {
422 uint32_t i;
423
424 unsigned int r;
425
426 if (!conn->last_relay_sentto) {
427 r = rand();
428 } else {
429 r = conn->last_relay_sentto - 1;
430 }
431
432 if (conn->num_tcp_online) {
433 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
434 pthread_mutex_lock(&c->tcp_mutex);
435
436 unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS;
437 int ret = 0;
438
439 if (conn->status_tcp[tcp_index] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
440 ret = send_data(c->tcp_connections[tcp_index], conn->con_number_tcp[tcp_index], data, length);
441 }
442
443 pthread_mutex_unlock(&c->tcp_mutex);
444
445 if (ret == 1) {
446 conn->last_relay_sentto = tcp_index + 1;
447 return 0;
448 }
449 }
450 }
451
452 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
453 pthread_mutex_lock(&c->tcp_mutex);
454
455 unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS;
456 int ret = 0;
457
458 if (conn->status_tcp[tcp_index] == STATUS_TCP_INVISIBLE) {
459 ret = send_oob_packet(c->tcp_connections[tcp_index], conn->dht_public_key, data, length);
460 }
461
462 pthread_mutex_unlock(&c->tcp_mutex);
463
464 if (ret == 1) {
465 conn->last_relay_sentto = tcp_index + 1;
466 return 0;
467 }
468 }
469
470 if (direct_send_attempt) {
471 return 0; 433 return 0;
472 } 434 }
473 435
@@ -1136,13 +1098,26 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
1136 &kill_packet, sizeof(kill_packet)); 1098 &kill_packet, sizeof(kill_packet));
1137} 1099}
1138 1100
1101static void connection_kill(Net_Crypto *c, int crypt_connection_id)
1102{
1103 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1104
1105 if (conn == 0)
1106 return;
1107
1108 if (conn->connection_status_callback) {
1109 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
1110 }
1111
1112 crypto_kill(c, crypt_connection_id);
1113}
1114
1139/* Handle a received data packet. 1115/* Handle a received data packet.
1140 * 1116 *
1141 * return -1 on failure. 1117 * return -1 on failure.
1142 * return 0 on success. 1118 * return 0 on success.
1143 */ 1119 */
1144static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, 1120static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
1145 uint16_t length)
1146{ 1121{
1147 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) 1122 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE)
1148 return -1; 1123 return -1;
@@ -1179,7 +1154,7 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i
1179 } 1154 }
1180 1155
1181 if (real_data[0] == PACKET_ID_KILL) { 1156 if (real_data[0] == PACKET_ID_KILL) {
1182 conn->killed = 1; 1157 connection_kill(c, crypt_connection_id);
1183 return 0; 1158 return 0;
1184 } 1159 }
1185 1160
@@ -1294,19 +1269,19 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons
1294 packet, length, conn->public_key) != 0) 1269 packet, length, conn->public_key) != 0)
1295 return -1; 1270 return -1;
1296 1271
1297 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1272 if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) {
1298 1273 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1299 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1300 if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0)
1301 return -1;
1302 }
1303 1274
1304 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1275 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1305 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1276 if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0)
1306 set_connection_dht_public_key(c, crypt_connection_id, dht_public_key); 1277 return -1;
1278 }
1307 1279
1308 if (conn->dht_pk_callback) 1280 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1309 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key); 1281 } else {
1282 if (conn->dht_pk_callback)
1283 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key);
1284 }
1310 1285
1311 } else { 1286 } else {
1312 return -1; 1287 return -1;
@@ -1448,31 +1423,12 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
1448 return -1; 1423 return -1;
1449} 1424}
1450 1425
1451/* Get crypto connection id from public key of peer.
1452 *
1453 * return -1 if there are no connections like we are looking for.
1454 * return id if it found it.
1455 */
1456static int getcryptconnection_id_dht_pubkey(const Net_Crypto *c, const uint8_t *dht_public_key)
1457{
1458 uint32_t i;
1459
1460 for (i = 0; i < c->crypto_connections_length; ++i) {
1461 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION && c->crypto_connections[i].dht_public_key_set)
1462 if (memcmp(dht_public_key, c->crypto_connections[i].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1463 return i;
1464 }
1465
1466 return -1;
1467}
1468
1469/* Add a source to the crypto connection. 1426/* Add a source to the crypto connection.
1470 * This is to be used only when we have received a packet from that source. 1427 * This is to be used only when we have received a packet from that source.
1471 * 1428 *
1472 * return -1 on failure. 1429 * return -1 on failure.
1473 * return positive number on success. 1430 * return positive number on success.
1474 * 0 if source was a direct UDP connection. 1431 * 0 if source was a direct UDP connection.
1475 * TODO
1476 */ 1432 */
1477static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source) 1433static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source)
1478{ 1434{
@@ -1490,8 +1446,11 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
1490 conn->ip_port = source; 1446 conn->ip_port = source;
1491 } 1447 }
1492 1448
1493 conn->direct_lastrecv_time = current_time_monotonic(); 1449 conn->direct_lastrecv_time = unix_time();
1494 return 0; 1450 return 0;
1451 } else if (source.ip.family == TCP_FAMILY) {
1452 if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip6.uint32[0]) == 0)
1453 return 1;
1495 } 1454 }
1496 1455
1497 return -1; 1456 return -1;
@@ -1537,30 +1496,29 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const
1537 int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); 1496 int crypt_connection_id = getcryptconnection_id(c, n_c.public_key);
1538 1497
1539 if (crypt_connection_id != -1) { 1498 if (crypt_connection_id != -1) {
1540 int ret = -1;
1541 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1499 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1542 1500
1543 if (conn != 0 && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) { 1501 if (public_key_cmp(n_c.dht_public_key, conn->dht_public_key) != 0) {
1544 memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES); 1502 connection_kill(c, crypt_connection_id);
1545 memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES); 1503 } else {
1546 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1504 int ret = -1;
1547
1548 crypto_connection_add_source(c, crypt_connection_id, source);
1549 1505
1550 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) { 1506 if (conn && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) {
1551 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1507 memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES);
1552 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1508 memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
1553 set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key); 1509 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1554 1510
1555 if (conn->dht_pk_callback) 1511 crypto_connection_add_source(c, crypt_connection_id, source);
1556 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, n_c.dht_public_key);
1557 1512
1558 ret = 0; 1513 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) {
1514 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1515 ret = 0;
1516 }
1559 } 1517 }
1560 }
1561 1518
1562 free(n_c.cookie); 1519 free(n_c.cookie);
1563 return ret; 1520 return ret;
1521 }
1564 } 1522 }
1565 1523
1566 int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); 1524 int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
@@ -1583,9 +1541,16 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1583 if (crypt_connection_id == -1) 1541 if (crypt_connection_id == -1)
1584 return -1; 1542 return -1;
1585 1543
1586 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1544 Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id];
1587 1545
1588 if (conn == 0) 1546 if (n_c->cookie_length != COOKIE_LENGTH)
1547 return -1;
1548
1549 pthread_mutex_lock(&c->tcp_mutex);
1550 conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id);
1551 pthread_mutex_unlock(&c->tcp_mutex);
1552
1553 if (conn->connection_number_tcp == -1)
1589 return -1; 1554 return -1;
1590 1555
1591 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES); 1556 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES);
@@ -1594,16 +1559,17 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1594 random_nonce(conn->sent_nonce); 1559 random_nonce(conn->sent_nonce);
1595 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1560 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1596 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1561 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1562 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1597 1563
1598 if (n_c->cookie_length != COOKIE_LENGTH) 1564 if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) {
1599 return -1; 1565 pthread_mutex_lock(&c->tcp_mutex);
1600 1566 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
1601 if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) 1567 pthread_mutex_unlock(&c->tcp_mutex);
1568 conn->status = CRYPTO_CONN_NO_CONNECTION;
1602 return -1; 1569 return -1;
1570 }
1603 1571
1604 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1572 memcpy(conn->dht_public_key, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES);
1605 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1606 set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key);
1607 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1573 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1608 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; 1574 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1609 crypto_connection_add_source(c, crypt_connection_id, n_c->source); 1575 crypto_connection_add_source(c, crypt_connection_id, n_c->source);
@@ -1616,7 +1582,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1616 * return -1 on failure. 1582 * return -1 on failure.
1617 * return connection id on success. 1583 * return connection id on success.
1618 */ 1584 */
1619int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key) 1585int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key)
1620{ 1586{
1621 int crypt_connection_id = getcryptconnection_id(c, real_public_key); 1587 int crypt_connection_id = getcryptconnection_id(c, real_public_key);
1622 1588
@@ -1628,149 +1594,40 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key)
1628 if (crypt_connection_id == -1) 1594 if (crypt_connection_id == -1)
1629 return -1; 1595 return -1;
1630 1596
1631 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1597 Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id];
1632 1598
1633 if (conn == 0) 1599 if (conn == 0)
1634 return -1; 1600 return -1;
1635 1601
1602 pthread_mutex_lock(&c->tcp_mutex);
1603 conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id);
1604 pthread_mutex_unlock(&c->tcp_mutex);
1605
1606 if (conn->connection_number_tcp == -1)
1607 return -1;
1608
1636 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES); 1609 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES);
1637 random_nonce(conn->sent_nonce); 1610 random_nonce(conn->sent_nonce);
1638 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1611 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1639 conn->status = CRYPTO_CONN_COOKIE_REQUESTING; 1612 conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
1640 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1613 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1641 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; 1614 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1642 return crypt_connection_id; 1615 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
1643}
1644
1645/* Set the status for the TCP connection for conn in location to status.
1646 */
1647static void set_conn_tcp_status(Crypto_Connection *conn, unsigned int location, unsigned int status)
1648{
1649 if (conn->status_tcp[location] == status) {
1650 return;
1651 }
1652
1653 if (conn->status_tcp[location] == STATUS_TCP_ONLINE) {
1654 --conn->num_tcp_online;
1655 }
1656
1657 if (status == STATUS_TCP_ONLINE) {
1658 ++conn->num_tcp_online;
1659 }
1660
1661 conn->status_tcp[location] = status;
1662}
1663
1664/* Disconnect peer from all associated TCP connections.
1665 *
1666 * return -1 on failure.
1667 * return 0 on success.
1668 */
1669static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1670{
1671 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1672
1673 if (conn == 0)
1674 return -1;
1675
1676 uint32_t i;
1677
1678 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1679 if (conn->status_tcp[i] != STATUS_TCP_NULL) {
1680 pthread_mutex_lock(&c->tcp_mutex);
1681 send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]);
1682 set_conn_tcp_status(conn, i, STATUS_TCP_NULL);
1683 conn->con_number_tcp[i] = 0;
1684 pthread_mutex_unlock(&c->tcp_mutex);
1685 }
1686 }
1687
1688 return 0;
1689}
1690
1691/* Connect peer to all associated TCP connections.
1692 *
1693 * return -1 on failure.
1694 * return 0 on success.
1695 */
1696static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1697{
1698 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1699
1700 if (conn == 0)
1701 return -1;
1702 1616
1703 uint32_t i; 1617 conn->cookie_request_number = random_64b();
1704 1618 uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
1705 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1706 if (c->tcp_connections[i] == NULL)
1707 continue;
1708 1619
1620 if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
1621 conn->shared_key) != sizeof(cookie_request)
1622 || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) {
1709 pthread_mutex_lock(&c->tcp_mutex); 1623 pthread_mutex_lock(&c->tcp_mutex);
1710 //TODO check function return? 1624 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
1711 send_routing_request(c->tcp_connections[i], conn->dht_public_key);
1712 pthread_mutex_unlock(&c->tcp_mutex); 1625 pthread_mutex_unlock(&c->tcp_mutex);
1713 } 1626 conn->status = CRYPTO_CONN_NO_CONNECTION;
1714
1715 return 0;
1716}
1717
1718/* Copy friends DHT public key into dht_key.
1719 *
1720 * return 0 on failure (no key copied).
1721 * return 1 on success (key copied).
1722 */
1723unsigned int get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key)
1724{
1725 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1726
1727 if (conn == 0)
1728 return 0;
1729
1730 if (conn->dht_public_key_set == 0)
1731 return 0;
1732
1733 memcpy(dht_public_key, conn->dht_public_key, crypto_box_PUBLICKEYBYTES);
1734 return 1;
1735}
1736
1737
1738/* Set the DHT public key of the crypto connection.
1739 *
1740 * return -1 on failure.
1741 * return 0 on success.
1742 */
1743int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key)
1744{
1745 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1746
1747 if (conn == 0)
1748 return -1; 1627 return -1;
1749
1750 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1751 return -1;
1752
1753 if (conn->dht_public_key_set == 1) {
1754 disconnect_peer_tcp(c, crypt_connection_id);
1755 } 1628 }
1756 1629
1757 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); 1630 return crypt_connection_id;
1758 conn->dht_public_key_set = 1;
1759
1760 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1761 conn->cookie_request_number = random_64b();
1762 uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
1763
1764 if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
1765 conn->shared_key) != sizeof(cookie_request))
1766 return -1;
1767
1768 if (new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0)
1769 return -1;
1770 }//TODO
1771
1772 connect_peer_tcp(c, crypt_connection_id);
1773 return 0;
1774} 1631}
1775 1632
1776/* Set the direct ip of the crypto connection. 1633/* Set the direct ip of the crypto connection.
@@ -1789,7 +1646,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1789 return -1; 1646 return -1;
1790 1647
1791 if (!ipport_equal(&ip_port, &conn->ip_port)) { 1648 if (!ipport_equal(&ip_port, &conn->ip_port)) {
1792 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) { 1649 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time()) {
1793 if (LAN_ip(ip_port.ip) == 0 && LAN_ip(conn->ip_port.ip) == 0 && conn->ip_port.port == ip_port.port) 1650 if (LAN_ip(ip_port.ip) == 0 && LAN_ip(conn->ip_port.ip) == 0 && conn->ip_port.port == ip_port.port)
1794 return -1; 1651 return -1;
1795 } 1652 }
@@ -1805,93 +1662,25 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1805 return -1; 1662 return -1;
1806} 1663}
1807 1664
1808static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key)
1809{
1810 TCP_Client_Connection *TCP_con = object;
1811 Net_Crypto *c = TCP_con->net_crypto_pointer;
1812
1813 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1814
1815 if (crypt_connection_id == -1)
1816 return -1;
1817
1818 set_tcp_connection_number(TCP_con, connection_id, crypt_connection_id);
1819 1665
1820 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1666static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t length)
1821
1822 if (conn == 0)
1823 return -1;
1824
1825 uint32_t location = TCP_con->net_crypto_location;
1826
1827 if (location >= MAX_TCP_CONNECTIONS)
1828 return -1;
1829
1830 if (c->tcp_connections[location] != TCP_con)
1831 return -1;
1832
1833 conn->con_number_tcp[location] = connection_id;
1834 uint32_t i;
1835
1836 for (i = 0; i < conn->num_tcp_relays; ++i) {
1837 if (memcmp(TCP_con->public_key, conn->tcp_relays[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1838 set_conn_tcp_status(conn, location, STATUS_TCP_INVISIBLE);
1839 return 0;
1840 }
1841 }
1842
1843 set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE);
1844 return 0;
1845}
1846
1847static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status)
1848{ 1667{
1849 TCP_Client_Connection *TCP_con = object; 1668 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1850 Net_Crypto *c = TCP_con->net_crypto_pointer;
1851
1852 Crypto_Connection *conn = get_crypto_connection(c, number);
1853
1854 if (conn == 0)
1855 return -1;
1856
1857 uint32_t location = TCP_con->net_crypto_location;
1858
1859 if (location >= MAX_TCP_CONNECTIONS)
1860 return -1;
1861
1862 if (c->tcp_connections[location] != TCP_con)
1863 return -1; 1669 return -1;
1864 1670
1865 if (status == 1) { 1671 Net_Crypto *c = object;
1866 set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE);
1867 } else if (status == 2) {
1868 set_conn_tcp_status(conn, location, STATUS_TCP_ONLINE);
1869 }
1870
1871 conn->con_number_tcp[location] = connection_id;
1872 return 0;
1873}
1874 1672
1875static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length) 1673 Crypto_Connection *conn = get_crypto_connection(c, id);
1876{
1877 1674
1878 if (length == 0) 1675 if (conn == 0)
1879 return -1; 1676 return -1;
1880 1677
1881 TCP_Client_Connection *TCP_con = object;
1882 Net_Crypto *c = TCP_con->net_crypto_pointer;
1883
1884 if (data[0] == NET_PACKET_COOKIE_REQUEST) { 1678 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1885 return tcp_handle_cookie_request(c, TCP_con, connection_id, data, length); 1679 return tcp_handle_cookie_request(c, conn->connection_number_tcp, data, length);
1886 } 1680 }
1887 1681
1888 Crypto_Connection *conn = get_crypto_connection(c, number);
1889
1890 if (conn == 0)
1891 return -1;
1892
1893 pthread_mutex_unlock(&c->tcp_mutex); 1682 pthread_mutex_unlock(&c->tcp_mutex);
1894 int ret = handle_packet_connection(c, number, data, length); 1683 int ret = handle_packet_connection(c, id, data, length);
1895 pthread_mutex_lock(&c->tcp_mutex); 1684 pthread_mutex_lock(&c->tcp_mutex);
1896 1685
1897 if (ret != 0) 1686 if (ret != 0)
@@ -1901,92 +1690,29 @@ static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_i
1901 return 0; 1690 return 0;
1902} 1691}
1903 1692
1904static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length) 1693static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned int tcp_connections_number,
1694 const uint8_t *data, uint16_t length)
1905{ 1695{
1906 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) 1696 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1907 return -1; 1697 return -1;
1908 1698
1909 TCP_Client_Connection *TCP_con = object; 1699 Net_Crypto *c = object;
1910 Net_Crypto *c = TCP_con->net_crypto_pointer;
1911 uint32_t location = TCP_con->net_crypto_location;
1912 1700
1913 if (data[0] == NET_PACKET_COOKIE_REQUEST) { 1701 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1914 return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length); 1702 return tcp_oob_handle_cookie_request(c, tcp_connections_number, public_key, data, length);
1915 } 1703 } else if (data[0] == NET_PACKET_CRYPTO_HS) {
1916
1917 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1918
1919 if (crypt_connection_id == -1) {
1920 IP_Port source; 1704 IP_Port source;
1921 source.port = 0; 1705 source.port = 0;
1922 source.ip.family = TCP_FAMILY; 1706 source.ip.family = TCP_FAMILY;
1923 source.ip.ip6.uint32[0] = location; 1707 source.ip.ip6.uint32[0] = tcp_connections_number;
1924
1925 if (data[0] != NET_PACKET_CRYPTO_HS) {
1926 LOGGER_DEBUG("tcp snhappen %u\n", data[0]);
1927 return -1;
1928 }
1929 1708
1930 if (handle_new_connection_handshake(c, source, data, length) != 0) 1709 if (handle_new_connection_handshake(c, source, data, length) != 0)
1931 return -1; 1710 return -1;
1932 1711
1933 return 0; 1712 return 0;
1934 } 1713 } else {
1935
1936 pthread_mutex_unlock(&c->tcp_mutex);
1937 int ret = handle_packet_connection(c, crypt_connection_id, data, length);
1938 pthread_mutex_lock(&c->tcp_mutex);
1939
1940 if (ret != 0)
1941 return -1; 1714 return -1;
1942
1943 return 0;
1944}
1945
1946static int tcp_onion_callback(void *object, const uint8_t *data, uint16_t length)
1947{
1948 Net_Crypto *c = object;
1949
1950 if (c->tcp_onion_callback)
1951 return c->tcp_onion_callback(c->tcp_onion_callback_object, data, length);
1952
1953 return 1;
1954}
1955
1956
1957/* Check if tcp connection to public key can be created.
1958 *
1959 * return -1 if it can't.
1960 * return 0 if it can.
1961 */
1962static int tcp_connection_check(const Net_Crypto *c, const uint8_t *public_key)
1963{
1964 uint32_t i;
1965
1966 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1967 if (c->tcp_connections_new[i] == NULL)
1968 continue;
1969
1970 if (memcmp(c->tcp_connections_new[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1971 return -1;
1972 }
1973
1974 uint32_t num = 0;
1975
1976 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1977 if (c->tcp_connections[i] == NULL)
1978 continue;
1979
1980 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1981 return -1;
1982
1983 ++num;
1984 } 1715 }
1985
1986 if (num == MAX_TCP_CONNECTIONS)
1987 return -1;
1988
1989 return 0;
1990} 1716}
1991 1717
1992/* Add a tcp relay, associating it to a crypt_connection_id. 1718/* Add a tcp relay, associating it to a crypt_connection_id.
@@ -2001,45 +1727,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
2001 if (conn == 0) 1727 if (conn == 0)
2002 return -1; 1728 return -1;
2003 1729
2004 if (ip_port.ip.family == TCP_INET) { 1730 pthread_mutex_lock(&c->tcp_mutex);
2005 ip_port.ip.family = AF_INET; 1731 int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
2006 } else if (ip_port.ip.family == TCP_INET6) { 1732 pthread_mutex_unlock(&c->tcp_mutex);
2007 ip_port.ip.family = AF_INET6; 1733 return ret;
2008 }
2009
2010 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
2011 return -1;
2012
2013 uint32_t i;
2014
2015 for (i = 0; i < conn->num_tcp_relays; ++i) {
2016 if (memcmp(conn->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
2017 conn->tcp_relays[i].ip_port = ip_port;
2018 return 0;
2019 }
2020 }
2021
2022 if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) {
2023 uint16_t index = rand() % MAX_TCP_RELAYS_PEER;
2024 conn->tcp_relays[index].ip_port = ip_port;
2025 memcpy(conn->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES);
2026 } else {
2027 conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port;
2028 memcpy(conn->tcp_relays[conn->num_tcp_relays].public_key, public_key, crypto_box_PUBLICKEYBYTES);
2029 ++conn->num_tcp_relays;
2030 }
2031
2032 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2033 if (c->tcp_connections[i] == NULL)
2034 continue;
2035
2036 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
2037 if (conn->status_tcp[i] == STATUS_TCP_OFFLINE)
2038 set_conn_tcp_status(conn, i, STATUS_TCP_INVISIBLE);
2039 }
2040 }
2041
2042 return add_tcp_relay(c, ip_port, public_key);
2043} 1734}
2044 1735
2045/* Add a tcp relay to the array. 1736/* Add a tcp relay to the array.
@@ -2049,30 +1740,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
2049 */ 1740 */
2050int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key) 1741int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
2051{ 1742{
2052 if (ip_port.ip.family == TCP_INET) { 1743 pthread_mutex_lock(&c->tcp_mutex);
2053 ip_port.ip.family = AF_INET; 1744 int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key);
2054 } else if (ip_port.ip.family == TCP_INET6) { 1745 pthread_mutex_unlock(&c->tcp_mutex);
2055 ip_port.ip.family = AF_INET6; 1746 return ret;
2056 }
2057
2058 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
2059 return -1;
2060
2061 if (tcp_connection_check(c, public_key) != 0)
2062 return -1;
2063
2064 uint32_t i;
2065
2066 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2067 if (c->tcp_connections_new[i] == NULL) {
2068 c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key,
2069 &c->proxy_info);
2070
2071 return 0;
2072 }
2073 }
2074
2075 return -1;
2076} 1747}
2077 1748
2078/* Return a random TCP connection number for use in send_tcp_onion_request. 1749/* Return a random TCP connection number for use in send_tcp_onion_request.
@@ -2085,47 +1756,25 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
2085 */ 1756 */
2086int get_random_tcp_con_number(Net_Crypto *c) 1757int get_random_tcp_con_number(Net_Crypto *c)
2087{ 1758{
2088 unsigned int i, r = rand(); 1759 pthread_mutex_lock(&c->tcp_mutex);
2089 1760 int ret = get_random_tcp_onion_conn_number(c->tcp_c);
2090 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 1761 pthread_mutex_unlock(&c->tcp_mutex);
2091 if (c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS]) {
2092 return (i + r) % MAX_TCP_CONNECTIONS;
2093 }
2094 }
2095 1762
2096 return -1; 1763 return ret;
2097} 1764}
2098 1765
2099/* Send an onion packet via the TCP relay corresponding to TCP_conn_number. 1766/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
2100 * 1767 *
2101 * return 0 on success. 1768 * return 0 on success.
2102 * return -1 on failure. 1769 * return -1 on failure.
2103 */ 1770 */
2104int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const uint8_t *data, uint16_t length) 1771int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length)
2105{ 1772{
2106 if (TCP_conn_number > MAX_TCP_CONNECTIONS) { 1773 pthread_mutex_lock(&c->tcp_mutex);
2107 return -1; 1774 int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
2108 } 1775 pthread_mutex_unlock(&c->tcp_mutex);
2109
2110 if (c->tcp_connections[TCP_conn_number]) {
2111 pthread_mutex_lock(&c->tcp_mutex);
2112 int ret = send_onion_request(c->tcp_connections[TCP_conn_number], data, length);
2113 pthread_mutex_unlock(&c->tcp_mutex);
2114
2115 if (ret == 1)
2116 return 0;
2117 }
2118
2119 return -1;
2120}
2121 1776
2122/* Set the function to be called when an onion response packet is received by one of the TCP connections. 1777 return ret;
2123 */
2124void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data,
2125 uint16_t length), void *object)
2126{
2127 c->tcp_onion_callback = tcp_onion_callback;
2128 c->tcp_onion_callback_object = object;
2129} 1778}
2130 1779
2131/* Copy a maximum of num TCP relays we are connected to to tcp_relays. 1780/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
@@ -2134,173 +1783,47 @@ void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *o
2134 * return number of relays copied to tcp_relays on success. 1783 * return number of relays copied to tcp_relays on success.
2135 * return 0 on failure. 1784 * return 0 on failure.
2136 */ 1785 */
2137unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num) 1786unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
2138{ 1787{
2139 if (num == 0) 1788 if (num == 0)
2140 return 0; 1789 return 0;
2141 1790
2142 uint32_t i; 1791 pthread_mutex_lock(&c->tcp_mutex);
2143 uint16_t copied = 0; 1792 unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
2144 1793 pthread_mutex_unlock(&c->tcp_mutex);
2145 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2146 if (c->tcp_connections[i] != NULL) {
2147 memcpy(tcp_relays[copied].public_key, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES);
2148 tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port;
2149
2150 if (tcp_relays[copied].ip_port.ip.family == AF_INET) {
2151 tcp_relays[copied].ip_port.ip.family = TCP_INET;
2152 } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) {
2153 tcp_relays[copied].ip_port.ip.family = TCP_INET6;
2154 }
2155
2156 ++copied;
2157
2158 if (copied == num)
2159 return copied;
2160 }
2161 }
2162 1794
2163 return copied; 1795 return ret;
2164} 1796}
2165 1797
2166/* Add a connected tcp connection to the tcp_connections array. 1798static void do_tcp(Net_Crypto *c)
2167 *
2168 * return 0 if it was added.
2169 * return -1 if it wasn't.
2170 */
2171static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con)
2172{ 1799{
2173 uint32_t i; 1800 pthread_mutex_lock(&c->tcp_mutex);
2174 1801 do_tcp_connections(c->tcp_c);
2175 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 1802 pthread_mutex_unlock(&c->tcp_mutex);
2176 if (c->tcp_connections[i] == NULL)
2177 break;
2178 }
2179
2180 if (i == MAX_TCP_CONNECTIONS)
2181 return -1;
2182 1803
2183 uint32_t tcp_num = i; 1804 uint32_t i;
2184 1805
2185 for (i = 0; i < c->crypto_connections_length; ++i) { 1806 for (i = 0; i < c->crypto_connections_length; ++i) {
2186 Crypto_Connection *conn = get_crypto_connection(c, i); 1807 Crypto_Connection *conn = get_crypto_connection(c, i);
2187 1808
2188 if (conn == 0) 1809 if (conn == 0)
2189 return -1; 1810 return;
2190
2191 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2192 continue;
2193
2194 if (conn->status == CRYPTO_CONN_TIMED_OUT)
2195 continue;
2196
2197 if (conn->dht_public_key_set)
2198 if (send_routing_request(tcp_con, conn->dht_public_key) != 1)
2199 return -1;
2200
2201 }
2202
2203 tcp_con->net_crypto_pointer = c;
2204 tcp_con->net_crypto_location = tcp_num;
2205 routing_response_handler(tcp_con, tcp_response_callback, tcp_con);
2206 routing_status_handler(tcp_con, tcp_status_callback, tcp_con);
2207 routing_data_handler(tcp_con, tcp_data_callback, tcp_con);
2208 oob_data_handler(tcp_con, tcp_oob_callback, tcp_con);
2209 onion_response_handler(tcp_con, tcp_onion_callback, c);
2210 c->tcp_connections[tcp_num] = tcp_con;
2211 return 0;
2212}
2213
2214static void do_tcp(Net_Crypto *c)
2215{
2216 uint32_t i;
2217
2218 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2219 if (c->tcp_connections_new[i] == NULL)
2220 continue;
2221
2222 pthread_mutex_lock(&c->tcp_mutex);
2223 do_TCP_connection(c->tcp_connections_new[i]);
2224 pthread_mutex_unlock(&c->tcp_mutex);
2225 1811
2226 if (c->tcp_connections_new[i]->status == TCP_CLIENT_CONFIRMED) { 1812 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
2227 pthread_mutex_lock(&c->tcp_mutex); 1813 _Bool direct_connected = 0;
2228 int ret = add_tcp_connected(c, c->tcp_connections_new[i]); 1814 crypto_connection_status(c, i, &direct_connected, NULL);
2229 pthread_mutex_unlock(&c->tcp_mutex);
2230 1815
2231 if (ret == 0) { 1816 if (direct_connected) {
2232 c->tcp_connections_new[i] = NULL; 1817 pthread_mutex_lock(&c->tcp_mutex);
1818 set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0);
1819 pthread_mutex_unlock(&c->tcp_mutex);
2233 } else { 1820 } else {
2234 kill_TCP_connection(c->tcp_connections_new[i]); 1821 pthread_mutex_lock(&c->tcp_mutex);
2235 c->tcp_connections_new[i] = NULL; 1822 set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1);
1823 pthread_mutex_unlock(&c->tcp_mutex);
2236 } 1824 }
2237 } 1825 }
2238 } 1826 }
2239
2240 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2241 if (c->tcp_connections[i] == NULL)
2242 continue;
2243
2244 pthread_mutex_lock(&c->tcp_mutex);
2245 do_TCP_connection(c->tcp_connections[i]);
2246 pthread_mutex_unlock(&c->tcp_mutex);
2247 }
2248}
2249
2250static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number)
2251{
2252 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2253 return;
2254
2255 if (number >= MAX_TCP_CONNECTIONS)
2256 return;
2257
2258 set_conn_tcp_status(conn, number, STATUS_TCP_NULL);
2259 conn->con_number_tcp[number] = 0;
2260}
2261
2262static void clear_disconnected_tcp(Net_Crypto *c)
2263{
2264 uint32_t i, j;
2265
2266 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2267 if (c->tcp_connections_new[i] == NULL)
2268 continue;
2269
2270 if (c->tcp_connections_new[i]->status != TCP_CLIENT_DISCONNECTED)
2271 continue;
2272
2273 kill_TCP_connection(c->tcp_connections_new[i]);
2274 c->tcp_connections_new[i] = NULL;
2275 }
2276
2277 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2278 if (c->tcp_connections[i] == NULL)
2279 continue;
2280
2281 TCP_Client_Connection *tcp_con = c->tcp_connections[i];
2282
2283 if (tcp_con->status != TCP_CLIENT_DISCONNECTED)
2284 continue;
2285
2286 /* Try reconnecting to relay on disconnect. */
2287 add_tcp_relay(c, tcp_con->ip_port, tcp_con->public_key);
2288
2289 pthread_mutex_lock(&c->tcp_mutex);
2290 c->tcp_connections[i] = NULL;
2291 kill_TCP_connection(tcp_con);
2292
2293 for (j = 0; j < c->crypto_connections_length; ++j) {
2294 Crypto_Connection *conn = get_crypto_connection(c, j);
2295
2296 if (conn == 0)
2297 continue;
2298
2299 clear_disconnected_tcp_peer(conn, i);
2300 }
2301
2302 pthread_mutex_unlock(&c->tcp_mutex);
2303 }
2304} 1827}
2305 1828
2306/* Set function to be called when connection with crypt_connection_id goes connects/disconnects. 1829/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
@@ -2372,8 +1895,10 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
2372} 1895}
2373 1896
2374 1897
2375/* Set the function for this friend that will be callbacked with object and number 1898/* Set the function for this friend that will be callbacked with object and number if
2376 * when that friend gives us his DHT temporary public key. 1899 * the friend sends us a different dht public key than we have associated to him.
1900 *
1901 * If this function is called, the connection should be recreated with the new public key.
2377 * 1902 *
2378 * object and number will be passed as argument to this function. 1903 * object and number will be passed as argument to this function.
2379 * 1904 *
@@ -2441,7 +1966,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
2441 return -1; 1966 return -1;
2442 1967
2443 pthread_mutex_lock(&conn->mutex); 1968 pthread_mutex_lock(&conn->mutex);
2444 conn->direct_lastrecv_time = current_time_monotonic(); 1969 conn->direct_lastrecv_time = unix_time();
2445 pthread_mutex_unlock(&conn->mutex); 1970 pthread_mutex_unlock(&conn->mutex);
2446 return 0; 1971 return 0;
2447} 1972}
@@ -2746,7 +2271,10 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2746 if (conn->status == CRYPTO_CONN_ESTABLISHED) 2271 if (conn->status == CRYPTO_CONN_ESTABLISHED)
2747 send_kill_packet(c, crypt_connection_id); 2272 send_kill_packet(c, crypt_connection_id);
2748 2273
2749 disconnect_peer_tcp(c, crypt_connection_id); 2274 pthread_mutex_lock(&c->tcp_mutex);
2275 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
2276 pthread_mutex_unlock(&c->tcp_mutex);
2277
2750 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); 2278 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id);
2751 clear_temp_packet(c, crypt_connection_id); 2279 clear_temp_packet(c, crypt_connection_id);
2752 clear_buffer(&conn->send_array); 2280 clear_buffer(&conn->send_array);
@@ -2762,18 +2290,26 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2762/* return one of CRYPTO_CONN_* values indicating the state of the connection. 2290/* return one of CRYPTO_CONN_* values indicating the state of the connection.
2763 * 2291 *
2764 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. 2292 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
2293 * sets online_tcp_relays to the number of connected tcp relays this connection has.
2765 */ 2294 */
2766unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected) 2295unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected,
2296 unsigned int *online_tcp_relays)
2767{ 2297{
2768 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 2298 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2769 2299
2770 if (conn == 0) 2300 if (conn == 0)
2771 return CRYPTO_CONN_NO_CONNECTION; 2301 return CRYPTO_CONN_NO_CONNECTION;
2772 2302
2773 *direct_connected = 0; 2303 if (direct_connected) {
2304 *direct_connected = 0;
2774 2305
2775 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) 2306 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time())
2776 *direct_connected = 1; 2307 *direct_connected = 1;
2308 }
2309
2310 if (online_tcp_relays) {
2311 *online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp);
2312 }
2777 2313
2778 return conn->status; 2314 return conn->status;
2779} 2315}
@@ -2816,8 +2352,19 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info)
2816 if (temp == NULL) 2352 if (temp == NULL)
2817 return NULL; 2353 return NULL;
2818 2354
2355 temp->tcp_c = new_tcp_connections(dht, proxy_info);
2356
2357 if (temp->tcp_c == NULL) {
2358 free(temp);
2359 return NULL;
2360 }
2361
2362 set_packet_tcp_connection_callback(temp->tcp_c, &tcp_data_callback, temp);
2363 set_oob_packet_tcp_connection_callback(temp->tcp_c, &tcp_oob_callback, temp);
2364
2819 if (create_recursive_mutex(&temp->tcp_mutex) != 0 || 2365 if (create_recursive_mutex(&temp->tcp_mutex) != 0 ||
2820 pthread_mutex_init(&temp->connections_mutex, NULL) != 0) { 2366 pthread_mutex_init(&temp->connections_mutex, NULL) != 0) {
2367 kill_tcp_connections(temp->tcp_c);
2821 free(temp); 2368 free(temp);
2822 return NULL; 2369 return NULL;
2823 } 2370 }
@@ -2836,8 +2383,6 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info)
2836 2383
2837 bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8); 2384 bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8);
2838 2385
2839 temp->proxy_info = *proxy_info;
2840
2841 return temp; 2386 return temp;
2842} 2387}
2843 2388
@@ -2852,7 +2397,7 @@ static void kill_timedout(Net_Crypto *c)
2852 if (conn == 0) 2397 if (conn == 0)
2853 return; 2398 return;
2854 2399
2855 if (conn->status == CRYPTO_CONN_NO_CONNECTION || conn->status == CRYPTO_CONN_TIMED_OUT) 2400 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2856 continue; 2401 continue;
2857 2402
2858 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT 2403 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT
@@ -2860,19 +2405,8 @@ static void kill_timedout(Net_Crypto *c)
2860 if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) 2405 if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES)
2861 continue; 2406 continue;
2862 2407
2863 conn->killed = 1; 2408 connection_kill(c, i);
2864
2865 }
2866
2867 if (conn->killed) {
2868 if (conn->connection_status_callback) {
2869 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
2870 crypto_kill(c, i);
2871 continue;
2872 }
2873 2409
2874 conn->status = CRYPTO_CONN_TIMED_OUT;
2875 continue;
2876 } 2410 }
2877 2411
2878 if (conn->status == CRYPTO_CONN_ESTABLISHED) { 2412 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
@@ -2894,7 +2428,6 @@ void do_net_crypto(Net_Crypto *c)
2894 unix_time_update(); 2428 unix_time_update();
2895 kill_timedout(c); 2429 kill_timedout(c);
2896 do_tcp(c); 2430 do_tcp(c);
2897 clear_disconnected_tcp(c);
2898 send_crypto_packets(c); 2431 send_crypto_packets(c);
2899} 2432}
2900 2433
@@ -2906,14 +2439,10 @@ void kill_net_crypto(Net_Crypto *c)
2906 crypto_kill(c, i); 2439 crypto_kill(c, i);
2907 } 2440 }
2908 2441
2909 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2910 kill_TCP_connection(c->tcp_connections_new[i]);
2911 kill_TCP_connection(c->tcp_connections[i]);
2912 }
2913
2914 pthread_mutex_destroy(&c->tcp_mutex); 2442 pthread_mutex_destroy(&c->tcp_mutex);
2915 pthread_mutex_destroy(&c->connections_mutex); 2443 pthread_mutex_destroy(&c->connections_mutex);
2916 2444
2445 kill_tcp_connections(c->tcp_c);
2917 bs_list_free(&c->ip_port_list); 2446 bs_list_free(&c->ip_port_list);
2918 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); 2447 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL);
2919 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); 2448 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL);
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index fab72cb3..9eb5e2d3 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -26,7 +26,7 @@
26 26
27#include "DHT.h" 27#include "DHT.h"
28#include "LAN_discovery.h" 28#include "LAN_discovery.h"
29#include "TCP_client.h" 29#include "TCP_connection.h"
30#include <pthread.h> 30#include <pthread.h>
31 31
32#define CRYPTO_CONN_NO_CONNECTION 0 32#define CRYPTO_CONN_NO_CONNECTION 0
@@ -34,7 +34,6 @@
34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets 34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets
35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other 35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other
36#define CRYPTO_CONN_ESTABLISHED 4 36#define CRYPTO_CONN_ESTABLISHED 4
37#define CRYPTO_CONN_TIMED_OUT 5
38 37
39/* Maximum size of receiving and sending packet buffers. */ 38/* Maximum size of receiving and sending packet buffers. */
40#define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */ 39#define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */
@@ -61,7 +60,7 @@
61#define MAX_NUM_SENDPACKET_TRIES 8 60#define MAX_NUM_SENDPACKET_TRIES 8
62 61
63/* The timeout of no received UDP packets before the direct UDP connection is considered dead. */ 62/* The timeout of no received UDP packets before the direct UDP connection is considered dead. */
64#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 2) 63#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 1000)
65 64
66#define PACKET_ID_PADDING 0 /* Denotes padding */ 65#define PACKET_ID_PADDING 0 /* Denotes padding */
67#define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */ 66#define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */
@@ -73,11 +72,6 @@
73#define MAX_TCP_CONNECTIONS 64 72#define MAX_TCP_CONNECTIONS 64
74#define MAX_TCP_RELAYS_PEER 4 73#define MAX_TCP_RELAYS_PEER 4
75 74
76#define STATUS_TCP_NULL 0
77#define STATUS_TCP_OFFLINE 1
78#define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */
79#define STATUS_TCP_ONLINE 3
80
81/* All packets starting with a byte in this range are considered lossy packets. */ 75/* All packets starting with a byte in this range are considered lossy packets. */
82#define PACKET_ID_LOSSY_RANGE_START 192 76#define PACKET_ID_LOSSY_RANGE_START 192
83#define PACKET_ID_LOSSY_RANGE_SIZE 63 77#define PACKET_ID_LOSSY_RANGE_SIZE 63
@@ -112,11 +106,9 @@ typedef struct {
112 * 2 if we are sending handshake packets 106 * 2 if we are sending handshake packets
113 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), 107 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet),
114 * 4 if the connection is established. 108 * 4 if the connection is established.
115 * 5 if the connection is timed out.
116 */ 109 */
117 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ 110 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
118 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */ 111 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
119 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
120 112
121 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ 113 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
122 uint16_t temp_packet_length; 114 uint16_t temp_packet_length;
@@ -155,15 +147,8 @@ typedef struct {
155 long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE]; 147 long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE];
156 uint32_t packets_sent; 148 uint32_t packets_sent;
157 149
158 uint8_t killed; /* set to 1 to kill the connection. */ 150 /* TCP_connection connection_number */
159 151 unsigned int connection_number_tcp;
160 uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */
161 uint8_t con_number_tcp[MAX_TCP_CONNECTIONS];
162 unsigned int last_relay_sentto;
163 unsigned int num_tcp_online;
164
165 Node_format tcp_relays[MAX_TCP_RELAYS_PEER];
166 uint16_t num_tcp_relays;
167 152
168 uint8_t maximum_speed_reached; 153 uint8_t maximum_speed_reached;
169 154
@@ -186,10 +171,9 @@ typedef struct {
186 171
187typedef struct { 172typedef struct {
188 DHT *dht; 173 DHT *dht;
174 TCP_Connections *tcp_c;
189 175
190 Crypto_Connection *crypto_connections; 176 Crypto_Connection *crypto_connections;
191 TCP_Client_Connection *tcp_connections_new[MAX_TCP_CONNECTIONS];
192 TCP_Client_Connection *tcp_connections[MAX_TCP_CONNECTIONS];
193 pthread_mutex_t tcp_mutex; 177 pthread_mutex_t tcp_mutex;
194 178
195 pthread_mutex_t connections_mutex; 179 pthread_mutex_t connections_mutex;
@@ -211,11 +195,6 @@ typedef struct {
211 uint32_t current_sleep_time; 195 uint32_t current_sleep_time;
212 196
213 BS_LIST ip_port_list; 197 BS_LIST ip_port_list;
214
215 int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length);
216 void *tcp_onion_callback_object;
217
218 TCP_Proxy_Info proxy_info;
219} Net_Crypto; 198} Net_Crypto;
220 199
221 200
@@ -241,21 +220,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
241 * return -1 on failure. 220 * return -1 on failure.
242 * return connection id on success. 221 * return connection id on success.
243 */ 222 */
244int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key); 223int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key);
245
246/* Copy friends DHT public key into dht_key.
247 *
248 * return 0 on failure (no key copied).
249 * return 1 on success (key copied).
250 */
251unsigned int get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key);
252
253/* Set the DHT public key of the crypto connection.
254 *
255 * return -1 on failure.
256 * return 0 on success.
257 */
258int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key);
259 224
260/* Set the direct ip of the crypto connection. 225/* Set the direct ip of the crypto connection.
261 * 226 *
@@ -301,8 +266,10 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
301 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object, 266 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object,
302 int id); 267 int id);
303 268
304/* Set the function for this friend that will be callbacked with object and number 269/* Set the function for this friend that will be callbacked with object and number if
305 * when that friend gives us his DHT temporary public key. 270 * the friend sends us a different dht public key than we have associated to him.
271 *
272 * If this function is called, the connection should be recreated with the new public key.
306 * 273 *
307 * object and number will be passed as argument to this function. 274 * object and number will be passed as argument to this function.
308 * 275 *
@@ -364,11 +331,6 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
364 */ 331 */
365int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key); 332int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key);
366 333
367/* Set the function to be called when an onion response packet is received by one of the TCP connections.
368 */
369void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data,
370 uint16_t length), void *object);
371
372/* Return a random TCP connection number for use in send_tcp_onion_request. 334/* Return a random TCP connection number for use in send_tcp_onion_request.
373 * 335 *
374 * return TCP connection number on success. 336 * return TCP connection number on success.
@@ -389,7 +351,7 @@ int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const ui
389 * return number of relays copied to tcp_relays on success. 351 * return number of relays copied to tcp_relays on success.
390 * return 0 on failure. 352 * return 0 on failure.
391 */ 353 */
392unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num); 354unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
393 355
394/* Kill a crypto connection. 356/* Kill a crypto connection.
395 * 357 *
@@ -398,13 +360,13 @@ unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_rel
398 */ 360 */
399int crypto_kill(Net_Crypto *c, int crypt_connection_id); 361int crypto_kill(Net_Crypto *c, int crypt_connection_id);
400 362
401
402/* return one of CRYPTO_CONN_* values indicating the state of the connection. 363/* return one of CRYPTO_CONN_* values indicating the state of the connection.
403 * 364 *
404 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. 365 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
366 * sets online_tcp_relays to the number of connected tcp relays this connection has.
405 */ 367 */
406unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected); 368unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected,
407 369 unsigned int *online_tcp_relays);
408 370
409/* Generate our public and private keys. 371/* Generate our public and private keys.
410 * Only call this function the first time the program starts. 372 * Only call this function the first time the program starts.
diff --git a/toxcore/onion.c b/toxcore/onion.c
index c6093f0c..48e4c769 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -35,8 +35,8 @@
35#define SEND_2 ONION_SEND_2 35#define SEND_2 ONION_SEND_2
36#define SEND_1 ONION_SEND_1 36#define SEND_1 ONION_SEND_1
37 37
38/* Change symmetric keys every hour to make paths expire eventually. */ 38/* Change symmetric keys every 2 hours to make paths expire eventually. */
39#define KEY_REFRESH_INTERVAL (60 * 60) 39#define KEY_REFRESH_INTERVAL (2 * 60 * 60)
40static void change_symmetric_key(Onion *onion) 40static void change_symmetric_key(Onion *onion)
41{ 41{
42 if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) { 42 if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) {
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index a9fc1643..ed328fb3 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -1425,7 +1425,6 @@ void do_onion_client(Onion_Client *onion_c)
1425 ++onion_c->onion_connected; 1425 ++onion_c->onion_connected;
1426 } 1426 }
1427 1427
1428 onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht);
1429 } else { 1428 } else {
1430 populate_path_nodes_tcp(onion_c); 1429 populate_path_nodes_tcp(onion_c);
1431 1430
@@ -1434,12 +1433,22 @@ void do_onion_client(Onion_Client *onion_c)
1434 } 1433 }
1435 } 1434 }
1436 1435
1436 onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht);
1437
1438 if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) {
1439 set_tcp_onion_status(onion_c->c->tcp_c, !onion_c->UDP_connected);
1440 }
1441
1437 if (onion_connection_status(onion_c)) { 1442 if (onion_connection_status(onion_c)) {
1438 for (i = 0; i < onion_c->num_friends; ++i) { 1443 for (i = 0; i < onion_c->num_friends; ++i) {
1439 do_friend(onion_c, i); 1444 do_friend(onion_c, i);
1440 } 1445 }
1441 } 1446 }
1442 1447
1448 if (onion_c->last_run == 0) {
1449 onion_c->first_run = unix_time();
1450 }
1451
1443 onion_c->last_run = unix_time(); 1452 onion_c->last_run = unix_time();
1444} 1453}
1445 1454
@@ -1467,7 +1476,7 @@ Onion_Client *new_onion_client(Net_Crypto *c)
1467 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); 1476 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
1468 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c); 1477 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c);
1469 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c); 1478 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c);
1470 tcp_onion_response_handler(onion_c->c, &handle_tcp_onion, onion_c); 1479 set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, &handle_tcp_onion, onion_c);
1471 1480
1472 return onion_c; 1481 return onion_c;
1473} 1482}
@@ -1483,7 +1492,7 @@ void kill_onion_client(Onion_Client *onion_c)
1483 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); 1492 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);
1484 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL); 1493 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL);
1485 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL); 1494 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL);
1486 tcp_onion_response_handler(onion_c->c, NULL, NULL); 1495 set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, NULL, NULL);
1487 memset(onion_c, 0, sizeof(Onion_Client)); 1496 memset(onion_c, 0, sizeof(Onion_Client));
1488 free(onion_c); 1497 free(onion_c);
1489} 1498}
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index e10a86c5..ad28ac51 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -136,7 +136,7 @@ typedef struct {
136 Onion_Client_Paths onion_paths_friends; 136 Onion_Client_Paths onion_paths_friends;
137 137
138 uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; 138 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
139 uint64_t last_run; 139 uint64_t last_run, first_run;
140 140
141 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; 141 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
142 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; 142 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 8e368851..d490eb91 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -368,7 +368,7 @@ struct Tox_Options {
368 * exceed 255 characters, and be in a NUL-terminated C string format 368 * exceed 255 characters, and be in a NUL-terminated C string format
369 * (255 chars + 1 NUL byte). 369 * (255 chars + 1 NUL byte).
370 * 370 *
371 * This member is ignored (it can be NULL) if proxy_enabled is false. 371 * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE.
372 */ 372 */
373 const char *proxy_host; 373 const char *proxy_host;
374 374
@@ -376,7 +376,7 @@ struct Tox_Options {
376 * The port to use to connect to the proxy server. 376 * The port to use to connect to the proxy server.
377 * 377 *
378 * Ports must be in the range (1, 65535). The value is ignored if 378 * Ports must be in the range (1, 65535). The value is ignored if
379 * proxy_enabled is false. 379 * proxy_type is TOX_PROXY_TYPE_NONE.
380 */ 380 */
381 uint16_t proxy_port; 381 uint16_t proxy_port;
382 382
@@ -1628,7 +1628,7 @@ typedef enum TOX_ERR_FILE_SEND {
1628 * a file name, not a path with directory names. 1628 * a file name, not a path with directory names.
1629 * 1629 *
1630 * If a non-zero file size is provided, this can be used by both sides to 1630 * If a non-zero file size is provided, this can be used by both sides to
1631 * determine the sending progress. File size can be set to zero for streaming 1631 * determine the sending progress. File size can be set to UINT64_MAX for streaming
1632 * data of unknown size. 1632 * data of unknown size.
1633 * 1633 *
1634 * File transmission occurs in chunks, which are requested through the 1634 * File transmission occurs in chunks, which are requested through the