dm: resolve service roles independently of delivery routes
This commit is contained in:
1 parent
307ca10733
commit
3c58fc80e3
2 files changed
+41
No files matched your search
@@ -33,6 +33,7 @@
|
||||
#include "../../lib/debug_config.h"
|
||||
#include "../../lib/platform_compat.h"
|
||||
#include "../../lib/strbuf.h"
|
||||
#include "../../lib/json_flat.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -153,6 +154,41 @@ int dm_route_group(struct UTUN_INSTANCE* inst, uint64_t peer, uint64_t preferred
|
||||
return dm_find_route_group(inst, peer, preferred, group_id, 0);
|
||||
}
|
||||
|
||||
int dm_peer_role(struct UTUN_INSTANCE* inst, uint64_t peer, const char* role) {
|
||||
if (!inst || !inst->topo_sqlite_db || !peer || !role || !role[0]) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "DM role: invalid lookup peer=%llu", (unsigned long long)peer); return 0;
|
||||
}
|
||||
uint64_t* groups = NULL;
|
||||
int count = 0, allowed = 0;
|
||||
if (topo_node_sqlite_get_member_channels(inst->topo_sqlite_db, inst->node_id, &groups, &count)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "DM role: membership lookup failed peer=%llu", (unsigned long long)peer); return 0;
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!topo_group_chat_allowed(inst, groups[i], peer)) continue;
|
||||
char sql[192], value[16];
|
||||
snprintf(sql, sizeof(sql), "SELECT adm_tags FROM \"peers_%llu\""
|
||||
" WHERE node_id=? AND source=0 AND deleted=0 AND admitted=1", (unsigned long long)groups[i]);
|
||||
sqlite3_stmt* st = NULL;
|
||||
int rc = sqlite3_prepare_v2(inst->topo_sqlite_db, sql, -1, &st, NULL);
|
||||
if (rc == SQLITE_OK) rc = sqlite3_bind_int64(st, 1, (sqlite3_int64)peer);
|
||||
if (rc == SQLITE_OK) rc = sqlite3_step(st);
|
||||
const char* tags = rc == SQLITE_ROW ? (const char*)sqlite3_column_text(st, 0) : NULL;
|
||||
allowed = tags && !json_flat_get(tags, role, value, sizeof(value)) && !strcmp(value, "yes");
|
||||
int final = sqlite3_finalize(st);
|
||||
if ((rc != SQLITE_ROW && rc != SQLITE_DONE) || final != SQLITE_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "DM role: lookup failed peer=%llu group=%llu role=%s rc=%d final=%d",
|
||||
(unsigned long long)peer, (unsigned long long)groups[i], role, rc, final);
|
||||
allowed = 0; break;
|
||||
}
|
||||
if (allowed) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_DM, "DM role: admitted peer=%llu role=%s group=%llu",
|
||||
(unsigned long long)peer, role, (unsigned long long)groups[i]); break;
|
||||
}
|
||||
}
|
||||
u_free(groups);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
/* Router владеет entry после вызова, в том числе при ошибке. */
|
||||
static int dm_route_send(struct dm_state* dm, uint64_t group_id, uint64_t dst, uint8_t subcmd,
|
||||
const uint8_t* body, size_t body_len) {
|
||||
|
||||
@@ -62,6 +62,11 @@ static inline int dm_msg_len(const uint8_t* msg, size_t avail, size_t* out_len)
|
||||
* 1 и *group_id при успехе; 0 при отсутствии пути/ошибке, выход не меняется.
|
||||
* group_id обязателен; наличие пути не гарантирует успешной последующей отправки. */
|
||||
int dm_route_group(struct UTUN_INSTANCE* inst, uint64_t peer, uint64_t preferred, uint64_t* group_id);
|
||||
/* Проверить role=yes у peer в любой живой общей CHAT-группе self/peer.
|
||||
* Группа объявления роли не ограничивает маршрут личной передачи. peer=self проверяет локальную роль.
|
||||
* Учитывает только source=0, admitted=1, deleted=0 и действующий канал; путь не требуется.
|
||||
* 1=роль найдена, 0=нет роли/ошибка с диагностикой. role — непустое имя adm_tags, только uasync. */
|
||||
int dm_peer_role(struct UTUN_INSTANCE* inst, uint64_t peer, const char* role);
|
||||
/* Проверить точную длину msg/len, conv/author/recipient/seq, descriptor и подпись автора из nodes.
|
||||
* 0=корректно, -1=отказ. Нужна SQLite, владелец dm_core не требуется.
|
||||
* Не расшифровывает тело и не проверяет членство/роль router-отправителя: это обязанность вызывающего. */
|
||||
|
||||
Reference in new issue
Block a user