mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
QSP-16 Fix Support for IPv6 (#6363)
* checkpoint changes * new changes * comment * clean up * set * fix * fix more * more stuff * clean up * clean up * remove * clean up * clean up * comment Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -127,6 +127,7 @@ go_test(
|
||||
"//shared/testutil:go_default_library",
|
||||
"//shared/testutil/assert:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//crypto:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//p2p/discover:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
|
||||
|
||||
@@ -3,7 +3,6 @@ package p2p
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -124,9 +123,10 @@ func (s *Service) createListener(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not listen to UDP")
|
||||
}
|
||||
|
||||
localNode, err := s.createLocalNode(
|
||||
privKey,
|
||||
ipAddr,
|
||||
udpAddr.IP,
|
||||
int(s.cfg.UDPPort),
|
||||
int(s.cfg.TCPPort),
|
||||
)
|
||||
@@ -365,22 +365,13 @@ func convertToAddrInfo(node *enode.Node) (*peer.AddrInfo, ma.Multiaddr, error) {
|
||||
}
|
||||
|
||||
func convertToSingleMultiAddr(node *enode.Node) (ma.Multiaddr, error) {
|
||||
ip4 := node.IP().To4()
|
||||
if ip4 == nil {
|
||||
return nil, errors.Errorf("node doesn't have an ip4 address, it's stated IP is %s", node.IP().String())
|
||||
}
|
||||
pubkey := node.Pubkey()
|
||||
assertedKey := convertToInterfacePubkey(pubkey)
|
||||
id, err := peer.IDFromPublicKey(assertedKey)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get peer id")
|
||||
}
|
||||
multiAddrString := fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", ip4.String(), node.TCP(), id)
|
||||
multiAddr, err := ma.NewMultiaddr(multiAddrString)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get multiaddr")
|
||||
}
|
||||
return multiAddr, nil
|
||||
return multiAddressBuilderWithID(node.IP().String(), uint(node.TCP()), id)
|
||||
}
|
||||
|
||||
func peersFromStringAddrs(addrs []string) ([]ma.Multiaddr, error) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
noise "github.com/libp2p/go-libp2p-noise"
|
||||
secio "github.com/libp2p/go-libp2p-secio"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
@@ -85,6 +86,20 @@ func multiAddressBuilder(ipAddr string, port uint) (ma.Multiaddr, error) {
|
||||
return ma.NewMultiaddr(fmt.Sprintf("/ip6/%s/tcp/%d", ipAddr, port))
|
||||
}
|
||||
|
||||
func multiAddressBuilderWithID(ipAddr string, port uint, id peer.ID) (ma.Multiaddr, error) {
|
||||
parsedIP := net.ParseIP(ipAddr)
|
||||
if parsedIP.To4() == nil && parsedIP.To16() == nil {
|
||||
return nil, errors.Errorf("invalid ip address provided: %s", ipAddr)
|
||||
}
|
||||
if id.String() == "" {
|
||||
return nil, errors.New("empty peer id given")
|
||||
}
|
||||
if parsedIP.To4() != nil {
|
||||
return ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", ipAddr, port, id.String()))
|
||||
}
|
||||
return ma.NewMultiaddr(fmt.Sprintf("/ip6/%s/tcp/%d/p2p/%s", ipAddr, port, id.String()))
|
||||
}
|
||||
|
||||
// Adds a private key to the libp2p option if the option was provided.
|
||||
// If the private key file is missing or cannot be read, or if the
|
||||
// private key contents cannot be marshaled, an exception is thrown.
|
||||
|
||||
@@ -5,9 +5,13 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
gethCrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
"github.com/libp2p/go-libp2p-core/crypto"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
@@ -46,3 +50,30 @@ func TestPrivateKeyLoading(t *testing.T) {
|
||||
t.Errorf("Private keys do not match got %#x but wanted %#x", rawBytes, newRaw)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPV6Support(t *testing.T) {
|
||||
key, err := gethCrypto.GenerateKey()
|
||||
db, err := enode.OpenDB("")
|
||||
if err != nil {
|
||||
log.Error("could not open node's peer database")
|
||||
}
|
||||
lNode := enode.NewLocalNode(db, key)
|
||||
mockIPV6 := net.IP{0xff, 0x02, 0xAA, 0, 0x1F, 0, 0x2E, 0, 0, 0x36, 0x45, 0, 0, 0, 0, 0x02}
|
||||
lNode.Set(enr.IP(mockIPV6))
|
||||
ma, err := convertToSingleMultiAddr(lNode.Node())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ipv6Exists := false
|
||||
for _, p := range ma.Protocols() {
|
||||
if p.Name == "ip4" {
|
||||
t.Error("Got ip4 address instead of ip6")
|
||||
}
|
||||
if p.Name == "ip6" {
|
||||
ipv6Exists = true
|
||||
}
|
||||
}
|
||||
if !ipv6Exists {
|
||||
t.Error("Multiaddress did not have ipv6 protocol")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ func metaDataFromConfig(cfg *Config) (*pbp2p.MetaData, error) {
|
||||
|
||||
// Retrieves an external ipv4 address and converts into a libp2p formatted value.
|
||||
func ipAddr() net.IP {
|
||||
ip, err := iputils.ExternalIPv4()
|
||||
ip, err := iputils.ExternalIP()
|
||||
if err != nil {
|
||||
log.Fatalf("Could not get IPv4 address: %v", err)
|
||||
}
|
||||
@@ -160,7 +160,7 @@ func ipAddr() net.IP {
|
||||
// Attempt to dial an address to verify its connectivity
|
||||
func verifyConnectivity(addr string, port uint, protocol string) {
|
||||
if addr != "" {
|
||||
a := fmt.Sprintf("%s:%d", addr, port)
|
||||
a := net.JoinHostPort(addr, fmt.Sprintf("%d", port))
|
||||
fields := logrus.Fields{
|
||||
"protocol": protocol,
|
||||
"address": a,
|
||||
|
||||
@@ -7,10 +7,64 @@ import (
|
||||
|
||||
// ExternalIPv4 returns the first IPv4 available.
|
||||
func ExternalIPv4() (string, error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
ips, err := retrieveIPAddrs()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(ips) == 0 {
|
||||
return "127.0.0.1", nil
|
||||
}
|
||||
for _, ip := range ips {
|
||||
ip = ip.To4()
|
||||
if ip == nil {
|
||||
continue // not an ipv4 address
|
||||
}
|
||||
return ip.String(), nil
|
||||
}
|
||||
return "127.0.0.1", nil
|
||||
}
|
||||
|
||||
// ExternalIPv6 retrieves any allocated IPv6 addresses
|
||||
// from the accessible network interfaces.
|
||||
func ExternalIPv6() (string, error) {
|
||||
ips, err := retrieveIPAddrs()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(ips) == 0 {
|
||||
return "127.0.0.1", nil
|
||||
}
|
||||
for _, ip := range ips {
|
||||
if ip.To4() != nil {
|
||||
continue // not an ipv6 address
|
||||
}
|
||||
if ip.To16() == nil {
|
||||
continue
|
||||
}
|
||||
return ip.String(), nil
|
||||
}
|
||||
return "127.0.0.1", nil
|
||||
}
|
||||
|
||||
// ExternalIP returns the first IPv4/IPv6 available.
|
||||
func ExternalIP() (string, error) {
|
||||
ips, err := retrieveIPAddrs()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(ips) == 0 {
|
||||
return "127.0.0.1", nil
|
||||
}
|
||||
return ips[0].String(), nil
|
||||
}
|
||||
|
||||
// retrieveIP returns all the valid IPs available.
|
||||
func retrieveIPAddrs() ([]net.IP, error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ipAddrs := []net.IP{}
|
||||
for _, iface := range ifaces {
|
||||
if iface.Flags&net.FlagUp == 0 {
|
||||
continue // interface down
|
||||
@@ -20,7 +74,7 @@ func ExternalIPv4() (string, error) {
|
||||
}
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
@@ -33,12 +87,8 @@ func ExternalIPv4() (string, error) {
|
||||
if ip == nil || ip.IsLoopback() {
|
||||
continue
|
||||
}
|
||||
ip = ip.To4()
|
||||
if ip == nil {
|
||||
continue // not an ipv4 address
|
||||
}
|
||||
return ip.String(), nil
|
||||
ipAddrs = append(ipAddrs, ip)
|
||||
}
|
||||
}
|
||||
return "127.0.0.1", nil
|
||||
return ipAddrs, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package iputils_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
@@ -18,3 +19,14 @@ func TestExternalIPv4(t *testing.T) {
|
||||
valid := regexp.MustCompile(IPv4Format)
|
||||
assert.Equal(t, true, valid.MatchString(test))
|
||||
}
|
||||
|
||||
func TestRetrieveIP(t *testing.T) {
|
||||
ip, err := iputils.ExternalIP()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
retIP := net.ParseIP(ip)
|
||||
if retIP.To4() == nil && retIP.To16() == nil {
|
||||
t.Errorf("An invalid IP was retrieved: %s", ip)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user