From 8792c0a00aac69f592c3587c376c21fa36a65403 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 19 Nov 2018 14:29:55 -0700 Subject: [PATCH] NC-1921 - IPv6 Bootnode (#280) Allow IPv6 bootnodes to be specified by translating to address only form when parsing a URI. --- .../pantheon/ethereum/p2p/peers/DefaultPeer.java | 9 ++++++++- .../pantheon/ethereum/p2p/peers/PeerTest.java | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/peers/DefaultPeer.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/peers/DefaultPeer.java index d329c41d0c..b1c94d19aa 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/peers/DefaultPeer.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/peers/DefaultPeer.java @@ -28,6 +28,7 @@ import java.util.OptionalInt; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.google.common.net.InetAddresses; import com.google.common.primitives.Ints; /** The default, basic representation of an Ethereum {@link Peer}. */ @@ -67,6 +68,12 @@ public class DefaultPeer extends DefaultPeerId implements Peer { // Process the peer's public key, in the host portion of the URI. final BytesValue id = BytesValue.fromHexString(uri.getUserInfo()); + // Process the host. If we have an IPv6 address in URL form translate to an address only form. + String host = uri.getHost(); + if (!InetAddresses.isInetAddress(host) && InetAddresses.isUriInetAddress(host)) { + host = InetAddresses.toAddrString(InetAddresses.forUriString(host)); + } + // Process the ports; falling back to the default port in both TCP and UDP. int tcpPort = DEFAULT_PORT; int udpPort = DEFAULT_PORT; @@ -80,7 +87,7 @@ public class DefaultPeer extends DefaultPeerId implements Peer { udpPort = extractUdpPortFromQuery(uri.getQuery()).orElse(tcpPort); } - final Endpoint endpoint = new Endpoint(uri.getHost(), udpPort, OptionalInt.of(tcpPort)); + final Endpoint endpoint = new Endpoint(host, udpPort, OptionalInt.of(tcpPort)); return new DefaultPeer(id, endpoint); } diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/peers/PeerTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/peers/PeerTest.java index 6bfe35629d..f7d2d00136 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/peers/PeerTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/peers/PeerTest.java @@ -132,6 +132,22 @@ public class PeerTest { assertEquals(30403, peer.getEndpoint().getTcpPort().getAsInt()); } + @Test + public void createFromIpv6URI() { + final Peer peer = + DefaultPeer.fromURI( + "enode://c7849b663d12a2b5bf05b1ebf5810364f4870d5f1053fbd7500d38bc54c705b453d7511ca8a4a86003d34d4c8ee0bbfcd387aa724f5b240b3ab4bbb994a1e09b@[2001:0DB8:85A3:0000::8A2E:370:7334]:30403"); + assertEquals( + fromHexString( + "c7849b663d12a2b5bf05b1ebf5810364f4870d5f1053fbd7500d38bc54c705b453d7511ca8a4a86003d34d4c8ee0bbfcd387aa724f5b240b3ab4bbb994a1e09b"), + peer.getId()); + // We expect bracket unwrapping, zero group removal via double colon, and leading zeros + // trimmed, and lowercase hex digits. + assertEquals("2001:db8:85a3::8a2e:370:7334", peer.getEndpoint().getHost()); + assertEquals(30403, peer.getEndpoint().getUdpPort()); + assertEquals(30403, peer.getEndpoint().getTcpPort().getAsInt()); + } + @Test(expected = IllegalArgumentException.class) public void createFromURIFailsForWrongScheme() { DefaultPeer.fromURI("http://user@foo:80");