116 lines
7.2 KiB
C
116 lines
7.2 KiB
C
/* Клиент TCP-прокси: принимает IPv4 с отдельного TUN через lwIP либо TCP от SOCKS/HTTP listener.
|
||
* Передаёт потоки через UTUN-router на via_node_id; proxy_flow обеспечивает окно и backpressure.
|
||
* create/destroy и callbacks — в uasync. Владеет созданными TUN/lwIP/listener/потоками,
|
||
* заимствует inst/ua/mappings до destroy. Без пары непустых tun_name/tun_ip работает только SOCKS/HTTP.
|
||
* Владелец сам записывает результат create в inst->tcp_proxy_client и обнуляет поле после destroy.
|
||
* Клиент принимает TCP-ответы только от via_node_id в TOPO_GROUP_UTUN; UDP/ICMP требуют TUN. */
|
||
#ifndef TCP_PROXY_CLIENT_H
|
||
#define TCP_PROXY_CLIENT_H
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
|
||
#include <stdint.h>
|
||
#include "proxy_protocol.h"
|
||
#include <stddef.h>
|
||
#include "../lib/socket_compat.h"
|
||
#include "../lib/ll_queue.h"
|
||
|
||
struct UASYNC;
|
||
struct UTUN_INSTANCE;
|
||
struct ETCP_CONN;
|
||
struct tun_if;
|
||
struct ll_queue;
|
||
struct ll_entry;
|
||
struct memory_pool;
|
||
struct tcp_proxy_client_mapping_config;
|
||
struct tcp_proxy_server;
|
||
struct lwip_tcp_ctx;
|
||
struct socks_proxy_conn;
|
||
struct listen_ctx;
|
||
|
||
struct tcp_pcb;
|
||
|
||
struct tcp_proxy_client_conn {
|
||
struct tcp_proxy_client_conn* next; // следующий lwIP-поток клиента
|
||
struct tcp_proxy_client* proxy; // заимствованный владелец
|
||
struct tcp_pcb* pcb; // принадлежит lwIP; NULL после detach/err callback
|
||
|
||
struct proxy_flow flow; // окно и retry CONNECTED/WINDOW/FIN
|
||
uint32_t stream_id; // общий генератор с SOCKS/HTTP-потоками
|
||
|
||
struct ll_queue* to_lwip; // DATA от exit → lwIP (управление потоком)
|
||
|
||
uint8_t fin_local; // локальная сторона отправила FIN (lwIP)
|
||
uint8_t fin_remote; // exit отправил FIN (назначение закрылось)
|
||
uint8_t fin_deferred; // FIN от exit пришёл, но отложен до дренажа to_lwip
|
||
uint8_t rem_closed; // exit отправил CLOSE
|
||
uint8_t error; // ошибка, немедленная очистка
|
||
uint8_t close_sent; // отправили CLOSE/ERROR в exit
|
||
uint8_t close_pending; // CLOSE/ERROR не принят router, повтор в poll/free пока pc жив
|
||
|
||
struct ll_queue* tx_queue; // буфер lwIP→ETCP при backpressure (аналог server read_queue)
|
||
struct queue_waiter_handle tx_waiter; // waiter на send_q (etcp_router_on_send_ready)
|
||
void* tx_retry_timer; // safety-net 500 мс, повтор DATA с force=1 (окно proxy сохраняется)
|
||
|
||
uint32_t bytes_to_exit; // байт принято router для exit (из lwIP/TUN)
|
||
uint32_t bytes_from_exit; // байт получено от exit (в lwIP/TUN)
|
||
uint32_t bp_count; // счётчик backpressure (send fail)
|
||
|
||
uint8_t dest_ip[4]; // IPv4 назначения в сетевом порядке
|
||
uint16_t dest_port; // порт назначения в сетевом порядке
|
||
};
|
||
|
||
struct tcp_proxy_client {
|
||
struct UTUN_INSTANCE* inst; // заимствован; NULL допустим для автономного TUN smoke test
|
||
struct UASYNC* ua; // заимствованный event loop
|
||
struct tun_if* tun; // собственный TUN или NULL для SOCKS/HTTP без TUN
|
||
struct tcp_proxy_client_conn* conns; // список собственных lwIP-потоков
|
||
int conn_count; // число lwIP-потоков, без SOCKS/HTTP
|
||
struct memory_pool* entry_pool; // собственный пул ll_entry для очередей lwIP-потоков
|
||
uint32_t next_stream_id; // общий счётчик TUN/SOCKS/HTTP, init=1, перед выдачей инкрементируется
|
||
uint64_t via_node_id; // настроенный exit для всех потоков
|
||
struct lwip_tcp_ctx* lwip; // собственный TCP-стек или NULL без TUN
|
||
|
||
struct tcp_proxy_client_mapping_config* mappings; // указатель на конфиг
|
||
int mapping_count; // число записей mappings, порты конфига в host byte order
|
||
|
||
// SOCKS proxy
|
||
int socks_enabled; // запрошен SOCKS5; не гарантирует успешный listener
|
||
struct socks_proxy_conn* socks_conns; // собственные SOCKS5-клиенты
|
||
int socks_conn_count; // число SOCKS5-клиентов
|
||
struct listen_ctx* socks_listen; // собственный listener или NULL при отключении/ошибке
|
||
|
||
// HTTP forward proxy и CONNECT
|
||
int http_proxy_enabled; // запрошен HTTP; не гарантирует успешный listener
|
||
struct socks_proxy_conn* http_conns; // собственные HTTP-клиенты
|
||
int http_conn_count; // число HTTP-клиентов
|
||
struct listen_ctx* http_listen; // собственный listener или NULL при отключении/ошибке
|
||
};
|
||
|
||
// Создать клиент; ua обязателен. Непустые tun_name И tun_ip включают TUN/lwIP (mtu<=0 → 1500).
|
||
// test_mode передаётся tun_init_nat: ненулевой использует тестовый TUN; mappings заимствуются до destroy.
|
||
// SOCKS/HTTP создаются при enabled и непустом IPv4:port; via_node_id — общий exit.
|
||
// Результат: собственный p или NULL при критической ошибке/отсутствии режима.
|
||
// Ошибки listener/router bind/UDP/ICMP не делают create атомарным: проверять listener и диагностику отдельно.
|
||
struct tcp_proxy_client* tcp_proxy_client_create(struct UTUN_INSTANCE* inst, struct UASYNC* ua,
|
||
const char* tun_name, const char* tun_ip, int mtu, int test_mode,
|
||
struct tcp_proxy_client_mapping_config* mappings, int mapping_count,
|
||
uint64_t via_node_id,
|
||
int socks_enabled, const char* socks_addr,
|
||
int http_proxy_enabled, const char* http_proxy_addr);
|
||
// Остановить listeners, освободить потоки/TUN/lwIP и снять router binding; NULL допустим.
|
||
// UDP/ICMP сохраняются, пока включён сервер того же inst. Не обнуляет inst->tcp_proxy_client.
|
||
void tcp_proxy_client_destroy(struct tcp_proxy_client* p);
|
||
// Router callback: conn->instance задаёт владельца, entry содержит метаданные router и передаёт владение.
|
||
// Освобождает entry/dgram при любом исходе; CLOSE_ALL = пустой payload router, а не TCP-подкоманда.
|
||
void tcp_proxy_client_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry);
|
||
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif // TCP_PROXY_CLIENT_H
|