mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-20 13:30:46 +02:00
ReplicaReceiver.DataAddr()/CtrlAddr() now return canonical ip:port instead of raw listener addresses that may be wildcard (:port, 0.0.0.0:port, [::]:port). New canonicalizeListenerAddr() resolves wildcard IPs using the provided advertised host (from VS listen address). Falls back to outbound-IP detection when no advertised host is available. NewReplicaReceiver accepts optional advertisedHost parameter for multi-NIC correctness. In production, the assignment path already provides canonical addresses; this fix ensures test patterns with :0 bind also produce routable addresses. 7 new tests. TestBug3_ReplicaAddr_MustBeIPPort_WildcardBind flips from FAIL to PASS. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
74 lines
2.2 KiB
Go
74 lines
2.2 KiB
Go
package blockvol
|
|
|
|
import (
|
|
"net"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestCanonicalizeAddr_WildcardIPv4_UsesAdvertised(t *testing.T) {
|
|
addr := &net.TCPAddr{IP: net.IPv4zero, Port: 5099}
|
|
result := canonicalizeListenerAddr(addr, "192.168.1.184")
|
|
if result != "192.168.1.184:5099" {
|
|
t.Fatalf("expected 192.168.1.184:5099, got %q", result)
|
|
}
|
|
}
|
|
|
|
func TestCanonicalizeAddr_WildcardIPv6_UsesAdvertised(t *testing.T) {
|
|
addr := &net.TCPAddr{IP: net.IPv6zero, Port: 5099}
|
|
result := canonicalizeListenerAddr(addr, "10.0.0.3")
|
|
if result != "10.0.0.3:5099" {
|
|
t.Fatalf("expected 10.0.0.3:5099, got %q", result)
|
|
}
|
|
}
|
|
|
|
func TestCanonicalizeAddr_NilIP_UsesAdvertised(t *testing.T) {
|
|
addr := &net.TCPAddr{IP: nil, Port: 5099}
|
|
result := canonicalizeListenerAddr(addr, "192.168.1.184")
|
|
if result != "192.168.1.184:5099" {
|
|
t.Fatalf("expected 192.168.1.184:5099, got %q", result)
|
|
}
|
|
}
|
|
|
|
func TestCanonicalizeAddr_AlreadyCanonical_Unchanged(t *testing.T) {
|
|
addr := &net.TCPAddr{IP: net.ParseIP("192.168.1.5"), Port: 5099}
|
|
result := canonicalizeListenerAddr(addr, "10.0.0.1")
|
|
if result != "192.168.1.5:5099" {
|
|
t.Fatalf("expected 192.168.1.5:5099 (unchanged), got %q", result)
|
|
}
|
|
}
|
|
|
|
func TestCanonicalizeAddr_Loopback_Unchanged(t *testing.T) {
|
|
addr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 3260}
|
|
result := canonicalizeListenerAddr(addr, "192.168.1.184")
|
|
if result != "127.0.0.1:3260" {
|
|
t.Fatalf("expected 127.0.0.1:3260 (loopback intentional), got %q", result)
|
|
}
|
|
}
|
|
|
|
func TestCanonicalizeAddr_NoAdvertised_FallsBackToOutbound(t *testing.T) {
|
|
addr := &net.TCPAddr{IP: net.IPv4zero, Port: 5099}
|
|
result := canonicalizeListenerAddr(addr, "")
|
|
// Should not be wildcard.
|
|
if strings.HasPrefix(result, "0.0.0.0:") || strings.HasPrefix(result, "[::]:") || strings.HasPrefix(result, ":") {
|
|
t.Fatalf("fallback should produce routable addr, got %q", result)
|
|
}
|
|
if !strings.Contains(result, ":5099") {
|
|
t.Fatalf("port should be preserved, got %q", result)
|
|
}
|
|
}
|
|
|
|
func TestPreferredOutboundIP_NotEmpty(t *testing.T) {
|
|
ip := preferredOutboundIP()
|
|
if ip == "" {
|
|
t.Skip("no network interface available")
|
|
}
|
|
parsed := net.ParseIP(ip)
|
|
if parsed == nil {
|
|
t.Fatalf("not a valid IP: %q", ip)
|
|
}
|
|
if parsed.IsUnspecified() {
|
|
t.Fatalf("returned unspecified IP: %q", ip)
|
|
}
|
|
}
|