0
0
mirror of https://github.com/cjdelisle/cjdns synced 2025-10-06 00:32:50 +02:00

Make the DNS seeder round robin between different DNS options, including the system's default.

This commit is contained in:
Caleb James DeLisle
2024-09-27 12:51:43 +02:00
parent f5a6188ba6
commit 9c1044e59a

View File

@@ -7,7 +7,9 @@ use byteorder::{ReadBytesExt,WriteBytesExt,BE};
use ipnetwork::{Ipv4Network,Ipv6Network};
use cjdns::bytes::{dnsseed::{CjdnsPeer, CjdnsTxtRecord}, message::Message as RMessage};
use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
use trust_dns_resolver::{
config::{ResolverConfig, ResolverOpts}, name_server::{GenericConnector,TokioRuntimeProvider}, AsyncResolver
};
use crate::{bytestring::ByteString, cffi::{self, Control_LlAddr_Udp4_t, Control_LlAddr_Udp6_t, Control_LlAddr_t, PFChan_Node}, external::interface::iface::{Iface, IfacePvt}, interface::wire::message::Message, util::now_ms};
@@ -19,6 +21,7 @@ struct SeederState {
tried_peers: Vec<(CjdnsPeer,u64)>,
last_get_peers: u64,
last_dns_req: u64,
dns_attempt_n: usize,
recommended_snode: Option<CJDNSPublicKey>,
}
@@ -29,6 +32,12 @@ struct SeederInner {
ifacep: IfacePvt,
send_message: mpsc::Sender<Message>,
my_pubkey: PublicKey,
// TODO(cjd): We can only read /etc/resolv.conf BEFORE we chroot(), so we're reading it at startup.
// If it changes while we're running, we're SOL for further seeding. The effect of this is
// if you launch while offline, then you connect to an environment where google/cf/quad9 is
// blocked but DNS does work, it will not pick up the DNS and use it.
// The fix for this is to use a separate process which is not chrooted and does necessary tasks.
system_resolver: std::io::Result<(ResolverConfig, ResolverOpts)>,
}
impl SeederInner {
@@ -81,6 +90,27 @@ impl SeederInner {
}
}
fn get_resolver(self: &Arc<Self>, st: &mut SeederState) -> Result<AsyncResolver<GenericConnector<TokioRuntimeProvider>>> {
let mut n = st.dns_attempt_n % 4;
st.dns_attempt_n += 1;
if n == 0 {
if let Ok((cfg, opts)) = &self.system_resolver {
return Ok(AsyncResolver::tokio(cfg.clone(), *opts));
} else {
st.dns_attempt_n += 1;
n += 1;
}
}
let mut ro = ResolverOpts::default();
ro.try_tcp_on_error = true;
Ok(match n {
1 => AsyncResolver::tokio(ResolverConfig::google(), ro),
2 => AsyncResolver::tokio(ResolverConfig::cloudflare(), ro),
3 => AsyncResolver::tokio(ResolverConfig::quad9(), ro),
_ => bail!("Logic error in get_resolver()"),
})
}
async fn cycle(self: &Arc<Self>, st: &mut SeederState) -> Result<()> {
// Sync locks
@@ -126,10 +156,7 @@ impl SeederInner {
}.cloned()
} {
log::debug!("Trying seed {seed}");
let resolver =
trust_dns_resolver::AsyncResolver::tokio(
ResolverConfig::default(),
ResolverOpts::default());
let resolver = self.get_resolver(st)?;
let res = resolver.txt_lookup(&seed).await
.with_context(||format!("Failed dns lookup for {seed}"))?;
@@ -508,6 +535,7 @@ impl Seeder {
snode_peers: Default::default(),
dns_seeds: Default::default(),
ifacep,
system_resolver: trust_dns_resolver::system_conf::read_system_conf(),
});
iface.set_receiver_f(incoming_event, Arc::clone(&inner));
tokio::task::spawn(Arc::clone(&inner).run(recv_message, done_r));