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.
 
 
 
 
 
 

76 lines
2.9 KiB

#ifndef PACKET_BUFFER_H
#define PACKET_BUFFER_H
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
// Стадии обработки пакета
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