mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
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.
This commit is contained in:
parent
e4ae993a80
commit
0a0ed45202
|
@ -333,6 +333,9 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num
|
|||
if (!tcp_con)
|
||||
return -1;
|
||||
|
||||
if (tcp_con->status != TCP_CONN_CONNECTED)
|
||||
return -1;
|
||||
|
||||
int ret = send_oob_packet(tcp_con->connection, public_key, packet, length);
|
||||
|
||||
if (ret == 1)
|
||||
|
@ -404,8 +407,14 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela
|
|||
TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
|
||||
|
||||
if (tcp_con) {
|
||||
if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
|
||||
return i;
|
||||
if (tcp_con->status == TCP_CONN_SLEEPING) {
|
||||
if (memcmp(tcp_con->relay_pk, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -465,6 +474,10 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
|
|||
|
||||
if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
|
||||
--tcp_con->lock_count;
|
||||
|
||||
if (con_to->status == TCP_CONN_SLEEPING) {
|
||||
--tcp_con->sleep_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -472,6 +485,72 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
|
|||
return wipe_connection(tcp_c, connections_number);
|
||||
}
|
||||
|
||||
/* Set connection status.
|
||||
*
|
||||
* status of 1 means we are using the connection.
|
||||
* status of 0 means we are not using it.
|
||||
*
|
||||
* Unused tcp connections will be disconnected from but kept in case they are needed.
|
||||
*
|
||||
* return 0 on success.
|
||||
* return -1 on failure.
|
||||
*/
|
||||
int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status)
|
||||
{
|
||||
TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
|
||||
|
||||
if (!con_to)
|
||||
return -1;
|
||||
|
||||
if (status) {
|
||||
/* Conection is unsleeping. */
|
||||
if (con_to->status != TCP_CONN_SLEEPING)
|
||||
return -1;
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
|
||||
if (con_to->connections[i].tcp_connection) {
|
||||
unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
|
||||
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
|
||||
|
||||
if (!tcp_con)
|
||||
continue;
|
||||
|
||||
if (tcp_con->status == TCP_CONN_SLEEPING) {
|
||||
tcp_con->unsleep = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
con_to->status = TCP_CONN_VALID;
|
||||
return 0;
|
||||
} else {
|
||||
/* Conection is going to sleep. */
|
||||
if (con_to->status != TCP_CONN_VALID)
|
||||
return -1;
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
|
||||
if (con_to->connections[i].tcp_connection) {
|
||||
unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
|
||||
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
|
||||
|
||||
if (!tcp_con)
|
||||
continue;
|
||||
|
||||
if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
|
||||
++tcp_con->sleep_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
con_to->status = TCP_CONN_SLEEPING;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connections_number)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -606,6 +685,9 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
|
|||
if (!tcp_con)
|
||||
return -1;
|
||||
|
||||
if (tcp_con->status == TCP_CONN_SLEEPING)
|
||||
return -1;
|
||||
|
||||
IP_Port ip_port = tcp_con->connection->ip_port;
|
||||
uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
|
||||
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
|
|||
}
|
||||
|
||||
tcp_con->lock_count = 0;
|
||||
tcp_con->sleep_count = 0;
|
||||
tcp_con->connected_time = 0;
|
||||
tcp_con->status = TCP_CONN_VALID;
|
||||
tcp_con->unsleep = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
|
||||
{
|
||||
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
|
||||
|
||||
if (!tcp_con)
|
||||
return -1;
|
||||
|
||||
if (tcp_con->status != TCP_CONN_CONNECTED)
|
||||
return -1;
|
||||
|
||||
if (tcp_con->lock_count != tcp_con->sleep_count)
|
||||
return -1;
|
||||
|
||||
tcp_con->ip_port = tcp_con->connection->ip_port;
|
||||
memcpy(tcp_con->relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES);
|
||||
|
||||
kill_TCP_connection(tcp_con->connection);
|
||||
tcp_con->connection = NULL;
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < tcp_c->connections_length; ++i) {
|
||||
TCP_Connection_to *con_to = get_connection(tcp_c, i);
|
||||
|
||||
if (con_to) {
|
||||
set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (tcp_con->onion) {
|
||||
--tcp_c->onion_num_conns;
|
||||
tcp_con->onion = 0;
|
||||
}
|
||||
|
||||
tcp_con->lock_count = 0;
|
||||
tcp_con->sleep_count = 0;
|
||||
tcp_con->connected_time = 0;
|
||||
tcp_con->status = TCP_CONN_SLEEPING;
|
||||
tcp_con->unsleep = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
|
||||
{
|
||||
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
|
||||
|
||||
if (!tcp_con)
|
||||
return -1;
|
||||
|
||||
if (tcp_con->status != TCP_CONN_SLEEPING)
|
||||
return -1;
|
||||
|
||||
tcp_con->connection = new_TCP_connection(tcp_con->ip_port, tcp_con->relay_pk, tcp_c->dht->self_public_key,
|
||||
tcp_c->dht->self_secret_key, &tcp_c->proxy_info);
|
||||
|
||||
if (!tcp_con->connection) {
|
||||
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcp_con->lock_count = 0;
|
||||
tcp_con->sleep_count = 0;
|
||||
tcp_con->connected_time = 0;
|
||||
tcp_con->status = TCP_CONN_VALID;
|
||||
tcp_con->unsleep = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send a TCP routing request.
|
||||
*
|
||||
* return 0 on success.
|
||||
|
@ -652,6 +805,9 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec
|
|||
if (!tcp_con)
|
||||
return -1;
|
||||
|
||||
if (tcp_con->status == TCP_CONN_SLEEPING)
|
||||
return -1;
|
||||
|
||||
if (send_routing_request(tcp_con->connection, public_key) != 1)
|
||||
return -1;
|
||||
|
||||
|
@ -704,11 +860,19 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection
|
|||
return -1;
|
||||
|
||||
--tcp_con->lock_count;
|
||||
|
||||
if (con_to->status == TCP_CONN_SLEEPING) {
|
||||
--tcp_con->sleep_count;
|
||||
}
|
||||
} else if (status == 2) {
|
||||
if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1)
|
||||
return -1;
|
||||
|
||||
++tcp_con->lock_count;
|
||||
|
||||
if (con_to->status == TCP_CONN_SLEEPING) {
|
||||
++tcp_con->sleep_count;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -906,6 +1070,10 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb
|
|||
if (!tcp_con)
|
||||
return -1;
|
||||
|
||||
if (con_to->status != TCP_CONN_SLEEPING && tcp_con->status == TCP_CONN_SLEEPING) {
|
||||
tcp_con->unsleep = 1;
|
||||
}
|
||||
|
||||
if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1)
|
||||
return -1;
|
||||
|
||||
|
@ -1012,23 +1180,35 @@ static void do_tcp_conns(TCP_Connections *tcp_c)
|
|||
TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
|
||||
|
||||
if (tcp_con) {
|
||||
do_TCP_connection(tcp_con->connection);
|
||||
if (tcp_con->status != TCP_CONN_SLEEPING) {
|
||||
do_TCP_connection(tcp_con->connection);
|
||||
|
||||
/* callbacks can change TCP connection address. */
|
||||
tcp_con = get_tcp_connection(tcp_c, i);
|
||||
/* callbacks can change TCP connection address. */
|
||||
tcp_con = get_tcp_connection(tcp_c, i);
|
||||
|
||||
if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) {
|
||||
if (tcp_con->status == TCP_CONN_CONNECTED) {
|
||||
reconnect_tcp_relay_connection(tcp_c, i);
|
||||
} else {
|
||||
kill_tcp_relay_connection(tcp_c, i);
|
||||
if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) {
|
||||
if (tcp_con->status == TCP_CONN_CONNECTED) {
|
||||
reconnect_tcp_relay_connection(tcp_c, i);
|
||||
} else {
|
||||
kill_tcp_relay_connection(tcp_c, i);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
continue;
|
||||
if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) {
|
||||
tcp_relay_on_online(tcp_c, i);
|
||||
}
|
||||
|
||||
if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion && tcp_con->lock_count
|
||||
&& tcp_con->lock_count == tcp_con->sleep_count
|
||||
&& is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
|
||||
sleep_tcp_relay_connection(tcp_c, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) {
|
||||
tcp_relay_on_online(tcp_c, i);
|
||||
if (tcp_con->status == TCP_CONN_SLEEPING && tcp_con->unsleep) {
|
||||
unsleep_tcp_relay_connection(tcp_c, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,13 @@
|
|||
|
||||
#define TCP_CONN_NONE 0
|
||||
#define TCP_CONN_VALID 1
|
||||
|
||||
/* NOTE: only used by TCP_con */
|
||||
#define TCP_CONN_CONNECTED 2
|
||||
|
||||
/* Connection is not connected but can be quickly reconnected in case it is needed. */
|
||||
#define TCP_CONN_SLEEPING 3
|
||||
|
||||
#define TCP_CONNECTIONS_STATUS_NONE 0
|
||||
#define TCP_CONNECTIONS_STATUS_REGISTERED 1
|
||||
#define TCP_CONNECTIONS_STATUS_ONLINE 2
|
||||
|
@ -64,7 +69,13 @@ typedef struct {
|
|||
TCP_Client_Connection *connection;
|
||||
uint64_t connected_time;
|
||||
uint32_t lock_count;
|
||||
uint32_t sleep_count;
|
||||
_Bool onion;
|
||||
|
||||
/* Only used when connection is sleeping. */
|
||||
IP_Port ip_port;
|
||||
uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
|
||||
_Bool unsleep; /* set to 1 to unsleep connection. */
|
||||
} TCP_con;
|
||||
|
||||
typedef struct {
|
||||
|
@ -153,6 +164,18 @@ int new_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key, int
|
|||
*/
|
||||
int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number);
|
||||
|
||||
/* Set connection status.
|
||||
*
|
||||
* status of 1 means we are using the connection.
|
||||
* status of 0 means we are not using it.
|
||||
*
|
||||
* Unused tcp connections will be disconnected from but kept in case they are needed.
|
||||
*
|
||||
* return 0 on success.
|
||||
* return -1 on failure.
|
||||
*/
|
||||
int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status);
|
||||
|
||||
/* Add a TCP relay tied to a connection.
|
||||
*
|
||||
* NOTE: This can only be used during the tcp_oob_callback.
|
||||
|
|
|
@ -1798,6 +1798,30 @@ static void do_tcp(Net_Crypto *c)
|
|||
pthread_mutex_lock(&c->tcp_mutex);
|
||||
do_tcp_connections(c->tcp_c);
|
||||
pthread_mutex_unlock(&c->tcp_mutex);
|
||||
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < c->crypto_connections_length; ++i) {
|
||||
Crypto_Connection *conn = get_crypto_connection(c, i);
|
||||
|
||||
if (conn == 0)
|
||||
return;
|
||||
|
||||
if (conn->status == CRYPTO_CONN_ESTABLISHED) {
|
||||
uint8_t direct_connected = 0;
|
||||
crypto_connection_status(c, i, &direct_connected);
|
||||
|
||||
if (direct_connected) {
|
||||
pthread_mutex_lock(&c->tcp_mutex);
|
||||
set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0);
|
||||
pthread_mutex_unlock(&c->tcp_mutex);
|
||||
} else {
|
||||
pthread_mutex_lock(&c->tcp_mutex);
|
||||
set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1);
|
||||
pthread_mutex_unlock(&c->tcp_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
|
||||
|
|
Loading…
Reference in New Issue
Block a user