icmp pinging + deleting

This commit is contained in:
2026-06-27 20:31:52 -05:00
parent 143c21305a
commit 914c9fbac8
6 changed files with 323 additions and 36 deletions
+8
View File
@@ -45,3 +45,11 @@ pub fn get_apps(conn: &mut SqliteConnection) -> Vec<models::App> {
.load::<models::App>(conn)
.expect("Error loading apps")
}
pub fn delete_app(conn: &mut SqliteConnection, app_id: &str) -> usize {
use crate::db::schema::app::dsl::*;
diesel::delete(app.filter(id.eq(app_id)))
.execute(conn)
.expect("Error deleting app")
}
+64 -4
View File
@@ -1,8 +1,49 @@
use crate::db::{create_app, delete_app, establish_connection, get_apps};
use db::models::App;
use crate::db::{create_app, establish_connection, get_apps};
use ping_async::IcmpEchoRequestor;
use std::net::IpAddr;
use std::time::Duration;
use tokio::net::lookup_host;
mod db;
/// Pings a target (domain or IP) on a given port with a 5-second timeout.
/// Returns true if successful, false otherwise.
async fn ping_target(address: &str) -> bool {
// 1. Resolve host domain to an IP address (ICMP needs an explicit IP)
// If it's already an IP string (e.g. "192.168.1.10"), lookup_host still parses it fine if appended with a dummy port
let target_host = if address.contains(':') {
address.to_string()
} else {
format!("{}:0", address)
};
let Ok(mut addresses) = lookup_host(&target_host).await else {
return false;
};
let Some(socket_addr) = addresses.next() else {
return false;
};
let ip_target: IpAddr = socket_addr.ip();
// 2. Configure unprivileged ICMP requestor
let timeout = Some(Duration::from_secs(2));
let pinger = match IcmpEchoRequestor::new(ip_target, None, None, timeout) {
Ok(p) => p,
Err(_) => return false,
};
// 3. Send ICMP Echo request asynchronously
match pinger.send().await {
Ok(reply) => {
// Check if the status returned is a valid success response
matches!(reply.status(), ping_async::IcmpEchoStatus::Success)
}
Err(_) => false,
}
}
#[tauri::command]
fn new_app(name: &str, address: &str, description: Option<&str>, ssh_address: Option<&str>) -> App {
let mut conn = &mut establish_connection();
@@ -13,7 +54,7 @@ fn new_app(name: &str, address: &str, description: Option<&str>, ssh_address: Op
}
#[tauri::command]
async fn get_app() -> Vec<App> {
fn get_app() -> Vec<App> {
let mut conn = &mut establish_connection();
let apps = get_apps(&mut conn);
@@ -21,11 +62,30 @@ async fn get_app() -> Vec<App> {
apps
}
#[tauri::command]
fn delete_apps(id: &str) {
let conn = &mut establish_connection();
delete_app(conn, id);
}
#[tauri::command]
async fn ping(address: &str) -> Result<bool, String> {
match ping_target(address).await {
true => Ok(true),
false => Err(format!("Failed to ping {}", address)),
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![new_app, get_app])
.invoke_handler(tauri::generate_handler![
new_app,
get_app,
delete_apps,
ping
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}