From e5a516c36d5571d836a7e9f707ff4f530ee6980a Mon Sep 17 00:00:00 2001 From: Jin Jiu Date: Thu, 9 May 2024 11:48:37 +0800 Subject: [PATCH] Fixed issues mentioned in PR review, and added test case for the sock_addr utils. --- src/utils/cidr.rs | 5 +- src/utils/ip_sock_addr.rs | 119 +++++++++++++++++++++++++++++ src/utils/ipaddr.rs | 74 ------------------ src/utils/mod.rs | 6 +- src/utils/salt.rs | 3 + src/utils/sock_addr.rs | 144 ++++++++++++++++++++++++++++++++++++ src/utils/sockaddr.rs | 78 ------------------- src/utils/unix_sock_addr.rs | 73 ++++++++++++++++++ src/utils/unixsock.rs | 51 ------------- 9 files changed, 346 insertions(+), 207 deletions(-) create mode 100644 src/utils/ip_sock_addr.rs delete mode 100644 src/utils/ipaddr.rs create mode 100644 src/utils/sock_addr.rs delete mode 100644 src/utils/sockaddr.rs create mode 100644 src/utils/unix_sock_addr.rs delete mode 100644 src/utils/unixsock.rs diff --git a/src/utils/cidr.rs b/src/utils/cidr.rs index 79f59b5..6be607b 100644 --- a/src/utils/cidr.rs +++ b/src/utils/cidr.rs @@ -1,3 +1,6 @@ +//! This module is a Rust replica of +//! https://github.com/hashicorp/vault/blob/main/sdk/helper/cidrutil/cidr.go + use std::{ str::FromStr, net::{IpAddr, Ipv4Addr, Ipv6Addr}, @@ -7,7 +10,7 @@ use std::{ use ipnetwork::IpNetwork; use super::{ - sockaddr::{new_sock_addr, SockAddrType, SockAddr}, + sock_addr::{new_sock_addr, SockAddrType, SockAddr}, }; use crate::errors::RvError; diff --git a/src/utils/ip_sock_addr.rs b/src/utils/ip_sock_addr.rs new file mode 100644 index 0000000..9e1e0da --- /dev/null +++ b/src/utils/ip_sock_addr.rs @@ -0,0 +1,119 @@ +//! This module is a Rust replica of +//! https://github.com/hashicorp/go-sockaddr/blob/master/ipv4addr.go + +use std::{ + fmt, + str::FromStr, + net::SocketAddr, +}; + +use as_any::Downcast; +use ipnetwork::IpNetwork; +use serde::{Deserialize, Serialize}; + +use super::{ + sock_addr::{SockAddr, SockAddrType}, +}; + +use crate::errors::RvError; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct IpSockAddr { + pub addr: IpNetwork, + pub port: u16, +} + +impl IpSockAddr { + pub fn new(s: &str) -> Result { + if let Ok(sock_addr) = SocketAddr::from_str(s) { + return Ok(IpSockAddr { + addr: IpNetwork::from(sock_addr.ip()), + port: sock_addr.port(), + }); + } else if let Ok(ip_addr) = IpNetwork::from_str(s) { + return Ok(IpSockAddr { + addr: ip_addr, + port: 0, + }); + } + return Err(RvError::ErrResponse(format!("Unable to parse {} to an IP address:", s))); + } +} + +impl SockAddr for IpSockAddr { + fn contains(&self, other: &dyn SockAddr) -> bool { + if let Some(ip_addr) = other.downcast_ref::() { + return self.addr.contains(ip_addr.addr.ip()); + } + + false + } + + fn equal(&self, other: &dyn SockAddr) -> bool { + if let Some(ip_addr) = other.downcast_ref::() { + return self.addr == ip_addr.addr && self.port == ip_addr.port; + } + + false + } + + fn sock_addr_type(&self) -> SockAddrType { + match self.addr { + IpNetwork::V4(_) => SockAddrType::IPv4, + IpNetwork::V6(_) => SockAddrType::IPv6, + } + } +} + +impl fmt::Display for IpSockAddr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.port == 0 { + write!(f, "{}", self.addr.ip()) + } else { + write!(f, "{}:{}", self.addr.ip(), self.port) + } + } +} + +#[cfg(test)] +mod test { + use super::{ + *, super::sock_addr::{SockAddrType}, + }; + + #[test] + fn test_ip_sock_addr() { + let addr1 = IpSockAddr::new("1.1.1.1").unwrap(); + let addr2 = IpSockAddr::new("1.1.1.1").unwrap(); + let addr3 = IpSockAddr::new("2.2.2.2").unwrap(); + let addr4 = IpSockAddr::new("333.333.333.333"); + let addr5 = IpSockAddr::new("1.1.1.1:80").unwrap(); + let addr6 = IpSockAddr::new("1.1.1.1:80").unwrap(); + let addr7 = IpSockAddr::new("1.1.1.1:8080").unwrap(); + let addr8 = IpSockAddr::new("2.2.2.2:80").unwrap(); + let addr9 = IpSockAddr::new("192.168.0.0/16").unwrap(); + let addr10 = IpSockAddr::new("192.168.0.0/24").unwrap(); + let addr11 = IpSockAddr::new("192.168.0.1").unwrap(); + let addr12 = IpSockAddr::new("192.168.1.1").unwrap(); + + assert!(addr4.is_err()); + assert!(addr1.contains(&addr2)); + assert!(addr1.equal(&addr2)); + assert!(!addr1.contains(&addr3)); + assert!(!addr1.equal(&addr3)); + assert_eq!(addr1.sock_addr_type(), SockAddrType::IPv4); + assert!(addr5.contains(&addr6)); + assert!(addr5.equal(&addr6)); + assert!(!addr5.equal(&addr7)); + assert!(!addr5.equal(&addr8)); + assert!(addr9.contains(&addr10)); + assert!(addr9.contains(&addr11)); + assert!(addr9.contains(&addr12)); + assert!(!addr9.contains(&addr1)); + assert!(addr10.contains(&addr9)); + assert!(addr10.contains(&addr11)); + assert!(!addr10.contains(&addr12)); + assert!(!addr9.equal(&addr10)); + assert!(!addr9.equal(&addr11)); + } +} diff --git a/src/utils/ipaddr.rs b/src/utils/ipaddr.rs deleted file mode 100644 index 346e876..0000000 --- a/src/utils/ipaddr.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::{ - fmt, - str::FromStr, - net::SocketAddr, -}; - -use as_any::Downcast; -use ipnetwork::IpNetwork; -use serde::{Deserialize, Serialize}; - -use super::{ - sockaddr::{SockAddr, SockAddrType}, -}; - -use crate::errors::RvError; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct IpAddr { - pub addr: IpNetwork, - pub port: u16, -} - -impl IpAddr { - pub fn new(s: &str) -> Result { - if let Ok(sock_addr) = SocketAddr::from_str(s) { - return Ok(IpAddr { - addr: IpNetwork::from(sock_addr.ip()), - port: sock_addr.port(), - }); - } else if let Ok(ip_addr) = IpNetwork::from_str(s) { - return Ok(IpAddr { - addr: ip_addr, - port: 0, - }); - } - return Err(RvError::ErrResponse(format!("Unable to parse {} to an IP address:", s))); - } -} - -impl SockAddr for IpAddr { - fn contains(&self, other: &dyn SockAddr) -> bool { - if let Some(ip_addr) = other.downcast_ref::() { - return self.addr.contains(ip_addr.addr.ip()); - } - - false - } - - fn equal(&self, other: &dyn SockAddr) -> bool { - if let Some(ip_addr) = other.downcast_ref::() { - return self.addr == ip_addr.addr && self.port == ip_addr.port; - } - - false - } - - fn sock_addr_type(&self) -> SockAddrType { - match self.addr { - IpNetwork::V4(_) => SockAddrType::IPv4, - IpNetwork::V6(_) => SockAddrType::IPv6, - } - } -} - -impl fmt::Display for IpAddr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.port == 0 { - write!(f, "{}", self.addr.ip()) - } else { - write!(f, "{}:{}", self.addr.ip(), self.port) - } - } -} - diff --git a/src/utils/mod.rs b/src/utils/mod.rs index ff4eca2..7997a67 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -12,9 +12,9 @@ pub mod cert; pub mod key; pub mod salt; pub mod cidr; -pub mod sockaddr; -pub mod ipaddr; -pub mod unixsock; +pub mod sock_addr; +pub mod ip_sock_addr; +pub mod unix_sock_addr; pub fn generate_uuid() -> String { let mut buf = [0u8; 16]; diff --git a/src/utils/salt.rs b/src/utils/salt.rs index 438300b..ed5962a 100644 --- a/src/utils/salt.rs +++ b/src/utils/salt.rs @@ -1,3 +1,6 @@ +//! This module is a Rust replica of +//! https://github.com/hashicorp/vault/blob/main/sdk/helper/salt/salt.go + use openssl::{ hash::{hash, MessageDigest}, pkey::PKey, diff --git a/src/utils/sock_addr.rs b/src/utils/sock_addr.rs new file mode 100644 index 0000000..63574ca --- /dev/null +++ b/src/utils/sock_addr.rs @@ -0,0 +1,144 @@ +//! This module is a Rust replica of +//! https://github.com/hashicorp/go-sockaddr/blob/master/sockaddr.go + +use std::{ + fmt, + str::FromStr, +}; + +use as_any::AsAny; +use serde::{Deserialize, Serialize}; + +use super::{ + ip_sock_addr::IpSockAddr, +}; + +use crate::errors::RvError; + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum SockAddrType { + Unknown = 0x0, + Unix = 0x1, + IPv4 = 0x2, + IPv6 = 0x4, + // IP is the union of IPv4 and IPv6 + IP = 0x6, +} + +pub trait SockAddr: fmt::Display + AsAny { + // contains returns true if the other SockAddr is contained within the receiver + fn contains(&self, other: &dyn SockAddr) -> bool; + + // equal allows for the comparison of two SockAddrs + fn equal(&self, other: &dyn SockAddr) -> bool; + + fn sock_addr_type(&self) -> SockAddrType; +} + +pub struct SockAddrMarshaler { + pub sock_addr: Box, +} + +impl SockAddrMarshaler { + pub fn new(sock_addr: Box) -> Self { + SockAddrMarshaler { sock_addr } + } +} + +impl fmt::Display for SockAddrMarshaler { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.sock_addr) + } +} + +impl fmt::Display for SockAddrType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let type_str = match self { + SockAddrType::IPv4 => "IPv4", + SockAddrType::IPv6 => "IPv6", + SockAddrType::Unix => "Unix", + _ => "Unknown", + }; + write!(f, "{}", type_str) + } +} + +impl FromStr for SockAddrType { + type Err = RvError; + fn from_str(s: &str) -> Result { + match s { + "IPv4" | "ipv4" => Ok(SockAddrType::IPv4), + "IPv6" | "ipv6" => Ok(SockAddrType::IPv6), + "Unix" | "UNIX" | "unix" => Ok(SockAddrType::Unix), + _ => Err(RvError::ErrResponse("invalid sockaddr type".to_string())) + } + } +} + +pub fn new_sock_addr(s: &str) -> Result, RvError> { + let ret = IpSockAddr::new(s)?; + Ok(Box::new(ret)) +} + +#[cfg(test)] +mod test { + use super::{ + *, super::{ + sock_addr::{SockAddrType}, + ip_sock_addr::IpSockAddr, + unix_sock_addr::UnixSockAddr, + }, + }; + + #[test] + fn test_sock_addr() { + let unix_addr1 = UnixSockAddr::new("/tmp/bar").unwrap(); + let unix_addr2 = UnixSockAddr::new("/tmp/bar").unwrap(); + let unix_addr3 = UnixSockAddr::new("/tmp/foo").unwrap(); + let ip_addr1 = IpSockAddr::new("1.1.1.1").unwrap(); + let ip_addr2 = IpSockAddr::new("1.1.1.1").unwrap(); + let ip_addr3 = IpSockAddr::new("2.2.2.2").unwrap(); + let ip_addr4 = IpSockAddr::new("333.333.333.333"); + let ip_addr5 = IpSockAddr::new("1.1.1.1:80").unwrap(); + let ip_addr6 = IpSockAddr::new("1.1.1.1:80").unwrap(); + let ip_addr7 = IpSockAddr::new("1.1.1.1:8080").unwrap(); + let ip_addr8 = IpSockAddr::new("2.2.2.2:80").unwrap(); + let ip_addr9 = IpSockAddr::new("192.168.0.0/16").unwrap(); + let ip_addr10 = IpSockAddr::new("192.168.0.0/24").unwrap(); + let ip_addr11 = IpSockAddr::new("192.168.0.1").unwrap(); + let ip_addr12 = IpSockAddr::new("192.168.1.1").unwrap(); + + assert!(unix_addr1.contains(&unix_addr2)); + assert!(unix_addr1.equal(&unix_addr2)); + assert!(!unix_addr1.contains(&unix_addr3)); + assert!(!unix_addr1.equal(&unix_addr3)); + assert_ne!(unix_addr1.sock_addr_type(), ip_addr1.sock_addr_type()); + + assert!(ip_addr4.is_err()); + assert!(ip_addr1.contains(&ip_addr2)); + assert!(ip_addr1.equal(&ip_addr2)); + assert!(!ip_addr1.contains(&ip_addr3)); + assert!(!ip_addr1.equal(&ip_addr3)); + assert_eq!(ip_addr1.sock_addr_type(), SockAddrType::IPv4); + assert_eq!(ip_addr1.sock_addr_type(), ip_addr2.sock_addr_type()); + assert_ne!(ip_addr1.sock_addr_type(), unix_addr2.sock_addr_type()); + assert!(ip_addr5.contains(&ip_addr6)); + assert!(ip_addr5.equal(&ip_addr6)); + assert!(!ip_addr5.equal(&ip_addr7)); + assert!(!ip_addr5.equal(&ip_addr8)); + assert!(ip_addr9.contains(&ip_addr10)); + assert!(ip_addr9.contains(&ip_addr11)); + assert!(ip_addr9.contains(&ip_addr12)); + assert!(!ip_addr9.contains(&ip_addr1)); + assert!(ip_addr10.contains(&ip_addr9)); + assert!(ip_addr10.contains(&ip_addr11)); + assert!(!ip_addr10.contains(&ip_addr12)); + assert!(!ip_addr9.equal(&ip_addr10)); + assert!(!ip_addr9.equal(&ip_addr11)); + + assert!(!ip_addr1.contains(&unix_addr1)); + assert!(!ip_addr1.equal(&unix_addr1)); + assert!(!unix_addr1.contains(&ip_addr1)); + assert!(!unix_addr1.equal(&ip_addr1)); + } +} diff --git a/src/utils/sockaddr.rs b/src/utils/sockaddr.rs deleted file mode 100644 index 907ef6a..0000000 --- a/src/utils/sockaddr.rs +++ /dev/null @@ -1,78 +0,0 @@ -use std::{ - fmt, - str::FromStr, -}; - -use as_any::AsAny; -use serde::{Deserialize, Serialize}; - -use super::{ - ipaddr::IpAddr, -}; - -use crate::errors::RvError; - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum SockAddrType { - Unknown = 0x0, - Unix = 0x1, - IPv4 = 0x2, - IPv6 = 0x4, - // IP is the union of IPv4 and IPv6 - IP = 0x6, -} - -pub trait SockAddr: fmt::Display + AsAny { - // contains returns true if the other SockAddr is contained within the receiver - fn contains(&self, other: &dyn SockAddr) -> bool; - - // equal allows for the comparison of two SockAddrs - fn equal(&self, other: &dyn SockAddr) -> bool; - - fn sock_addr_type(&self) -> SockAddrType; -} - -pub struct SockAddrMarshaler { - pub sock_addr: Box, -} - -impl SockAddrMarshaler { - pub fn new(sock_addr: Box) -> Self { - SockAddrMarshaler { sock_addr } - } -} - -impl fmt::Display for SockAddrMarshaler { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.sock_addr) - } -} - -impl fmt::Display for SockAddrType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let type_str = match self { - SockAddrType::IPv4 => "IPv4", - SockAddrType::IPv6 => "IPv6", - SockAddrType::Unix => "Unix", - _ => "Unknown", - }; - write!(f, "{}", type_str) - } -} - -impl FromStr for SockAddrType { - type Err = RvError; - fn from_str(s: &str) -> Result { - match s { - "IPv4" | "ipv4" => Ok(SockAddrType::IPv4), - "IPv6" | "ipv6" => Ok(SockAddrType::IPv6), - "Unix" | "UNIX" | "unix" => Ok(SockAddrType::Unix), - _ => Err(RvError::ErrResponse("invalid sockaddr type".to_string())) - } - } -} - -pub fn new_sock_addr(s: &str) -> Result, RvError> { - let ret = IpAddr::new(s)?; - Ok(Box::new(ret)) -} diff --git a/src/utils/unix_sock_addr.rs b/src/utils/unix_sock_addr.rs new file mode 100644 index 0000000..c7cc8ca --- /dev/null +++ b/src/utils/unix_sock_addr.rs @@ -0,0 +1,73 @@ +//! This module is a Rust replica of +//! https://github.com/hashicorp/go-sockaddr/blob/master/unixsock.go + +use std::fmt; +use as_any::Downcast; +use serde::{Deserialize, Serialize}; + +use super::{ + sock_addr::{SockAddr, SockAddrType}, +}; + +use crate::errors::RvError; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct UnixSockAddr { + pub path: String, +} + +impl UnixSockAddr { + pub fn new(s: &str) -> Result { + Ok(Self { + path: s.to_string(), + }) + } +} + +impl SockAddr for UnixSockAddr { + fn contains(&self, other: &dyn SockAddr) -> bool { + if let Some(unix_sock) = other.downcast_ref::() { + return self.path == unix_sock.path; + } + + false + } + + fn equal(&self, other: &dyn SockAddr) -> bool { + if let Some(unix_sock) = other.downcast_ref::() { + return self.path == unix_sock.path; + } + + false + } + + fn sock_addr_type(&self) -> SockAddrType { + SockAddrType::Unix + } +} + +impl fmt::Display for UnixSockAddr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.path) + } +} + +#[cfg(test)] +mod test { + use super::{ + *, super::sock_addr::{SockAddrType}, + }; + + #[test] + fn test_unix_sock_addr() { + let addr1 = UnixSockAddr::new("/tmp/bar").unwrap(); + let addr2 = UnixSockAddr::new("/tmp/bar").unwrap(); + let addr3 = UnixSockAddr::new("/tmp/foo").unwrap(); + + assert!(addr1.contains(&addr2)); + assert!(addr1.equal(&addr2)); + assert!(!addr1.contains(&addr3)); + assert!(!addr1.equal(&addr3)); + assert_eq!(addr1.sock_addr_type(), SockAddrType::Unix); + } +} diff --git a/src/utils/unixsock.rs b/src/utils/unixsock.rs deleted file mode 100644 index 88a1034..0000000 --- a/src/utils/unixsock.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::fmt; -use as_any::Downcast; -use serde::{Deserialize, Serialize}; - -use super::{ - sockaddr::{SockAddr, SockAddrType}, -}; - -use crate::errors::RvError; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct UnixSock { - pub path: String, -} - -impl UnixSock { - pub fn new(s: &str) -> Result { - Ok(Self { - path: s.to_string(), - }) - } -} - -impl SockAddr for UnixSock { - fn contains(&self, other: &dyn SockAddr) -> bool { - if let Some(unix_sock) = other.downcast_ref::() { - return self.path == unix_sock.path; - } - - false - } - - fn equal(&self, other: &dyn SockAddr) -> bool { - if let Some(unix_sock) = other.downcast_ref::() { - return self.path == unix_sock.path; - } - - false - } - - fn sock_addr_type(&self) -> SockAddrType { - SockAddrType::Unix - } -} - -impl fmt::Display for UnixSock { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.path) - } -} -