From 7139969acd25eda2cdbb334fd8dafad0d6d3786b Mon Sep 17 00:00:00 2001 From: jeka Date: Sun, 5 Jul 2026 20:57:44 +0300 Subject: [PATCH] fix: Windows/MSYS2 build compatibility - proxy/icmp_proxy.c: define struct icmp/ip + ICMP constants for _WIN32 - lwip_tcp_priv.h: use #include instead of #define htonl/htons - lwip_tcp.h/c: rename poll field to pollfn (avoid WSAPoll macro conflict) - tests: guard Unix-only headers with #ifndef _WIN32, skip fork/socketpair tests --- src/lwip_tcp/lwip_tcp.c | 2 +- src/lwip_tcp/lwip_tcp.h | 2 +- src/lwip_tcp/lwip_tcp_priv.h | 7 ++--- src/proxy/icmp_proxy.c | 23 ++++++++++++++ src/route6_lib.h | 32 ++++++++++++++++++++ tests/bbr_integration/test_bbr_integration.c | 2 ++ tests/test_etcp_congestion.c | 2 ++ tests/test_etcp_dummynet.c | 2 ++ tests/test_etcp_reinit_inflight.c | 2 ++ tests/test_ipv6_sockets.c | 2 ++ tests/test_lwip_tcp.c | 4 +++ tests/test_socks_http_proxy.c | 11 ++++++- tests/test_tcp_io.c | 5 +++ tests/test_tcp_proxy_server.c | 14 +++++++++ tests/test_uasync_socket_race.c | 11 +++++++ 15 files changed, 113 insertions(+), 8 deletions(-) diff --git a/src/lwip_tcp/lwip_tcp.c b/src/lwip_tcp/lwip_tcp.c index 723a56c5..8d600c83 100644 --- a/src/lwip_tcp/lwip_tcp.c +++ b/src/lwip_tcp/lwip_tcp.c @@ -1167,7 +1167,7 @@ void tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) void tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, uint8_t interval) { if (!pcb || pcb->state == LISTEN) return; - pcb->poll = poll; + pcb->pollfn = poll; pcb->pollinterval = interval; } diff --git a/src/lwip_tcp/lwip_tcp.h b/src/lwip_tcp/lwip_tcp.h index d3058d77..9da4acbf 100644 --- a/src/lwip_tcp/lwip_tcp.h +++ b/src/lwip_tcp/lwip_tcp.h @@ -164,7 +164,7 @@ struct tcp_pcb { tcp_sent_fn sent; tcp_recv_fn recv; tcp_connected_fn connected; - tcp_poll_fn poll; + tcp_poll_fn pollfn; tcp_err_fn errf; uint32_t keep_idle; uint8_t persist_cnt; diff --git a/src/lwip_tcp/lwip_tcp_priv.h b/src/lwip_tcp/lwip_tcp_priv.h index 6a12f045..ddee3020 100644 --- a/src/lwip_tcp/lwip_tcp_priv.h +++ b/src/lwip_tcp/lwip_tcp_priv.h @@ -27,10 +27,7 @@ #ifndef _WIN32 #include #else -#define htons(x) ((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF)) -#define ntohs(x) htons(x) -#define htonl(x) ((((x) & 0xFF) << 24) | (((x) & 0xFF00) << 8) | (((x) >> 8) & 0xFF00) | (((x) >> 24) & 0xFF)) -#define ntohl(x) htonl(x) +#include #endif // TCP header (wire format) @@ -138,7 +135,7 @@ struct tcp_seg { do { if((pcb)->connected != NULL) (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); else (ret) = LERR_OK; } while(0) #define TCP_EVENT_POLL(pcb,ret) \ - do { if((pcb)->poll != NULL) (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); else (ret) = LERR_OK; } while(0) + do { if((pcb)->pollfn != NULL) (ret) = (pcb)->pollfn((pcb)->callback_arg,(pcb)); else (ret) = LERR_OK; } while(0) #define TCP_EVENT_ERR(last_state,errf,arg,err) \ do { (void)(last_state); if((errf) != NULL) (errf)((arg),(err)); } while(0) diff --git a/src/proxy/icmp_proxy.c b/src/proxy/icmp_proxy.c index 87dfabdf..7cb8387f 100644 --- a/src/proxy/icmp_proxy.c +++ b/src/proxy/icmp_proxy.c @@ -19,6 +19,29 @@ #include #include #include +#else +#define ICMP_MINLEN 8 +#define ICMP_ECHO 8 +#define ICMP_ECHOREPLY 0 +struct icmp { + uint8_t icmp_type; + uint8_t icmp_code; + uint16_t icmp_cksum; + uint16_t icmp_id; + uint16_t icmp_seq; + uint8_t icmp_data[1]; +}; +struct ip { + uint8_t ip_hl:4, ip_v:4; + uint8_t ip_tos; + uint16_t ip_len; + uint16_t ip_id; + uint16_t ip_off; + uint8_t ip_ttl; + uint8_t ip_p; + uint16_t ip_sum; + struct in_addr ip_src, ip_dst; +}; #endif #define ICMP_DEF_TTL 64 diff --git a/src/route6_lib.h b/src/route6_lib.h index 9356ebda..0b356b64 100644 --- a/src/route6_lib.h +++ b/src/route6_lib.h @@ -7,6 +7,38 @@ #include "../lib/ll_queue.h" #include "../lib/u_async.h" + +/* +Диапазон Назначение +::/128 Неопределенный адрес (unspecified). Используется до назначения адреса интерфейсу. +::1/128 Адрес обратной петли (loopback), аналог 127.0.0.1 в IPv4. +2000::/3 Глобально маршрутизируемые (Global Unicast) адреса. Основное адресное пространство Интернета. +fc00::/7 Уникальные локальные адреса (ULA), аналог частных IPv4 (10.0.0.0/8, 192.168.0.0/16). На практике обычно используется fd00::/8. +fe80::/10 Локальные канальные адреса (Link-Local). Автоматически назначаются интерфейсам и работают только в пределах одного сегмента сети. Не маршрутизируются. +ff00::/8 Multicast-адреса. Используются вместо широковещания (broadcast), которого в IPv6 нет. +100::/64 Адреса для протокола Discard-Only. Предназначены для тестирования и отладки. +64:ff9b::/96 Префикс для трансляции IPv4↔IPv6 (NAT64). +64:ff9b:1::/48 Расширенный префикс NAT64. +2001:db8::/32 Зарезервирован для документации и примеров. Не используется в Интернете. +2002::/16 6to4-адреса (устаревший механизм перехода с IPv4 на IPv6). +2001::/32 Teredo (устаревшая технология туннелирования IPv6 через IPv4). +::ffff:0:0/96 IPv4-mapped IPv6 addresses. Используются ОС для представления IPv4-адресов в IPv6 API. + +Адреса узлов сети формируются по следующему принципу: +FCxx:xxxx:xxxx:xxxx : yyyy:yyyy:yyyy:yyyy - local network: x = network id, y - node id. + -- network id --- ---- node id ------ + +FDxx/8 - опциональные ipv6 подсети узлов /64 (если нужно) + +В разных node_groups общие: +- nodelists с их настройками (глобальная таблица) +- одинаковые линки между nodes (т.к. только один линк между парой узлов) + +- При маршрутизации используем только узлы + + +*/ + // таблица маршрутизации IPv6 на radix tree + ll_queue (поиск по node_id для удаления) struct ROUTE6_DATA { diff --git a/tests/bbr_integration/test_bbr_integration.c b/tests/bbr_integration/test_bbr_integration.c index a7515642..dabaa348 100644 --- a/tests/bbr_integration/test_bbr_integration.c +++ b/tests/bbr_integration/test_bbr_integration.c @@ -13,9 +13,11 @@ #include #include #include +#ifndef _WIN32 #include #include #include +#endif #include "../lib/u_async.h" #include "../lib/ll_queue.h" diff --git a/tests/test_etcp_congestion.c b/tests/test_etcp_congestion.c index ccc9eff3..be919ebb 100644 --- a/tests/test_etcp_congestion.c +++ b/tests/test_etcp_congestion.c @@ -13,9 +13,11 @@ #include #include #include +#ifndef _WIN32 #include #include #include +#endif #include #include "../lib/u_async.h" diff --git a/tests/test_etcp_dummynet.c b/tests/test_etcp_dummynet.c index d999469e..77888be5 100644 --- a/tests/test_etcp_dummynet.c +++ b/tests/test_etcp_dummynet.c @@ -7,9 +7,11 @@ #include #include #include +#ifndef _WIN32 #include #include #include +#endif #include "../lib/u_async.h" #include "../lib/ll_queue.h" diff --git a/tests/test_etcp_reinit_inflight.c b/tests/test_etcp_reinit_inflight.c index 20270b69..574f50d6 100644 --- a/tests/test_etcp_reinit_inflight.c +++ b/tests/test_etcp_reinit_inflight.c @@ -2,9 +2,11 @@ #include #include #include +#ifndef _WIN32 #include #include #include +#endif #include "../lib/u_async.h" #include "../lib/ll_queue.h" diff --git a/tests/test_ipv6_sockets.c b/tests/test_ipv6_sockets.c index fcd743b2..05b8deaf 100644 --- a/tests/test_ipv6_sockets.c +++ b/tests/test_ipv6_sockets.c @@ -15,7 +15,9 @@ #include #include #include +#ifndef _WIN32 #include +#endif #include "../lib/platform_compat.h" #include "test_utils.h" diff --git a/tests/test_lwip_tcp.c b/tests/test_lwip_tcp.c index 0f63bb11..8441b887 100644 --- a/tests/test_lwip_tcp.c +++ b/tests/test_lwip_tcp.c @@ -631,7 +631,11 @@ int main(int argc, char *argv[]) debug_config_init(); debug_set_console_level(DEBUG_LEVEL_NONE); debug_set_category_level(DEBUG_CATEGORY_ALL, DEBUG_LEVEL_ERROR); +#ifndef _WIN32 setlinebuf(stdout); +#else + setvbuf(stdout, NULL, _IOLBF, 0); +#endif struct UASYNC *ua = uasync_create(); if (!ua) return 1; diff --git a/tests/test_socks_http_proxy.c b/tests/test_socks_http_proxy.c index aa731de4..ba468c0d 100644 --- a/tests/test_socks_http_proxy.c +++ b/tests/test_socks_http_proxy.c @@ -6,12 +6,14 @@ #include #include #include +#ifndef _WIN32 #include #include #include #include #include #include +#endif #include #include #include @@ -39,6 +41,7 @@ static const int file_sizes[] = { 1024, 100*1024, 1024*1024, 10*1024*1024 }; static const char* file_names[] = { "f_1k.bin", "f_100k.bin", "f_1m.bin", "f_10m.bin" }; static const int num_files = 4; +#ifndef _WIN32 static struct UTUN_INSTANCE* g_cli = NULL; static struct UTUN_INSTANCE* g_srv = NULL; static struct UASYNC* g_ua = NULL; @@ -416,9 +419,14 @@ static void test_timeout(void* arg) { if (!g_done) { printf("[FAIL] timeout (%ds)\n", TIMEOUT_MS/1000); g_done = -1; } } +#endif /* !_WIN32 */ + int main(void) { printf("=== test_socks_http_proxy ===\n"); fflush(stdout); - +#ifdef _WIN32 + printf("[SKIP] test_socks_http_proxy — fork() not available on Windows\n"); + return 0; +#else { int fd = open("/dev/null", O_RDONLY); if (fd > 0 && fd != 0) { dup2(fd, 0); close(fd); } else if (fd < 0) { close(0); open("/dev/null", O_RDONLY); } } debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); debug_set_categories(DEBUG_CATEGORY_ALL); @@ -486,4 +494,5 @@ cleanup: 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; +#endif } diff --git a/tests/test_tcp_io.c b/tests/test_tcp_io.c index 079328f6..fd6a9659 100644 --- a/tests/test_tcp_io.c +++ b/tests/test_tcp_io.c @@ -537,6 +537,10 @@ static void test_fin_before_close(void) { } int main(void) { +#ifdef _WIN32 + printf("[SKIP] test_tcp_io — socketpair() not available on Windows\n"); + return 0; +#else debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO); debug_set_categories(DEBUG_CATEGORY_ALL); @@ -561,4 +565,5 @@ int main(void) { DEBUG_INFO(DEBUG_CATEGORY_UASYNC, "Tests failed: %d", tests_failed); return (tests_failed > 0) ? 1 : 0; +#endif } diff --git a/tests/test_tcp_proxy_server.c b/tests/test_tcp_proxy_server.c index 44d5592f..383264d2 100644 --- a/tests/test_tcp_proxy_server.c +++ b/tests/test_tcp_proxy_server.c @@ -3,12 +3,15 @@ #include #include #include +#ifndef _WIN32 #include #include #include #include #include #include +#endif +#include "../lib/platform_compat.h" #include "../lib/tcp_io.h" #include "../lib/u_async.h" #include "../lib/ll_queue.h" @@ -20,10 +23,13 @@ #define PAYLOAD_SIZE 64 static int g_ok = 0, g_done = 0; +#ifndef _WIN32 static pid_t echo_pid = 0; +#endif 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); @@ -39,6 +45,7 @@ static void echo_server(void) { } done: close(cli); close(srv); } +#endif static void on_fin_cb(struct tcp_conn* tc, void* arg) { (void)tc; (void)arg; } static void on_error_cb(struct tcp_conn* tc, int err, void* arg) { (void)tc; (void)arg; (void)err; } @@ -63,9 +70,14 @@ int main(void) { debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN); +#ifdef _WIN32 + printf("[SKIP] test_tcp_proxy_server — fork() not available on Windows\n"); + return 0; +#else echo_pid = fork(); if (echo_pid == 0) { echo_server(); _exit(0); } usleep(50000); // даём серверу запуститься +#endif struct UASYNC* ua = uasync_create(); if (!ua) return 1; @@ -115,7 +127,9 @@ int main(void) { tcp_conn_destroy(tc); uasync_destroy(ua, 0); +#ifndef _WIN32 kill(echo_pid, SIGKILL); waitpid(echo_pid, NULL, 0); +#endif return g_ok ? 0 : 1; } diff --git a/tests/test_uasync_socket_race.c b/tests/test_uasync_socket_race.c index 1658f680..4f0b420c 100644 --- a/tests/test_uasync_socket_race.c +++ b/tests/test_uasync_socket_race.c @@ -5,13 +5,16 @@ #include #include #include +#ifndef _WIN32 #include #include #include #include #include #include +#endif #include +#include "../lib/platform_compat.h" #include "../lib/tcp_io.h" #include "../lib/u_async.h" #include "../lib/ll_queue.h" @@ -25,6 +28,7 @@ static struct UASYNC* g_ua = NULL; static int g_ok = 0, g_done = 0; static int g_conn_count = 0, g_read_count = 0, g_err_count = 0; +#ifndef _WIN32 static pid_t g_children[CHILDREN]; static int g_port = 0; static void* g_mon_id = NULL; @@ -103,8 +107,14 @@ static void test_timeout(void* arg) { g_done = -1; } +#endif /* !_WIN32 */ + int main(void) { printf("=== test_uasync_socket_race ===\n"); fflush(stdout); +#ifdef _WIN32 + printf("[SKIP] test_uasync_socket_race — fork() not available on Windows\n"); + return 0; +#else debug_config_init(); for (int i = 1; i < DEBUG_CATEGORY_COUNT; i++) debug_set_category_level(i, DEBUG_LEVEL_ERROR); @@ -157,4 +167,5 @@ cleanup: if (g_mon_id) uasync_cancel_timeout(g_ua, g_mon_id); if (g_ua) uasync_destroy(g_ua, 0); return g_ok ? 0 : 1; +#endif }