- Router: unified service delivery format [svc_id][src][dst][payload] (end-to-end src/dst from SVC_ROUTE header) - tcp_proxy_client: replace single tx_buf drop-on-backpressure with bounded tx_queue + send_q waiter + retry timer (no data loss, bulk window reopen — removes 62.5ms delayed-ACK stall) - tcp_io: configurable connect timeout (tcp_conn_set_connect_timeout) - tcp_proxy_server: connect_timeout config option (ms, default 2000, 0=off) - check.sh: run tcp_proxy_full integration test with sudo (skip if passwordless sudo unavailable) - test_tcp_io: connect timeout unit test; docs (lwip_nuances.md)
81 lines
3.1 KiB
C
81 lines
3.1 KiB
C
// icmp_proxy.h — ICMP echo (ping) прокси: клиент ↔ exit через etcp_router
|
||
#ifndef ICMP_PROXY_H
|
||
#define ICMP_PROXY_H
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
|
||
#include <stdint.h>
|
||
#include "../lib/socket_compat.h"
|
||
#include "../routing_layer/etcp_router.h"
|
||
|
||
struct UTUN_INSTANCE;
|
||
struct UASYNC;
|
||
struct ll_entry;
|
||
struct ETCP_CONN;
|
||
|
||
// Подкоманды
|
||
#define ICMP_PROXY_SUBCMD_REQUEST 0x01 // client→exit: пингани dst_ip
|
||
#define ICMP_PROXY_SUBCMD_REPLY 0x02 // exit→client: echo reply
|
||
|
||
// Заголовок сообщения на отправке (включая байт svc_id; src/dst node_id добавляет роутер):
|
||
// svc_id(1) + subcmd(1) + dst_ip(4) + orig_src_ip(4) + icmp_id(2) + icmp_seq(2) + payload
|
||
#define ICMP_PROXY_HDR_SIZE 14
|
||
// Полный заголовок на приёме (после router_deliver):
|
||
// svc_id(1) + src_node_id(8) + dst_node_id(8) + subcmd(1) + dst_ip(4) + orig_src_ip(4) + icmp_id(2) + icmp_seq(2)
|
||
#define ICMP_PROXY_RECV_HDR_SIZE (ROUTER_SVC_PAYLOAD_OFF + 13) // 30
|
||
|
||
// Активный ICMP echo запрос (сторона exit узла)
|
||
struct icmp_request {
|
||
struct icmp_request* next;
|
||
uint64_t client_node_id;
|
||
uint32_t dst_ip;
|
||
uint32_t orig_src_ip; // IP исходного отправителя (чтобы вернуть reply правильному адресату)
|
||
uint16_t echo_id;
|
||
uint16_t echo_seq;
|
||
uint8_t payload[1500];
|
||
size_t payload_len;
|
||
uint64_t sent_tb;
|
||
socket_t sock; // raw сокет (только если per-request)
|
||
};
|
||
|
||
struct icmp_proxy_ctx {
|
||
int initialized;
|
||
int is_exit;
|
||
struct UTUN_INSTANCE* inst;
|
||
struct UASYNC* ua;
|
||
socket_t raw_sock; // один SOCK_RAW для всего ICMP на exit
|
||
void* raw_read_id;
|
||
struct icmp_request* pending;
|
||
uint64_t request_timeout_tb;
|
||
int test_loopback; // 1 = виртуальный loopback без raw сокета (только тесты)
|
||
void* expire_timer; // периодический таймер очистки истёкших запросов
|
||
};
|
||
|
||
extern struct icmp_proxy_ctx* g_icmp_ctx;
|
||
|
||
int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua);
|
||
void icmp_proxy_destroy(struct UTUN_INSTANCE* inst);
|
||
|
||
// Единый etcp_router коллбэк
|
||
void icmp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry);
|
||
|
||
// Сторона клиента: принять IP/ICMP echo request с TUN, отправить через etcp
|
||
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,
|
||
const uint8_t* payload, size_t payload_len);
|
||
|
||
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,
|
||
const uint8_t* payload, size_t payload_len);
|
||
|
||
void icmp_proxy_set_test_loopback(struct UTUN_INSTANCE* inst, int enabled);
|
||
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif // ICMP_PROXY_H
|