use anyhow::Result;
use futures_lite::stream::Boxed as BoxStream;
use crate::{
discovery::{Discovery, DiscoveryItem},
dns::ResolverExt,
relay::force_staging_infra,
Endpoint, NodeId,
};
pub const N0_DNS_NODE_ORIGIN_PROD: &str = "dns.iroh.link";
pub const N0_DNS_NODE_ORIGIN_STAGING: &str = "staging-dns.iroh.link";
const DNS_STAGGERING_MS: &[u64] = &[200, 300];
#[derive(Debug)]
pub struct DnsDiscovery {
origin_domain: String,
}
impl DnsDiscovery {
pub fn new(origin_domain: String) -> Self {
Self { origin_domain }
}
pub fn n0_dns() -> Self {
if force_staging_infra() {
Self::new(N0_DNS_NODE_ORIGIN_STAGING.to_string())
} else {
Self::new(N0_DNS_NODE_ORIGIN_PROD.to_string())
}
}
}
impl Discovery for DnsDiscovery {
fn resolve(&self, ep: Endpoint, node_id: NodeId) -> Option<BoxStream<Result<DiscoveryItem>>> {
let resolver = ep.dns_resolver().clone();
let origin_domain = self.origin_domain.clone();
let fut = async move {
let node_addr = resolver
.lookup_by_id_staggered(&node_id, &origin_domain, DNS_STAGGERING_MS)
.await?;
Ok(DiscoveryItem {
node_id,
provenance: "dns",
last_updated: None,
addr_info: node_addr.info,
})
};
let stream = futures_lite::stream::once_future(fut);
Some(Box::pin(stream))
}
}