package io.fathom.auto.config; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.List; import com.google.common.base.Charsets; import com.google.common.collect.Lists; import com.google.common.io.Files; public class MachineInfo { public static final MachineInfo INSTANCE = new MachineInfo(); List<InetAddress> addresses; List<InetAddress> getAddresses() { // TODO: Don't cache? What if this changes? if (this.addresses == null) { List<InetAddress> addresses = Lists.newArrayList(); Enumeration<NetworkInterface> networkInterfaces; try { networkInterfaces = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e) { throw new IllegalStateException("Error listing network interfaces", e); } while (networkInterfaces.hasMoreElements()) { NetworkInterface networkInterface = networkInterfaces.nextElement(); List<InterfaceAddress> interfaceAddresses = networkInterface.getInterfaceAddresses(); for (InterfaceAddress interfaceAddress : interfaceAddresses) { InetAddress address = interfaceAddress.getAddress(); addresses.add(address); } } this.addresses = addresses; } return this.addresses; } public synchronized String getMachineKey() { File keyPath = new File("/var/machineid"); if (!keyPath.exists()) { String value = new MachineSignature().generateKey(); if (!keyPath.exists()) { // TODO: Can we do this only-if-not-exists? try { Files.write(value.getBytes(Charsets.UTF_8), keyPath); } catch (IOException e) { throw new IllegalStateException("Error writing machine key file", e); } } } try { String machineKey = Files.toString(keyPath, Charsets.UTF_8); return machineKey; } catch (IOException e) { throw new IllegalStateException("Error reading machine key file", e); } } static class CompareInetAddress implements Comparator<InetAddress> { @Override public int compare(InetAddress l, InetAddress r) { int scoreL = score(l); int scoreR = score(r); return Integer.compare(scoreL, scoreR); } } InetAddress bestIp; public InetAddress getIp() { if (bestIp == null) { List<InetAddress> addresses = getAddresses(); bestIp = Collections.max(addresses, new CompareInetAddress()); } return bestIp; } static int score(InetAddress a) { if (a.isLoopbackAddress()) { return -1000; } if (a.isLinkLocalAddress()) { return -1000; } if (a.isMulticastAddress()) { return -1000; } byte[] data = a.getAddress(); if (data.length == 4) { // 192.168.0.0/16 if (data[0] == 192 && data[1] == 168) { return -100; } // 172.16.0.0/20 if (data[0] == 172 && ((data[1] & 240) == 16)) { return -100; } // 10.0.0.0/24 if (data[0] == 10) { return -50; } // 100.64.0.0/10 if (data[0] == 100 && ((data[1] & 192) == 64)) { return -20; } } return 0; } }