/** * @file routing.h * @brief Улучшенная система маршрутизации с поддержкой пропускной способности и типов маршрутов * @details Поддерживает статические/динамические маршруты с метриками и валидацией */ #ifndef ROUTING_H #define ROUTING_H #include #include #include #include "connection.h" #include "control_socket.h" // Типы маршрутов typedef enum { ROUTE_TYPE_STATIC = 0, // Статические маршруты, загружаемые при старте ROUTE_TYPE_DYNAMIC = 1, // Динамические маршруты, полученные от соседей ROUTE_TYPE_LOCAL = 2, // Локальные подсети ROUTE_TYPE_LEARNED = 3 // Маршруты, полученные от других узлов } route_type_t; // Флаги маршрута typedef enum { ROUTE_FLAG_ACTIVE = (1 << 0), // Маршрут активен (лучший путь) ROUTE_FLAG_VALIDATED = (1 << 1), // Маршрут прошёл валидацию (по разрешенным подсетям в конфиге) ROUTE_FLAG_ADVERTISED = (1 << 2), // Маршрут анонсируется другим узлам ROUTE_FLAG_LEARNED = (1 << 3) // Маршрут получен от соседа } route_flags_t; // Расширенные метрики маршрута typedef struct { uint32_t bandwidth_kbps; // Доступная (минимальная по всем узлам) пропускная способность до узла по этому маршруту, кбит/с uint16_t packet_loss_rate; // Процент потерь пакетов (0–10000 = 0.00–100.00%) uint16_t latency_ms; // Задержка в миллисекундах (суммарная до узла, не вулючает задержку до next hop) uint8_t hop_count; // Количество хопов до цели (не включая next hop) uint64_t last_updated; // Время последнего обновления (в timebase 0.1ms) } route_metrics_t; // Расширенная запись маршрута typedef struct { uint32_t network; // Адрес сети (в сетевом порядке байтов) uint8_t prefix_length; // Длина префикса (0–32) uint32_t next_hop_ip; // IP-адрес следующего хопа (узла который анонсировал маршрут) conn_handle_t* next_hop; // Указатель на соединение со следующим хопом route_type_t type; // Тип маршрута uint8_t flags; // Флаги маршрута route_metrics_t metrics; // Метрики маршрута uint64_t created_time; // Время создания записи uint64_t last_update; // Время последнего обновления uint64_t last_used; // Время последнего использования } route_entry_t; // Расширенная таблица маршрутизации (элементы сортированы по IP), может содержать дублирующие маршруты по альтернативным каналам. typedef struct { route_entry_t *entries; // Массив записей маршрутов size_t count; // Количество активных записей size_t capacity; // Выделенная ёмкость массива (расширение x2 при нехватке места) // Диапазоны для валидации подсетей uint32_t *dynamic_subnets; // Разрешённые диапазоны динамических маршрутов (анонс не принимается если вне этой таблицы) size_t dynamic_subnet_count; // Локальные подсети, которые будут анонсироваться uint32_t *local_subnets; size_t local_subnet_count; routing_stats_t stats; // Statistics counters } routing_table_t; /** * @brief Создаёт улучшенную таблицу маршрутизации * @return указатель на новую таблицу или NULL при ошибке */ routing_table_t *routing_table_create(void); /** * @brief Уничтожает таблицу маршрутизации */ void routing_table_destroy(routing_table_t *table); /** * @brief Получить статистику таблицы маршрутизации * @param table таблица маршрутизации * @param stats указатель на структуру для заполнения статистики */ void routing_get_stats(const routing_table_t *table, routing_stats_t *stats); /** * @brief Добавляет маршрут в таблицу * * @param table таблица маршрутизации * @param entry структура маршрута для вставки * @return true при успехе, false при ошибке */ bool routing_table_insert(routing_table_t *table, const route_entry_t *entry); /** * @brief Удаляет маршрут из таблицы * * @param table таблица маршрутизации * @param network адрес сети * @param prefix_length длина префикса * @param source_node_id идентификатор узла-источника * @return true — маршрут удалён, false — не найден */ bool routing_table_delete(routing_table_t *table, uint32_t network, uint8_t prefix_length, uint32_t source_node_id); /** * @brief Ищет лучший маршрут до указанного адреса * * @param table таблица маршрутизации * @param dest_ip целевой IP-адрес * @param best_route [out] сюда будет записан лучший маршрут * @return true — маршрут найден, false — нет подходящего маршрута */ bool routing_table_lookup(routing_table_t *table, uint32_t dest_ip, route_entry_t *best_route); /** * @brief Проверяет маршрут на соответствие разрешённым подсетям * * @param table таблица с диапазонами валидации * @param network адрес сети * @param prefix_length длина префикса * @param route_type ожидаемый тип маршрута * @return true — маршрут разрешён, false — запрещён */ bool routing_validate_route(routing_table_t *table, uint32_t network, uint8_t prefix_length, route_type_t route_type); /** * @brief Добавляет диапазон подсети для динамической валидации */ bool routing_add_dynamic_subnet(routing_table_t *table, uint32_t network, uint8_t prefix_length); /** * @brief Добавляет локальную подсеть, которая будет анонсироваться соседям */ bool routing_add_local_subnet(routing_table_t *table, uint32_t network, uint8_t prefix_length); /** * @brief Возвращает все маршруты для указанной сети/префикса * * @param routes [out] массив указателей (выделяется внутри, нужно освободить) */ bool routing_get_all_routes(const routing_table_t *table, uint32_t network, uint8_t prefix_length, route_entry_t **routes, size_t *count); /** * @brief Выводит содержимое таблицы маршрутизации (для отладки) */ void routing_table_print(const routing_table_t *table); /** * @brief Преобразует тип маршрута в строку * @return текстовое представление типа */ const char *route_type_to_string(route_type_t type); /** * @brief Преобразует IP-адрес в строку (для отладки) * * @param ip адрес в сетевом порядке байтов * @param buffer буфер минимум 16 байт * @return указатель на заполненный буфер */ char *ip_to_string(uint32_t ip, char *buffer); #endif // ROUTING_H