2022-12-03 21:47:09 -08:00
|
|
|
use netstat2::{AddressFamilyFlags, ProtocolFlags, ProtocolSocketInfo};
|
2023-05-02 15:24:35 -07:00
|
|
|
use tauri::Manager;
|
2022-12-20 13:01:44 -08:00
|
|
|
use sysinfo::{System, SystemExt, Pid, PidExt, ProcessExt};
|
2022-12-19 16:20:46 -08:00
|
|
|
use serde::{Serialize, Deserialize};
|
2022-12-03 21:47:09 -08:00
|
|
|
|
2023-05-02 15:24:35 -07:00
|
|
|
use crate::{
|
|
|
|
errors::*,
|
|
|
|
config::AppConfig,
|
|
|
|
state::AppState,
|
|
|
|
};
|
2022-12-19 16:20:46 -08:00
|
|
|
|
|
|
|
|
2022-12-22 16:36:32 -08:00
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
2022-12-19 16:20:46 -08:00
|
|
|
pub struct Client {
|
|
|
|
pub pid: u32,
|
|
|
|
pub exe: String,
|
|
|
|
}
|
2022-12-03 21:47:09 -08:00
|
|
|
|
|
|
|
|
2023-05-02 15:24:35 -07:00
|
|
|
async fn get_associated_pids(local_port: u16) -> Result<Vec<u32>, netstat2::error::Error> {
|
|
|
|
let state = crate::APP.get().unwrap().state::<AppState>();
|
|
|
|
let AppConfig {
|
|
|
|
listen_addr: app_listen_addr,
|
|
|
|
listen_port: app_listen_port,
|
|
|
|
..
|
|
|
|
} = *state.config.read().await;
|
|
|
|
|
2022-12-20 16:11:49 -08:00
|
|
|
let sockets_iter = netstat2::iterate_sockets_info(
|
2022-12-03 21:47:09 -08:00
|
|
|
AddressFamilyFlags::IPV4,
|
|
|
|
ProtocolFlags::TCP
|
|
|
|
)?;
|
2022-12-20 16:11:49 -08:00
|
|
|
for item in sockets_iter {
|
2022-12-03 21:47:09 -08:00
|
|
|
let sock_info = item?;
|
|
|
|
let proto_info = match sock_info.protocol_socket_info {
|
|
|
|
ProtocolSocketInfo::Tcp(tcp_info) => tcp_info,
|
|
|
|
ProtocolSocketInfo::Udp(_) => {continue;}
|
|
|
|
};
|
|
|
|
|
|
|
|
if proto_info.local_port == local_port
|
2023-05-02 15:24:35 -07:00
|
|
|
&& proto_info.remote_port == app_listen_port
|
|
|
|
&& proto_info.local_addr == app_listen_addr
|
|
|
|
&& proto_info.remote_addr == app_listen_addr
|
2022-12-03 21:47:09 -08:00
|
|
|
{
|
|
|
|
return Ok(sock_info.associated_pids)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(vec![])
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-12-20 16:11:49 -08:00
|
|
|
// Theoretically, on some systems, multiple processes can share a socket
|
2023-05-02 15:24:35 -07:00
|
|
|
pub async fn get_clients(local_port: u16) -> Result<Vec<Option<Client>>, ClientInfoError> {
|
2022-12-13 16:50:44 -08:00
|
|
|
let mut clients = Vec::new();
|
2022-12-03 21:47:09 -08:00
|
|
|
let mut sys = System::new();
|
2023-05-02 15:24:35 -07:00
|
|
|
for p in get_associated_pids(local_port).await? {
|
2022-12-20 13:01:44 -08:00
|
|
|
let pid = Pid::from_u32(p);
|
2022-12-03 21:47:09 -08:00
|
|
|
sys.refresh_process(pid);
|
|
|
|
let proc = sys.process(pid)
|
2022-12-21 11:01:34 -08:00
|
|
|
.ok_or(ClientInfoError::ProcessNotFound)?;
|
2022-12-03 21:47:09 -08:00
|
|
|
|
2022-12-13 16:50:44 -08:00
|
|
|
let client = Client {
|
|
|
|
pid: p,
|
|
|
|
exe: proc.exe().to_string_lossy().into_owned(),
|
|
|
|
};
|
2022-12-20 16:11:49 -08:00
|
|
|
clients.push(Some(client));
|
2022-12-13 16:50:44 -08:00
|
|
|
}
|
2022-12-20 16:11:49 -08:00
|
|
|
|
|
|
|
if clients.is_empty() {
|
|
|
|
clients.push(None);
|
|
|
|
}
|
|
|
|
|
2022-12-13 16:50:44 -08:00
|
|
|
Ok(clients)
|
2022-12-03 21:47:09 -08:00
|
|
|
}
|