From f9994e11b5e193d56b19eeb8feac0b5d11a76194 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 24 Oct 2026 14:17:13 +0200 Subject: [PATCH] Clarify local update ownership, results and failure contracts --- src/routing_layer/topo_node.c | 6 +++--- src/routing_layer/topo_node.h | 15 +++++++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/routing_layer/topo_node.c b/src/routing_layer/topo_node.c index 18016f8b..54bf1712 100644 --- a/src/routing_layer/topo_node.c +++ b/src/routing_layer/topo_node.c @@ -1118,7 +1118,7 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR if (!lq) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "local node update: allocation failed"); return -1; } struct TOPO_NODE* ni = NULL; char* name = NULL; - int new_identity = 0, retained = 0, routes_changed = 0, vc = 0, vc6 = 0; + int new_identity = 0, retained = 0, routes_changed = 0, changed = 1, vc = 0, vc6 = 0; lq->node_id = instance->node_id; lq->radio = group->radio_active; lq->phone_status = call_phone_status(instance); if (group->group_type != TOPO_GROUP_TYPE_CHAT) { struct TOPO_SUBNET4** tail4 = NULL; struct TOPO_SUBNET6** tail6 = NULL; @@ -1150,7 +1150,7 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR } } ni = topo_node_registry_find(groups, instance->node_id); - int changed = !old || !ni || strcmp(ni->node_name ? ni->node_name : "", instance->name) || + changed = !old || !ni || strcmp(ni->node_name ? ni->node_name : "", instance->name) || memcmp(ni->public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE) || memcmp(ni->ed25519_public_key, instance->my_ed25519_pubkey, SC_PUBKEY_SIZE) || ni->client_type != instance->client_type || ni->client_activity != instance->client_activity || @@ -1201,7 +1201,7 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR lq->last_ver = ni->ver; lq->last_timestamp = ni->timestamp; if (old) { topo_nodeq_clear_paths(old); topo_nodeq_free_group_fields(groups, old); u_free(old); } group->local_node = lq; - DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "local node published: group=%016llx v4=%d v6=%d ver=%u timestamp=%llu", + DEBUG_INFO(DEBUG_CATEGORY_BGP, "local node published: group=%016llx v4=%d v6=%d ver=%u timestamp=%llu", (unsigned long long)group->group_id, vc, vc6, ni->ver, (unsigned long long)ni->timestamp); return vc; allocation_failed: diff --git a/src/routing_layer/topo_node.h b/src/routing_layer/topo_node.h index 31bebbda..f9d7f8c0 100644 --- a/src/routing_layer/topo_node.h +++ b/src/routing_layer/topo_node.h @@ -212,7 +212,7 @@ struct TOPO_GROUP_NODE { uint64_t node_id; // идентификатор узла в этой группе struct TOPO_NODESUBNETS* subnets; // подсети узла (v4/v6), для route_insert() struct ll_queue* paths; // TOPO_NODEPATH{conn,hop_count,rtt} — маршруты - uint8_t last_ver; // последняя версия NODEINFO (защита от stale, BGP) + uint8_t last_ver; // диагностический циклический ver; свежесть определяется timestamp uint64_t last_timestamp; // последняя принятая версия записи в группе uint8_t conn_mgr_type; // CONN_TYPE_DIRECT/REVERSE/INDIRECT/NONE uint64_t conn_mgr_intermediaries[CONN_MGR_MAX_INTERMEDIARIES]; // посредники для INDIRECT @@ -271,11 +271,17 @@ uint64_t* topo_node_best_hop_list(struct TOPO_GROUP_NODE* nq, uint8_t* out_count /* Лучший живой путь: минимум переходов, затем ID соседа. Указатель заимствованный. */ struct TOPO_NODEPATH* topo_node_best_path(const struct TOPO_GROUP_NODE* nq); -/* Обновить локальный узел группы и его анонс. 0/-1. */ +/* Подготовить и опубликовать local_node с актуальными подсетями/состоянием; число IPv4-подсетей или -1. + * Учитывает адреса и префиксы, а не только счётчики; CHAT не анонсирует подсети и возвращает 0. + * При отказе подготовки/подписи или конфликте IPv4 сохраняет прежние local_node и маршруты. + * Вызывает обновление общей подписанной записи; рассылку NODEINFO выполняет вызывающий. */ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GROUP* group); /* Создать подписанную локальную идентичность с отдельной ссылкой ядра. 0/-1. */ int topo_node_init_self(struct UTUN_INSTANCE* instance); -int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance); /* 1=changed, 0=unchanged, -1=error */ +/* Пересобрать общие адреса из рабочих UDP/TCP-сокетов; 1=изменились, 0=прежние, -1=ошибка. + * Новая запись подписывается/сохраняется перед заменой, затем рассылается во все группы. + * Ошибка SQL-проекции даёт -1 и после применённого изменения; при неизменных адресах проекция также обновляется. */ +int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance); /* Обработчик изменений локального сокета: обновляет адреса узла. */ void topo_node_on_socket_changed(struct ETCP_SOCKET* sock, int event, void* arg); /* Вывести диагностику узлов группы в лог категории BGP на уровне INFO. */ @@ -299,7 +305,8 @@ uint16_t topo_get_chain_rtt(struct TOPO_GROUP_NODE* nq); * тип/активность и полные списки сокетов/адресов/Reality. Длина или -1. */ int topo_node_build_sig_msg(struct TOPO_NODE* ni, uint8_t* buf, size_t buf_size); -/* Увеличить timestamp, подписать локальный NODEINFO и сохранить снимок в SQLite. 0/-1. */ +/* Увеличить timestamp (выше текущего/сохранённого), подписать локальный NODEINFO; при наличии SQLite сохранить снимок. + * 0/-1; при ошибке возвращает прежние timestamp/подпись, остальные изменённые вызывающим поля не откатывает. */ int topo_node_sign_self(struct UTUN_INSTANCE* instance, struct TOPO_NODE* ni); /* Проверить timestamp, привязку node_id к ключу и подпись. 0/-1. */ int topo_node_verify(const struct TOPO_NODE* ni);