diff options
Diffstat (limited to 'src/transport/identity.rs')
| -rw-r--r-- | src/transport/identity.rs | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/src/transport/identity.rs b/src/transport/identity.rs index abedd35..bfd9432 100644 --- a/src/transport/identity.rs +++ b/src/transport/identity.rs @@ -30,7 +30,7 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex, MutexGuard}; use std::time::Duration; -use anyhow::{Result, anyhow, bail}; +use anyhow::{Context, Result, anyhow, bail}; use async_trait::async_trait; use tokio::sync::{mpsc, oneshot}; use tokio::time::Instant; @@ -514,22 +514,43 @@ impl Transport for IdentityTransport { } bail!("a node ID alone doesn't say where that node is; give its address"); } + // With a scheme of ours, only that transport resolves the rest (an address the + // transport can't read as an identity, e.g. a libp2p multiaddr without its peer + // ID, still resolves); without one, the first transport that can. + let scheme_and_rest = seed.split_once(':').and_then(|(scheme, rest)| { + let link = self + .shared + .links + .iter() + .find(|link| link.scheme == scheme)?; + Some((link, rest)) + }); let address = match self.shared.canonical(seed) { Some(address) => address, - None => { - let mut failures = Vec::new(); - let mut resolved = None; - for link in &self.shared.links { - match link.inner.resolve_seed(seed).await { - Ok(target) => { - resolved = Some(link.address(&target)); - break; + None => match scheme_and_rest { + Some((link, rest)) => { + let target = link + .inner + .resolve_seed(rest) + .await + .with_context(|| format!("{}: {seed}", link.scheme))?; + link.address(&target) + } + None => { + let mut failures = Vec::new(); + let mut resolved = None; + for link in &self.shared.links { + match link.inner.resolve_seed(seed).await { + Ok(target) => { + resolved = Some(link.address(&target)); + break; + } + Err(error) => failures.push(format!("{}: {error:#}", link.scheme)), } - Err(error) => failures.push(format!("{}: {error:#}", link.scheme)), } + resolved.ok_or_else(|| anyhow!("{}", failures.join("; ")))? } - resolved.ok_or_else(|| anyhow!("{}", failures.join("; ")))? - } + }, }; if self.shared.is_own(&address) { bail!("{seed} is this node"); |
