Browse Source

fix: Windows/MSYS2 build compatibility

- proxy/icmp_proxy.c: define struct icmp/ip + ICMP constants for _WIN32
- lwip_tcp_priv.h: use #include <winsock2.h> 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
chatgui
jeka 3 months ago
parent
commit
7139969acd
  1. 2
      src/lwip_tcp/lwip_tcp.c
  2. 2
      src/lwip_tcp/lwip_tcp.h
  3. 7
      src/lwip_tcp/lwip_tcp_priv.h
  4. 23
      src/proxy/icmp_proxy.c
  5. 32
      src/route6_lib.h
  6. 2
      tests/bbr_integration/test_bbr_integration.c
  7. 2
      tests/test_etcp_congestion.c
  8. 2
      tests/test_etcp_dummynet.c
  9. 2
      tests/test_etcp_reinit_inflight.c
  10. 2
      tests/test_ipv6_sockets.c
  11. 4
      tests/test_lwip_tcp.c
  12. 11
      tests/test_socks_http_proxy.c
  13. 5
      tests/test_tcp_io.c
  14. 14
      tests/test_tcp_proxy_server.c
  15. 11
      tests/test_uasync_socket_race.c

2
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) void tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, uint8_t interval)
{ {
if (!pcb || pcb->state == LISTEN) return; if (!pcb || pcb->state == LISTEN) return;
pcb->poll = poll; pcb->pollfn = poll;
pcb->pollinterval = interval; pcb->pollinterval = interval;
} }

2
src/lwip_tcp/lwip_tcp.h

@ -164,7 +164,7 @@ struct tcp_pcb {
tcp_sent_fn sent; tcp_sent_fn sent;
tcp_recv_fn recv; tcp_recv_fn recv;
tcp_connected_fn connected; tcp_connected_fn connected;
tcp_poll_fn poll; tcp_poll_fn pollfn;
tcp_err_fn errf; tcp_err_fn errf;
uint32_t keep_idle; uint32_t keep_idle;
uint8_t persist_cnt; uint8_t persist_cnt;

7
src/lwip_tcp/lwip_tcp_priv.h

@ -27,10 +27,7 @@
#ifndef _WIN32 #ifndef _WIN32
#include <arpa/inet.h> #include <arpa/inet.h>
#else #else
#define htons(x) ((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF)) #include <winsock2.h>
#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)
#endif #endif
// TCP header (wire format) // 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) 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) \ #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) \ #define TCP_EVENT_ERR(last_state,errf,arg,err) \
do { (void)(last_state); if((errf) != NULL) (errf)((arg),(err)); } while(0) do { (void)(last_state); if((errf) != NULL) (errf)((arg),(err)); } while(0)

23
src/proxy/icmp_proxy.c

@ -19,6 +19,29 @@
#include <netinet/ip_icmp.h> #include <netinet/ip_icmp.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/socket.h> #include <sys/socket.h>
#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 #endif
#define ICMP_DEF_TTL 64 #define ICMP_DEF_TTL 64

32
src/route6_lib.h

@ -7,6 +7,38 @@
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
#include "../lib/u_async.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 для удаления) // таблица маршрутизации IPv6 на radix tree + ll_queue (поиск по node_id для удаления)
struct ROUTE6_DATA { struct ROUTE6_DATA {

2
tests/bbr_integration/test_bbr_integration.c

@ -13,9 +13,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#endif
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"

2
tests/test_etcp_congestion.c

@ -13,9 +13,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#endif
#include <math.h> #include <math.h>
#include "../lib/u_async.h" #include "../lib/u_async.h"

2
tests/test_etcp_dummynet.c

@ -7,9 +7,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#endif
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"

2
tests/test_etcp_reinit_inflight.c

@ -2,9 +2,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#endif
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"

2
tests/test_ipv6_sockets.c

@ -15,7 +15,9 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef _WIN32
#include <arpa/inet.h> #include <arpa/inet.h>
#endif
#include "../lib/platform_compat.h" #include "../lib/platform_compat.h"
#include "test_utils.h" #include "test_utils.h"

4
tests/test_lwip_tcp.c

@ -631,7 +631,11 @@ int main(int argc, char *argv[])
debug_config_init(); debug_config_init();
debug_set_console_level(DEBUG_LEVEL_NONE); debug_set_console_level(DEBUG_LEVEL_NONE);
debug_set_category_level(DEBUG_CATEGORY_ALL, DEBUG_LEVEL_ERROR); debug_set_category_level(DEBUG_CATEGORY_ALL, DEBUG_LEVEL_ERROR);
#ifndef _WIN32
setlinebuf(stdout); setlinebuf(stdout);
#else
setvbuf(stdout, NULL, _IOLBF, 0);
#endif
struct UASYNC *ua = uasync_create(); struct UASYNC *ua = uasync_create();
if (!ua) return 1; if (!ua) return 1;

11
tests/test_socks_http_proxy.c

@ -6,12 +6,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#ifndef _WIN32
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/wait.h> #include <sys/wait.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
@ -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 char* file_names[] = { "f_1k.bin", "f_100k.bin", "f_1m.bin", "f_10m.bin" };
static const int num_files = 4; static const int num_files = 4;
#ifndef _WIN32
static struct UTUN_INSTANCE* g_cli = NULL; static struct UTUN_INSTANCE* g_cli = NULL;
static struct UTUN_INSTANCE* g_srv = NULL; static struct UTUN_INSTANCE* g_srv = NULL;
static struct UASYNC* g_ua = 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; } if (!g_done) { printf("[FAIL] timeout (%ds)\n", TIMEOUT_MS/1000); g_done = -1; }
} }
#endif /* !_WIN32 */
int main(void) { int main(void) {
printf("=== test_socks_http_proxy ===\n"); fflush(stdout); 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); } } { 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); 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); if (g_ua) uasync_destroy(g_ua, 0);
{ char buf[512]; snprintf(buf, sizeof(buf), "rm -rf %s", g_tmpdir); system(buf); } { char buf[512]; snprintf(buf, sizeof(buf), "rm -rf %s", g_tmpdir); system(buf); }
return g_ok ? 0 : 1; return g_ok ? 0 : 1;
#endif
} }

5
tests/test_tcp_io.c

@ -537,6 +537,10 @@ static void test_fin_before_close(void) {
} }
int main(void) { int main(void) {
#ifdef _WIN32
printf("[SKIP] test_tcp_io — socketpair() not available on Windows\n");
return 0;
#else
debug_config_init(); debug_config_init();
debug_set_level(DEBUG_LEVEL_INFO); debug_set_level(DEBUG_LEVEL_INFO);
debug_set_categories(DEBUG_CATEGORY_ALL); debug_set_categories(DEBUG_CATEGORY_ALL);
@ -561,4 +565,5 @@ int main(void) {
DEBUG_INFO(DEBUG_CATEGORY_UASYNC, "Tests failed: %d", tests_failed); DEBUG_INFO(DEBUG_CATEGORY_UASYNC, "Tests failed: %d", tests_failed);
return (tests_failed > 0) ? 1 : 0; return (tests_failed > 0) ? 1 : 0;
#endif
} }

14
tests/test_tcp_proxy_server.c

@ -3,12 +3,15 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#ifndef _WIN32
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/wait.h> #include <sys/wait.h>
#endif
#include "../lib/platform_compat.h"
#include "../lib/tcp_io.h" #include "../lib/tcp_io.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
@ -20,10 +23,13 @@
#define PAYLOAD_SIZE 64 #define PAYLOAD_SIZE 64
static int g_ok = 0, g_done = 0; static int g_ok = 0, g_done = 0;
#ifndef _WIN32
static pid_t echo_pid = 0; static pid_t echo_pid = 0;
#endif
static uint8_t send_buf[PAYLOAD_SIZE]; static uint8_t send_buf[PAYLOAD_SIZE];
static void* timeout_id = NULL; static void* timeout_id = NULL;
#ifndef _WIN32
static void echo_server(void) { static void echo_server(void) {
int srv = socket(AF_INET, SOCK_STREAM, 0); int srv = socket(AF_INET, SOCK_STREAM, 0);
if (srv < 0) _exit(1); if (srv < 0) _exit(1);
@ -39,6 +45,7 @@ static void echo_server(void) {
} }
done: close(cli); close(srv); done: close(cli); close(srv);
} }
#endif
static void on_fin_cb(struct tcp_conn* tc, void* arg) { (void)tc; (void)arg; } 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; } 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_config_init();
debug_set_level(DEBUG_LEVEL_WARN); 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(); echo_pid = fork();
if (echo_pid == 0) { echo_server(); _exit(0); } if (echo_pid == 0) { echo_server(); _exit(0); }
usleep(50000); // даём серверу запуститься usleep(50000); // даём серверу запуститься
#endif
struct UASYNC* ua = uasync_create(); struct UASYNC* ua = uasync_create();
if (!ua) return 1; if (!ua) return 1;
@ -115,7 +127,9 @@ int main(void) {
tcp_conn_destroy(tc); tcp_conn_destroy(tc);
uasync_destroy(ua, 0); uasync_destroy(ua, 0);
#ifndef _WIN32
kill(echo_pid, SIGKILL); kill(echo_pid, SIGKILL);
waitpid(echo_pid, NULL, 0); waitpid(echo_pid, NULL, 0);
#endif
return g_ok ? 0 : 1; return g_ok ? 0 : 1;
} }

11
tests/test_uasync_socket_race.c

@ -5,13 +5,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#ifndef _WIN32
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/wait.h> #include <sys/wait.h>
#endif
#include <fcntl.h> #include <fcntl.h>
#include "../lib/platform_compat.h"
#include "../lib/tcp_io.h" #include "../lib/tcp_io.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
@ -25,6 +28,7 @@
static struct UASYNC* g_ua = NULL; static struct UASYNC* g_ua = NULL;
static int g_ok = 0, g_done = 0; static int g_ok = 0, g_done = 0;
static int g_conn_count = 0, g_read_count = 0, g_err_count = 0; static int g_conn_count = 0, g_read_count = 0, g_err_count = 0;
#ifndef _WIN32
static pid_t g_children[CHILDREN]; static pid_t g_children[CHILDREN];
static int g_port = 0; static int g_port = 0;
static void* g_mon_id = NULL; static void* g_mon_id = NULL;
@ -103,8 +107,14 @@ static void test_timeout(void* arg) {
g_done = -1; g_done = -1;
} }
#endif /* !_WIN32 */
int main(void) { int main(void) {
printf("=== test_uasync_socket_race ===\n"); fflush(stdout); 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(); debug_config_init();
for (int i = 1; i < DEBUG_CATEGORY_COUNT; i++) debug_set_category_level(i, DEBUG_LEVEL_ERROR); 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_mon_id) uasync_cancel_timeout(g_ua, g_mon_id);
if (g_ua) uasync_destroy(g_ua, 0); if (g_ua) uasync_destroy(g_ua, 0);
return g_ok ? 0 : 1; return g_ok ? 0 : 1;
#endif
} }

Loading…
Cancel
Save