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.
155 lines
9.4 KiB
155 lines
9.4 KiB
#ifndef ETCP_CONNECTIONS_H |
|
#define ETCP_CONNECTIONS_H |
|
|
|
// подмодуль ETCP который обслуживает сокеты ETCP для приёма-передачи пакетов и одно ETCP подключение через несколько каналов связи (failover) |
|
|
|
#include "secure_channel.h" |
|
#include "utun_instance.h" |
|
#include "../lib/socket_compat.h" |
|
#include <stdint.h> |
|
|
|
#define PACKET_DATA_SIZE 1600//1536 |
|
|
|
// Типы кодограмм протокола |
|
#define ETCP_INIT_REQUEST 0x02 |
|
#define ETCP_INIT_RESPONSE 0x03 |
|
#define ETCP_INIT_REQUEST_NOINIT 0x04 |
|
#define ETCP_INIT_RESPONSE_NOINIT 0x05 |
|
|
|
|
|
#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[0];// данные пакета (без timestamp) |
|
}; |
|
#pragma pack(pop) |
|
|
|
// список активных подключений которые обслуживает сокет. каждый сокет может обслуживать много подключений |
|
struct ETCP_SOCKET { |
|
struct ETCP_SOCKET* next; // Linked list для всех соединений |
|
struct UTUN_INSTANCE* instance; |
|
socket_t fd; // UDP socket (cross-platform) |
|
struct sockaddr_storage local_addr; // Локальный адрес |
|
int mtu; // MTU для этого сокета |
|
int loss_rate; // packet loss rate in percent (0-100) |
|
|
|
// для входящих подключений (links) - массив упорядоченный по ip_port_hash |
|
size_t max_channels; // сколько выделено памяти |
|
size_t num_channels; // сколько активно |
|
struct ETCP_LINK** links;// массив указателей на линки, сортированный по ip_port_hash |
|
int errorcode; |
|
size_t pkt_format_errors; |
|
|
|
void* socket_id; // Socket ID from uasync_add_socket |
|
uint8_t type; // CFG_SERVER_TYPE_PUBLIC/NAT/PRIVATE |
|
uint32_t local_defaultroute_ip; // auto-detected IPv4 for public servers (network byte order) |
|
}; |
|
|
|
// ETCP Link - одно динамическое соединение (один путь) |
|
struct ETCP_LINK { |
|
uint32_t ip_port_hash; // crc32 для быстрого поиска |
|
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 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; |
|
|
|
size_t encrypt_errors; |
|
size_t decrypt_errors; |
|
size_t send_errors; |
|
size_t recv_errors; |
|
size_t total_encrypted; |
|
size_t total_decrypted; |
|
|
|
uint16_t rtt_last; // round trip (время отправки + приёма) |
|
uint16_t rtt_history[10]; // Circular buffer for last 10 RTT values |
|
uint8_t rtt_history_count; // Number of valid entries in history (0-10) |
|
uint8_t rtt_history_index; // Current write position in history buffer |
|
uint32_t jitter; // Current jitter [>>16] x0.1 ms |
|
uint16_t rtt_max_val; // Current max RTT in history |
|
uint8_t rtt_max_idx; // Index of max (255 = needs recalc) |
|
uint16_t rtt_avg10; // round trip average (excl. max) |
|
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 (network 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) |
|
|
|
// Keepalive state |
|
void* keepalive_timer; // Таймер для отправки keepalive пакетов |
|
uint32_t keepalive_timeout; // таймаут (ms) |
|
uint8_t pkt_sent_since_keepalive; // Флаг: был ли отправлен пакет с последнего keepalive тика |
|
uint32_t keepalive_sent_count; // Счётчик отправленных keepalive |
|
uint32_t keepalive_recv_count; // Счётчик полученных keepalive |
|
}; |
|
|
|
// INITIALIZATION (создаёт listen-сокеты и подключения из конфига) |
|
int init_connections(struct UTUN_INSTANCE* instance); |
|
|
|
// SOCKET FUNCTIONS |
|
// добавляет новый версер (сокет для приёма и отправки кодограмм. обслуживает много подключений) |
|
struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct sockaddr_storage* ip, uint32_t netif_index, int so_mark, uint8_t type, int mtu, int loss_rate); |
|
// удаляет сокет и освобождает ресурсы (грохает все его подключения и сокет) |
|
void etcp_socket_remove(struct ETCP_SOCKET* conn); |
|
|
|
// 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_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); |
|
|
|
// 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); |
|
|
|
#endif // ETCP_CONNECTIONS_H
|
|
|