feat(connector): Hyper-V vmconnect support#1475
Draft
irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 5 commits into
Draft
feat(connector): Hyper-V vmconnect support#1475irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 5 commits into
irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 5 commits into
Conversation
A Hyper-V VM console speaks plain RDP, but the host expects the front of the connection in a different order: a Preconnection Blob carrying the VM id first, then TLS, then CredSSP, and the X.224 negotiation last. This is the Direct Approach, where the host must select exactly PROTOCOL_HYBRID because NLA has already run by the time X.224 happens. `ClientConnector::new_vmconnect(..)` selects that ordering. The whole difference between the two orderings lives in one place, the `Front` enum: where the sequence starts, what X.224 advertises, which selected protocol is acceptable, and where the negotiation and NLA each hand over. `after_initiation` and `after_credssp` are mirror images, since whichever of the two runs last is the one that hands over to the Basic Settings Exchange. Only one state is added, `SendPreconnectionBlob`; both orderings share the existing X.224 initiation states. Everything from the Basic Settings Exchange onward is untouched, so the async and blocking drivers run the new ordering exactly like a standard connection.
`ConfigBuilder::with_vmconnect(vm_id)` points the client at a Hyper-V VM console instead of a normal RDP host. The Direct transport builds the connector with `new_vmconnect(..)` when a VM id is set, so the connection runs the Hyper-V ordering and then rejoins the shared sequence; no transport-specific plumbing is needed.
Address review feedback on the reactivation fix: link the spec section from `reactivate`, stop `set_share_id` from claiming it must be called during a Deactivation-Reactivation Sequence (it no longer does), and warn on `set_fastpath_processor` that a hand-built processor is how bulk decompression gets silently dropped. The FFI method keeps its name for ABI compatibility, so say what it actually does now.
…eview A gateway or RDCleanPath proxy performs the X.224 connection initiation itself, which the Hyper-V ordering moves to after authentication. Combining them left RDCleanPath failing deep in the handshake with "invalid connector state"; the builder now rejects it up front. Review fixes: lowercase error messages per STYLE.md, "VM ID" casing, `PreconnectionBlobSendRequest` to match the `<Phase><Action>` naming of the sibling states, `HYPERV_SECURITY_PROTOCOL` made private (nothing outside the crate consumes it), a spec section number on its doc link, the stale "shared by" doc on `decode_connection_confirm` corrected along with its unused return component, and the trimmed comments now say why rather than what.
Pins the Hyper-V ordering (preconnection blob carrying the VM ID, then TLS and NLA, then the X.224 negotiation, then the shared tail) and the requirement that the host select plain HYBRID. Both orderings share the X.224 initiation states now, so the standard path is covered here too: negotiation first, and a protocol the client never advertised is refused. Also document that a Hyper-V console ignores the TLS and NLA config flags, and why the preconnection blob names a protocol before anything is negotiated.
irvingouj@Devolutions (irvingoujAtDevolution)
force-pushed
the
feat/vmconnect
branch
from
July 27, 2026 15:26
fa6e5ed to
cdcb1fd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1474 — review that one first, this diff is only the vmconnect part.
Lets you connect to a Hyper-V VM console. Same RDP steps as usual, the host just wants the front in a different order: Preconnection Blob with the VM id → TLS → CredSSP → X.224 last. That's the Direct Approach, and since NLA already ran by then the host has to select exactly
PROTOCOL_HYBRID.ClientConnector::new_vmconnect(..)picks the ordering,ConfigBuilder::with_vmconnect(vm_id)on the client side.The bit I'd like eyes on: the whole difference between the two orderings sits in one
Frontenum — where we start, what X.224 advertises, what selected protocol we accept, and where negotiation/NLA each hand over.after_initiationandafter_credsspare mirrors of each other, because whichever runs last is the one handing over to Basic Settings. Only one new state (SendPreconnectionBlob); both orderings share the existing X.224 initiation states. Tail is untouched and the existing drivers run it as-is.No API break —
ClientConnectorStateis already#[non_exhaustive]and the FFI getters all have catch-all arms.Still missing (why it's a draft)
--vm-idon ironrdp-viewer, not wired to.rdpprops), so today only a library embedder like RDM can reach itTesting
Ran the real
RdpClientagainst my local Hyper-V host, all 7 running lab VMs, default config (compression on) — every one negotiated HYBRID and rendered. Also drove Ctrl+Alt+Del in and watched the VM's own console change from the host side, so input round-trips.Standard RDP to a Windows Server VM still fine (both orderings share the X.224 states now, so that was the thing to not break).
clippy/check clean on connector, client, web wasm32, ffi. fmt clean. testsuite-core 949, testsuite-extra 21.