Skip to content

Commit

Permalink
update: server-client handshake
Browse files Browse the repository at this point in the history
  • Loading branch information
luftaquila committed Apr 29, 2024
1 parent 69549da commit 19545a7
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/bin/transistor-client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn main() -> Result<(), Error> {

client.start()?;

loop { }
loop {}

Ok(())
}
4 changes: 2 additions & 2 deletions src/bin/transistor-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ fn main() -> Result<(), Error> {
let client_config = config_dir!().join("authorized_clients.json");
let server = Server::new()?;

server.start(PORT, client_config);
server.start(client_config);

println!("{:?}", server);

loop { }
loop {}

Ok(())
}
49 changes: 39 additions & 10 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use std::{mem, u32};
use std::{fs, net::TcpStream};
use std::collections::HashMap;
use std::io::{Error, ErrorKind::*, Read, Write};
use std::{fs, net::TcpStream};
use std::{mem, u32};

use bincode::deserialize;
use display_info::DisplayInfo;
use serde::{Deserialize, Serialize};

use crate::{config_dir, tcp_stream_read, tcp_stream_write};
use crate::display::*;
use crate::*;

pub type Cid = u32;

Expand All @@ -28,25 +32,50 @@ impl Client {
})
}

pub fn start(&mut self) -> Result<(), Error>{
/* send cid to server */
pub fn start(&mut self) -> Result<(), Error> {
/* transmit cid to server */
tcp_stream_write!(self.tcp, self.cid);

/* get display counts; 0 is unauthorized */
let mut buffer = [0u8; mem::size_of::<u32>()];
/* receive display counts; 0 is unauthorized */
let mut buffer = vec![0u8; mem::size_of::<u32>()];
tcp_stream_read!(self.tcp, buffer);
let disp_cnt: u32 = bincode::deserialize(&buffer).unwrap();

println!("cnt: {}", disp_cnt);
let disp_cnt: u32 = deserialize(&buffer).unwrap();

if disp_cnt < 1 {
return Err(Error::new(NotConnected, "[ERR] authorization failed"));
}

/* receive server's current display configurations */
tcp_stream_read_resize!(self.tcp, buffer);
let server_disp_map: HashMap<Did, Display> = deserialize(&buffer).unwrap();
let server_disp: Vec<Display> = server_disp_map.values().cloned().collect();

/* configure our displays' attach position */
let displays: Vec<Display> = set_display_position(server_disp);
tcp_stream_write!(self.tcp, displays);

/* wait server ack */
tcp_stream_read!(self.tcp, buffer);

if let HandshakeStatus::HandshakeErr = deserialize(&buffer).unwrap() {
return Err(Error::new(InvalidData, "[ERR] display attach request rejected"));
};

Ok(())
}
}

fn set_display_position(server_disp: Vec<Display>) -> Vec<Display> {
let system_disp: Vec<Display> = DisplayInfo::all()
.expect("[ERR] failed to get system displays")
.into_iter()
.map(Display::from)
.collect();

// TODO
system_disp
}

fn load_or_generate_cid() -> Result<Cid, Error> {
let cid_file = config_dir!().join("cid");

Expand Down
3 changes: 2 additions & 1 deletion src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub struct AssignedDisplays {

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Display {
pub name: String,
pub id: Did,
pub x: i32,
pub y: i32,
Expand All @@ -58,7 +59,7 @@ pub struct Display {
impl From<DisplayInfo> for Display {
fn from(item: DisplayInfo) -> Self {
Display {
// name - not meaningful on every platform
name: item.name,
id: rand::random(),
// raw_handle - cannot serialize
x: item.x,
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
mod utils;
mod display;
mod client;
mod display;
mod server;
mod utils;

pub use utils::*;
pub use display::*;
pub use client::*;
pub use display::*;
pub use server::*;
pub use utils::*;

pub const PORT: u16 = 2426;
pub const MAX_DISPLAYS: u32 = 128;
63 changes: 40 additions & 23 deletions src/server.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
use std::collections::HashMap;
use std::fs;
use std::mem;
use std::io::{Error, ErrorKind::*, Read, Write};
use std::mem;
use std::net::{TcpListener, TcpStream};
use std::path::PathBuf;
use std::sync::{mpsc, Arc, Mutex};
use std::sync::{mpsc, Arc, RwLock};
use std::thread;

use bincode::deserialize;
use display_info::DisplayInfo;
use mouce::Mouse;

use crate::tcp_stream_write;
use crate::{client::*, tcp_stream_read};
use crate::client::*;
use crate::display::*;
use crate::*;

#[derive(Debug)]
pub struct Server {
clients: Arc<Mutex<HashMap<Cid, Client>>>,
displays: HashMap<Did, Display>,
clients: Arc<RwLock<HashMap<Cid, Client>>>,
displays: Arc<RwLock<HashMap<Did, Display>>>,
disp_ids: AssignedDisplays,
current: Did,
}
Expand All @@ -36,10 +37,12 @@ impl Server {

let system = disp.iter().map(|x| x.id).collect();
let current = disp.iter().find(|x| x.is_primary).unwrap_or(&disp[0]).id;
let displays = disp.into_iter().map(|x| (x.id, x)).collect();
let displays = Arc::new(RwLock::new(disp.into_iter().map(|x| (x.id, x)).collect()));

// TODO: set warpzones

Ok(Server {
clients: Arc::new(Mutex::new(HashMap::new())),
clients: Arc::new(RwLock::new(HashMap::new())),
displays,
disp_ids: AssignedDisplays {
system,
Expand All @@ -49,43 +52,57 @@ impl Server {
})
}

pub fn start(&self, port: u16, client_config: PathBuf) {
pub fn start(&self, client_config: PathBuf) {
// let (tx, rx) = mpsc::channel();
let clients = self.clients.clone();
let displays = self.displays.clone();

thread::spawn(move || {
handle_client(port, clients, client_config);
handle_client(clients, displays, client_config);
});
}
}

fn handle_client(port: u16, clients: Arc<Mutex<HashMap<Cid, Client>>>, config: PathBuf) -> Result<(), Error> {
let tcp = TcpListener::bind(("0.0.0.0", port)).expect("[ERR] TCP binding failed");
fn handle_client(
clients: Arc<RwLock<HashMap<Cid, Client>>>,
displays: Arc<RwLock<HashMap<Did, Display>>>,
config: PathBuf,
) -> Result<(), Error> {
let tcp = TcpListener::bind(("0.0.0.0", PORT)).expect("[ERR] TCP binding failed");
let authorized = authorized_clients(config).expect("[ERR] failed to read client config");

for mut stream in tcp.incoming().filter_map(Result::ok) {
/* read cid from remote client */
let mut buffer = [0u8; mem::size_of::<Cid>()];
let mut buffer = vec![0u8; mem::size_of::<Cid>()];
tcp_stream_read!(stream, buffer);
let cid = bincode::deserialize(&buffer).unwrap();

println!("incoming cid: {}", cid);
let cid = deserialize(&buffer).unwrap();

/* reject not known client */
if !authorized.contains(&cid) {
tcp_stream_write!(stream, 0);
}

let client = Client {
tcp: stream,
cid,
};
/* transmit display counts to client */
tcp_stream_write!(stream, displays.read().unwrap().len() as u32);

/* transmit current displays */
let disp = displays.read().unwrap();
tcp_stream_write!(stream, *disp);

/* receive display attach request */
tcp_stream_read_resize!(stream, buffer);
let client_disp: Vec<Display> = deserialize(&buffer).unwrap();

clients.lock().unwrap().insert(cid, client);
/* calculate warpzones for new displays */
// TODO

/* send current displays */
/* transmit ack */
tcp_stream_write!(stream, HandshakeStatus::HandshakeOk);

/* receive attach request */
/* add accepted client */
// TODO
let client = Client { tcp: stream, cid };
clients.write().unwrap().insert(cid, client);
}

Ok(())
Expand Down
27 changes: 24 additions & 3 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
use display_info::DisplayInfo;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
pub enum HandshakeStatus {
HandshakeOk,
HandshakeErr
}

pub fn print_displays() {
println!("[INF] detected system displays:");
Expand All @@ -23,15 +30,29 @@ macro_rules! config_dir {

#[macro_export]
macro_rules! tcp_stream_read {
($stream:expr, $buffer:expr) => {
($stream:expr, $buffer:expr) => {{
let mut size = [0u8; 4];
$stream.read_exact(&mut size)?;

let len = u32::from_be_bytes(size) as usize;
$stream.read_exact(&mut $buffer[..len])?;

len
}};
}

#[macro_export]
macro_rules! tcp_stream_read_resize {
($stream:expr, $buffer:expr) => {{
let mut size = [0u8; 4];
$stream.read_exact(&mut size)?;

let len = u32::from_be_bytes(size) as usize;
$buffer.resize(len, 0);
$stream.read_exact(&mut $buffer)?;

$stream.read_exact(&mut $buffer[..len])?;
};
len
}};
}

#[macro_export]
Expand Down

0 comments on commit 19545a7

Please sign in to comment.