diff --git a/tests/test_tcp_proxy_server.c b/tests/test_tcp_proxy_server.c index 383264d2..7985e481 100644 --- a/tests/test_tcp_proxy_server.c +++ b/tests/test_tcp_proxy_server.c @@ -18,7 +18,6 @@ #include "../lib/debug_config.h" #include "../lib/mem.h" -#define ECHO_PORT 19991 #define TIMEOUT_MS 8000 #define PAYLOAD_SIZE 64 @@ -30,12 +29,7 @@ static uint8_t send_buf[PAYLOAD_SIZE]; static void* timeout_id = NULL; #ifndef _WIN32 -static void echo_server(void) { - int srv = socket(AF_INET, SOCK_STREAM, 0); - if (srv < 0) _exit(1); - int opt = 1; setsockopt(srv, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - struct sockaddr_in a = {.sin_family = AF_INET, .sin_port = htons(ECHO_PORT), .sin_addr.s_addr = inet_addr("127.0.0.1")}; - if (bind(srv, (struct sockaddr*)&a, sizeof(a)) < 0 || listen(srv, 1) < 0) { close(srv); _exit(1); } +static void echo_server(socket_t srv) { int cli = accept(srv, NULL, NULL); if (cli < 0) { close(srv); _exit(1); } uint8_t buf[8192]; ssize_t n; @@ -62,6 +56,7 @@ static int push_write(struct tcp_conn* tc, const uint8_t* data, size_t len) { static void timeout_cb(void* arg) { (void)arg; + timeout_id = NULL; printf("[FAIL] timeout\n"); g_done = -1; } @@ -69,33 +64,47 @@ static void timeout_cb(void* arg) { int main(void) { debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN); + struct UASYNC* ua = NULL; + struct tcp_conn* tc = NULL; + socket_t sock = SOCKET_INVALID; + uint16_t echo_port = 0; #ifdef _WIN32 printf("[SKIP] test_tcp_proxy_server — fork() not available on Windows\n"); return 0; #else + socket_t listener = socket(AF_INET, SOCK_STREAM, 0); + if (listener == SOCKET_INVALID) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo socket: %s", strerror(errno)); return 1; } + struct sockaddr_in a = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("127.0.0.1")}; + if (bind(listener, (struct sockaddr*)&a, sizeof(a)) < 0 || listen(listener, 1) < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo listen: %s", strerror(errno)); socket_close_wrapper(listener); return 1; + } + echo_port = socket_get_bound_port(listener); + if (!echo_port) { socket_close_wrapper(listener); return 1; } echo_pid = fork(); - if (echo_pid == 0) { echo_server(); _exit(0); } - usleep(50000); // даём серверу запуститься + if (echo_pid < 0) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo fork: %s", strerror(errno)); socket_close_wrapper(listener); return 1; } + if (echo_pid == 0) { echo_server(listener); _exit(0); } + socket_close_wrapper(listener); // Слушатель уже готов, дочерний процесс сохраняет его fd и порт. #endif - struct UASYNC* ua = uasync_create(); - if (!ua) return 1; + ua = uasync_create(); + if (!ua) { DEBUG_ERROR(DEBUG_CATEGORY_SYS, "echo test: uasync create failed"); goto done; } timeout_id = uasync_set_timeout(ua, TIMEOUT_MS * 10, NULL, timeout_cb, "timeout"); + if (!timeout_id) { DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "echo test: timeout allocation failed"); goto done; } - socket_t sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock == SOCKET_INVALID) return 1; + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == SOCKET_INVALID) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo client socket failed"); goto done; } socket_set_nonblocking(sock); - struct tcp_conn* tc = tcp_conn_create(ua, sock, 1500, 8192, 32, 8, 0, on_fin_cb, on_error_cb, NULL); - if (!tc) return 1; + tc = tcp_conn_create(ua, sock, 1500, 8192, 32, 8, 0, on_fin_cb, on_error_cb, NULL); + if (!tc) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo client tcp_conn create failed"); goto done; } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = htons(ECHO_PORT); + addr.sin_port = htons(echo_port); int ret = connect(sock, (struct sockaddr*)&addr, sizeof(addr)); if (ret < 0 && errno != EINPROGRESS) { printf("[FAIL] connect: %s\n", strerror(errno)); g_done = -1; } @@ -125,8 +134,11 @@ int main(void) { } } - tcp_conn_destroy(tc); - uasync_destroy(ua, 0); +done: + if (timeout_id) uasync_cancel_timeout(ua, timeout_id); + if (tc) tcp_conn_destroy(tc); + else if (sock != SOCKET_INVALID) socket_close_wrapper(sock); + if (ua) uasync_destroy(ua, 0); #ifndef _WIN32 kill(echo_pid, SIGKILL); waitpid(echo_pid, NULL, 0);