Util: Add Addresses.getConnectedAddressTypes()

method to efficiently get all types in one pass
This commit is contained in:
zzz
2022-03-01 07:25:49 -05:00
parent ce53714ba1
commit 5ef93f11a9
4 changed files with 49 additions and 4 deletions

View File

@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -57,6 +58,7 @@ public abstract class Addresses {
/** /**
* Do we have any address of this type? * Do we have any address of this type?
* Warning, very slow on Windows, appx. 200ms + 50ms/interface * Warning, very slow on Windows, appx. 200ms + 50ms/interface
* Use getConnectedAddressTypes() to get all types at once.
* *
* @since 0.9.54 * @since 0.9.54
*/ */
@ -77,6 +79,7 @@ public abstract class Addresses {
/** /**
* Do we have any non-loop, non-wildcard IPv4 address at all? * Do we have any non-loop, non-wildcard IPv4 address at all?
* Warning, very slow on Windows, appx. 200ms + 50ms/interface * Warning, very slow on Windows, appx. 200ms + 50ms/interface
* Use getConnectedAddressTypes() to get all types at once.
* *
* @since 0.9.4 * @since 0.9.4
*/ */
@ -88,6 +91,7 @@ public abstract class Addresses {
/** /**
* Do we have any non-loop, non-wildcard IPv6 address at all? * Do we have any non-loop, non-wildcard IPv6 address at all?
* Warning, very slow on Windows, appx. 200ms + 50ms/interface * Warning, very slow on Windows, appx. 200ms + 50ms/interface
* Use getConnectedAddressTypes() to get all types at once.
* *
* @since 0.9.29 * @since 0.9.29
*/ */
@ -313,6 +317,39 @@ public abstract class Addresses {
return null; 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() * Strip the trailing "%nn" from Inet6Address.getHostAddress()
* @since IPv6 * @since IPv6
@ -901,6 +938,7 @@ public abstract class Addresses {
* Print out the local addresses * Print out the local addresses
*/ */
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Connected Address Types: " + getConnectedAddressTypes() + '\n');
System.out.println("External IPv4 Addresses:"); System.out.println("External IPv4 Addresses:");
Set<String> a = getAddresses(false, false, false); Set<String> a = getAddresses(false, false, false);
print(a); print(a);
@ -970,7 +1008,8 @@ public abstract class Addresses {
} }
print(macs); print(macs);
System.out.println("\nHas IPv4? " + isConnected() + 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("Has v6 flags? " + INET6_CACHE_ENABLED);
System.out.println("Uses v6 temp? " + getPrivacyStatus()); System.out.println("Uses v6 temp? " + getPrivacyStatus());
// Windows 8.1 Java 1.8.0_66 netbook appx. 200ms + 50ms/interface // Windows 8.1 Java 1.8.0_66 netbook appx. 200ms + 50ms/interface

View File

@ -166,7 +166,8 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
* @return null if not found * @return null if not found
*/ */
public String lookup(String host) { 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); return lookup(host, type);
} }

View File

@ -4,11 +4,13 @@ import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.util.Addresses; import net.i2p.util.Addresses;
import net.i2p.util.AddressType;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.SimpleTimer; import net.i2p.util.SimpleTimer;
@ -105,7 +107,8 @@ public class ReseedChecker {
File noReseedFileAlt2 = new File(_context.getConfigDir(), ".i2pnoreseed"); File noReseedFileAlt2 = new File(_context.getConfigDir(), ".i2pnoreseed");
File noReseedFileAlt3 = new File(_context.getConfigDir(), "noreseed.i2p"); File noReseedFileAlt3 = new File(_context.getConfigDir(), "noreseed.i2p");
if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) { 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) { if (!_networkLogged) {
_log.logAlways(Log.WARN, "Cannot reseed, no network connection"); _log.logAlways(Log.WARN, "Cannot reseed, no network connection");
_networkLogged = true; _networkLogged = true;

View File

@ -31,6 +31,7 @@ import net.i2p.router.transport.crypto.X25519KeyFactory;
import net.i2p.router.transport.udp.UDPTransport; import net.i2p.router.transport.udp.UDPTransport;
import net.i2p.router.util.EventLog; import net.i2p.router.util.EventLog;
import net.i2p.util.Addresses; import net.i2p.util.Addresses;
import net.i2p.util.AddressType;
import net.i2p.util.I2PThread; import net.i2p.util.I2PThread;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.SimpleTimer; import net.i2p.util.SimpleTimer;
@ -711,7 +712,8 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
} }
public void timeReached() { 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 (_netMonitorStatus != good) {
if (good) if (good)
_log.logAlways(Log.INFO, "Network reconnected"); _log.logAlways(Log.INFO, "Network reconnected");