diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 8af3cbbc..112931ad 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2039,29 +2039,50 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key) return -1; } -/* Send an onion packet via a random connected TCP relay. +/* Return a random TCP connection number for use in send_tcp_onion_request. * - * return 0 on success. + * TODO: This number is just the index of an array that the elements can + * change without warning. + * + * return TCP connection number on success. * return -1 on failure. */ -int send_tcp_onion_request(Net_Crypto *c, const uint8_t *data, uint16_t length) +int get_random_tcp_con_number(Net_Crypto *c) { unsigned int i, r = rand(); for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { if (c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS]) { - pthread_mutex_lock(&c->tcp_mutex); - int ret = send_onion_request(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], data, length); - pthread_mutex_unlock(&c->tcp_mutex); - - if (ret == 1) - return 0; + return (i + r) % MAX_TCP_CONNECTIONS; } } return -1; } +/* Send an onion packet via the TCP relay corresponding to TCP_conn_number. + * + * return 0 on success. + * return -1 on failure. + */ +int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const uint8_t *data, uint16_t length) +{ + if (TCP_conn_number > MAX_TCP_CONNECTIONS) { + return -1; + } + + if (c->tcp_connections[TCP_conn_number]) { + pthread_mutex_lock(&c->tcp_mutex); + int ret = send_onion_request(c->tcp_connections[TCP_conn_number], data, length); + pthread_mutex_unlock(&c->tcp_mutex); + + if (ret == 1) + return 0; + } + + return -1; +} + /* Set the function to be called when an onion response packet is received by one of the TCP connections. */ void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data, diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index b9fb1747..9d699340 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -364,12 +364,19 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key); void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length), void *object); -/* Send an onion packet via a random connected TCP relay. +/* Return a random TCP connection number for use in send_tcp_onion_request. + * + * return TCP connection number on success. + * return -1 on failure. + */ +int get_random_tcp_con_number(Net_Crypto *c); + +/* Send an onion packet via the TCP relay corresponding to TCP_conn_number. * * return 0 on success. * return -1 on failure. */ -int send_tcp_onion_request(Net_Crypto *c, const uint8_t *data, uint16_t length); +int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const uint8_t *data, uint16_t length); /* Copy a maximum of 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/onion_client.c b/toxcore/onion_client.c index f8d7630b..a9eb16a0 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -140,8 +140,15 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format nodes[i] = onion_c->path_nodes[rand() % num_nodes]; } } else { + int random_tcp = get_random_tcp_con_number(onion_c->c); + + if (random_tcp == -1) { + return 0; + } + if (num_nodes >= 2) { nodes[0].ip_port.ip.family = TCP_FAMILY; + nodes[0].ip_port.ip.ip4.uint32 = random_tcp; for (i = 1; i < max_num; ++i) { nodes[i] = onion_c->path_nodes[rand() % num_nodes]; @@ -154,6 +161,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format return 0; nodes[0].ip_port.ip.family = TCP_FAMILY; + nodes[0].ip_port.ip.ip4.uint32 = random_tcp; for (i = 1; i < max_num; ++i) { nodes[i] = onion_c->path_nodes_bs[rand() % num_nodes_bs]; @@ -301,7 +309,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa if (len == -1) return -1; - return send_tcp_onion_request(onion_c->c, packet, len); + return send_tcp_onion_request(onion_c->c, path->ip_port1.ip.ip4.uint32, packet, len); } else { return -1; }