refactor: collapse port53 advisory to single flat path
The per-platform cause sentences were cosmetic — they didn't change the user's actions (install, or bind_addr on a non-privileged port), but they introduced duplicated "another process..." strings, a dead-from-CI branch (is_systemd_resolved_active() == true is never reached by any test), and a pub visibility bump on is_systemd_resolved_active for a single caller. Replace with one flat format! whose cause line mentions both systemd-resolved and the Windows DNS Client inline. The existing smoke test now exercises 100% of the function. is_systemd_resolved_active reverts to private. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -56,58 +56,37 @@ pub fn is_port_53(bind_addr: &str) -> bool {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Human-readable diagnostic for port-53 bind conflicts. Explains the
|
/// Human-readable diagnostic for port-53 bind conflicts. Offers two
|
||||||
/// likely cause on the current platform and offers two concrete fixes:
|
/// concrete fixes: install Numa as the system resolver, or bind to a
|
||||||
/// install Numa as the system resolver, or test on a non-privileged port.
|
/// non-privileged port.
|
||||||
pub fn port53_conflict_advisory(bind_addr: &str) -> String {
|
pub fn port53_conflict_advisory(bind_addr: &str) -> String {
|
||||||
let o = "\x1b[1;38;2;192;98;58m"; // bold orange
|
let o = "\x1b[1;38;2;192;98;58m"; // bold orange
|
||||||
let r = "\x1b[0m";
|
let r = "\x1b[0m";
|
||||||
let mut msg = format!(
|
format!(
|
||||||
"\n{o}Numa{r} — cannot bind to {}: port 53 is already in use.\n\n",
|
"
|
||||||
bind_addr
|
{o}Numa{r} — cannot bind to {bind_addr}: port 53 is already in use.
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
Another process is already bound to port 53. On Linux this is
|
||||||
{
|
typically systemd-resolved; on Windows, the DNS Client service.
|
||||||
if is_systemd_resolved_active() {
|
|
||||||
msg.push_str(
|
|
||||||
" systemd-resolved is holding port 53 via its stub listener\n \
|
|
||||||
(127.0.0.53:53), which blocks bind(0.0.0.0:53) on Linux.\n\n",
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
msg.push_str(
|
|
||||||
" Another process is holding port 53 on this host.\n \
|
|
||||||
Check with: sudo ss -lntu 'sport = :53'\n\n",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
Fix — pick one:
|
||||||
{
|
|
||||||
msg.push_str(" Windows DNS Client (Dnscache) holds port 53 at the kernel level.\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "linux", windows)))]
|
1. Install Numa as the system resolver (frees port 53):
|
||||||
{
|
|
||||||
msg.push_str(" Another process on this host is already bound to port 53.\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.push_str(" Fix — pick one:\n\n");
|
sudo numa install (on Windows, run as Administrator)
|
||||||
msg.push_str(" 1. Install Numa as the system resolver (frees port 53):\n");
|
|
||||||
#[cfg(windows)]
|
|
||||||
msg.push_str(" numa install (run as Administrator)\n\n");
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
msg.push_str(" sudo numa install\n\n");
|
|
||||||
|
|
||||||
msg.push_str(" 2. Test without privileges on a non-standard port.\n");
|
2. Run on a non-privileged port for testing.
|
||||||
msg.push_str(" Create ~/.config/numa/numa.toml with:\n\n");
|
Create ~/.config/numa/numa.toml with:
|
||||||
msg.push_str(" [server]\n");
|
|
||||||
msg.push_str(" bind_addr = \"127.0.0.1:5354\"\n");
|
|
||||||
msg.push_str(" api_port = 5380\n\n");
|
|
||||||
msg.push_str(" Then run: numa\n");
|
|
||||||
msg.push_str(" Test with: dig @127.0.0.1 -p 5354 example.com\n\n");
|
|
||||||
|
|
||||||
msg
|
[server]
|
||||||
|
bind_addr = \"127.0.0.1:5354\"
|
||||||
|
api_port = 5380
|
||||||
|
|
||||||
|
Then run: numa
|
||||||
|
Test with: dig @127.0.0.1 -p 5354 example.com
|
||||||
|
|
||||||
|
"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
@@ -1258,7 +1237,7 @@ fn backup_path_linux() -> std::path::PathBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn is_systemd_resolved_active() -> bool {
|
fn is_systemd_resolved_active() -> bool {
|
||||||
std::process::Command::new("systemctl")
|
std::process::Command::new("systemctl")
|
||||||
.args(["is-active", "--quiet", "systemd-resolved"])
|
.args(["is-active", "--quiet", "systemd-resolved"])
|
||||||
.status()
|
.status()
|
||||||
|
|||||||
Reference in New Issue
Block a user