Files
utun2/src/proxy/tcp_proxy_client.h
T

116 lines
7.2 KiB
C
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.
/* Клиент 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