#2, send client encodings

This commit is contained in:
Jovi Hsu 2021-11-17 11:09:28 +08:00
parent 098629536a
commit 0762d972a4
3 changed files with 122 additions and 32 deletions

View File

@ -194,6 +194,12 @@ impl Component for PageRemote {
} }
} }
} }
fn rendered(&mut self, first_render: bool) {
if first_render {
self.handler.set_resolution(1366, 768);
}
}
} }
// impl PageRemote // impl PageRemote
@ -250,7 +256,7 @@ impl PageRemote {
let canvas = self.canvas.cast::<HtmlCanvasElement>().unwrap(); let canvas = self.canvas.cast::<HtmlCanvasElement>().unwrap();
canvas.set_width(width as u32); canvas.set_width(width as u32);
canvas.set_height(height as u32); canvas.set_height(height as u32);
self.link.send_message(RemoteMsg::RequireFrame(1)); self.link.send_message(RemoteMsg::RequireFrame(0));
let ctx = match &self.canvas_ctx { let ctx = match &self.canvas_ctx {
Some(ctx) => ctx, Some(ctx) => ctx,
None => { None => {

View File

@ -43,6 +43,10 @@ where
self.inner.set_credential(username, password); self.inner.set_credential(username, password);
} }
pub fn set_resolution(&mut self, width: u16, height: u16) {
self.inner.set_resolution(width, height);
}
pub fn require_frame(&mut self, incremental: u8) { pub fn require_frame(&mut self, incremental: u8) {
self.inner.require_frame(incremental); self.inner.require_frame(incremental);
} }
@ -53,26 +57,37 @@ pub trait ProtocalImpl {
fn do_input(&mut self, input: Vec<u8>); fn do_input(&mut self, input: Vec<u8>);
fn get_output(&mut self) -> Vec<ProtocalHandlerOutput>; fn get_output(&mut self) -> Vec<ProtocalHandlerOutput>;
fn set_credential(&mut self, username: &str, password: &str); fn set_credential(&mut self, username: &str, password: &str);
fn set_resolution(&mut self, width: u16, height: u16);
fn require_frame(&mut self, incremental: u8); fn require_frame(&mut self, incremental: u8);
} }
pub struct StreamReader { pub struct StreamReader {
inner: Vec<Vec<u8>>, inner: Vec<Vec<u8>>,
remain: usize,
} }
#[allow(dead_code)] #[allow(dead_code)]
impl StreamReader { impl StreamReader {
pub fn new(bufs: Vec<Vec<u8>>) -> Self { pub fn new(bufs: Vec<Vec<u8>>) -> Self {
Self { inner: bufs } Self {
inner: bufs,
remain: 0,
}
} }
pub fn append(&mut self, buf: Vec<u8>) { pub fn append(&mut self, buf: Vec<u8>) {
self.remain += buf.len();
self.inner.push(buf); self.inner.push(buf);
} }
pub fn remain(&self) -> usize {
self.remain
}
pub fn read_exact_vec(&mut self, out_vec: &mut Vec<u8>, n: usize) { pub fn read_exact_vec(&mut self, out_vec: &mut Vec<u8>, n: usize) {
let mut i = 0; let mut i = 0;
let mut left = n; let mut left = n;
self.remain -= n;
while i < n { while i < n {
if self.inner[0].len() > left { if self.inner[0].len() > left {
for it in self.inner[0].drain(0..left) { for it in self.inner[0].drain(0..left) {
@ -92,6 +107,7 @@ impl StreamReader {
pub fn read_exact(&mut self, out_buf: &mut [u8], n: usize) { pub fn read_exact(&mut self, out_buf: &mut [u8], n: usize) {
let mut i = 0; let mut i = 0;
let mut left = n; let mut left = n;
self.remain -= n;
while i < n { while i < n {
if self.inner[0].len() > left { if self.inner[0].len() > left {
out_buf[i..i + left].copy_from_slice(&self.inner[0][0..left]); out_buf[i..i + left].copy_from_slice(&self.inner[0][0..left]);

View File

@ -22,6 +22,19 @@ pub enum SecurityType {
// VeNCrypt = 19, // VeNCrypt = 19,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(i32)]
pub enum VncEncoding {
Raw = 0,
CopyRect = 1,
RRE = 2,
Hextile = 5,
TRLE = 15,
ZRLE = 16,
CursorPseudo = -239,
DesktopSizePseudo = -223,
}
pub enum VncState { pub enum VncState {
Init, Init,
Handshake, Handshake,
@ -40,9 +53,10 @@ pub enum ServerMessage {
pub struct VncHandler { pub struct VncHandler {
state: VncState, state: VncState,
// supported_versions: Vec<u8>,
supported_encodings: Vec<VncEncoding>,
security_type: SecurityType, security_type: SecurityType,
challenge: [u8; 16], challenge: [u8; 16],
buf_num: usize,
reader: StreamReader, reader: StreamReader,
require: usize, require: usize,
width: u16, width: u16,
@ -60,9 +74,18 @@ impl ProtocalImpl for VncHandler {
fn new() -> Self { fn new() -> Self {
Self { Self {
state: VncState::Init, state: VncState::Init,
supported_encodings: vec![
VncEncoding::Raw,
// VncEncoding::CopyRect,
// VncEncoding::RRE,
// VncEncoding::Hextile,
// VncEncoding::TRLE,
// VncEncoding::ZRLE,
// VncEncoding::CursorPseudo,
// VncEncoding::DesktopSizePseudo,
],
security_type: SecurityType::Invalid, security_type: SecurityType::Invalid,
challenge: [0; 16], challenge: [0; 16],
buf_num: 0,
reader: StreamReader::new(Vec::with_capacity(10)), reader: StreamReader::new(Vec::with_capacity(10)),
require: 12, // the handleshake message length require: 12, // the handleshake message length
width: 0, width: 0,
@ -78,16 +101,20 @@ impl ProtocalImpl for VncHandler {
} }
fn do_input(&mut self, input: Vec<u8>) { fn do_input(&mut self, input: Vec<u8>) {
self.buf_num += input.len();
// ConsoleService::info(&format!( // ConsoleService::info(&format!(
// "VNC input {}, left {}, require {}", // "VNC input {}, left {}, require {}",
// input.len(), // input.len(),
// self.buf_num, // self.reader.remain(),
// self.require // self.require
// )); // ));
self.reader.append(input); self.reader.append(input);
while self.buf_num >= self.require { while self.reader.remain() >= self.require {
self.handle_input(); self.handle_input();
// ConsoleService::info(&format!(
// "left {}, require {}",
// self.reader.remain(),
// self.require
// ));
} }
} }
@ -131,7 +158,16 @@ impl ProtocalImpl for VncHandler {
self.require = 4; // the auth result message length self.require = 4; // the auth result message length
} }
fn set_resolution(&mut self, _width: u16, _height: u16) {
// VNC client doen't support resolution change
}
fn require_frame(&mut self, incremental: u8) { fn require_frame(&mut self, incremental: u8) {
if 0 == incremental {
// first frame
// set the client encoding
self.send_client_encodings();
}
if let ServerMessage::None = self.msg_handling { if let ServerMessage::None = self.msg_handling {
self.framebuffer_update_request(incremental) self.framebuffer_update_request(incremental)
} }
@ -141,55 +177,45 @@ impl ProtocalImpl for VncHandler {
#[allow(dead_code)] #[allow(dead_code)]
impl VncHandler { impl VncHandler {
fn read_u8(&mut self) -> u8 { fn read_u8(&mut self) -> u8 {
self.buf_num -= 1;
self.reader.read_u8() self.reader.read_u8()
} }
fn read_u16(&mut self) -> u16 { fn read_u16(&mut self) -> u16 {
self.buf_num -= 2;
self.reader.read_u16() self.reader.read_u16()
} }
fn read_u32(&mut self) -> u32 { fn read_u32(&mut self) -> u32 {
self.buf_num -= 4;
self.reader.read_u32() self.reader.read_u32()
} }
fn read_u64(&mut self) -> u64 { fn read_u64(&mut self) -> u64 {
self.buf_num -= 8;
self.reader.read_u64() self.reader.read_u64()
} }
fn read_exact_vec(&mut self, out_vec: &mut Vec<u8>, len: usize) { fn read_exact_vec(&mut self, out_vec: &mut Vec<u8>, len: usize) {
self.buf_num -= len;
self.reader.read_exact_vec(out_vec, len); self.reader.read_exact_vec(out_vec, len);
} }
fn read_exact(&mut self, buf: &mut [u8], len: usize) { fn read_exact(&mut self, buf: &mut [u8], len: usize) {
self.buf_num -= len;
self.reader.read_exact(buf, len) self.reader.read_exact(buf, len)
} }
fn read_string(&mut self, len: usize) -> String { fn read_string(&mut self, len: usize) -> String {
self.buf_num -= len;
self.reader.read_string(len) self.reader.read_string(len)
} }
fn read_string_l8(&mut self) -> String { fn read_string_l8(&mut self) -> String {
let len = self.read_u8() as usize; let len = self.read_u8() as usize;
self.buf_num -= len;
self.reader.read_string(len) self.reader.read_string(len)
} }
fn read_string_l16(&mut self) -> String { fn read_string_l16(&mut self) -> String {
let len = self.read_u16() as usize; let len = self.read_u16() as usize;
self.buf_num -= len;
self.reader.read_string(len) self.reader.read_string(len)
} }
fn read_string_l32(&mut self) -> String { fn read_string_l32(&mut self) -> String {
let len = self.read_u32() as usize; let len = self.read_u32() as usize;
self.buf_num -= len;
self.reader.read_string(len) self.reader.read_string(len)
} }
} }
@ -206,10 +232,38 @@ impl VncHandler {
self.require = 25; // the minimal length of server_init message self.require = 25; // the minimal length of server_init message
// send client_init message // send client_init message
let shared_flag = 0; let shared_flag = 1;
self.outbuf.push(shared_flag); self.outbuf.push(shared_flag);
} }
// +--------------+--------------+---------------------+
// | No. of bytes | Type [Value] | Description |
// +--------------+--------------+---------------------+
// | 1 | U8 [2] | message-type |
// | 1 | | padding |
// | 2 | U16 | number-of-encodings |
// +--------------+--------------+---------------------+
// This is followed by number-of-encodings repetitions of the following:
// +--------------+--------------+---------------+
// | No. of bytes | Type [Value] | Description |
// +--------------+--------------+---------------+
// | 4 | S32 | encoding-type |
// +--------------+--------------+---------------+
fn send_client_encodings(&mut self) {
let mut out = Vec::with_capacity(10);
let mut sw = StreamWriter::new(&mut out);
sw.write_u8(2); // message-type
sw.write_u8(0); // padding
sw.write_u16(self.supported_encodings.len().try_into().unwrap()); // number-of-encodings
for i in &self.supported_encodings {
sw.write_u32(*i as u32);
}
self.outbuf.extend_from_slice(&out);
}
// No. of bytes Type [Value] Description // No. of bytes Type [Value] Description
// 1 CARD8 3 message-type // 1 CARD8 3 message-type
// 1 CARD8 incremental // 1 CARD8 incremental
@ -262,6 +316,7 @@ impl VncHandler {
} }
fn do_authenticate(&mut self) { fn do_authenticate(&mut self) {
// ConsoleService::log(&format!("VNC: do_authenticate {}", self.reader.remain()));
if self.security_type == SecurityType::Invalid { if self.security_type == SecurityType::Invalid {
let auth_type = self.read_u32(); let auth_type = self.read_u32();
match auth_type { match auth_type {
@ -369,18 +424,19 @@ impl VncHandler {
let width = self.read_u16(); let width = self.read_u16();
let height = self.read_u16(); let height = self.read_u16();
let encoding_type = self.read_u32(); let encoding_type = self.read_u32();
match encoding_type { let encoding_enum = unsafe { std::mem::transmute(encoding_type) };
0 => self.handle_raw_encoding(x, y, width, height), match encoding_enum {
1 => self.handle_copy_rect_encoding(x, y, width, height), VncEncoding::Raw => self.handle_raw_encoding(x, y, width, height),
2 => self.handle_rre_encoding(x, y, width, height), VncEncoding::CopyRect => self.handle_copy_rect_encoding(x, y, width, height),
4 => self.handle_corre_encoding(x, y, width, height), VncEncoding::RRE => self.handle_rre_encoding(x, y, width, height),
5 => self.handle_hextile_encoding(x, y, width, height), VncEncoding::Hextile => self.handle_hextile_encoding(x, y, width, height),
_ => { VncEncoding::TRLE => self.handle_trle_encoding(x, y, width, height),
ConsoleService::log(&format!( VncEncoding::ZRLE => self.handle_zrle_encoding(x, y, width, height),
"VNC: Unsupported encoding type {}", VncEncoding::CursorPseudo => {
encoding_type self.handle_cursor_pseudo_encoding(x, y, width, height)
)); }
self.disconnect_with_err(VNC_FAILED) VncEncoding::DesktopSizePseudo => {
self.handle_desktop_size_pseudo_encoding(x, y, width, height)
} }
} }
} else { } else {
@ -517,11 +573,23 @@ impl VncHandler {
unimplemented!() unimplemented!()
} }
fn handle_corre_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) { fn handle_hextile_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
unimplemented!() unimplemented!()
} }
fn handle_hextile_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) { fn handle_trle_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
unimplemented!()
}
fn handle_zrle_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
unimplemented!()
}
fn handle_cursor_pseudo_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
unimplemented!()
}
fn handle_desktop_size_pseudo_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
unimplemented!() unimplemented!()
} }
} }