// icmp_proxy.h — ICMP echo (ping) прокси: клиент ↔ exit через etcp_router #ifndef ICMP_PROXY_H #define ICMP_PROXY_H #include #include "../lib/socket_compat.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) // 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 // Активный 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; // периодический таймер очистки истёкших запросов }; 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); #endif // ICMP_PROXY_H