Authorize call channels and stop revoked calls immediately
This commit is contained in:
1 parent
8633b35388
commit
d83ab168cb
2 files changed
+41
-2
No files matched your search
+34
-2
@@ -161,7 +161,7 @@ static int call_send_invite(struct call_ctx* ctx, struct call_session* s) {
|
||||
int call_resolve_targets(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t peer, int devices,
|
||||
uint64_t* out, unsigned capacity) {
|
||||
struct TOPO_GROUP* g = inst && inst->topo_groups ? topo_groups_find(inst->topo_groups, group) : NULL;
|
||||
if (!g || g->group_type != TOPO_GROUP_TYPE_CHAT || !peer || !out || !capacity) {
|
||||
if (!g || !topo_group_chat_allowed(inst, group, peer) || !peer || !out || !capacity) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CALL, "call target invalid group=%llx peer=%llx", (unsigned long long)group, (unsigned long long)peer);
|
||||
return -1;
|
||||
}
|
||||
@@ -424,6 +424,11 @@ static void call_target_tick(void* arg) {
|
||||
for (unsigned i = 0; i < s->target_count; ++i) {
|
||||
struct call_target* t = &s->targets[i];
|
||||
if (!t->end_subcmd || t->ack) continue;
|
||||
if (!topo_group_chat_allowed(s->ctx->inst, s->group_id, t->peer)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "call target retry cancelled after revoke id=%llx peer=%llx",
|
||||
(unsigned long long)s->call_id, (unsigned long long)t->peer);
|
||||
t->ack = 1; continue;
|
||||
}
|
||||
if (now - t->ended_tb >= CALL_END_TIMEOUT_TB) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CALL, "call target end timeout id=%llx peer=%llx",
|
||||
(unsigned long long)s->call_id, (unsigned long long)t->peer);
|
||||
@@ -516,6 +521,30 @@ static void call_end(struct call_ctx* ctx, struct call_session* s, uint8_t reaso
|
||||
call_session_remove_and_free(ctx, s);
|
||||
}
|
||||
|
||||
void call_revalidate_members(struct UTUN_INSTANCE* inst, uint64_t group) {
|
||||
struct call_ctx* ctx = call_of(inst);
|
||||
struct ll_entry* e = ctx && ctx->sessions ? ctx->sessions->head : NULL;
|
||||
while (e) {
|
||||
struct call_session* s = (struct call_session*)e->data;
|
||||
e = e->next;
|
||||
if (s->group_id != group) continue;
|
||||
int allowed = topo_group_chat_allowed(inst, group, s->peer_node_id);
|
||||
for (unsigned i = 0; i < s->target_count; ++i) {
|
||||
struct call_target* t = &s->targets[i];
|
||||
if (topo_group_chat_allowed(inst, group, t->peer)) continue;
|
||||
t->ack = 1;
|
||||
if (!s->selected && t->state != CALL_ST_ENDED) allowed = 0;
|
||||
}
|
||||
if (allowed) continue;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "call access revoked id=%llx group=%llx peer=%llx state=%s; stopping media and retries",
|
||||
(unsigned long long)s->call_id, (unsigned long long)group,
|
||||
(unsigned long long)s->peer_node_id, call_state_name(s->state));
|
||||
if (s->cm_handle) { conn_mgr_close(s->cm_handle); s->cm_handle = NULL; }
|
||||
s->end_subcmd = 0;
|
||||
call_end(ctx, s, CALL_REASON_CONNECT_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ─────────────────── conn_mgr ─────────────────── */
|
||||
|
||||
static void call_traffic_timeout_cb(void* arg);
|
||||
@@ -1114,8 +1143,10 @@ int call_init(struct UTUN_INSTANCE* inst) {
|
||||
|
||||
ctx->initialized = 1;
|
||||
if (etcp_router_require_crypto(inst, ETCP_RT_ID_CALL, ROUTE_CRYPTO_SIGN | ROUTE_CRYPTO_ENCRYPT)
|
||||
|| etcp_router_set_authorize(inst, ETCP_RT_ID_CALL, topo_group_chat_allowed)
|
||||
|| etcp_router_bind(inst, ETCP_RT_ID_CALL_AUDIO, call_etcp_recv)
|
||||
|| etcp_router_require_crypto(inst, ETCP_RT_ID_CALL_AUDIO, ROUTE_CRYPTO_SIGN | ROUTE_CRYPTO_ENCRYPT)
|
||||
|| etcp_router_set_authorize(inst, ETCP_RT_ID_CALL_AUDIO, topo_group_chat_allowed)
|
||||
|| call_video_transport_bind(inst)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call media channel bind failed");
|
||||
call_destroy(inst); return -1;
|
||||
@@ -1165,8 +1196,9 @@ int call_busy(struct UTUN_INSTANCE* inst) {
|
||||
/* Только uasync: проверка доступности перед созданием сессии; очереди групп не межпоточные. */
|
||||
static int call_is_online(struct UTUN_INSTANCE* inst, const char* ch_id, uint64_t peer_node_id) {
|
||||
if (!inst || !ch_id || !ch_id[0] || !inst->topo_groups) return 0;
|
||||
if (peer_node_id == inst->node_id) return 1;
|
||||
uint64_t group_id = strtoull(ch_id, NULL, 10);
|
||||
if (!topo_group_chat_allowed(inst, group_id, peer_node_id)) return 0;
|
||||
if (peer_node_id == inst->node_id) return 1;
|
||||
struct TOPO_GROUP* g = topo_groups_find(inst->topo_groups, group_id);
|
||||
if (!g) return 0;
|
||||
return topo_node_find_by_id(g, peer_node_id) != NULL;
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
// CHAT-группы или из DM (group_id — группа маршрутизации, как в dm_core).
|
||||
// Сигналинг, аудио и видео идут через etcp_router с обязательными ROUTE_CRYPTO_SIGN|ENCRYPT; соединение
|
||||
// оптимизируется через параллельные пробы conn_mgr (DIRECT/REVERSE/INDIRECT).
|
||||
// Оба узла должны оставаться допущенными участниками группы доставки. При отзыве доступа
|
||||
// или остановке группы звонок завершается, очереди медиа очищаются. Группа активного звонка
|
||||
// не меняется; новый звонок из DM заново выбирает доступную общую группу через dm_call_route.
|
||||
//
|
||||
// Все функции, кроме явно отмеченных, — в uasync-потоке. GUI/headless вызывают через trampoline
|
||||
// (gui_bridge_post_uasync_fn / uasync_post).
|
||||
@@ -34,6 +37,10 @@ int call_init(struct UTUN_INSTANCE* inst);
|
||||
* Регистрация call_audio_ops у ядра сохраняется, DSP и устройства frontend здесь не освобождаются. */
|
||||
void call_destroy(struct UTUN_INSTANCE* inst);
|
||||
|
||||
/* uasync: после изменения участников/остановки CHAT-группы завершить затронутые звонки
|
||||
* с CONNECT_FAIL, отменить их медиа/CM/повторы отозванным пирам. Остальные группы не затрагивает. */
|
||||
void call_revalidate_members(struct UTUN_INSTANCE* inst, uint64_t group);
|
||||
|
||||
// ── сигналинг (uasync-поток) ──
|
||||
|
||||
/* Caller: ch_id — группа либо "dm:<conv_id>" (BGP-группа выбирается при запуске).
|
||||
|
||||
Reference in new issue
Block a user