diff --git a/Cargo.lock b/Cargo.lock index 395b5d87ce2..0e528fd782d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1013,17 +1013,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "attohttpc" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" -dependencies = [ - "http 0.2.12", - "log", - "url", -] - [[package]] name = "aurora-engine-modexp" version = "1.1.0" @@ -1724,7 +1713,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", + "strsim", ] [[package]] @@ -2266,38 +2255,14 @@ dependencies = [ "tracing", ] -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core 0.10.2", - "darling_macro 0.10.2", -] - [[package]] name = "darling" version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ - "darling_core 0.20.9", - "darling_macro 0.20.9", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.9.3", - "syn 1.0.109", + "darling_core", + "darling_macro", ] [[package]] @@ -2310,28 +2275,17 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.11.1", + "strsim", "syn 2.0.66", ] -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core 0.10.2", - "quote", - "syn 1.0.109", -] - [[package]] name = "darling_macro" version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ - "darling_core 0.20.9", + "darling_core", "quote", "syn 2.0.66", ] @@ -2453,31 +2407,6 @@ dependencies = [ "syn 2.0.66", ] -[[package]] -name = "derive_builder" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" -dependencies = [ - "darling 0.10.2", - "derive_builder_core", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_core" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" -dependencies = [ - "darling 0.10.2", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -2605,18 +2534,6 @@ dependencies = [ "syn 2.0.66", ] -[[package]] -name = "dns-lookup" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53ecafc952c4528d9b51a458d1a8904b81783feff9fde08ab6ed2545ff396872" -dependencies = [ - "cfg-if", - "libc", - "socket2 0.4.10", - "winapi", -] - [[package]] name = "downcast" version = "0.11.0" @@ -2775,18 +2692,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "enum-as-inner" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "enum-as-inner" version = "0.6.0" @@ -3768,20 +3673,6 @@ dependencies = [ "tower-service", ] -[[package]] -name = "hyper-system-resolver" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eea26c5d0b6ab9d72219f65000af310f042a740926f7b2fa3553e774036e2e7" -dependencies = [ - "derive_builder", - "dns-lookup", - "hyper 0.14.28", - "tokio", - "tower-service", - "tracing", -] - [[package]] name = "hyper-util" version = "0.1.4" @@ -3984,17 +3875,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "0.4.0" @@ -4015,25 +3895,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "igd-next" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" -dependencies = [ - "async-trait", - "attohttpc", - "bytes", - "futures", - "http 0.2.12", - "hyper 0.14.28", - "log", - "rand 0.8.5", - "tokio", - "url", - "xmltree", -] - [[package]] name = "impl-codec" version = "0.6.0" @@ -4870,12 +4731,6 @@ dependencies = [ "regex-automata 0.1.10", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "memchr" version = "2.7.2" @@ -5977,27 +5832,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "public-ip" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4c40db5262d93298c363a299f8bc1b3a956a78eecddba3bc0e58b76e2f419a" -dependencies = [ - "dns-lookup", - "futures-core", - "futures-util", - "http 0.2.12", - "hyper 0.14.28", - "hyper-system-resolver", - "pin-project-lite", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "trust-dns-client", - "trust-dns-proto 0.20.4", -] - [[package]] name = "quanta" version = "0.11.1" @@ -7196,14 +7030,12 @@ dependencies = [ name = "reth-net-nat" version = "0.2.0-beta.7" dependencies = [ - "igd-next", - "pin-project-lite", - "public-ip", + "futures-util", + "reqwest 0.12.4", "reth-tracing", "serde_with", "thiserror", "tokio", - "tracing", ] [[package]] @@ -8874,7 +8706,7 @@ version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" dependencies = [ - "darling 0.20.9", + "darling", "proc-macro2", "quote", "syn 2.0.66", @@ -9207,12 +9039,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "strsim" version = "0.11.1" @@ -9427,7 +9253,7 @@ version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abe1689311f7edc6bab4033a259a3c37510b41063e4b01e57970105c0c764428" dependencies = [ - "darling 0.20.9", + "darling", "itertools 0.12.1", "once_cell", "prettyplease", @@ -9846,8 +9672,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "futures", - "futures-task", "pin-project", "tracing", ] @@ -9927,51 +9751,6 @@ dependencies = [ "rlp", ] -[[package]] -name = "trust-dns-client" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4ef9b9bde0559b78a4abb00339143750085f05e5a453efb7b8bef1061f09dc" -dependencies = [ - "cfg-if", - "data-encoding", - "futures-channel", - "futures-util", - "lazy_static", - "log", - "radix_trie", - "rand 0.8.5", - "thiserror", - "time", - "tokio", - "trust-dns-proto 0.20.4", -] - -[[package]] -name = "trust-dns-proto" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner 0.3.4", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static", - "log", - "rand 0.8.5", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "url", -] - [[package]] name = "trust-dns-proto" version = "0.23.2" @@ -9981,7 +9760,7 @@ dependencies = [ "async-trait", "cfg-if", "data-encoding", - "enum-as-inner 0.6.0", + "enum-as-inner", "futures-channel", "futures-io", "futures-util", @@ -10015,7 +9794,7 @@ dependencies = [ "thiserror", "tokio", "tracing", - "trust-dns-proto 0.23.2", + "trust-dns-proto", ] [[package]] @@ -10661,21 +10440,6 @@ dependencies = [ "tap", ] -[[package]] -name = "xml-rs" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" - -[[package]] -name = "xmltree" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" -dependencies = [ - "xml-rs", -] - [[package]] name = "yoke" version = "0.7.3" diff --git a/crates/net/nat/Cargo.toml b/crates/net/nat/Cargo.toml index 72ea9e11a9a..8ab78d46a5b 100644 --- a/crates/net/nat/Cargo.toml +++ b/crates/net/nat/Cargo.toml @@ -12,16 +12,11 @@ description = "Helpers for working around NAT" workspace = true [dependencies] -# nat -public-ip = "0.2" -igd-next = { workspace = true, features = ["aio_tokio"] } - -# misc -tracing.workspace = true -pin-project-lite = "0.2.9" -tokio = { workspace = true, features = ["time"] } -thiserror.workspace = true +futures-util.workspace = true +reqwest.workspace = true serde_with = { workspace = true, optional = true } +thiserror.workspace = true +tokio = { workspace = true, features = ["time"] } [dev-dependencies] reth-tracing.workspace = true diff --git a/crates/net/nat/src/lib.rs b/crates/net/nat/src/lib.rs index 33722bb5e5c..f9cfc139f19 100644 --- a/crates/net/nat/src/lib.rs +++ b/crates/net/nat/src/lib.rs @@ -12,22 +12,25 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -use igd_next::aio::tokio::search_gateway; -use pin_project_lite::pin_project; use std::{ fmt, future::{poll_fn, Future}, net::{AddrParseError, IpAddr}, pin::Pin, str::FromStr, - task::{ready, Context, Poll}, + task::{Context, Poll}, time::Duration, }; -use tracing::debug; #[cfg(feature = "serde")] use serde_with::{DeserializeFromStr, SerializeDisplay}; +/// URLs to `GET` the external IP address. +/// +/// Taken from: +const EXTERNAL_IP_APIS: &[&str] = + &["http://ipinfo.io/ip", "http://icanhazip.com", "http://ifconfig.me"]; + /// All builtin resolvers. #[derive(Debug, Clone, Copy, Eq, PartialEq, Default, Hash)] #[cfg_attr(feature = "serde", derive(SerializeDisplay, DeserializeFromStr))] @@ -35,9 +38,9 @@ pub enum NatResolver { /// Resolve with any available resolver. #[default] Any, - /// Resolve via Upnp + /// Resolve external IP via UPnP. Upnp, - /// Resolve external IP via [public_ip::Resolver] + /// Resolve external IP via a network request. PublicIp, /// Use the given [IpAddr] ExternalIp(IpAddr), @@ -45,8 +48,6 @@ pub enum NatResolver { None, } -// === impl NatResolver === - impl NatResolver { /// Attempts to produce an IP address (best effort). pub async fn external_addr(self) -> Option { @@ -103,12 +104,10 @@ impl FromStr for NatResolver { #[must_use = "Does nothing unless polled"] pub struct ResolveNatInterval { resolver: NatResolver, - future: Option, + future: Option> + Send>>>, interval: tokio::time::Interval, } -// === impl ResolveNatInterval === - impl fmt::Debug for ResolveNatInterval { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ResolveNatInterval") @@ -146,8 +145,7 @@ impl ResolveNatInterval { /// Completes when the next [IpAddr] in the interval has been reached. pub async fn tick(&mut self) -> Option { - let ip = poll_fn(|cx| self.poll_tick(cx)); - ip.await + poll_fn(|cx| self.poll_tick(cx)).await } /// Polls for the next resolved [IpAddr] in the interval to be reached. @@ -165,9 +163,7 @@ impl ResolveNatInterval { if let Some(mut fut) = self.future.take() { match fut.as_mut().poll(cx) { Poll::Ready(ip) => return Poll::Ready(ip), - Poll::Pending => { - self.future = Some(fut); - } + Poll::Pending => self.future = Some(fut), } } @@ -183,83 +179,26 @@ pub async fn external_ip() -> Option { /// Given a [`NatResolver`] attempts to produce an IP address (best effort). pub async fn external_addr_with(resolver: NatResolver) -> Option { match resolver { - NatResolver::Any => { - ResolveAny { - upnp: Some(Box::pin(resolve_external_ip_upnp())), - external: Some(Box::pin(resolve_external_ip())), - } - .await - } - NatResolver::Upnp => resolve_external_ip_upnp().await, - NatResolver::PublicIp => resolve_external_ip().await, + NatResolver::Any | NatResolver::Upnp | NatResolver::PublicIp => resolve_external_ip().await, NatResolver::ExternalIp(ip) => Some(ip), NatResolver::None => None, } } -type ResolveFut = Pin> + Send>>; - -pin_project! { - /// A future that resolves the first ip via all configured resolvers - struct ResolveAny { - #[pin] - upnp: Option, - #[pin] - external: Option, - } -} - -impl Future for ResolveAny { - type Output = Option; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let mut this = self.as_mut().project(); - - if let Some(upnp) = this.upnp.as_mut().as_pin_mut() { - // if upnp is configured we prefer it over http and dns resolvers - let ip = ready!(upnp.poll(cx)); - this.upnp.set(None); - if ip.is_some() { - return Poll::Ready(ip) - } - } - - if let Some(upnp) = this.external.as_mut().as_pin_mut() { - if let Poll::Ready(ip) = upnp.poll(cx) { - this.external.set(None); - if ip.is_some() { - return Poll::Ready(ip) - } - } - } - - if this.upnp.is_none() && this.external.is_none() { - return Poll::Ready(None) - } - - Poll::Pending - } +async fn resolve_external_ip() -> Option { + let futures = EXTERNAL_IP_APIS.iter().copied().map(resolve_external_ip_url_res).map(Box::pin); + futures_util::future::select_ok(futures).await.ok().map(|(res, _)| res) } -async fn resolve_external_ip_upnp() -> Option { - search_gateway(Default::default()) - .await - .map_err(|err| { - debug!(target: "net::nat", %err, "Failed to resolve external IP via UPnP: failed to find gateway"); - err - }) - .ok()? - .get_external_ip() - .await - .map_err(|err| { - debug!(target: "net::nat", %err, "Failed to resolve external IP via UPnP"); - err - }) - .ok() +async fn resolve_external_ip_url_res(url: &str) -> Result { + resolve_external_ip_url(url).await.ok_or(()) } -async fn resolve_external_ip() -> Option { - public_ip::addr().await +async fn resolve_external_ip_url(url: &str) -> Option { + let response = reqwest::get(url).await.ok()?; + let response = response.error_for_status().ok()?; + let text = response.text().await.ok()?; + text.trim().parse().ok() } #[cfg(test)]