mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-11 12:21:29 +03:00
simplify Service
This commit is contained in:
118
src/service.rs
118
src/service.rs
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user