mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(nat): add None Natresolver (#834)
This commit is contained in:
@ -22,6 +22,7 @@ igd = { git = "https://github.com/stevefan1999-personal/rust-igd", features = [
|
||||
tracing = "0.1"
|
||||
pin-project-lite = "0.2.9"
|
||||
tokio = { version = "1", features = ["time"] }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
reth-tracing = { path = "../../tracing" }
|
||||
|
||||
@ -10,9 +10,11 @@
|
||||
use igd::aio::search_gateway;
|
||||
use pin_project_lite::pin_project;
|
||||
use std::{
|
||||
fmt,
|
||||
future::{poll_fn, Future},
|
||||
net::IpAddr,
|
||||
net::{AddrParseError, IpAddr},
|
||||
pin::Pin,
|
||||
str::FromStr,
|
||||
task::{ready, Context, Poll},
|
||||
time::Duration,
|
||||
};
|
||||
@ -27,7 +29,11 @@ pub enum NatResolver {
|
||||
/// Resolve via Upnp
|
||||
Upnp,
|
||||
/// Resolve external IP via [public_ip::Resolver]
|
||||
ExternalIp,
|
||||
PublicIp,
|
||||
/// Use the given [IpAddr]
|
||||
ExternalIp(IpAddr),
|
||||
/// Resolve nothing
|
||||
None,
|
||||
}
|
||||
|
||||
// === impl NatResolver ===
|
||||
@ -39,6 +45,52 @@ impl NatResolver {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for NatResolver {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
NatResolver::Any => f.write_str("any"),
|
||||
NatResolver::Upnp => f.write_str("upnp"),
|
||||
NatResolver::PublicIp => f.write_str("publicip"),
|
||||
NatResolver::ExternalIp(ip) => write!(f, "extip:{ip}"),
|
||||
NatResolver::None => f.write_str("none"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Error when parsing a [NatResolver]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ParseNatResolverError {
|
||||
/// Failed to parse provided IP
|
||||
#[error(transparent)]
|
||||
AddrParseError(#[from] AddrParseError),
|
||||
/// Failed to parse due to unknown variant
|
||||
#[error("Unknown Nat Resolver variant: {0}")]
|
||||
UnknonwVariant(String),
|
||||
}
|
||||
|
||||
impl FromStr for NatResolver {
|
||||
type Err = ParseNatResolverError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let r = match s {
|
||||
"any" => NatResolver::Any,
|
||||
"upnp" => NatResolver::Upnp,
|
||||
"none" => NatResolver::None,
|
||||
"publicip" | "public-ip" => NatResolver::PublicIp,
|
||||
s => {
|
||||
if let Some(ip) = s.strip_prefix("extip:") {
|
||||
NatResolver::ExternalIp(ip.parse::<IpAddr>()?)
|
||||
} else {
|
||||
return Err(ParseNatResolverError::UnknonwVariant(format!(
|
||||
"Unknown Nat Resolver: {s}"
|
||||
)))
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
/// With this type you can resolve the external public IP address on an interval basis.
|
||||
#[must_use = "Does nothing unless polled"]
|
||||
pub struct ResolveNatInterval {
|
||||
@ -121,7 +173,9 @@ pub async fn external_addr_with(resolver: NatResolver) -> Option<IpAddr> {
|
||||
.await
|
||||
}
|
||||
NatResolver::Upnp => resolve_external_ip_upnp().await,
|
||||
NatResolver::ExternalIp => resolve_external_ip().await,
|
||||
NatResolver::PublicIp => resolve_external_ip().await,
|
||||
NatResolver::ExternalIp(ip) => Some(ip),
|
||||
NatResolver::None => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,6 +247,7 @@ async fn resolve_external_ip() -> Option<IpAddr> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
@ -213,4 +268,15 @@ mod tests {
|
||||
let ip = interval.tick().await;
|
||||
dbg!(ip);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!(NatResolver::Any, "any".parse().unwrap());
|
||||
assert_eq!(NatResolver::None, "none".parse().unwrap());
|
||||
|
||||
let ip = NatResolver::ExternalIp(IpAddr::V4(Ipv4Addr::UNSPECIFIED));
|
||||
let s = "extip:0.0.0.0";
|
||||
assert_eq!(ip, s.parse().unwrap());
|
||||
assert_eq!(ip.to_string().as_str(), s);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user