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.
83 lines
4.3 KiB
83 lines
4.3 KiB
/** |
|
* @file topo_recovery.h |
|
* @brief Восстановление каскадно отвалившихся узлов после разрыва ETCP-соединения. |
|
* |
|
* Когда рвётся соединение, узлы достижимые только через него становятся недоступны. |
|
* Модуль собирает их перед удалением из BGP-таблицы и пробует переподключиться |
|
* напрямую (ncd): |
|
* 1. add_node — из hop_list вычисляет next_hop относительно failed_peer, |
|
* группирует узлы по next_hop в отдельные recovery-контексты |
|
* 2. start — для каждого контекста запускает асинхронный перебор: |
|
* сперва пробует next_hop-узел (is_next_hop=1), затем остальные по мин. RTT |
|
* 3. Таймаут 2с на каждую попытку node_conn_direct_open |
|
* |
|
* Группировка: <мы> -> <failed_peer N> -> <next_hop A, B...> |
|
* Каждый next_hop со своим subtree — отдельный recovery-контекст. |
|
* Восстановление next_hop автоматически оживляет его subtree через BGP. |
|
* |
|
* Отмена: topo_group_new_conn (узел появился в сети) сканирует все active recovery, |
|
* при совпадении отменяет контекст целиком. Самоуничтожение при исчерпании списков. |
|
*/ |
|
#ifndef TOPO_RECOVERY_H |
|
#define TOPO_RECOVERY_H |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
#include <stdint.h> |
|
#include <stddef.h> |
|
|
|
struct TOPO_GROUP; |
|
struct TOPO_GROUP_NODE; |
|
struct NODE_CONN_DIRECT; |
|
|
|
#define TOPO_RECOVERY_CONNECT_TIMEOUT_MS 2000 |
|
|
|
struct TOPO_RECOVERY_NODE { |
|
uint64_t node_id; |
|
uint16_t min_rtt; /* 0.1ms, из connectivity-проб (interface/nat/real) */ |
|
uint8_t is_next_hop; /* 1 = прямой downstream отвалившегося узла, пробуется первым */ |
|
}; |
|
|
|
struct TOPO_RECOVERY_CTX { |
|
struct TOPO_RECOVERY_CTX* next; /* следующий в group->recovery_list */ |
|
struct UTUN_INSTANCE* instance; |
|
struct TOPO_GROUP* group; |
|
uint64_t next_hop_id; /* ключ группировки: node_id next-hop'а от failed_peer */ |
|
struct TOPO_RECOVERY_NODE* nodes; /* кандидаты на восстановление (прямые) */ |
|
size_t count; /* текущее количество */ |
|
size_t capacity; /* выделенная ёмкость */ |
|
uint64_t current_node_id; /* node_id в текущей попытке, 0=нет активной */ |
|
struct NODE_CONN_DIRECT* current_handle; /* handle текущей попытки node_conn_direct_open */ |
|
void* connect_timer; /* внешний таймер 2с (uasync) */ |
|
uint8_t started; /* 0=сбор узлов (add_node), 1=перебор запущен */ |
|
}; |
|
|
|
/** |
|
* Добавляет узел в pending-контекст, сгруппированный по next_hop относительно failed_peer. |
|
* Вызывается из topo_group_remove_conn ДО topo_node_free_lists (нужен hop_list). |
|
* @param failed_peer node_id отвалившегося пира (conn->peer_node_id) |
|
*/ |
|
void topo_recovery_add_node(struct TOPO_GROUP* group, struct TOPO_GROUP_NODE* nq, uint64_t next_hop); |
|
|
|
/** |
|
* Запускает перебор узлов для всех pending-контекстов. |
|
* Вызывается после цикла в topo_group_remove_conn если есть каскадные узлы. |
|
*/ |
|
void topo_recovery_start(struct TOPO_GROUP* group); |
|
|
|
/** |
|
* Сканирует все active recovery: если node_id найден в любом контексте — |
|
* отменяет текущую попытку connect и освобождает контекст. |
|
* Вызывается из topo_group_new_conn (узел появился в сети). |
|
*/ |
|
void topo_recovery_cancel_for_node(struct TOPO_GROUP* group, uint64_t node_id); |
|
|
|
/** Отменяет все recovery-контексты. Вызывается из topo_group_destroy. */ |
|
void topo_recovery_cancel_all(struct TOPO_GROUP* group); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
#endif
|
|
|