diff --git a/iroh-dns-server/src/config.rs b/iroh-dns-server/src/config.rs index 40b3e6cf07..89222f9daf 100644 --- a/iroh-dns-server/src/config.rs +++ b/iroh-dns-server/src/config.rs @@ -71,8 +71,20 @@ pub struct MainlineConfig { pub enabled: bool, /// Set custom bootstrap nodes. /// + /// Addresses can either be `domain:port` or `ipv4:port`. + /// /// If empty this will use the default bittorrent mainline bootstrap nodes as defined by pkarr. - pub bootstrap: Vec, + pub bootstrap: Option>, +} + +/// Configure the bootstrap servers for mainline DHT resolution. +#[derive(Debug, Serialize, Deserialize, Default)] +pub enum BootstrapOption { + /// Use the default bootstrap servers. + #[default] + Default, + /// Use custom bootstrap servers. + Custom(Vec), } #[allow(clippy::derivable_impls)] @@ -80,7 +92,7 @@ impl Default for MainlineConfig { fn default() -> Self { Self { enabled: false, - bootstrap: vec![], + bootstrap: None, } } } @@ -128,11 +140,17 @@ impl Config { } } - pub(crate) fn mainline_enabled(&self) -> Option<&Vec> { + pub(crate) fn mainline_enabled(&self) -> Option { match self.mainline.as_ref() { None => None, - Some(config) if !config.enabled => None, - Some(config) => Some(&config.bootstrap), + Some(MainlineConfig { enabled: false, .. }) => None, + Some(MainlineConfig { + bootstrap: Some(bootstrap), + .. + }) => Some(BootstrapOption::Custom(bootstrap.clone())), + Some(MainlineConfig { + bootstrap: None, .. + }) => Some(BootstrapOption::Default), } } } diff --git a/iroh-dns-server/src/lib.rs b/iroh-dns-server/src/lib.rs index 1fe97a2604..663b909707 100644 --- a/iroh-dns-server/src/lib.rs +++ b/iroh-dns-server/src/lib.rs @@ -34,7 +34,7 @@ mod tests { use pkarr::{PkarrClient, SignedPacket}; use url::Url; - use crate::server::Server; + use crate::{config::BootstrapOption, server::Server}; #[tokio::test] async fn pkarr_publish_dns_resolve() -> Result<()> { @@ -186,15 +186,11 @@ mod tests { // run a mainline testnet let testnet = mainline::dht::Testnet::new(5); - let bootstrap = testnet - .bootstrap - .iter() - .map(|addr| SocketAddr::from_str(addr).unwrap()) - .collect::>(); + let bootstrap = testnet.bootstrap.clone(); // spawn our server with mainline support let (server, nameserver, _http_url) = - Server::spawn_for_tests_with_mainline(Some(bootstrap)).await?; + Server::spawn_for_tests_with_mainline(Some(BootstrapOption::Custom(bootstrap))).await?; let origin = "irohdns.example."; diff --git a/iroh-dns-server/src/server.rs b/iroh-dns-server/src/server.rs index 63bb5a0557..c9580fa121 100644 --- a/iroh-dns-server/src/server.rs +++ b/iroh-dns-server/src/server.rs @@ -97,9 +97,9 @@ impl Server { /// bootstrap addresses. #[cfg(test)] pub async fn spawn_for_tests_with_mainline( - bootstrap: Option>, + mainline: Option, ) -> Result<(Self, std::net::SocketAddr, url::Url)> { - use crate::config::{MainlineConfig, MetricsConfig}; + use crate::config::MetricsConfig; use std::net::{IpAddr, Ipv4Addr}; let mut config = Config::default(); @@ -109,16 +109,12 @@ impl Server { config.http.as_mut().unwrap().bind_addr = Some(IpAddr::V4(Ipv4Addr::LOCALHOST)); config.https = None; config.metrics = Some(MetricsConfig::disabled()); - config.mainline = bootstrap.map(|bootstrap| MainlineConfig { - enabled: true, - bootstrap, - }); let mut store = ZoneStore::in_memory()?; - if let Some(bootstrap) = config.mainline_enabled() { + if let Some(bootstrap) = mainline { info!("mainline fallback enabled"); store = store.with_mainline_fallback(bootstrap); - }; + } let server = Self::spawn(config, store).await?; let dns_addr = server.dns_server.local_addr(); let http_addr = server.http_server.http_addr().expect("http is set"); diff --git a/iroh-dns-server/src/store.rs b/iroh-dns-server/src/store.rs index 3dbf537efd..dd8d911911 100644 --- a/iroh-dns-server/src/store.rs +++ b/iroh-dns-server/src/store.rs @@ -1,9 +1,6 @@ //! Pkarr packet store used to resolve DNS queries. -use std::{ - collections::BTreeMap, net::SocketAddr, num::NonZeroUsize, path::Path, sync::Arc, - time::Duration, -}; +use std::{collections::BTreeMap, num::NonZeroUsize, path::Path, sync::Arc, time::Duration}; use anyhow::Result; use hickory_proto::rr::{Name, RecordSet, RecordType, RrKey}; @@ -15,6 +12,7 @@ use tracing::{debug, trace}; use ttl_cache::TtlCache; use crate::{ + config::BootstrapOption, metrics::Metrics, util::{signed_packet_to_hickory_records_without_origin, PublicKeyBytes}, }; @@ -64,15 +62,12 @@ impl ZoneStore { /// /// Optionally set custom bootstrap nodes. If `bootstrap` is empty it will use the default /// mainline bootstrap nodes. - pub fn with_mainline_fallback(self, bootstrap: &[SocketAddr]) -> Self { - let pkarr_client = if bootstrap.is_empty() { - PkarrClient::default() - } else { - let bootstrap = bootstrap - .iter() - .map(|addr| addr.to_string()) - .collect::>(); - PkarrClient::builder().bootstrap(&bootstrap).build() + pub fn with_mainline_fallback(self, bootstrap: BootstrapOption) -> Self { + let pkarr_client = match bootstrap { + BootstrapOption::Default => PkarrClient::default(), + BootstrapOption::Custom(bootstrap) => { + PkarrClient::builder().bootstrap(&bootstrap).build() + } }; Self { pkarr: Some(Arc::new(pkarr_client)),