Close excluded group sessions and validate preservation selections

This commit is contained in:
evgeny committed 2026-11-03 15:56:35 +01:00
1 parent 9410570e4e
commit f611cbb80b
3 files changed
+30 -3

No files matched your search

+10 -2
View File
@@ -217,13 +217,14 @@ int group_policy_refresh(struct UTUN_INSTANCE* inst, const char* channel) {
{ int rc = sqlite3_finalize(st); st = NULL; if (rc != SQLITE_OK) goto done; }
if (sqlite3_exec(db, "COMMIT /* admission */", NULL, NULL, NULL) != SQLITE_OK) goto done;
result = 0;
struct TOPO_GROUP* group = inst->topo_groups ? topo_groups_find(inst->topo_groups, chat_channel_id(channel)) : NULL;
if (group) topo_group_revalidate_members(group);
for (size_t i = 0; i < count; i++) if (m[i].previous != m[i].allowed) {
DEBUG_INFO(DEBUG_CATEGORY_MEMBER_SYNC, "group admission ch=%s node=%016llx signer=%016llx allowed=%u all=%u version=%llu",
channel, (unsigned long long)m[i].node, (unsigned long long)m[i].signer, m[i].allowed, policy.all_members,
(unsigned long long)policy.version);
struct TOPO_GROUP* g = inst->topo_groups ? topo_groups_find(inst->topo_groups, chat_channel_id(channel)) : NULL;
struct ETCP_CONN* conn = instance_find_conn(inst, m[i].node);
if (g && conn && !m[i].allowed) topo_group_remove_conn(g, conn, TOPO_REMOVE_MEMBER_INVALID);
if (g && conn && m[i].allowed && conn->links_up && !conn->close_requested) topo_group_new_conn(g, conn);
}
if (changes) {
@@ -258,7 +259,14 @@ int group_policy_can_invite(struct UTUN_INSTANCE* inst, const char* channel, uin
/* Выбор передаётся строковыми uint64 ID: JSON number не сохраняет точность в интерфейсах. */
static int gp_select(sqlite3* db, struct gp_member* m, size_t count, const char* json) {
sqlite3_stmt* st = NULL;
int rc = sqlite3_prepare_v2(db, "SELECT type,value FROM json_each(?1) WHERE json_type(?1)='array'", -1, &st, NULL);
int rc = sqlite3_prepare_v2(db, "SELECT json_type(?1)", -1, &st, NULL);
if (rc == SQLITE_OK) rc = sqlite3_bind_text(st, 1, json ? json : "[]", -1, SQLITE_STATIC);
if (rc == SQLITE_OK) rc = sqlite3_step(st);
if (rc != SQLITE_ROW || !sqlite3_column_text(st, 0) || strcmp((const char*)sqlite3_column_text(st, 0), "array")) {
rc = SQLITE_MISMATCH; goto done;
}
rc = sqlite3_finalize(st); st = NULL;
if (rc == SQLITE_OK) rc = sqlite3_prepare_v2(db, "SELECT type,value FROM json_each(?1)", -1, &st, NULL);
if (rc == SQLITE_OK) rc = sqlite3_bind_text(st, 1, json ? json : "[]", -1, SQLITE_STATIC);
if (rc != SQLITE_OK) goto done;
while ((rc = sqlite3_step(st)) == SQLITE_ROW) {
+18 -1
View File
@@ -407,7 +407,24 @@ static int topo_group_has_sender(struct TOPO_GROUP* group, struct ETCP_CONN* con
static int topo_group_peer_allowed(struct TOPO_GROUP* group, uint64_t node_id) {
if (group->group_type != TOPO_GROUP_TYPE_CHAT) return 1;
sqlite3* db = group->instance->topo_sqlite_db;
return db && group->channel_id[0] && topo_node_sqlite_member_allowed(db, group->channel_id, node_id);
return db && group->channel_id[0] && topo_node_sqlite_member_allowed(db, group->channel_id, group->instance->node_id) &&
topo_node_sqlite_member_allowed(db, group->channel_id, node_id);
}
void topo_group_revalidate_members(struct TOPO_GROUP* group) {
if (!group || group->group_type != TOPO_GROUP_TYPE_CHAT || group->stopping) return;
/* Удаление вызывает callbacks и меняет список; каждый раз ищем следующего заново. */
for (;;) {
struct TOPO_GROUP_CONN_ITEM* invalid = NULL;
for (struct ll_entry* e = group->senders_list ? group->senders_list->head : NULL; e; e = e->next) {
struct TOPO_GROUP_CONN_ITEM* p = (struct TOPO_GROUP_CONN_ITEM*)e->data;
if (!topo_group_peer_allowed(group, p->node_id)) { invalid = p; break; }
}
if (!invalid) break;
if (invalid->conn) topo_group_remove_conn(group, invalid->conn, TOPO_REMOVE_MEMBER_INVALID);
else topo_group_pending_remove(invalid);
}
topo_group_connect_changed(group);
}
/* Политика знакомого пира принадлежит группам/БД; транспорт передаёт только ключ, без SQL и таблиц. */
+2
View File
@@ -385,6 +385,8 @@ enum topo_group_remove_reason {
* При DOWN живые запросы сохраняют NCD для повторного UP. Только потеря транспорта
* запускает recovery каскадно потерянных маршрутов. */
void topo_group_remove_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn, enum topo_group_remove_reason reason);
/* После пересчёта admitted: закрыть недопущенные сессии/запросы только этой группы. Общий транспорт сохраняется. */
void topo_group_revalidate_members(struct TOPO_GROUP* group);
/**
* @brief Обрабатывает пакет NODEINFO.