Consolidate platform adapter documentation in header
This commit is contained in:
1 parent
1c4010ebed
commit
4f3f6d3e60
2 files changed
+12
-88
No files matched your search
+12
-7
@@ -2,6 +2,12 @@
|
||||
* platform_compat — общие заголовки POSIX/Windows и адаптеры отсутствующих POSIX-функций.
|
||||
* Также предоставляет криптографический random_bytes, адреса интерфейсов, выбор default route
|
||||
* и классификацию публичных IPv4. Сокетные типы/ошибки и nonblocking API — в socket_compat.h.
|
||||
* Подключать этот заголовок вместо прямых POSIX includes для общего кода.
|
||||
* Windows: htobe*/be*toh через byteswap, strcasecmp/strncasecmp через _stricmp/_strnicmp,
|
||||
* memmem через inline-поиск (пустой образец возвращает начало), poll через WSAPoll, mkdir через _mkdir.
|
||||
* utun_gettimeofday — календарное Unix-время (не монотонное); Windows игнорирует tz.
|
||||
* Windows pipe — _pipe(4096, _O_BINARY). fcntl: F_GETFL возвращает 0, F_SETFL с O_NONBLOCK включает
|
||||
* неблокирующий режим; остальные флаги игнорируются, обратное переключение этим адаптером не выполняется.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_COMPAT_H
|
||||
@@ -178,12 +184,12 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Generate cryptographically secure random bytes
|
||||
// Returns 0 on success, -1 on error
|
||||
// Заполняет buffer криптографическими случайными байтами: POSIX /dev/urandom, Windows BCryptGenRandom.
|
||||
// buffer не NULL, len > 0 (Windows: помещается в ULONG). 0 — всё заполнено, -1 — ошибка/неполное чтение.
|
||||
int random_bytes(uint8_t *buffer, size_t len);
|
||||
|
||||
// Get IPv4 address of interface by its index (ifindex)
|
||||
// Returns IPv4 address in network byte order, 0 on error
|
||||
// POSIX: getifaddrs; Windows: IP Helper. Адрес в network byte order, 0 при ошибке/отсутствии адреса.
|
||||
uint32_t get_interface_ip_by_index(uint32_t netif_index);
|
||||
|
||||
// Get IPv6 address of interface by its index (ifindex)
|
||||
@@ -200,15 +206,14 @@ int get_interface_ipv6_by_index(uint32_t netif_index, int temporary, uint8_t* ad
|
||||
int get_interface_ipv6_addr_nl(uint32_t netif_index, int prefer_stable, uint8_t* addr_out);
|
||||
|
||||
// Determine the interface index for the default route (outgoing traffic)
|
||||
// POSIX: UDP connect к фиксированному внешнему адресу, затем сопоставление локального IP с getifaddrs().
|
||||
// POSIX: UDP connect к 8.8.8.8:53 или [2001:4860:4860::8888]:53, сопоставление локального IP с getifaddrs().
|
||||
// Windows: GetBestInterfaceEx к тому же адресу. Результат — выбранный маршрут к этому адресу,
|
||||
// который может отличаться от default route при более специфичных маршрутах.
|
||||
// family: AF_INET or AF_INET6, returns ifindex (0 on failure)
|
||||
uint32_t get_default_route_netif_index(int family);
|
||||
|
||||
// Классифицирует IPv4-адрес (network byte order):
|
||||
// 1 = глобальный/публичный (маршрутизируемый в интернете),
|
||||
// 0 = приватный, CGNAT, loopback, link-local, multicast или зарезервированный.
|
||||
// Классифицирует IPv4 (network byte order) по встроенному списку: 0 для 0/8, 10/8, 127/8, 169.254/16,
|
||||
// 172.16/12, 192.168/16, 100.64/10, 224/4 и 240/4; 1 для остальных. Это не проверка достижимости адреса.
|
||||
int ip_is_public(uint32_t addr_be);
|
||||
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
# 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 |
|
||||
Reference in new issue
Block a user