dummynet: route between explicit independently bound endpoints
This commit is contained in:
1 parent
70b55e4626
commit
12d4e2433e
4 files changed
+50
-92
No files matched your search
@@ -36,12 +36,9 @@
|
||||
#include "../src/config_updater.h"
|
||||
#include "routing.h"
|
||||
#include "crc32.h"
|
||||
#include "test_net.h"
|
||||
|
||||
/* ===== Test constants ===== */
|
||||
#define DN_PORT 21001
|
||||
#define SRV_PORT 21002
|
||||
#define CLI_PORT 21000
|
||||
|
||||
#define PAYLOAD_SIZE 1200
|
||||
#define TEST_DURATION_MS 3500
|
||||
#define METRICS_TB 1000 /* 100ms in 0.1ms units */
|
||||
@@ -343,12 +340,14 @@ int main(void) {
|
||||
ctx.sender->test_user_ptr = &ctx;
|
||||
ctx.receiver->test_user_ptr = &ctx;
|
||||
|
||||
if (add_server(ctx.receiver, "srv", SRV_PORT) < 0 ||
|
||||
add_server(ctx.sender, "local", CLI_PORT) < 0 ||
|
||||
if (add_server(ctx.receiver, "srv", 0) < 0 ||
|
||||
add_server(ctx.sender, "local", 0) < 0 ||
|
||||
add_client(ctx.sender, s_pub) < 0) {
|
||||
printf("ERROR: config setup failed\n"); return 1;
|
||||
}
|
||||
add_link(ctx.sender->config->clients, ctx.sender->config->servers, DN_PORT);
|
||||
ctx.dn = dummynet_create(ctx.ua, "127.0.0.1", 0);
|
||||
if (!ctx.dn) { printf("ERROR: dummynet_create failed\n"); return 1; }
|
||||
add_link(ctx.sender->config->clients, ctx.sender->config->servers, dummynet_get_listen_port(ctx.dn));
|
||||
|
||||
printf("Init receiver...\n");
|
||||
if (utun_instance_init(ctx.receiver) < 0) { printf("ERROR: receiver init failed\n"); return 1; }
|
||||
@@ -357,16 +356,16 @@ int main(void) {
|
||||
|
||||
etcp_bind(ctx.receiver, ETCP_RT_ID_DATA, on_recv);
|
||||
|
||||
printf("Creating dummynet on port %d ...\n", DN_PORT);
|
||||
ctx.dn = dummynet_create(ctx.ua, "127.0.0.1", DN_PORT);
|
||||
if (!ctx.dn) { printf("ERROR: dummynet_create failed\n"); return 1; }
|
||||
int receiver_port = ss_get_port(&test_etcp_bound_socket(ctx.receiver, "srv")->local_addr);
|
||||
int sender_port = ss_get_port(&test_etcp_bound_socket(ctx.sender, "local")->local_addr);
|
||||
printf("Ports assigned: client=%d dummynet=%u server=%d\n", sender_port, dummynet_get_listen_port(ctx.dn), receiver_port);
|
||||
dummynet_set_direction(ctx.dn, DUMMYNET_FORWARD,
|
||||
EMU_DELAY_MS, EMU_JITTER_MS,
|
||||
EMU_BW_KBPS, EMU_QUEUE_PKTS, EMU_LOSS_PERM,
|
||||
"127.0.0.1", SRV_PORT);
|
||||
"127.0.0.1", (uint16_t)receiver_port);
|
||||
dummynet_set_direction(ctx.dn, DUMMYNET_BACKWARD,
|
||||
5, 1, 0, 200, 0,
|
||||
"127.0.0.1", CLI_PORT);
|
||||
"127.0.0.1", (uint16_t)sender_port);
|
||||
|
||||
/* Wait for connection */
|
||||
printf("Waiting for connection...\n");
|
||||
|
||||
+14
-53
@@ -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");
|
||||
|
||||
|
||||
Reference in new issue
Block a user