Close excluded group sessions and validate preservation selections
This commit is contained in:
1 parent
9410570e4e
commit
f611cbb80b
3 files changed
+30
-3
No files matched your search
+10
-2
@@ -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) {
|
||||
|
||||
@@ -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 и таблиц. */
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user