Skip to content

Commit

Permalink
refactor(core): replace process_result helper function
Browse files Browse the repository at this point in the history
  • Loading branch information
fujiapple852 committed Aug 8, 2024
1 parent 6069d4c commit 072dd38
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 53 deletions.
91 changes: 46 additions & 45 deletions crates/trippy-core/src/net/common.rs
Original file line number Diff line number Diff line change
@@ -1,70 +1,71 @@
use crate::error::{Error, ErrorKind, IoResult, Result};
use std::io;
use crate::error::ErrorKind;
use crate::error::{Error, Result};
use std::net::SocketAddr;

/// Helper function to convert an `IoResult` to a `Result`.
///
/// The `AddressInUse` error is handled separately to allow for more specific
/// handling upstream.
pub fn process_result(addr: SocketAddr, res: IoResult<()>) -> Result<()> {
match res {
Ok(()) => Ok(()),
Err(err) => match err.kind() {
ErrorKind::InProgress => Ok(()),
ErrorKind::Std(io::ErrorKind::AddrInUse) => Err(Error::AddressInUse(addr)),
ErrorKind::Std(_) => Err(Error::IoError(err)),
},
/// Utility methods to map errors.
pub struct ErrorMapper;

impl ErrorMapper {
/// Convert [`ErrorKind::InProgress`] to [`Ok`].
pub fn in_progress(err: Error) -> Result<()> {
match err {
Error::IoError(io_err) => match io_err.kind() {
ErrorKind::InProgress => Ok(()),
ErrorKind::Std(_) => Err(Error::IoError(io_err)),
},
err => Err(err),
}
}

/// Convert [`io::ErrorKind::AddrInUse`] to [`Error::AddressInUse`].
#[must_use]
pub fn addr_in_use(err: Error, addr: SocketAddr) -> Error {
match err {
Error::IoError(io_err) => match io_err.kind() {
ErrorKind::Std(std::io::ErrorKind::AddrInUse) => Error::AddressInUse(addr),
_ => Error::IoError(io_err),
},
err => err,
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::error::{IoError, IoOperation};
use crate::error::IoError;
use std::io;
use std::net::{Ipv4Addr, SocketAddrV4};

const ADDR: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0));

#[test]
fn test_ok() {
let res = Ok(());
let trace_res = process_result(ADDR, res);
assert!(trace_res.is_ok());
}

#[test]
fn test_err() {
let io_error = io::Error::from(io::ErrorKind::ConnectionRefused);
let res = Err(IoError::Connect(io_error, ADDR));
let trace_res = process_result(ADDR, res);
let trace_io_error = trace_res.unwrap_err();
assert!(matches!(trace_io_error, Error::IoError(_)));
fn test_in_progress() {
let io_err = io::Error::from(ErrorKind::InProgress);
let err = Error::IoError(IoError::Bind(io_err, ADDR));
assert!(ErrorMapper::in_progress(err).is_ok());
}

#[test]
fn test_addr_in_use_err() {
let io_error = io::Error::from(io::ErrorKind::AddrInUse);
let res = Err(IoError::Other(io_error, IoOperation::Read));
let trace_res = process_result(ADDR, res);
let trace_err = trace_res.unwrap_err();
assert!(matches!(trace_err, Error::AddressInUse(ADDR)));
fn test_not_in_progress() {
let io_err = io::Error::from(ErrorKind::Std(io::ErrorKind::Other));
let err = Error::IoError(IoError::Bind(io_err, ADDR));
assert!(ErrorMapper::in_progress(err).is_err());
}

#[test]
fn test_addr_not_avail_err() {
let io_error = io::Error::from(io::ErrorKind::AddrNotAvailable);
let res = Err(IoError::Bind(io_error, ADDR));
let trace_res = process_result(ADDR, res);
let trace_err = trace_res.unwrap_err();
assert!(matches!(trace_err, Error::IoError(_)));
fn test_addr_in_use() {
let io_err = io::Error::from(ErrorKind::Std(io::ErrorKind::AddrInUse));
let err = Error::IoError(IoError::Bind(io_err, ADDR));
let addr_in_use_err = ErrorMapper::addr_in_use(err, ADDR);
assert!(matches!(addr_in_use_err, Error::AddressInUse(ADDR)));
}

#[test]
fn test_in_progress_ok() {
let io_error = io::Error::from(ErrorKind::InProgress);
let res = Err(IoError::Other(io_error, IoOperation::Select));
let trace_res = process_result(ADDR, res);
assert!(trace_res.is_ok());
fn test_not_addr_in_use() {
let io_err = io::Error::from(ErrorKind::Std(io::ErrorKind::Other));
let err = Error::IoError(IoError::Bind(io_err, ADDR));
let addr_in_use_err = ErrorMapper::addr_in_use(err, ADDR);
assert!(matches!(addr_in_use_err, Error::IoError(_)));
}
}
20 changes: 16 additions & 4 deletions crates/trippy-core/src/net/ipv4.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::config::IcmpExtensionParseMode;
use crate::error::{Error, ErrorKind, Result};
use crate::net::channel::MAX_PACKET_SIZE;
use crate::net::common::process_result;
use crate::net::common::ErrorMapper;
use crate::net::platform;
use crate::net::socket::{Socket, SocketError};
use crate::probe::{
Expand Down Expand Up @@ -178,7 +178,11 @@ impl Ipv4 {
let local_addr = SocketAddr::new(IpAddr::V4(self.src_addr), probe.src_port.0);
let remote_addr = SocketAddr::new(IpAddr::V4(self.dest_addr), probe.dest_port.0);
let mut socket = S::new_udp_send_socket_ipv4(false)?;
process_result(local_addr, socket.bind(local_addr))?;
socket
.bind(local_addr)
.map_err(Error::IoError)
.or_else(ErrorMapper::in_progress)
.map_err(|err| ErrorMapper::addr_in_use(err, local_addr))?;
socket.set_ttl(u32::from(probe.ttl.0))?;
socket.send_to(payload, remote_addr)?;
Ok(())
Expand All @@ -189,11 +193,19 @@ impl Ipv4 {
pub fn dispatch_tcp_probe<S: Socket>(&self, probe: &Probe) -> Result<S> {
let mut socket = S::new_stream_socket_ipv4()?;
let local_addr = SocketAddr::new(IpAddr::V4(self.src_addr), probe.src_port.0);
process_result(local_addr, socket.bind(local_addr))?;
socket
.bind(local_addr)
.map_err(Error::IoError)
.or_else(ErrorMapper::in_progress)
.map_err(|err| ErrorMapper::addr_in_use(err, local_addr))?;
socket.set_ttl(u32::from(probe.ttl.0))?;
socket.set_tos(u32::from(self.tos.0))?;
let remote_addr = SocketAddr::new(IpAddr::V4(self.dest_addr), probe.dest_port.0);
process_result(remote_addr, socket.connect(remote_addr))?;
socket
.connect(remote_addr)
.map_err(Error::IoError)
.or_else(ErrorMapper::in_progress)
.map_err(|err| ErrorMapper::addr_in_use(err, remote_addr))?;
Ok(socket)
}

Expand Down
20 changes: 16 additions & 4 deletions crates/trippy-core/src/net/ipv6.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::config::IcmpExtensionParseMode;
use crate::error::{Error, ErrorKind, Result};
use crate::net::channel::MAX_PACKET_SIZE;
use crate::net::common::process_result;
use crate::net::common::ErrorMapper;
use crate::net::socket::{Socket, SocketError};
use crate::probe::{
Extensions, IcmpPacketCode, Probe, Response, ResponseData, ResponseSeq, ResponseSeqIcmp,
Expand Down Expand Up @@ -162,7 +162,11 @@ impl Ipv6 {
let local_addr = SocketAddr::new(IpAddr::V6(self.src_addr), probe.src_port.0);
let remote_addr = SocketAddr::new(IpAddr::V6(self.dest_addr), probe.dest_port.0);
let mut socket = S::new_udp_send_socket_ipv6(false)?;
process_result(local_addr, socket.bind(local_addr))?;
socket
.bind(local_addr)
.map_err(Error::IoError)
.or_else(ErrorMapper::in_progress)
.map_err(|err| ErrorMapper::addr_in_use(err, local_addr))?;
socket.set_unicast_hops_v6(probe.ttl.0)?;
socket.send_to(payload, remote_addr)?;
Ok(())
Expand All @@ -173,10 +177,18 @@ impl Ipv6 {
pub fn dispatch_tcp_probe<S: Socket>(&self, probe: &Probe) -> Result<S> {
let mut socket = S::new_stream_socket_ipv6()?;
let local_addr = SocketAddr::new(IpAddr::V6(self.src_addr), probe.src_port.0);
process_result(local_addr, socket.bind(local_addr))?;
socket
.bind(local_addr)
.map_err(Error::IoError)
.or_else(ErrorMapper::in_progress)
.map_err(|err| ErrorMapper::addr_in_use(err, local_addr))?;
socket.set_unicast_hops_v6(probe.ttl.0)?;
let remote_addr = SocketAddr::new(IpAddr::V6(self.dest_addr), probe.dest_port.0);
process_result(remote_addr, socket.connect(remote_addr))?;
socket
.connect(remote_addr)
.map_err(Error::IoError)
.or_else(ErrorMapper::in_progress)
.map_err(|err| ErrorMapper::addr_in_use(err, remote_addr))?;
Ok(socket)
}

Expand Down

0 comments on commit 072dd38

Please sign in to comment.