Files
utun2/lib/platform_compat_doc.md
T
evgeny 38c9f229bc stcp: ed25519 pubkey exchange in handshake, fix instance destroy segfault, fix chat_tcp_test
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll
- stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close
- utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP),
  add deferred drain in both Phase J and L
- stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39,
  exchange ed25519_pubkey in both handshake directions
- etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in
  etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb
- chat_sync.c: fix lk->conn NULL dereference for TCP links
- test_stcp.c: update stcp_server_create/stcp_client_connect callsites
- tools/chat_tcp_test: change transport udp→tcp
2026-08-07 00:48:27 +03:00

4.3 KiB
Raw Blame History

platform_compat — Cross-platform compatibility layer

1. Назначение

Унифицирует различия между POSIX (Linux/FreeBSD) и Windows (MSYS2 UCRT64) на уровне системных вызовов и типов. Предоставляет единый API для байтового порядка, строковых функций, энтропии, работы с сетевыми интерфейсами и времени. Полностью заголовочный (inline) для макросов и тривиальных обёрток, .c только для нетривиальных реализаций.

2. Как пользоваться

Подключить "platform_compat.h" — всё остальное разрешается автоматически в зависимости от _WIN32.

Байтовый порядок

uint16_t v16 = htobe16(x);    // host → big-endian
uint32_t v32 = be32toh(x);    // big-endian → host
uint64_t v64 = be64toh(x);    // big-endian → host
// На Linux использует <endian.h>, на Windows — _byteswap_*

Криптостойкий random

uint8_t salt[8];
if (random_bytes(salt, sizeof(salt)) != 0) { /* ошибка */ }
// Linux: /dev/urandom, Windows: BCryptGenRandom

Сетевые интерфейсы

// Определить интерфейс маршрута по умолчанию
uint32_t ifidx = get_default_route_netif_index(AF_INET);   // или AF_INET6

// Получить IPv4 адрес интерфейса по индексу
uint32_t ipv4 = get_interface_ip_by_index(ifidx);           // network byte order

// Получить IPv6 адрес (постоянный или временный)
uint8_t ipv6[16];
if (get_interface_ipv6_by_index(ifidx, 1, ipv6) == 0) {    // temporary=1
    // ipv6 содержит 16 байт адреса
}

Windows: get_interface_ip_by_index, get_interface_ipv6_by_index, get_default_route_netif_index — заглушки (возвращают 0/-1).

Время

struct timeval tv;
utun_gettimeofday(&tv, NULL);   // макрос: на Linux → gettimeofday, на Windows → inline-реализация

Прочее

  • strcasecmp/strncasecmp — на Windows _stricmp/_strnicmp
  • memmem — на Windows inline-реализация compat_memmem
  • pipe — на Windows _pipe с _O_BINARY
  • poll — на Windows WSAPoll, флаги POLLIN/POLLOUT и т.д. определены если отсутствуют
  • ssize_t — определён если отсутствует
  • fcntl — на Windows упрощённая реализация только для F_SETFL/O_NONBLOCK
  • utun_mkdir — кроссплатформенный mkdir

Ограничения

  • Функции сетевых интерфейсов работают только на POSIX, на Windows — заглушки
  • get_default_route_netif_index создаёт временный UDP-сокет к 8.8.8.8 (IPv4) или 2001:4860:4860::8888 (IPv6) для определения интерфейса
  • Только IPv4/IPv6; family только AF_INET или AF_INET6

3. API

Байтовый порядок

Макрос Назначение
htobe16(x) / be16toh(x) 16-bit host ↔ big-endian
htobe32(x) / be32toh(x) 32-bit host ↔ big-endian
htobe64(x) / be64toh(x) 64-bit host ↔ big-endian

Основные функции

Функция Назначение
random_bytes(buffer, len) Криптостойкие случайные байты. 0 — успех, -1 — ошибка
get_interface_ip_by_index(ifindex) IPv4 адрес интерфейса в network byte order, 0 при ошибке
get_interface_ipv6_by_index(ifindex, temporary, out) IPv6 адрес (temporary=1 — временный privacy-адрес), 0 — успех
get_default_route_netif_index(family) ifindex дефолтного маршрута через connect() к внешнему IP

Макросы-заменители (условные)

Макрос Назначение
utun_gettimeofday(tv, tz) gettimeofday (inline на Windows)
utun_mkdir(path, mode) mkdir