From 12a04ffe1282a5e73e58388b739258bb7530e2ea Mon Sep 17 00:00:00 2001 From: shemnon Date: Mon, 19 Nov 2018 12:45:29 -0700 Subject: [PATCH 1/3] NC-1883 - IPv6 peers Add ipV6 to the datagram socket options, this creates a socket that handles both ipv4 and ipv6 socket connections. --- .../pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java index 700d30a5e4..2d9e4aa08b 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java @@ -150,7 +150,7 @@ public CompletableFuture start(final int tcpPort) { LOG.info("Starting peer discovery agent on host={}, port={}", host, port); vertx - .createDatagramSocket(new DatagramSocketOptions()) + .createDatagramSocket(new DatagramSocketOptions().setIpV6(true)) .listen( port, host, From 2ef97fa2ac1e2bba739f2755702d29d7be09f3b6 Mon Sep 17 00:00:00 2001 From: shemnon Date: Tue, 20 Nov 2018 08:12:03 -0700 Subject: [PATCH 2/3] NC-1883 - IPv6 peers Set the IPv6 state based on the presence or absence of an IPv6 address. --- .../p2p/discovery/PeerDiscoveryAgent.java | 3 +- .../p2p/NetworkingServiceLifecycleTest.java | 5 ++- .../pegasys/pantheon/util/NetworkUtility.java | 39 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java index 2d9e4aa08b..da07c51177 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java @@ -150,7 +150,8 @@ public CompletableFuture start(final int tcpPort) { LOG.info("Starting peer discovery agent on host={}, port={}", host, port); vertx - .createDatagramSocket(new DatagramSocketOptions().setIpV6(true)) + .createDatagramSocket( + new DatagramSocketOptions().setIpV6(NetworkUtility.isIPv6Available())) .listen( port, host, diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java index 1081cf4414..a2a49168b2 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java @@ -25,6 +25,7 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryServiceException; import tech.pegasys.pantheon.ethereum.p2p.netty.NettyP2PNetwork; import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist; +import tech.pegasys.pantheon.util.NetworkUtility; import java.io.IOException; @@ -56,7 +57,9 @@ public void createPeerDiscoveryAgent() { service.run(); final int port = service.getDiscoverySocketAddress().getPort(); - assertEquals("/0.0.0.0:" + port, service.getDiscoverySocketAddress().toString()); + assertEquals( + (NetworkUtility.isIPv6Available() ? "/0:0:0:0:0:0:0:0:" : "/0.0.0.0:") + port, + service.getDiscoverySocketAddress().toString()); assertThat(service.getDiscoveryPeers()).hasSize(0); } } diff --git a/util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java b/util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java index 1e61bcec42..dd7a2d4e1e 100644 --- a/util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java +++ b/util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java @@ -12,13 +12,52 @@ */ package tech.pegasys.pantheon.util; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.util.Enumeration; +import java.util.function.Supplier; + +import com.google.common.base.Suppliers; public class NetworkUtility { private NetworkUtility() {} + private static final Supplier ipv6Available = + Suppliers.memoize(NetworkUtility::checkIpv6Availability); + + /** Is IPv6 available? */ + public static boolean isIPv6Available() { + return ipv6Available.get(); + } + + /** + * The standard for IPv6 availability is if the machine has any IPv6 addresses. + * + * @return Returns true if any IPv6 addresses are iterable via {@link NetworkInterface}. + */ + private static Boolean checkIpv6Availability() { + try { + final Enumeration networkInterfaces = + NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + final Enumeration addresses = + networkInterfaces.nextElement().getInetAddresses(); + while (addresses.hasMoreElements()) { + if (addresses.nextElement() instanceof Inet6Address) { + // Found an IPv6 address, hence the IPv6 stack is available. + return true; + } + } + } + } catch (final Exception ignore) { + // Any exception means we treat it as not available. + } + return false; + } + /** * Checks the port is not null and is in the valid range port (1-65536). * From aee1890c4ef5fe5899a4e67c91c992602188f2e0 Mon Sep 17 00:00:00 2001 From: shemnon Date: Tue, 20 Nov 2018 10:34:25 -0700 Subject: [PATCH 3/3] javadoc --- .../java/tech/pegasys/pantheon/util/NetworkUtility.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java b/util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java index dd7a2d4e1e..b4a57b8e2f 100644 --- a/util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java +++ b/util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java @@ -28,7 +28,11 @@ private NetworkUtility() {} private static final Supplier ipv6Available = Suppliers.memoize(NetworkUtility::checkIpv6Availability); - /** Is IPv6 available? */ + /** + * Is IPv6 available? + * + * @return Returns true if the machine reports having any IPv6 addresses. + */ public static boolean isIPv6Available() { return ipv6Available.get(); }