2023-07-25 11:53:09 +02:00
|
|
|
/* Auto Tests: Many TCP.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include "../testing/misc_tools.h"
|
|
|
|
#include "../toxcore/crypto_core.h"
|
|
|
|
#include "../toxcore/tox.h"
|
|
|
|
#include "../toxcore/util.h"
|
|
|
|
#include "auto_test_support.h"
|
|
|
|
#include "check_compat.h"
|
|
|
|
|
|
|
|
/* The Travis-CI container responds poorly to ::1 as a localhost address
|
|
|
|
* You're encouraged to -D FORCE_TESTS_IPV6 on a local test */
|
|
|
|
#ifdef FORCE_TESTS_IPV6
|
|
|
|
#define TOX_LOCALHOST "::1"
|
|
|
|
#else
|
|
|
|
#define TOX_LOCALHOST "127.0.0.1"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static bool enable_broken_tests = false;
|
|
|
|
|
|
|
|
static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
|
|
|
|
{
|
|
|
|
if (*((uint32_t *)userdata) != 974536) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
|
|
|
|
tox_friend_add_norequest(m, public_key, nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NUM_FRIENDS 50
|
|
|
|
#define NUM_TOXES_TCP 40
|
|
|
|
|
|
|
|
static uint16_t tcp_relay_port = 33448;
|
|
|
|
|
|
|
|
static void test_many_clients_tcp(void)
|
|
|
|
{
|
|
|
|
const Random *rng = system_random();
|
|
|
|
ck_assert(rng != nullptr);
|
|
|
|
long long unsigned int cur_time = time(nullptr);
|
|
|
|
Tox *toxes[NUM_TOXES_TCP];
|
|
|
|
uint32_t index[NUM_TOXES_TCP];
|
|
|
|
uint32_t to_comp = 974536;
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
2023-07-25 11:53:09 +02:00
|
|
|
struct Tox_Options *opts = tox_options_new(nullptr);
|
|
|
|
|
|
|
|
if (i == 0) {
|
|
|
|
tox_options_set_tcp_port(opts, tcp_relay_port);
|
|
|
|
} else {
|
|
|
|
tox_options_set_udp_enabled(opts, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
index[i] = i + 1;
|
|
|
|
Tox_Err_New err;
|
|
|
|
toxes[i] = tox_new_log(opts, &err, &index[i]);
|
|
|
|
if (i == 0 && err == TOX_ERR_NEW_PORT_ALLOC) {
|
|
|
|
ck_assert(toxes[i] == nullptr);
|
|
|
|
--i;
|
|
|
|
++tcp_relay_port;
|
|
|
|
tox_options_free(opts);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i);
|
|
|
|
tox_callback_friend_request(toxes[i], accept_friend_request);
|
|
|
|
uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
|
|
|
|
tox_self_get_dht_id(toxes[0], dpk);
|
2023-10-10 19:37:39 +02:00
|
|
|
Tox_Err_Bootstrap error;
|
2023-07-25 11:53:09 +02:00
|
|
|
ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port, dpk, &error), "add relay error, %u, %d", i,
|
|
|
|
error);
|
|
|
|
uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr);
|
|
|
|
ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, first_port, dpk, nullptr), "Bootstrap error");
|
|
|
|
|
|
|
|
tox_options_free(opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct {
|
|
|
|
uint16_t tox1;
|
|
|
|
uint16_t tox2;
|
|
|
|
} pairs[NUM_FRIENDS];
|
|
|
|
|
|
|
|
uint8_t address[TOX_ADDRESS_SIZE];
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_FRIENDS; ++i) {
|
2023-07-25 11:53:09 +02:00
|
|
|
loop_top:
|
|
|
|
pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP;
|
|
|
|
pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t j = 0; j < i; ++j) {
|
2023-07-25 11:53:09 +02:00
|
|
|
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
|
|
|
|
goto loop_top;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tox_self_get_address(toxes[pairs[i].tox1], address);
|
|
|
|
|
|
|
|
Tox_Err_Friend_Add test;
|
|
|
|
uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test);
|
|
|
|
|
|
|
|
if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) {
|
|
|
|
goto loop_top;
|
|
|
|
}
|
|
|
|
|
|
|
|
ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
uint16_t counter = 0;
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
|
|
|
for (uint32_t j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) {
|
2023-07-25 11:53:09 +02:00
|
|
|
if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) {
|
|
|
|
++counter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter == NUM_FRIENDS * 2) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
2023-07-25 11:53:09 +02:00
|
|
|
tox_iterate(toxes[i], &to_comp);
|
|
|
|
}
|
|
|
|
|
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
2023-07-25 11:53:09 +02:00
|
|
|
tox_kill(toxes[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("test_many_clients_tcp succeeded, took %llu seconds\n", time(nullptr) - cur_time);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NUM_TCP_RELAYS 3
|
|
|
|
|
|
|
|
static void test_many_clients_tcp_b(void)
|
|
|
|
{
|
|
|
|
const Random *rng = system_random();
|
|
|
|
ck_assert(rng != nullptr);
|
|
|
|
long long unsigned int cur_time = time(nullptr);
|
|
|
|
Tox *toxes[NUM_TOXES_TCP];
|
|
|
|
uint32_t index[NUM_TOXES_TCP];
|
|
|
|
uint32_t to_comp = 974536;
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
2023-07-25 11:53:09 +02:00
|
|
|
struct Tox_Options *opts = tox_options_new(nullptr);
|
|
|
|
|
|
|
|
if (i < NUM_TCP_RELAYS) {
|
|
|
|
tox_options_set_tcp_port(opts, tcp_relay_port + i);
|
|
|
|
} else {
|
|
|
|
tox_options_set_udp_enabled(opts, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
index[i] = i + 1;
|
|
|
|
toxes[i] = tox_new_log(opts, nullptr, &index[i]);
|
|
|
|
ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i);
|
|
|
|
tox_callback_friend_request(toxes[i], accept_friend_request);
|
|
|
|
uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
|
|
|
|
tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk);
|
|
|
|
ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port + (i % NUM_TCP_RELAYS), dpk, nullptr),
|
|
|
|
"add relay error");
|
|
|
|
tox_self_get_dht_id(toxes[0], dpk);
|
|
|
|
uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr);
|
|
|
|
ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, first_port, dpk, nullptr), "Bootstrap error");
|
|
|
|
|
|
|
|
tox_options_free(opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct {
|
|
|
|
uint16_t tox1;
|
|
|
|
uint16_t tox2;
|
|
|
|
} pairs[NUM_FRIENDS];
|
|
|
|
|
|
|
|
uint8_t address[TOX_ADDRESS_SIZE];
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_FRIENDS; ++i) {
|
2023-07-25 11:53:09 +02:00
|
|
|
loop_top:
|
|
|
|
pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP;
|
|
|
|
pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t j = 0; j < i; ++j) {
|
2023-07-25 11:53:09 +02:00
|
|
|
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
|
|
|
|
goto loop_top;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tox_self_get_address(toxes[pairs[i].tox1], address);
|
|
|
|
|
|
|
|
Tox_Err_Friend_Add test;
|
|
|
|
uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test);
|
|
|
|
|
|
|
|
if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) {
|
|
|
|
goto loop_top;
|
|
|
|
}
|
|
|
|
|
|
|
|
ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t last_count = 0;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
uint16_t counter = 0;
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
|
|
|
for (uint32_t j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) {
|
2023-07-25 11:53:09 +02:00
|
|
|
if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) {
|
|
|
|
++counter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter != last_count) {
|
|
|
|
printf("many_clients_tcp_b got to %u\n", counter);
|
|
|
|
last_count = counter;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter == NUM_FRIENDS * 2) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
2023-07-25 11:53:09 +02:00
|
|
|
tox_iterate(toxes[i], &to_comp);
|
|
|
|
}
|
|
|
|
|
|
|
|
c_sleep(30);
|
|
|
|
}
|
|
|
|
|
2023-10-10 19:37:39 +02:00
|
|
|
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
2023-07-25 11:53:09 +02:00
|
|
|
tox_kill(toxes[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void tox_suite(void)
|
|
|
|
{
|
|
|
|
/* Each tox connects to a single tox TCP */
|
|
|
|
test_many_clients_tcp();
|
|
|
|
|
|
|
|
if (enable_broken_tests) {
|
|
|
|
/* Try to make a connection to each "older sibling" tox instance via TCP */
|
|
|
|
/* Currently this test intermittently fails for unknown reasons. */
|
|
|
|
test_many_clients_tcp_b();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
{
|
|
|
|
setvbuf(stdout, nullptr, _IONBF, 0);
|
|
|
|
tox_suite();
|
|
|
|
return 0;
|
|
|
|
}
|