summaryrefslogtreecommitdiff
path: root/toxcore/TCP_connection.c
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/TCP_connection.c
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/TCP_connection.c')
-rw-r--r--toxcore/TCP_connection.c206
1 files changed, 193 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 }