diff --git a/src/capture.rs b/src/capture.rs new file mode 100644 index 0000000..02b41ee --- /dev/null +++ b/src/capture.rs @@ -0,0 +1,17 @@ +use crate::server::Server; + +pub(crate) struct Capture { + server: Server, +} + +impl Capture { + pub(crate) fn new(server: Server) -> Self { + Self { server } + } + + pub(crate) async fn run(&mut self, backend: input_capture::Backend) { + loop { + if let Err(e) = do_capture(backend) + } + } +} diff --git a/src/connect.rs b/src/connect.rs index 48262f1..3d24f4f 100644 --- a/src/connect.rs +++ b/src/connect.rs @@ -1,6 +1,9 @@ -use std::{io, net::SocketAddr, sync::Arc}; +use crate::server::Server; +use lan_mouse_ipc::{ClientHandle, DEFAULT_PORT}; +use lan_mouse_proto::{ProtoEvent, MAX_EVENT_SIZE}; +use std::{collections::HashMap, io, net::SocketAddr, sync::Arc}; use thiserror::Error; -use tokio::net::UdpSocket; +use tokio::{net::UdpSocket, task::JoinSet}; use webrtc_dtls::{ config::{Config, ExtendedMasterSecretType}, conn::DTLSConn, @@ -14,6 +17,10 @@ pub(crate) enum LanMouseConnectionError { Bind(#[from] io::Error), #[error(transparent)] Dtls(#[from] webrtc_dtls::Error), + #[error(transparent)] + Webrtc(#[from] webrtc_util::Error), + #[error("no ips associated with the client")] + NoIps, } pub(crate) struct LanMouseConnection {} @@ -36,4 +43,62 @@ impl LanMouseConnection { Arc::new(DTLSConn::new(conn, config, true, None).await?); Ok(dtls_conn) } + + pub(crate) async fn connect_any( + addrs: &[SocketAddr], + ) -> Result, LanMouseConnectionError> { + let mut joinset = JoinSet::new(); + for &addr in addrs { + joinset.spawn_local(Self::connect(addr)); + } + let conn = joinset.join_next().await; + conn.expect("no addrs to connect").expect("failed to join") + } +} + +struct ConnectionProxy { + server: Server, + conns: HashMap>, +} + +impl ConnectionProxy { + fn find_conn(&self, addrs: &[SocketAddr]) -> Vec> { + let mut conns = vec![]; + for addr in addrs { + if let Some(conn) = self.conns.get(&addr) { + conns.push(conn.clone()); + } + } + conns + } + + async fn send( + &self, + event: ProtoEvent, + handle: ClientHandle, + ) -> Result<(), LanMouseConnectionError> { + let (buf, len): ([u8; MAX_EVENT_SIZE], usize) = event.into(); + let buf = &buf[..len]; + if let Some(addr) = self.server.active_addr(handle) { + if let Some(conn) = self.conns.get(&addr) { + if let Ok(_) = conn.send(buf).await { + return Ok(()); + } + } + } + // sending did not work, figure out active conn. + if let Some(addrs) = self.server.get_ips(handle) { + let port = self.server.get_port(handle).unwrap_or(DEFAULT_PORT); + let addrs = addrs + .into_iter() + .map(|a| SocketAddr::new(a, port)) + .collect::>(); + let conn = LanMouseConnection::connect_any(&addrs).await?; + let addr = conn.remote_addr().expect("no remote addr"); + self.server.set_active_addr(handle, addr); + conn.send(buf).await?; + return Ok(()); + } + Err(LanMouseConnectionError::NoIps) + } } diff --git a/src/lib.rs b/src/lib.rs index 4094088..df771c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ pub mod config; pub mod dns; pub mod server; +mod capture; mod capture_test; mod connect; mod crypto; diff --git a/src/server.rs b/src/server.rs index bd0b7fd..874f871 100644 --- a/src/server.rs +++ b/src/server.rs @@ -134,7 +134,6 @@ impl Server { }; let (capture_tx, capture_rx) = channel(); /* requests for input capture */ - let (emulation_tx, emulation_rx) = channel(); /* emulation requests */ let (dns_tx, dns_rx) = channel(); /* dns requests */ // udp task @@ -165,8 +164,9 @@ impl Server { } None => break, }; - log::debug!("handle frontend request: {request:?}"); - self.handle_request(&capture_tx.clone(), &emulation_tx.clone(), request, &dns_tx); + log::debug!("received frontend request: {request:?}"); + self.handle_request(&capture_tx.clone(), request); + log::debug!("handled frontend request"); } _ = self.notifies.frontend_event_pending.notified() => { while let Some(event) = { @@ -254,7 +254,6 @@ impl Server { fn handle_request( &self, capture: &Sender, - emulate: &Sender, event: FrontendRequest, dns: &Sender, ) -> bool { @@ -267,14 +266,14 @@ impl Server { } FrontendRequest::Activate(handle, active) => { if active { - self.activate_client(capture, emulate, handle); + self.activate_client(capture, handle); } else { - self.deactivate_client(capture, emulate, handle); + self.deactivate_client(capture, handle); } } FrontendRequest::ChangePort(port) => self.request_port_change(port), FrontendRequest::Delete(handle) => { - self.remove_client(capture, emulate, handle); + self.remove_client(capture, handle); self.notify_frontend(FrontendEvent::Deleted(handle)); } FrontendRequest::Enumerate() => self.enumerate(), @@ -285,7 +284,7 @@ impl Server { } FrontendRequest::UpdatePort(handle, port) => self.update_port(handle, port), FrontendRequest::UpdatePosition(handle, pos) => { - self.update_pos(handle, capture, emulate, pos) + self.update_pos(handle, capture, pos); } FrontendRequest::ResolveDns(handle) => dns.send(handle).expect("channel closed"), FrontendRequest::Sync => { @@ -316,12 +315,8 @@ impl Server { handle } - fn deactivate_client( - &self, - capture: &Sender, - emulate: &Sender, - handle: ClientHandle, - ) { + fn deactivate_client(&self, capture: &Sender, handle: ClientHandle) { + log::debug!("deactivating client {handle}"); match self.client_manager.borrow_mut().get_mut(handle) { None => return, Some((_, s)) if !s.active => return, @@ -329,17 +324,12 @@ impl Server { }; let _ = capture.send(CaptureRequest::Destroy(handle)); - let _ = emulate.send(EmulationRequest::Destroy(handle)); self.client_updated(handle); log::info!("deactivated client {handle}"); } - fn activate_client( - &self, - capture: &Sender, - emulate: &Sender, - handle: ClientHandle, - ) { + fn activate_client(&self, capture: &Sender, handle: ClientHandle) { + log::debug!("activating client"); /* deactivate potential other client at this position */ let pos = match self.client_manager.borrow().get(handle) { None => return, @@ -349,7 +339,7 @@ impl Server { let other = self.client_manager.borrow_mut().find_client(pos); if let Some(other) = other { - self.deactivate_client(capture, emulate, other); + self.deactivate_client(capture, other); } /* activate the client */ @@ -359,21 +349,13 @@ impl Server { return; }; - /* notify emulation, capture and frontends */ + /* notify capture and frontends */ let _ = capture.send(CaptureRequest::Create(handle, to_capture_pos(pos))); - let _ = emulate.send(EmulationRequest::Create(handle)); - self.client_updated(handle); - log::info!("activated client {handle} ({pos})"); } - fn remove_client( - &self, - capture: &Sender, - emulate: &Sender, - handle: ClientHandle, - ) { + fn remove_client(&self, capture: &Sender, handle: ClientHandle) { let Some(active) = self .client_manager .borrow_mut() @@ -385,7 +367,6 @@ impl Server { if active { let _ = capture.send(CaptureRequest::Destroy(handle)); - let _ = emulate.send(EmulationRequest::Destroy(handle)); } } @@ -416,6 +397,22 @@ impl Server { } } + pub(crate) fn get_ips(&self, handle: ClientHandle) -> Option> { + if let Some((_, s)) = self.client_manager.borrow().get(handle) { + Some(s.ips.iter().copied().collect()) + } else { + None + } + } + + pub(crate) fn get_port(&self, handle: ClientHandle) -> Option { + if let Some((c, _)) = self.client_manager.borrow().get(handle) { + Some(c.port) + } else { + None + } + } + fn update_hostname( &self, handle: ClientHandle, @@ -451,13 +448,7 @@ impl Server { } } - fn update_pos( - &self, - handle: ClientHandle, - capture: &Sender, - emulate: &Sender, - pos: Position, - ) { + fn update_pos(&self, handle: ClientHandle, capture: &Sender, pos: Position) { let (changed, active) = { let mut client_manager = self.client_manager.borrow_mut(); let Some((c, s)) = client_manager.get_mut(handle) else { @@ -474,9 +465,9 @@ impl Server { // update state in event input emulator & input capture if changed { - self.deactivate_client(capture, emulate, handle); + self.deactivate_client(capture, handle); if active { - self.activate_client(capture, emulate, handle); + self.activate_client(capture, handle); } } } @@ -531,7 +522,13 @@ impl Server { self.active_client.replace(handle); } - fn active_addr(&self, handle: ClientHandle) -> Option { + pub(crate) fn set_active_addr(&self, handle: ClientHandle, addr: SocketAddr) { + if let Some((_, s)) = self.client_manager.borrow_mut().get_mut(handle) { + s.active_addr.replace(addr); + } + } + + pub(crate) fn active_addr(&self, handle: ClientHandle) -> Option { self.client_manager .borrow() .get(handle)