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
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
|