From 24382271d6fb64e90c131d5c60b7dba44fea6380 Mon Sep 17 00:00:00 2001 From: lc6464 <64722907+lc6464@users.noreply.github.com> Date: Tue, 14 Apr 2026 15:17:27 +0800 Subject: [PATCH] fix(web): align wildcard advertise IP preference --- web/backend/main.go | 44 +++++++++++++++++++++++++++++++++++----- web/backend/main_test.go | 20 +++++++++++++++--- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/web/backend/main.go b/web/backend/main.go index 4318a8a4e..3ee47cb07 100644 --- a/web/backend/main.go +++ b/web/backend/main.go @@ -124,15 +124,49 @@ func hasWildcardBindHosts(bindHosts []string) bool { return false } -func wildcardAdvertiseIP(bindHosts []string, ipv4, ipv6 string) string { - if !hasWildcardBindHosts(bindHosts) { - return "" +func wildcardBindHostFamilies(bindHosts []string) (hasIPv4, hasIPv6 bool) { + for _, bindHost := range bindHosts { + host := strings.TrimSpace(bindHost) + if host == "" { + continue + } + + if !netbind.IsUnspecifiedHost(host) { + continue + } + + ip := net.ParseIP(strings.Trim(host, "[]")) + if ip == nil { + continue + } + if ip.To4() != nil { + hasIPv4 = true + continue + } + hasIPv6 = true } - if v6 := strings.TrimSpace(ipv6); v6 != "" { + return hasIPv4, hasIPv6 +} + +func wildcardAdvertiseIP(bindHosts []string, ipv4, ipv6 string) string { + hasIPv4Wildcard, hasIPv6Wildcard := wildcardBindHostFamilies(bindHosts) + v4 := strings.TrimSpace(ipv4) + v6 := strings.TrimSpace(ipv6) + + switch { + case hasIPv4Wildcard && hasIPv6Wildcard: + if v6 != "" { + return v6 + } + return v4 + case hasIPv6Wildcard: return v6 + case hasIPv4Wildcard: + return v4 + default: + return "" } - return strings.TrimSpace(ipv4) } func advertiseIPForWildcardBindHosts(bindHosts []string) string { diff --git a/web/backend/main_test.go b/web/backend/main_test.go index ea2a34104..e1702a61e 100644 --- a/web/backend/main_test.go +++ b/web/backend/main_test.go @@ -250,10 +250,17 @@ func TestWildcardAdvertiseIP(t *testing.T) { want string }{ { - name: "ipv4 wildcard prefers ipv6 when available", + name: "ipv4 wildcard uses ipv4", bindHosts: []string{"0.0.0.0"}, ipv4: "192.168.1.2", ipv6: "2001:db8::1", + want: "192.168.1.2", + }, + { + name: "dual wildcard prefers ipv6", + bindHosts: []string{"0.0.0.0", "::"}, + ipv4: "192.168.1.2", + ipv6: "2001:db8::1", want: "2001:db8::1", }, { @@ -264,12 +271,19 @@ func TestWildcardAdvertiseIP(t *testing.T) { want: "2001:db8::1", }, { - name: "ipv6 wildcard falls back to ipv4", - bindHosts: []string{"::"}, + name: "dual wildcard falls back to ipv4 when ipv6 missing", + bindHosts: []string{"0.0.0.0", "::"}, ipv4: "192.168.1.2", ipv6: "", want: "192.168.1.2", }, + { + name: "ipv6 wildcard without ipv6 does not advertise ipv4", + bindHosts: []string{"::"}, + ipv4: "192.168.1.2", + ipv6: "", + want: "", + }, { name: "non wildcard does not advertise", bindHosts: []string{"127.0.0.1"},