Browse Source

Distinguish relay-only stream subscriptions in member profiles

master
evgeny 7 days ago
parent
commit
8883002e3f
  1. 20
      src/stream/stream_member.c
  2. 5
      src/stream/stream_member.h

20
src/stream/stream_member.c

@ -3,6 +3,7 @@
#include "../../lib/debug_config.h"
#include "../../lib/json_flat.h"
#include "../../lib/mem.h"
#include "../utun_instance.h"
#include "../routing_layer/topo_node_sqlite.h"
#include "stream_block.h"
@ -70,9 +71,10 @@ static int member_option(const char *key, const char *value, void *arg) {
const char *p = value;
while (*p) {
if (parse->state.count == STREAM_MEMBER_MAX_SUBSCRIPTIONS) return -1;
struct stream_subscription_key entry;
struct stream_subscription_key entry = {0};
if (member_hex(&p, &entry.source_node_id) != STREAM_OK || *p++ != ':'
|| member_hex(&p, &entry.source_epoch) != STREAM_OK) return -1;
if (*p == ':') { p++; if (*p++ != 'r') return -1; entry.relay_only = 1; }
if (parse->state.count) {
const struct stream_subscription_key *previous = &parse->state.subscriptions[parse->state.count - 1];
if (entry.source_node_id < previous->source_node_id
@ -132,8 +134,9 @@ int stream_member_format(const struct stream_member_state *state, char source[MS
&& entry->source_epoch <= state->subscriptions[i - 1].source_epoch)))) {
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "member format invalid subscription index=%zu", i); return STREAM_ERR_ARGUMENT;
}
int length = snprintf(encoded_subscriptions + used, sizeof(encoded_subscriptions) - used, "%s%016llx:%016llx",
i ? "," : "", (unsigned long long)entry->source_node_id, (unsigned long long)entry->source_epoch);
int length = snprintf(encoded_subscriptions + used, sizeof(encoded_subscriptions) - used, "%s%016llx:%016llx%s",
i ? "," : "", (unsigned long long)entry->source_node_id, (unsigned long long)entry->source_epoch,
entry->relay_only ? ":r" : "");
if (length < 0 || (size_t)length >= sizeof(encoded_subscriptions) - used) {
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "member subscriptions exceed limit count=%zu", state->count); return STREAM_ERR_ARGUMENT;
}
@ -217,3 +220,14 @@ int stream_member_online(struct UTUN_INSTANCE *inst, uint64_t group_id, uint64_t
struct TOPO_GROUP_NODE *node = topo_node_find_by_id(group, member_id);
return node && topo_node_best_path(node) != NULL;
}
/* Роль относится к каналу, не к устройству или глобальному media_delivery. */
int stream_member_supernode(struct UTUN_INSTANCE *inst, uint64_t group_id, uint64_t member_id) {
struct TOPO_GROUP *group = inst && inst->topo_groups ? topo_groups_find(inst->topo_groups, group_id) : NULL;
if (!group || group->stopping || group->group_type != TOPO_GROUP_TYPE_CHAT) return 0;
struct topo_connect_peer *peers = NULL; size_t count = 0;
if (topo_node_sqlite_get_connect_peers(inst->topo_sqlite_db, group->channel_id, &peers, &count) < 0) return -1;
int supernode = 0;
for (size_t i = 0; i < count; i++) if (peers[i].node_id == member_id) { supernode = peers[i].supernode; break; }
u_free(peers); return supernode;
}

5
src/stream/stream_member.h

@ -1,6 +1,6 @@
/* Строковые опции подписанного блока мембера, без отдельного протокола объявлений.
* stream_source = epoch(16 hex):n:r:RS-size; отсутствие/пустое значение — не публикует.
* stream_subscriptions = source(16 hex):epoch(16 hex),...; сортировка по source/epoch.
* stream_subscriptions = source(16 hex):epoch(16 hex)[:r],...; :r — только помощь, без локального зрителя.
* Указанная в stream_source собственная трансляция также должна быть в subscriptions.
* load проверяет подпись профиля и принадлежность ключа источника, BGP-доступность — отдельно.
* parse/format не меняют выход при ошибке. Все вызовы — один uasync-поток. */
@ -23,6 +23,7 @@ struct UTUN_INSTANCE;
struct stream_subscription_key {
uint64_t source_node_id;
uint64_t source_epoch;
int relay_only;
};
struct stream_member_state {
@ -43,6 +44,8 @@ int stream_member_has_subscription(const struct stream_member_state *state, uint
int stream_member_load(struct UTUN_INSTANCE *inst, uint64_t group_id, uint64_t member_id,
struct stream_member_state *state, uint8_t public_key[SC_PUBKEY_SIZE]);
int stream_member_online(struct UTUN_INSTANCE *inst, uint64_t group_id, uint64_t member_id);
/* Канальная роль из принятого блока владельца; -1 — ошибка чтения, 0/1 — отсутствие/наличие роли. */
int stream_member_supernode(struct UTUN_INSTANCE *inst, uint64_t group_id, uint64_t member_id);
#ifdef __cplusplus
}

Loading…
Cancel
Save