From 3e256e429f6b2d3b8d3b49c1beac62f3b2f138ee Mon Sep 17 00:00:00 2001 From: irungentoo Date: Fri, 24 Apr 2015 11:09:42 -0400 Subject: [PATCH] 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. --- toxcore/Messenger.c | 19 ++++++++++++++++--- toxcore/Messenger.h | 3 ++- toxcore/TCP_connection.c | 13 +++++++++++++ toxcore/TCP_connection.h | 5 +++++ toxcore/net_crypto.c | 30 +++++++++++++++++++----------- toxcore/net_crypto.h | 8 ++++---- 6 files changed, 59 insertions(+), 19 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index efb66961..fd17ab98 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -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); diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index c9573639..5221e639 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -109,7 +109,8 @@ enum { enum { CONNECTION_NONE, CONNECTION_TCP, - CONNECTION_UDP + CONNECTION_UDP, + CONNECTION_UNKNOWN }; /* USERSTATUS - diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index 7b478611..fe39dc52 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c @@ -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. * diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index 3f7b616d..29fbdee0 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h @@ -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. diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index b6b1050a..ab0fb03a 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -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; } diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index f6dd4702..9eb5e2d3 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -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.