Document NAT ownership, packet formats and API contracts
This commit is contained in:
1 parent
bfa23afae9
commit
19a5870d5f
3 files changed
+49
-23
No files matched your search
+2
-1
@@ -184,7 +184,8 @@ struct global_config {
|
||||
int allowed_keys_count;
|
||||
int allowed_keys_allow_all;
|
||||
|
||||
// NAT configuration ([nat] section)
|
||||
// Опции [nat] включают NAT; forward=proto:node_id_hex:IPv4:internal_port:external_port.
|
||||
// Ошибки parse_nat отклоняют весь конфиг; диапазон портов дополнительно проверяет eim_nat_init_ctx.
|
||||
int nat_enabled;
|
||||
char nat_tun_ifname[16];
|
||||
struct IP nat_tun_ip;
|
||||
|
||||
+32
-16
@@ -5,7 +5,9 @@
|
||||
* IPv4 UDP: отключённая checksum=0 сохраняется; вычисленный ноль записывается как 0xffff.
|
||||
* Перед обработкой нужен инициализированный ctx; вызовы последовательны в uasync-потоке.
|
||||
* gateway/internal IP — host order, internal_port — network order, внешний порт — host order.
|
||||
* src_conn заимствован; срок жизни и выбор транспорта обратной отправки контролирует nat_transport. */
|
||||
* Записи живут до destroy_ctx, автоматического истечения/освобождения портов нет.
|
||||
* Фрагменты и неподдерживаемые протоколы возвращаются без изменений с кодом 0.
|
||||
* src_conn только сохраняется при создании динамической записи, для отправки не используется. */
|
||||
#ifndef EIM_NAT_H
|
||||
#define EIM_NAT_H
|
||||
|
||||
@@ -30,39 +32,53 @@ struct ETCP_CONN;
|
||||
#define IPPROTO_ICMP_UINT8 1
|
||||
|
||||
struct eim_nat_entry {
|
||||
uint32_t internal_ip;
|
||||
uint16_t internal_port;
|
||||
uint8_t proto;
|
||||
uint8_t state;
|
||||
uint64_t src_node_id; // which node sent the original packet
|
||||
uint64_t last_seen;
|
||||
struct ETCP_CONN* src_conn; // cached connection for sendback
|
||||
uint32_t internal_ip; // Внутренний IPv4, host order.
|
||||
uint16_t internal_port; // Внутренний TCP/UDP-порт или ICMP echo ID, network order.
|
||||
uint8_t proto; // IPPROTO_*_UINT8.
|
||||
uint8_t state; // EIM_NAT_ENTRY_FREE / ACTIVE / STATIC.
|
||||
uint64_t src_node_id; // Узел-владелец mapping и адресат обратной отправки.
|
||||
uint64_t last_seen; // Резерв, остаётся 0; таймауты записей не реализованы.
|
||||
struct ETCP_CONN* src_conn; // Заимствованная метка исходного conn, может быть NULL; модуль её не разыменовывает.
|
||||
};
|
||||
|
||||
// Состояние преобразования; TUN и транспортные ресурсы принадлежат nat_transport.
|
||||
struct eim_nat_ctx {
|
||||
uint32_t gateway_ip;
|
||||
uint32_t gateway_ip; // Внешний IPv4 NAT, host order; nat_tun_ip, иначе tun_ip.
|
||||
uint16_t port_start; // Начало динамического диапазона включительно; 1 <= port_start < port_end.
|
||||
uint16_t port_end; // Конец диапазона включительно; допускается 65535.
|
||||
uint16_t next_port;
|
||||
struct eim_nat_entry* table;
|
||||
size_t table_size;
|
||||
int initialized;
|
||||
uint16_t next_port; // Следующая позиция циклического поиска свободного динамического порта.
|
||||
struct eim_nat_entry* table; // Владеет table_size записями; индекс — внешний порт/echo ID для всех протоколов вместе.
|
||||
size_t table_size; // EIM_NAT_TABLE_SIZE при успешной инициализации.
|
||||
int initialized; // 1 — таблица создана; 0 — NAT отключён, не создан или уничтожен.
|
||||
};
|
||||
|
||||
struct global_config;
|
||||
|
||||
/* Создать ctx по g: IPv4 шлюза, 1 <= port_start < port_end <= 65535, статические пробросы.
|
||||
* ctx не должен владеть предыдущей таблицей: перед повторным init вызвать destroy_ctx.
|
||||
* 0 — успех (при !nat_enabled таблица не создаётся); -1 — ошибка, созданная таблица освобождена. */
|
||||
int eim_nat_init_ctx(struct eim_nat_ctx* ctx, const struct global_config* g);
|
||||
/* Освободить таблицу и обнулить созданный ctx; NULL и повторное уничтожение допустимы. */
|
||||
void eim_nat_destroy_ctx(struct eim_nat_ctx* ctx);
|
||||
|
||||
/* 0 — обработано или пакет не подлежит NAT, -1 — ошибка; буфер принадлежит вызывающему. */
|
||||
/* Изменить source IP и порт/echo ID в ip_data (ip_len байтов IPv4), выделив/переиспользовав mapping.
|
||||
* src_node_id — владелец записи; src_conn — необязательная заимствованная метка только для новой ACTIVE-записи.
|
||||
* Контрольные суммы должны быть корректны до вызова: модуль их обновляет, но не проверяет.
|
||||
* ctx создан, ip_data — полный доступный для записи IPv4-пакет; буфер остаётся у вызывающего.
|
||||
* 0 — преобразован или пропущен без изменений; -1 — короткий заголовок/неверный IHL/исчерпан пул. */
|
||||
int eim_nat_egress(struct eim_nat_ctx* ctx, uint8_t* ip_data, size_t ip_len,
|
||||
uint64_t src_node_id, struct ETCP_CONN* src_conn);
|
||||
/* out_entry изменяется только при найденном mapping; заранее установить *out_entry=NULL.
|
||||
* Запись заимствована у ctx. 0 само по себе не означает, что пакет был преобразован. */
|
||||
/* Для пакета на gateway_ip найти запись по внешнему порту/echo ID и протоколу, восстановить destination.
|
||||
* ctx/ip_data/checksum — как у egress. out_entry необязателен и изменяется только при найденном mapping:
|
||||
* заранее установить *out_entry=NULL. Запись заимствована у ctx до destroy_ctx.
|
||||
* 0 — преобразован или не найден/не поддерживается; -1 — короткий заголовок/неверный IHL. */
|
||||
int eim_nat_ingress(struct eim_nat_ctx* ctx, uint8_t* ip_data, size_t ip_len,
|
||||
struct eim_nat_entry** out_entry);
|
||||
|
||||
/* Добавить TCP/UDP-проброс на node_id != 0: internal_ip_host — IPv4 host order,
|
||||
* internal_port_net — ненулевой порт network order; external_port — 1..65535 host order,
|
||||
* включая порты вне динамического диапазона. Ответ владельца использует тот же внешний порт.
|
||||
* 0 — добавлен; -1 — ctx не создан, неверные аргументы, занят внешний порт или уже есть такой внутренний ключ. */
|
||||
int eim_nat_add_forward(struct eim_nat_ctx* ctx, uint8_t proto,
|
||||
uint32_t internal_ip_host, uint16_t internal_port_net,
|
||||
uint16_t external_port, uint64_t node_id);
|
||||
|
||||
+15
-6
@@ -2,7 +2,11 @@
|
||||
* nat_via_node_id задаёт удалённого провайдера; при 0 узел сам выполняет eim_nat для клиентов.
|
||||
* Приём ограничен группой UTUN; клиент принимает ответы только от настроенного провайдера.
|
||||
* init создаёт TUN/обработчики по nat_enabled; destroy снимает их и освобождает ресурсы.
|
||||
* Контекст принадлежит UTUN_INSTANCE; очереди и callbacks работают в uasync. */
|
||||
* TUN-очередь содержит [prefix:1][IP]; tun_write принимает только IP без prefix.
|
||||
* Отправка роутеру: [svc_id:1][IP], владение entry/dgram передаётся ему даже при ошибке.
|
||||
* Приём использует общий ROUTER_SVC_HDR_SIZE=26: [svc][src][dst][flags][group][IP].
|
||||
* Клиент не создаёт таблицу eim_nat: inst->nat.initialized служит флагом готовности транспорта.
|
||||
* Контекст принадлежит UTUN_INSTANCE; все вызовы и callbacks работают в его uasync-потоке. */
|
||||
#ifndef NAT_TRANSPORT_H
|
||||
#define NAT_TRANSPORT_H
|
||||
|
||||
@@ -14,18 +18,23 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
|
||||
struct tun_if;
|
||||
struct ETCP_CONN;
|
||||
|
||||
struct nat_transport_ctx {
|
||||
uint64_t self_node_id;
|
||||
uint64_t nat_via_node_id;
|
||||
struct tun_if* nat_tun;
|
||||
int initialized;
|
||||
uint64_t self_node_id; // Копия локального ID, установленная при init.
|
||||
uint64_t nat_via_node_id; // 0 — провайдер; иначе ID единственного NAT-провайдера клиента.
|
||||
struct tun_if* nat_tun; // Отдельный принадлежащий модулю TUN, MTU=TUN_MTU_DEFAULT.
|
||||
int initialized; // TUN, binding и callback созданы; 0 при отключённом NAT/после destroy.
|
||||
};
|
||||
|
||||
struct UTUN_INSTANCE;
|
||||
|
||||
/* inst и inst->config обязательны, ядро/роутер уже созданы; перед повторным init вызвать destroy.
|
||||
* Создать отдельный TUN и binding ETCP_RT_ID_NAT; провайдер также создаёт eim_nat.
|
||||
* 0 — успех, включая выключенный NAT; -1 — ошибка, созданные NAT-ресурсы освобождены.
|
||||
* Настройка внешних маршрутов/доступа в интернет выполняется отдельно от этого API. */
|
||||
int nat_transport_init(struct UTUN_INSTANCE* inst);
|
||||
/* Снять binding, закрыть NAT TUN и уничтожить eim_nat; NULL и повторный вызов допустимы.
|
||||
* Вызвать до освобождения роутера/uasync, вне выполняемого NAT callback. */
|
||||
void nat_transport_destroy(struct UTUN_INSTANCE* inst);
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user