#ifndef ETCP_CONNECTIONS_H #define ETCP_CONNECTIONS_H // подмодуль ETCP который обслуживает сокеты ETCP для приёма-передачи пакетов и одно ETCP подключение через несколько каналов связи (failover) #include "secure_channel.h" #include "utun_instance.h" #include #include #define PACKET_DATA_SIZE 1536 // Типы кодограмм протокола #define ETCP_INIT_REQUEST 0x02 #define ETCP_INIT_RESPONSE 0x03 #define ETCP_CHANNEL_INIT 0x04 #define ETCP_CHANNEL_RESPONSE 0x05 struct ETCP_DGRAM {// пакет (незашифрованный) struct ETCP_LINK* link;// откуда получена или куда отправялем uint16_t data_len;// общий размер пакета не включая timestamp uint16_t noencrypt_len;// число байт (с конца) которые не надо шифровать. для передачи pubkey uint16_t timestamp;// timestamp принятого или для отправки uint8_t data[0];// данные пакета (без timestamp) }; // список активных подключений которые обслуживает сокет. каждый сокет может обслуживать много подключений struct ETCP_SOCKET { struct ETCP_SOCKET* next; // Linked list для всех соединений struct UTUN_INSTANCE* instance; int fd; // Файловый дескриптор UDP сокета struct sockaddr_storage local_addr; // Локальный адрес // для входящих подключений (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 }; // 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 keepalive_interval; // Keepalive интервал uint8_t is_server; // инициирует подключение клиент uint8_t initialized; // Флаг инициализации (1=подтверждено или получен request) // Состояние установки соединения (только для клиентов) void* init_timer; // Таймер для повторов INIT (NULL=не подключается) uint16_t init_timeout; // Текущий таймаут в мс uint16_t init_retry_count; // Счетчик попыток uint64_t last_activity; // Время последней активности uint64_t last_recv_local_time; uint16_t last_recv_timestamp; 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 bandwidth; // Link bandwidth in bits/sec }; // 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); struct ETCP_SOCKET* etcp_socket_add_ex(struct UTUN_INSTANCE* instance, struct sockaddr_storage* ip, uint32_t netif_index, int so_mark, uint8_t type, uint32_t flags); // удаляет сокет и освобождает ресурсы (грохает все его подключения и сокет) 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); #endif // ETCP_CONNECTIONS_H