#ifndef PACKET_BUFFER_H #define PACKET_BUFFER_H #include #include #include #include // Стадии обработки пакета typedef enum { PACKET_STAGE_RX_SOCKET, // Получен из сокета (зашифрован) PACKET_STAGE_RX_DECRYPTED, // Расшифрован (plain-text) PACKET_STAGE_RX_ETCP, // Обработан ETCP (собран фрагмент) PACKET_STAGE_RX_APP, // Передан в приложение PACKET_STAGE_TX_APP, // Из приложения на отправку PACKET_STAGE_TX_ETCP, // Обработан ETCP (фрагментирован) PACKET_STAGE_TX_ENCRYPTED // Зашифрован, готов к отправке } packet_stage_t; // Флаги пакета #define PACKET_FLAG_ENCRYPTED (1 << 0) #define PACKET_FLAG_FRAGMENTED (1 << 1) #define PACKET_FLAG_RETRANSMIT (1 << 2) #define PACKET_FLAG_CONTROL (1 << 3) // Служебный пакет (RST, INIT) // Размеры #define PACKET_METADATA_SIZE 64 #define PACKET_DATA_SIZE 1536 #define PACKET_TOTAL_SIZE 1600 #define PACKET_POOL_SIZE 64 // Основная структура пакета struct packet_buffer { // Метаданные (64 байта) struct { struct ETCP_SOCKET* s; // Сокет через который получен/ планируется отправить struct etcp_channel* channel; // Канал ETCP (NULL до поиска) struct sockaddr_storage remote_addr;// Адрес удаленного endpoint uint64_t timestamp_us; // Время создания пакета uint16_t data_len; // Длина данных в буфере uint8_t stage; // Стадия обработки пакета } metadata; struct packet_buffer* next_free; // Для пула - используется только когда пакет свободен uint8_t data[0]; // Данные (variable size) }; // Инлайн функции для удобного доступа // Доступ к данным static inline uint8_t* packet_data(struct packet_buffer* pkt) { return pkt->data; } static inline struct sockaddr* packet_remote_addr(struct packet_buffer* pkt) { return (struct sockaddr*)&pkt->metadata.remote_addr; } static inline uint16_t packet_remote_port(const struct packet_buffer* pkt) { if (pkt->metadata.remote_addr.ss_family == AF_INET) { return ((struct sockaddr_in*)&pkt->metadata.remote_addr)->sin_port; } return 0; } // Инициализация static inline void packet_init(struct packet_buffer* pkt) { memset(&pkt->metadata, 0, sizeof(pkt->metadata)); pkt->metadata.timestamp_us = 0; // TODO: get current time pkt->metadata.stage = PACKET_STAGE_RX_SOCKET; } #endif // PACKET_BUFFER_H