feat: resolve .numa services to LAN IP for remote clients #23

Merged
razvandimescu merged 3 commits from feat/lan-proxy-reachability into main 2026-03-30 04:15:42 +08:00
2 changed files with 21 additions and 4 deletions
Showing only changes of commit 1a6a2a5f31 - Show all commits

View File

@@ -108,12 +108,17 @@ pub async fn handle_query(
} else if !ctx.proxy_tld_suffix.is_empty()
&& (qname.ends_with(&ctx.proxy_tld_suffix) || qname == ctx.proxy_tld)
{
// Resolve .numa: local services → 127.0.0.1, LAN peers → peer IP
// Resolve .numa: remote clients get LAN IP (can't reach 127.0.0.1), local get loopback
let service_name = qname.strip_suffix(&ctx.proxy_tld_suffix).unwrap_or(&qname);
let is_remote = !src_addr.ip().is_loopback();
let resolve_ip = {
let local = ctx.services.lock().unwrap();
if local.lookup(service_name).is_some() {
if is_remote {
*ctx.lan_ip.lock().unwrap()
} else {
std::net::Ipv4Addr::LOCALHOST
}
} else {
let mut peers = ctx.lan_peers.lock().unwrap();
peers

View File

@@ -208,6 +208,7 @@ async fn main() -> numa::Result<()> {
});
let zone_count: usize = ctx.zone_map.values().map(|m| m.len()).sum();
let dns_is_public = config.server.bind_addr.starts_with("0.0.0.0");
// Build banner rows, then size the box to fit the longest value
let api_url = format!("http://localhost:{}", api_port);
@@ -308,6 +309,17 @@ async fn main() -> numa::Result<()> {
);
if let Some(ref label) = proxy_label {
row("Proxy", g, label);
if !config.lan.enabled && !dns_is_public && config.proxy.bind_addr == "127.0.0.1" {
let y = "\x1b[38;2;204;176;59m"; // yellow
row(
"",
y,
&format!(
"⚠ proxy on 127.0.0.1 — .{} not LAN reachable",
config.proxy.tld
),
);
}
}
if config.lan.enabled {
row("LAN", g, "mDNS (_numa._tcp.local)");
@@ -375,8 +387,8 @@ async fn main() -> numa::Result<()> {
axum::serve(listener, app).await.unwrap();
});
// Proxy binds 0.0.0.0 when LAN is enabled (cross-machine access), otherwise config value
let proxy_bind: std::net::Ipv4Addr = if config.lan.enabled {
// Proxy binds 0.0.0.0 when LAN is enabled or DNS is already on 0.0.0.0 (cross-machine access)
let proxy_bind: std::net::Ipv4Addr = if config.lan.enabled || dns_is_public {
std::net::Ipv4Addr::UNSPECIFIED
} else {
config