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.
411 lines
23 KiB
411 lines
23 KiB
#ifndef ETCP_CONNECTIONS_H |
|
#define ETCP_CONNECTIONS_H |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
|
|
// подмодуль ETCP который обслуживает сокеты ETCP для приёма-передачи пакетов и одно ETCP подключение через несколько каналов связи (failover) |
|
|
|
#include "secure_channel.h" |
|
#include "utun_instance.h" |
|
#include "etcp_bbr.h" |
|
#include "../lib/socket_compat.h" |
|
#include "../lib/ll_queue.h" |
|
#include <stdint.h> |
|
#include <stddef.h> |
|
|
|
#define IP_UDP_OVERHEAD_V4 (20 + 8) // IP(20)+UDP(8) |
|
#define IP_UDP_OVERHEAD_V6 (40 + 8) // IP(40)+UDP(8) |
|
#define SC_ENCRYPT_OVERHEAD (ETCP_ENCRYPTED_HDR_SIZE + SC_NONCE_SIZE + SC_CRC32_SIZE + SC_TAG_SIZE) // 3+13+4+16=36 |
|
#define UDP_SC_HDR_SIZE (SC_NONCE_SIZE + SC_TAG_SIZE + SC_CRC32_SIZE + 5) // 13+16+4+5=38 — sc overhead без ETCP_HDR + etcp framing |
|
#define ACK_REZERV 100// сколько байт резервировать под ack и прочие заголовки |
|
#define WIRE_OVERHEAD(fam) ((fam) == AF_INET6 ? IP_UDP_OVERHEAD_V6 + SC_ENCRYPT_OVERHEAD : IP_UDP_OVERHEAD_V4 + SC_ENCRYPT_OVERHEAD) |
|
|
|
#define INFLIGHT_LIM_MIN 8192 // 8K |
|
#define INFLIGHT_LIM_MAX 1048576 // 1M |
|
|
|
#define PACKET_DATA_SIZE 2048 |
|
#define PACKET_DATA_MAX_MTU 2048 |
|
#define ETCP_MAX_PAYLOAD_SIZE (PACKET_DATA_SIZE - ETCP_ACK_BASE_SIZE - 5) /* 2035 */ |
|
#define ETCP_RFC791_MIN_MTU 576 |
|
|
|
// Типы кодограмм протокола |
|
#define ETCP_INIT_REQUEST 0x02 |
|
#define ETCP_INIT_RESPONSE 0x03 |
|
#define ETCP_INIT_REQUEST_NOINIT 0x04 |
|
#define ETCP_INIT_RESPONSE_NOINIT 0x05 |
|
#define ETCP_PING 0x06 |
|
#define ETCP_PONG 0x07 |
|
#define ETCP_KEEPALIVE 0x08 |
|
|
|
#define ETCP_PING_FLAG_WANT_RTT 0x01 // в PONG: хочу получить RTT от пингера |
|
#define ETCP_PING_FLAG_SEND_RTT 0x02 // в PING: несу RTT для получателя |
|
|
|
/* Адаптивный keepalive */ |
|
#define KA_PERIOD_MIN_MS 200 |
|
#define KA_PERIOD_MAX_MS 10000 |
|
#define KA_TIMEOUT_MULT 10 /* timeout = period * mult */ |
|
|
|
|
|
#pragma pack(push, 1) |
|
struct ETCP_DGRAM {// пакет (незашифрованный) |
|
struct ETCP_LINK* link;// откуда получена или куда отправялем |
|
uint16_t data_len;// общий размер пакета не включая timestamp |
|
uint16_t noencrypt_len;// число байт (с конца) которые не надо шифровать. для передачи pubkey |
|
uint16_t timestamp;// timestamp отправляющего узла при отправке пакета |
|
uint8_t flag_up:1;// bit0 = up/down (recv_keepalive) |
|
uint8_t data[];// данные пакета (без timestamp) |
|
}; |
|
#pragma pack(pop) |
|
|
|
/* Размер зашифрованного заголовка ETCP_DGRAM (timestamp + flag_up + padding) */ |
|
#define ETCP_ENCRYPTED_HDR_SIZE (offsetof(struct ETCP_DGRAM, data) - offsetof(struct ETCP_DGRAM, timestamp)) |
|
|
|
/* Размер базового ACK: type(1) + count(1) + last_delivered_id(4) + rx_dup_count(2) */ |
|
#define ETCP_ACK_BASE_SIZE (2 + 4 + 2) |
|
|
|
// --- INIT packet wire formats (inside encrypted payload, before padding) --- |
|
|
|
// INIT REQUEST: client → server |
|
struct ETCP_INIT_REQUEST_PKT { |
|
uint8_t code; // 0: ETCP_INIT_REQUEST (0x02) или ETCP_INIT_REQUEST_NOINIT (0x04) |
|
uint8_t node_id[8]; // 1: sender node_id (big-endian) |
|
uint8_t session_id[4]; // 9: session (big-endian) |
|
uint8_t reset_id[8]; // 13: reset epoch id (big-endian) |
|
uint8_t mtu[2]; // 21: client MTU (big-endian) |
|
uint8_t keepalive[2]; // 23: keepalive interval (big-endian) |
|
uint8_t recovery[2]; // 25: recovery interval/100 (big-endian) |
|
uint8_t link_id; // 27: client's local link id |
|
uint8_t socket_id; // 28: client's socket id |
|
uint8_t only_local; // 29: client only_local flag |
|
uint8_t type; // 30: client socket type (CFG_SERVER_TYPE_*) |
|
// V2 fields (NAT_DIRECT detection): |
|
uint8_t src_ipv4[4]; // 31: client interface_addr IPv4 (big-endian, 0 if N/A) |
|
uint8_t src_port[2]; // 35: client interface_addr port (big-endian) |
|
uint8_t collision; // 37: 1 = cross-connect, remote claims master |
|
uint8_t ed25519_pubkey[SC_PUBKEY_SIZE]; // 38: client Ed25519 pubkey (32 bytes) |
|
// V4 fields: |
|
uint8_t device_type; // 70: CLIENT_TYPE_SERVER/DESKTOP/MOBILE |
|
} __attribute__((packed)); |
|
#define ETCP_INIT_REQ_SIZE sizeof(struct ETCP_INIT_REQUEST_PKT) |
|
|
|
// INIT RESPONSE: server → client |
|
struct ETCP_INIT_RESPONSE_PKT { |
|
uint8_t code; // 0: ETCP_INIT_RESPONSE (0x03) или ETCP_INIT_RESPONSE_NOINIT (0x05) |
|
uint8_t node_id[8]; // 1: server node_id (big-endian) |
|
uint8_t session_id[4]; // 9: session (big-endian) |
|
uint8_t reset_id[8]; // 13: reset epoch id (big-endian) |
|
uint8_t mtu[2]; // 21: server MTU (big-endian) |
|
uint8_t link_id; // 23: server's local link id |
|
uint8_t remote_socket_id; // 24: echo of client's socket_id |
|
uint8_t only_local; // 25: server only_local flag |
|
uint8_t type; // 26: server socket type (CFG_SERVER_TYPE_*) |
|
// V2 fields: |
|
uint8_t peer_ipv4[4]; // 27: client's external NAT address (big-endian) |
|
uint8_t peer_port[2]; // 31: client's external NAT port (big-endian) |
|
// V3 fields: |
|
uint8_t ed25519_pubkey[SC_PUBKEY_SIZE]; // 33: server Ed25519 pubkey (32 bytes) |
|
// V4 fields: |
|
uint8_t device_type; // 65: CLIENT_TYPE_SERVER/DESKTOP/MOBILE |
|
uint8_t keepalive[2]; // 66: server keepalive interval (big-endian) |
|
} __attribute__((packed)); |
|
#define ETCP_INIT_RESP_SIZE sizeof(struct ETCP_INIT_RESPONSE_PKT) |
|
|
|
typedef void (*etcp_ping_callback_t)(int success, uint16_t rtt, void* arg, uint64_t nonce, |
|
const uint8_t* resp_data, size_t resp_data_len); |
|
struct PING_CONTEXT { |
|
struct PING_CONTEXT* next; |
|
struct UTUN_INSTANCE* instance; |
|
etcp_ping_callback_t cb; |
|
void* arg; |
|
uint64_t nonce; |
|
void* timeout_timer; |
|
uint64_t send_time; // время отправки пинга в 0.1ms |
|
uint8_t peer_pubkey[SC_PUBKEY_SIZE]; |
|
uint8_t* user_data; |
|
size_t user_data_len; |
|
}; |
|
|
|
#define LINK_ADDR_KEY_SIZE 19 // port(2) + addr(16) + family(1) |
|
|
|
struct link_queue_entry { |
|
uint8_t key[LINK_ADDR_KEY_SIZE]; |
|
struct ETCP_LINK* link; |
|
}; |
|
|
|
// список активных подключений которые обслуживает сокет. каждый сокет может обслуживать много подключений |
|
struct ETCP_SOCKET { |
|
struct ETCP_SOCKET* next; // Linked list для всех соединений |
|
struct UTUN_INSTANCE* instance; |
|
char name[MAX_CONN_NAME_LEN]; |
|
socket_t fd; // UDP socket / TCP listen socket |
|
int mtu; |
|
|
|
uint8_t type; // CFG_SERVER_TYPE_* |
|
uint8_t sock_id; // unique id (0-255) for NAT matching |
|
uint8_t is_tcp; // 1=TCP (STCP), 0=UDP |
|
uint8_t only_local; // 1 = only local, no forwarding (UDP) |
|
uint32_t netif_index; // для sin6_scope_id |
|
struct sockaddr_storage local_addr; |
|
struct sockaddr_storage interface_addr; |
|
struct sockaddr_storage nat_addr; |
|
|
|
/* ── uasync handle (UDP read_cb / TCP accept_cb) ── */ |
|
void* socket_id; |
|
|
|
/* ── UDP-only ── */ |
|
struct ll_queue* links_queue; // hash-очередь линков |
|
int errorcode; |
|
size_t pkt_format_errors; |
|
uint8_t nat_type; // NAT_TYPE_* |
|
uint32_t local_defaultroute_ip; // auto-detected IPv4 (network byte order) |
|
uint8_t local_defaultroute_ip6[16]; |
|
}; |
|
|
|
// NAT check status |
|
#define NAT_CHECK_NONE 0 |
|
#define NAT_CHECK_WAITING 1 |
|
#define NAT_CHECK_IN_PROGRESS 2 |
|
#define NAT_CHECK_EIM 3 |
|
#define NAT_CHECK_STRICT 4 |
|
|
|
// NAT type (detected by server during NAT check) |
|
#define NAT_TYPE_UNKNOWN 0 |
|
#define NAT_TYPE_EIM 1 // Endpoint-Independent Mapping |
|
#define NAT_TYPE_STRICT 2 // Address/Restricted or Symmetric |
|
#define NAT_TYPE_DIRECT 3 // real public IP, no NAT (detected during INIT handshake) |
|
|
|
// Verified NAT types (published in nodeinfo after server-side NAT detection) |
|
// Values above CFG_SERVER_TYPE_PRIVATE to avoid collision with config types |
|
#define NAT_VERIFIED_UNKNOWN 4 // detection failed or inconclusive |
|
#define NAT_VERIFIED_EIM 5 // EIM NAT |
|
#define NAT_VERIFIED_STRICT 6 // strict NAT |
|
#define NAT_VERIFIED_DIRECT 7 // real public IP, no NAT |
|
|
|
|
|
#define LINK_STATE_HANDSHAKE 1 |
|
#define LINK_STATE_TRY_RECONNECT 2 |
|
#define LINK_STATE_CONNECTED 3 |
|
|
|
// Тип функции-перехватчика отправки UDP. |
|
// Если link->send_hook != NULL, etcp_udp_send вызывает её вместо socket_sendto. |
|
struct ETCP_LINK; |
|
typedef ssize_t (*etcp_udp_send_fn_t)(socket_t fd, const void* buf, size_t len, |
|
const struct sockaddr* addr, socklen_t addr_len, |
|
struct ETCP_LINK* link, void* context); |
|
|
|
|
|
// ETCP Link - одно динамическое соединение (один путь) |
|
struct ETCP_LINK { |
|
struct ll_entry* link_queue_entry; // элемент в socket->links_queue |
|
struct ETCP_LINK* next; // Linked list подключений для ETCP_CONN (каждое подключение это child для ETCP_CONN) |
|
|
|
struct ETCP_CONN* etcp; // подключение (parent) |
|
struct ETCP_SOCKET* conn; // сокет через который работаем |
|
// Путь соединения |
|
struct sockaddr_storage remote_addr; // Удалённый адрес |
|
|
|
// Параметры соединения |
|
uint16_t mtu; // MTU общий |
|
uint16_t mtu_local; // MTU моего зла |
|
uint16_t mtu_remote; // MTU удаленного узла |
|
uint16_t keepalive_interval; // Keepalive интервал (x1ms) |
|
uint32_t recovery_interval; // recovery интервал (x0.1ms) |
|
uint8_t is_server; // инициирует подключение клиент |
|
uint8_t initialized; // Флаг инициализации (1=подтверждено или получен request) |
|
uint8_t local_link_id; // id моего линка |
|
uint8_t remote_link_id; // id этого линка на peer (устанавливается в момент initialized) |
|
uint8_t remote_socket_id; // socket id peer |
|
uint8_t remote_only_local; // only_local flag from peer |
|
uint8_t remote_type; // CFG_SERVER_TYPE_* (type of peer's socket) |
|
uint8_t nat_type; // NAT_TYPE_* (detected for this client link) |
|
uint8_t remote_ed25519_pubkey[SC_PUBKEY_SIZE]; // Ed25519 pubkey пира (из INIT handshake) |
|
uint8_t recv_keepalive; // 1 - up, 0 - down (принимаются ли пакеты) |
|
uint8_t remote_keepalive; // 1 - up, 0 - down (удаленная сторона сообщает - принимаются ли у нее пакеты) |
|
uint8_t link_status; // 1 - up, 0 - down (итоговый статус - если есть проблемы на любой стороне - линк down) |
|
uint8_t link_state; // 0 - just init, 1 - handshake, 2 - try reconnect, 3 - connected |
|
|
|
// Состояние установки соединения (только для клиентов) |
|
void* init_timer; // Таймер для повторов INIT (NULL=не подключается) |
|
uint16_t init_timeout; // Текущий таймаут в мс |
|
uint16_t init_retry_count; // Счетчик попыток |
|
|
|
// uint64_t last_activity; // Время последней активности |
|
uint64_t last_recv_local_time; // x0.1 ms |
|
uint16_t last_recv_timestamp; |
|
uint8_t last_recv_updated; // =1 при обновлении timestamp, =0 при отправке (чтобы не дублировать отправки при отсутствии обновлений) |
|
|
|
uint64_t shaper_load_time_tb; // основной в 0.1 мс units |
|
uint64_t shaper_sub_nanotime; // sub 0-999999 для 0.1 нс - 0.1 мс |
|
uint8_t shaper_state; |
|
void* shaper_timer; |
|
|
|
uint32_t inflight_bytes; |
|
uint32_t inflight_packets; |
|
uint32_t inflight_lim_bytes; |
|
|
|
// statistics |
|
size_t encrypt_errors; |
|
size_t decrypt_errors; |
|
size_t send_errors; |
|
size_t recv_errors; |
|
size_t total_encrypted; |
|
size_t total_decrypted; |
|
uint32_t total_retransmissions; |
|
uint64_t acked_bytes; // подтверждённых байт на этом линке |
|
uint64_t acked_packets; // подтверждённых пакетов на этом линке |
|
|
|
uint16_t rtt_last; // round trip (время отправки + приёма) |
|
uint32_t jitter; // Current jitter [>>16] x0.1 ms |
|
// rtt_avg10 удалён — заменён BBR (bbr->min_rtt_us/100) |
|
uint32_t recv_dt_avg_tx; // дельта времени для отправленных пакетов (относительное время отправки) x256 |
|
uint32_t recv_dt_avg_rx; // дельта времени для принятых пакетов (относительное время отправки) x256 |
|
|
|
uint16_t tt_last; // transmit time (время доставки отправленных пакетов) |
|
uint16_t rt_last; // recv time (время доставки принятых пакетов) |
|
uint32_t bandwidth; // Link bandwidth in Kbits/sec |
|
|
|
// NAT address tracking (from INIT_RESPONSE) |
|
uint32_t nat_ip; // NAT IPv4 address (network byte order), 0 = not set |
|
uint16_t nat_port; // NAT port (host byte order) |
|
uint32_t nat_changes_count; // Counter of NAT address changes |
|
uint32_t nat_hits_count; // Counter of NAT address matches (new init response with same IP:port) |
|
uint8_t nat_check_status; // NAT_CHECK_* |
|
|
|
// Keepalive state |
|
void* keepalive_timer; // Таймер для отправки keepalive пакетов |
|
uint32_t keepalive_timeout; // таймаут (ms) |
|
uint16_t ka_period_ms; // адаптивный период отправки keepalive (200→10000->200) |
|
uint8_t ka_pinned; // 1 = период зафиксирован протоколом (standby-режим мобильного), адаптивный рост отключён |
|
uint8_t pkt_sent_since_keepalive; // Флаг: был ли отправлен пакет с последнего keepalive тика |
|
uint32_t keepalive_sent_count; // Счётчик отправленных keepalive |
|
uint32_t keepalive_recv_count; // Счётчик полученных keepalive |
|
uint8_t peer_device_type; // CLIENT_TYPE_* удалённой стороны (из handshake) |
|
uint16_t handshake_minsize; // минимальный размер udp при handshake |
|
uint16_t handshake_maxsize; // мax размер udp при handshake (выбирает рандом) |
|
|
|
// === Burst-измерение bandwidth === |
|
// Sender-сторона |
|
uint16_t burst_id; // монотонно возрастающий ID burst |
|
uint8_t burst_active; // 1 = burst в процессе отправки |
|
uint8_t burst_seq; // текущий номер пакета в burst (0..burst_count-1) |
|
uint8_t burst_count; // общее число пакетов в burst |
|
uint64_t burst_last_time_tb; // время последнего burst (0.1ms), для MIN_BURST_INTERVAL |
|
void* burst_resp_timer; // таймер ожидания ответа на burst |
|
uint32_t burst_target_bdp; // BDP из последнего успешного burst (байты) |
|
uint16_t burst_pkt_size; // сохранённый размер пакета для вычисления BW |
|
|
|
// Receiver-сторона |
|
uint16_t burst_recv_id; // ID отслеживаемого burst |
|
uint8_t burst_recv_count; // ожидаемое число пакетов в burst |
|
uint8_t burst_recv_next_seq; // следующий ожидаемый seq |
|
uint8_t burst_recv_valid; // 1 = порядок пакетов не нарушен |
|
uint8_t burst_recv_received; // сколько пакетов уже принято |
|
uint64_t burst_recv_times[16]; // время прихода каждого пакета (µs) |
|
uint16_t burst_recv_pkt_size; // размер пакета из MEAS_TS (для ответа) |
|
uint8_t burst_resp_pending; // 1 = есть готовый ответ для piggyback |
|
uint32_t burst_resp_gap_avg; // средний inter-packet gap (µs) |
|
uint32_t burst_resp_gap_min; // минимальный inter-packet gap (µs) |
|
uint8_t burst_resp_pkt_count; // число пакетов в измерении |
|
uint8_t burst_resp_valid; // валидность измерения |
|
|
|
// === BBR congestion control === |
|
struct bbr* bbr; // BBR state (per-link, создаётся в etcp_link_new) |
|
uint64_t delivered_bytes; // кумулятивно delivered bytes на линке (для round detection) |
|
uint64_t last_ack_time_tb; // 0.1ms timestamp последнего ACK (для interval_us) |
|
uint32_t bbr_pacing_rate; // bytes/sec output BBR → shaper |
|
uint32_t bbr_loss_since_ack; // счётчик потерь на линке с последнего ACK (для rs->lost) |
|
|
|
etcp_udp_send_fn_t send_hook; // NULL = socket_sendto напрямую |
|
void* send_hook_ctx; |
|
|
|
struct sockaddr_storage local_bound_addr; // локальный адрес к которому привязан линк (interface_addr на момент создания) |
|
uint8_t is_tcp; // 1 = TCP транспорт (STCP) |
|
struct stcp_link *tcp_link; // STCP линк (для TCP) |
|
void *tcp_reconnect_timer; // таймер реконнекта (TCP клиент) |
|
uint32_t tcp_reconnect_delay_ms; // задержка реконнекта (экспоненциальный backoff) |
|
}; |
|
|
|
// Единая точка отправки всех ETCP-пакетов. |
|
ssize_t etcp_udp_send(struct ETCP_LINK* link, socket_t fd, const void* buf, size_t len, |
|
const struct sockaddr* addr, socklen_t addr_len); |
|
|
|
// INITIALIZATION |
|
// Создаёт только listen-сокеты из конфига (серверы для incoming connections) |
|
int init_sockets(struct UTUN_INSTANCE* instance); |
|
// Создаёт listen-сокеты и client connections из конфига |
|
int init_connections(struct UTUN_INSTANCE* instance); |
|
|
|
// SOCKET FUNCTIONS |
|
// добавляет новый версер (сокет для приёма и отправки кодограмм. обслуживает много подключений) |
|
struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_SERVER* server); |
|
// удаляет сокет и освобождает ресурсы (грохает все его подключения и сокет) |
|
void etcp_socket_remove(struct ETCP_SOCKET* conn); |
|
|
|
// TCP socket functions (uses unified ETCP_SOCKET with is_tcp=1) |
|
struct ETCP_SOCKET* tcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_SERVER* server); |
|
void tcp_socket_remove(struct ETCP_SOCKET* sock); |
|
|
|
// Создаёт один серверный сокет (UDP или TCP) из CFG_SERVER. Линки не добавляет. |
|
int etcp_create_server_socket(struct UTUN_INSTANCE* instance, struct CFG_SERVER* server, struct ETCP_SOCKET** out_sock); |
|
|
|
struct stcp_link; |
|
void tcp_server_on_link(struct stcp_link *link, struct ETCP_SOCKET *tcp_sock); |
|
|
|
// connection functions |
|
// создает новый канал связи для etcp подключения (ETCP_CONN) |
|
struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn, struct sockaddr_storage* remote_addr, uint8_t is_server); |
|
void etcp_link_update_inflight_lim(struct ETCP_LINK* link, uint32_t new_lim); |
|
void etcp_link_close(struct ETCP_LINK* link); |
|
//int etcp_input_cbk(struct packet_buffer* pkt, struct ETCP_SOCKET* conn);// получает расшифрованный пакет |
|
int etcp_encrypt_send(struct ETCP_DGRAM* dgram);// зашифровывает и отправляет пакет |
|
// find link by address |
|
struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, struct sockaddr_storage* addr, int is_tcp); |
|
|
|
// find free local_link_id for connection |
|
// scans all links in connection, marks used ids in bit array |
|
// returns first free id (0-255) or -1 if all occupied |
|
int etcp_find_free_local_link_id(struct ETCP_CONN* etcp); |
|
|
|
// Burst measurement functions |
|
void etcp_link_burst_start(struct ETCP_LINK* link); |
|
void etcp_link_burst_check(struct ETCP_LINK* link); |
|
void etcp_link_burst_finish(struct ETCP_LINK* link); |
|
|
|
void etcp_link_enter_init(struct ETCP_LINK *link); |
|
void etcp_link_enter_reinit(struct ETCP_LINK *link); |
|
void etcp_link_enter_ready_tcp(struct ETCP_LINK *link); |
|
void etcp_tcp_link_start_connect(struct ETCP_LINK *link, struct sockaddr_storage *addr, uint16_t port); |
|
void etcp_tcp_link_start_reconnect(struct ETCP_LINK *link); |
|
|
|
int etcp_packet_decrypted(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, |
|
struct ETCP_LINK* link, size_t pkt_len); |
|
|
|
int etcp_send_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubkey_bin, |
|
const struct sockaddr_storage* addr, int timeout_ms, |
|
etcp_ping_callback_t cb, void* user_arg, |
|
const uint8_t* user_data, size_t user_data_len); |
|
|
|
// шлёт пинг на addr используя pubkey. в пакет помещает user_data[user_len]. при получении ответа или таймауте вызывает callback. |
|
// flags: ETCP_PING_FLAG_SEND_RTT — user_data содержит RTT для peer |
|
int etcp_send_ping_to_socket(struct UTUN_INSTANCE* instance, struct ETCP_SOCKET* e_sock, |
|
const uint8_t* peer_pubkey_bin, const struct sockaddr_storage* addr, |
|
int timeout_ms, etcp_ping_callback_t cb, void* user_arg, |
|
const uint8_t* user_data, size_t user_data_len, |
|
uint8_t flags); |
|
|
|
// TCP-ping: подключение к TCP-адресу peer + хендшейк с флагом PING. RTT меряется |
|
// по хендшейку (send→response). cb вызывается один раз (success=1/rtt или success=0). |
|
int etcp_send_tcp_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubkey_bin, |
|
const struct sockaddr_storage* addr, int timeout_ms, |
|
etcp_ping_callback_t cb, void* user_arg); |
|
|
|
void etcp_connections_read_callback_socket(socket_t sock, void* arg); |
|
|
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
#endif // ETCP_CONNECTIONS_H
|
|
|