From 209c9211b97af7e25fa455d04f241261ee5f6c6c Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Mon, 26 Jan 2026 16:56:46 +0700 Subject: [PATCH] fix(dns): handle empty and invalid IP addresses gracefully Add guard checks to prevent panics when processing client info with empty IP addresses. Replace netip.MustParseAddr with ParseAddr to handle invalid IP addresses gracefully instead of panicking. Add test to verify queryFromSelf handles IP addresses safely. --- cmd/cli/dns_proxy.go | 14 ++++++++++++-- cmd/cli/dns_proxy_test.go | 10 ++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/cmd/cli/dns_proxy.go b/cmd/cli/dns_proxy.go index 9474b50..3d8cc30 100644 --- a/cmd/cli/dns_proxy.go +++ b/cmd/cli/dns_proxy.go @@ -910,7 +910,12 @@ func (p *prog) getClientInfo(remoteIP string, msg *dns.Msg) *ctrld.ClientInfo { } else { ci.Hostname = p.ciTable.LookupHostname(ci.IP, ci.Mac) } - ci.Self = p.queryFromSelf(ci.IP) + + if ci.IP == "" { + mainLog.Load().Debug().Msgf("client info entry with empty IP address: %v", ci) + } else { + ci.Self = p.queryFromSelf(ci.IP) + } // If this is a query from self, but ci.IP is not loopback IP, // try using hostname mapping for lookback IP if presents. if ci.Self { @@ -1026,7 +1031,12 @@ func (p *prog) queryFromSelf(ip string) bool { if val, ok := p.queryFromSelfMap.Load(ip); ok { return val.(bool) } - netIP := netip.MustParseAddr(ip) + netIP, err := netip.ParseAddr(ip) + if err != nil { + mainLog.Load().Debug().Err(err).Msgf("could not parse IP: %q", ip) + return false + } + regularIPs, loopbackIPs, err := netmon.LocalAddresses() if err != nil { mainLog.Load().Warn().Err(err).Msg("could not get local addresses") diff --git a/cmd/cli/dns_proxy_test.go b/cmd/cli/dns_proxy_test.go index 4a4e5b4..f909e96 100644 --- a/cmd/cli/dns_proxy_test.go +++ b/cmd/cli/dns_proxy_test.go @@ -464,3 +464,13 @@ func Test_isWanClient(t *testing.T) { }) } } + +func Test_prog_queryFromSelf(t *testing.T) { + p := &prog{} + require.NotPanics(t, func() { + p.queryFromSelf("") + }) + require.NotPanics(t, func() { + p.queryFromSelf("foo") + }) +}