mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 08:14:42 +00:00
Add host-to-npub static mapping with DNS hostname resolution
Add a HostMap that resolves human-readable hostnames to npubs, enabling `gateway.fips` instead of the full `npub1...xyz.fips`. Two sources populate the map: peer `alias` fields from the YAML config and an operator-maintained hosts file at /etc/fips/hosts. The DNS responder auto-reloads the hosts file on each request by checking the file modification time, so operators can update mappings without restarting the daemon. - New src/upper/hosts.rs: HostMap, HostMapReloader, hostname validation, hosts file parser with auto-reload on mtime change - DNS resolver checks host map before falling back to direct npub - Node uses host map for peer display names - Default hosts file added to both .deb and tarball packaging - 26 new tests (789 total)
This commit is contained in:
@@ -448,10 +448,13 @@ impl Node {
|
||||
let dns_channel_size = self.config.node.buffers.dns_channel;
|
||||
let (identity_tx, identity_rx) = tokio::sync::mpsc::channel(dns_channel_size);
|
||||
let dns_ttl = self.config.dns.ttl();
|
||||
let handle = tokio::spawn(crate::upper::dns::run_dns_responder(socket, identity_tx, dns_ttl));
|
||||
let base_hosts = crate::upper::hosts::HostMap::from_peer_configs(self.config.peers());
|
||||
let hosts_path = std::path::PathBuf::from(crate::upper::hosts::DEFAULT_HOSTS_PATH);
|
||||
let reloader = crate::upper::hosts::HostMapReloader::new(base_hosts, hosts_path);
|
||||
info!(bind = %bind, hosts = reloader.hosts().len(), "DNS responder started for .fips domain (auto-reload enabled)");
|
||||
let handle = tokio::spawn(crate::upper::dns::run_dns_responder(socket, identity_tx, dns_ttl, reloader));
|
||||
self.dns_identity_rx = Some(identity_rx);
|
||||
self.dns_task = Some(handle);
|
||||
info!(bind = %bind, "DNS responder started for .fips domain");
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(bind = %bind, error = %e, "Failed to start DNS responder");
|
||||
|
||||
+26
-4
@@ -33,6 +33,7 @@ use crate::transport::tcp::TcpTransport;
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::transport::ethernet::EthernetTransport;
|
||||
use crate::tree::TreeState;
|
||||
use crate::upper::hosts::HostMap;
|
||||
use crate::upper::icmp_rate_limit::IcmpRateLimiter;
|
||||
use crate::upper::tun::{TunError, TunOutboundRx, TunState, TunTx};
|
||||
use self::wire::{build_encrypted, build_established_header, prepend_inner_header, FLAG_CE, FLAG_KEY_EPOCH, FLAG_SP};
|
||||
@@ -40,6 +41,7 @@ use crate::{Config, ConfigError, Identity, IdentityError, NodeAddr, PeerIdentity
|
||||
use rand::Rng;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use std::thread::JoinHandle;
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -380,6 +382,11 @@ pub struct Node {
|
||||
/// Human-readable names for configured peers (alias or short npub).
|
||||
/// Populated at startup from peer config.
|
||||
peer_aliases: HashMap<NodeAddr, String>,
|
||||
|
||||
// === Host Map ===
|
||||
/// Static hostname → npub mapping for DNS resolution.
|
||||
/// Built at construction from peer aliases and /etc/fips/hosts.
|
||||
host_map: Arc<HostMap>,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
@@ -433,6 +440,13 @@ impl Node {
|
||||
let max_links = config.node.limits.max_links;
|
||||
let coords_response_interval_ms = config.node.session.coords_response_interval_ms;
|
||||
|
||||
let mut host_map = HostMap::from_peer_configs(config.peers());
|
||||
let hosts_file = HostMap::load_hosts_file(std::path::Path::new(
|
||||
crate::upper::hosts::DEFAULT_HOSTS_PATH,
|
||||
));
|
||||
host_map.merge(hosts_file);
|
||||
let host_map = Arc::new(host_map);
|
||||
|
||||
Ok(Self {
|
||||
identity,
|
||||
startup_epoch,
|
||||
@@ -483,6 +497,7 @@ impl Node {
|
||||
last_parent_reeval: None,
|
||||
last_congestion_log: None,
|
||||
peer_aliases: HashMap::new(),
|
||||
host_map,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -530,6 +545,8 @@ impl Node {
|
||||
let max_links = config.node.limits.max_links;
|
||||
let coords_response_interval_ms = config.node.session.coords_response_interval_ms;
|
||||
|
||||
let host_map = Arc::new(HostMap::new());
|
||||
|
||||
Self {
|
||||
identity,
|
||||
startup_epoch,
|
||||
@@ -580,6 +597,7 @@ impl Node {
|
||||
last_parent_reeval: None,
|
||||
last_congestion_log: None,
|
||||
peer_aliases: HashMap::new(),
|
||||
host_map,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,11 +748,15 @@ impl Node {
|
||||
/// Return a human-readable display name for a NodeAddr.
|
||||
///
|
||||
/// Lookup order:
|
||||
/// 1. Configured peer alias or short npub (from startup map)
|
||||
/// 2. Active peer's short npub (e.g., inbound peer not in config)
|
||||
/// 3. Session endpoint's short npub (end-to-end, may not be direct peer)
|
||||
/// 4. Truncated NodeAddr hex (unknown address)
|
||||
/// 1. Host map hostname (from peer aliases + /etc/fips/hosts)
|
||||
/// 2. Configured peer alias or short npub (from startup map)
|
||||
/// 3. Active peer's short npub (e.g., inbound peer not in config)
|
||||
/// 4. Session endpoint's short npub (end-to-end, may not be direct peer)
|
||||
/// 5. Truncated NodeAddr hex (unknown address)
|
||||
pub(crate) fn peer_display_name(&self, addr: &NodeAddr) -> String {
|
||||
if let Some(hostname) = self.host_map.lookup_hostname(addr) {
|
||||
return hostname.to_string();
|
||||
}
|
||||
if let Some(name) = self.peer_aliases.get(addr) {
|
||||
return name.clone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user