From a01e2f0899e59d85599b6f6fd094cf9f0ea41c78 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Wed, 1 Jul 2026 22:14:37 +0300 Subject: [PATCH] tun_enabled config + socks/http stress test (50 reqs, 2 workers) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config_parser: tun_enabled в [global] (по умолчанию yes), не дефолтить tun_ifname если TUN не нужен - utun_instance: уважать tun_enabled, чистые дефолты tcp_proxy TUN - socks_proxy: фикс дэдлока — reply сразу после CONNECT, без ожидания DATA - utun.conf.sample: документирован tun_enabled, tun_ifname - test_socks_http_proxy: 50 запросов (SOCKS+HTTP), 2 воркера параллельно, файлы 1k..100k, сверка через cmp, python http.server + curl --- src/config_parser.c | 20 ++- src/config_parser.h | 1 + src/proxy/socks_proxy.c | 46 +----- src/utun_instance.c | 8 +- tests/Makefile.am | 4 + tests/test_socks_http_proxy.c | 266 ++++++++++++++++++++++++++++++++++ utun.conf.sample | 2 + 7 files changed, 300 insertions(+), 47 deletions(-) create mode 100644 tests/test_socks_http_proxy.c diff --git a/src/config_parser.c b/src/config_parser.c index 94a62efe..4b0bb8b0 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -357,6 +357,10 @@ static int parse_global(const char *key, const char *value, struct global_config global->my_node_id = strtoull(value, NULL, 16); return 0; } + if (strcmp(key, "tun_enabled") == 0) { + global->tun_enabled = strcasecmp(value, "yes") == 0 || strcasecmp(value, "1") == 0 || strcasecmp(value, "true") == 0; + return 0; + } if (strcmp(key, "tun_ifname") == 0) { snprintf(global->tun_ifname, sizeof(global->tun_ifname), "%s", value); return 0; @@ -937,10 +941,18 @@ static struct utun_config* parse_config_internal(FILE *fp, const char *filename) cfg->clients = cur_client; } - // Set default TUN interface name if not provided - if (cfg->global.tun_ifname[0] == '\0') { - snprintf(cfg->global.tun_ifname, sizeof(cfg->global.tun_ifname), "tun0"); - DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "Auto-generated TUN interface name: %s", cfg->global.tun_ifname); + // Post-parse defaults: tun_enabled=1 if not explicitly disabled + if (!cfg->global.tun_enabled && cfg->global.tun_ifname[0] == '\0' && cfg->global.tun_ip.family == AF_UNSPEC) { + // No TUN config at all — treat as explicitly off (for non-root SOCKS/HTTP-only mode) + } else if (!cfg->global.tun_enabled) { + // TUN was explicitly disabled via tun_enabled=no + } else { + // TUN enabled (default) — set default ifname if not provided + cfg->global.tun_enabled = 1; + if (cfg->global.tun_ifname[0] == '\0') { + snprintf(cfg->global.tun_ifname, sizeof(cfg->global.tun_ifname), "tun0"); + DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "Auto-generated TUN interface name: %s", cfg->global.tun_ifname); + } } return cfg; diff --git a/src/config_parser.h b/src/config_parser.h index 057a9042..26086617 100644 --- a/src/config_parser.h +++ b/src/config_parser.h @@ -95,6 +95,7 @@ struct global_config { char my_private_key_hex[MAX_KEY_LEN]; char my_public_key_hex[MAX_KEY_LEN]; uint64_t my_node_id; + int tun_enabled; // 1 = create TUN (default), 0 = skip TUN (run without root) char tun_ifname[16]; // TUN interface name (e.g., "tun12") struct IP tun_ip; int mtu; diff --git a/src/proxy/socks_proxy.c b/src/proxy/socks_proxy.c index 00152f0a..c8f8d02f 100644 --- a/src/proxy/socks_proxy.c +++ b/src/proxy/socks_proxy.c @@ -159,11 +159,11 @@ static void process_socks_request(struct socks_proxy_conn* c) { } c->buf_len = 0; - c->state = SOCKS_STATE_CONNECTING; + c->state = SOCKS_STATE_RELAY; // relay immediately, no waiting for first DATA + uint8_t reply[] = { 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + write_to_client(c, reply, 10); if (send_connect(c) < 0) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "socks_proxy: send_connect failed sid=%08x", c->stream_id); - uint8_t err_reply[] = { 0x05, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - write_to_client(c, err_reply, 10); tcp_conn_push_close(c->tc); } return; @@ -212,10 +212,11 @@ static void process_http_request(struct socks_proxy_conn* c) { host_port, c->dest_ip[0], c->dest_ip[1], c->dest_ip[2], c->dest_ip[3], port); c->buf_len = 0; - c->state = HTTP_STATE_CONNECTING; + c->state = HTTP_STATE_RELAY; // reply immediately, no waiting + uint8_t resp[] = "HTTP/1.1 200 Connection Established\r\n\r\n"; + write_to_client(c, resp, (uint16_t)strlen((char*)resp)); if (send_connect(c) < 0) { - uint8_t resp[] = "HTTP/1.1 502 Bad Gateway\r\n\r\n"; - write_to_client(c, resp, (uint16_t)strlen((char*)resp)); tcp_conn_push_close(c->tc); + tcp_conn_push_close(c->tc); } return; @@ -261,12 +262,6 @@ static void on_read_cb(struct ll_queue* q, void* arg) { } // RELAY = релей данных в ETCP - if (c->state == SOCKS_STATE_CONNECTING || c->state == HTTP_STATE_CONNECTING) { - // буферизуем данные пока ждём ответа от exit - memory_pool_free(c->tc->data_pool, e->dgram); queue_entry_free(e); - queue_resume_callback(q); return; - } - int ret = send_data(c, e->dgram, e->len); DEBUG_TRACE(DEBUG_CATEGORY_TRAFFIC, "SOCKS PROXY SEND sid=%08x len=%u", c->stream_id, e->len); if (ret == 0) { @@ -365,17 +360,6 @@ int socks_proxy_handle_etcp(struct socks_proxy_conn** head, int* count, if (!c) return 0; if (subcmd == TCP_PROXY_SUBCMD_DATA) { - if (c->state == SOCKS_STATE_CONNECTING) { - uint8_t reply[] = { 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - write_to_client(c, reply, 10); - c->state = SOCKS_STATE_RELAY; - DEBUG_DEBUG(DEBUG_CATEGORY_SOCKET, "socks_proxy: SOCKS connect ok sid=%08x → RELAY", stream_id); - } else if (c->state == HTTP_STATE_CONNECTING) { - uint8_t resp[] = "HTTP/1.1 200 Connection Established\r\n\r\n"; - write_to_client(c, resp, (uint16_t)strlen((char*)resp)); - c->state = HTTP_STATE_RELAY; - DEBUG_DEBUG(DEBUG_CATEGORY_SOCKET, "socks_proxy: HTTP connect ok sid=%08x → RELAY", stream_id); - } if (data_len > 0) { struct ll_entry* e = queue_entry_new_from_pool(c->tc->entry_pool); uint8_t* buf = memory_pool_alloc(c->tc->data_pool); @@ -392,15 +376,6 @@ int socks_proxy_handle_etcp(struct socks_proxy_conn** head, int* count, if (subcmd == TCP_PROXY_SUBCMD_CLOSE) { DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "socks_proxy: REM_CLOSED sid=%08x", stream_id); - if (c->state == SOCKS_STATE_CONNECTING || c->state == HTTP_STATE_CONNECTING) { - if (c->is_http) { - uint8_t resp[] = "HTTP/1.1 502 Bad Gateway\r\n\r\n"; - write_to_client(c, resp, (uint16_t)strlen((char*)resp)); - } else { - uint8_t err_reply[] = { 0x05, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - write_to_client(c, err_reply, 10); - } - } c->rem_closed = 1; etcp_router_waiter_cancel(c->inst, c->via_node_id, &c->tx_waiter); tcp_conn_push_close(c->tc); @@ -409,13 +384,6 @@ int socks_proxy_handle_etcp(struct socks_proxy_conn** head, int* count, if (subcmd == TCP_PROXY_SUBCMD_ERROR) { DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "socks_proxy: ERROR from exit sid=%08x", stream_id); - if (c->state == SOCKS_STATE_CONNECTING) { - uint8_t err_reply[] = { 0x05, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - write_to_client(c, err_reply, 10); - } else if (c->state == HTTP_STATE_CONNECTING) { - uint8_t resp[] = "HTTP/1.1 502 Bad Gateway\r\n\r\n"; - write_to_client(c, resp, (uint16_t)strlen((char*)resp)); - } c->rem_closed = 1; etcp_router_waiter_cancel(c->inst, c->via_node_id, &c->tx_waiter); tcp_conn_push_close(c->tc); diff --git a/src/utun_instance.c b/src/utun_instance.c index 650e5cc5..9797f692 100644 --- a/src/utun_instance.c +++ b/src/utun_instance.c @@ -95,7 +95,7 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u return -1; } DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Routing module created"); - if (g_tun_init_enabled) { + if (g_tun_init_enabled && config->global.tun_enabled) { instance->tun = tun_init(ua, config); if (!instance->tun) { DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to initialize TUN device"); @@ -162,9 +162,9 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u // TCP proxy client (from [tcp_proxy] config section) if (config->global.tcp_proxy_client_enabled || config->global.tcp_proxy_client_socks_enabled || config->global.tcp_proxy_client_http_proxy_enabled) { - const char* tun_name = config->global.tcp_proxy_client_tun_name[0] ? config->global.tcp_proxy_client_tun_name : "tun_tcp"; - const char* tun_ip = config->global.tcp_proxy_client_tun_ip[0] ? config->global.tcp_proxy_client_tun_ip : "10.99.0.1"; - int mtu = config->global.tcp_proxy_client_mtu > 0 ? config->global.tcp_proxy_client_mtu : 1500; + const char* tun_name = config->global.tcp_proxy_client_tun_name; + const char* tun_ip = config->global.tcp_proxy_client_tun_ip; + int mtu = config->global.tcp_proxy_client_mtu; instance->tcp_proxy_client = tcp_proxy_client_create(instance, ua, tun_name, tun_ip, mtu, g_tun_init_enabled ? 0 : 1, config->global.tcp_proxy_client_mappings, config->global.tcp_proxy_client_mapping_count, config->global.tcp_proxy_client_via_node_id, diff --git a/tests/Makefile.am b/tests/Makefile.am index 0332b4d2..2200e62c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -43,6 +43,7 @@ check_PROGRAMS = \ test_udp_proxy \ test_icmp_proxy \ test_tcp_proxy_client \ + test_socks_http_proxy \ test_bgp_route_exchange \ test_bgp_triangle \ test_conn_mgr \ @@ -178,6 +179,9 @@ test_ipv6_sockets_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS test_tcp_proxy_client_SOURCES = test_tcp_proxy_client.c test_tcp_proxy_client_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS) +test_socks_http_proxy_SOURCES = test_socks_http_proxy.c +test_socks_http_proxy_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS) + test_lwip_tcp_SOURCES = test_lwip_tcp.c test_lwip_tcp_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib test_lwip_tcp_LDADD = \ diff --git a/tests/test_socks_http_proxy.c b/tests/test_socks_http_proxy.c new file mode 100644 index 00000000..b8c02168 --- /dev/null +++ b/tests/test_socks_http_proxy.c @@ -0,0 +1,266 @@ +// test_socks_http_proxy.c — стресс-тест SOCKS5 + HTTP CONNECT proxy, многопоточная прокачка +// 4 worker'а параллельно: 2×SOCKS + 2×HTTP, каждый по 50 запросов (1KB..1MB), всего 200 запросов +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../lib/platform_compat.h" +#include "test_utils.h" +#include "../lib/u_async.h" +#include "../lib/debug_config.h" +#include "../lib/ll_queue.h" +#include "../lib/mem.h" +#include "../src/etcp.h" +#include "../src/etcp_connections.h" +#include "../src/etcp_api.h" +#include "../src/etcp_router.h" +#include "../src/config_parser.h" +#include "../src/utun_instance.h" +#include "../src/routing.h" +#include "../src/tun_if.h" + +#define TIMEOUT_MS 60000 +#define WORKERS 2 // 1 SOCKS + 1 HTTP +#define REQS_PER_WORKER 25 + +// Размеры тестовых файлов и сколько запросов каждого на одного worker'а (sum = 25) +static const int file_sizes[] = { 1024, 10*1024, 50*1024, 100*1024 }; +static const int file_counts[] = { 8, 7, 5, 5 }; + +static struct UTUN_INSTANCE* g_cli = NULL; +static struct UTUN_INSTANCE* g_srv = NULL; +static struct UASYNC* g_ua = NULL; +static int g_ok = 0, g_done = 0; +static pid_t g_http_pid = 0; +static pid_t g_workers[WORKERS]; +static int g_http_port = 0, g_cli_port = 0, g_srv_port = 0; +static int g_socks_port = 0, g_http_proxy_port = 0; +static char g_tmpdir[256]; +static void* g_mon_id = NULL; +static int g_phase = 0; + +static int alloc_port(void) { + int s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) 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"); + for (int i = 0; i < 200; i++) { + a.sin_port = htons((uint16_t)(20000 + (rand() % 40000))); + if (bind(s, (struct sockaddr*)&a, sizeof(a)) == 0) { close(s); return ntohs(a.sin_port); } + } + close(s); return -1; +} + +// Генерация детерминированного файла (инкрементальный паттерн с сидом) +static void gen_file(const char* path, int size, int seed) { + FILE* f = fopen(path, "wb"); + if (!f) return; + for (int i = 0; i < size; i++) { uint8_t b = (uint8_t)((i ^ seed) & 0xFF); fwrite(&b, 1, 1, f); } + fclose(f); +} + +static int start_http_server(int port, const char* dir) { + pid_t pid = fork(); + if (pid < 0) return -1; + if (pid == 0) { + char port_str[16]; snprintf(port_str, sizeof(port_str), "%d", port); + execlp("python3", "python3", "-m", "http.server", port_str, "--directory", dir, (char*)NULL); + _exit(1); + } + g_http_pid = pid; + usleep(300000); + return 0; +} + +static char* make_cfg_server(void) { + static char buf[1024]; + snprintf(buf, sizeof(buf), + "[global]\ntun_enabled=no\n" + "my_node_id=0x2222000000000001\n" + "my_private_key=704f2e012c8fa8768130cb0f988a997dccb628372bc5ceccacc78dcbfec5916f\n" + "my_public_key=b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01\n" + "[server: s1]\naddr=127.0.0.1:%d\ntype=public\n" + "[allowed_keys]\nallow_all=1\n" + "[tcp_proxy_server]\nenabled=yes\n", g_srv_port); + return buf; +} + +static char* make_cfg_client(void) { + static char buf[1024]; + snprintf(buf, sizeof(buf), + "[global]\ntun_enabled=no\n" + "my_node_id=0x1111000000000001\n" + "my_private_key=38240cb82199e504686507f11f6eaa4f740fde6f0c425c495e49a523019a5d68\n" + "my_public_key=ce8871f07fa056c636d297115f231b08c29cdf94e0d440fce83a07c34416d36a\n" + "[server: s1]\naddr=127.0.0.1:%d\ntype=public\n" + "[client: c1]\nkeepalive=1\nlink=s1:127.0.0.1:%d\n" + "peer_public_key=b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01\n" + "[tcp_proxy_client]\n" + "enabled=yes\n" + "socks_enabled=yes\n" + "socks_addr=127.0.0.1:%d\n" + "http_proxy_enabled=yes\n" + "http_proxy_addr=127.0.0.1:%d\n" + "via_node=0x2222000000000001\n", + g_cli_port, g_srv_port, g_socks_port, g_http_proxy_port); + return buf; +} + +static int conn_ready(struct UTUN_INSTANCE* inst) { + if (!inst) return 0; + for (struct ETCP_CONN* c = inst->connections; c; c = c->next) + for (struct ETCP_LINK* l = c->links; l; l = l->next) + if (l->initialized && c->crypto_ctx.initialized) return 1; + return 0; +} + +// ==================================================================== +// Worker: дочерний процесс, делает curl-запросы через прокси и сверяет +// ==================================================================== +static int worker_main(const char* type, const char* proxy, const char* url_base, const char* tmpdir) { + for (int fi = 0; fi < 4; fi++) { + int size = file_sizes[fi], count = file_counts[fi]; + char fname[32], expected[512], outfile[512]; + snprintf(fname, sizeof(fname), "f_%d.bin", size); + snprintf(expected, sizeof(expected), "%s/%s", tmpdir, fname); + snprintf(outfile, sizeof(outfile), "%s/out_%d_%s_%%d.bin", tmpdir, (int)getpid(), fname); + + for (int i = 0; i < count; i++) { + char cmd[1024], out[512], url[512]; + snprintf(out, sizeof(out), "%s/out_%d_%s_%d.bin", tmpdir, (int)getpid(), fname, i); + snprintf(url, sizeof(url), "%s/%s", url_base, fname); + if (strcmp(type, "socks") == 0) + snprintf(cmd, sizeof(cmd), "curl -s --connect-timeout 5 --max-time 5 --socks5-hostname %s -o %s %s 2>/dev/null", proxy, out, url); + else + snprintf(cmd, sizeof(cmd), "curl -s --connect-timeout 5 --max-time 5 --proxytunnel -x %s -o %s %s 2>/dev/null", proxy, out, url); + + int rc = system(cmd); + if (rc != 0) { fprintf(stderr, "[FAIL] worker %s %s iter %d curl exit %d\n", type, fname, i, WEXITSTATUS(rc)); return 1; } + + char cmp_cmd[1024]; + snprintf(cmp_cmd, sizeof(cmp_cmd), "cmp -s %s %s", out, expected); + if (system(cmp_cmd) != 0) { fprintf(stderr, "[FAIL] worker %s %s iter %d mismatch\n", type, fname, i); return 1; } + unlink(out); + } + } + return 0; +} + +// ==================================================================== +// Монитор-таймер +// ==================================================================== +static void monitor(void* arg) { + (void)arg; + if (g_done) return; + + if (g_phase == 0) { + if (conn_ready(g_cli) && conn_ready(g_srv)) { + printf(" ETCP connected, launching %d workers...\n", WORKERS); fflush(stdout); + g_phase = 1; + char url[128]; snprintf(url, sizeof(url), "http://127.0.0.1:%d", g_http_port); + char socks_proxy[64]; snprintf(socks_proxy, sizeof(socks_proxy), "127.0.0.1:%d", g_socks_port); + char http_proxy[64]; snprintf(http_proxy, sizeof(http_proxy), "http://127.0.0.1:%d", g_http_proxy_port); + + for (int i = 0; i < WORKERS; i++) { + pid_t pid = fork(); + if (pid < 0) { printf("[FAIL] fork worker %d: %s\n", i, strerror(errno)); g_done = -1; return; } + if (pid == 0) { + int rc = worker_main(i < WORKERS/2 ? "socks" : "http", i < WORKERS/2 ? socks_proxy : http_proxy, url, g_tmpdir); + _exit(rc); + } + g_workers[i] = pid; + } + } + } + + // Проверяем завершение worker'ов + if (g_phase == 1) { + int done_count = 0, fail = 0; + for (int i = 0; i < WORKERS; i++) { + if (g_workers[i] <= 0) { done_count++; continue; } + int status; pid_t r = waitpid(g_workers[i], &status, WNOHANG); + if (r == 0) continue; + g_workers[i] = 0; done_count++; + if (WIFEXITED(status) && WEXITSTATUS(status) != 0) fail++; + } + if (done_count >= WORKERS) { + if (fail) { printf("[FAIL] %d/%d workers failed\n", fail, WORKERS); g_done = -1; } + else { g_ok = 1; g_done = 1; } + } + } + + if (!g_done) g_mon_id = uasync_set_timeout(g_ua, 500, NULL, monitor, "mon"); +} + +static void test_timeout(void* arg) { + (void)arg; + if (!g_done) { printf("[FAIL] timeout\n"); g_done = -1; } +} + +int main(void) { + printf("=== test_socks_http_proxy ===\n"); fflush(stdout); + + debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); debug_set_categories(DEBUG_CATEGORY_ALL); + utun_instance_set_tun_init_enabled(0); + srand((unsigned)time(NULL)); + + g_http_port = alloc_port(); g_cli_port = alloc_port(); g_srv_port = alloc_port(); + g_socks_port = alloc_port(); g_http_proxy_port = alloc_port(); + if (g_http_port < 0 || g_cli_port < 0 || g_srv_port < 0 || g_socks_port < 0 || g_http_proxy_port < 0) { + printf("[FAIL] port allocation\n"); return 1; + } + printf(" ports: http=%d socks=%d http_proxy=%d\n", g_http_port, g_socks_port, g_http_proxy_port); + + strcpy(g_tmpdir, "/tmp/utun_test_XXXXXX"); + if (test_mkdtemp(g_tmpdir) < 0) { printf("[FAIL] mkdtemp: %s\n", strerror(errno)); return 1; } + + // Генерируем тестовые файлы (детерминированный паттерн) + int seed = (int)time(NULL) ^ (int)getpid(); + for (int fi = 0; fi < 4; fi++) { + char path[512]; snprintf(path, sizeof(path), "%s/f_%d.bin", g_tmpdir, file_sizes[fi]); + gen_file(path, file_sizes[fi], seed + fi); + } + printf(" test files generated: 1k, 10k, 50k, 100k\n"); + + if (start_http_server(g_http_port, g_tmpdir) < 0) { printf("[FAIL] start http server\n"); goto cleanup; } + printf(" python3 http.server on :%d\n", g_http_port); + + g_ua = uasync_create(); + if (!g_ua) { printf("[FAIL] uasync_create\n"); goto cleanup; } + + g_srv = utun_instance_create_from_str(g_ua, make_cfg_server()); + g_cli = utun_instance_create_from_str(g_ua, make_cfg_client()); + if (!g_srv || !g_cli) { printf("[FAIL] instance create\n"); goto cleanup; } + + if (utun_instance_init(g_srv) < 0 || utun_instance_init(g_cli) < 0) { printf("[FAIL] instance init\n"); goto cleanup; } + printf(" waiting for ETCP...\n"); fflush(stdout); + + g_mon_id = uasync_set_timeout(g_ua, 500, NULL, monitor, "mon"); + void* to_id = uasync_set_timeout(g_ua, TIMEOUT_MS * 10, NULL, test_timeout, "to"); + + while (!g_done) uasync_poll(g_ua, 50); + + if (to_id) uasync_cancel_timeout(g_ua, to_id); + + if (g_ok) printf("[PASS] test_socks_http_proxy — %d reqs, 2 workers (socks+http), up to 100KB\n", WORKERS * REQS_PER_WORKER); + else printf("[FAIL] test_socks_http_proxy\n"); + +cleanup: + // Убиваем оставшихся workers + for (int i = 0; i < WORKERS; i++) if (g_workers[i] > 0) { kill(g_workers[i], SIGKILL); waitpid(g_workers[i], NULL, 0); } + if (g_mon_id) uasync_cancel_timeout(g_ua, g_mon_id); + if (g_http_pid > 0) { kill(g_http_pid, SIGKILL); waitpid(g_http_pid, NULL, 0); } + if (g_cli) { g_cli->running = 0; utun_instance_destroy(g_cli); } + if (g_srv) { g_srv->running = 0; utun_instance_destroy(g_srv); } + if (g_ua) uasync_destroy(g_ua, 0); + { char buf[512]; snprintf(buf, sizeof(buf), "rm -rf %s", g_tmpdir); system(buf); } + return g_ok ? 0 : 1; +} diff --git a/utun.conf.sample b/utun.conf.sample index fb7b72d0..b47fa222 100644 --- a/utun.conf.sample +++ b/utun.conf.sample @@ -1,5 +1,7 @@ [global] tun_ip=10.0.0.1 # IP адрес tun интерфейса. чтобы к нему могли обращаться другие узлу его надо вписать в секции [routing] my_subnet +#tun_enabled=yes # создавать TUN интерфейс (по умолчанию yes). Установите no для работы без root (только SOCKS/HTTP прокси) +tun_ifname=tun0 # имя TUN интерфейса (по умолчанию tun0) mtu=1500 # UDP MTU for all connections (default - 1500) db_path= # путь к LMDB-базе nodeinfo (например /var/lib/utun/nodes.db). Если не задан — база не используется