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

82 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# platform_compat — Cross-platform compatibility layer
## 1. Назначение
Унифицирует различия между POSIX (Linux/FreeBSD) и Windows (MSYS2 UCRT64) на уровне системных вызовов и типов. Предоставляет единый API для байтового порядка, строковых функций, энтропии, работы с сетевыми интерфейсами и времени. Полностью заголовочный (inline) для макросов и тривиальных обёрток, `.c` только для нетривиальных реализаций.
## 2. Как пользоваться
Подключить `"platform_compat.h"` — всё остальное разрешается автоматически в зависимости от `_WIN32`.
### Байтовый порядок
```c
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
```c
uint8_t salt[8];
if (random_bytes(salt, sizeof(salt)) != 0) { /* ошибка */ }
// Linux: /dev/urandom, Windows: BCryptGenRandom
```
### Сетевые интерфейсы
```c
// Определить интерфейс маршрута по умолчанию
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).
### Время
```c
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 |