From 487dfaa43e0370e63157dc302d55543cff2949cf Mon Sep 17 00:00:00 2001 From: Thomas Karpiniec Date: Fri, 28 Jun 2024 11:13:17 +1000 Subject: [PATCH 1/1] Improve errors --- src/error.rs | 24 ++++++++++++++++++++++++ src/lib.rs | 16 +++------------- src/list_unix.rs | 6 +++--- src/list_win.rs | 12 ++++++------ src/watch_linux.rs | 8 ++++---- 5 files changed, 40 insertions(+), 26 deletions(-) create mode 100644 src/error.rs diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..bb099cc --- /dev/null +++ b/src/error.rs @@ -0,0 +1,24 @@ +/// Errors in netwatcher or in one of the underlying platform integratinos. +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub enum Error { + CreateSocket(String), + Bind(String), + CreatePipe(String), + Getifaddrs(String), + GetInterfaceName(String), + FormatMacAddress, + UnexpectedWindowsResult(u32), + AddressNotAssociated, + InvalidParameter, + NotEnoughMemory, + InvalidHandle, +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl std::error::Error for Error {} diff --git a/src/lib.rs b/src/lib.rs index 6d22c98..495b9e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ use std::{ ops::Sub, }; -use nix::errno::Errno; +mod error; #[cfg_attr(windows, path = "list_win.rs")] #[cfg_attr(unix, path = "list_unix.rs")] @@ -20,6 +20,8 @@ mod watch; type IfIndex = u32; +pub use error::Error; + /// Information about one network interface at a point in time. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Interface { @@ -73,18 +75,6 @@ pub struct InterfaceDiff { pub addrs_removed: Vec, } -/// Errors in netwatcher or in one of the underlying platform integratinos. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Error { - CreateSocket(Errno), - Bind(Errno), - CreatePipe(Errno), - Getifaddrs(Errno), - GetInterfaceName(Errno), - FormatMacAddress, - Internal, -} - #[derive(Default, PartialEq, Eq)] struct List(HashMap); diff --git a/src/list_unix.rs b/src/list_unix.rs index a7cd881..4a49140 100644 --- a/src/list_unix.rs +++ b/src/list_unix.rs @@ -13,12 +13,12 @@ struct CandidateInterface { } pub(crate) fn list_interfaces() -> Result { - let addrs = getifaddrs().map_err(|e| Error::Getifaddrs(e))?; + let addrs = getifaddrs().map_err(|e| Error::Getifaddrs(e.to_string()))?; let mut candidates = HashMap::new(); for addr in addrs { - let index = - if_nametoindex(addr.interface_name.as_str()).map_err(|e| Error::GetInterfaceName(e))?; + let index = if_nametoindex(addr.interface_name.as_str()) + .map_err(|e| Error::GetInterfaceName(e.to_string()))?; let candidate = candidates .entry(addr.interface_name.clone()) .or_insert_with(|| CandidateInterface { diff --git a/src/list_win.rs b/src/list_win.rs index 8f0b783..00b7769 100644 --- a/src/list_win.rs +++ b/src/list_win.rs @@ -38,15 +38,15 @@ pub(crate) fn list_interfaces() -> Result { ); match WIN32_ERROR(res) { ERROR_SUCCESS => break, - ERROR_ADDRESS_NOT_ASSOCIATED => return Err(Error::Internal), + ERROR_ADDRESS_NOT_ASSOCIATED => return Err(Error::AddressNotAssociated), ERROR_BUFFER_OVERFLOW => { buf.resize(sizepointer as usize, 0); continue; } - ERROR_INVALID_PARAMETER => return Err(Error::Internal), - ERROR_NOT_ENOUGH_MEMORY => return Err(Error::Internal), + ERROR_INVALID_PARAMETER => return Err(Error::InvalidParameter), + ERROR_NOT_ENOUGH_MEMORY => return Err(Error::NotEnoughMemory), ERROR_NO_DATA => return Ok(List(HashMap::new())), // there aren't any - _ => return Err(Error::Internal), // TODO: Use FormatMessage to get a string + _ => return Err(Error::UnexpectedWindowsResult(res)), } } @@ -61,10 +61,10 @@ pub(crate) fn list_interfaces() -> Result { let mut hw_addr = String::with_capacity(adapter.PhysicalAddressLength as usize * 3); for i in 0..adapter.PhysicalAddressLength as usize { if i != 0 { - write!(hw_addr, ":").map_err(|_| Error::Internal)?; + write!(hw_addr, ":").map_err(|_| Error::FormatMacAddress)?; } write!(hw_addr, "{:02X}", adapter.PhysicalAddress[i]) - .map_err(|_| Error::Internal)?; + .map_err(|_| Error::FormatMacAddress)?; } let mut ips = vec![]; let mut unicast_ptr = adapter.FirstUnicastAddress; diff --git a/src/watch_linux.rs b/src/watch_linux.rs index e8e1ffc..c38be37 100644 --- a/src/watch_linux.rs +++ b/src/watch_linux.rs @@ -44,14 +44,14 @@ fn start_watcher_thread( SockFlag::empty(), Some(SockProtocol::NetlinkRoute), ) - .map_err(|e| Error::CreateSocket(e))?; - // TODO: set nonblocking + .map_err(|e| Error::CreateSocket(e.to_string()))?; + sockfd.set_nonblocking(true); let sa_nl = NetlinkAddr::new( 0, (RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR) as u32, ); - bind(sockfd.as_raw_fd(), &sa_nl).map_err(|e| Error::Bind(e))?; - let (pipe_rd, pipe_wr) = pipe().map_err(|e| Error::CreatePipe(e))?; + bind(sockfd.as_raw_fd(), &sa_nl).map_err(|e| Error::Bind(e.to_string()))?; + let (pipe_rd, pipe_wr) = pipe().map_err(|e| Error::CreatePipe(e.to_string()))?; let mut prev_list = List::default(); let mut handle_update = move |new_list: List| { -- 2.39.5