mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-15 10:25:40 +00:00
fix: replace stale magic DNS records on IP change (#1906)
Magic DNS updates are full snapshots, so appending routes keeps old IPs and returns duplicate A records. Replace each client's previous routes on update and add a regression test to ensure hostname resolution keeps only the latest IP.
This commit is contained in:
@@ -140,6 +140,19 @@ impl MagicDnsServerInstanceData {
|
||||
}
|
||||
}
|
||||
|
||||
async fn keep_zone_authoritative(&self, zone: &str) {
|
||||
if let Err(e) = self
|
||||
.update_dns_records(std::iter::empty::<&Route>(), zone)
|
||||
.await
|
||||
{
|
||||
tracing::error!(
|
||||
"Failed to keep DNS zone {} authoritative after route prune: {:?}",
|
||||
zone,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn do_system_config(&self, zone: &str) -> Result<(), anyhow::Error> {
|
||||
if let Some(c) = &self.system_config {
|
||||
c.set_dns(&OSConfig {
|
||||
@@ -183,10 +196,25 @@ impl MagicDnsServerRpc for MagicDnsServerInstanceData {
|
||||
return Err(anyhow::anyhow!("No remote addr").into());
|
||||
};
|
||||
let zone = input.zone.clone();
|
||||
self.route_infos
|
||||
.entry(zone.clone())
|
||||
.or_default()
|
||||
.insert_many(remote_addr.clone().into(), input.routes);
|
||||
let remote_addr: url::Url = remote_addr.clone().into();
|
||||
let mut zone_removed = false;
|
||||
|
||||
if let Some(mut routes_by_addr) = self.route_infos.get_mut(&zone) {
|
||||
routes_by_addr.remove(&remote_addr);
|
||||
if !input.routes.is_empty() {
|
||||
routes_by_addr.insert_many(remote_addr, input.routes);
|
||||
}
|
||||
zone_removed = routes_by_addr.is_empty();
|
||||
} else if !input.routes.is_empty() {
|
||||
let mut routes_by_addr = MultiMap::new();
|
||||
routes_by_addr.insert_many(remote_addr, input.routes);
|
||||
self.route_infos.insert(zone.clone(), routes_by_addr);
|
||||
}
|
||||
|
||||
if zone_removed {
|
||||
self.route_infos.remove(&zone);
|
||||
self.keep_zone_authoritative(&zone).await;
|
||||
}
|
||||
|
||||
self.update().await;
|
||||
Ok(Default::default())
|
||||
@@ -438,11 +466,19 @@ impl RpcServerHook for MagicDnsServerInstanceData {
|
||||
return;
|
||||
};
|
||||
let remote_addr = remote_addr.into();
|
||||
let mut removed_zones = vec![];
|
||||
for mut item in self.route_infos.iter_mut() {
|
||||
item.value_mut().remove(&remote_addr);
|
||||
if item.value().is_empty() {
|
||||
removed_zones.push(item.key().clone());
|
||||
}
|
||||
}
|
||||
for zone in &removed_zones {
|
||||
self.route_infos.remove(zone);
|
||||
}
|
||||
for zone in removed_zones {
|
||||
self.keep_zone_authoritative(&zone).await;
|
||||
}
|
||||
self.route_infos.retain(|_, v| !v.is_empty());
|
||||
self.route_infos.shrink_to_fit();
|
||||
self.update().await;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user