Skip to content

Commit 5de61f3

Browse files
authored
[client] Fix dns ipv6 upstream (#4257)
1 parent 541e258 commit 5de61f3

File tree

2 files changed

+63
-5
lines changed

2 files changed

+63
-5
lines changed

client/internal/dns/server.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -586,10 +586,7 @@ func (s *DefaultServer) registerFallback(config HostDNSConfig) {
586586
continue
587587
}
588588

589-
ns = fmt.Sprintf("%s:%d", ns, defaultPort)
590-
if ip, err := netip.ParseAddr(ns); err == nil && ip.Is6() {
591-
ns = fmt.Sprintf("[%s]:%d", ns, defaultPort)
592-
}
589+
ns = formatAddr(ns, defaultPort)
593590

594591
handler.upstreamServers = append(handler.upstreamServers, ns)
595592
}
@@ -774,7 +771,15 @@ func (s *DefaultServer) updateMux(muxUpdates []handlerWrapper) {
774771
}
775772

776773
func getNSHostPort(ns nbdns.NameServer) string {
777-
return fmt.Sprintf("%s:%d", ns.IP.String(), ns.Port)
774+
return formatAddr(ns.IP.String(), ns.Port)
775+
}
776+
777+
// formatAddr formats a nameserver address with port, handling IPv6 addresses properly
778+
func formatAddr(address string, port int) string {
779+
if ip, err := netip.ParseAddr(address); err == nil && ip.Is6() {
780+
return fmt.Sprintf("[%s]:%d", address, port)
781+
}
782+
return fmt.Sprintf("%s:%d", address, port)
778783
}
779784

780785
// upstreamCallbacks returns two functions, the first one is used to deactivate

client/internal/dns/server_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,3 +2053,56 @@ func TestLocalResolverPriorityConstants(t *testing.T) {
20532053
assert.Equal(t, PriorityLocal, localMuxUpdates[0].priority, "Local handler should use PriorityLocal")
20542054
assert.Equal(t, "local.example.com", localMuxUpdates[0].domain)
20552055
}
2056+
2057+
func TestFormatAddr(t *testing.T) {
2058+
tests := []struct {
2059+
name string
2060+
address string
2061+
port int
2062+
expected string
2063+
}{
2064+
{
2065+
name: "IPv4 address",
2066+
address: "8.8.8.8",
2067+
port: 53,
2068+
expected: "8.8.8.8:53",
2069+
},
2070+
{
2071+
name: "IPv4 address with custom port",
2072+
address: "1.1.1.1",
2073+
port: 5353,
2074+
expected: "1.1.1.1:5353",
2075+
},
2076+
{
2077+
name: "IPv6 address",
2078+
address: "fd78:94bf:7df8::1",
2079+
port: 53,
2080+
expected: "[fd78:94bf:7df8::1]:53",
2081+
},
2082+
{
2083+
name: "IPv6 address with custom port",
2084+
address: "2001:db8::1",
2085+
port: 5353,
2086+
expected: "[2001:db8::1]:5353",
2087+
},
2088+
{
2089+
name: "IPv6 localhost",
2090+
address: "::1",
2091+
port: 53,
2092+
expected: "[::1]:53",
2093+
},
2094+
{
2095+
name: "Invalid address treated as hostname",
2096+
address: "dns.example.com",
2097+
port: 53,
2098+
expected: "dns.example.com:53",
2099+
},
2100+
}
2101+
2102+
for _, tt := range tests {
2103+
t.Run(tt.name, func(t *testing.T) {
2104+
result := formatAddr(tt.address, tt.port)
2105+
assert.Equal(t, tt.expected, result)
2106+
})
2107+
}
2108+
}

0 commit comments

Comments
 (0)