Repository navigation
Remote Desktop Stacks
English · Русский
Both protocols are implemented in this repository. Nothing is shelled out to and no third-party client is bundled.
interface RemoteDesktopSession {
val framebuffer: RemoteFramebuffer // pixels
val updates: Flow<RemoteDesktopUpdate> // cold, single-collector; collecting runs the session
val title: String
val capabilities: RemoteDesktopCapabilities // which optional controls this protocol has
val diagnostics: RemoteDesktopDiagnostics
suspend fun sendPointer(x: Int, y: Int, buttonMask: Int)
suspend fun sendKey(event: RemoteKeyEvent, down: Boolean)
suspend fun sendClipboardText(text: String)
…
}VNC and RDP differ in nearly every wire detail and in none of the things a screen needs, so the
protocol vocabulary — keysyms, scancodes, encodings — stops at the adapters (VncRemoteDesktop,
RdpRemoteDesktop). The pointer mask follows the RFB convention because it is the more expressive
of the two; RDP, which sends transitions, derives them from the change since the previous call.
RemoteFramebuffer is the shared ARGB buffer (resize / blit / fill / copyRect).
flowchart TD
TCP[TCP + TLS<br/>RdpTcpTransport] --> X[X.224 connection request]
X --> NLA[CredSSP / NTLM<br/>nla: TsRequest, Ntlm*, Der]
NLA --> MCS[MCS + GCC<br/>Mcs, McsConnect, Gcc, Per, Ber]
MCS --> LIC[Licensing<br/>LicenseExchange + RdpLicenseCrypto]
LIC --> CAP[Capability exchange → font map<br/>RdpConnectionSequence]
CAP --> LIVE{live session}
LIVE --> FP[Fast-path updates<br/>FastPath, SurfaceCommands, PointerUpdate]
LIVE --> DYC[Dynamic channels · MS-RDPEDYC<br/>DynamicChannelHandler]
DYC --> EGFX[egfx: GraphicsChannel, GraphicsSurface]
DYC --> CLIP[ClipboardChannel]
DYC --> DISP[DisplayControlChannel]
DYC --> AUD[AudioChannel]
| Layer | Files |
|---|---|
| Byte-level IO with bounds checks |
RdpIo (RdpReader, RdpWriter, RdpSource, RdpSink); malformed input → RdpProtocolException
|
| Connection sequence |
RdpConnect (RdpConnectionSequence, RdpSessionState) — pure protocol over an injected source/sink, so the whole sequence is driven by a test |
| Entry point and live session |
RdpTransport (RdpTransport, RdpSession, RdpUpdate) |
| Bitmap codecs |
NsCodec, PlanarCodec, InterleavedRle, rfx/ (RemoteFX: DWT, RLGR, colour) |
| Graphics pipeline codecs |
egfx/: Progressive, ProgressiveDwt, ClearCodec, Zgfx, AvcCodec, AvcStream, Avc444Planes, H264Color
|
| Platform crypto |
nla/NtlmCrypto, LicenseCrypto / RdpLicenseCrypto — injected, so the protocol stays platform-free |
| Certificate trust |
RdpCertificate / RdpCertificateVerifier (TOFU by fingerprint), RdpVerifyingTrustManager, FileRdpCertificateStore
|
| Session extras |
RdpDisplayScale, RdpImageQuality, RdpClientSettings, RdpFile/RdpFileImport, ServerRedirection (farm routing) |
H.264 is injected as egfx/H264Decoder: H264DecoderFactory + YuvFrame. The platform
answers for the decoder only — the wire format and the 4:4:4 assembly belong to AvcCodec — and
available is what decides whether AVC is advertised at all. Desktop resolves ffmpeg on PATH
(process/resolveExecutableOnPath, FfmpegH264, Y4mFrameReader); Android uses MediaCodecH264.
Audio redirection goes through the shared audio/RemoteAudio contract (AudioOutputs,
RemoteAudioPlayerFactory, RemoteAudioFormat) and audio/PcmPlayer — a platform sink answers
for the device, never for when to open it.
| Layer | Files |
|---|---|
| Entry point, session, auth |
VncTransport (VncTransport, VncSession, VncUpdate, VncAuth) |
| Wire |
VncIo, RfbCodec, RfbEncodings, RfbStreaming, PixelFormat
|
| Adapter to the shared contract | VncRemoteDesktop |
| Injected platform codecs |
VncCodecPorts: InflaterFactory (zlib), VncImageDecoder (JPEG), VncChallengeResponder (the DES challenge VNC-Auth requires) |
| Transport |
VncTcpTransport (jvmShared) |
VNC-Auth uses DES because RFC 6143 specifies it; that is a protocol constraint, not a choice, and the corresponding scanner alerts are closed as won't-fix for that reason.
- Protocol types never leak into the UI — the shared contract in
graphics/is the boundary. - Every PDU read goes through the bounds-checked reader; malformed input raises a typed protocol exception rather than an index error.
- Server-chosen text (clipboard previews, desktop names) is untrusted and is drawn through
ui/design/UntrustedText. - Platform capabilities are injected, never detected inside the protocol code.
User guide
- Installation
- Getting started
- Hosts and connections
- Vault and credentials
- Terminal
- Files (SFTP)
- Port forwarding
- Remote desktops
- Snippets and runbooks
- Monitoring and guard
- AI assistant
- Sync and devices
- Teams and sharing
- Settings and shortcuts
- Android
- Troubleshooting
Development
- Architecture
- Building and running
- Connections and transports
- Terminal engine
- Vault and crypto
- Sync protocol
- Remote desktop stacks
- UI layer
- Testing and the gate
- Contributing and releases
Русский — оглавление