feat: resolve .numa services to LAN IP for remote clients
Remote DNS clients (e.g. phones on same WiFi) received 127.0.0.1 for local .numa services, which is unreachable from their perspective. Now returns the host's LAN IP when the query originates from a non-loopback address. Also auto-widens proxy bind to 0.0.0.0 when DNS is already public, and adds a startup warning when the proxy remains localhost-only. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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() {
|
||||
std::net::Ipv4Addr::LOCALHOST
|
||||
if is_remote {
|
||||
*ctx.lan_ip.lock().unwrap()
|
||||
} else {
|
||||
std::net::Ipv4Addr::LOCALHOST
|
||||
}
|
||||
} else {
|
||||
let mut peers = ctx.lan_peers.lock().unwrap();
|
||||
peers
|
||||
|
||||
16
src/main.rs
16
src/main.rs
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user