Some optimizations on how TCP relays are used.

This commit is contained in:
irungentoo 2014-12-15 15:21:39 -05:00
parent 7425a0dd09
commit f9f236248d
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
2 changed files with 52 additions and 20 deletions

View File

@ -421,37 +421,48 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
//TODO: detect and kill bad relays.
uint32_t i;
unsigned int r = crypt_connection_id;
unsigned int r;
for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
pthread_mutex_lock(&c->tcp_mutex);
if (!conn->last_relay_sentto) {
r = rand();
} else {
r = conn->last_relay_sentto - 1;
}
int ret = 0;
if (conn->num_tcp_online) {
for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
pthread_mutex_lock(&c->tcp_mutex);
if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
ret = send_data(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->con_number_tcp[(i + r) % MAX_TCP_CONNECTIONS],
data, length);
}
unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS;
int ret = 0;
pthread_mutex_unlock(&c->tcp_mutex);
if (conn->status_tcp[tcp_index] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
ret = send_data(c->tcp_connections[tcp_index], conn->con_number_tcp[tcp_index], data, length);
}
if (ret == 1) {
return 0;
pthread_mutex_unlock(&c->tcp_mutex);
if (ret == 1) {
conn->last_relay_sentto = tcp_index + 1;
return 0;
}
}
}
for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
pthread_mutex_lock(&c->tcp_mutex);
unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS;
int ret = 0;
if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_INVISIBLE) {
ret = send_oob_packet(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->dht_public_key, data, length);
if (conn->status_tcp[tcp_index] == STATUS_TCP_INVISIBLE) {
ret = send_oob_packet(c->tcp_connections[tcp_index], conn->dht_public_key, data, length);
}
pthread_mutex_unlock(&c->tcp_mutex);
if (ret == 1) {
conn->last_relay_sentto = tcp_index + 1;
return 0;
}
}
@ -1595,6 +1606,25 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key)
return crypt_connection_id;
}
/* Set the status for the TCP connection for conn in location to status.
*/
static void set_conn_tcp_status(Crypto_Connection *conn, unsigned int location, unsigned int status)
{
if (conn->status_tcp[location] == status) {
return;
}
if (conn->status_tcp[location] == STATUS_TCP_ONLINE) {
--conn->num_tcp_online;
}
if (status == STATUS_TCP_ONLINE) {
++conn->num_tcp_online;
}
conn->status_tcp[location] = status;
}
/* Disconnect peer from all associated TCP connections.
*
* return -1 on failure.
@ -1613,7 +1643,7 @@ static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
if (conn->status_tcp[i] != STATUS_TCP_NULL) {
pthread_mutex_lock(&c->tcp_mutex);
send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]);
conn->status_tcp[i] = STATUS_TCP_NULL;
set_conn_tcp_status(conn, i, STATUS_TCP_NULL);
conn->con_number_tcp[i] = 0;
pthread_mutex_unlock(&c->tcp_mutex);
}
@ -1769,12 +1799,12 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
for (i = 0; i < conn->num_tcp_relays; ++i) {
if (memcmp(TCP_con->public_key, conn->tcp_relays[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) {
conn->status_tcp[location] = STATUS_TCP_INVISIBLE;
set_conn_tcp_status(conn, location, STATUS_TCP_INVISIBLE);
return 0;
}
}
conn->status_tcp[location] = STATUS_TCP_OFFLINE;
set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE);
return 0;
}
@ -1797,9 +1827,9 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection
return -1;
if (status == 1) {
conn->status_tcp[location] = STATUS_TCP_OFFLINE;
set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE);
} else if (status == 2) {
conn->status_tcp[location] = STATUS_TCP_ONLINE;
set_conn_tcp_status(conn, location, STATUS_TCP_ONLINE);
}
conn->con_number_tcp[location] = connection_id;
@ -1969,7 +1999,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
if (conn->status_tcp[i] == STATUS_TCP_OFFLINE)
conn->status_tcp[i] = STATUS_TCP_INVISIBLE;
set_conn_tcp_status(conn, i, STATUS_TCP_INVISIBLE);
}
}
@ -2173,7 +2203,7 @@ static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number
if (number >= MAX_TCP_CONNECTIONS)
return;
conn->status_tcp[number] = STATUS_TCP_NULL;
set_conn_tcp_status(conn, number, STATUS_TCP_NULL);
conn->con_number_tcp[number] = 0;
}

View File

@ -159,6 +159,8 @@ typedef struct {
uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */
uint8_t con_number_tcp[MAX_TCP_CONNECTIONS];
unsigned int last_relay_sentto;
unsigned int num_tcp_online;
Node_format tcp_relays[MAX_TCP_RELAYS_PEER];
uint16_t num_tcp_relays;