Skip to content
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

[v10] Add error check before handle_bitmap #13899

Merged
merged 11 commits into from
Jun 29, 2022
60 changes: 32 additions & 28 deletions lib/srv/desktop/rdp/rdpclient/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,40 +609,44 @@ pub unsafe extern "C" fn read_rdp_output(client_ptr: *mut Client) -> CGOErrCode
fn read_rdp_output_inner(client: &Client) -> Option<String> {
let tcp_fd = client.tcp_fd;
let client_ref = client.go_ref;

// Read incoming events.
//
// Wait for some data to be available on the TCP socket FD before consuming it. This prevents
// us from locking the mutex in Client permanently while no data is available.
while wait_for_fd(tcp_fd as usize) {
let mut err = CGOErrCode::ErrCodeSuccess;
let res = client
.rdp_client
.lock()
.unwrap()
.read(|rdp_event| match rdp_event {
RdpEvent::Bitmap(bitmap) => {
let mut cbitmap = match CGOBitmap::try_from(bitmap) {
Ok(cb) => cb,
Err(e) => {
error!(
"failed to convert RDP bitmap to CGO representation: {:?}",
e
);
return;
}
};
unsafe {
err = handle_bitmap(client_ref, &mut cbitmap) as CGOErrCode;
};
}
// These should never really be sent by the server to us.
RdpEvent::Pointer(_) => {
debug!("got unexpected pointer event from RDP server, ignoring");
}
RdpEvent::Key(_) => {
debug!("got unexpected keyboard event from RDP server, ignoring");
let res = client.rdp_client.lock().unwrap().read(|rdp_event| {
// This callback can be called multiple times per rdp_client.read()
// (if multiple messages were received since the last call). Therefore,
// we check that the previous call to handle_bitmap succeeded, so we don't
// have a situation where handle_bitmap fails repeatedly and creates a
// bunch of repetitive error messages in the logs. If it fails once,
// we assume the connection is broken and stop trying to send bitmaps.
if err == CGOErrCode::ErrCodeSuccess {
match rdp_event {
RdpEvent::Bitmap(bitmap) => {
let mut cbitmap = match CGOBitmap::try_from(bitmap) {
Ok(cb) => cb,
Err(e) => {
error!(
"failed to convert RDP bitmap to CGO representation: {:?}",
e
);
return;
}
};
unsafe {
err = handle_bitmap(client_ref, &mut cbitmap) as CGOErrCode;
};
}
// No other events should be sent by the server to us.
_ => {
debug!("got unexpected pointer event from RDP server, ignoring");
}
}
});
}
});
match res {
Err(RdpError::Io(io_err)) if io_err.kind() == ErrorKind::UnexpectedEof => return None,
Err(e) => {
Expand Down Expand Up @@ -831,7 +835,7 @@ unsafe fn from_go_array(len: u32, ptr: *mut u8) -> Vec<u8> {
}

#[repr(C)]
#[derive(Copy, Clone, PartialEq)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum CGOErrCode {
ErrCodeSuccess = 0,
ErrCodeFailure = 1,
Expand Down