Commit Graph
1387 Commits
Author SHA1 Message Date
Evgeny 7a9e3bea5f db_sync: mc>pc guard with last_peer_count — detect stalled sync when pc doesn't change 2026-07-25 16:56:30 +03:00
Evgeny 3490789249 db_sync: skip SYNC_DONE in count>0 handler when received==0 — breaks bad_sig recv→send loop on client side 2026-07-25 16:49:46 +03:00
Evgeny c9436219a0 db_sync: fix synced_pos overwrite in SYNC_DONE — use max to preserve total_processed advance 2026-07-25 16:28:09 +03:00
Evgeny 34404403ef db_sync: verify sig before send + fix total_processed double-count 2026-07-25 16:10:20 +03:00
Evgeny e9fce43be5 db_sync: fix bad_sig infinite loop — delete+rechain, advance synced_pos past dup/bad_sig, accept on covered tail 2026-07-25 15:58:18 +03:00
Evgeny 27906e9f91 db_sync: односторонний sync, sparse-таблица, vp в SEND_DATA, PUSH-релей 2026-07-25 15:00:21 +03:00
Evgeny e071a9e2f8 db_sync: fix test sync protocol isolation (add auto_sync flag, destroy order, test refactor)
- utun_instance: fix destroy order (topo_groups before conn_mgr to avoid UAF in topo_recovery)
- topo_recovery: add NULL guard for instance/ua in try_next
- db_sync_instance_add: add auto_sync flag (1=send INIT_SYNC, 0=quiet)
  replaces separate _quiet variant, cleaner API
- db_sync_peer_set_state, db_sync_reinitiate: test-only peer control utilities
- test_db_sync: full rewrite — stable, isolated sync protocol testing
  all 3 branches (peer_empty, hash_MATCH, divergence) tested without PUSH contamination
  Phase 6 extended: triple merge + tail PUSH + mid PUSH cascade on star topology
  runs in 1.4s, consistently passes 10/10
- db_sync_doc: updated protocol architecture description
- chatgui: update db_sync_instance_add call with auto_sync=1
2026-07-24 21:27:23 +03:00
Evgeny ad56767646 db_sync: notify all peers when cascade_from changes chain (lock-free sync)
После cascade_from в db_handle_send_data оповещаем ВСЕХ пиров
с synced_pos >= fix_from о том что цепочка изменилась — откатываем
их synced_pos. Это устраняет неэффективность конкурентных sync:
раньше только пир-отправитель обновлялся, остальные видели устаревшие
хеши и обнаруживали ложное расхождение на следующем цикле.
2026-07-24 17:26:09 +03:00
Evgeny c46cb9a979 db_sync: fix si_send_data_batch column bug (author→node_id), add cascade_from to PUSH, add divergence+cascade test phases
- si_send_data_batch: неправильный SQL SELECT с несуществующей колонкой author
  вместо node_id → ломал всю передачу данных в REFINE/SEND_DATA
- Добавлена проверка si_prep и возврат int с кодом ошибки
- Все вызовы si_send_data_batch проверяют возврат, при ошибке сброс sync_state
- db_handle_push: добавлен db_cascade_from после вставки (раньше chain_hash
  не пересчитывался после PUSH)
- db_handle_refine: DEBUG_WARN при scnt==0 (fm за пределами диапазона)
- Добавлена публичная db_sync_chain_verify() для верификации цепочек
- test_db_sync: фаза 4 (divergence через разныe hashes + REFINE/SEND_DATA),
  фаза 5 (PUSH без хвоста + cascade verification)
- Убран мёртвый код db_sync_on_new_conn
- chatgui: адаптивная раскраска пузырей исходящих сообщений
2026-07-24 16:55:08 +03:00
Evgeny a7ec45c4af db_sync: replace all sync logs with unified narrative format sync [TBL:NODE]
- Unified format: 'sync [SHORT_TBL:PEER_HI] <-/->  action: key_data'
- Each log line explains what the algorithm is doing and why
- Added batch progress tracking in dump-all and tail SEND_DATA loops
- Track dropped records (duplicates, bad_sigs, parse_fails) in SEND_DATA recv
- Show synced_pos transitions (old->new) in SEND_DATA and SYNC_DONE
- Show all launched syncs in PEER CHECK log
- Convert all silent returns to ERROR logs with [TBL:NODE] context
- Convert old WARN/ERROR formats to new sync [TBL:NODE] format
- Add sync_state reset details on ERROR and timeout paths
2026-07-24 13:23:17 +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 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 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 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 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 b1cbd5acf9 topo_node_sqlite: dynamic idx_sql allocation instead of fixed 128-byte buffer 2026-07-22 09:18:54 +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 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 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
Evgeny f6f7e12192 refactor: demote high-frequency debug logs (raw_recv/dispatch→TRACE, normalizer→DEBUG), NTP drift→WARN 2026-07-19 13:53:27 +03:00
Evgeny 42041dfe84 feat: log connection status changes at general=info level (NEW/UP/DOWN/DELETE) 2026-07-19 13:41:25 +03:00
Evgeny beed7a4e07 fix: INIT reset logic — reset only on session change or got_initial_pkt, always sync session_id 2026-07-19 13:18:42 +03:00
Evgeny 58df4d8571 ntp_node_time: переход с etcp_router на raw ETCP (P2P)
- Добавлен ETCP_ID_NTP_TIME=0x04 (raw ETCP packet ID)
- Удалён ETCP_RT_ID_NTP_TIME=0x12 (router-сервис)
- ntp_node_time.c: etcp_router_bind/send → etcp_bind/etcp_send
- send_time_sync() принимает ETCP_CONN* вместо dst_node_id
- recv_cb разбирает raw dgram вместо SVC_ROUTE_HDR
- Обновлены doc-файлы
2026-07-19 12:16:37 +03:00
Evgeny 2e7c32c893 fix(db): use INSERT ... ON CONFLICT instead of INSERT OR REPLACE for nodes table
INSERT OR REPLACE deletes the old row and inserts a new one,
resetting unspecified columns (online, update_ts) to DEFAULT 0.
This was wiping online=1 set by cs_on_peer_status_changed/member_sync_set_online.

Replaced 5 INSERT OR REPLACE INTO nodes with INSERT INTO ... ON CONFLICT
DO UPDATE SET — only updates the specified columns, preserving online status.

Files:
- chat_core.c:638 (invite flow)
- chat_sync.c:1045 (CHANNEL_INFO_RESP), 1193 (JOIN), 1449 (PEER_UPSERT)
- topo_node_sqlite.c:121 (BGP node_put)
2026-07-19 11:16:26 +03:00