diff --git a/core/java/src/net/i2p/util/Addresses.java b/core/java/src/net/i2p/util/Addresses.java index c228954298797b44338bc86c97f40e102092550e..a1b3937287de9f371502eb69be4e1756c1080892 100644 --- a/core/java/src/net/i2p/util/Addresses.java +++ b/core/java/src/net/i2p/util/Addresses.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -57,6 +58,7 @@ public abstract class Addresses { /** * Do we have any address of this type? * Warning, very slow on Windows, appx. 200ms + 50ms/interface + * Use getConnectedAddressTypes() to get all types at once. * * @since 0.9.54 */ @@ -77,6 +79,7 @@ public abstract class Addresses { /** * Do we have any non-loop, non-wildcard IPv4 address at all? * Warning, very slow on Windows, appx. 200ms + 50ms/interface + * Use getConnectedAddressTypes() to get all types at once. * * @since 0.9.4 */ @@ -88,6 +91,7 @@ public abstract class Addresses { /** * Do we have any non-loop, non-wildcard IPv6 address at all? * Warning, very slow on Windows, appx. 200ms + 50ms/interface + * Use getConnectedAddressTypes() to get all types at once. * * @since 0.9.29 */ @@ -313,6 +317,39 @@ public abstract class Addresses { return null; } + /** + * Efficiently get all connected address types in one pass. + * Warning, very slow on Windows. Caller should cache. + * + * @return the set of connected address types, non-null + * @since 0.9.54 + */ + public static Set<AddressType> getConnectedAddressTypes() { + Set<AddressType> rv = EnumSet.noneOf(AddressType.class); + try { + Enumeration<NetworkInterface> ifcs = NetworkInterface.getNetworkInterfaces(); + if (ifcs != null) { + while (ifcs.hasMoreElements()) { + NetworkInterface ifc = ifcs.nextElement(); + if (!ifc.isUp()) + continue; + for(Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements();) { + InetAddress addr = addrs.nextElement(); + byte[] ip = addr.getAddress(); + if (ip.length == 16 && (ip[0] & 0xfe) == 0x02) { + rv.add(AddressType.YGG); + } else if (shouldInclude(addr, true, false, true)) { + rv.add(ip.length == 16 ? AddressType.IPV6 : AddressType.IPV4); + } + } + } + } + } catch (SocketException e) { + } catch (java.lang.Error e) { + } + return rv; + } + /** * Strip the trailing "%nn" from Inet6Address.getHostAddress() * @since IPv6 @@ -901,6 +938,7 @@ public abstract class Addresses { * Print out the local addresses */ public static void main(String[] args) { + System.out.println("Connected Address Types: " + getConnectedAddressTypes() + '\n'); System.out.println("External IPv4 Addresses:"); Set<String> a = getAddresses(false, false, false); print(a); @@ -970,7 +1008,8 @@ public abstract class Addresses { } print(macs); System.out.println("\nHas IPv4? " + isConnected() + - "\nHas IPv6? " + isConnectedIPv6()); + "\nHas IPv6? " + isConnectedIPv6() + + "\nHas Ygg? " + (ygg != null)); System.out.println("Has v6 flags? " + INET6_CACHE_ENABLED); System.out.println("Uses v6 temp? " + getPrivacyStatus()); // Windows 8.1 Java 1.8.0_66 netbook appx. 200ms + 50ms/interface diff --git a/core/java/src/net/i2p/util/DNSOverHTTPS.java b/core/java/src/net/i2p/util/DNSOverHTTPS.java index e40679534597ad83b29c67a3f9717e8469668a9c..206596237d1f29eed95c27d7d78ab33326177381 100644 --- a/core/java/src/net/i2p/util/DNSOverHTTPS.java +++ b/core/java/src/net/i2p/util/DNSOverHTTPS.java @@ -166,7 +166,8 @@ public class DNSOverHTTPS implements EepGet.StatusListener { * @return null if not found */ public String lookup(String host) { - Type type = (Addresses.isConnected() || !Addresses.isConnectedIPv6()) ? Type.V4_ONLY : Type.V6_ONLY; + Set<AddressType> addrs = Addresses.getConnectedAddressTypes(); + Type type = (addrs.contains(AddressType.IPV4) || !addrs.contains(AddressType.IPV6)) ? Type.V4_ONLY : Type.V6_ONLY; return lookup(host, type); } diff --git a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java index b221df494354690d18848ef99dcdd568c287e09e..d3680a173075bb31b837662b058bbaab17fdd83d 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java @@ -4,11 +4,13 @@ import java.io.File; import java.io.InputStream; import java.io.IOException; import java.net.URI; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import net.i2p.data.DataHelper; import net.i2p.router.RouterContext; import net.i2p.util.Addresses; +import net.i2p.util.AddressType; import net.i2p.util.Log; import net.i2p.util.SimpleTimer; @@ -105,7 +107,8 @@ public class ReseedChecker { File noReseedFileAlt2 = new File(_context.getConfigDir(), ".i2pnoreseed"); File noReseedFileAlt3 = new File(_context.getConfigDir(), "noreseed.i2p"); if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) { - if (!Addresses.isConnected() && !Addresses.isConnectedIPv6()) { + Set<AddressType> addrs = Addresses.getConnectedAddressTypes(); + if (!addrs.contains(AddressType.IPV4) && !addrs.contains(AddressType.IPV6)) { if (!_networkLogged) { _log.logAlways(Log.WARN, "Cannot reseed, no network connection"); _networkLogged = true; diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index bd42472bae2c3a5851f8f90934510096552a04a7..0114d27725f5fc952d0ca60d25f6d115183d5149 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -31,6 +31,7 @@ import net.i2p.router.transport.crypto.X25519KeyFactory; import net.i2p.router.transport.udp.UDPTransport; import net.i2p.router.util.EventLog; import net.i2p.util.Addresses; +import net.i2p.util.AddressType; import net.i2p.util.I2PThread; import net.i2p.util.Log; import net.i2p.util.SimpleTimer; @@ -711,7 +712,8 @@ public class CommSystemFacadeImpl extends CommSystemFacade { } public void timeReached() { - boolean good = Addresses.isConnected() || Addresses.isConnectedIPv6(); + Set<AddressType> addrs = Addresses.getConnectedAddressTypes(); + boolean good = addrs.contains(AddressType.IPV4) || addrs.contains(AddressType.IPV6); if (_netMonitorStatus != good) { if (good) _log.logAlways(Log.INFO, "Network reconnected");