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->self_public_key, tcp_c->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; }
static int reconnect_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; } IP_Port ip_port = tcp_con_ip_port(tcp_con->connection); uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE]; memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); kill_TCP_connection(tcp_con->connection); tcp_con->connection = new_TCP_connection(ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (!tcp_con->connection) { kill_tcp_relay_connection(tcp_c, tcp_connections_number); return -1; } 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_VALID; tcp_con->unsleep = 0; return 0; }
static void do_tcp_conns(TCP_Connections *tcp_c, void *userdata) { unsigned int i; for (i = 0; i < tcp_c->tcp_connections_length; ++i) { TCP_con *tcp_con = get_tcp_connection(tcp_c, i); if (tcp_con) { if (tcp_con->status != TCP_CONN_SLEEPING) { do_TCP_connection(tcp_con->connection, userdata); /* callbacks can change TCP connection address. */ tcp_con = get_tcp_connection(tcp_c, i); // Make sure the TCP connection wasn't dropped in any of the callbacks. assert(tcp_con != nullptr); if (tcp_con_status(tcp_con->connection) == 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; } if (tcp_con->status == TCP_CONN_VALID && tcp_con_status(tcp_con->connection) == 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_SLEEPING && tcp_con->unsleep) { unsleep_tcp_relay_connection(tcp_c, i); } } } }
static void kill_nonused_tcp(TCP_Connections *tcp_c) { unsigned int i, num_online = 0; for (i = 0; i < tcp_c->tcp_connections_length; ++i) { TCP_con *tcp_con = get_tcp_connection(tcp_c, i); if (tcp_con) { if (tcp_con->status == TCP_CONN_CONNECTED) { if (!tcp_con->lock_count && num_online >= MAX_FRIEND_TCP_CONNECTIONS) { kill_tcp_relay_connection(tcp_c, i); continue; } ++num_online; } } } }
static void kill_nonused_tcp(TCP_Connections *tcp_c) { if (tcp_c->tcp_connections_length == 0) { return; } unsigned int i; unsigned int num_online = 0; unsigned int num_kill = 0; VLA(unsigned int, to_kill, tcp_c->tcp_connections_length); for (i = 0; i < tcp_c->tcp_connections_length; ++i) { TCP_con *tcp_con = get_tcp_connection(tcp_c, i); if (tcp_con) { if (tcp_con->status == TCP_CONN_CONNECTED) { if (!tcp_con->onion && !tcp_con->lock_count && mono_time_is_timeout(tcp_c->mono_time, tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) { to_kill[num_kill] = i; ++num_kill; } ++num_online; } } } if (num_online <= RECOMMENDED_FRIEND_TCP_CONNECTIONS) { return; } unsigned int n = num_online - RECOMMENDED_FRIEND_TCP_CONNECTIONS; if (n < num_kill) { num_kill = n; } for (i = 0; i < num_kill; ++i) { kill_tcp_relay_connection(tcp_c, to_kill[i]); } }
static void do_tcp_conns(TCP_Connections *tcp_c) { unsigned int i; for (i = 0; i < tcp_c->tcp_connections_length; ++i) { TCP_con *tcp_con = get_tcp_connection(tcp_c, i); if (tcp_con) { do_TCP_connection(tcp_con->connection); if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { kill_tcp_relay_connection(tcp_c, i); continue; } if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) { tcp_relay_on_online(tcp_c, i); } } } }