# Data flow — rustdesk/rustdesk

> Canonical page: https://codevetter.com/unpack/rustdesk/data-flow

# Data flow — rustdesk/rustdesk

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

All remote traffic is protobuf `Message`/`RendezvousMessage` frames over a `Stream` abstraction (TCP, KCP/UDP, WebSocket, WebRTC datachannel) provided by hbb_common. Controlled side: rendezvous registration over UDP to hbbs, then per-connection streams multiplexed to named services via `ConnInner` send channels. Controlling side: Session/LoginConfigHandler state owned per session, decoded frames pushed to Flutter via StreamSink events or texture handles. Config is TOML files (Config/Config2/LocalConfig/PeerConfig) synchronized between the root service process and user process over IPC.
- Identity/registration flow: `RendezvousMediator::start_udp` opens UDP to the rendezvous server (RENDEZVOUS_PORT) and loops sending `register_peer` on a timer; `handle_resp` processes RegisterPeerResponse→register_pk, RegisterPkResponse (OK→key_confirmed, UUID_MISMATCH→handle_uuid_mismatch, NOT_DEPLOYED→NEEDS_DEPLOY+DEPLOY_RETRY_INTERVAL backoff), plus latency EMA updates into Config. — [src/rendezvous_mediator.rs#L367-485](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/rendezvous_mediator.rs#L367-L485) [src/rendezvous_mediator.rs#L487-534](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/rendezvous_mediator.rs#L487-L534)
- Inbound path: hbbs delivers PunchHole/relay requests → `accept_connection`/`create_relay_connection` → `create_tcp_connection` → `admit_unauthorized` (bounds unauthenticated conns) → `identity_handshake` (NaCl sign of IdPk + box_ key exchange; on WebRTC the DTLS fingerprint is signed into the identity) → `Connection::start`. — [src/server.rs#L211-326](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L211-L326) [src/server/connection.rs#L524-561](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L524-L561)
- Outbound path: `Remote::io_loop` → `Client::start` → `_start` sets up parallel transports — direct IP/domain shortcut, UDP punch socket + NAT test, IPv6 socket, optional WebRTC offerer — then `_start_inner` runs the rendezvous dance and a second offer-less request races a pure TCP punch fallback (`select_ok`/race_transports_prefer_webrtc). — [src/client/io_loop.rs#L151-220](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/client/io_loop.rs#L151-L220) [src/client.rs#L409-580](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/client.rs#L409-L580)
- Session crypto: `secure_connection` verifies the peer's signed IdPk against the rendezvous-server public key (custom `key` option or built-in RS_PUB_KEY), on WebRTC additionally binds the signed DTLS fingerprint to fail closed against SDP-swap MITM, then installs a symmetric key via PublicKey message + `conn.set_key`. — [src/client.rs#L1645-1758](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/client.rs#L1645-L1758) [src/server.rs#L262-326](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L262-L326)
- After login the controlled `Connection` runs a `tokio::select!` loop over: peer messages (on_message), CM IPC channel (`rx_from_cm`: Authorize→send_logon_response_and_keep_alive, Close, CmWindowClosed...), authed IPC channel, video/main send queues (tx, tx_video), hbbs broadcast receiver, and timers (test_delay, file_timer, per-second). — [src/server/connection.rs#L734-779](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L734-L779) [src/server/connection.rs#L548-560](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L548-L560)
- Video frames flow display→`scrap::Capturer`→encoder→`Message`→`ServiceTmpl::send_video_frame_shared` to each subscribed `ConnInner`, whose `tx_video` queue is drained by the connection's send task; incoming `ConnInner::send` pushes `(Instant, Arc<Message>)` onto unbounded mpsc channels. — [src/server/service.rs#L231-243](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/service.rs#L231-L243) [src/server/connection.rs#L76](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L76) [src/server/connection.rs#L552-553](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L552-L553)
- UI data path on the controller: decoded frames/options go to `Session<T: InvokeUiSession>` which calls handler methods (FlutterHandler) that push JSON `{"name": event, ...}` onto per-app-type `GLOBAL_EVENT_STREAM` StreamSinks, or RGBA/texture via `EventToUI::Rgba/Texture`. — [src/flutter_ffi.rs#L96-100](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter_ffi.rs#L96-L100) [src/flutter.rs#L1550-1569](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter.rs#L1550-L1569) [src/ui_session_interface.rs#L57-75](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/ui_session_interface.rs#L57-L75)
- Config persistence: `Config`/`Config2`/`LocalConfig`/`PeerConfig` (hbb_common TOML stores) are read/written through `ui_interface`/`ipc`; on Linux/macOS `sync_and_watch_config_dir` keeps the root service and user `--server` process configs in sync over IPC `Data::SyncConfig` every 0.3s, and `import_config` merges TOML by mtime. — [src/server.rs#L767-899](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L767-L899) [src/ipc.rs#L370](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/ipc.rs#L370) [src/core_main.rs#L739-763](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/core_main.rs#L739-L763)
- HTTP control plane: `hbbs_http::sync` posts heartbeat + sysinfo to `api-server` URL every 3s tick (15s heartbeat), downloads `StrategyOptions` (config_options + extra maps) that are applied into Config — meaning the server can remotely set any option key listed in libs/base/src/config/keys.rs. (inferred) — [src/hbbs_http/sync.rs#L18-50](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/hbbs_http/sync.rs#L18-L50) [libs/base/src/config/keys.rs](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/libs/base/src/config/keys.rs)
- LAN discovery is a separate UDP broadcast channel on get_broadcast_port(): `PeerDiscovery` protobuf ping→pong carrying id/mac/hostname/username, independent of the rendezvous path. — [src/lan.rs#L23-60](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/lan.rs#L23-L60)
- Custom-client provisioning is embedded, not configured at runtime: `custom_server::get_custom_server_from_string` parses `host=,key=,api=,relay=` from the exe filename or a reversed base64/signed blob; `load_custom_client` runs at startup in core_main/flutter initialize. — [src/custom_server.rs#L21-80](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/custom_server.rs#L21-L80) [src/flutter_ffi.rs#L48-53](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter_ffi.rs#L48-L53)
- File-transfer data moves as `ipc::FS`/`FileAction` protobuf messages + raw bytes; `TransferJob` objects in libs/base/src/fs.rs own per-job state (read_jobs/write_jobs in both Remote and Connection), with digest checks (`CheckDigest`) for resume/overwrite detection. — [src/ipc.rs#L140-238](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/ipc.rs#L140-L238) [src/client/io_loop.rs#L82-84](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/client/io_loop.rs#L82-L84) [libs/base/src/fs.rs](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/libs/base/src/fs.rs)

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)
