mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-04 10:11:27 +03:00
connection things
This commit is contained in:
17
src/capture.rs
Normal file
17
src/capture.rs
Normal file
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 thiserror::Error;
|
||||||
use tokio::net::UdpSocket;
|
use tokio::{net::UdpSocket, task::JoinSet};
|
||||||
use webrtc_dtls::{
|
use webrtc_dtls::{
|
||||||
config::{Config, ExtendedMasterSecretType},
|
config::{Config, ExtendedMasterSecretType},
|
||||||
conn::DTLSConn,
|
conn::DTLSConn,
|
||||||
@@ -14,6 +17,10 @@ pub(crate) enum LanMouseConnectionError {
|
|||||||
Bind(#[from] io::Error),
|
Bind(#[from] io::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Dtls(#[from] webrtc_dtls::Error),
|
Dtls(#[from] webrtc_dtls::Error),
|
||||||
|
#[error(transparent)]
|
||||||
|
Webrtc(#[from] webrtc_util::Error),
|
||||||
|
#[error("no ips associated with the client")]
|
||||||
|
NoIps,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct LanMouseConnection {}
|
pub(crate) struct LanMouseConnection {}
|
||||||
@@ -36,4 +43,62 @@ impl LanMouseConnection {
|
|||||||
Arc::new(DTLSConn::new(conn, config, true, None).await?);
|
Arc::new(DTLSConn::new(conn, config, true, None).await?);
|
||||||
Ok(dtls_conn)
|
Ok(dtls_conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn connect_any(
|
||||||
|
addrs: &[SocketAddr],
|
||||||
|
) -> Result<Arc<dyn Conn + Send + Sync>, 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<SocketAddr, Arc<dyn Conn + Send + Sync>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConnectionProxy {
|
||||||
|
fn find_conn(&self, addrs: &[SocketAddr]) -> Vec<Arc<dyn Conn + Send + Sync>> {
|
||||||
|
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::<Vec<_>>();
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ pub mod config;
|
|||||||
pub mod dns;
|
pub mod dns;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|
||||||
|
mod capture;
|
||||||
mod capture_test;
|
mod capture_test;
|
||||||
mod connect;
|
mod connect;
|
||||||
mod crypto;
|
mod crypto;
|
||||||
|
|||||||
@@ -134,7 +134,6 @@ impl Server {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (capture_tx, capture_rx) = channel(); /* requests for input capture */
|
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 */
|
let (dns_tx, dns_rx) = channel(); /* dns requests */
|
||||||
|
|
||||||
// udp task
|
// udp task
|
||||||
@@ -165,8 +164,9 @@ impl Server {
|
|||||||
}
|
}
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
log::debug!("handle frontend request: {request:?}");
|
log::debug!("received frontend request: {request:?}");
|
||||||
self.handle_request(&capture_tx.clone(), &emulation_tx.clone(), request, &dns_tx);
|
self.handle_request(&capture_tx.clone(), request);
|
||||||
|
log::debug!("handled frontend request");
|
||||||
}
|
}
|
||||||
_ = self.notifies.frontend_event_pending.notified() => {
|
_ = self.notifies.frontend_event_pending.notified() => {
|
||||||
while let Some(event) = {
|
while let Some(event) = {
|
||||||
@@ -254,7 +254,6 @@ impl Server {
|
|||||||
fn handle_request(
|
fn handle_request(
|
||||||
&self,
|
&self,
|
||||||
capture: &Sender<CaptureRequest>,
|
capture: &Sender<CaptureRequest>,
|
||||||
emulate: &Sender<EmulationRequest>,
|
|
||||||
event: FrontendRequest,
|
event: FrontendRequest,
|
||||||
dns: &Sender<ClientHandle>,
|
dns: &Sender<ClientHandle>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@@ -267,14 +266,14 @@ impl Server {
|
|||||||
}
|
}
|
||||||
FrontendRequest::Activate(handle, active) => {
|
FrontendRequest::Activate(handle, active) => {
|
||||||
if active {
|
if active {
|
||||||
self.activate_client(capture, emulate, handle);
|
self.activate_client(capture, handle);
|
||||||
} else {
|
} else {
|
||||||
self.deactivate_client(capture, emulate, handle);
|
self.deactivate_client(capture, handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FrontendRequest::ChangePort(port) => self.request_port_change(port),
|
FrontendRequest::ChangePort(port) => self.request_port_change(port),
|
||||||
FrontendRequest::Delete(handle) => {
|
FrontendRequest::Delete(handle) => {
|
||||||
self.remove_client(capture, emulate, handle);
|
self.remove_client(capture, handle);
|
||||||
self.notify_frontend(FrontendEvent::Deleted(handle));
|
self.notify_frontend(FrontendEvent::Deleted(handle));
|
||||||
}
|
}
|
||||||
FrontendRequest::Enumerate() => self.enumerate(),
|
FrontendRequest::Enumerate() => self.enumerate(),
|
||||||
@@ -285,7 +284,7 @@ impl Server {
|
|||||||
}
|
}
|
||||||
FrontendRequest::UpdatePort(handle, port) => self.update_port(handle, port),
|
FrontendRequest::UpdatePort(handle, port) => self.update_port(handle, port),
|
||||||
FrontendRequest::UpdatePosition(handle, pos) => {
|
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::ResolveDns(handle) => dns.send(handle).expect("channel closed"),
|
||||||
FrontendRequest::Sync => {
|
FrontendRequest::Sync => {
|
||||||
@@ -316,12 +315,8 @@ impl Server {
|
|||||||
handle
|
handle
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deactivate_client(
|
fn deactivate_client(&self, capture: &Sender<CaptureRequest>, handle: ClientHandle) {
|
||||||
&self,
|
log::debug!("deactivating client {handle}");
|
||||||
capture: &Sender<CaptureRequest>,
|
|
||||||
emulate: &Sender<EmulationRequest>,
|
|
||||||
handle: ClientHandle,
|
|
||||||
) {
|
|
||||||
match self.client_manager.borrow_mut().get_mut(handle) {
|
match self.client_manager.borrow_mut().get_mut(handle) {
|
||||||
None => return,
|
None => return,
|
||||||
Some((_, s)) if !s.active => return,
|
Some((_, s)) if !s.active => return,
|
||||||
@@ -329,17 +324,12 @@ impl Server {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let _ = capture.send(CaptureRequest::Destroy(handle));
|
let _ = capture.send(CaptureRequest::Destroy(handle));
|
||||||
let _ = emulate.send(EmulationRequest::Destroy(handle));
|
|
||||||
self.client_updated(handle);
|
self.client_updated(handle);
|
||||||
log::info!("deactivated client {handle}");
|
log::info!("deactivated client {handle}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn activate_client(
|
fn activate_client(&self, capture: &Sender<CaptureRequest>, handle: ClientHandle) {
|
||||||
&self,
|
log::debug!("activating client");
|
||||||
capture: &Sender<CaptureRequest>,
|
|
||||||
emulate: &Sender<EmulationRequest>,
|
|
||||||
handle: ClientHandle,
|
|
||||||
) {
|
|
||||||
/* deactivate potential other client at this position */
|
/* deactivate potential other client at this position */
|
||||||
let pos = match self.client_manager.borrow().get(handle) {
|
let pos = match self.client_manager.borrow().get(handle) {
|
||||||
None => return,
|
None => return,
|
||||||
@@ -349,7 +339,7 @@ impl Server {
|
|||||||
|
|
||||||
let other = self.client_manager.borrow_mut().find_client(pos);
|
let other = self.client_manager.borrow_mut().find_client(pos);
|
||||||
if let Some(other) = other {
|
if let Some(other) = other {
|
||||||
self.deactivate_client(capture, emulate, other);
|
self.deactivate_client(capture, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* activate the client */
|
/* activate the client */
|
||||||
@@ -359,21 +349,13 @@ impl Server {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* notify emulation, capture and frontends */
|
/* notify capture and frontends */
|
||||||
let _ = capture.send(CaptureRequest::Create(handle, to_capture_pos(pos)));
|
let _ = capture.send(CaptureRequest::Create(handle, to_capture_pos(pos)));
|
||||||
let _ = emulate.send(EmulationRequest::Create(handle));
|
|
||||||
|
|
||||||
self.client_updated(handle);
|
self.client_updated(handle);
|
||||||
|
|
||||||
log::info!("activated client {handle} ({pos})");
|
log::info!("activated client {handle} ({pos})");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_client(
|
fn remove_client(&self, capture: &Sender<CaptureRequest>, handle: ClientHandle) {
|
||||||
&self,
|
|
||||||
capture: &Sender<CaptureRequest>,
|
|
||||||
emulate: &Sender<EmulationRequest>,
|
|
||||||
handle: ClientHandle,
|
|
||||||
) {
|
|
||||||
let Some(active) = self
|
let Some(active) = self
|
||||||
.client_manager
|
.client_manager
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
@@ -385,7 +367,6 @@ impl Server {
|
|||||||
|
|
||||||
if active {
|
if active {
|
||||||
let _ = capture.send(CaptureRequest::Destroy(handle));
|
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<Vec<IpAddr>> {
|
||||||
|
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<u16> {
|
||||||
|
if let Some((c, _)) = self.client_manager.borrow().get(handle) {
|
||||||
|
Some(c.port)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_hostname(
|
fn update_hostname(
|
||||||
&self,
|
&self,
|
||||||
handle: ClientHandle,
|
handle: ClientHandle,
|
||||||
@@ -451,13 +448,7 @@ impl Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_pos(
|
fn update_pos(&self, handle: ClientHandle, capture: &Sender<CaptureRequest>, pos: Position) {
|
||||||
&self,
|
|
||||||
handle: ClientHandle,
|
|
||||||
capture: &Sender<CaptureRequest>,
|
|
||||||
emulate: &Sender<EmulationRequest>,
|
|
||||||
pos: Position,
|
|
||||||
) {
|
|
||||||
let (changed, active) = {
|
let (changed, active) = {
|
||||||
let mut client_manager = self.client_manager.borrow_mut();
|
let mut client_manager = self.client_manager.borrow_mut();
|
||||||
let Some((c, s)) = client_manager.get_mut(handle) else {
|
let Some((c, s)) = client_manager.get_mut(handle) else {
|
||||||
@@ -474,9 +465,9 @@ impl Server {
|
|||||||
|
|
||||||
// update state in event input emulator & input capture
|
// update state in event input emulator & input capture
|
||||||
if changed {
|
if changed {
|
||||||
self.deactivate_client(capture, emulate, handle);
|
self.deactivate_client(capture, handle);
|
||||||
if active {
|
if active {
|
||||||
self.activate_client(capture, emulate, handle);
|
self.activate_client(capture, handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,7 +522,13 @@ impl Server {
|
|||||||
self.active_client.replace(handle);
|
self.active_client.replace(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn active_addr(&self, handle: ClientHandle) -> Option<SocketAddr> {
|
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<SocketAddr> {
|
||||||
self.client_manager
|
self.client_manager
|
||||||
.borrow()
|
.borrow()
|
||||||
.get(handle)
|
.get(handle)
|
||||||
|
|||||||
Reference in New Issue
Block a user