Fixed a couple possible issues with the friend connection callback.

A TCP callback could be received when only a UDP connection was present.

Increased a UDP timeout to make it less likely to time out and switch to TCP.
This commit is contained in:
irungentoo 2015-04-24 11:09:42 -04:00
parent e24d57d467
commit 3e256e429f
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
6 changed files with 59 additions and 19 deletions

View File

@ -433,14 +433,19 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber)
return -1;
if (m->friendlist[friendnumber].status == FRIEND_ONLINE) {
uint8_t direct_connected = 0;
_Bool direct_connected = 0;
unsigned int num_online_relays = 0;
crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c,
m->friendlist[friendnumber].friendcon_id), &direct_connected);
m->friendlist[friendnumber].friendcon_id), &direct_connected, &num_online_relays);
if (direct_connected) {
return CONNECTION_UDP;
} else {
return CONNECTION_TCP;
if (num_online_relays) {
return CONNECTION_TCP;
} else {
return CONNECTION_UNKNOWN;
}
}
} else {
return CONNECTION_NONE;
@ -851,6 +856,14 @@ static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber)
if (ret == -1)
return;
if (ret == CONNECTION_UNKNOWN) {
if (last_connection_udp_tcp == CONNECTION_UDP) {
return;
} else {
ret = CONNECTION_TCP;
}
}
if (last_connection_udp_tcp != ret) {
if (m->friend_connectionstatuschange)
m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata);

View File

@ -109,7 +109,8 @@ enum {
enum {
CONNECTION_NONE,
CONNECTION_TCP,
CONNECTION_UDP
CONNECTION_UDP,
CONNECTION_UNKNOWN
};
/* USERSTATUS -

View File

@ -1124,6 +1124,19 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
}
}
/* return number of online tcp relays tied to the connection on success.
* return 0 on failure.
*/
unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number)
{
TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
if (!con_to)
return 0;
return online_tcp_connection_from_conn(con_to);
}
/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
* NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
*

View File

@ -186,6 +186,11 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number);
*/
int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status);
/* return number of online tcp relays tied to the connection on success.
* return 0 on failure.
*/
unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number);
/* Add a TCP relay tied to a connection.
*
* NOTE: This can only be used during the tcp_oob_callback.

View File

@ -404,8 +404,8 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
//TODO: on bad networks, direct connections might not last indefinitely.
if (conn->ip_port.ip.family != 0) {
uint8_t direct_connected = 0;
crypto_connection_status(c, crypt_connection_id, &direct_connected);
_Bool direct_connected = 0;
crypto_connection_status(c, crypt_connection_id, &direct_connected, NULL);
if (direct_connected) {
if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) {
@ -1446,7 +1446,7 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
conn->ip_port = source;
}
conn->direct_lastrecv_time = current_time_monotonic();
conn->direct_lastrecv_time = unix_time();
return 0;
} else if (source.ip.family == TCP_FAMILY) {
if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip6.uint32[0]) == 0)
@ -1646,7 +1646,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
return -1;
if (!ipport_equal(&ip_port, &conn->ip_port)) {
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) {
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time()) {
if (LAN_ip(ip_port.ip) == 0 && LAN_ip(conn->ip_port.ip) == 0 && conn->ip_port.port == ip_port.port)
return -1;
}
@ -1810,8 +1810,8 @@ static void do_tcp(Net_Crypto *c)
return;
if (conn->status == CRYPTO_CONN_ESTABLISHED) {
uint8_t direct_connected = 0;
crypto_connection_status(c, i, &direct_connected);
_Bool direct_connected = 0;
crypto_connection_status(c, i, &direct_connected, NULL);
if (direct_connected) {
pthread_mutex_lock(&c->tcp_mutex);
@ -1966,7 +1966,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
return -1;
pthread_mutex_lock(&conn->mutex);
conn->direct_lastrecv_time = current_time_monotonic();
conn->direct_lastrecv_time = unix_time();
pthread_mutex_unlock(&conn->mutex);
return 0;
}
@ -2290,18 +2290,26 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
/* return one of CRYPTO_CONN_* values indicating the state of the connection.
*
* sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
* sets online_tcp_relays to the number of connected tcp relays this connection has.
*/
unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected)
unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected,
unsigned int *online_tcp_relays)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == 0)
return CRYPTO_CONN_NO_CONNECTION;
*direct_connected = 0;
if (direct_connected) {
*direct_connected = 0;
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic())
*direct_connected = 1;
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time())
*direct_connected = 1;
}
if (online_tcp_relays) {
*online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp);
}
return conn->status;
}

View File

@ -60,7 +60,7 @@
#define MAX_NUM_SENDPACKET_TRIES 8
/* The timeout of no received UDP packets before the direct UDP connection is considered dead. */
#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 2)
#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 1000)
#define PACKET_ID_PADDING 0 /* Denotes padding */
#define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */
@ -360,13 +360,13 @@ unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, u
*/
int crypto_kill(Net_Crypto *c, int crypt_connection_id);
/* return one of CRYPTO_CONN_* values indicating the state of the connection.
*
* sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
* sets online_tcp_relays to the number of connected tcp relays this connection has.
*/
unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected);
unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected,
unsigned int *online_tcp_relays);
/* Generate our public and private keys.
* Only call this function the first time the program starts.