diff --git a/src/service.rs b/src/service.rs index 590704a..9a0372f 100644 --- a/src/service.rs +++ b/src/service.rs @@ -16,11 +16,9 @@ use lan_mouse_ipc::{ }; use log; use std::{ - cell::{Cell, RefCell}, collections::{HashMap, HashSet, VecDeque}, io, net::{IpAddr, SocketAddr}, - rc::Rc, sync::{Arc, RwLock}, }; use thiserror::Error; @@ -50,21 +48,20 @@ pub struct Incoming { pos: Position, } -#[derive(Clone)] pub struct Service { authorized_keys: Arc>>, pub(crate) client_manager: ClientManager, - port: Rc>, + port: u16, public_key_fingerprint: String, - frontend_event_pending: Rc, - pub(crate) config: Rc, - pending_frontend_events: Rc>>, - capture_status: Rc>, - pub(crate) emulation_status: Rc>, + frontend_event_pending: Notify, + pub(crate) config: Config, + pending_frontend_events: VecDeque, + capture_status: Status, + pub(crate) emulation_status: Status, /// keep track of registered connections to avoid duplicate barriers - incoming_conns: Rc>>, + incoming_conns: HashSet, /// map from capture handle to connection info - incoming_conn_info: Rc>>, + incoming_conn_info: HashMap, cert: Certificate, next_trigger_handle: u64, } @@ -72,7 +69,6 @@ pub struct Service { impl Service { pub async fn new(config: Config) -> Result { let client_manager = ClientManager::default(); - let port = Rc::new(Cell::new(config.port)); for client in config.get_clients() { let config = ClientConfig { hostname: client.hostname, @@ -95,15 +91,16 @@ impl Service { let cert = crypto::load_or_generate_key_and_cert(&config.cert_path)?; let public_key_fingerprint = crypto::certificate_fingerprint(&cert); + let port = config.port; let service = Self { authorized_keys: Arc::new(RwLock::new(config.authorized_fingerprints.clone())), cert, public_key_fingerprint, - config: Rc::new(config), + config, client_manager, frontend_event_pending: Default::default(), port, - pending_frontend_events: Rc::new(RefCell::new(VecDeque::new())), + pending_frontend_events: Default::default(), capture_status: Default::default(), emulation_status: Default::default(), incoming_conn_info: Default::default(), @@ -172,10 +169,10 @@ impl Service { } } FrontendRequest::ChangePort(port) => { - if self.port.get() != port { + if self.port != port { emulation.request_port_change(port); } else { - self.notify_frontend(FrontendEvent::PortChanged(self.port.get(), None)); + self.notify_frontend(FrontendEvent::PortChanged(self.port, None)); } } FrontendRequest::Delete(handle) => { @@ -199,15 +196,14 @@ impl Service { } FrontendRequest::Sync => { self.enumerate(); - self.notify_frontend(FrontendEvent::EmulationStatus(self.emulation_status.get())); - self.notify_frontend(FrontendEvent::CaptureStatus(self.capture_status.get())); - self.notify_frontend(FrontendEvent::PortChanged(self.port.get(), None)); + self.notify_frontend(FrontendEvent::EmulationStatus(self.emulation_status)); + self.notify_frontend(FrontendEvent::CaptureStatus(self.capture_status)); + self.notify_frontend(FrontendEvent::PortChanged(self.port, None)); self.notify_frontend(FrontendEvent::PublicKeyFingerprint( self.public_key_fingerprint.clone(), )); - self.notify_frontend(FrontendEvent::AuthorizedUpdated( - self.authorized_keys.read().expect("lock").clone(), - )); + let keys = self.authorized_keys.read().expect("lock").clone(); + self.notify_frontend(FrontendEvent::AuthorizedUpdated(keys)); } FrontendRequest::AuthorizeKey(desc, fp) => { self.add_authorized_key(desc, fp); @@ -218,30 +214,25 @@ impl Service { } } _ = self.frontend_event_pending.notified() => { - while let Some(event) = { - /* need to drop borrow before next iteration! */ - let event = self.pending_frontend_events.borrow_mut().pop_front(); - event - } { + while let Some(event) = self.pending_frontend_events.pop_front() { frontend_listener.broadcast(event).await; } }, event = emulation.event() => match event { EmulationEvent::Connected { addr, pos, fingerprint } => { // check if already registered - if !self.incoming_conns.borrow_mut().contains(&addr) { + if !self.incoming_conns.contains(&addr) { self.add_incoming(addr, pos, fingerprint.clone(), &capture); self.notify_frontend(FrontendEvent::IncomingConnected(fingerprint, addr, pos)); } else { let handle = self .incoming_conn_info - .borrow() .iter() .find(|(_, incoming)| incoming.addr == addr) .map(|(k, _)| *k) .expect("no such client"); let mut changed = false; - if let Some(incoming) = self.incoming_conn_info.borrow_mut().get_mut(&handle) { + if let Some(incoming) = self.incoming_conn_info.get_mut(&handle) { if incoming.fingerprint != fingerprint { incoming.fingerprint = fingerprint.clone(); changed = true; @@ -266,17 +257,17 @@ impl Service { } EmulationEvent::PortChanged(port) => match port { Ok(port) => { - self.port.replace(port); + self.port = port; self.notify_frontend(FrontendEvent::PortChanged(port, None)); }, - Err(e) => self.notify_frontend(FrontendEvent::PortChanged(self.port.get(), Some(format!("{e}")))), + Err(e) => self.notify_frontend(FrontendEvent::PortChanged(self.port, Some(format!("{e}")))), } EmulationEvent::EmulationDisabled => { - self.emulation_status.replace(Status::Disabled); + self.emulation_status = Status::Disabled; self.notify_frontend(FrontendEvent::EmulationStatus(Status::Disabled)); }, EmulationEvent::EmulationEnabled => { - self.emulation_status.replace(Status::Enabled); + self.emulation_status = Status::Enabled; self.notify_frontend(FrontendEvent::EmulationStatus(Status::Enabled)); }, EmulationEvent::ReleaseNotify => capture.release(), @@ -285,16 +276,16 @@ impl Service { ICaptureEvent::CaptureBegin(handle) => { // we entered the capture zone for an incoming connection // => notify it that its capture should be released - if let Some(incoming) = self.incoming_conn_info.borrow().get(&handle) { + if let Some(incoming) = self.incoming_conn_info.get(&handle) { emulation.send_leave_event(incoming.addr); } } ICaptureEvent::CaptureDisabled => { - self.capture_status.replace(Status::Disabled); + self.capture_status = Status::Disabled; self.notify_frontend(FrontendEvent::CaptureStatus(Status::Disabled)); } ICaptureEvent::CaptureEnabled => { - self.capture_status.replace(Status::Enabled); + self.capture_status = Status::Enabled; self.notify_frontend(FrontendEvent::CaptureStatus(Status::Enabled)); } ICaptureEvent::ClientEntered(handle) => { @@ -345,8 +336,8 @@ impl Service { let handle = Self::ENTER_HANDLE_BEGIN + self.next_trigger_handle; self.next_trigger_handle += 1; capture.create(handle, pos, CaptureType::EnterOnly); - self.incoming_conns.borrow_mut().insert(addr); - self.incoming_conn_info.borrow_mut().insert( + self.incoming_conns.insert(addr); + self.incoming_conn_info.insert( handle, Incoming { fingerprint, @@ -359,47 +350,43 @@ impl Service { fn remove_incoming(&mut self, addr: SocketAddr, capture: &Capture) -> Option { let handle = self .incoming_conn_info - .borrow() .iter() .find(|(_, incoming)| incoming.addr == addr) .map(|(k, _)| *k)?; capture.destroy(handle); - self.incoming_conns.borrow_mut().remove(&addr); + self.incoming_conns.remove(&addr); self.incoming_conn_info - .borrow_mut() .remove(&handle) .map(|incoming| incoming.addr) } - fn notify_frontend(&self, event: FrontendEvent) { - self.pending_frontend_events.borrow_mut().push_back(event); + fn notify_frontend(&mut self, event: FrontendEvent) { + self.pending_frontend_events.push_back(event); self.frontend_event_pending.notify_one(); } - pub(crate) fn client_updated(&self, handle: ClientHandle) { + pub(crate) fn client_updated(&mut self, handle: ClientHandle) { self.notify_frontend(FrontendEvent::Changed(handle)); } - fn add_authorized_key(&self, desc: String, fp: String) { + fn add_authorized_key(&mut self, desc: String, fp: String) { self.authorized_keys.write().expect("lock").insert(fp, desc); - self.notify_frontend(FrontendEvent::AuthorizedUpdated( - self.authorized_keys.read().expect("lock").clone(), - )); + let keys = self.authorized_keys.read().expect("lock").clone(); + self.notify_frontend(FrontendEvent::AuthorizedUpdated(keys)); } - fn remove_authorized_key(&self, fp: String) { + fn remove_authorized_key(&mut self, fp: String) { self.authorized_keys.write().expect("lock").remove(&fp); - self.notify_frontend(FrontendEvent::AuthorizedUpdated( - self.authorized_keys.read().expect("lock").clone(), - )); + let keys = self.authorized_keys.read().expect("lock").clone(); + self.notify_frontend(FrontendEvent::AuthorizedUpdated(keys)); } - fn enumerate(&self) { + fn enumerate(&mut self) { let clients = self.client_manager.get_client_states(); self.notify_frontend(FrontendEvent::Enumerate(clients)); } - fn add_client(&self) -> ClientHandle { + fn add_client(&mut self) -> ClientHandle { let handle = self.client_manager.add_client(); log::info!("added client {handle}"); let (c, s) = self.client_manager.get_state(handle).unwrap(); @@ -407,7 +394,7 @@ impl Service { handle } - fn deactivate_client(&self, capture: &Capture, handle: ClientHandle) { + fn deactivate_client(&mut self, capture: &Capture, handle: ClientHandle) { log::debug!("deactivating client {handle}"); if self.client_manager.deactivate_client(handle) { capture.destroy(handle); @@ -416,7 +403,7 @@ impl Service { } } - fn activate_client(&self, capture: &Capture, handle: ClientHandle) { + fn activate_client(&mut self, capture: &Capture, handle: ClientHandle) { log::debug!("activating client"); /* deactivate potential other client at this position */ let Some(pos) = self.client_manager.get_pos(handle) else { @@ -448,17 +435,22 @@ impl Service { } } - fn update_fix_ips(&self, handle: ClientHandle, fix_ips: Vec) { + fn update_fix_ips(&mut self, handle: ClientHandle, fix_ips: Vec) { self.client_manager.set_fix_ips(handle, fix_ips); self.client_updated(handle); } - pub(crate) fn update_dns_ips(&self, handle: ClientHandle, dns_ips: Vec) { + pub(crate) fn update_dns_ips(&mut self, handle: ClientHandle, dns_ips: Vec) { self.client_manager.set_dns_ips(handle, dns_ips); self.client_updated(handle); } - fn update_hostname(&self, handle: ClientHandle, hostname: Option, dns: &DnsResolver) { + fn update_hostname( + &mut self, + handle: ClientHandle, + hostname: Option, + dns: &DnsResolver, + ) { if self.client_manager.set_hostname(handle, hostname.clone()) { if let Some(hostname) = hostname { dns.resolve(handle, hostname); @@ -471,7 +463,7 @@ impl Service { self.client_manager.set_port(handle, port); } - fn update_pos(&self, handle: ClientHandle, capture: &Capture, pos: Position) { + fn update_pos(&mut self, handle: ClientHandle, capture: &Capture, pos: Position) { // update state in event input emulator & input capture if self.client_manager.set_pos(handle, pos) { self.deactivate_client(capture, handle); @@ -479,7 +471,7 @@ impl Service { } } - fn broadcast_client(&self, handle: ClientHandle) { + fn broadcast_client(&mut self, handle: ClientHandle) { let event = if let Some((config, state)) = self.client_manager.get_state(handle) { FrontendEvent::State(handle, config, state) } else { @@ -488,7 +480,7 @@ impl Service { self.notify_frontend(event); } - pub(crate) fn set_resolving(&self, handle: ClientHandle, status: bool) { + pub(crate) fn set_resolving(&mut self, handle: ClientHandle, status: bool) { self.client_manager.set_resolving(handle, status); self.client_updated(handle); }