Browse Source

tests: allocate live and blackhole multilink endpoints dynamically

master
evgeny 7 days ago
parent
commit
e836090a02
  1. 70
      tests/test_etcp_link_stress.c

70
tests/test_etcp_link_stress.c

@ -5,6 +5,7 @@
#include <string.h>
#include "../lib/platform_compat.h"
#include "test_utils.h"
#include "test_net.h"
#include "etcp.h"
#include "etcp_api.h"
@ -38,7 +39,8 @@ static char server_config_path[256];
static char client_config_path[256];
static int server_port = 0;
static int client_port = 0;
static int next_port = 0;
static socket_t dead_sockets[3] = {SOCKET_INVALID, SOCKET_INVALID, SOCKET_INVALID};
static unsigned dead_socket_count;
static uint32_t packets_sent = 0;
static uint32_t packets_received = 0;
@ -52,10 +54,6 @@ static int traffic_corrupt = 0;
static int create_temp_configs(void) {
if (test_mkdtemp(temp_dir) != 0) { fprintf(stderr, "Failed to create temp directory\n"); return -1; }
int base_port = 50000 + (getpid() % 15000);
server_port = base_port;
client_port = base_port + 1;
next_port = base_port + 100;
snprintf(server_config_path, sizeof(server_config_path), "%s/server.conf", temp_dir);
snprintf(client_config_path, sizeof(client_config_path), "%s/client.conf", temp_dir);
@ -73,12 +71,11 @@ static int create_temp_configs(void) {
"keepalive_adaptive=0\n"
"\n"
"[server: udp0]\n"
"addr=127.0.0.1:%d\n"
"addr=127.0.0.1:0\n"
"type=public\n"
"\n"
"[allowed_keys]\n"
"allow_all=1\n",
server_port);
"allow_all=1\n");
fclose(f);
f = fopen(client_config_path, "w");
@ -94,17 +91,16 @@ static int create_temp_configs(void) {
"keepalive_adaptive=0\n"
"\n"
"[server: udp0]\n"
"addr=127.0.0.1:%d\n"
"addr=127.0.0.1:0\n"
"type=public\n"
"\n"
"[client: test_client]\n"
"keepalive=1\n"
"peer_public_key=ce8871f07fa056c636d297115f231b08c29cdf94e0d440fce83a07c34416d36a\n"
"link=udp0:127.0.0.1:%d\n"
"link=udp0:127.0.0.1:0\n"
"\n"
"[allowed_keys]\n"
"allow_all=1\n",
client_port, server_port);
"allow_all=1\n");
fclose(f);
return 0;
}
@ -148,15 +144,28 @@ static void mk_addr(struct sockaddr_storage* out, uint16_t port) {
sin->sin_port = htons(port);
}
static int alloc_port(void) { return next_port++; }
// Чёрная дыра не читает INIT; удерживаем её порт, чтобы другой параллельный тест не ответил вместо неё.
static int alloc_dead_port(void) {
if (dead_socket_count == 3) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "test: too many dead endpoints"); abort(); }
socket_t sock = socket_create_udp(AF_INET);
if (sock == SOCKET_INVALID) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "test: dead socket creation failed"); abort(); }
struct sockaddr_storage address; mk_addr(&address, 0);
if (bind(sock, (struct sockaddr*)&address, sizeof(struct sockaddr_in)) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "test: dead socket bind failed err=%d", socket_get_error()); abort();
}
dead_sockets[dead_socket_count++] = sock;
return test_bound_port(sock);
}
static struct ETCP_SOCKET* add_udp_socket(struct UTUN_INSTANCE* inst, uint16_t port, const char* name) {
static struct ETCP_SOCKET* add_udp_socket(struct UTUN_INSTANCE* inst, int* port, const char* name) {
struct CFG_SERVER cfg; memset(&cfg, 0, sizeof(cfg));
snprintf(cfg.name, sizeof(cfg.name), "%s", name);
cfg.type = CFG_SERVER_TYPE_PUBLIC;
cfg.mtu = PACKET_DATA_MAX_MTU;
mk_addr(&cfg.ip, port);
return etcp_socket_add(inst, &cfg);
mk_addr(&cfg.ip, 0);
struct ETCP_SOCKET* sock = etcp_socket_add(inst, &cfg);
if (sock) *port = ss_get_port(&sock->local_addr);
return sock;
}
static struct ETCP_LINK* find_link_by_remote_port(struct ETCP_CONN* conn, uint16_t port) {
@ -361,10 +370,13 @@ static int start_instances(void) {
printf("failed to create server\n"); return -1;
}
client_instance = utun_instance_create(ua, client_config_path);
if (client_instance) test_etcp_set_peer(client_instance, "test_client", server_instance, "udp0");
if (!client_instance || utun_instance_init(client_instance) < 0) {
printf("failed to create client\n"); return -1;
}
etcp_bind(server_instance, 0x7f, receive_test_packet);
server_port = ss_get_port(&test_etcp_bound_socket(server_instance, "udp0")->local_addr);
client_port = ss_get_port(&test_etcp_bound_socket(client_instance, "udp0")->local_addr);
if (poll_until(c_conn_up_both, LINK_UP_TIMEOUT_MS, "initial connection") != 0) {
printf("initial connection timeout\n"); dump_state(); return -1;
}
@ -411,8 +423,8 @@ static int session_a(void) {
CHECK(sc->reinit_count == srv_reinit0 && cc->reinit_count == cli_reinit0, "reinit during initial traffic");
// -- V1: клиент дозванивается до нового серверного сокета S1 --
int sp1 = alloc_port();
struct ETCP_SOCKET* s1 = add_udp_socket(server_instance, sp1, "dyn_s1");
int sp1 = 0;
struct ETCP_SOCKET* s1 = add_udp_socket(server_instance, &sp1, "dyn_s1");
CHECK(s1, "V1: failed to add server socket S1");
struct sockaddr_storage s1_addr; mk_addr(&s1_addr, sp1);
struct ETCP_LINK* lc1 = etcp_link_new(cc, c0, &s1_addr, 0);
@ -426,8 +438,8 @@ static int session_a(void) {
CHECK(check_link_traffic(c0, sp1, "V1") == 0, "V1 link carried no traffic");
// -- V2: сервер дозванивается до клиента --
int sp2 = alloc_port();
struct ETCP_SOCKET* s2 = add_udp_socket(server_instance, sp2, "dyn_s2");
int sp2 = 0;
struct ETCP_SOCKET* s2 = add_udp_socket(server_instance, &sp2, "dyn_s2");
CHECK(s2, "V2: failed to add server socket S2");
struct sockaddr_storage c0_addr; mk_addr(&c0_addr, client_port);
struct ETCP_LINK* ls2 = etcp_link_new(sc, s2, &c0_addr, 0);
@ -506,13 +518,12 @@ static int session_collision(int which) {
uint64_t srv_epoch = sc->reset_id, cli_epoch = cc->reset_id;
CHECK(run_traffic(TRAFFIC_PACKETS, TRAFFIC_TIMEOUT_MS) == 0, "traffic before link add failed");
int sp3 = alloc_port();
int cp1 = alloc_port();
int dead = alloc_port();
int sp3 = 0, cp1 = 0;
int dead = alloc_dead_port();
struct ETCP_SOCKET* s3 = add_udp_socket(server_instance, sp3, "dyn_s3");
struct ETCP_SOCKET* s3 = add_udp_socket(server_instance, &sp3, "dyn_s3");
CHECK(s3, "failed to add server socket S3");
struct ETCP_SOCKET* c1 = add_udp_socket(client_instance, cp1, "dyn_c1");
struct ETCP_SOCKET* c1 = add_udp_socket(client_instance, &cp1, "dyn_c1");
CHECK(c1, "failed to add client socket C1");
struct sockaddr_storage s3_addr; mk_addr(&s3_addr, sp3);
@ -584,9 +595,9 @@ static int session_cross_socket(void) {
CHECK(run_traffic(TRAFFIC_PACKETS, TRAFFIC_TIMEOUT_MS) == 0, "initial traffic failed");
uint32_t srv_reinit = sc->reinit_count, cli_reinit = cc->reinit_count;
uint64_t srv_epoch = sc->reset_id, cli_epoch = cc->reset_id;
int sp1 = alloc_port(), cp1 = alloc_port();
struct ETCP_SOCKET* s1 = add_udp_socket(server_instance, sp1, "cross_s1");
struct ETCP_SOCKET* c1 = add_udp_socket(client_instance, cp1, "cross_c1");
int sp1 = 0, cp1 = 0;
struct ETCP_SOCKET* s1 = add_udp_socket(server_instance, &sp1, "cross_s1");
struct ETCP_SOCKET* c1 = add_udp_socket(client_instance, &cp1, "cross_c1");
CHECK(s1 && c1, "failed to add sockets");
struct sockaddr_storage c1_addr, s0_addr, s1_addr;
mk_addr(&c1_addr, cp1); mk_addr(&s0_addr, server_port); mk_addr(&s1_addr, sp1);
@ -636,7 +647,7 @@ int main(void) {
}
printf("=== ETCP Multilink Test ===\n");
printf("server_port=%d client_port=%d dyn_ports=%d..\n", server_port, client_port, next_port);
printf("ports assigned by the operating system for each live socket\n");
utun_instance_set_tun_init_enabled(0);
ua = uasync_create();
@ -651,6 +662,7 @@ int main(void) {
if (ua) { uasync_poll(ua, 0); uasync_destroy(ua, 0); ua = NULL; }
cleanup_temp_configs();
for (unsigned i = 0; i < dead_socket_count; i++) socket_close_wrapper(dead_sockets[i]);
if (rc == 0) { printf("\n=== ALL TESTS PASSED ===\n"); return 0; }
printf("\n=== TESTS FAILED ===\n");

Loading…
Cancel
Save