# Behavior traces — rustdesk/rustdesk

> Canonical page: https://codevetter.com/unpack/rustdesk/behavior-traces

# Behavior traces — rustdesk/rustdesk

Scanned commit c6a358afbe37c518689a6157a8e8cdbd645dcc5d (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Three flows verified end-to-end: (1) cold start → host registration, (2) outgoing remote-desktop session, (3) incoming controlled connection. A fourth — config sync between the privileged service and user process — is the persistence backbone. Function names below are the real call chain.
- STARTUP (desktop, no args): main() → core_main() → common::global_init() → load_custom_client() → windows bootstrap → arg scan → hbb_common::init_log → std::thread::spawn(crate::start_server) → returns Some(flutter_args) → ui::start (sciter) or Flutter engine main(). — [src/main.rs#L24-33](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/main.rs#L24-L33) [src/core_main.rs#L32-205](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/core_main.rs#L32-L205) [flutter/lib/main.dart#L38-118](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/flutter/lib/main.dart#L38-L118)
- STARTUP (host): start_server(is_server=true) → ipc::start("") listener thread → drm_capturer::warm_availability (linux+drm) → input_service::fix_key_down_timeout_loop / setup_uinput → wait_initial_config_sync → RendezvousMediator::start_all(). — [src/server.rs#L631-724](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L631-L724)
- STARTUP (registration): RendezvousMediator::start_all → test_nat_type → hbbs_http::sync::start → check_zombie → new_server() → spawn direct_server listener → lan::start_listening thread → loop{ per rendezvous host spawn Self::start → start_udp → register_peer on timer → handle_resp }. SHOULD_EXIT restarts all. — [src/rendezvous_mediator.rs#L274-352](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/rendezvous_mediator.rs#L274-L352) [src/rendezvous_mediator.rs#L367-485](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/rendezvous_mediator.rs#L367-L485)
- OUTGOING CONNECT (UI): Flutter connect → bind.sessionAdd/sessionStart (flutter_ffi) → flutter::session_add creates Session<FlutterHandler> + LoginConfigHandler.initialize → session_start_ → Remote::new + io_loop on a thread. — [src/flutter_ffi.rs#L138-140](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter_ffi.rs#L138-L140) [src/flutter.rs#L1265-1371](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter.rs#L1265-L1371) [src/client/io_loop.rs#L118-151](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/client/io_loop.rs#L118-L151)
- OUTGOING CONNECT (network): Remote::io_loop → Client::start → _start → (ip/domain direct shortcut | rendezvous resolution) → UDP punch socket + test_udp_uat + ipv6 socket + WebRTCStream offerer → _start_inner + TCP-punch fallback raced → secure_connection (signed id + DTLS fingerprint bind + symmetric key) → LoginRequest sent → io_loop remote_loop on frames. — [src/client/io_loop.rs#L185-220](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/client/io_loop.rs#L185-L220) [src/client.rs#L409-580](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/client.rs#L409-L580) [src/client.rs#L1645-1758](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/client.rs#L1645-L1758)
- INCOMING CONNECT: hbbs PunchHole → accept_connection → new_listener on the punched socket → create_tcp_connection → admit_unauthorized (64 global / 16 per-IP, oldest evicted) → stream.set_max_packet_length(128KiB) → identity_handshake → Connection::start → on_open → permission send_permission notices → select! loop → on_message → LoginRequest → check_login_scope + password/2FA or CM authorize → authorized=true → service subscription. — [src/server.rs#L180-258](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L180-L258) [src/server/connection.rs#L83-142](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L83-L142) [src/server/connection.rs#L2838-2932](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L2838-L2932)
- INCOMING CONNECT (auth gates): unauthorized conns die on `unauthorized_evicted` or `login_deadline` (LOGIN_GRACE=180s); login failures are bucketed [password, 2FA, id-whitelist] in LOGIN_FAILURES with 10-minute decay for whitelist rejects; on success `self.authorized=true; self.unauthorized_id=None` releases the slot. — [src/server/connection.rs#L78-103](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L78-L103) [src/server/connection.rs#L186-199](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L186-L199) [src/server/connection.rs#L1839-1887](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L1839-L1887)
- PERSISTENCE: Config::get/set writes TOML via hbb_common; user process start_server(is_server=false) first ipc::connect→Data::SyncConfig to pull config from the running server; Linux/macOS server waits up to 3s (CONFIG_SYNC_INITIAL_WAIT_SECS) for root→local sync, then `sync_and_watch_config_dir` pushes local changes back to root every 0.3s. — [src/server.rs#L689-723](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L689-L723) [src/server.rs#L767-899](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L767-L899)
- UNI-LINK dispatch: `rustdesk://`-style URIs or `--connect <id>` args are normalized in core_main_invoke_new_connection into `{prefix}{authority}/{id}?params` and forwarded to the running instance via D-Bus (linux), WM_USER+2 window message (windows), or ipc::send_url_scheme (macos); falls back to handling locally. — [src/core_main.rs#L771-863](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/core_main.rs#L771-L863)
- CM approval flow: pending conn sends ipc::Data::Login{...} to the CM ipc server (ui_cm_interface::start_ipc); Flutter `--cm` window shows the prompt; operator accept sends Data::Authorize back → conn.send_logon_response_and_keep_alive; Data::Close→send_close_reason_no_retry+on_close. — [src/server/connection.rs#L749-779](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L749-L779) [src/flutter.rs#L1572-1605](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter.rs#L1572-L1605) [src/ipc.rs#L323-357](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/ipc.rs#L323-L357)
- Service template loop: each registered Service runs ServiceTmpl::run/repeat thread that hibernates at HIBERNATE_TIMEOUT=30ms until a subscriber exists, calls state.init() on first subscriber and state.reset() when the last leaves — so capture/encode resources are only held during active sessions. — [src/server/service.rs#L255-329](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/service.rs#L255-L329)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
