diff --git a/src/routing_layer/topo_group.c b/src/routing_layer/topo_group.c index 5d8b452ef..2dceffe90 100644 --- a/src/routing_layer/topo_group.c +++ b/src/routing_layer/topo_group.c @@ -158,7 +158,8 @@ static void topo_group_peer_event(struct NODE_CONN_DIRECT* handle, enum ncd_even int topo_group_peer_open(struct TOPO_GROUP* group, uint64_t node_id, struct TOPO_PEER_REQUEST** out) { if (out) *out = NULL; if (!group || !group->instance || !out || !node_id || node_id == group->instance->node_id || - !group->senders_list || group->stopping || !topo_group_peer_allowed(group, node_id)) { + !group->senders_list || group->stopping || (group->group_type == TOPO_GROUP_TYPE_CHAT && + !topo_node_sqlite_member_in_channel(group->instance->topo_sqlite_db, group->channel_id, node_id))) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "cannot request group peer=%016llx: invalid arguments, stopped group or unknown member", (unsigned long long)node_id); return -1; } @@ -999,9 +1000,10 @@ static int topo_group_begin_conn(struct TOPO_GROUP* group, struct ETCP_CONN* con } if (!conn->instance->rt) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "conn->instance->rt is NULL"); return -1; } if (!topo_group_peer_allowed(group, conn->peer_node_id)) { - DEBUG_INFO(DEBUG_CATEGORY_BGP, "group connect deferred: member unknown peer=%016llx group=%016llx", + DEBUG_INFO(DEBUG_CATEGORY_BGP, "group connect waits for admission checkpoint peer=%016llx group=%016llx", (unsigned long long)conn->peer_node_id, (unsigned long long)group->group_id); - return -1; + /* Запрошенный транспорт нужен для MEMBERS Merkle. Групповой JOIN/READY пока запрещён. */ + return !incoming && topo_group_peer(group, conn->peer_node_id) ? 0 : -1; } struct TOPO_GROUP_CONN_ITEM* peer = topo_group_peer(group, conn->peer_node_id); if (!incoming && (!peer || !peer->conn) && topo_group_connect_defer_join(group, conn->peer_node_id)) return 0; diff --git a/src/routing_layer/topo_group.h b/src/routing_layer/topo_group.h index a5e883c93..333eb9ca5 100644 --- a/src/routing_layer/topo_group.h +++ b/src/routing_layer/topo_group.h @@ -362,6 +362,8 @@ enum topo_peer_phase { TOPO_PEER_FAILED, TOPO_PEER_CONNECTING, TOPO_PEER_SYNCING * закрыть его. Все операции выполняются в потоке единственного uasync. * progress — timebase последнего принятого NODEINFO/шага обмена, не polling time. * open: node_id ненулевой и не self; 0 = запрос создан в *out, -1 = ошибка (*out=NULL). */ +/* Известный CHAT-мембер может удерживать транспорт для начальной MEMBERS сверки; + * групповая сессия остаётся закрытой, пока собственный узел и пир не admitted. */ int topo_group_peer_open(struct TOPO_GROUP* group, uint64_t node_id, struct TOPO_PEER_REQUEST** out); /* Освободить свой запрос; после вызова request недействителен. NULL допустим. */ void topo_group_peer_close(struct TOPO_PEER_REQUEST* request);