diff --git a/beacon-chain/p2p/discovery.go b/beacon-chain/p2p/discovery.go index 045bc3b006..5ae09b1281 100644 --- a/beacon-chain/p2p/discovery.go +++ b/beacon-chain/p2p/discovery.go @@ -4,7 +4,6 @@ import ( "bytes" "crypto/ecdsa" "net" - "strconv" "time" "github.com/ethereum/go-ethereum/p2p/discover" @@ -98,25 +97,31 @@ func (s *Service) createListener( ipAddr net.IP, privKey *ecdsa.PrivateKey, ) (*discover.UDPv5, error) { - // assume ip is either ipv4 or ipv6 - networkVersion := "" + // Listen to all network interfaces + // for both ip protocols. + var networkVersion string + // BindIP is used to specify the ip + // on which we will bind our listener on + // by default we will listen to all interfaces. + var bindIP net.IP if ipAddr.To4() != nil { networkVersion = "udp4" + bindIP = net.IPv4zero } else { networkVersion = "udp6" + bindIP = net.IPv6zero } - // Check for the real local address which may - // be different in the presence of virtual networks. - ipAddr = s.localAddress(networkVersion, ipAddr) + // If local ip is specified then use that instead. if s.cfg.LocalIP != "" { ipAddr = net.ParseIP(s.cfg.LocalIP) if ipAddr == nil { return nil, errors.New("invalid local ip provided") } + bindIP = ipAddr } udpAddr := &net.UDPAddr{ - IP: ipAddr, + IP: bindIP, Port: int(s.cfg.UDPPort), } conn, err := net.ListenUDP(networkVersion, udpAddr) @@ -126,7 +131,7 @@ func (s *Service) createListener( localNode, err := s.createLocalNode( privKey, - udpAddr.IP, + ipAddr, int(s.cfg.UDPPort), int(s.cfg.TCPPort), ) @@ -185,6 +190,7 @@ func (s *Service) createLocalNode( return nil, errors.Wrap(err, "could not open node's peer database") } localNode := enode.NewLocalNode(db, privKey) + ipEntry := enr.IP(ipAddr) udpEntry := enr.UDP(udpPort) tcpEntry := enr.TCP(tcpPort) @@ -275,37 +281,6 @@ func (s *Service) isPeerAtLimit() bool { return activePeers >= maxPeers || numOfConns >= maxPeers } -// retrieve real local address of the node. In the event -// that is not possible we return the provided ip. -func (s *Service) localAddress(network string, addr net.IP) net.IP { - if len(s.cfg.BootstrapNodeAddr) == 0 { - return addr - } - // Dial the first bootnode to determine our 'real' local address. - bootNode, err := enode.Parse(enode.ValidSchemes, s.cfg.BootstrapNodeAddr[0]) - if err != nil { - log.Error("Could not parse bootnode address") - return addr - } - conn, err := net.DialTimeout(network, net.JoinHostPort(bootNode.IP().String(), strconv.Itoa(bootNode.UDP())), dialTimeout) - if err != nil { - log.Error("Could not dial remote peer") - return addr - } - defer func() { - if err := conn.Close(); err != nil { - log.Error(err) - } - }() - // Determine the real address from which the initial connection was made. - realAddr, _, err := net.SplitHostPort(conn.LocalAddr().String()) - if err != nil { - log.Error("Could not dial remote peer") - return addr - } - return net.ParseIP(realAddr) -} - func parseBootStrapAddrs(addrs []string) (discv5Nodes []string) { discv5Nodes, _ = parseGenericAddrs(addrs) if len(discv5Nodes) == 0 { diff --git a/tools/bootnode/bootnode.go b/tools/bootnode/bootnode.go index 252f0a6321..a60f1dc4d5 100644 --- a/tools/bootnode/bootnode.go +++ b/tools/bootnode/bootnode.go @@ -92,7 +92,7 @@ func main() { cfg := discover.Config{ PrivateKey: privKey, } - ipAddr, err := iputils.ExternalIPv4() + ipAddr, err := iputils.ExternalIP() if err != nil { log.Fatal(err) } @@ -125,11 +125,23 @@ func createListener(ipAddr string, port int, cfg discover.Config) *discover.UDPv if ip.To4() == nil { log.Fatalf("IPV4 address not provided instead %s was provided", ipAddr) } + var bindIP net.IP + var networkVersion string + switch { + case ip.To16() != nil && ip.To4() == nil: + bindIP = net.IPv6zero + networkVersion = "udp6" + case ip.To4() != nil: + bindIP = net.IPv4zero + networkVersion = "udp4" + default: + log.Fatalf("Valid ip address not provided instead %s was provided", ipAddr) + } udpAddr := &net.UDPAddr{ - IP: ip, + IP: bindIP, Port: port, } - conn, err := net.ListenUDP("udp4", udpAddr) + conn, err := net.ListenUDP(networkVersion, udpAddr) if err != nil { log.Fatal(err) }