diff --git a/src/routing_layer/topo_group.c b/src/routing_layer/topo_group.c index 967aaaaa..7426cc9c 100644 --- a/src/routing_layer/topo_group.c +++ b/src/routing_layer/topo_group.c @@ -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;