From e556e3336e9ccae1af349001afada6bd4de1ff78 Mon Sep 17 00:00:00 2001 From: kph7 <40610313+kph7@users.noreply.github.com> Date: Thu, 28 Jun 2018 00:29:27 -0700 Subject: [PATCH] Adding IPv6 support to peering (#1818) --- node/node.go | 2 +- p2p/listener.go | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/node/node.go b/node/node.go index 6e4f7df0..8accc766 100644 --- a/node/node.go +++ b/node/node.go @@ -696,7 +696,7 @@ func (n *Node) makeNodeInfo(nodeID p2p.ID) p2p.NodeInfo { } p2pListener := n.sw.Listeners()[0] - p2pHost := p2pListener.ExternalAddress().IP.String() + p2pHost := p2pListener.ExternalAddressToString() p2pPort := p2pListener.ExternalAddress().Port nodeInfo.ListenAddr = cmn.Fmt("%v:%v", p2pHost, p2pPort) diff --git a/p2p/listener.go b/p2p/listener.go index 3d2fae74..35ef0371 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "strconv" + "strings" "time" "github.com/tendermint/tendermint/p2p/upnp" @@ -15,6 +16,7 @@ type Listener interface { Connections() <-chan net.Conn InternalAddress() *NetAddress ExternalAddress() *NetAddress + ExternalAddressToString() string String() string Stop() error } @@ -159,6 +161,15 @@ func (l *DefaultListener) ExternalAddress() *NetAddress { return l.extAddr } +func (l *DefaultListener) ExternalAddressToString() string { + ip := l.ExternalAddress().IP + if isIpv6(ip) { + // Means it's ipv6, so format it with brackets + return "[" + ip.String() + "]" + } + return ip.String() +} + // NOTE: The returned listener is already Accept()'ing. // So it's not suitable to pass into http.Serve(). func (l *DefaultListener) NetListener() net.Listener { @@ -201,6 +212,18 @@ func getUPNPExternalAddress(externalPort, internalPort int, logger log.Logger) * return NewNetAddressIPPort(ext, uint16(externalPort)) } +func isIpv6(ip net.IP) bool { + v4 := ip.To4() + if v4 != nil { + return false + } + + ipString := ip.String() + + // Extra check just to be sure it's IPv6 + return (strings.Contains(ipString, ":") && !strings.Contains(ipString, ".")) +} + // TODO: use syscalls: see issue #712 func getNaiveExternalAddress(port int, settleForLocal bool, logger log.Logger) *NetAddress { addrs, err := net.InterfaceAddrs() @@ -213,10 +236,16 @@ func getNaiveExternalAddress(port int, settleForLocal bool, logger log.Logger) * if !ok { continue } - v4 := ipnet.IP.To4() - if v4 == nil || (!settleForLocal && v4[0] == 127) { + if !isIpv6(ipnet.IP) { + v4 := ipnet.IP.To4() + if v4 == nil || (!settleForLocal && v4[0] == 127) { + // loopback + continue + } + } else if !settleForLocal && ipnet.IP.IsLoopback() { + // IPv6, check for loopback continue - } // loopback + } return NewNetAddressIPPort(ipnet.IP, uint16(port)) }