NC-1883 - IPv6 peers (#281)

* Add the ipV6 flag to the datagram socket options, this creates a socket that handles both
ipv4 and ipv6 socket connections.
* Set the IPv6 flag state based on the presence or absence of an IPv6 address.

i.e. if your machine runs IPv6 it will accept IPv6 bootnodes and peers.  However link-local IPv6 is not fully supported (see issue #288).
Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Danno Ferrin 6 years ago committed by GitHub
parent bad7729efa
commit 055d63f109
  1. 3
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java
  2. 5
      ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java
  3. 43
      util/src/main/java/tech/pegasys/pantheon/util/NetworkUtility.java

@ -150,7 +150,8 @@ public class PeerDiscoveryAgent implements DisconnectCallback {
LOG.info("Starting peer discovery agent on host={}, port={}", host, port);
vertx
.createDatagramSocket(new DatagramSocketOptions())
.createDatagramSocket(
new DatagramSocketOptions().setIpV6(NetworkUtility.isIPv6Available()))
.listen(
port,
host,

@ -25,6 +25,7 @@ import tech.pegasys.pantheon.ethereum.p2p.config.NetworkingConfiguration;
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 class NetworkingServiceLifecycleTest {
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);
}
}

@ -12,13 +12,56 @@
*/
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<Boolean> ipv6Available =
Suppliers.memoize(NetworkUtility::checkIpv6Availability);
/**
* Is IPv6 available?
*
* @return Returns true if the machine reports having any IPv6 addresses.
*/
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<NetworkInterface> networkInterfaces =
NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
final Enumeration<InetAddress> 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).
*

Loading…
Cancel
Save