-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Server resize follow-up #532
Conversation
00ad7f6
to
12a6c98
Compare
@elmarco Thank you! |
yes, thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two commits with the same summary: feat(async): teach single_sequence_step() to keep unmatched PDUs
Did you intend to change the scope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor code into something like this:
diff --git a/crates/ironrdp-async/src/framed.rs b/crates/ironrdp-async/src/framed.rs
index 2597f644..fa4cf600 100644
--- a/crates/ironrdp-async/src/framed.rs
+++ b/crates/ironrdp-async/src/framed.rs
@@ -60,10 +60,6 @@ impl<S> Framed<S> {
pub fn peek(&self) -> &[u8] {
&self.buf
}
-
- pub fn leftover_mut(&mut self) -> &mut BytesMut {
- &mut self.buf
- }
}
impl<S> Framed<S>
diff --git a/crates/ironrdp-server/src/server.rs b/crates/ironrdp-server/src/server.rs
index 63888d3d..e15deacb 100644
--- a/crates/ironrdp-server/src/server.rs
+++ b/crates/ironrdp-server/src/server.rs
@@ -17,6 +17,7 @@ use ironrdp_pdu::{self, decode, encode_vec, mcs, nego, rdp, Action, PduResult};
use ironrdp_svc::{impl_as_any, server_encode_svc_messages, StaticChannelId, StaticChannelSet, SvcProcessor};
use ironrdp_tokio::{Framed, FramedRead, FramedWrite, TokioFramed};
use rdpsnd::server::{RdpsndServer, RdpsndServerMessage};
+use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::{mpsc, Mutex};
use tokio::task;
@@ -797,25 +798,29 @@ impl RdpServer {
}
}
- async fn accept_finalize<S>(&mut self, mut framed: Framed<S>, mut acceptor: Acceptor) -> Result<()>
+ async fn accept_finalize<S>(&mut self, mut framed: TokioFramed<S>, mut acceptor: Acceptor) -> Result<()>
where
- S: FramedRead + FramedWrite,
+ S: AsyncRead + AsyncWrite + Sync + Send + Unpin,
{
let mut other_pdus = None;
+
loop {
let (new_framed, result) = ironrdp_acceptor::accept_finalize(framed, &mut acceptor, other_pdus.as_mut())
.await
.context("failed to accept client during finalize")?;
- framed = new_framed;
+ let (stream, mut leftover) = new_framed.into_inner();
debug!(other_pdus = other_pdus.as_ref().map_or(0, |o| o.len()));
if let Some(pdus) = other_pdus.take() {
- let mut leftover: Vec<_> = pdus.iter().flat_map(|p| p.iter().copied()).collect();
- leftover.extend_from_slice(&framed.leftover_mut().split()[..]);
- framed.leftover_mut().extend_from_slice(&leftover);
+ let unmatched_frames = pdus.into_iter().flatten();
+ let previous_leftover = leftover.split();
+ leftover.extend(unmatched_frames);
+ leftover.extend_from_slice(&previous_leftover);
}
+ framed = TokioFramed::new_with_leftover(stream, leftover);
+
match self.client_accepted(&mut framed, result).await? {
RunState::Continue => {
unreachable!();
Signed-off-by: Marc-André Lureau <[email protected]>
#[wasm_bindgen] creates annoying warnings, such as: rust-analyzer: Function `__wasm_bindgen_generated_Session_apply_inputs` should have snake_case name, e.g. `__wasm_bindgen_generated_session_apply_inputs` Signed-off-by: Marc-André Lureau <[email protected]>
Signed-off-by: Marc-André Lureau <[email protected]>
This is not supported yet, and I am not sure how to do it atm. Generally, server uses multiple of 4 widths, and client has surface capabilities, so this path is unlikely. Signed-off-by: Marc-André Lureau <[email protected]>
Fixes a73e0b7 Signed-off-by: Marc-André Lureau <[email protected]>
…hint When compiled in debug mode, the code checks the expected Action hint. But in release mode, no checks are done and the it will have to fail later. Instead, return whether the PDU is matching the hint, so the caller can decide what to do in this case. Signed-off-by: Marc-André Lureau <[email protected]>
@elmarco By the way, are you getting these client messages from mstsc as well? I’m wondering if the real fix should not be about modifying the IronRDP client to not send messages unrelated to the connection sequence before the connection sequence is over. |
Yes. The reactivation sequence is triggered by the server, so there can always be client messages in flight. |
Oh right. It becomes a problem during the reactivation sequence. Sounds good. |
…ytes The caller can then decide what to do. Signed-off-by: Marc-André Lureau <[email protected]>
…d bytes The caller can then decide what to do. Signed-off-by: Marc-André Lureau <[email protected]>
The caller can gather the unmatching/unexpected PDUs as necessary. Signed-off-by: Marc-André Lureau <[email protected]>
The caller can gather the unmatching/unexpected PDUs as necessary. Signed-off-by: Marc-André Lureau <[email protected]>
The client may have pending messages while the activation-reactivation sequence is ongoing. Let's collect them in this case and restore them after successfull reconnection. Signed-off-by: Marc-André Lureau <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
I forgot to squash BitmapEncoder support in #530.
The main part is handling pending incoming client message during deact-react; queuing and replaying them after acceptation.