fix(pdu)!: send NetworkAutoDetect over the MCS message channel#1348
fix(pdu)!: send NetworkAutoDetect over the MCS message channel#1348Greg Lamberson (glamberson) wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR corrects Network Auto-Detect framing and routing to match MS-RDPBCGR by moving it off the I/O channel slow-path Share Data PDUs and onto the MCS message channel with the required Basic Security Header (SEC_AUTODETECT_REQ / SEC_AUTODETECT_RSP). This aligns IronRDP with mstsc/xfreerdp behavior and enables both connect-time and continuous auto-detection to actually function.
Changes:
- Add
AutoDetectReqPdu/AutoDetectRspPduwrappers (Basic Security Header framing) and remove the fabricated Share Data PDU representation for auto-detect. - Negotiate, join, and plumb the MCS message channel ID through acceptor/connector/session and use it for auto-detect traffic (client + server).
- Update and expand tests to cover message-channel negotiation and auto-detect request/response processing on that channel.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/ironrdp-testsuite-core/tests/session/autodetect.rs | Migrates session auto-detect tests to use message-channel framing and validates channel usage. |
| crates/ironrdp-testsuite-core/tests/server/acceptor.rs | Adds coverage ensuring the acceptor advertises Extended Client Data support and allocates a deterministic message channel ID. |
| crates/ironrdp-session/src/x224/mod.rs | Routes message-channel traffic to new auto-detect decoder/encoder path and stops handling auto-detect as Share Data. |
| crates/ironrdp-session/src/active_stage.rs | Wires negotiated message-channel ID into the session processor. |
| crates/ironrdp-server/src/server.rs | Sends auto-detect requests on message channel and decodes auto-detect responses from message channel. |
| crates/ironrdp-pdu/src/rdp/headers.rs | Removes auto-detect from ShareDataPdu / ShareDataPduType since it is not a real slow-path Share Data PDU. |
| crates/ironrdp-pdu/src/rdp/autodetect.rs | Introduces AutoDetectReqPdu / AutoDetectRspPdu with Basic Security Header framing + round-trip tests. |
| crates/ironrdp-connector/src/connection.rs | Requests message channel in GCC, joins it, enables connect-time auto-detect handling on the message channel, and propagates message_channel_id. |
| crates/ironrdp-acceptor/src/connection.rs | Negotiates and joins the message channel when requested and surfaces message_channel_id in AcceptorResult. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
a7fd8d2 to
27c6446
Compare
There was a problem hiding this comment.
Thanks for chasing this down, the protocol diagnosis is right: 0x3b was never a real PDUTYPE2, and auto-detect belongs on the message channel behind a Basic Security Header. My one real concern is the connector connect-time state machine. Also I think the migrated tests cover the continuous (session) path well, but I don't see coverage for the connector connect-time branch specifically (the inlined-licensing path and the "ignore a non-autodetect message-channel PDU and keep listening" path). Those are the two riskiest branches in the PR. Could you add a test for that?
|
Added connector connect-time tests in a new tests/connector/autodetect.rs, covering the ConnectTimeAutoDetection demux you flagged: an Auto-Detect Request on the message channel is answered and the phase continues; an unrelated message-channel PDU is ignored and the phase continues; and a first licensing PDU on the I/O channel advances the connector out of auto-detection into the licensing path. That exercises the two branches you called out as riskiest plus the auto-detect path itself. The four inline points are addressed in their threads: the inlined licensing transition is now a shared helper so the terminal-state transition lives in one place; the message-channel input is decoded once; the next_pdu_hint gate carries a comment stating why it cannot stall; and the connect-time bandwidth no-op is now an explicit documented decision, with the Bandwidth Measure Results reply noted as a follow-up. I have also rebased the branch onto current master. |
NetworkAutoDetect was modeled as a slow-path Share Data PDU (ShareDataPduType::AutoDetect, a fabricated 0x3B) carried on the I/O channel. Per [MS-RDPBCGR] 2.2.14.3 / 2.2.14.4 the auto-detect PDUs are framed by a Basic Security Header (SEC_AUTODETECT_REQ / SEC_AUTODETECT_RSP) and ride the MCS message channel, so neither mstsc nor xfreerdp answered the requests. ironrdp-pdu: add AutoDetectReqPdu / AutoDetectRspPdu, which wrap the request and response data with the security header (mirroring the multitransport PDUs). Remove the ShareDataPdu::AutoDetectReq / AutoDetectRsp variants and the ShareDataPduType::AutoDetect discriminant, which did not correspond to any real PDUTYPE2. ironrdp-server: send auto-detect requests and receive responses on the message channel surfaced by the acceptor, with the new framing. ironrdp-connector and ironrdp-session: the client now requests the message channel (Client Message Channel Data), advertises SUPPORT_NET_CHAR_AUTODETECT, joins the channel, and answers RTT requests on it. The connector handles connect-time auto-detection (previously a no-op) and the session handles continuous auto-detection. Resolves the client side of the message-channel TODO (Devolutions#140). Builds on the acceptor message-channel negotiation merged in Devolutions#1347 (efa5732).
27c6446 to
26b5c14
Compare
Stacked on #1347 (acceptor message-channel negotiation). Until that merges,
the diff here also contains its commit; review the top commit
(
fix(pdu)!: send NetworkAutoDetect over the MCS message channel). I willrebase this to master-only once #1347 lands.
NetworkAutoDetect was modeled as a slow-path Share Data PDU
(ShareDataPduType::AutoDetect, a fabricated 0x3B value) carried on the I/O
channel. Per MS-RDPBCGR 2.2.14.3 / 2.2.14.4 the auto-detect PDUs are framed by
a Basic Security Header (SEC_AUTODETECT_REQ / SEC_AUTODETECT_RSP) and ride the
MCS message channel, so neither mstsc nor xfreerdp ever answered the requests.
ironrdp-pdu: add AutoDetectReqPdu / AutoDetectRspPdu, wrapping the request and
response data with the security header (mirroring the multitransport PDUs).
Remove the ShareDataPdu::AutoDetectReq / AutoDetectRsp variants and the
ShareDataPduType::AutoDetect discriminant, which did not correspond to any real
PDUTYPE2. This is the breaking change.
ironrdp-server: send auto-detect requests and receive responses on the message
channel surfaced by the acceptor, with the new framing.
ironrdp-connector and ironrdp-session: the client requests the message channel
(Client Message Channel Data), advertises SUPPORT_NET_CHAR_AUTODETECT, joins the
channel, and answers RTT requests on it. The connector handles connect-time
auto-detection (previously a no-op) and the session handles continuous
auto-detection. Resolves the client side of the message-channel TODO (#140).
Tested: the in-process client/server tests in ironrdp-testsuite-core exercise
the full negotiation and continuous auto-detect; new ironrdp-pdu round-trip
tests cover the security-header framing; the session auto-detect tests were
migrated to the message channel.