summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2015-04-21 14:30:39 -0400
committerirungentoo <irungentoo@gmail.com>2015-04-21 14:30:39 -0400
commit0a0ed452026129fc9055c35ab75cfadab6f0dc06 (patch)
tree5367d65cde7398bf39a45e3622a02f3b7fad9247 /toxcore
parente4ae993a80261d12cf7adb7f797a56579c39ea91 (diff)
If a net_crypto connection isn't using the TCP relays, disconnect from them.
TCP_connections can now be put to sleep, a state where they store what they were connected to without being connected and then resumed from sleep.
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/TCP_connection.c206
-rw-r--r--toxcore/TCP_connection.h23
-rw-r--r--toxcore/net_crypto.c24
3 files changed, 240 insertions, 13 deletions
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c
index 912f4be4..d2aa3d96 100644
--- a/toxcore/TCP_connection.c
+++ b/toxcore/TCP_connection.c
@@ -333,6 +333,9 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num
333 if (!tcp_con) 333 if (!tcp_con)
334 return -1; 334 return -1;
335 335
336 if (tcp_con->status != TCP_CONN_CONNECTED)
337 return -1;
338
336 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);
337 340
338 if (ret == 1) 341 if (ret == 1)
@@ -404,8 +407,14 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela
404 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 407 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
405 408
406 if (tcp_con) { 409 if (tcp_con) {
407 if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { 410 if (tcp_con->status == TCP_CONN_SLEEPING) {
408 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 }
409 } 418 }
410 } 419 }
411 } 420 }
@@ -465,6 +474,10 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
465 474
466 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) { 475 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
467 --tcp_con->lock_count; 476 --tcp_con->lock_count;
477
478 if (con_to->status == TCP_CONN_SLEEPING) {
479 --tcp_con->sleep_count;
480 }
468 } 481 }
469 } 482 }
470 } 483 }
@@ -472,6 +485,72 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
472 return wipe_connection(tcp_c, connections_number); 485 return wipe_connection(tcp_c, connections_number);
473} 486}
474 487
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
475static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connections_number) 554static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connections_number)
476{ 555{
477 unsigned int i; 556 unsigned int i;
@@ -606,6 +685,9 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
606 if (!tcp_con) 685 if (!tcp_con)
607 return -1; 686 return -1;
608 687
688 if (tcp_con->status == TCP_CONN_SLEEPING)
689 return -1;
690
609 IP_Port ip_port = tcp_con->connection->ip_port; 691 IP_Port ip_port = tcp_con->connection->ip_port;
610 uint8_t relay_pk[crypto_box_PUBLICKEYBYTES]; 692 uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
611 memcpy(relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES); 693 memcpy(relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES);
@@ -634,12 +716,83 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
634 } 716 }
635 717
636 tcp_con->lock_count = 0; 718 tcp_con->lock_count = 0;
719 tcp_con->sleep_count = 0;
637 tcp_con->connected_time = 0; 720 tcp_con->connected_time = 0;
638 tcp_con->status = TCP_CONN_VALID; 721 tcp_con->status = TCP_CONN_VALID;
722 tcp_con->unsleep = 0;
639 723
640 return 0; 724 return 0;
641} 725}
642 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
643/* Send a TCP routing request. 796/* Send a TCP routing request.
644 * 797 *
645 * return 0 on success. 798 * return 0 on success.
@@ -652,6 +805,9 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec
652 if (!tcp_con) 805 if (!tcp_con)
653 return -1; 806 return -1;
654 807
808 if (tcp_con->status == TCP_CONN_SLEEPING)
809 return -1;
810
655 if (send_routing_request(tcp_con->connection, public_key) != 1) 811 if (send_routing_request(tcp_con->connection, public_key) != 1)
656 return -1; 812 return -1;
657 813
@@ -704,11 +860,19 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection
704 return -1; 860 return -1;
705 861
706 --tcp_con->lock_count; 862 --tcp_con->lock_count;
863
864 if (con_to->status == TCP_CONN_SLEEPING) {
865 --tcp_con->sleep_count;
866 }
707 } else if (status == 2) { 867 } else if (status == 2) {
708 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)
709 return -1; 869 return -1;
710 870
711 ++tcp_con->lock_count; 871 ++tcp_con->lock_count;
872
873 if (con_to->status == TCP_CONN_SLEEPING) {
874 ++tcp_con->sleep_count;
875 }
712 } 876 }
713 877
714 return 0; 878 return 0;
@@ -906,6 +1070,10 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb
906 if (!tcp_con) 1070 if (!tcp_con)
907 return -1; 1071 return -1;
908 1072
1073 if (con_to->status != TCP_CONN_SLEEPING && tcp_con->status == TCP_CONN_SLEEPING) {
1074 tcp_con->unsleep = 1;
1075 }
1076
909 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) 1077 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1)
910 return -1; 1078 return -1;
911 1079
@@ -1012,23 +1180,35 @@ static void do_tcp_conns(TCP_Connections *tcp_c)
1012 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1180 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1013 1181
1014 if (tcp_con) { 1182 if (tcp_con) {
1015 do_TCP_connection(tcp_con->connection); 1183 if (tcp_con->status != TCP_CONN_SLEEPING) {
1184 do_TCP_connection(tcp_con->connection);
1185
1186 /* callbacks can change TCP connection address. */
1187 tcp_con = get_tcp_connection(tcp_c, i);
1016 1188
1017 /* callbacks can change TCP connection address. */ 1189 if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) {
1018 tcp_con = get_tcp_connection(tcp_c, i); 1190 if (tcp_con->status == TCP_CONN_CONNECTED) {
1191 reconnect_tcp_relay_connection(tcp_c, i);
1192 } else {
1193 kill_tcp_relay_connection(tcp_c, i);
1194 }
1019 1195
1020 if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { 1196 continue;
1021 if (tcp_con->status == TCP_CONN_CONNECTED) {
1022 reconnect_tcp_relay_connection(tcp_c, i);
1023 } else {
1024 kill_tcp_relay_connection(tcp_c, i);
1025 } 1197 }
1026 1198
1027 continue; 1199 if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) {
1200 tcp_relay_on_online(tcp_c, i);
1201 }
1202
1203 if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion && tcp_con->lock_count
1204 && tcp_con->lock_count == tcp_con->sleep_count
1205 && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
1206 sleep_tcp_relay_connection(tcp_c, i);
1207 }
1028 } 1208 }
1029 1209
1030 if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) { 1210 if (tcp_con->status == TCP_CONN_SLEEPING && tcp_con->unsleep) {
1031 tcp_relay_on_online(tcp_c, i); 1211 unsleep_tcp_relay_connection(tcp_c, i);
1032 } 1212 }
1033 } 1213 }
1034 } 1214 }
diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h
index 0b7aae64..c3cf4889 100644
--- a/toxcore/TCP_connection.h
+++ b/toxcore/TCP_connection.h
@@ -28,8 +28,13 @@
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
@@ -64,7 +69,13 @@ typedef struct {
64 TCP_Client_Connection *connection; 69 TCP_Client_Connection *connection;
65 uint64_t connected_time; 70 uint64_t connected_time;
66 uint32_t lock_count; 71 uint32_t lock_count;
72 uint32_t sleep_count;
67 _Bool onion; 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. */
68} TCP_con; 79} TCP_con;
69 80
70typedef struct { 81typedef struct {
@@ -153,6 +164,18 @@ int new_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key, int
153 */ 164 */
154int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number); 165int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number);
155 166
167/* Set connection status.
168 *
169 * status of 1 means we are using the connection.
170 * status of 0 means we are not using it.
171 *
172 * Unused tcp connections will be disconnected from but kept in case they are needed.
173 *
174 * return 0 on success.
175 * return -1 on failure.
176 */
177int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status);
178
156/* Add a TCP relay tied to a connection. 179/* Add a TCP relay tied to a connection.
157 * 180 *
158 * NOTE: This can only be used during the tcp_oob_callback. 181 * NOTE: This can only be used during the tcp_oob_callback.
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index c7b059cb..1784083b 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -1798,6 +1798,30 @@ static void do_tcp(Net_Crypto *c)
1798 pthread_mutex_lock(&c->tcp_mutex); 1798 pthread_mutex_lock(&c->tcp_mutex);
1799 do_tcp_connections(c->tcp_c); 1799 do_tcp_connections(c->tcp_c);
1800 pthread_mutex_unlock(&c->tcp_mutex); 1800 pthread_mutex_unlock(&c->tcp_mutex);
1801
1802 uint32_t i;
1803
1804 for (i = 0; i < c->crypto_connections_length; ++i) {
1805 Crypto_Connection *conn = get_crypto_connection(c, i);
1806
1807 if (conn == 0)
1808 return;
1809
1810 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
1811 uint8_t direct_connected = 0;
1812 crypto_connection_status(c, i, &direct_connected);
1813
1814 if (direct_connected) {
1815 pthread_mutex_lock(&c->tcp_mutex);
1816 set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0);
1817 pthread_mutex_unlock(&c->tcp_mutex);
1818 } else {
1819 pthread_mutex_lock(&c->tcp_mutex);
1820 set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1);
1821 pthread_mutex_unlock(&c->tcp_mutex);
1822 }
1823 }
1824 }
1801} 1825}
1802 1826
1803/* Set function to be called when connection with crypt_connection_id goes connects/disconnects. 1827/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.