herolib_rust/src/net/tcp.rs
kristof ba9103685f
Some checks failed
Rhai Tests / Run Rhai Tests (push) Has been cancelled
...
2025-06-16 07:53:03 +02:00

74 lines
2.2 KiB
Rust

use std::net::{IpAddr, SocketAddr};
use std::time::Duration;
use anyhow::Result;
use tokio::net::TcpStream;
use tokio::time::timeout;
/// TCP Connectivity module for checking TCP connections
pub struct TcpConnector {
timeout: Duration,
}
impl TcpConnector {
/// Create a new TCP connector with the default timeout (5 seconds)
pub fn new() -> Self {
Self {
timeout: Duration::from_secs(5),
}
}
/// Create a new TCP connector with a custom timeout
pub fn with_timeout(timeout: Duration) -> Self {
Self { timeout }
}
/// Check if a TCP port is open on a host
pub async fn check_port<A: Into<IpAddr>>(&self, host: A, port: u16) -> Result<bool> {
let addr = SocketAddr::new(host.into(), port);
let connect_future = TcpStream::connect(addr);
match timeout(self.timeout, connect_future).await {
Ok(Ok(_)) => Ok(true),
Ok(Err(_)) => Ok(false),
Err(_) => Ok(false), // Timeout occurred
}
}
/// Check if multiple TCP ports are open on a host
pub async fn check_ports<A: Into<IpAddr> + Clone>(&self, host: A, ports: &[u16]) -> Result<Vec<(u16, bool)>> {
let mut results = Vec::with_capacity(ports.len());
for &port in ports {
let is_open = self.check_port(host.clone(), port).await?;
results.push((port, is_open));
}
Ok(results)
}
/// Check if a host is reachable on the network using ICMP ping
pub async fn ping<S: AsRef<str>>(&self, host: S) -> Result<bool> {
// Convert to owned strings to avoid borrowing issues
let host_str = host.as_ref().to_string();
let timeout_secs = self.timeout.as_secs().to_string();
// Run the ping command with explicit arguments
let status = tokio::process::Command::new("ping")
.arg("-c")
.arg("1") // Just one ping
.arg("-W")
.arg(timeout_secs) // Timeout in seconds
.arg(host_str) // Host to ping
.output()
.await?;
Ok(status.status.success())
}
}
impl Default for TcpConnector {
fn default() -> Self {
Self::new()
}
}