-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed issues mentioned in PR review, and added test case for the sock…
…_addr utils.
- Loading branch information
Showing
9 changed files
with
346 additions
and
207 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Self, RvError> { | ||
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::<IpSockAddr>() { | ||
return self.addr.contains(ip_addr.addr.ip()); | ||
} | ||
|
||
false | ||
} | ||
|
||
fn equal(&self, other: &dyn SockAddr) -> bool { | ||
if let Some(ip_addr) = other.downcast_ref::<IpSockAddr>() { | ||
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)); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<dyn SockAddr>, | ||
} | ||
|
||
impl SockAddrMarshaler { | ||
pub fn new(sock_addr: Box<dyn SockAddr>) -> 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<Self, RvError> { | ||
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<Box<dyn SockAddr>, 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)); | ||
} | ||
} |
Oops, something went wrong.