Cancel JOIN waiters when connection or inviter rights are revoked

This commit is contained in:
evgeny committed 2026-11-03 20:40:33 +01:00
1 parent 5d0e4a4673
commit c3575aca6f
3 files changed
+30 -1

No files matched your search

+23 -1
View File
@@ -1608,11 +1608,32 @@ static void cs_pending_prune(struct chat_sync* cs) {
}
}
void chat_sync_revalidate_join(struct UTUN_INSTANCE* inst, uint64_t group) {
struct chat_sync* cs = cs_of(inst);
if (!cs || !cs->initialized) return;
struct join_pending** link = &cs->join_pending;
while (*link) {
struct join_pending* p = *link;
uint64_t channel = strtoull(p->ch_id, NULL, 10);
if ((group && group != channel) || (topo_group_chat_allowed(inst, channel, p->inviter) &&
group_policy_can_invite(inst, p->ch_id, p->inviter) == 1)) { link = &p->next; continue; }
*link = p->next;
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "join waiter revoked ch=%s peer=%016llx inviter=%016llx attempt=%016llx", p->ch_id,
(unsigned long long)p->node_id, (unsigned long long)p->inviter, (unsigned long long)p->attempt);
int32_t code = CHAT_CONNECT_AUTH;
uint8_t error[5] = {CS_MSG_ERROR}; memcpy(error + 1, &code, 4);
cs_send_attempt(cs, p->ch_id, p->node_id, error, sizeof(error), p->attempt, &p->route);
if (p->route.handle && inst->join_carrier) inst->join_carrier->close(inst->join_carrier->ctx, p->route.handle, 0);
u_free(p);
}
}
/* ─── отправка JOIN_READY джойнеру + снятие pending (connection-узел) ─── */
static void cs_send_join_ready(struct chat_sync* cs, const char* ch_id, uint64_t node_id) {
if (!topo_node_sqlite_member_allowed(cs->inst->topo_sqlite_db, ch_id, node_id)) return;
uint64_t group = strtoull(ch_id, NULL, 10);
chat_sync_revalidate_join(cs->inst, group);
if (!topo_group_chat_allowed(cs->inst, group, node_id)) return;
uint8_t data[9] = { CS_MSG_JOIN_READY }; memcpy(data + 1, &group, 8);
int sent = 0;
struct join_pending** link = &cs->join_pending;
@@ -1644,6 +1665,7 @@ void chat_sync_join_inviter_result(struct UTUN_INSTANCE* inst, uint64_t channel,
uint64_t attempt, uint64_t node, int result) {
struct chat_sync* cs = cs_of(inst);
if (!cs || !cs->initialized) return;
chat_sync_revalidate_join(inst, channel);
char ch[32]; snprintf(ch, sizeof(ch), "%llu", (unsigned long long)channel);
struct join_pending** link = &cs->join_pending;
while (*link) {
+3
View File
@@ -103,6 +103,9 @@ void chat_sync_join_result(struct UTUN_INSTANCE* inst, uint64_t request, uint64_
/* Подписанный ответ инвайтера на forwarded JOIN. Проверяет inviter, attempt и node ожидающего запроса. */
void chat_sync_join_inviter_result(struct UTUN_INSTANCE* inst, uint64_t channel, uint64_t inviter,
uint64_t attempt, uint64_t node, int result);
/* uasync после commit: отменить ожидания JOIN_READY, если connection/инвайтер потеряли доступ или право приглашать.
* group=0 проверяет все каналы. Джойнеру членство до сохранения его записи не требуется. */
void chat_sync_revalidate_join(struct UTUN_INSTANCE* inst, uint64_t group);
/* uasync: пригласить адресата в свой channel. SERVER-ссылка запускает запрос с add_key и обычным
* приглашением через self; успех возвращает сервер после своего JOIN. CHANNEL — обычный push-invite.
+4
View File
@@ -34,6 +34,8 @@
#include "../stream/stream.h"
#include "../chat/chat_setting.h"
#include "../chat/group_avatar.h"
#include "../chat/chat_join.h"
#include "../chat/chat_sync.h"
#include "../member_files/member_files.h"
#define TOPO_GROUP_UTUN 0x8000000000000000ULL
@@ -446,6 +448,8 @@ void topo_group_revalidate_members(struct TOPO_GROUP* group) {
radio_call_revalidate_members(group->instance, group->group_id);
member_files_revalidate_members(group->instance, group->group_id);
group_avatar_revalidate_members(group->instance, group->group_id);
chat_join_revalidate_members(group->instance, group->group_id);
chat_sync_revalidate_join(group->instance, group->group_id);
/* Удаление вызывает callbacks и меняет список; каждый раз ищем следующего заново. */
for (;;) {
struct TOPO_GROUP_CONN_ITEM* invalid = NULL;