mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: resolve external IP with just an http request (#8516)
This commit is contained in:
258
Cargo.lock
generated
258
Cargo.lock
generated
@ -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"
|
||||
@ -7198,14 +7032,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]]
|
||||
@ -8877,7 +8709,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",
|
||||
@ -9210,12 +9042,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"
|
||||
@ -9430,7 +9256,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",
|
||||
@ -9849,8 +9675,6 @@ version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"futures-task",
|
||||
"pin-project",
|
||||
"tracing",
|
||||
]
|
||||
@ -9930,51 +9754,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"
|
||||
@ -9984,7 +9763,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"cfg-if",
|
||||
"data-encoding",
|
||||
"enum-as-inner 0.6.0",
|
||||
"enum-as-inner",
|
||||
"futures-channel",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
@ -10018,7 +9797,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"trust-dns-proto 0.23.2",
|
||||
"trust-dns-proto",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -10664,21 +10443,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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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: <https://stackoverflow.com/questions/3253701/get-public-external-ip-address>
|
||||
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<IpAddr> {
|
||||
@ -103,12 +104,10 @@ impl FromStr for NatResolver {
|
||||
#[must_use = "Does nothing unless polled"]
|
||||
pub struct ResolveNatInterval {
|
||||
resolver: NatResolver,
|
||||
future: Option<ResolveFut>,
|
||||
future: Option<Pin<Box<dyn Future<Output = Option<IpAddr>> + 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<IpAddr> {
|
||||
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<IpAddr> {
|
||||
/// Given a [`NatResolver`] attempts to produce an IP address (best effort).
|
||||
pub async fn external_addr_with(resolver: NatResolver) -> Option<IpAddr> {
|
||||
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<Box<dyn Future<Output = Option<IpAddr>> + Send>>;
|
||||
|
||||
pin_project! {
|
||||
/// A future that resolves the first ip via all configured resolvers
|
||||
struct ResolveAny {
|
||||
#[pin]
|
||||
upnp: Option<ResolveFut>,
|
||||
#[pin]
|
||||
external: Option<ResolveFut>,
|
||||
}
|
||||
}
|
||||
|
||||
impl Future for ResolveAny {
|
||||
type Output = Option<IpAddr>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
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_upnp() -> Option<IpAddr> {
|
||||
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() -> Option<IpAddr> {
|
||||
public_ip::addr().await
|
||||
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_url_res(url: &str) -> Result<IpAddr, ()> {
|
||||
resolve_external_ip_url(url).await.ok_or(())
|
||||
}
|
||||
|
||||
async fn resolve_external_ip_url(url: &str) -> Option<IpAddr> {
|
||||
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)]
|
||||
|
||||
Reference in New Issue
Block a user