|
|
|
|
@ -12,6 +12,7 @@
|
|
|
|
|
#include "../lib/platform_compat.h" |
|
|
|
|
#include "../lib/socket_compat.h" |
|
|
|
|
#include "test_utils.h" |
|
|
|
|
#include "test_net.h" |
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
#include <windows.h> |
|
|
|
|
#include <direct.h> |
|
|
|
|
@ -125,40 +126,6 @@ static double toc_ms(const struct timespec* start) {
|
|
|
|
|
return (end.tv_sec - start->tv_sec) * 1000.0 + (end.tv_nsec - start->tv_nsec) / 1000000.0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ======================== Port allocation ========================
|
|
|
|
|
static int alloc_consecutive_ports(int* base_port) { |
|
|
|
|
for (int attempt = 0; attempt < 200; attempt++) { |
|
|
|
|
socket_t s = socket_create_udp(AF_INET); |
|
|
|
|
if (s == SOCKET_INVALID) return -1; |
|
|
|
|
struct sockaddr_in a; |
|
|
|
|
memset(&a, 0, sizeof(a)); |
|
|
|
|
a.sin_family = AF_INET; |
|
|
|
|
a.sin_addr.s_addr = inet_addr("127.0.0.1"); |
|
|
|
|
a.sin_port = 0; // auto-assign
|
|
|
|
|
if (bind(s, (struct sockaddr*)&a, sizeof(a)) != 0) { socket_close_wrapper(s); continue; } |
|
|
|
|
socklen_t alen = sizeof(a); |
|
|
|
|
getsockname(s, (struct sockaddr*)&a, &alen); |
|
|
|
|
int port = ntohs(a.sin_port); |
|
|
|
|
socket_close_wrapper(s); |
|
|
|
|
// Need port-1, port, port+1 all free
|
|
|
|
|
int ok = 1; |
|
|
|
|
for (int p = port - 1; p <= port + 1 && ok; p++) { |
|
|
|
|
if (p < 1024) { ok = 0; break; } |
|
|
|
|
socket_t ts = socket_create_udp(AF_INET); |
|
|
|
|
if (ts == SOCKET_INVALID) { ok = 0; break; } |
|
|
|
|
struct sockaddr_in ta; |
|
|
|
|
memset(&ta, 0, sizeof(ta)); |
|
|
|
|
ta.sin_family = AF_INET; |
|
|
|
|
ta.sin_addr.s_addr = inet_addr("127.0.0.1"); |
|
|
|
|
ta.sin_port = htons((uint16_t)p); |
|
|
|
|
if (bind(ts, (struct sockaddr*)&ta, sizeof(ta)) != 0) ok = 0; |
|
|
|
|
socket_close_wrapper(ts); |
|
|
|
|
} |
|
|
|
|
if (ok) { *base_port = port; return 0; } |
|
|
|
|
} |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ======================== Config generation ========================
|
|
|
|
|
static const char* srv_priv = "38240cb82199e504686507f11f6eaa4f740fde6f0c425c495e49a523019a5d68"; |
|
|
|
|
static const char* srv_pub = "ce8871f07fa056c636d297115f231b08c29cdf94e0d440fce83a07c34416d36a"; |
|
|
|
|
@ -393,8 +360,7 @@ static int test_loopback(void) {
|
|
|
|
|
|
|
|
|
|
// ======================== Dummynet setup ========================
|
|
|
|
|
static int setup_dummynet(void) { |
|
|
|
|
dn = dummynet_create(ua, "127.0.0.1", (uint16_t)g_dn_port); |
|
|
|
|
if (!dn) { printf("[FAIL] dummynet_create on port %d\n", g_dn_port); return -1; } |
|
|
|
|
if (!dn) { printf("[FAIL] dummynet listener missing\n"); return -1; } |
|
|
|
|
// Forward: dummynet → server
|
|
|
|
|
dummynet_set_direction(dn, DUMMYNET_FORWARD, 0, 0, 0, DUMMY_QUEUE_SIZE, 0, |
|
|
|
|
"127.0.0.1", (uint16_t)g_srv_port); |
|
|
|
|
@ -694,20 +660,6 @@ int main(void) {
|
|
|
|
|
if (!g_reset_mode) g_reset_mode = g_tcp ? "both" : "client"; |
|
|
|
|
if (test_mkdtemp(temp_dir) != 0) { fprintf(stderr, "mkdtemp fail\n"); return 1; } |
|
|
|
|
|
|
|
|
|
// Allocate consecutive ports
|
|
|
|
|
int base_port; |
|
|
|
|
if (alloc_consecutive_ports(&base_port) != 0) { |
|
|
|
|
printf("[FAIL] cannot allocate consecutive ports\n"); |
|
|
|
|
test_rmdir(temp_dir); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
g_dn_port = base_port; |
|
|
|
|
g_srv_port = base_port + 1; |
|
|
|
|
g_cli_port = base_port - 1; |
|
|
|
|
printf("Ports: dummynet=%d server=%d client=%d\n", g_dn_port, g_srv_port, g_cli_port); |
|
|
|
|
|
|
|
|
|
write_configs(); |
|
|
|
|
|
|
|
|
|
printf("=== test_etcp_router (%s, bounded backpressure and transport recovery) ===\n", g_tcp ? "TCP" : "UDP"); |
|
|
|
|
|
|
|
|
|
debug_config_init(); |
|
|
|
|
@ -725,11 +677,23 @@ int main(void) {
|
|
|
|
|
tic(&t_phase_start); |
|
|
|
|
ua = uasync_create(); |
|
|
|
|
if (!ua) { printf("[FAIL] uasync_create\n"); goto done; } |
|
|
|
|
if (!g_tcp) { |
|
|
|
|
dn = dummynet_create(ua, "127.0.0.1", 0); |
|
|
|
|
if (!dn) { printf("[FAIL] dummynet create\n"); goto done; } |
|
|
|
|
g_dn_port = dummynet_get_listen_port(dn); |
|
|
|
|
} |
|
|
|
|
write_configs(); |
|
|
|
|
|
|
|
|
|
srv = utun_instance_create(ua, server_conf); |
|
|
|
|
if (!srv || utun_instance_init(srv) < 0) { printf("[FAIL] server create\n"); goto done; } |
|
|
|
|
|
|
|
|
|
cli = utun_instance_create(ua, client_conf); |
|
|
|
|
if (cli) { |
|
|
|
|
g_srv_port = ss_get_port(&test_etcp_bound_socket(srv, "s1")->local_addr); |
|
|
|
|
g_cli_port = ss_get_port(&test_etcp_bound_socket(cli, "s1")->local_addr); |
|
|
|
|
if (!g_tcp && setup_dummynet() != 0) { printf("[FAIL] dummynet setup\n"); goto done; } |
|
|
|
|
printf("Ports: dummynet=%d server=%d client=%d\n", g_dn_port, g_srv_port, g_cli_port); |
|
|
|
|
} |
|
|
|
|
if (!cli || utun_instance_init(cli) < 0) { printf("[FAIL] client create\n"); goto done; } |
|
|
|
|
|
|
|
|
|
server_node_id = srv->node_id; client_node_id = cli->node_id; |
|
|
|
|
@ -743,9 +707,6 @@ int main(void) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create dummynet between client and server
|
|
|
|
|
if (!g_tcp && setup_dummynet() != 0) { printf("[FAIL] dummynet setup\n"); goto done; } |
|
|
|
|
|
|
|
|
|
g_mon_id = uasync_set_timeout(ua, 100, NULL, monitor, "mon"); |
|
|
|
|
void* to_id = uasync_set_timeout(ua, TEST_TIMEOUT_MS * 10, NULL, timeout_cb, "to"); |
|
|
|
|
|
|
|
|
|
|