Store group policy and derived member admission

This commit is contained in:
evgeny committed 2026-11-03 15:47:36 +01:00
1 parent 23159f791a
commit 94ae8231aa
2 files changed
+16 -4

No files matched your search

+14 -4
View File
@@ -391,6 +391,8 @@ int topo_node_sqlite_init(sqlite3* db) {
"CREATE UNIQUE INDEX IF NOT EXISTS idx_na_unique ON node_addresses(node_id,family,socket_id,protocol,address,port,address_kind);"
"CREATE INDEX IF NOT EXISTS idx_na_addr_lookup ON node_addresses(family, address, port, socket_id);"
"CREATE TABLE IF NOT EXISTS group_policy(channel_id TEXT PRIMARY KEY,version INTEGER NOT NULL,"
"all_members INTEGER NOT NULL,signature BLOB NOT NULL);"
"CREATE TABLE IF NOT EXISTS channels ("
" channel_id TEXT PRIMARY KEY," // ID канала
" name TEXT NOT NULL," // Название канала
@@ -515,16 +517,23 @@ int topo_node_sqlite_member_local_init(sqlite3* db, const char* channel_id) {
if (sqlite3_prepare_v2(db, sql, -1, &st, NULL) != SQLITE_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "radio: inspect member schema ch=%s: %s", channel_id, sqlite3_errmsg(db)); return -1;
}
int has_radio_muted = 0, rc;
int has_radio_muted = 0, has_admitted = 0, rc;
while ((rc = sqlite3_step(st)) == SQLITE_ROW) {
const char* column = (const char*)sqlite3_column_text(st, 1);
if (column && !strcmp(column, "radio_muted")) has_radio_muted = 1;
if (column && !strcmp(column, "admitted")) has_admitted = 1;
}
int final = sqlite3_finalize(st);
if (rc != SQLITE_DONE || final != SQLITE_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "radio: read member schema ch=%s step=%d finalize=%d: %s",
channel_id, rc, final, sqlite3_errmsg(db)); return -1;
}
if (!has_admitted) {
snprintf(sql, sizeof(sql), "ALTER TABLE \"%s\" ADD COLUMN admitted INTEGER NOT NULL DEFAULT 0", peers_tbl);
if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "member admission schema ch=%s: %s", channel_id, sqlite3_errmsg(db)); return -1;
}
}
if (!has_radio_muted) {
snprintf(sql, sizeof(sql), "ALTER TABLE \"%s\" ADD COLUMN radio_muted INTEGER NOT NULL DEFAULT 0", peers_tbl);
if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
@@ -580,6 +589,7 @@ int topo_node_sqlite_channel_put(sqlite3* db, const char* channel_id,
" deleted INTEGER NOT NULL DEFAULT 0," /* 1 = аккаунт удалён владельцем (не отображаем, не подключаемся) */
" local_nick TEXT," /* локальный ник (GUI only, не синхронизируется) */
" radio_muted INTEGER NOT NULL DEFAULT 0," /* локальное отключение голоса участника */
" admitted INTEGER NOT NULL DEFAULT 0," /* локальный допуск по текущей политике */
" source INTEGER NOT NULL DEFAULT 0" /* 0=полная merkle-запись 1=упрощённый плейсхолдер topo_group
(не участвует в merkle-хеше, дополняется полной записью) */
")";
@@ -943,7 +953,7 @@ int topo_node_sqlite_member_allowed(sqlite3* db, const char* channel_id, uint64_
DEBUG_WARN(DEBUG_CATEGORY_BGP, "member admission: invalid channel/node"); return 0;
}
char table[80], sql[256]; peers_table_name(channel_id, table, sizeof(table));
snprintf(sql, sizeof(sql), "SELECT 1 FROM \"%s\" WHERE node_id=? AND source=0 AND deleted=0", table);
snprintf(sql, sizeof(sql), "SELECT 1 FROM \"%s\" WHERE node_id=? AND source=0 AND deleted=0 AND admitted=1", table);
sqlite3_stmt* statement = NULL;
int rc = sqlite3_prepare_v2(db, sql, -1, &statement, NULL);
if (rc == SQLITE_OK) rc = sqlite3_bind_int64(statement, 1, (sqlite3_int64)node_id);
@@ -961,7 +971,7 @@ int topo_node_sqlite_member_key_allowed(sqlite3* db, const char* channel_id, con
}
uint64_t node = sc_derive_node_id_from_pubkey(key);
char table[80], sql[320]; peers_table_name(channel_id, table, sizeof(table));
snprintf(sql, sizeof(sql), "SELECT 1 FROM \"%s\" WHERE node_id=? AND x25519_pubkey=? AND source=0 AND deleted=0", table);
snprintf(sql, sizeof(sql), "SELECT 1 FROM \"%s\" WHERE node_id=? AND x25519_pubkey=? AND source=0 AND deleted=0 AND admitted=1", table);
sqlite3_stmt* st = NULL;
int rc = sqlite3_prepare_v2(db, sql, -1, &st, NULL);
if (rc == SQLITE_OK) rc = sqlite3_bind_int64(st, 1, (sqlite3_int64)node);
@@ -1634,7 +1644,7 @@ int topo_node_sqlite_get_connect_peers(sqlite3* db, const char* channel_id,
char sql[512];
snprintf(sql, sizeof(sql),
"SELECT p.node_id,p.adm_tags,s.timestamp,s.record FROM \"%s\" p"
" LEFT JOIN node_snapshots s ON s.node_id=p.node_id AND s.format=1 AND length(s.record)>0 WHERE p.deleted=0 AND p.source=0"
" LEFT JOIN node_snapshots s ON s.node_id=p.node_id AND s.format=1 AND length(s.record)>0 WHERE p.deleted=0 AND p.source=0 AND p.admitted=1"
" ORDER BY p.connected DESC,p.node_RTT IS NULL,p.node_RTT,p.node_id", table);
sqlite3_stmt* stmt = NULL;
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);