From 1615797364ea3fc0c302d13feede4e2e1d415b6f Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 27 Jun 2026 00:49:38 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20Deprecate=20top-lev?= =?UTF-8?q?el=20ping=20function=20in=20favor=20of=20Ping=20builder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib.rs | 1 + src/ping.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index eb1fec3..b7f8363 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,6 +54,7 @@ mod packet; mod ping; pub use crate::errors::Error; +#[allow(deprecated)] pub use crate::ping::{ Ping, PingResult, SocketType, SocketType::DGRAM, SocketType::RAW, dgramsock, new, ping, rawsock, }; diff --git a/src/ping.rs b/src/ping.rs index e9e3841..ff791fd 100644 --- a/src/ping.rs +++ b/src/ping.rs @@ -237,6 +237,7 @@ pub mod dgramsock { } } +#[deprecated(since = "0.8.0", note = "use `Ping::new` builder and `Ping::send` instead")] pub fn ping( addr: IpAddr, timeout: Option, From bbdc1d7893b3b4f596477bf02ab8aebb79704ca0 Mon Sep 17 00:00:00 2001 From: An Long Date: Fri, 10 Jul 2026 22:18:51 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20ping=20time?= =?UTF-8?q?out=20tracking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ping.rs | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/ping.rs b/src/ping.rs index ff791fd..7f854e5 100644 --- a/src/ping.rs +++ b/src/ping.rs @@ -1,5 +1,5 @@ use std::net::{IpAddr, SocketAddr}; -use std::time::{Duration, SystemTime}; +use std::time::{Duration, Instant}; use rand::random; use socket2::{Domain, Protocol, Socket, Type}; @@ -11,6 +11,12 @@ const TOKEN_SIZE: usize = 24; const ECHO_REQUEST_BUFFER_SIZE: usize = ICMP_HEADER_SIZE + TOKEN_SIZE; type Token = [u8; TOKEN_SIZE]; +fn remaining_timeout(started_at: Instant, timeout: Duration) -> std::io::Result { + timeout + .checked_sub(started_at.elapsed()) + .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::TimedOut, "ping request timed out")) +} + /// The kind of socket used to send the ICMP request. /// /// The default depends on the platform. On Windows [`Ping::new`] uses @@ -75,8 +81,6 @@ fn ping_with_socktype( payload: Option<&Token>, bind_device: Option<&str>, ) -> Result { - let time_start = SystemTime::now(); - let timeout = match timeout { Some(timeout) => timeout, None => Duration::from_secs(4), @@ -125,12 +129,12 @@ fn ping_with_socktype( socket.set_write_timeout(Some(timeout))?; + let started_at = Instant::now(); socket.send_to(&mut buffer, &dest.into())?; // loop until either an echo whose payload token matches was received or timeout is over - let mut elapsed_time = Duration::from_secs(0); loop { - socket.set_read_timeout(Some(timeout - elapsed_time))?; + socket.set_read_timeout(Some(remaining_timeout(started_at, timeout)?))?; let mut buffer: [u8; 2048] = [0; 2048]; // socket2 0.6 recv_from requires &mut [MaybeUninit]; cast is sound @@ -172,16 +176,10 @@ fn ping_with_socktype( } }; - // update elapsed time before deciding whether the payload token matches - elapsed_time = match SystemTime::now().duration_since(time_start) { - Ok(reply) => reply, - Err(_) => return Err(Error::InternalError.into()), - }; - if reply.payload == request.payload { // payload token matched: this reply belongs to our request return Ok(PingResult { - rtt: elapsed_time, + rtt: started_at.elapsed(), ident: reply.ident, seq_cnt: reply.seq_cnt, payload: reply.payload.to_vec(), @@ -190,11 +188,6 @@ fn ping_with_socktype( ttl: recv_ttl, }); } - - if elapsed_time >= timeout { - let error = std::io::Error::new(std::io::ErrorKind::TimedOut, "Timeout occured"); - return Err(Error::IoError { error: (error) }); - } } }