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
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
|
|
|