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)
|
if (!tcp_con)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (tcp_con->status != TCP_CONN_CONNECTED)
|
||||||
|
return -1;
|
||||||
|
|
||||||
int ret = send_oob_packet(tcp_con->connection, public_key, packet, length);
|
int ret = send_oob_packet(tcp_con->connection, public_key, packet, length);
|
||||||
|
|
||||||
if (ret == 1)
|
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);
|
TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
|
||||||
|
|
||||||
if (tcp_con) {
|
if (tcp_con) {
|
||||||
if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
|
if (tcp_con->status == TCP_CONN_SLEEPING) {
|
||||||
return i;
|
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) {
|
if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
|
||||||
--tcp_con->lock_count;
|
--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);
|
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)
|
static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connections_number)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -606,6 +685,9 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
|
||||||
if (!tcp_con)
|
if (!tcp_con)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (tcp_con->status == TCP_CONN_SLEEPING)
|
||||||
|
return -1;
|
||||||
|
|
||||||
IP_Port ip_port = tcp_con->connection->ip_port;
|
IP_Port ip_port = tcp_con->connection->ip_port;
|
||||||
uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
|
uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
|
||||||
memcpy(relay_pk, tcp_con->connection->public_key, 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->lock_count = 0;
|
||||||
|
tcp_con->sleep_count = 0;
|
||||||
tcp_con->connected_time = 0;
|
tcp_con->connected_time = 0;
|
||||||
tcp_con->status = TCP_CONN_VALID;
|
tcp_con->status = TCP_CONN_VALID;
|
||||||
|
tcp_con->unsleep = 0;
|
||||||
|
|
||||||
return 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.
|
/* Send a TCP routing request.
|
||||||
*
|
*
|
||||||
* return 0 on success.
|
* 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)
|
if (!tcp_con)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (tcp_con->status == TCP_CONN_SLEEPING)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (send_routing_request(tcp_con->connection, public_key) != 1)
|
if (send_routing_request(tcp_con->connection, public_key) != 1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -704,11 +860,19 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
--tcp_con->lock_count;
|
--tcp_con->lock_count;
|
||||||
|
|
||||||
|
if (con_to->status == TCP_CONN_SLEEPING) {
|
||||||
|
--tcp_con->sleep_count;
|
||||||
|
}
|
||||||
} else if (status == 2) {
|
} else if (status == 2) {
|
||||||
if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1)
|
if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
++tcp_con->lock_count;
|
++tcp_con->lock_count;
|
||||||
|
|
||||||
|
if (con_to->status == TCP_CONN_SLEEPING) {
|
||||||
|
++tcp_con->sleep_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -906,6 +1070,10 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb
|
||||||
if (!tcp_con)
|
if (!tcp_con)
|
||||||
return -1;
|
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)
|
if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1)
|
||||||
return -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);
|
TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
|
||||||
|
|
||||||
if (tcp_con) {
|
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. */
|
/* callbacks can change TCP connection address. */
|
||||||
tcp_con = get_tcp_connection(tcp_c, i);
|
tcp_con = get_tcp_connection(tcp_c, i);
|
||||||
|
|
||||||
if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) {
|
if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) {
|
||||||
if (tcp_con->status == TCP_CONN_CONNECTED) {
|
if (tcp_con->status == TCP_CONN_CONNECTED) {
|
||||||
reconnect_tcp_relay_connection(tcp_c, i);
|
reconnect_tcp_relay_connection(tcp_c, i);
|
||||||
} else {
|
} else {
|
||||||
kill_tcp_relay_connection(tcp_c, i);
|
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) {
|
if (tcp_con->status == TCP_CONN_SLEEPING && tcp_con->unsleep) {
|
||||||
tcp_relay_on_online(tcp_c, i);
|
unsleep_tcp_relay_connection(tcp_c, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,13 @@
|
||||||
|
|
||||||
#define TCP_CONN_NONE 0
|
#define TCP_CONN_NONE 0
|
||||||
#define TCP_CONN_VALID 1
|
#define TCP_CONN_VALID 1
|
||||||
|
|
||||||
|
/* NOTE: only used by TCP_con */
|
||||||
#define TCP_CONN_CONNECTED 2
|
#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_NONE 0
|
||||||
#define TCP_CONNECTIONS_STATUS_REGISTERED 1
|
#define TCP_CONNECTIONS_STATUS_REGISTERED 1
|
||||||
#define TCP_CONNECTIONS_STATUS_ONLINE 2
|
#define TCP_CONNECTIONS_STATUS_ONLINE 2
|
||||||
|
@ -64,7 +69,13 @@ typedef struct {
|
||||||
TCP_Client_Connection *connection;
|
TCP_Client_Connection *connection;
|
||||||
uint64_t connected_time;
|
uint64_t connected_time;
|
||||||
uint32_t lock_count;
|
uint32_t lock_count;
|
||||||
|
uint32_t sleep_count;
|
||||||
_Bool onion;
|
_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;
|
} TCP_con;
|
||||||
|
|
||||||
typedef struct {
|
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);
|
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.
|
/* Add a TCP relay tied to a connection.
|
||||||
*
|
*
|
||||||
* NOTE: This can only be used during the tcp_oob_callback.
|
* 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);
|
pthread_mutex_lock(&c->tcp_mutex);
|
||||||
do_tcp_connections(c->tcp_c);
|
do_tcp_connections(c->tcp_c);
|
||||||
pthread_mutex_unlock(&c->tcp_mutex);
|
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.
|
/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user