mirror of
https://github.com/redis/go-redis.git
synced 2025-09-02 22:01:16 +03:00
fix(client): Do not assume that all non-IP hosts are loopbacks (#3085)
* Do not assume that all non-IP hosts are loopbacks * handle localhost and Docker internal hostnames --------- Co-authored-by: Nedyalko Dyakov <nedyalko.dyakov@gmail.com> Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com> Co-authored-by: ofekshenawa <ofek.shenawa@redis.com> Co-authored-by: ofekshenawa <104765379+ofekshenawa@users.noreply.github.com>
This commit is contained in:
@@ -383,3 +383,38 @@ var _ = Describe("ClusterClient", func() {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("isLoopback", func() {
|
||||
DescribeTable("should correctly identify loopback addresses",
|
||||
func(host string, expected bool) {
|
||||
result := isLoopback(host)
|
||||
Expect(result).To(Equal(expected))
|
||||
},
|
||||
// IP addresses
|
||||
Entry("IPv4 loopback", "127.0.0.1", true),
|
||||
Entry("IPv6 loopback", "::1", true),
|
||||
Entry("IPv4 non-loopback", "192.168.1.1", false),
|
||||
Entry("IPv6 non-loopback", "2001:db8::1", false),
|
||||
|
||||
// Well-known loopback hostnames
|
||||
Entry("localhost lowercase", "localhost", true),
|
||||
Entry("localhost uppercase", "LOCALHOST", true),
|
||||
Entry("localhost mixed case", "LocalHost", true),
|
||||
|
||||
// Docker-specific loopbacks
|
||||
Entry("host.docker.internal", "host.docker.internal", true),
|
||||
Entry("HOST.DOCKER.INTERNAL", "HOST.DOCKER.INTERNAL", true),
|
||||
Entry("custom.docker.internal", "custom.docker.internal", true),
|
||||
Entry("app.docker.internal", "app.docker.internal", true),
|
||||
|
||||
// Non-loopback hostnames
|
||||
Entry("redis hostname", "redis-cluster", false),
|
||||
Entry("FQDN", "redis.example.com", false),
|
||||
Entry("docker but not internal", "redis.docker.com", false),
|
||||
|
||||
// Edge cases
|
||||
Entry("empty string", "", false),
|
||||
Entry("invalid IP", "256.256.256.256", false),
|
||||
Entry("partial docker internal", "docker.internal", false),
|
||||
)
|
||||
})
|
||||
|
@@ -781,12 +781,25 @@ func replaceLoopbackHost(nodeAddr, originHost string) string {
|
||||
return net.JoinHostPort(originHost, nodePort)
|
||||
}
|
||||
|
||||
// isLoopback returns true if the host is a loopback address.
|
||||
// For IP addresses, it uses net.IP.IsLoopback().
|
||||
// For hostnames, it recognizes well-known loopback hostnames like "localhost"
|
||||
// and Docker-specific loopback patterns like "*.docker.internal".
|
||||
func isLoopback(host string) bool {
|
||||
ip := net.ParseIP(host)
|
||||
if ip == nil {
|
||||
if ip != nil {
|
||||
return ip.IsLoopback()
|
||||
}
|
||||
|
||||
if strings.ToLower(host) == "localhost" {
|
||||
return true
|
||||
}
|
||||
return ip.IsLoopback()
|
||||
|
||||
if strings.HasSuffix(strings.ToLower(host), ".docker.internal") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *clusterState) slotMasterNode(slot int) (*clusterNode, error) {
|
||||
|
Reference in New Issue
Block a user