release capture if emulation disabled on target

This commit is contained in:
Ferdinand Schober
2024-09-28 19:18:54 +02:00
parent f6a7010d17
commit 1979f203d2
5 changed files with 42 additions and 14 deletions

View File

@@ -161,7 +161,7 @@ pub struct ClientState {
/// This should generally be the socket address where data /// This should generally be the socket address where data
/// was last received from. /// was last received from.
pub active_addr: Option<SocketAddr>, pub active_addr: Option<SocketAddr>,
/// tracks whether or not the client is responding to pings /// tracks whether or not the client is available for emulation
pub alive: bool, pub alive: bool,
/// ips from dns /// ips from dns
pub dns_ips: Vec<IpAddr>, pub dns_ips: Vec<IpAddr>,
@@ -239,7 +239,7 @@ pub enum FrontendRequest {
RemoveAuthorizedKey(String), RemoveAuthorizedKey(String),
} }
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
pub enum Status { pub enum Status {
#[default] #[default]
Disabled, Disabled,

View File

@@ -61,8 +61,8 @@ pub enum ProtoEvent {
/// Ping event for tracking unresponsive clients. /// Ping event for tracking unresponsive clients.
/// A client has to respond with [`ProtoEvent::Pong`]. /// A client has to respond with [`ProtoEvent::Pong`].
Ping, Ping,
/// Response to [`ProtoEvent::Ping`] /// Response to [`ProtoEvent::Ping`], true if emulation is enabled / available
Pong, Pong(bool),
} }
impl Display for ProtoEvent { impl Display for ProtoEvent {
@@ -73,7 +73,13 @@ impl Display for ProtoEvent {
ProtoEvent::Ack(s) => write!(f, "Ack({s})"), ProtoEvent::Ack(s) => write!(f, "Ack({s})"),
ProtoEvent::Input(e) => write!(f, "{e}"), ProtoEvent::Input(e) => write!(f, "{e}"),
ProtoEvent::Ping => write!(f, "ping"), ProtoEvent::Ping => write!(f, "ping"),
ProtoEvent::Pong => write!(f, "pong"), ProtoEvent::Pong(alive) => {
write!(
f,
"pong: {}",
if *alive { "alive" } else { "not available" }
)
}
} }
} }
} }
@@ -110,7 +116,7 @@ impl ProtoEvent {
}, },
}, },
ProtoEvent::Ping => EventType::Ping, ProtoEvent::Ping => EventType::Ping,
ProtoEvent::Pong => EventType::Pong, ProtoEvent::Pong(_) => EventType::Pong,
ProtoEvent::Enter(_) => EventType::Enter, ProtoEvent::Enter(_) => EventType::Enter,
ProtoEvent::Leave(_) => EventType::Leave, ProtoEvent::Leave(_) => EventType::Leave,
ProtoEvent::Ack(_) => EventType::Ack, ProtoEvent::Ack(_) => EventType::Ack,
@@ -164,7 +170,7 @@ impl TryFrom<[u8; MAX_EVENT_SIZE]> for ProtoEvent {
}, },
))), ))),
EventType::Ping => Ok(Self::Ping), EventType::Ping => Ok(Self::Ping),
EventType::Pong => Ok(Self::Pong), EventType::Pong => Ok(Self::Pong(decode_u8(&mut buf)? != 0)),
EventType::Enter => Ok(Self::Enter(decode_u8(&mut buf)?.try_into()?)), EventType::Enter => Ok(Self::Enter(decode_u8(&mut buf)?.try_into()?)),
EventType::Leave => Ok(Self::Leave(decode_u32(&mut buf)?)), EventType::Leave => Ok(Self::Leave(decode_u32(&mut buf)?)),
EventType::Ack => Ok(Self::Ack(decode_u32(&mut buf)?)), EventType::Ack => Ok(Self::Ack(decode_u32(&mut buf)?)),
@@ -228,7 +234,7 @@ impl From<ProtoEvent> for ([u8; MAX_EVENT_SIZE], usize) {
}, },
}, },
ProtoEvent::Ping => {} ProtoEvent::Ping => {}
ProtoEvent::Pong => {} ProtoEvent::Pong(alive) => encode_u8(buf, len, alive as u8),
ProtoEvent::Enter(pos) => encode_u8(buf, len, pos as u8), ProtoEvent::Enter(pos) => encode_u8(buf, len, pos as u8),
ProtoEvent::Leave(serial) => encode_u32(buf, len, serial), ProtoEvent::Leave(serial) => encode_u32(buf, len, serial),
ProtoEvent::Ack(serial) => encode_u32(buf, len, serial), ProtoEvent::Ack(serial) => encode_u32(buf, len, serial),

View File

@@ -224,27 +224,41 @@ impl ClientManager {
.collect() .collect()
} }
pub(crate) fn set_active_addr(&self, handle: u64, addr: Option<SocketAddr>) { pub(crate) fn set_active_addr(&self, handle: ClientHandle, addr: Option<SocketAddr>) {
if let Some((_, s)) = self.clients.borrow_mut().get_mut(handle as usize) { if let Some((_, s)) = self.clients.borrow_mut().get_mut(handle as usize) {
s.active_addr = addr; s.active_addr = addr;
} }
} }
pub(crate) fn active_addr(&self, handle: u64) -> Option<SocketAddr> { pub(crate) fn set_alive(&self, handle: ClientHandle, alive: bool) {
if let Some((_, s)) = self.clients.borrow_mut().get_mut(handle as usize) {
s.alive = alive;
}
}
pub(crate) fn active_addr(&self, handle: ClientHandle) -> Option<SocketAddr> {
self.clients self.clients
.borrow() .borrow()
.get(handle as usize) .get(handle as usize)
.and_then(|(_, s)| s.active_addr) .and_then(|(_, s)| s.active_addr)
} }
pub(crate) fn get_port(&self, handle: u64) -> Option<u16> { pub(crate) fn alive(&self, handle: ClientHandle) -> bool {
self.clients
.borrow()
.get(handle as usize)
.map(|(_, s)| s.alive)
.unwrap_or(false)
}
pub(crate) fn get_port(&self, handle: ClientHandle) -> Option<u16> {
self.clients self.clients
.borrow() .borrow()
.get(handle as usize) .get(handle as usize)
.map(|(c, _)| c.port) .map(|(c, _)| c.port)
} }
pub(crate) fn get_ips(&self, handle: u64) -> Option<HashSet<IpAddr>> { pub(crate) fn get_ips(&self, handle: ClientHandle) -> Option<HashSet<IpAddr>> {
self.clients self.clients
.borrow() .borrow()
.get(handle as usize) .get(handle as usize)

View File

@@ -33,6 +33,8 @@ pub(crate) enum LanMouseConnectionError {
Webrtc(#[from] webrtc_util::Error), Webrtc(#[from] webrtc_util::Error),
#[error("not connected")] #[error("not connected")]
NotConnected, NotConnected,
#[error("emulation is disabled on the target device")]
TargetEmulationDisabled,
} }
async fn connect( async fn connect(
@@ -104,6 +106,9 @@ impl LanMouseConnection {
conns.get(&addr).cloned() conns.get(&addr).cloned()
}; };
if let Some(conn) = conn { if let Some(conn) = conn {
if !self.server.client_manager.alive(handle) {
return Err(LanMouseConnectionError::TargetEmulationDisabled);
}
log::trace!("{event} >->->->->- {addr}"); log::trace!("{event} >->->->->- {addr}");
match conn.send(buf).await { match conn.send(buf).await {
Ok(_) => return Ok(()), Ok(_) => return Ok(()),
@@ -220,7 +225,10 @@ async fn receive_loop(
while let Ok(_) = conn.recv(&mut buf).await { while let Ok(_) = conn.recv(&mut buf).await {
if let Ok(event) = buf.try_into() { if let Ok(event) = buf.try_into() {
match event { match event {
ProtoEvent::Pong => server.client_manager.set_active_addr(handle, Some(addr)), ProtoEvent::Pong(b) => {
server.client_manager.set_active_addr(handle, Some(addr));
server.client_manager.set_alive(handle, b);
}
event => tx.send((handle, event)).expect("channel closed"), event => tx.send((handle, event)).expect("channel closed"),
} }
} }

View File

@@ -55,7 +55,7 @@ impl Emulation {
listener.reply(addr, ProtoEvent::Ack(0)).await; listener.reply(addr, ProtoEvent::Ack(0)).await;
} }
ProtoEvent::Input(event) => emulation_proxy.consume(event, addr), ProtoEvent::Input(event) => emulation_proxy.consume(event, addr),
ProtoEvent::Ping => listener.reply(addr, ProtoEvent::Pong).await, ProtoEvent::Ping => listener.reply(addr, ProtoEvent::Pong(server.emulation_status.get() == Status::Enabled)).await,
_ => {} _ => {}
} }
} }