Authorize avatar channels and cancel revoked peer state

This commit is contained in:
evgeny committed 2026-11-03 20:21:16 +01:00
1 parent ec8d8f8734
commit 71f73a21e1
2 files changed
+23 -1

No files matched your search

+21 -1
View File
@@ -263,7 +263,7 @@ static struct ga_peer* ga_find(struct group_avatar* ctx, uint64_t group, uint64_
}
static int ga_allowed(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t peer) {
if (!member_files_member(inst, group, inst->node_id, 0) || !member_files_member(inst, group, peer, 0)) return 0;
if (!topo_group_chat_allowed(inst, group, peer)) return 0;
struct TOPO_GROUP* g = topo_groups_find(inst->topo_groups, group);
for (struct ll_entry* e = g && g->senders_list ? g->senders_list->head : NULL; e; e = e->next) {
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e->data;
@@ -366,6 +366,7 @@ static void ga_receive(struct ETCP_CONN* conn, struct ll_entry* entry) {
uint64_t group, peer; memcpy(&group, entry->dgram + ROUTER_SVC_GROUP_OFF, 8); memcpy(&peer, entry->dgram + ROUTER_SVC_SRC_OFF, 8);
struct ga_peer* p = ga_find(ctx, group, peer, 0);
if (entry->len == ROUTER_SVC_PAYLOAD_OFF) {
if (!topo_group_chat_allowed(ctx->inst, group, peer)) { group_avatar_revalidate_members(ctx->inst, group); goto out; }
if (p) { ga_release(p, 1); ga_release(p, 0); p->requested_at = 0; p->state_pending = 1; ga_schedule(p); }
goto out;
}
@@ -510,6 +511,11 @@ int group_avatar_init(struct UTUN_INSTANCE* inst) {
if (etcp_router_bind(inst, ETCP_RT_ID_GROUP_AVATAR, ga_receive)) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "group avatar: router registration failed"); CC(inst)->group_avatar = NULL; u_free(ctx); return -1;
}
if (etcp_router_require_crypto(inst, ETCP_RT_ID_GROUP_AVATAR, ROUTER_FLAG_SIGNED | ROUTER_FLAG_ENCRYPTED) ||
etcp_router_set_authorize(inst, ETCP_RT_ID_GROUP_AVATAR, topo_group_chat_allowed)) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "group avatar: router access policy initialization failed");
group_avatar_destroy(inst); return -1;
}
etcp_router_set_receive_ready(inst, ETCP_RT_ID_GROUP_AVATAR, ga_receive_ready);
ctx->timer = uasync_set_timeout(inst->ua, 10000, ctx, ga_tick, "group_avatar");
if (!ctx->timer) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "group avatar: initial timer failed"); group_avatar_destroy(inst); return -1; }
@@ -524,6 +530,20 @@ void group_avatar_cancel_group(struct UTUN_INSTANCE* inst, uint64_t group) {
while (*link) { struct ga_peer* p = *link; if (p->group != group) link = &p->next; else { *link = p->next; ga_free(p); } }
}
void group_avatar_revalidate_members(struct UTUN_INSTANCE* inst, uint64_t group) {
struct group_avatar* ctx = ga_context(inst);
if (!ctx || ctx->closing) return;
struct ga_peer** link = &ctx->peers;
while (*link) {
struct ga_peer* p = *link;
if (p->group != group || topo_group_chat_allowed(inst, group, p->peer)) { link = &p->next; continue; }
DEBUG_INFO(DEBUG_CATEGORY_CHAT, "group avatar: revoke group=%llx peer=%llx tx=%d rx=%d pending=%d/%d/%d",
(unsigned long long)group, (unsigned long long)p->peer, p->tx != NULL, p->rx != NULL,
p->state_pending, p->get_pending, p->reply_pending);
*link = p->next; ga_free(p);
}
}
void group_avatar_destroy(struct UTUN_INSTANCE* inst) {
struct group_avatar* ctx = ga_context(inst); if (!ctx) return;
ctx->closing = 1; if (ctx->timer) uasync_cancel_timeout(inst->ua, ctx->timer);
+2
View File
@@ -39,6 +39,8 @@ void group_avatar_destroy(struct UTUN_INSTANCE* inst);
// Отменить сборки/waiters/call_soon канала перед удалением группы; БД и router-сессия остаются у своих владельцев.
void group_avatar_cancel_group(struct UTUN_INSTANCE* inst, uint64_t group);
// После commit состава: снять сборки/waiters/call_soon отозванных участников только этого канала; БД сохраняется.
void group_avatar_revalidate_members(struct UTUN_INSTANCE* inst, uint64_t group);
// ── Чтение и изменение аватарки ──