Commit Graph
2373 Commits
Author SHA1 Message Date
Evgeny 3f662d85ba chat_core: split 912-line module into 5 files + delete dead chat_conn_mgr
chat_core.c (236 lines): init/destroy, getters, g_cc, helpers, si-registry
chat_msg.c (223 lines): submit_message, count, chain_hash, list_*, load_nodeinfo
chat_channel.c (197 lines): ensure_ready, create_channel, connect_channel, sign_join helper
chat_profile.c (189 lines): update_my_name, sync_my_addresses, save_ui_state
chat_status.c (118 lines): collect_status (NTP + ETCP connections)
chat_core_priv.h: shared g_cc extern + helpers

chat_conn_mgr.c/h: dead code (never compiled, never called)
CMakeLists.txt: add 4 new .c files to build
2026-07-23 22:41:28 +03:00
Evgeny 3448b0a482 channellist: fix dual blue selection — block signals + explicit select
- selectionCommand: remove Current flag to avoid redundant
  currentChanged emission during mouse press
- loadChannels: wrap clear+repopulate in blockSignals(true/false)
  to prevent selectionChanged and currentChanged from firing
  on intermediate model states
- selectChannel: use explicit selectionModel()->select() with
  ClearAndSelect + setCurrentIndex with NoUpdate
- simplified selection restore: only track selectedCid by ID,
  removed fallback-to-row logic
2026-07-23 21:31:00 +03:00
Evgeny 4ec930c8f0 chatgui: fix dual selection highlight and missing online count
- channellist.cpp: selectionChanged guard now checks currentIndex().row()
  is within model->rowCount() to avoid re-selecting stale index after
  model clear, which caused both channels to stay blue when switching.
- chat_sync.c: cs_refresh_channels now posts CHANNEL_PEERS_ONLINE
  for all channels after loading, fixing online count showing only
  on the last connected group.
2026-07-23 21:25:39 +03:00
Evgeny cbd9536a28 chatgui: fix invite link and Russian channel name encoding
- chat_sync.c: after invite trampoline, check if connection to invite
  node is already UP and trigger cs_on_conn_up to send CHANNEL_INFO_REQ.
  Fixes invite not completing when connection is reused (Fix 1 side effect).
- mainwindow.cpp: use name.toUtf8().constData() instead of qPrintable()
  to preserve UTF-8 encoding on Windows (Russian channel names).
2026-07-23 21:07:41 +03:00
Evgeny 23db012064 conn_mgr: fix duplicate connection and double-release bugs
- conn_mgr_connect_node: check instance->connections globally to reuse
  existing ETCP_CONN across groups instead of creating a new one (DUP addr)
- cm_start_phase_direct: close dead connection when etcp_link_new fails
  to prevent shadowing live connection in instance->connections hash
- cm_cleanup_db_node: remove redundant topo_node_registry_release
  (already done inside topo_node_free_lists)
2026-07-23 20:36:55 +03:00
Evgeny 58ad643516 Add debug logs to Ed25519 self-sig flow: computation, verification, skip due to no key 2026-07-23 20:00:11 +03:00
Evgeny 85269d1da3 Ed25519 self-signature in NODEINFO + fix sync sequence and zero-key bug
Add x25519_self_sig[64] to TOPOMSG_NODE/TOPO_NODE:
- topo_node.h: add field to both structs (wire format + memory)
- topo_node.c: compute Ed25519_sign(ed25519_privkey, x25519_pubkey) for own node
- topo_node.c: serialize/deserialize x25519_self_sig
- topo_group.c: verify Ed25519 self-sig on NODEINFO receive, reject forgery

Fix Ed25519 pubkey zero-key bug:
- topo_node_sqlite.c: get_ed25519_pubkey rejects all-zero key (MUST be non-zero)

Delay db_sync until Ed25519 key is available:
- db_sync.c: db_sync_on_conn_up checks db_get_ed25519_pubkey before starting
- db_sync.c: db_sync_peer_check_cb also checks Ed25519 key availability
- This prevents sync starting before NODEINFO with verified Ed25519 arrives
2026-07-23 19:55:15 +03:00
Evgeny 3890d2038d db_sync: add missing ERROR/WARN logs to all error branches
- db_record_insert: error logs for si_prep failures (SELECT, INSERT, cascade SELECT/UPDATE)
- si_parse_record: WARN logs for truncated header, data/sig overrun
- db_chain_hash_at: ERROR logs for missing row, corrupted blob
- db_prev_chain_hash: ERROR log for si_prep failure
- db_cascade_from: ERROR logs for si_prep failures
2026-07-23 18:16:53 +03:00
Evgeny acd4a189ae db_sync: add author_sig VERIFY FAIL diagnostics + SYNC_DONE retry limit
- db_verify_author_sig: show ed_pubkey and sig first bytes on failure
- SI_PEER: add sync_retry_count field
- db_handle_sync_done: limit re-initiate to 3 retries before giving up
- db_sync_initiate_sync / db_sync_on_conn_up: reset retry_count
2026-07-23 18:13:14 +03:00
Evgeny b48d3b4a77 db_sync: add diagnostic logs for message sync debugging during join
- db_handle_init_sync: TRACE→INFO with peer_cnt/my_cnt/tp_offset
- db_handle_send_data: detailed batch info (range, remaining count)
- db_sync_initiate_sync: add table name to log
- db_sync_on_conn_up: add first table name to summary log
2026-07-23 16:47:22 +03:00
Evgeny 3e95cf5ca6 fix: dialog hangs on join success + remove per-packet spam logs
- chat_sync.c: move pending_invite clear from INFO_RESP to WELCOME,
  post GUI_EVT_CONNECT_RESULT on invite success in cs_handle_welcome
- etcp_connections.c: NORM_DECRYPT_TRY/CRYPTO_DECRYPT_OK DEBUG_DEBUG->TRACE
- secure_channel.c: ENCRYPT/DECRYPT DEBUG_DEBUG->TRACE
2026-07-23 16:36:40 +03:00
Evgeny 4f831703f0 fix: etcp_conn_set_peer_node_id переиндексация при state=0 + conn_mgr ставит peer_id сразу 2026-07-23 16:19:03 +03:00
Evgeny 511a2dcd06 fix: авто-подключение Phase 2/3 — запрос всех нод из node_addresses, без привязки к peers_<ch> 2026-07-23 14:41:22 +03:00
Evgeny 196c2896d3 debug: sochet count after instance_init (категория debug, видно при текущем конфиге) 2026-07-23 14:17:58 +03:00
Evgeny 01a0a568a6 debug: crypto_ctx session_key логгирование — CRYPTO_CONN_READY, CRYPTO_ON_UP, CRYPTO_DECRYPT_OK, DECRYPT_FAIL+seskey 2026-07-23 14:04:44 +03:00
Evgeny 3e0a4e0eb1 fix: замена malloc на u_strdup в channelSelected — u_free падал на чужой памяти 2026-07-23 13:12:04 +03:00
Evgeny 0e324cf36d chat_core: connect_channel API — запуск topo_group_connect_init при выборе канала из GUI, убрано дублирование создания групп в utun_node 2026-07-23 12:51:45 +03:00
Evgeny be258eea4d fix: remove stale peers_* CREATE TABLE from chat_core, drop ORDER BY node_RTT
chat_core_ensure_channel_ready() had a duplicate CREATE TABLE peers_*
with OLD schema (no node_RTT, node_type, connected). Since it was called
from 4 places WITHOUT topo_node_sqlite_channel_put() first, the old
schema was created first, and IF NOT EXISTS in the new DDL was a no-op.

Removed the entire old block. Only topo_node_sqlite_channel_put() now
creates peers_* tables with the full schema.

Also removed ORDER BY p.node_RTT from get_public_peers/get_local_peers —
ordering not needed for sequential connect attempts.
2026-07-23 00:24:16 +03:00
Evgeny 8facce46ac feat: auto-connect Phase 3 (local/netif addresses) + restart fix
Phase 1: connected peers (connected=1)
Phase 2: direct/EIM (addr_type=1,2), exclude self
Phase 3: local/strict NAT (addr_type=0,3), exclude self
Timeout: 5000→2000ms per attempt
Restart: DOWN triggers reconnect when phase=DONE & active=0

Debug logs: init, Phase1 per-peer, UP phase info, restart branches
2026-07-22 23:55:44 +03:00
Evgeny 7dee05c628 fix: node_registry crash — TOPO_NODE_REG_ENTRY node/lldata overlap
struct TOPO_NODE_REG_ENTRY имел node и ll.data[0] (гибкий массив) на одном смещении.
memcpy(re->ll.data, &node_id, 8) затирало re->node значением node_id,
из-за чего node_registry_find возвращал не указатель а битый node_id → SIGSEGV.

Убрал struct TOPO_NODE_REG_ENTRY, перешёл на явные смещения:
data[0..7]=ключ, data[8..15]=указатель, queue_entry_new(16).
2026-07-22 23:05:04 +03:00
Evgeny 6edd40d141 topo_group_connect: авто-подключение CHAT-групп + conn_mgr_connect_from_invite + замена chat_conn_mgr в chatgui
Добавлено:
- conn_mgr_connect_from_invite() — подключение к новому узлу по invite-данным
  (INIT → INVITE_INFO_REQ/RESP → проверка членства в группе → сохранение в БД)
- topo_group_connect.c — авто-подключение при старте CHAT-группы:
  Phase 1: одновременный connect всех connected=1 пиров, таймаут, отмена незавершённых
  Phase 2: последовательный перебор публичных адресов до первого успеха
- Счётчик active_conn_count с проверкой nodeinfo-путей (UP/DOWN)
- restart() при phase=DONE и count==0

БД:
- connected INTEGER NOT NULL DEFAULT 0 в peers_<ch> + ALTER TABLE для существующих
- topo_node_sqlite_set_connected / get_connected_peers / get_public_peers

Chatgui:
- Включён topo_group (убран utun_instance_set_topo_group_enabled(0))
- Создание TOPO_GROUP_TYPE_CHAT при channel_ready и при старте
- Invite connect через conn_mgr_connect_from_invite
- Удалён chat_conn_mgr (из сборки) + весь старый auto-connect код
2026-07-22 22:48:12 +03:00
Evgeny 4215349349 topo_recovery: каскадное восстановление узлов с группировкой по next_hop
При разрыве ETCP-соединения модуль собирает каскадно отвалившиеся узлы:
- add_node из hop_list вычисляет next_hop относительно failed_peer,
  группирует узлы в отдельные recovery-контексты (direct/indirect списки)
- start запускает асинхронный перебор для каждой группы параллельно
- is_next_hop-узел пробуется первым с приоритетом по мин. RTT
- таймаут 2с на попытку, conn_mgr_cancel_callback при отмене
- отмена: topo_group_new_conn (on_up) находит узел в любом ctx -> ctx целиком
- завершение: оба списка пусты -> освобождение ctx
2026-07-22 19:01:55 +03:00
Evgeny f6b37a857b conn_mgr: bind to topo_group, DB node loading, configurable DIRECT timeout, tests
- conn_mgr_init(TOPO_GROUP* group) — работает внутри заданной группы
- conn_mgr_connect_node: загрузка узла из SQLite если нет в BGP-таблице
- topo_node_sqlite_node_load(): загрузка TOPO_NODE (ref=0) из БД
- cm_start_phase_direct: db_loaded-ветка — перебор всех адресов без NAT-фильтра
- cm_cleanup_db_node: удаление TOPO_NODEQ из группы при неудаче, только если нет путей
- cm_start_phase_indirect: исправлено зависание при best_candidates==0 (cm_deliver_result)
- conn_mgr_set_direct_timeout_ms(): конфигурируемый таймаут фазы DIRECT
- conn_mgr_destroy до etcp_router_destroy (исправлен порядок)
- test_conn_mgr: +2 сценария (DB-успех, DB-недоступен), проверка topo_group
2026-07-22 17:33:58 +03:00
Evgeny 852ce401e7 Добавлен group_id в etcp_router и topo_group, удалён msg_transport
- etcp_router: SVC_ROUTE_HDR (+8B), ETCP_ROUTER_CONN/TRANSIT_QUEUE хеши расширены под group_id
- Все caller'ы (proxy, routing, conn_mgr, nat, chatgui, tests) обновлены
- topo_group: глобальный реестр TOPO_NODE по node_id, ref_count=0 при создании
- BGP-обмен активируется для всех групп (а не только дефолтной)
- Протокол: group_id добавлен в WITHDRAW/TABLE_REQ/TABLE_COMPLETE/ERR_GROUP_MISMATCH
- Per-connection коллбэки заменены на instance-level conn_status
- msg_transport полностью удалён из проекта
57/57 тестов
2026-07-22 15:51:03 +03:00
Evgeny 5265783164 fix: self node online=0 after chat_core_init refactor — add topo_node_sqlite_node_set_online(self, 1) 2026-07-22 13:54:36 +03:00
Evgeny e2d9879636 refactor: remove direct nodes table writes from chat_core/conn_mgr, use topo_node_sqlite API
- chat_core_init: replace INSERT INTO nodes with topo_node_sqlite_node_update_verified, remove redundant topo_node_sqlite_init call
- chat_core_update_my_name: replace UPDATE nodes with topo_node_sqlite_node_update_verified
- chat_conn_mgr_connect_from_invite: simplify invite node insert (x25519 only, no ed25519)
- topo_node_sqlite: add detailed column comments to peers table DDL (both server and chatgui)
- chat_core: add detailed column comments to peers table CREATE TABLE
2026-07-22 13:38:17 +03:00
Evgeny 7aa4a34f35 fix chatgui: members showing offline after JOIN — always refresh channel cache before posting online count 2026-07-22 12:19:59 +03:00
Evgeny a7346c25e3 fix chatgui: members not showing (schema mismatch) and username showing JSON instead of name
- topo_node_sqlite_member_put: remove joined_at column from INSERT (not in server schema, duplicates join_ts)
- chat_core: rename peers table column name→userinfo to match server schema + add ALTER TABLE migration
- chat_sync: remove 3 redundant INSERT INTO nodes that wrote raw JSON userinfo into nodes.name, overwriting correct plain name from topo_node_sqlite_node_update_verified
2026-07-22 12:03:57 +03:00
Evgeny df809f251c ntp: use NTP-corrected time everywhere instead of unixepoch()/gettimeofday
- db_sync_next_timestamp(): ntp_time_get_us() via si->db_sync->inst
- topo_node_sqlite_node_put: +time_t now_sec param, replace unixepoch()
- topo_node_sqlite_node_update_verified: +time_t created_at param
- topo_node_sqlite_member_put: joined_at = join_ts (already NTP-corrected)
- All INSERTs (nodes, local_identity, accounts, peers):
  replace DEFAULT(unixepoch()) with explicit ntp_time_get_seconds()
- ON CONFLICT DO UPDATE: created_at = COALESCE(nodes.created_at, excluded.created_at)
- Updated callers: topo_group.c, chat_sync.c, chat_conn_mgr.c, chat_core.c
2026-07-22 11:39:10 +03:00
Evgeny fab1c77cfb chatgui: remove unused addServer/addClient/removeServer/removeClient 2026-07-22 10:22:37 +03:00
Evgeny 6574c58257 chatgui: unify config update logic, fix node_id derivation, fix test
- config_updater.{h,cpp}: single implementation — config_update_in_lines
  for batch updates + config_update_option for file-level. REPLACE/APPEND
  modes, section auto-creation
- node_config.cpp: generateIdentity() now derives node_id via
  SHA256(pubkey) (like sc_derive_node_id_from_pubkey) instead of random.
  save() uses config_update_in_lines for line-level update when file
  exists, saveFull() only for new file and addServer/addClient.
  Removed duplicate findSectionBounds/updateOptionInSection/configUpdateOption
- test_config_updater.cpp: Q_ASSERT replaced with VERIFY macro — Q_ASSERT
  in Release mode does not evaluate the expression, causing false positives.
  Test now works in both Debug and Release
2026-07-22 10:13:40 +03:00
Evgeny ab252a0984 chatgui: include platform_compat.h for htole64 on Windows 2026-07-22 09:23:35 +03:00
Evgeny b1cbd5acf9 topo_node_sqlite: dynamic idx_sql allocation instead of fixed 128-byte buffer 2026-07-22 09:18:54 +03:00
Evgeny 2785845acf platform_compat: use #include <process.h> instead of getpid macro 2026-07-22 09:13:36 +03:00
Evgeny b1bf27d023 fix Windows warnings: getpid, htole64, gettimeofday, socket_t mismatches, radix min 2026-07-22 09:08:19 +03:00
Evgeny b9a31b9fba proxy: fix Windows warnings - getsockopt cast, uasync_add_socket_t 2026-07-22 08:55:48 +03:00
Evgeny 17202beb0a test_ntp: use compat headers instead of arpa/inet.h, add rule to AGENTS.md 2026-07-22 08:47:56 +03:00
Evgeny 090acc1f00 etc/rtt: UPSERT node_update_verified; gui: account delegate (rtt+nat subline), context menu member props (admin/supernode), cleanOrphanedPeers, refreshRtt timer 2s 2026-07-22 01:15:33 +03:00
Evgeny c367144776 etcp: rtt_last→ping_update_rtt раз в минуту; route_ping: ping_update_rtt на PING_RESP 2026-07-21 22:29:19 +03:00
Evgeny ad42f66df5 feat: PING/PONG RTT exchange + burst sender + TCP server; fix INIT peer_id offset
- etcp_connections: add flags byte to PING/PONG wire format (WANT_RTT/SEND_RTT)
- etcp_connections: add etcp_link_burst_start/check for BDP measurement
- etcp_connections: add tcp_server_on_link for STCP→ETCP bridge
- topo_node: add ping_request_cbk/ping_update_rtt for live RTT tracking
- topo_node: add last_ping_time field in connectivity
- topo_node_sqlite: extend DB schema for RTT data
- fix: INIT path read peer_id from offset 1 (not 2), PING offset stays 2
2026-07-21 20:50:14 +03:00
Evgeny 542694a0e9 fix: restore original source content after refactoring (accidental code changes removed) 2026-07-21 20:35:02 +03:00
Evgeny fcf3fb7f51 refactor: move transport (etcp/stcp/normalizer) to transport_layer/, routing (bgp/pings/topo*) to routing_layer/ 2026-07-21 20:25:41 +03:00
Evgeny 3dda701c67 schema: rm is_dm, rename name→userinfo (json_flat), fix join_msg format
- Remove is_dm column from channels table (dm detection by member count)
- Rename member name column to userinfo — extensible json_flat format
- Add json_flat.c/h library for compact JSON serialization
- Fix join_sig message format: use ch_x25519+ch_ed25519 instead of channel_id string
- Remove name from join_msg body (now in userinfo via json_flat)
- Update chat_core, chat_sync, member_sync, db_manager to new format
- Add topo_strategy.txt — архитектурные заметки по топологии
2026-07-21 00:11:50 +03:00
Evgeny 88d51349ea statuspage: компактный блок часов, offset в секундах
- Шрифт часов 20 (был 22), bold оставлен
- Убраны зазоры: padding 10px→1px, margins 12,8→4,0, spacing 8→2
- Offset в NTP-статусе: микросекунды → секунды (114.8 s)
- Убран зазор (пустая строка) между NTP и Connections
2026-07-20 01:31:49 +03:00
Evgeny 333acb2fe5 ntp_node_time: учёт пол-RTT в корректировке времени
offset = t4 - t_sender_us - avg_rtt/2
RTT усредняется по всем линкам соединения (rtt_last в 0.1ms).
2026-07-20 01:19:33 +03:00
Evgeny f83efda54e ntp_node_time: исправлен знак offset — корректировка шла в обратную сторону
ntp_time_get_us() вычитает offset (local_us - offset_us), поэтому
offset_us должен быть local_raw - peer_time, а не наоборот.
Было peer_time - local_raw → corrected = 2*local - peer (ошибка).
Стало local_raw - peer_time → corrected = peer_time (верно).
2026-07-20 01:07:09 +03:00
Evgeny fdaaa41010 ntp_node_time: фикс ложных докладов о дрейфе часов
check_drift() вызывался с сырой разницей часов между узлами, а не
с изменением offset со временем. При разнице часов между машинами
в 229 секунд это давало спам WARN на каждый TIME_SYNC обмен.

Теперь: первый обмен сохраняет offset без проверки; последующие
сравнивают дельту и warn только при реальном дрейфе (изменении offset).
2026-07-20 00:53:53 +03:00
Evgeny 15ca0675c0 Безопасность: pubkey check при reusing линка + node_changed при конфликте адреса чужого конна 2026-07-20 00:47:38 +03:00
Evgeny ccd35074d8 Заменил find_link_index на ll_queue с хеш-индексом: универсальный ключ port(2)+addr(16)+family(1)=19 байт, IPv4 дополнен нулями 2026-07-20 00:21:12 +03:00
Evgeny 7a5df3e196 etcp: add node_changed callback chain + chatgui subscription
- etcp.h: add node_changed_cbks field to ETCP_CONN
- etcp_api.h/c: add etcp_conn_node_changed() + add/remove_node_changed_cbk
- etcp_connections.c: fire node_changed callbacks on pubkey mismatch
  (with DEBUG_WARN(GENERAL) logging source addr, peer_id, old/new pubkey)
- etcp.c: cleanup node_changed_cbks on connection close
- chat_conn_mgr.c: subscribe to node_changed — clear DB addresses,
  reset in-memory cache, close connections (deferred for current conn),
  post GUI_EVT_NODE_CHANGED
- gui_bridge.h: GUI_EVT_NODE_CHANGED=11
- gui_bridge_impl.cpp: handle GUI_EVT_NODE_CHANGED
2026-07-19 22:09:23 +03:00