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