Skip to content

Commit

Permalink
Merge pull request #839 from go-redis/fix/cluster-loopback-fix
Browse files Browse the repository at this point in the history
Fix cluster loopback handling. Fixes #589
  • Loading branch information
vmihailenco authored Aug 15, 2018
2 parents 03f0590 + c1c2753 commit ef3e0e9
Showing 1 changed file with 32 additions and 40 deletions.
72 changes: 32 additions & 40 deletions cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,13 +438,15 @@ func newClusterState(
createdAt: time.Now(),
}

isLoopbackOrigin := isLoopbackAddr(origin)
originHost, _, _ := net.SplitHostPort(origin)
isLoopbackOrigin := isLoopback(originHost)

for _, slot := range slots {
var nodes []*clusterNode
for i, slotNode := range slot.Nodes {
addr := slotNode.Addr
if !isLoopbackOrigin && useOriginAddr(origin, addr) {
addr = origin
if !isLoopbackOrigin {
addr = replaceLoopbackHost(addr, originHost)
}

node, err := c.nodes.GetOrCreate(addr)
Expand Down Expand Up @@ -478,6 +480,33 @@ func newClusterState(
return &c, nil
}

func replaceLoopbackHost(nodeAddr, originHost string) string {
nodeHost, nodePort, err := net.SplitHostPort(nodeAddr)
if err != nil {
return nodeAddr
}

nodeIP := net.ParseIP(nodeHost)
if nodeIP == nil {
return nodeAddr
}

if !nodeIP.IsLoopback() {
return nodeAddr
}

// Use origin host which is not loopback and node port.
return net.JoinHostPort(originHost, nodePort)
}

func isLoopback(host string) bool {
ip := net.ParseIP(host)
if ip == nil {
return true
}
return ip.IsLoopback()
}

func (c *clusterState) slotMasterNode(slot int) (*clusterNode, error) {
nodes := c.slotNodes(slot)
if len(nodes) > 0 {
Expand Down Expand Up @@ -1565,43 +1594,6 @@ func (c *ClusterClient) PSubscribe(channels ...string) *PubSub {
return pubsub
}

func useOriginAddr(originAddr, nodeAddr string) bool {
nodeHost, nodePort, err := net.SplitHostPort(nodeAddr)
if err != nil {
return false
}

nodeIP := net.ParseIP(nodeHost)
if nodeIP == nil {
return false
}

if !nodeIP.IsLoopback() {
return false
}

_, originPort, err := net.SplitHostPort(originAddr)
if err != nil {
return false
}

return nodePort == originPort
}

func isLoopbackAddr(addr string) bool {
host, _, err := net.SplitHostPort(addr)
if err != nil {
return false
}

ip := net.ParseIP(host)
if ip == nil {
return false
}

return ip.IsLoopback()
}

func appendUniqueNode(nodes []*clusterNode, node *clusterNode) []*clusterNode {
for _, n := range nodes {
if n == node {
Expand Down

0 comments on commit ef3e0e9

Please sign in to comment.