// etcp.h - ETCP Protocol Header (refactored based on etcp_protocol.txt) #ifndef ETCP_H #define ETCP_H #include "etcp_connections.h" #include "secure_channel.h" #include "../lib/ll_queue.h" #include #ifdef __cplusplus extern "C" { #endif #include "pkt_normalizer.h" struct stcp_link; // forward declaration // In struct ETCP_CONN, add: //struct pn_pair* normalizer; // Forward declarations struct UTUN_INSTANCE; struct ETCP_CONN; typedef void (*etcp_on_conn_ready)(struct ETCP_CONN* conn, void* arg); struct UASYNC; uint16_t get_current_timestamp(void); // ETCP packet section types (from protocol spec) #define ETCP_SECTION_PAYLOAD 0x00 // Data payload #define ETCP_SECTION_ACK 0x01 // ACK section #define ETCP_SECTION_TIMESTAMP 0x06 // Channel timestamp (example, adjust if needed) #define ETCP_SECTION_MEAS_TS 0x07 // Measurement timestamp for bandwidth (burst packet) #define ETCP_SECTION_MEAS_RESP 0x08 // Measurement response (burst result) #define ETCP_SECTION_FILLER 0x09 // Filler/dummy data (discarded by receiver) // Burst measurement constants #define BURST_PACKET_COUNT 12 // число пакетов в burst #define BURST_SKIP_COUNT 3 // сколько первых пакетов пропустить при замере gap #define MIN_BURST_INTERVAL_TB 5000 // минимальный интервал между burst (500ms в 0.1ms) #define BURST_RESP_TIMEOUT_TB 20000 // таймаут ожидания ответа на burst (2s в 0.1ms) // Inflight phases #define INFLIGHT_PHASE_SLOW_START 0 #define INFLIGHT_PHASE_CONG_AVOIDANCE 1 // Section sizes #define MEAS_TS_SECTION_SIZE 9 // type(1) + burst_id(2) + flags(1) + seq(1) + ts_us(2) + pkt_sz(2) #define MEAS_RESP_SECTION_SIZE 13 // type(1) + burst_id(2) + valid(1) + gap_avg(4) + gap_min(4) + pkt_count(1) #define FILLER_HDR_SIZE 3 // type(1) + len(2) // MEAS_TS flags #define MEAS_FLAG_IS_FILLER 0x01 // пакет содержит FILLER вместо PAYLOAD #define MEAS_FLAG_IS_LAST 0x02 // последний пакет в burst #define MEAS_FLAG_IS_FIRST 0x04 // первый пакет в burst // MEAS_RESP valid #define MEAS_RESP_VALID 1 #define INFLIGHT_STATE_WAIT_ACK 0 #define INFLIGHT_STATE_WAIT_SEND 1 #define INFLIGHT_INITIAL_HASH_SIZE 1024 #define MAX_INFLIGHT_SIZE 16384 // максимальное число элементов в inflight приёмной очереди (для предотвращения атак) #define ASM_BUF_MAX_SIZE (64 * 1024) // максимальный размер буфера сборки фрагментов // в этот список пакет добавляется когда перемещается из input_queue в input_send_q, при этом к пакету добавляется struct INFLIGHT_PACKET из inflight_pool. // пакет полностью удаляется когда приходит ACK (либо conn_reset/close) struct INFLIGHT_PACKET {// выделяется из etcp->inflight_pool struct ll_entry ll; uint32_t seq; // packet seq (ID по документации) struct ETCP_LINK* last_link; // Last sent link uint64_t last_timestamp; // Last send timestamp uint8_t send_count; // Number of sends uint8_t retrans_req_count; // Number of retrans requests uint8_t state; // WAIT_ACK or WAIT_SEND uint8_t send_hist[8]; // через какие каналы передавался пакет (NEW). send_count - head ptr uint64_t delivered_at_send; // link->delivered_bytes на момент отправки (для BBR prior_delivered) uint32_t inflight_at_send; // link->inflight_bytes на момент отправки (для BBR tx_in_flight) uint8_t is_app_limited; // данные ограничены приложением на момент отправки }; // Список пакетов для сборки. собирается в ll_queue (используем быстрый поиск с хешем) struct ETCP_FRAGMENT {// выделяется из пула etcp->rx_pool struct ll_entry ll; uint32_t seq; uint16_t timestamp; }; struct ACK_PACKET { struct ll_entry ll; uint32_t seq;// sequence number uint16_t pkt_timestamp;// timestamp пакета (часы уладенной стороны) uint32_t recv_timestamp;// время приема (локальное) }; #define ETCP_TX_STATE_DATA_WAIT 1 #define ETCP_TX_STATE_LINK_WAIT 2 // ETCP connection structure (refactored) struct ETCP_CONN { struct ETCP_CONN* next; int mtu; struct UTUN_INSTANCE* instance; // Links (channels) - linked list struct ETCP_LINK* links; struct ETCP_LINK* last_rr_link; // последний линк, выбранный round-robin struct stcp_link *transport_link; // non-NULL for TCP connections // Crypto and state struct secure_channel crypto_ctx; struct PKTNORM* normalizer; // Peer info uint64_t peer_node_id; // Peer node ID // ============ Processing incoming data to be sent by ETCP struct ll_queue* input_queue; // Incoming packets to send (rx_pool -> ETCP_FRAGMENT) // Inflight очереди (2 шт) - пока пакет в статусе inflight - к нему прикрепляется struct INFLIGHT_PACKET struct memory_pool* inflight_pool; // память для inflight очередей struct memory_pool* io_pool; // память для rx очередей struct ll_queue* input_send_q; // очередь на отправку (inflight_pool -> INFLIGHT_PACKET) struct ll_queue* input_wait_ack; // очередь ожидающих подтверждение (inflight_pool -> struct INFLIGHT_PACKET) struct ll_queue* ack_q; // неотправленные подтверждения приема пакетов (instance.ack_pool -> struct ACK_PACKET) + index [+0 SEQ] struct ll_queue* recv_q; // очередь на сборку фрагментированных пакетов(rx_pool -> struct ETCP_FRAGMENT) + index [+0 SEQ] void (*link_ready_for_send_fn)(struct ETCP_CONN*);// функцию которую должен вызвать драйвер линка при готовности линка принимать данные struct ll_queue* output_queue; // Assembled outgoing packets (storage: ETCP_FRAGMENT / rx_pool) // IDs and state uint32_t next_tx_id; // ID для добавления в очередь отправки (с этим id будет добавлен следующий пакет) uint32_t last_rx_id; // Last received ID uint32_t last_delivered_id; // Last delivered to output_queue uint32_t rx_ack_till;// из ack пакета - по какой пакет получено и собрано на удаленной стороне // Metrics (RTT, jitter, etc.) // uint16_t retrans_delay; // Not used uint16_t rtt_last;// round-trip time uint16_t tt_last;// transmission time (время пакета до меня) // uint16_t rxt_last;// recv relative time (бустро регаирует на изменение задержки rx и медленно на изменение задержки tx) uint16_t rtt_avg_10; uint16_t rtt_avg_100; uint16_t jitter; uint32_t bytes_sent_total; // uint32_t bytes_received_total; // Not used uint32_t retransmissions_count; uint32_t reinit_count; uint32_t reset_count; // uint32_t bytes_sent_norx; // сколько отправили байт без единого ответного пакета (для детекции запроса реконнекта) // Window and inflight management uint32_t unacked_bytes; // Current inflight bytes uint32_t max_inflight; // Max inflight cap from config (bbr_max_cwnd) uint32_t optimal_inflight; // Sum over links // Timers void* retrans_timer; // Retrans check timer void* ack_resp_timer; // ACK send timer // Bandwidth measurement state // uint8_t burst_in_progress; // Burst transmission flag - Not used // uint16_t burst_start_id; // Start ID for burst - Not used // Statistics counters uint32_t ack_packets_count; // Count of ACK packets received // uint16_t last_rx_ack_id; // Last ACK ID received - Not used uint16_t rtt_history[10]; // RTT history for jitter calculation (RTT_HISTORY_SIZE=10) uint8_t rtt_history_idx; // Current index in RTT history // uint32_t total_packets_sent; // Total packets sent counter - Not used // Flags uint8_t routing_exchange_active; // 0-не активен, 1-надо инициировать (клиент), 2-обмен идёт, 3-завершён, 4-пропущен (нет BGP) uint8_t got_initial_pkt; // uint8_t initialized; // 0 - только созданный ETCP, 1 - хотя бы один линк проинициалзирован (обмен ключами произведен) uint32_t session_id; // случайный ID сессии (генерируется клиентом) для защиты от ложного reinit uint8_t tx_state; // 0 - n/a, 1 - data_wait (queues empty), 2 - link_wait (link busy) uint8_t links_up; // 0 - канал не готов для передачи, 1 - канал готов для передачи (хотя бы один линк не down) // Callback for ready notification etcp_on_conn_ready ready_cbk; // callback при готовности соединения void* ready_arg; // аргумент для ready_cbk etcp_on_conn_ready up_cbk; // callback при готовности соединения void* up_arg; // аргумент для ready_cbk etcp_on_conn_ready down_cbk; // callback при готовности соединения void* down_arg; // аргумент для ready_cbk void (*bgp_ready_cbk)(struct ETCP_CONN* conn); // вызывается когда BGP готов (завершён или пропущен) uint32_t cnt_ack_hit_inf; // счетчик удлений из inflight uint32_t cnt_ack_hit_sndq; // счетчик удалений inflight пакетов из sndq uint32_t cnt_ack_miss; // счетчик не найденных ack uint32_t cnt_link_wait; // счетчик переходов в ожидание когда link busy uint32_t rx_dup_count; // счетчик принятых дубликатов (локальные) uint32_t tx_dup_count; // счетчик дубликатов удаленной стороны (из ACK) uint32_t debug[8]; // 8 значений для дебага (live watch) // Logging identifier (format: "XXXX→XXXX [name]" - last 4 digits of local and peer node_id + optional name) char log_name[256]; char* name; // Connection name from config (e.g., "client_test1"), or NULL/empty }; // Functions struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* name); void etcp_connection_close(struct ETCP_CONN* etcp); void etcp_conn_reset(struct ETCP_CONN* etcp); void etcp_links_reset(struct ETCP_CONN* etcp); void etcp_conn_reinit(struct ETCP_CONN* etcp); void etcp_connection_ready(struct ETCP_CONN* etcp);// вызывается когда подключение инициализировано // Отправка: используем api ll_queue для очереди ETCP_CONN.input_queue // Прием: используем api ll_queue для очереди ETCP_CONN.output_queue // для очередей используется формат // Input from etcp_connections (decrypted packet) void etcp_conn_input(struct ETCP_DGRAM* pkt); // Send data through ETCP connection // Allocates memory from data_pool and places in input queue // Returns: 0 on success, -1 on failure int etcp_int_send(struct ETCP_CONN* etcp, const void* data, uint16_t len); // Request next packet for load balancer struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp); // Process ACK receipt - remove acknowledged packet from inflight queues void etcp_ack_recv(struct ETCP_CONN* etcp, uint32_t seq, uint16_t ts, uint16_t dts); // Recalculate optimal_inflight and resume input queue after link inflight_lim change void etcp_conn_on_inflight_lim_changed(struct ETCP_CONN* etcp); // Update log_name when peer_node_id becomes known void etcp_update_log_name(struct ETCP_CONN* etcp); // Вызывается стеком etcp когда соединение установлено (можно передавать данные) void etcp_conn_ready(struct ETCP_CONN* conn); void etcp_on_link_down(struct ETCP_CONN* etcp); void etcp_update_mtu(struct ETCP_CONN* etcp); #ifdef __cplusplus } #endif #endif // ETCP_H