Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/ironrdp-acceptor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ironrdp-pdu = { path = "../ironrdp-pdu", version = "0.9" } # public
ironrdp-svc = { path = "../ironrdp-svc", version = "0.8" } # public
ironrdp-connector = { path = "../ironrdp-connector", version = "0.10" } # public
ironrdp-async = { path = "../ironrdp-async", version = "0.10" } # public
rand = "0.9"
tracing = { version = "0.1", features = ["log"] }

[lints]
Expand Down
339 changes: 315 additions & 24 deletions crates/ironrdp-acceptor/src/connection.rs

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions crates/ironrdp-acceptor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,75 @@ where
}

pub async fn accept_finalize<S>(
framed: Framed<S>,
acceptor: &mut Acceptor,
) -> ConnectorResult<(Framed<S>, AcceptorResult)>
where
S: FramedRead + FramedWrite,
{
accept_finalize_with_multitransport(framed, acceptor, |_, _| async {}).await
}

/// Completes the connection sequence, notifying `multitransport_handler` each
/// time the acceptor sends an Initiate Multitransport Request, so the caller
/// can establish the sideband UDP transport (RDPEUDP2 + TLS + RDPEMT).
///
/// Unlike [`ironrdp_async::connect_finalize_with_multitransport`] on the
/// client side, `multitransport_handler` does not report an outcome back
/// into the sequence: by the time it runs, the acceptor has already sent the
/// request and moved on to capability negotiation (see the doc comment on
/// [`ironrdp_acceptor::AcceptorState::MultitransportBootstrapping`]), and
/// nothing here waits for the sideband transport to come up. Establishing it
/// is the caller's job, driven independently of this function's return.
/// `multitransport_handler` is awaited once per request, synchronously,
/// immediately after the sequence step that sent it: it should return
/// promptly (for example, by spawning the actual UDP-accept work on the
/// caller's own runtime) rather than driving the transport to completion
/// inline, or the RDP handshake stalls behind it.
///
/// # Panics
///
/// Panics if `multitransport_soft_sync_negotiated()` returns `None` right
/// after `multitransport_request()` returned `Some`, which the two methods'
/// own contract does not allow.
pub async fn accept_finalize_with_multitransport<S, H>(
mut framed: Framed<S>,
acceptor: &mut Acceptor,
mut multitransport_handler: H,
) -> ConnectorResult<(Framed<S>, AcceptorResult)>
where
S: FramedRead + FramedWrite,
H: AsyncFnMut(ironrdp_pdu::rdp::multitransport::MultitransportRequestPdu, bool),
{
let mut buf = WriteBuf::new();
// `multitransport_request()` borrows rather than consumes (the field it
// reads also gates `CapabilitiesWaitConfirm`'s tolerance for a late
// Initiate Multitransport Response), so this driver tracks locally
// whether it has already notified the caller instead. Seeded from
// whatever is already present rather than `false`: a Deactivation-
// Reactivation Sequence rebuilds the acceptor via
// `Acceptor::new_deactivation_reactivation()`, which carries the
// original request forward, then this function is called again on the
// rebuilt acceptor. Bootstrapping does not run a second time, so without
// this the first loop iteration of that fresh call would treat the
// carried-over request as newly sent and notify the handler again.
let mut notified = acceptor.multitransport_request().is_some();

loop {
if let Some(result) = acceptor.get_result() {
return Ok((framed, result));
}

single_sequence_step(&mut framed, acceptor, &mut buf).await?;

if !notified && let Some(request) = acceptor.multitransport_request() {
let request = request.clone();
let soft_sync = acceptor
.multitransport_soft_sync_negotiated()
.expect("multitransport_request() just returned Some, so a request was sent");
multitransport_handler(request, soft_sync).await;
notified = true;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions crates/ironrdp-testsuite-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ hex = "0.4"
ironrdp-cliprdr-format.path = "../ironrdp-cliprdr-format"
ironrdp-cliprdr = { path = "../ironrdp-cliprdr", features = ["__test"] }
ironrdp-acceptor.path = "../ironrdp-acceptor"
ironrdp-async.path = "../ironrdp-async"
ironrdp-tokio.path = "../ironrdp-tokio"
ironrdp-bulk.path = "../ironrdp-bulk"
ironrdp-connector.path = "../ironrdp-connector"
ironrdp-displaycontrol.path = "../ironrdp-displaycontrol"
Expand Down
Loading
Loading