fix for virtual networks (#6676)

This commit is contained in:
Nishant Das 2020-07-22 23:44:17 +08:00 committed by GitHub
parent 4017743f7f
commit 647599e87f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,6 +5,7 @@ import (
"crypto/ecdsa"
"fmt"
"net"
"strconv"
"time"
"github.com/ethereum/go-ethereum/p2p/discover"
@ -98,10 +99,6 @@ func (s *Service) createListener(
ipAddr net.IP,
privKey *ecdsa.PrivateKey,
) (*discover.UDPv5, error) {
udpAddr := &net.UDPAddr{
IP: ipAddr,
Port: int(s.cfg.UDPPort),
}
// assume ip is either ipv4 or ipv6
networkVersion := ""
if ipAddr.To4() != nil {
@ -109,6 +106,13 @@ func (s *Service) createListener(
} else {
networkVersion = "udp6"
}
// Check for the real local address which may
// be different in the presence of virtual networks.
ipAddr = s.localAddress(networkVersion, ipAddr)
udpAddr := &net.UDPAddr{
IP: ipAddr,
Port: int(s.cfg.UDPPort),
}
conn, err := net.ListenUDP(networkVersion, udpAddr)
if err != nil {
return nil, errors.Wrap(err, "could not listen to UDP")
@ -251,6 +255,37 @@ 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 {