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)
{
if (!pcb || pcb->state == LISTEN) return;
pcb->poll = poll;
pcb->pollfn = poll;
pcb->pollinterval = interval;
}

2
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;

7
src/lwip_tcp/lwip_tcp_priv.h

@ -27,10 +27,7 @@
#ifndef _WIN32
#include <arpa/inet.h>
#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 <winsock2.h>
#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)

23
src/proxy/icmp_proxy.c

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

32
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 {

2
tests/bbr_integration/test_bbr_integration.c

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

2
tests/test_etcp_congestion.c

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

2
tests/test_etcp_dummynet.c

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

2
tests/test_etcp_reinit_inflight.c

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

2
tests/test_ipv6_sockets.c

@ -15,7 +15,9 @@
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include "../lib/platform_compat.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_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;

11
tests/test_socks_http_proxy.c

@ -6,12 +6,14 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifndef _WIN32
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#endif
#include <sys/stat.h>
#include <fcntl.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 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
}

5
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
}

14
tests/test_tcp_proxy_server.c

@ -3,12 +3,15 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifndef _WIN32
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#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;
}

11
tests/test_uasync_socket_race.c

@ -5,13 +5,16 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifndef _WIN32
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#endif
#include <fcntl.h>
#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
}

Loading…
Cancel
Save