Browse Source

перевод комментариев tcp/udp/icmp proxy на русский

congestion
Evgeny 4 months ago
parent
commit
f691c01b45
  1. 18
      src/icmp_proxy.c
  2. 20
      src/icmp_proxy.h
  3. 28
      src/tcp_proxy.c
  4. 24
      src/tcp_proxy.h
  5. 32
      src/udp_proxy.c
  6. 20
      src/udp_proxy.h

18
src/icmp_proxy.c

@ -1,4 +1,4 @@
// icmp_proxy.c — ICMP echo (ping) прокси: client ↔ exit через etcp_router // icmp_proxy.c — ICMP echo (ping) прокси: клиент ↔ exit через etcp_router
#include "icmp_proxy.h" #include "icmp_proxy.h"
#include "etcp.h" #include "etcp.h"
#include "etcp_api.h" #include "etcp_api.h"
@ -35,7 +35,7 @@ static struct icmp_request* req_find_by_id(struct icmp_request* head, uint16_t e
return NULL; return NULL;
} }
// Build and send a raw ICMP echo request // Сборка и отправка raw ICMP echo запроса
static int exit_send_echo(struct UTUN_INSTANCE* inst, uint64_t client_node_id, static int exit_send_echo(struct UTUN_INSTANCE* inst, uint64_t client_node_id,
uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq, uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq,
const uint8_t* payload, size_t payload_len) { const uint8_t* payload, size_t payload_len) {
@ -78,7 +78,7 @@ static int exit_send_echo(struct UTUN_INSTANCE* inst, uint64_t client_node_id,
return 0; return 0;
} }
// Read echo reply from raw socket, match by echo_id // Чтение echo ответа из raw сокета, сопоставление по echo_id
static void raw_read_cb(socket_t sock, void* arg) { static void raw_read_cb(socket_t sock, void* arg) {
(void)sock; (void)arg; (void)sock; (void)arg;
if (!g_icmp_ctx || g_icmp_ctx->raw_sock == SOCKET_INVALID) return; if (!g_icmp_ctx || g_icmp_ctx->raw_sock == SOCKET_INVALID) return;
@ -127,7 +127,7 @@ static void raw_read_cb(socket_t sock, void* arg) {
} }
// ==================================================================== // ====================================================================
// Exit node: receive REQUEST, send echo via raw socket // Exit узел: принять REQUEST, отправить echo через raw сокет
// ==================================================================== // ====================================================================
static void exit_handle_request(struct ETCP_CONN* conn, struct ll_entry* entry) { static void exit_handle_request(struct ETCP_CONN* conn, struct ll_entry* entry) {
struct UTUN_INSTANCE* inst = conn ? conn->instance : (g_icmp_ctx ? g_icmp_ctx->inst : NULL); struct UTUN_INSTANCE* inst = conn ? conn->instance : (g_icmp_ctx ? g_icmp_ctx->inst : NULL);
@ -170,7 +170,7 @@ drop:
} }
// ==================================================================== // ====================================================================
// Client side: receive REPLY, deliver echo reply to TUN // Сторона клиента: принять REPLY, доставить echo ответ в TUN
// ==================================================================== // ====================================================================
static void client_handle_reply(struct ETCP_CONN* conn, struct ll_entry* entry) { static void client_handle_reply(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (entry->len < ICMP_PROXY_HDR_SIZE + 1) { queue_entry_free(entry); queue_dgram_free(entry); return; } if (entry->len < ICMP_PROXY_HDR_SIZE + 1) { queue_entry_free(entry); queue_dgram_free(entry); return; }
@ -190,7 +190,7 @@ static void client_handle_reply(struct ETCP_CONN* conn, struct ll_entry* entry)
} }
// ==================================================================== // ====================================================================
// Unified etcp_router callback // Единый etcp_router коллбэк
// ==================================================================== // ====================================================================
void icmp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) { void icmp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (!entry || !entry->dgram || entry->len < 2) { if (!entry || !entry->dgram || entry->len < 2) {
@ -204,7 +204,7 @@ void icmp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
} }
// ==================================================================== // ====================================================================
// Client side: send ICMP echo request to exit node // Сторона клиента: отправить ICMP echo запрос в exit узел
// ==================================================================== // ====================================================================
int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id, int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq, uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq,
@ -227,7 +227,7 @@ int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
} }
// ==================================================================== // ====================================================================
// Client side: deliver ICMP echo reply to TUN // Сторона клиента: доставить ICMP echo ответ в TUN
// ==================================================================== // ====================================================================
int icmp_proxy_deliver_reply(struct UTUN_INSTANCE* inst, int icmp_proxy_deliver_reply(struct UTUN_INSTANCE* inst,
uint32_t dst_ip, uint32_t src_ip, uint16_t echo_id, uint16_t echo_seq, uint32_t dst_ip, uint32_t src_ip, uint16_t echo_id, uint16_t echo_seq,
@ -298,7 +298,7 @@ static void req_expire(struct icmp_proxy_ctx* ctx) {
} }
// ==================================================================== // ====================================================================
// Public init/destroy // Публичные init/destroy
// ==================================================================== // ====================================================================
int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua) { int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua) {
if (!inst) return -1; if (!inst) return -1;

20
src/icmp_proxy.h

@ -1,4 +1,4 @@
// icmp_proxy.h — ICMP echo (ping) прокси: client ↔ exit через etcp_router // icmp_proxy.h — ICMP echo (ping) прокси: клиент ↔ exit через etcp_router
#ifndef ICMP_PROXY_H #ifndef ICMP_PROXY_H
#define ICMP_PROXY_H #define ICMP_PROXY_H
@ -10,15 +10,15 @@ struct UASYNC;
struct ll_entry; struct ll_entry;
struct ETCP_CONN; struct ETCP_CONN;
// Sub-commands // Подкоманды
#define ICMP_PROXY_SUBCMD_REQUEST 0x01 // client→exit: пингани dst_ip #define ICMP_PROXY_SUBCMD_REQUEST 0x01 // client→exit: пингани dst_ip
#define ICMP_PROXY_SUBCMD_REPLY 0x02 // exit→client: echo reply #define ICMP_PROXY_SUBCMD_REPLY 0x02 // exit→client: echo reply
// Message header (excluding svc_id byte) // Заголовок сообщения (не включая байт svc_id)
// svc_id(1) + subcmd(1) + sender_node_id(8) + dst_ip(4) + orig_src_ip(4) + icmp_id(2) + icmp_seq(2) + payload // svc_id(1) + subcmd(1) + sender_node_id(8) + dst_ip(4) + orig_src_ip(4) + icmp_id(2) + icmp_seq(2) + payload
#define ICMP_PROXY_HDR_SIZE 22 #define ICMP_PROXY_HDR_SIZE 22
// In-flight ICMP echo request (exit node side) // Активный ICMP echo запрос (сторона exit узла)
struct icmp_request { struct icmp_request {
struct icmp_request* next; struct icmp_request* next;
uint64_t client_node_id; uint64_t client_node_id;
@ -29,7 +29,7 @@ struct icmp_request {
uint8_t payload[1500]; uint8_t payload[1500];
size_t payload_len; size_t payload_len;
uint64_t sent_tb; uint64_t sent_tb;
socket_t sock; // raw socket (only if we use per-request) socket_t sock; // raw сокет (только если per-request)
}; };
struct icmp_proxy_ctx { struct icmp_proxy_ctx {
@ -37,21 +37,21 @@ struct icmp_proxy_ctx {
int is_exit; int is_exit;
struct UTUN_INSTANCE* inst; struct UTUN_INSTANCE* inst;
struct UASYNC* ua; struct UASYNC* ua;
socket_t raw_sock; // one SOCK_RAW for all ICMP on exit socket_t raw_sock; // один SOCK_RAW для всего ICMP на exit
void* raw_read_id; void* raw_read_id;
struct icmp_request* pending; struct icmp_request* pending;
uint64_t request_timeout_tb; uint64_t request_timeout_tb;
int test_loopback; // 1 = virtual loopback when no raw socket (test only) int test_loopback; // 1 = виртуальный loopback без raw сокета (только тесты)
void* expire_timer; // periodic cleanup timer for pending requests void* expire_timer; // периодический таймер очистки истёкших запросов
}; };
int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua); int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua);
void icmp_proxy_destroy(struct UTUN_INSTANCE* inst); void icmp_proxy_destroy(struct UTUN_INSTANCE* inst);
// Unified etcp_router callback // Единый etcp_router коллбэк
void icmp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry); void icmp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry);
// Client side: принять IP/ICMP echo request с TUN, отправить через etcp // Сторона клиента: принять IP/ICMP echo request с TUN, отправить через etcp
int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id, int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq, uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq,
const uint8_t* payload, size_t payload_len); const uint8_t* payload, size_t payload_len);

28
src/tcp_proxy.c

@ -1,4 +1,4 @@
// tcp_proxy.c — TCP proxy: lwIP TCP stack → ETCP → remote exit node // tcp_proxy.c — TCP прокси: стек lwIP TCP → ETCP → удалённый exit узел
#include "tcp_proxy.h" #include "tcp_proxy.h"
#include "lwip_tcp/lwip_tcp.h" #include "lwip_tcp/lwip_tcp.h"
#include "lwip_tcp/lwip_tcp_priv.h" #include "lwip_tcp/lwip_tcp_priv.h"
@ -30,7 +30,7 @@
#endif #endif
// ==================================================================== // ====================================================================
// Forward declarations // Предварительные объявления
// ==================================================================== // ====================================================================
static err_t proxy_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); static err_t proxy_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static err_t proxy_sent_cb(void *arg, struct tcp_pcb *pcb, uint16_t len); static err_t proxy_sent_cb(void *arg, struct tcp_pcb *pcb, uint16_t len);
@ -45,7 +45,7 @@ static int proxy_send_msg(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t su
static int send_data(struct proxy_conn* pc, const uint8_t* data, uint16_t len); static int send_data(struct proxy_conn* pc, const uint8_t* data, uint16_t len);
// ==================================================================== // ====================================================================
// ll_entry helper // Помощник ll_entry
// ==================================================================== // ====================================================================
static struct ll_entry* entry_from_data(struct memory_pool* pool, const uint8_t* data, uint16_t len) { static struct ll_entry* entry_from_data(struct memory_pool* pool, const uint8_t* data, uint16_t len) {
struct ll_entry* e = queue_entry_new_from_pool(pool); struct ll_entry* e = queue_entry_new_from_pool(pool);
@ -60,7 +60,7 @@ static struct ll_entry* entry_from_data(struct memory_pool* pool, const uint8_t*
} }
// ==================================================================== // ====================================================================
// Protocol: build and send proxy messages via ETCP // Протокол: сборка и отправка сообщений прокси через ETCP
// ==================================================================== // ====================================================================
static int proxy_send_msg(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t subcmd, static int proxy_send_msg(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t subcmd,
uint32_t sid, uint16_t seq, const uint8_t* data, size_t len) { uint32_t sid, uint16_t seq, const uint8_t* data, size_t len) {
@ -106,7 +106,7 @@ static int send_error(struct proxy_conn* pc) {
} }
// ==================================================================== // ====================================================================
// Output: lwIP TCP sends IP packets through this callback // Вывод: lwIP TCP отправляет IP пакеты через этот callback
// ==================================================================== // ====================================================================
static err_t tcp_output_cb(void *arg, struct pbuf *p, uint32_t src_ip, uint32_t dst_ip) { static err_t tcp_output_cb(void *arg, struct pbuf *p, uint32_t src_ip, uint32_t dst_ip) {
struct tcp_proxy *proxy = (struct tcp_proxy *)arg; struct tcp_proxy *proxy = (struct tcp_proxy *)arg;
@ -127,7 +127,7 @@ static err_t tcp_output_cb(void *arg, struct pbuf *p, uint32_t src_ip, uint32_t
} }
// ==================================================================== // ====================================================================
// Non-TCP handler (UDP/ICMP proxy) // Обработчик не-TCP (UDP/ICMP прокси)
// ==================================================================== // ====================================================================
static int tcp_proxy_handle_non_tcp(struct tcp_proxy* p, uint8_t* buf, size_t len) { static int tcp_proxy_handle_non_tcp(struct tcp_proxy* p, uint8_t* buf, size_t len) {
if (len < 20) return 0; if (len < 20) return 0;
@ -157,7 +157,7 @@ static int tcp_proxy_handle_non_tcp(struct tcp_proxy* p, uint8_t* buf, size_t le
} }
// ==================================================================== // ====================================================================
// Helper: feed data from to_lwip queue to lwIP TCP // Помощник: передача данных из очереди to_lwip в lwIP TCP
// ==================================================================== // ====================================================================
static void proxy_feed_from_transport(struct proxy_conn *pc) { static void proxy_feed_from_transport(struct proxy_conn *pc) {
if (!pc->to_lwip || !pc->pcb) return; if (!pc->to_lwip || !pc->pcb) return;
@ -182,7 +182,7 @@ static void proxy_feed_from_transport(struct proxy_conn *pc) {
} }
// ==================================================================== // ====================================================================
// lwIP TCP callbacks // lwIP TCP коллбэки
// ==================================================================== // ====================================================================
static err_t proxy_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { static err_t proxy_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) {
struct tcp_proxy *p = (struct tcp_proxy *)arg; struct tcp_proxy *p = (struct tcp_proxy *)arg;
@ -319,7 +319,7 @@ static err_t proxy_poll_cb(void *arg, struct tcp_pcb *pcb) {
} }
// ==================================================================== // ====================================================================
// Ensure dynamic listen pcb for transparent outbound TCP proxying // Обеспечить динамический listen pcb для прозрачного исходящего TCP проксирования
// ==================================================================== // ====================================================================
static void tcp_proxy_ensure_outbound_listen(struct tcp_proxy* p, uint16_t dport_net) { static void tcp_proxy_ensure_outbound_listen(struct tcp_proxy* p, uint16_t dport_net) {
uint16_t dport_host = ntohs(dport_net); uint16_t dport_host = ntohs(dport_net);
@ -336,7 +336,7 @@ static void tcp_proxy_ensure_outbound_listen(struct tcp_proxy* p, uint16_t dport
} }
// ==================================================================== // ====================================================================
// Input: IP packet → lwip_tcp (from TUN output_queue) // Ввод: IP пакет → lwip_tcp (из TUN output_queue)
// ==================================================================== // ====================================================================
static void tcp_proxy_tun_input(struct ll_queue* q, void* arg) { static void tcp_proxy_tun_input(struct ll_queue* q, void* arg) {
struct tcp_proxy* p = (struct tcp_proxy*)arg; struct tcp_proxy* p = (struct tcp_proxy*)arg;
@ -367,7 +367,7 @@ static void tcp_proxy_tun_input(struct ll_queue* q, void* arg) {
} }
// ==================================================================== // ====================================================================
// proxy_conn cleanup // Очистка proxy_conn
// ==================================================================== // ====================================================================
static void proxy_conn_free(struct proxy_conn *pc) { static void proxy_conn_free(struct proxy_conn *pc) {
if (!pc) return; if (!pc) return;
@ -387,7 +387,7 @@ static void proxy_conn_free(struct proxy_conn *pc) {
} }
// ==================================================================== // ====================================================================
// Incoming message handlers (client side) // Обработчики входящих сообщений (сторона клиента)
// ==================================================================== // ====================================================================
static struct proxy_conn* find_pc_by_stream(struct tcp_proxy* p, uint32_t stream_id) { static struct proxy_conn* find_pc_by_stream(struct tcp_proxy* p, uint32_t stream_id) {
struct proxy_conn* pc; struct proxy_conn* pc;
@ -467,7 +467,7 @@ static void handle_error(struct tcp_proxy* p, uint32_t stream_id) {
} }
// ==================================================================== // ====================================================================
// Unified etcp_router handler (dispatches to tcp_proxy or remote_proxy) // Единый обработчик etcp_router (диспетчеризация в tcp_proxy или remote_proxy)
// ==================================================================== // ====================================================================
void tcp_proxy_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) { void tcp_proxy_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (!entry || !entry->dgram || entry->len < TCP_PROXY_HDR_SIZE) { if (!entry || !entry->dgram || entry->len < TCP_PROXY_HDR_SIZE) {
@ -503,7 +503,7 @@ void tcp_proxy_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
} }
// ==================================================================== // ====================================================================
// Public API // Публичное API
// ==================================================================== // ====================================================================
struct tcp_proxy* tcp_proxy_create(struct UTUN_INSTANCE* inst, struct UASYNC* ua, 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, const char* tun_name, const char* tun_ip, int mtu, int test_mode,

24
src/tcp_proxy.h

@ -1,4 +1,4 @@
// tcp_proxy.h — TCP proxy: lwIP TCP stack → ETCP → remote exit node // tcp_proxy.h — TCP прокси: стек lwIP TCP → ETCP → удалённый exit узел
#ifndef TCP_PROXY_H #ifndef TCP_PROXY_H
#define TCP_PROXY_H #define TCP_PROXY_H
@ -25,19 +25,19 @@ struct proxy_conn {
struct tcp_pcb* pcb; struct tcp_pcb* pcb;
uint32_t stream_id; uint32_t stream_id;
uint16_t send_seq; // 16-bit circular, only for DATA uint16_t send_seq; // 16-битный циклический, только для DATA
uint16_t recv_last_seq; // last received seq for gap detection uint16_t recv_last_seq; // последний принятый seq для обнаружения пропусков
uint8_t recv_init; // first DATA received uint8_t recv_init; // первый DATA принят
struct ll_queue* to_lwip; // DATA from exit → lwIP (flow control) struct ll_queue* to_lwip; // DATA от exit → lwIP (управление потоком)
uint8_t* send_buf; // lwIP→exit data until CONNECTED uint8_t* send_buf; // данные lwIP→exit до CONNECTED
uint16_t send_len; uint16_t send_len;
uint8_t tun_closed; // lwIP side sent FIN uint8_t tun_closed; // сторона lwIP отправила FIN
uint8_t rem_closed; // exit sent CLOSE uint8_t rem_closed; // exit отправил CLOSE
uint8_t error; // error condition, cleanup immediately uint8_t error; // ошибка, немедленная очистка
uint8_t close_sent; // we sent CLOSE/ERROR to exit uint8_t close_sent; // отправили CLOSE/ERROR в exit
uint8_t connected; // CONNECTED(OK) received from exit uint8_t connected; // CONNECTED(OK) получен от exit
uint8_t dest_ip[4]; uint8_t dest_ip[4];
uint16_t dest_port; uint16_t dest_port;
@ -54,7 +54,7 @@ struct tcp_proxy {
uint64_t via_node_id; uint64_t via_node_id;
struct lwip_tcp_ctx* lwip; struct lwip_tcp_ctx* lwip;
struct tcp_proxy_mapping_config* mappings; // pointer to config struct tcp_proxy_mapping_config* mappings; // указатель на конфиг
int mapping_count; int mapping_count;
}; };

32
src/udp_proxy.c

@ -1,4 +1,4 @@
// udp_proxy.c — UDP datagram прокси: client ↔ exit через etcp_router // udp_proxy.c — UDP датаграммный прокси: клиент ↔ exit через etcp_router
#include "udp_proxy.h" #include "udp_proxy.h"
#include "etcp.h" #include "etcp.h"
#include "etcp_api.h" #include "etcp_api.h"
@ -20,7 +20,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#define UDP_FLOW_TIMEOUT_TB 600000 // 60s #define UDP_FLOW_TIMEOUT_TB 600000 // 60с
static struct udp_proxy_ctx* g_udp_ctx = NULL; static struct udp_proxy_ctx* g_udp_ctx = NULL;
@ -47,7 +47,7 @@ static void flow_read_cb(socket_t sock, void* arg) {
f->last_activity_tb = get_time_tb(); f->last_activity_tb = get_time_tb();
// Wrap reply: swap src/dst for client-side reconstruction // Обернуть ответ: меняем src/dst для восстановления на стороне клиента
struct ll_entry* e = queue_entry_new(0); struct ll_entry* e = queue_entry_new(0);
if (!e) return; if (!e) return;
e->dgram = u_malloc(UDP_PROXY_HDR_SIZE + n); e->dgram = u_malloc(UDP_PROXY_HDR_SIZE + n);
@ -55,10 +55,10 @@ static void flow_read_cb(socket_t sock, void* arg) {
e->dgram[0] = ETCP_ID_UDP_PROXY; e->dgram[0] = ETCP_ID_UDP_PROXY;
e->dgram[1] = UDP_PROXY_SUBCMD_DATA; e->dgram[1] = UDP_PROXY_SUBCMD_DATA;
memcpy(e->dgram + 2, &f->client_node_id, 8); memcpy(e->dgram + 2, &f->client_node_id, 8);
// Reply src = original dst_ip:dest_port // Ответ src = оригинальный dst_ip:dest_port
memcpy(e->dgram + 10, &f->dst_ip, 4); memcpy(e->dgram + 10, &f->dst_ip, 4);
memcpy(e->dgram + 14, &f->dst_port, 2); memcpy(e->dgram + 14, &f->dst_port, 2);
// Reply dst = original src_ip:src_port // Ответ dst = оригинальный src_ip:src_port
memcpy(e->dgram + 16, &f->src_ip, 4); memcpy(e->dgram + 16, &f->src_ip, 4);
memcpy(e->dgram + 20, &f->src_port, 2); memcpy(e->dgram + 20, &f->src_port, 2);
memcpy(e->dgram + UDP_PROXY_HDR_SIZE, buf, n); memcpy(e->dgram + UDP_PROXY_HDR_SIZE, buf, n);
@ -68,7 +68,7 @@ static void flow_read_cb(socket_t sock, void* arg) {
} }
// ==================================================================== // ====================================================================
// Exit node: receive REQUEST, create socket, forward // Exit узел: принять REQUEST, создать сокет, переслать
// ==================================================================== // ====================================================================
static void exit_handle_data(struct ETCP_CONN* conn, struct ll_entry* entry) { static void exit_handle_data(struct ETCP_CONN* conn, struct ll_entry* entry) {
struct UTUN_INSTANCE* inst = conn ? conn->instance : (g_udp_ctx ? g_udp_ctx->inst : NULL); struct UTUN_INSTANCE* inst = conn ? conn->instance : (g_udp_ctx ? g_udp_ctx->inst : NULL);
@ -111,19 +111,19 @@ drop:
} }
// ==================================================================== // ====================================================================
// Client side: receive REPLY, deliver to TUN // Сторона клиента: принять REPLY, доставить в TUN
// ==================================================================== // ====================================================================
static void client_handle_reply(struct ETCP_CONN* conn, struct ll_entry* entry) { static void client_handle_reply(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (entry->len < UDP_PROXY_HDR_SIZE + 1) { queue_entry_free(entry); queue_dgram_free(entry); return; } if (entry->len < UDP_PROXY_HDR_SIZE + 1) { queue_entry_free(entry); queue_dgram_free(entry); return; }
// svc_id already consumed by etcp_router dispatch // svc_id уже обработан диспетчером etcp_router
uint32_t src_ip, dst_ip; uint32_t src_ip, dst_ip;
uint16_t src_port, dst_port; uint16_t src_port, dst_port;
uint8_t* payload = entry->dgram + 1 + 1 + 8 + 4 + 2 + 4 + 2; // svc_id + subcmd + node_id + src + dst uint8_t* payload = entry->dgram + 1 + 1 + 8 + 4 + 2 + 4 + 2; // svc_id + subcmd + node_id + src_ip:port + dst_ip:port
size_t payload_len = entry->len - UDP_PROXY_HDR_SIZE; size_t payload_len = entry->len - UDP_PROXY_HDR_SIZE;
memcpy(&dst_ip, entry->dgram + 1 + 1 + 8 + 4 + 2, 4); // src in message → dst in reply memcpy(&dst_ip, entry->dgram + 1 + 1 + 8 + 4 + 2, 4); // src в сообщении → dst в ответе
memcpy(&dst_port, entry->dgram + 1 + 1 + 8 + 4 + 2 + 4, 2); memcpy(&dst_port, entry->dgram + 1 + 1 + 8 + 4 + 2 + 4, 2);
memcpy(&src_ip, entry->dgram + 1 + 1 + 8, 4); // dst in message → src in reply memcpy(&src_ip, entry->dgram + 1 + 1 + 8, 4); // dst в сообщении → src в ответе
memcpy(&src_port, entry->dgram + 1 + 1 + 8 + 4, 2); memcpy(&src_port, entry->dgram + 1 + 1 + 8 + 4, 2);
struct UTUN_INSTANCE* inst = conn ? conn->instance : (g_udp_ctx ? g_udp_ctx->inst : NULL); struct UTUN_INSTANCE* inst = conn ? conn->instance : (g_udp_ctx ? g_udp_ctx->inst : NULL);
@ -132,7 +132,7 @@ static void client_handle_reply(struct ETCP_CONN* conn, struct ll_entry* entry)
} }
// ==================================================================== // ====================================================================
// Unified etcp_router callback // Единый etcp_router коллбэк
// ==================================================================== // ====================================================================
void udp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) { void udp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (!entry || !entry->dgram || entry->len < 2) { if (!entry || !entry->dgram || entry->len < 2) {
@ -149,7 +149,7 @@ void udp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
} }
// ==================================================================== // ====================================================================
// Client side: send UDP datagram to exit node // Сторона клиента: отправить UDP датаграмму в exit узел
// ==================================================================== // ====================================================================
int udp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id, int udp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
uint32_t src_ip, uint16_t src_port, uint32_t src_ip, uint16_t src_port,
@ -173,7 +173,7 @@ int udp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
} }
// ==================================================================== // ====================================================================
// Client side: deliver UDP reply to TUN // Сторона клиента: доставить UDP ответ в TUN
// ==================================================================== // ====================================================================
int udp_proxy_deliver_reply(struct UTUN_INSTANCE* inst, int udp_proxy_deliver_reply(struct UTUN_INSTANCE* inst,
uint32_t src_ip, uint16_t src_port, uint32_t src_ip, uint16_t src_port,
@ -181,7 +181,7 @@ int udp_proxy_deliver_reply(struct UTUN_INSTANCE* inst,
const uint8_t* payload, size_t payload_len) { const uint8_t* payload, size_t payload_len) {
if (!inst || !inst->tcp_proxy || !inst->tcp_proxy->tun) return -1; if (!inst || !inst->tcp_proxy || !inst->tcp_proxy->tun) return -1;
// Build IP/UDP reply packet // Собрать IP/UDP ответный пакет
size_t ip_len = 20 + 8 + payload_len; size_t ip_len = 20 + 8 + payload_len;
uint8_t* pkt = u_malloc(ip_len); uint8_t* pkt = u_malloc(ip_len);
if (!pkt) return -1; if (!pkt) return -1;
@ -233,7 +233,7 @@ static void flow_expire(struct udp_proxy_ctx* ctx) {
} }
// ==================================================================== // ====================================================================
// Public init/destroy // Публичные init/destroy
// ==================================================================== // ====================================================================
int udp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua) { int udp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua) {
if (!inst) return -1; if (!inst) return -1;

20
src/udp_proxy.h

@ -1,4 +1,4 @@
// udp_proxy.h — UDP datagram прокси: client ↔ exit через etcp_router // udp_proxy.h — UDP датаграммный прокси: клиент ↔ exit через etcp_router
#ifndef UDP_PROXY_H #ifndef UDP_PROXY_H
#define UDP_PROXY_H #define UDP_PROXY_H
@ -10,14 +10,14 @@ struct UASYNC;
struct ll_entry; struct ll_entry;
struct ETCP_CONN; struct ETCP_CONN;
// Sub-commands // Подкоманды
#define UDP_PROXY_SUBCMD_DATA 0x01 // client→exit: пробрось датаграмму | exit→client: ответ #define UDP_PROXY_SUBCMD_DATA 0x01 // client→exit: пробрось датаграмму | exit→client: ответ
// Message header (excluding svc_id byte) // Заголовок сообщения (не включая байт svc_id)
// svc_id(1) + subcmd(1) + sender_node_id(8) + src_ip(4) + src_port(2) + dst_ip(4) + dst_port(2) + payload // svc_id(1) + subcmd(1) + sender_node_id(8) + src_ip(4) + src_port(2) + dst_ip(4) + dst_port(2) + payload
#define UDP_PROXY_HDR_SIZE 22 #define UDP_PROXY_HDR_SIZE 22
// One UDP flow (exit node side: maps client_node_id + addr tuple to OS socket) // Один UDP поток (сторона exit узла: сопоставляет client_node_id + кортеж адресов с OS сокетом)
struct udp_flow { struct udp_flow {
struct udp_flow* next; struct udp_flow* next;
uint64_t client_node_id; uint64_t client_node_id;
@ -34,29 +34,29 @@ struct udp_flow {
struct udp_proxy_ctx { struct udp_proxy_ctx {
int initialized; int initialized;
int is_exit; // 1=exit node (создаёт сокеты), 0=client (шлёт через etcp) int is_exit; // 1=exit узел (создаёт сокеты), 0=клиент (шлёт через etcp)
struct UTUN_INSTANCE* inst; struct UTUN_INSTANCE* inst;
struct UASYNC* ua; struct UASYNC* ua;
struct udp_flow* flows; struct udp_flow* flows;
int flow_count; int flow_count;
uint64_t flow_timeout_tb; uint64_t flow_timeout_tb;
void* expire_timer; // periodic cleanup timer for expired flows void* expire_timer; // периодический таймер очистки истёкших потоков
}; };
int udp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua); int udp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua);
void udp_proxy_destroy(struct UTUN_INSTANCE* inst); void udp_proxy_destroy(struct UTUN_INSTANCE* inst);
// Exit node: принимает REQUEST, создаёт сокет, шлёт данные // Exit узел: принимает REQUEST, создаёт сокет, шлёт данные
// Client side: принимает REPLY, доставляет на TUN // Сторона клиента: принимает REPLY, доставляет на TUN
void udp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry); void udp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry);
// Client side: принять IP/UDP пакет с TUN, отправить через etcp_route_send // Сторона клиента: принять IP/UDP пакет с TUN, отправить через etcp_route_send
int udp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id, int udp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
uint32_t src_ip, uint16_t src_port, uint32_t src_ip, uint16_t src_port,
uint32_t dst_ip, uint16_t dst_port, uint32_t dst_ip, uint16_t dst_port,
const uint8_t* payload, size_t payload_len); const uint8_t* payload, size_t payload_len);
// Client side: доставить ответ на TUN (вызывается из recv_cb) // Сторона клиента: доставить ответ на TUN (вызывается из recv_cb)
int udp_proxy_deliver_reply(struct UTUN_INSTANCE* inst, int udp_proxy_deliver_reply(struct UTUN_INSTANCE* inst,
uint32_t src_ip, uint16_t src_port, uint32_t src_ip, uint16_t src_port,
uint32_t dst_ip, uint16_t dst_port, uint32_t dst_ip, uint16_t dst_port,

Loading…
Cancel
Save