simplify Service

This commit is contained in:
Ferdinand Schober
2024-11-08 18:40:10 +01:00
parent 6dfd5d97a4
commit 809fbbf453

View File

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