summaryrefslogtreecommitdiffstats
path: root/src/transport/identity.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-27 02:57:15 +0100
committertv <tv@krebsco.de>2026-10-27 02:57:15 +0100
commit0f9c74fbde6da95d7ec25d8de4741c45415c2dcc (patch)
treea118aa623ae99fa03d046a55d29a00e34c0ca8a8 /src/transport/identity.rs
parent5ae2f49509be196aec3d6de1ef558b046562c4ac (diff)
admit scheme in seeds
Diffstat (limited to 'src/transport/identity.rs')
-rw-r--r--src/transport/identity.rs45
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");