topo_group: узлы меняются только по BGP (NODEINFO/WITHDRAW), удаление по link down через BGP-коллбэк
This commit is contained in:
1 parent
b0f149092f
commit
1a88ea88a8
1 file changed
+14
-53
@@ -213,45 +213,6 @@ static void topo_group_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
||||
// Init / Destroy / New / Remove conn
|
||||
// ============================================================================
|
||||
|
||||
/* Создать TOPO_GROUP_NODE (если нет) + прямой путь через conn (hop=1). Без BGP.
|
||||
Используется из topo_group_new_conn (add + init BGP) и из приёма TABLE_REQ (входящий запросил BGP). */
|
||||
static void topo_group_conn_add_path(struct TOPO_GROUP* group, struct ETCP_CONN* conn, uint64_t node_id) {
|
||||
if (!group || !conn || !node_id || node_id == group->instance->node_id) return;
|
||||
|
||||
/* узел в реестре — иначе загрузить из БД (nodes + node_addresses), чтобы форвардинг мог сериализовать */
|
||||
{ struct TOPO_GROUPS* groups = group->instance->topo_groups;
|
||||
struct TOPO_NODE* ni = topo_node_registry_find(groups, node_id);
|
||||
if (!ni) {
|
||||
sqlite3* db = group->instance->topo_sqlite_db;
|
||||
ni = db ? topo_node_sqlite_node_load(db, groups, node_id) : NULL;
|
||||
if (ni) ni = topo_node_registry_store(groups, ni);
|
||||
}
|
||||
}
|
||||
|
||||
struct TOPO_GROUP_NODE* nq = topo_node_find_by_id(group, node_id);
|
||||
if (nq && nq->paths) {
|
||||
struct ll_entry* pe = nq->paths->head;
|
||||
while (pe) { if (((struct TOPO_NODEPATH*)pe)->conn == conn) return; pe = pe->next; }
|
||||
}
|
||||
if (!nq) {
|
||||
struct ll_entry* qe = queue_entry_new(sizeof(struct TOPO_GROUP_NODE));
|
||||
if (!qe) return;
|
||||
nq = (struct TOPO_GROUP_NODE*)qe;
|
||||
memset((uint8_t*)nq + sizeof(struct ll_entry), 0, sizeof(*nq) - sizeof(struct ll_entry));
|
||||
nq->node_id = node_id;
|
||||
queue_data_put_with_index(group->nodes, &nq->ll);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "node added to group: node=%016llx grp=%016llx type=%u ch=%s (direct)",
|
||||
(unsigned long long)node_id, (unsigned long long)group->group_id, group->group_type, group->channel_id);
|
||||
}
|
||||
uint64_t hop[1] = { node_id };
|
||||
topo_group_add_path(nq, conn, hop, 1, 0);
|
||||
nq->conn_presence |= NCONN_DIRECT;
|
||||
nq->conn_up |= NCONN_DIRECT;
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "conn_add_path: node=0x%016llx grp=%016llx ch=%s conn=%s",
|
||||
(unsigned long long)node_id, (unsigned long long)group->group_id, group->channel_id, conn->log_name);
|
||||
}
|
||||
|
||||
static void topo_group_conn_status(struct ETCP_CONN* conn, int status, void* arg) {
|
||||
struct TOPO_GROUPS* groups = (struct TOPO_GROUPS*)arg;
|
||||
if (!conn || !groups) return;
|
||||
@@ -551,21 +512,9 @@ void topo_group_new_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) {
|
||||
if (!conn->instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "conn->instance is NULL"); return; }
|
||||
if (!conn->instance->rt) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "conn->instance->rt is NULL"); return; }
|
||||
|
||||
topo_recovery_cancel_for_node(group, conn->peer_node_id);
|
||||
|
||||
/* создать узел + прямой путь (сразу, не дожидаясь NODEINFO; дедуп внутри по conn).
|
||||
Делаем ДО проверки senders_list: conn может уже быть в senders_list (через handle_request_table),
|
||||
но узел ещё не создан (входящий JOIN_GROUP). */
|
||||
topo_group_conn_add_path(group, conn, conn->peer_node_id);
|
||||
{ struct TOPO_GROUP_NODE* peer_nq = topo_node_find_by_id(group, conn->peer_node_id);
|
||||
if (peer_nq) {
|
||||
peer_nq->connectivity.last_ping_time = get_time_tb();
|
||||
if (conn->instance->topo_sqlite_db) topo_node_sqlite_nodeinfo_updated(conn->instance->topo_sqlite_db, conn->peer_node_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* дедуп: тот же conn стреляет ETCP_CONN_STATUS_UP дважды (UDP-линк, затем TCP-линк).
|
||||
* Если conn уже в senders_list — не слать повторно TABLE_REQ и не задваивать active_conn_count. */
|
||||
* Если conn уже в senders_list — повторно не обрабатываем, иначе active_conn_count
|
||||
* задваивается и переподключение никогда не стартует. */
|
||||
{ struct ll_entry* se = group->senders_list ? group->senders_list->head : NULL;
|
||||
while (se) {
|
||||
if (((struct TOPO_GROUP_CONN_ITEM*)se->data)->conn == conn) {
|
||||
@@ -576,6 +525,15 @@ void topo_group_new_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) {
|
||||
}
|
||||
}
|
||||
|
||||
topo_recovery_cancel_for_node(group, conn->peer_node_id);
|
||||
|
||||
struct TOPO_GROUP_NODE* peer_nq = topo_node_find_by_id(group, conn->peer_node_id);
|
||||
if (peer_nq) {
|
||||
peer_nq->connectivity.last_ping_time = get_time_tb();
|
||||
peer_nq->conn_presence |= NCONN_DIRECT;
|
||||
peer_nq->conn_up |= NCONN_DIRECT;
|
||||
if (conn->instance->topo_sqlite_db) topo_node_sqlite_nodeinfo_updated(conn->instance->topo_sqlite_db, conn->peer_node_id);
|
||||
}
|
||||
topo_group_add_to_senders(group, conn);
|
||||
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "topo_group_new_conn: peer=%016llx group=%016llx type=%d ch=%s", (unsigned long long)conn->peer_node_id, (unsigned long long)group->group_id, group->group_type, group->channel_id);
|
||||
@@ -625,6 +583,9 @@ void topo_group_remove_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) {
|
||||
uint64_t wd_src = (key == conn->peer_node_id) ? conn->instance->node_id : conn->peer_node_id;
|
||||
topo_group_broadcast_withdraw(group, key, wd_src, NULL);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Removed node %016llx after link down", (unsigned long long)key);
|
||||
{ struct topo_node_cbk_entry* c = group->node_cbks;
|
||||
while (c) { c->fn(group, key, TOPO_NODE_EVENT_REMOVE, c->arg); c = c->next; }
|
||||
}
|
||||
} else {
|
||||
nq->conn_up &= ~NCONN_DIRECT;
|
||||
{ int has_direct = 0; struct ll_entry* pe2 = nq->paths ? nq->paths->head : NULL;
|
||||
|
||||
Reference in new issue
Block a user