Commit Graph
1365 Commits
Author SHA1 Message Date
Evgeny abee0ef3a9 chatgui: add --asan flag to build_linux.sh 2026-07-16 19:33:52 +03:00
Evgeny f3ac1cbb06 chat_sync: fix double-free in auto_connect — clear ca_state in ac_result_cb on success 2026-07-16 19:24:13 +03:00
Evgeny 3d04c37f56 stcp: add on_close callback to stcp_server_create/stcp_client_connect; member_sync: add join_ts/update_sig/update_ts fields, verify update_sig in apply; topo_node_sqlite: add join_ts/update_sig/update_ts to member_put, add member_get_join, add node_update_verified; chat_sync: include join_ts in join_msg, add update_sig/update_ts to CHANNEL_INFO_RESP; WELCOME verify join_sig; tests: use generated node_ids, reduce max ticks 2026-07-16 19:04:00 +03:00
Evgeny 0137a1bad4 chatgui: preserve input focus on chat refresh (save/restore focusWidget in loadChannel) 2026-07-16 13:03:23 +03:00
Evgeny 51d47ea6a8 chatgui: restore input focus after sending message 2026-07-16 12:54:34 +03:00
Evgeny c4d1f984bd chatgui settings: add Database tab with integrity check (quick/full) and optimize 2026-07-16 12:46:40 +03:00
Evgeny 0479c309bb Диагностика синхронизации: merkle_sync DEBUG_DEBUG логи обмена; убран спам auto_connect no IPv4; сохранение адреса инвайтера из ETCP; детали DECRYPT FAIL (link_state/enc_errs) 2026-07-16 00:41:51 +03:00
Evgeny 0d5a72c40e chat_sync: node_name теперь в пакетах — CHANNEL_INFO_RESP/JOIN/PEER_UPSERT передают имя, верификация использует имя из пакета (не из БД) 2026-07-16 00:32:09 +03:00
Evgeny ef24af7d24 Ключи: node_id из SHA-256(privkey) через весь конфиг; приоритет privkey — pubkey/node_id всегда выводятся из него; CHANNEL_INFO_RESP: верификация inviter_join_sig через ETCP-ключи 2026-07-15 23:13:29 +03:00
Evgeny da86841516 Диагностика: WARN при мутации конфига (ключи/node_id) + детали при invalid sig в JOIN/CHANNEL_INFO_RESP + предупреждение при расхождении node_id инвайта и ETCP 2026-07-15 22:44:33 +03:00
Evgeny 895eb0abbf Убрал спам-логи ETCP SEND/RECV/DECRYPT OK + добавил диагностику синхронизации мемберов (DEBUG_CATEGORY_DEBUG) в ключевые точки topo_group, merkle_sync, member_sync, chat_sync 2026-07-15 22:25:19 +03:00
Evgeny d161782b46 fix: merkle_sync.c linked-list -> queue lookup, upgrade debug logs to INFO
- merkle_sync.c ms_find_conn_for_node: replace c=c->next with queue_find_data_by_index
- chat_sync.c cs_find_conn_for_node, cs_on_conn_up: DEBUG_DEBUG -> DEBUG_INFO
- etcp.c queue_set_ready: DEBUG_DEBUG -> DEBUG_INFO
2026-07-15 21:59:29 +03:00
Evgeny d71753fa79 debug: add diagnostic logs for chat invite connect flow
- cs_find_conn_for_node: show queue state, entry found/missing, conn flags
- cs_on_conn_up: log when skipping due to !initialized
- etcp_conn_queue_set_ready: log reindex details (old/new entry, count)
- etcp_conn_set_peer_node_id: show state+reindexed flag
2026-07-15 21:42:16 +03:00
Evgeny a7ecee01f5 etcp: replace connections linked-list with indexed ll_queue, add state/ref_count lifecycle
- Remove ETCP_CONN.next linked-list, UTUN_INSTANCE.connections list/count
- Unified connections in single ll_queue indexed by peer_node_id (0=pending)
- struct conn_queue_entry { peer_node_id, conn* } for uniform queue data
- Connection lifecycle via etcp.c: create→pending, conn_ready→indexed, close→detach+deferred free
- Close split: phase1 detach from external world, phase2 deferred via uasync_call_soon
- etcp_conn_set_peer_node_id: reindex on ID change (WARN)
- etcp_conn_ref_take/free: blocking close until refcount returns to 0
- Remove chat_connections — use unified connections queue directly
- Update all iteration/search patterns across 40 files (src + tests + chatgui)
2026-07-15 19:56:47 +03:00
Evgeny 6902f5fd95 chat: add ll_queue with index for P2P connections (replaces linear search)
- utun_instance.h: add chat_connections queue (indexed by node_id, 8 bytes)
- chat_sync.c: queue_new in init, queue_free in destroy, queue_find_data_by_index in cs_find_conn_for_node
- chat_sync.c: remove from queue in cs_on_conn_down
- chat_core.c: add to queue in connect_from_invite and connect_auto
- chat_core.c: remove from queue in cc_parallel_cleanup and ca_cleanup
- db_sync.c: replace linear conn search with queue_find_data_by_index (db_sync_send_hash)
2026-07-15 18:15:16 +03:00
Evgeny 3368abad2a etcp+chat: add DEBUG_INFO logs for invite/crypto handshake debugging
- etcp_connections: DECRYPT FAIL now logs my_pub/peer_pub/session_ready at INFO level (debug category)
- chat_sync: log invite start with pubkey/node_id/addr_count
- chat_core: log pubkey set on invite connect (my_pub + peer_pub)
- joindialog: GUI_INFO on decoded invite
2026-07-15 17:53:25 +03:00
Evgeny d83d281fa0 config: add [allowed_keys] allow_all=yes by default, add [gui] as valid section
- node_config.cpp: add [allowed_keys] allow_all=yes to default config
- config_parser.c: add SECTION_GUI to suppress 'Key outside section' warnings
2026-07-15 17:34:48 +03:00
Evgeny 4c8e5f6223 db_sync+chat_sync+etcp: fix conn init race, reduce keepalive log spam
- etcp_connections: keepalive SEND/RECV/DECRYPT_OK: DEBUG→TRACE; DECRYPT_FAIL: WARN→DEBUG
- db_sync_on_conn_up: skip sync if !conn->initialized, wait for next UP event
- db_sync peer_check_timer+instance_add: also check conn->initialized
- chat_sync cs_on_conn_up: ignore conn_up before initialized (cs_send fails otherwise)
- db_sync_on_conn_up log now includes init= and links=
2026-07-15 17:25:14 +03:00
Evgeny 5b749d6cc8 chatgui: db_path is now a directory (chat_data/) with chats.db and sync/ inside
- Default db_path changed from 'chats.db' to 'chat_data' directory
- chat_core_init receives <db_path>/chats.db
- db_sync receives <db_path> (creates <db_path>/sync internally)
- Directory auto-created on startup via QDir::mkpath
2026-07-15 17:09:11 +03:00
Evgeny 6252556a02 chatgui: migrate message sync from chat_sync to db_sync
- Replace db_sync_stub.c with real src/db_sync.c in libutun
- Remove message sync protocol from chat_sync (INIT_SYNC/INIT_RESP/SEND_DATA/PUSH/ACK_PUSH/SYNC_DONE)
- Keep chat_sync auxiliary: join protocol, peer management, auto-connect
- Remove chat_core_insert_record, cursor_*, mark_sent/ttl_delete stubs
- chat_core on_db_sync_insert now only does SQLite INSERT + GUI notify
- Move db_sync_init() from instance_init_common to utun_instance_init for config override timing
- Force db_sync_enabled=1 in utun_node.cpp
- db_sync handles all P2P message sync via service 0x20
2026-07-15 17:02:47 +03:00
Evgeny acaa3a767c refactor: move chat_sync and member_sync to direct ETCP P2P, bypass etcp_router
Replace etcp_router_bind/etcp_route_send/etcp_router_unbind with
direct etcp_bind/etcp_send/etcp_unbind + find-conn-by-node_id helpers.
Same approach as db_sync (0x20). Service IDs unchanged (0x30, 0x31).
2026-07-15 16:13:45 +03:00
Evgeny 9378b18ce7 fix: defer connection_close in ready_cb using uasync_call_soon
ca_ready_cb and cc_parallel_ready_cb called etcp_connection_close
synchronously on non-selected connections from within the ready_cbk
callback chain. This corrupts senders_list in topo_group, causing
UAF in topo_group_start_link_nat_check.

Now uses uasync_call_soon (zero-delay timer) to defer the close
to the next event loop iteration, after the callback chain completes
and callbacks_running flag is reset.
2026-07-15 15:00:05 +03:00
Evgeny 371208d489 chatgui: выпилить все записи в БД из GUI потока (DbManager)
- DbManager теперь read-only, получает sqlite3* handle через setDb()
- chat_core — единственный владелец БД (SQLITE_OPEN_FULLMUTEX + WAL)
- initTables/seedStubData/createChannel/insertMessage/setUiState удалены из DbManager
- seed 5 stub-аккаунтов перенесён в chat_core_init()
- GUI_EVT_DB_READY — уведомление о готовности БД
- setUiState заменён на QSettings
- каналы загружаются по DB_READY коллбэку
- убран двойной sqlite3_open (один файл, один хендл)
2026-07-15 14:26:32 +03:00
Evgeny f7d88e5532 fix segfault in ca_ready_cb: ca_state owns all ca_ctx, single cleanup point
- Added struct ca_ctx** ctxs to ca_state (parallel array)
- ca_cleanup now frees all ctxs[i] and the ctxs array
- ca_ready_cb: removed u_free(ctx), added etcp_conn_remove_ready_cbk before cleanup
- ca_timeout_cb: removed u_free(ctx) — ctx lives until ca_cleanup
- All error paths set ctxs[i]=NULL for ca_cleanup safety
2026-07-15 11:21:31 +03:00
Evgeny 1e7585438d chat_core_connect_auto: add outbound conn to inst->connections
etcp_connection_create does NOT add conn to inst->connections list.
Without this, incoming INIT handler can't find the outbound conn
by peer_node_id and creates a new one, causing insert_link collision.
2026-07-15 11:05:27 +03:00
Evgeny a8164baf41 chat_core_connect_auto: set peer_node_id on ETCP_CONN
Without peer_node_id, incoming INIT handler can't find the existing
outbound connection, creates a new one, and fails on insert_link collision.
2026-07-15 10:51:53 +03:00
Evgeny 0adf7d07ef chat_core_connect_auto: dedup addresses by (addr,port) 2026-07-15 10:32:06 +03:00
Evgeny 33aa6bbd5a auto-connect: cursor-based, no close on timeout, GC every 1s, cancel API
- ca_timeout_cb: removed etcp_connection_close, ETCP lives past 3s timeout
- ca_state.cancelled flag + chat_core_connect_auto_cancel() for external cancel
- chat_core_connect_auto returns ca_state* via out_state
- Rewritten auto_connect: cursor (ch,peer) instead of bulk collect
- GC every 1s: closes flights with no link_status after 3s
- ac_result_cb no longer clears ca_state (GC handles cleanup)
- stop: cancels all flights via chat_core_connect_auto_cancel
2026-07-15 10:24:44 +03:00
Evgeny dccf54b30b auto-connect + GUI per-channel indicators
- chat_core_connect_auto: direct ETCP connect from SQLite (no BGP)
- auto_connect: parallel connect to peers with 3s timeout, retry 10s
- RTT saved to node_addresses on disconnect
- vertical status bar + circle badge with online count per channel
- ChannelListView prevents deselection
2026-07-15 06:00:43 +03:00
Evgeny 1a0229fd4f add NTP time synchronization module 2026-07-14 20:14:00 +03:00
Evgeny f3719a28df fix: change timestamp unit from microseconds to milliseconds
- db_sync.c: last_timestamp_us → last_timestamp_ms, use tv_sec*1000 + tv_usec/1000
- db_sync_stub.c: same change
- QDateTime::fromMSecsSinceEpoch() in chatgui expects milliseconds
- 1 µs → 1 ms change fixes 'minutes ticking like seconds' display bug
2026-07-14 19:33:16 +03:00
Evgeny 5fc621690a fix: wall-clock timestamps + merkle_sync timeout + build script
- Replace get_time_us() with utun_gettimeofday() for PUSH message timestamps
  (db_sync.c, chat_core.c) — monotonic clocks differ across Linux/Windows
- Fix merkle_sync: restart session timer in _handle_request to prevent
  double-sided timeout when both nodes start member_sync simultaneously
- Fix INIT_RESP short-format: don't mark synced when my_count > peer_count
- Add db_sync_get_last_timestamp() to avoid duplicate timestamp generation
  between db_sync and chat_core on_db_sync_insert
- Fix db_sync_stub to generate timestamps consistently
- build.sh: auto-rebuild chatgui via CMake after utun build
2026-07-14 19:23:02 +03:00
Evgeny 4636a69225 fix chatgui: pass chain_hash in PUSH + start member_sync on server join
chat_sync_push: add chain_hash parameter, use it instead of zeros
  (fixes chain_hash mismatch → all PUSH messages were rejected)

on_db_sync_insert: pass computed chain_h to chat_sync_push

cs_handle_channel_join: call member_sync_start for the joiner
  (server now initiates member sync when client joins.
  Previously merkle_sync was only started by client → timeout
  because server never responded)

cs_handle_welcome: add DEBUG_INFO before member_sync_start on client side
2026-07-14 18:43:04 +03:00
Evgeny f9f516c2e9 fix chatgui: PUSH new messages to peers + comprehensive debug logging
chat_sync_push: fix PUSH format to match cs_handle_push expectations
  (was missing insert_record header: ts+dh+nid before ct+dlen+data)
  Add DEBUG_INFO log with peer count after send.

on_db_sync_insert: call chat_sync_push after successful local insert
  → new messages are now pushed to all connected peers
  Add DEBUG_ERROR to 4 silent returns (JSON parse fail, SQL errors)

chat_core_submit_message: add DEBUG_INFO entry log (ch, ct, len)

chat_core_insert_record: add DEBUG_WARN/ERROR to 7 silent returns
  (truncated record, SQL prepare fail, unknown step error)

cs_handle_push: add DEBUG_INFO for ACK send, DEBUG_ERROR for insert fail

cs_handle_send_data: DEBUG_WARN when record truncated mid-loop

cs_on_conn_up: DEBUG_INFO sync path with channel count

Full trace now shows every message: SUBMIT → insert → PUSH → RECV PUSH → ACK
2026-07-14 18:34:24 +03:00
Evgeny 58b9f28149 fix chatgui: prevent invite deadlock on connection flap
cs_on_conn_down: remove invite state zeroing on disconnection.
Only timeout callbacks and explicit protocol end (CS_MSG_ERROR,
transition to JOIN phase) clear the invite state.

Connection flap now causes automatic retry:
  conn_up → pending_invite_ch_id != 0 && !info_req_timer → resend
  CHANNEL_INFO_REQ. No deadlock possible.
2026-07-14 18:22:05 +03:00
Evgeny 8c41b44718 fix chatgui: repair INIT_RESP handler, add debug logging to all sync handlers
- cs_handle_init_resp: change silent reject len<37→len<5 (actual payload
  sent is 6 bytes, plen=5 after stripping type byte).
  Support short format (synced, peer_count+sparse_count) and long format
  (divergence, with test_pos+peer_ch). Add INFO logs at each decision.
  (fixes sync never starting after invite join — RECV INIT_RESP len=5
  was silently rejected)

- All 12 silent return branches in handlers: add DEBUG_WARN with
  handler name, peer, ch_id, and reason (makes malformed packets
  visible in logs)

- Key sync flow INFO logs:
  cs_handle_init_sync: peer_count, my_count
  cs_handle_send_data: records sent/received count
  cs_on_conn_up: invite vs sync path
  chat_core_insert_record: successful insert
2026-07-14 18:07:57 +03:00
Evgeny 2d179ec41d fix chatgui: message format, member notify, chain_hash sync
- on_db_sync_insert: parse JSON {"n":...,"ct":...,"d":...}, store
  d→data, n→node_id, ct→content_type with proper chain_hash
  (fixes JSON displayed instead of message text)
- chat_core_cursor_open: SELECT chain_hash column
- chat_core_cursor_next: include chain_hash(32) in output record
- cs_handle_send_data: parse chain_hash in received records
  (fixes chain_hash mismatch → all sync records were dropped)
- cs_handle_channel_join: post GUI_EVT_MEMBERS_CHANGED
  (fixes creator not seeing new member after join)
- cs_handle_welcome: trigger INIT_SYNC with inviter after join
  (fixes no message sync after invite join)
2026-07-14 17:46:33 +03:00
Evgeny c4751557b1 fix chatgui: ensure msg table + db_sync instance on join and restart
- chat_core_ensure_channel_ready(ch_id): idempotent — creates
  msg_<id> table + registers db_sync instance if missing
- chat_core_create_channel: refactored to use ensure_channel_ready
- cs_handle_channel_info_resp: call ensure_channel_ready on join
- chat_core_init: iterate existing channels on restart
- Fixes 'no such table: msg_<id>' after invite join
- Fixes 'no db_sync instance for ch=<id>' after restart
2026-07-14 17:22:01 +03:00
Evgeny 4254ab97bb fix chatgui: db_sync_stub + chat_sync_init for invite link join
- db_sync_stub.c: complete rewrite — proper structs, all API functions
  (db_sync_instance_add, insert_signed, set_insert_cb, select)
  Fixes db_sync_instance_add returning NULL (inst->db_sync was NULL)
- libutun/CMakeLists.txt: remove src/db_sync.c, stub replaces it
- chatgui/CMakeLists.txt: add transport/db_sync_stub.c
- utun_node.cpp: remove redundant db_sync_init/destroy,
  add chat_sync_init/destroy — server now registers svc_id=48
  Fixes 'no handler for svc_id=48' on incoming CHANNEL_INFO_REQ
2026-07-14 17:03:00 +03:00
Evgeny ccd25813f6 refactor: extract merkle_sync — universal Merkle-tree sync module
- merkle_sync.h/c: tree (5-level prefix, SHA256 buckets), wire protocol
  (HASHES/REQUEST/BATCH), sessions (10s timeout, 3 retries), async API
  with done_cb
- member_sync: thin glue layer, implements 3 data model callbacks
  (update_bucket_hash, get_items, apply_items) for chat members
- chat_sync: updated member_sync_start() calls with done_cb callback
- member_tree_hash table renamed to merkle_tree_hash
- member_sync.h public API preserved, internal tree/wire logic removed
2026-07-14 16:35:58 +03:00
Evgeny f617dcd68e db_sync: LMDB→SQLite, multi-instance, etcp_api, chatgui integration
- src/db_sync: LMDB replaced with SQLite (separate tables per instance: db_sync_name_id)
  TTL index (author, timestamp), WAL mode, per-instance peers/timers
  opaque DB_SYNC_INSTANCE* handle, insert callback, select API
  new fields: author_signature, delivered_peers, delivery_chain
  transport: etcp_api direct P2P (was etcp_router)

- src/db_sync.h: user-oriented API docs, multi-instance lifecycle

- lib/Makefile.am: liblmdb sources removed
- lib/sqlite3.c+h: SQLite amalgamation added

- topo_node: LMDB→SQLite (src/topo_node_sqlite.c moved from chatgui)

- chatgui: real db_sync.c replaces db_sync_stub.c
  chat_core: db_sync_insert_signed + dual-write insert callback
  utun_node: db_sync_init/destroy replaces chat_sync_init/destroy
  CMakeLists: stubs removed, real db_sync.c added
2026-07-14 14:17:43 +03:00
Evgeny 37417ba49d Fix: my_node_name insert inside [global] section, add button tooltips in channellist 2026-07-14 09:17:01 +03:00
Evgeny cca3511503 fix: replace deprecated SHA256 API with EVP, conditional dl linkage for Windows 2026-07-14 09:07:03 +03:00
Evgeny d70cdbb040 chatgui: preserve active channel selection on reload, members sync, profile settings, member list model 2026-07-14 08:52:10 +03:00
Evgeny c3f946fb63 chat_sync: fix join group stall — remove node_id match in cs_on_conn_up, add CS_MSG_ERROR protocol response 2026-07-13 18:11:18 +03:00
Evgeny 0c2eeb8820 chatgui: validate config options on startup, refuse to start on errors 2026-07-13 15:46:20 +03:00
Evgeny 637b21da9e debug: remove console_level/file_level — simplified output routing
Remove secondary level filtering in debug_output(). Now the only filter
is debug_should_output() (per-category + global fallback). Output goes
to file (if file_output set) or console (if console_enabled), with no
additional level check.

Removed:
- debug_set_console_level(), debug_set_file_level()
- console_level, file_level fields from debug_config_t
- debug_set_level() no longer sets console_level
2026-07-13 15:38:08 +03:00
Evgeny 6bf267924d add DEBUG_CATEGORY_CONNECTIVITY for handshake/protocol lifecycle logs
New category (id=25) replaces DEBUG_CATEGORY_DEBUG in chat_sync and
chat_core. This allows enabling only protocol-level logs (SEND/RECV,
timeouts, handshake) without the noise from DEBUG category.

Changes:
- debug_config.h: add CONNECTIVITY=25, COUNT→26
- debug_config.c: add 'connectivity' to g_debug_categories
- chat_sync.c: DEBUG→CONNECTIVITY in all protocol logs
- chat_core.c: DEBUG→CONNECTIVITY in connection/create logs
- utun_node.cpp: remove hardcoded DEBUG=TRACE (now config-driven)
- chatgui.cfg: connectivity=info in debug_categories
2026-07-13 15:14:48 +03:00
Evgeny 5318476cdf chat_sync: add protocol request timeouts and SEND/RECV debug logs
- Add info_req_timer (5s) for CHANNEL_INFO_REQ — reports CONN_MGR_ERR_TIMEOUT
  to GUI on timeout, clears pending invite state
- Add join_timer (8s) for CHANNEL_JOIN → WELCOME — reports timeout on failure
- cs_on_conn_down: cancel all proto timers, reset pending invite state
- cs_send: log every outgoing message (SEND <type> to=<peer> ch=<id> len=<n>)
- Dispatcher: log every incoming message (RECV <type> from=<peer> ch=<id> len=<n>)
- Add cs_msg_name() helper for readable message type names
- pending_invite_node_id/ch_id no longer cleared immediately after send —
  kept until response or timeout, enabling proper error reporting
2026-07-13 15:06:06 +03:00
Evgeny 43d95016ae fix: send INIT_RESPONSE with reset when server creates new connection after restart
When server restarts, new ETCP_CONN has session_id=0 (calloc).
If client sends INIT_REQUEST_NOINIT (0x04) with session_id=0,
the condition conn->session_id != session_id is false (both 0),
so no reset was sent. Client kept old seq numbers while server
expected seq=1, causing 'Waiting for initial packet' deadlock.

Fix: add || new_conn to the condition — when server created a
fresh connection (was restarted), always send reset to client.
2026-07-13 14:19:27 +03:00