BGP: фикс владения адресами в реестре (мульти-группа), проброс group_id в сервис (conn_mgr per-group), membership-фильтр create_group; тест media через chat-группу
This commit is contained in:
1 parent
6c9a47b201
commit
42a94aa916
14 files changed
+324
-71
No files matched your search
@@ -132,6 +132,21 @@ uint64_t* topo_node_best_hop_list(struct TOPO_GROUP_NODE* nq, uint8_t* out_count
|
||||
return (uint64_t*)((uint8_t*)best + sizeof(struct TOPO_NODEPATH));
|
||||
}
|
||||
|
||||
/* Освобождает списки адресов (sock_meta + addrs + reality) узла в глобальном реестре.
|
||||
* Адреса — глобальная идентичность узла, шарится между группами через node_registry,
|
||||
* поэтому освобождаются только при последнем unref (topo_node_registry_unref). */
|
||||
static void topo_node_identity_free(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
|
||||
if (!groups || !ni) return;
|
||||
free_v4_sock_list(groups->v4_sock_meta_pool, ni->v4_sock_meta);
|
||||
free_v4_addr_list(groups->v4_addr_pool, ni->v4_addrs);
|
||||
free_v6_sock_list(groups->v6_sock_meta_pool, ni->v6_sock_meta);
|
||||
free_v6_addr_list(groups->v6_addr_pool, ni->v6_addrs);
|
||||
free_reality_sock_list(ni->reality_socks);
|
||||
ni->v4_sock_meta = NULL; ni->v4_addrs = NULL;
|
||||
ni->v6_sock_meta = NULL; ni->v6_addrs = NULL;
|
||||
ni->reality_socks = NULL;
|
||||
}
|
||||
|
||||
void topo_node_free_raw(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
|
||||
if (!ni) return;
|
||||
if (groups) {
|
||||
@@ -151,18 +166,7 @@ void topo_node_destroy(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
|
||||
|
||||
void topo_nodeq_free_group_fields(struct TOPO_GROUPS* groups, struct TOPO_GROUP_NODE* nq) {
|
||||
if (!groups || !nq) return;
|
||||
struct TOPO_NODE* ni = topo_node_registry_find(groups, nq->node_id);
|
||||
if (ni) {
|
||||
free_v4_sock_list(groups->v4_sock_meta_pool, ni->v4_sock_meta);
|
||||
free_v4_addr_list(groups->v4_addr_pool, ni->v4_addrs);
|
||||
free_v6_sock_list(groups->v6_sock_meta_pool, ni->v6_sock_meta);
|
||||
free_v6_addr_list(groups->v6_addr_pool, ni->v6_addrs);
|
||||
free_reality_sock_list(ni->reality_socks);
|
||||
ni->v4_sock_meta = NULL; ni->v4_addrs = NULL;
|
||||
ni->v6_sock_meta = NULL; ni->v6_addrs = NULL;
|
||||
ni->reality_socks = NULL;
|
||||
topo_node_registry_unref(groups, nq->node_id);
|
||||
}
|
||||
topo_node_registry_unref(groups, nq->node_id);
|
||||
if (nq->subnets) {
|
||||
free_v4_sub_list(groups->v4_subnet_pool, nq->subnets->v4_subnets);
|
||||
free_v6_sub_list(groups->v6_subnet_pool, nq->subnets->v6_subnets);
|
||||
@@ -183,22 +187,42 @@ struct TOPO_NODE* topo_node_registry_find(struct TOPO_GROUPS* groups, uint64_t n
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Является ли входящий узел полной идентичностью (BGP NODEINFO / локальный узел).
|
||||
* Partial-узлы из invite/DB-load не несут ed25519 — по ним идентичность не перезаписываем. */
|
||||
static int topo_node_is_full_identity(const struct TOPO_NODE* ni) {
|
||||
for (int i = 0; i < SC_PUBKEY_SIZE; i++) if (ni->ed25519_public_key[i]) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct TOPO_NODE* topo_node_registry_store(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni) {
|
||||
if (!groups || !ni) return NULL;
|
||||
struct TOPO_NODE* existing = topo_node_registry_find(groups, ni->node_id);
|
||||
if (existing) {
|
||||
int n4 = topo_list_count((struct _topo_head*)ni->v4_addrs);
|
||||
int n6 = topo_list_count((struct _topo_head*)ni->v6_addrs);
|
||||
int e4 = topo_list_count((struct _topo_head*)existing->v4_addrs);
|
||||
int e6 = topo_list_count((struct _topo_head*)existing->v6_addrs);
|
||||
int drop4 = (e4 && n4), drop6 = (e6 && n6);
|
||||
if (drop4 || drop6)
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "registry_store: node=%016llx EXISTS — dropping new addrs v4=%d v6=%d (existing v4=%d v6=%d)",
|
||||
(unsigned long long)ni->node_id, drop4 ? n4 : 0, drop6 ? n6 : 0, e4, e6);
|
||||
topo_node_ref(existing);
|
||||
if (!existing->v4_addrs && ni->v4_addrs) { existing->v4_addrs = ni->v4_addrs; ni->v4_addrs = NULL; }
|
||||
if (!existing->v6_addrs && ni->v6_addrs) { existing->v6_addrs = ni->v6_addrs; ni->v6_addrs = NULL; }
|
||||
if (!existing->reality_socks && ni->reality_socks) { existing->reality_socks = ni->reality_socks; ni->reality_socks = NULL; }
|
||||
|
||||
/* Идентичность (ver/имя/pubkeys/подпись) — авторитетна у полного NODEINFO,
|
||||
* иначе реестр держит устаревший ver/имя и форвард nodeinfo ломает подпись. */
|
||||
if (topo_node_is_full_identity(ni)) {
|
||||
existing->ver = ni->ver;
|
||||
existing->client_type = ni->client_type;
|
||||
existing->client_activity = ni->client_activity;
|
||||
memcpy(existing->public_key, ni->public_key, SC_PUBKEY_SIZE);
|
||||
memcpy(existing->ed25519_public_key, ni->ed25519_public_key, SC_PUBKEY_SIZE);
|
||||
memcpy(existing->x25519_self_sig, ni->x25519_self_sig, 64);
|
||||
if (ni->node_name) {
|
||||
if (existing->node_name) u_free(existing->node_name);
|
||||
existing->node_name = ni->node_name; ni->node_name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Адреса — глобальная идентичность. Обновляем каждый список, который входящий узел несёт
|
||||
* (частичные узлы заполняют только то, что знают, не затирая остальное). */
|
||||
if (ni->v4_sock_meta) { free_v4_sock_list(groups->v4_sock_meta_pool, existing->v4_sock_meta); existing->v4_sock_meta = ni->v4_sock_meta; ni->v4_sock_meta = NULL; }
|
||||
if (ni->v4_addrs) { free_v4_addr_list(groups->v4_addr_pool, existing->v4_addrs); existing->v4_addrs = ni->v4_addrs; ni->v4_addrs = NULL; }
|
||||
if (ni->v6_sock_meta) { free_v6_sock_list(groups->v6_sock_meta_pool, existing->v6_sock_meta); existing->v6_sock_meta = ni->v6_sock_meta; ni->v6_sock_meta = NULL; }
|
||||
if (ni->v6_addrs) { free_v6_addr_list(groups->v6_addr_pool, existing->v6_addrs); existing->v6_addrs = ni->v6_addrs; ni->v6_addrs = NULL; }
|
||||
if (ni->reality_socks) { free_reality_sock_list(existing->reality_socks); existing->reality_socks = ni->reality_socks; ni->reality_socks = NULL; }
|
||||
|
||||
topo_node_free_raw(groups, ni);
|
||||
return existing;
|
||||
}
|
||||
@@ -223,6 +247,8 @@ void topo_node_registry_unref(struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
struct TOPO_NODE* ni = topo_node_registry_find(groups, node_id);
|
||||
if (!ni) return;
|
||||
uint32_t prev_ref = ni->group_ref_count;
|
||||
if (prev_ref == 1)
|
||||
topo_node_identity_free(groups, ni);
|
||||
topo_node_unref(ni);
|
||||
if (prev_ref == 1) {
|
||||
struct ll_entry* e = groups->node_registry ? queue_find_data_by_index(groups->node_registry, &node_id) : NULL;
|
||||
|
||||
Reference in new issue
Block a user