#2, send client encodings
This commit is contained in:
parent
098629536a
commit
0762d972a4
@ -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
|
||||
@ -250,7 +256,7 @@ impl PageRemote {
|
||||
let canvas = self.canvas.cast::<HtmlCanvasElement>().unwrap();
|
||||
canvas.set_width(width 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 {
|
||||
Some(ctx) => ctx,
|
||||
None => {
|
||||
|
@ -43,6 +43,10 @@ where
|
||||
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) {
|
||||
self.inner.require_frame(incremental);
|
||||
}
|
||||
@ -53,26 +57,37 @@ pub trait ProtocalImpl {
|
||||
fn do_input(&mut self, input: Vec<u8>);
|
||||
fn get_output(&mut self) -> Vec<ProtocalHandlerOutput>;
|
||||
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);
|
||||
}
|
||||
|
||||
pub struct StreamReader {
|
||||
inner: Vec<Vec<u8>>,
|
||||
remain: usize,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl StreamReader {
|
||||
pub fn new(bufs: Vec<Vec<u8>>) -> Self {
|
||||
Self { inner: bufs }
|
||||
Self {
|
||||
inner: bufs,
|
||||
remain: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append(&mut self, buf: Vec<u8>) {
|
||||
self.remain += buf.len();
|
||||
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) {
|
||||
let mut i = 0;
|
||||
let mut left = n;
|
||||
self.remain -= n;
|
||||
while i < n {
|
||||
if self.inner[0].len() > 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) {
|
||||
let mut i = 0;
|
||||
let mut left = n;
|
||||
self.remain -= n;
|
||||
while i < n {
|
||||
if self.inner[0].len() > left {
|
||||
out_buf[i..i + left].copy_from_slice(&self.inner[0][0..left]);
|
||||
|
@ -22,6 +22,19 @@ pub enum SecurityType {
|
||||
// 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 {
|
||||
Init,
|
||||
Handshake,
|
||||
@ -40,9 +53,10 @@ pub enum ServerMessage {
|
||||
|
||||
pub struct VncHandler {
|
||||
state: VncState,
|
||||
// supported_versions: Vec<u8>,
|
||||
supported_encodings: Vec<VncEncoding>,
|
||||
security_type: SecurityType,
|
||||
challenge: [u8; 16],
|
||||
buf_num: usize,
|
||||
reader: StreamReader,
|
||||
require: usize,
|
||||
width: u16,
|
||||
@ -60,9 +74,18 @@ impl ProtocalImpl for VncHandler {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
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,
|
||||
challenge: [0; 16],
|
||||
buf_num: 0,
|
||||
reader: StreamReader::new(Vec::with_capacity(10)),
|
||||
require: 12, // the handleshake message length
|
||||
width: 0,
|
||||
@ -78,16 +101,20 @@ impl ProtocalImpl for VncHandler {
|
||||
}
|
||||
|
||||
fn do_input(&mut self, input: Vec<u8>) {
|
||||
self.buf_num += input.len();
|
||||
// ConsoleService::info(&format!(
|
||||
// "VNC input {}, left {}, require {}",
|
||||
// input.len(),
|
||||
// self.buf_num,
|
||||
// self.reader.remain(),
|
||||
// self.require
|
||||
// ));
|
||||
self.reader.append(input);
|
||||
while self.buf_num >= self.require {
|
||||
while self.reader.remain() >= self.require {
|
||||
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
|
||||
}
|
||||
|
||||
fn set_resolution(&mut self, _width: u16, _height: u16) {
|
||||
// VNC client doen't support resolution change
|
||||
}
|
||||
|
||||
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 {
|
||||
self.framebuffer_update_request(incremental)
|
||||
}
|
||||
@ -141,55 +177,45 @@ impl ProtocalImpl for VncHandler {
|
||||
#[allow(dead_code)]
|
||||
impl VncHandler {
|
||||
fn read_u8(&mut self) -> u8 {
|
||||
self.buf_num -= 1;
|
||||
self.reader.read_u8()
|
||||
}
|
||||
|
||||
fn read_u16(&mut self) -> u16 {
|
||||
self.buf_num -= 2;
|
||||
self.reader.read_u16()
|
||||
}
|
||||
|
||||
fn read_u32(&mut self) -> u32 {
|
||||
self.buf_num -= 4;
|
||||
self.reader.read_u32()
|
||||
}
|
||||
|
||||
fn read_u64(&mut self) -> u64 {
|
||||
self.buf_num -= 8;
|
||||
self.reader.read_u64()
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
fn read_exact(&mut self, buf: &mut [u8], len: usize) {
|
||||
self.buf_num -= len;
|
||||
self.reader.read_exact(buf, len)
|
||||
}
|
||||
|
||||
fn read_string(&mut self, len: usize) -> String {
|
||||
self.buf_num -= len;
|
||||
self.reader.read_string(len)
|
||||
}
|
||||
|
||||
fn read_string_l8(&mut self) -> String {
|
||||
let len = self.read_u8() as usize;
|
||||
self.buf_num -= len;
|
||||
self.reader.read_string(len)
|
||||
}
|
||||
|
||||
fn read_string_l16(&mut self) -> String {
|
||||
let len = self.read_u16() as usize;
|
||||
self.buf_num -= len;
|
||||
self.reader.read_string(len)
|
||||
}
|
||||
|
||||
fn read_string_l32(&mut self) -> String {
|
||||
let len = self.read_u32() as usize;
|
||||
self.buf_num -= len;
|
||||
self.reader.read_string(len)
|
||||
}
|
||||
}
|
||||
@ -206,10 +232,38 @@ impl VncHandler {
|
||||
self.require = 25; // the minimal length of server_init message
|
||||
|
||||
// send client_init message
|
||||
let shared_flag = 0;
|
||||
let shared_flag = 1;
|
||||
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
|
||||
// 1 CARD8 3 message-type
|
||||
// 1 CARD8 incremental
|
||||
@ -262,6 +316,7 @@ impl VncHandler {
|
||||
}
|
||||
|
||||
fn do_authenticate(&mut self) {
|
||||
// ConsoleService::log(&format!("VNC: do_authenticate {}", self.reader.remain()));
|
||||
if self.security_type == SecurityType::Invalid {
|
||||
let auth_type = self.read_u32();
|
||||
match auth_type {
|
||||
@ -369,18 +424,19 @@ impl VncHandler {
|
||||
let width = self.read_u16();
|
||||
let height = self.read_u16();
|
||||
let encoding_type = self.read_u32();
|
||||
match encoding_type {
|
||||
0 => self.handle_raw_encoding(x, y, width, height),
|
||||
1 => self.handle_copy_rect_encoding(x, y, width, height),
|
||||
2 => self.handle_rre_encoding(x, y, width, height),
|
||||
4 => self.handle_corre_encoding(x, y, width, height),
|
||||
5 => self.handle_hextile_encoding(x, y, width, height),
|
||||
_ => {
|
||||
ConsoleService::log(&format!(
|
||||
"VNC: Unsupported encoding type {}",
|
||||
encoding_type
|
||||
));
|
||||
self.disconnect_with_err(VNC_FAILED)
|
||||
let encoding_enum = unsafe { std::mem::transmute(encoding_type) };
|
||||
match encoding_enum {
|
||||
VncEncoding::Raw => self.handle_raw_encoding(x, y, width, height),
|
||||
VncEncoding::CopyRect => self.handle_copy_rect_encoding(x, y, width, height),
|
||||
VncEncoding::RRE => self.handle_rre_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),
|
||||
VncEncoding::ZRLE => self.handle_zrle_encoding(x, y, width, height),
|
||||
VncEncoding::CursorPseudo => {
|
||||
self.handle_cursor_pseudo_encoding(x, y, width, height)
|
||||
}
|
||||
VncEncoding::DesktopSizePseudo => {
|
||||
self.handle_desktop_size_pseudo_encoding(x, y, width, height)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -517,11 +573,23 @@ impl VncHandler {
|
||||
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!()
|
||||
}
|
||||
|
||||
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!()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user