You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

113 lines
5.0 KiB

// tcp_proxy.h — TCP proxy: lwIP TCP stack ↔ ll_queue ↔ transport → destination
// Modes: TUN (use_tun=1) or raw-fd (use_tun=0, socketpair etc.)
// Supports port forwarding + EIM NAT + half-close + active connections + remote proxy
#ifndef TCP_PROXY_H
#define TCP_PROXY_H
#include <stdint.h>
#include <stddef.h>
#include "../lib/socket_compat.h"
struct UASYNC;
struct UTUN_INSTANCE;
struct ETCP_CONN;
struct tun_if;
struct ll_queue;
struct ll_entry;
struct memory_pool;
struct tcp_proxy_mapping_config;
struct remote_proxy_ctx;
struct lwip_tcp_ctx;
// Transport abstraction (local OS socket or remote via ETCP)
struct tcp_proxy_transport;
struct tcp_proxy_transport_ops {
int (*send)(struct tcp_proxy_transport* t, const uint8_t* data, size_t len);
void (*close)(struct tcp_proxy_transport* t);
void (*destroy)(struct tcp_proxy_transport* t);
};
struct tcp_proxy_transport {
struct tcp_proxy_transport_ops* ops;
};
// Port mapping (static from config or dynamic from EIM NAT)
struct tcp_proxy_mapping {
struct tcp_proxy_mapping* next;
uint16_t local_port;
uint8_t remote_ip[4];
uint16_t remote_port;
int dynamic;
uint64_t created_tb;
uint64_t delete_at_tb;
};
// Forward declarations
struct tcp_pcb;
struct tcp_pcb_listen;
// One proxy connection: TCP PCB ↔ ll_queues ↔ transport ↔ destination
struct proxy_conn {
struct proxy_conn* next;
struct tcp_proxy* proxy;
struct tcp_pcb* pcb;
struct tcp_pcb_listen* listen_pcb; // for listening connection tracking
struct tcp_proxy_transport* transport;
struct ll_queue* uip_to_transport; // data: TCP → transport or remote→test (active)
struct ll_queue* transport_to_uip; // data: transport → TCP or test→remote (active)
uint8_t dest_ip[4]; // proxy target IP (where to forward OS socket)
uint32_t tun_ip; // TUN IP (what client connected to, for uip_hostaddr)
uint16_t dest_port;
int closing;
int half_closed;
int active; // 1 = outgoing connection
struct tcp_proxy_mapping* eim_mapping;
uint64_t remote_stream_id; // stream ID for remote proxy (0=local)
};
// Main TCP proxy module
struct tcp_proxy {
struct UTUN_INSTANCE* inst;
struct UASYNC* ua;
struct tun_if* tun; // TUN interface (NULL in raw-fd mode)
int ip_fd; // raw IP fd (only when tun==NULL)
void* ip_fd_id; // uasync socket id for ip_fd
struct proxy_conn* conns;
int conn_count;
struct memory_pool* entry_pool;
struct tcp_proxy_mapping* mappings;
int eim_timeout_tb;
uint64_t next_stream_id; // counter for remote proxy stream IDs
uint64_t via_node_id; // узел через который проксируются все forward (0=локально)
int has_remote_mappings; // 1=via_node_id задан и не равен local node_id
struct lwip_tcp_ctx* lwip; // lwIP TCP stack context
uint32_t tun_ip_addr; // TUN IP (network byte order) for reply packets
int ip_fd_mode; // 1=raw fd input, 0=TUN input
// Framed read: для raw-fd mode, где поток байт не сохраняет границы пакетов
uint8_t raw_buf[2002]; // 2-byte len + max IP packet (MTU=1500 + 2B prefix)
size_t raw_pos; // сколько байт уже получено в текущем кадре
uint16_t raw_need; // сколько ещё байт ждать (0=ждём 2-байтный заголовок)
};
// ========== API ==========
// Create TCP proxy
// use_tun=1: TUN mode (needs root), uses tun_name/tun_ip/mtu/test_mode, ip_fd ignored
// use_tun=0: raw-fd mode, uses ip_fd for IP packet I/O, TUN params ignored
struct tcp_proxy* tcp_proxy_create(struct UTUN_INSTANCE* inst, struct UASYNC* ua,
const char* tun_name, const char* tun_ip, int mtu, int test_mode,
struct tcp_proxy_mapping_config* mappings, int mapping_count,
int eim_timeout_sec, int use_tun, int ip_fd, uint64_t via_node_id);
void tcp_proxy_destroy(struct tcp_proxy* p);
// Active (outgoing) connections — for test client or EIM NAT
struct proxy_conn* tcp_proxy_active_open (struct tcp_proxy* p, const char* dest_ip, uint16_t dest_port);
int tcp_proxy_active_send (struct tcp_proxy* p, struct proxy_conn* pc, const uint8_t* data, size_t len);
ssize_t tcp_proxy_active_recv (struct tcp_proxy* p, struct proxy_conn* pc, uint8_t* buf, size_t len);
int tcp_proxy_active_close(struct tcp_proxy* p, struct proxy_conn* pc);
int tcp_proxy_active_send_done(struct tcp_proxy* p, struct proxy_conn* pc); // 1=all queued data sent
// etcp_router handler for incoming proxy messages (called from etcp_router dispatch)
void tcp_proxy_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry);
#endif // TCP_PROXY_H