package net.i2p.router.transport; /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain * with no warranty of any kind { either expressed or implied. * It probably won't make your computer catch on fire { or eat * your children { but it might. Use at your own risk. * */ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import net.i2p.I2PAppContext; import net.i2p.data.router.RouterAddress; import net.i2p.router.RouterContext; /** * @since IPv6 */ public abstract class TransportUtil { public static final String NTCP_IPV6_CONFIG = "i2np.ntcp.ipv6"; public static final String SSU_IPV6_CONFIG = "i2np.udp.ipv6"; public static final String PROP_IPV4_FIREWALLED = "i2np.ipv4.firewalled"; /** @since 0.9.28 */ public static final String PROP_IPV6_FIREWALLED = "i2np.ipv6.firewalled"; public enum IPv6Config { /** IPv6 disabled */ IPV6_DISABLED("false"), /** lower priority than IPv4 */ IPV6_NOT_PREFERRED("preferIPv4"), /** equal priority to IPv4 */ IPV6_ENABLED("enable"), /** higher priority than IPv4 */ IPV6_PREFERRED("preferIPv6"), /** IPv4 disabled */ IPV6_ONLY("only"); private final String cfgstr; IPv6Config(String cfgstr) { this.cfgstr = cfgstr; } public String toConfigString() { return cfgstr; } } private static final Map<String, IPv6Config> BY_NAME = new HashMap<String, IPv6Config>(); public static final IPv6Config DEFAULT_IPV6_CONFIG = IPv6Config.IPV6_PREFERRED; static { for (IPv6Config cfg : IPv6Config.values()) { BY_NAME.put(cfg.toConfigString(), cfg); } // alias BY_NAME.put("true", IPv6Config.IPV6_ENABLED); BY_NAME.put("disable", IPv6Config.IPV6_DISABLED); } public static IPv6Config getIPv6Config(RouterContext ctx, String transportStyle) { String cfg; if (transportStyle.equals("NTCP")) cfg = ctx.getProperty(NTCP_IPV6_CONFIG); else if (transportStyle.equals("SSU")) cfg = ctx.getProperty(SSU_IPV6_CONFIG); else return DEFAULT_IPV6_CONFIG; return getIPv6Config(cfg); } public static IPv6Config getIPv6Config(String cfg) { if (cfg == null) return DEFAULT_IPV6_CONFIG; IPv6Config c = BY_NAME.get(cfg); if (c != null) return c; return DEFAULT_IPV6_CONFIG; } /** * This returns true if the force-firewalled setting is configured, false otherwise. * * @param transportStyle ignored * @since 0.9.20 */ public static boolean isIPv4Firewalled(RouterContext ctx, String transportStyle) { return ctx.getBooleanProperty(PROP_IPV4_FIREWALLED); } /** * This returns true if the force-firewalled setting is configured, false otherwise. * * @param transportStyle ignored * @since 0.9.27, implemented in 0.9.28 */ public static boolean isIPv6Firewalled(RouterContext ctx, String transportStyle) { return ctx.getBooleanProperty(PROP_IPV6_FIREWALLED); } /** * Addresses without a host (i.e. w/introducers) * are assumed to be IPv4 */ public static boolean isIPv6(RouterAddress addr) { // do this the fast way, without calling getIP() to parse the host string String host = addr.getHost(); return host != null && host.contains(":"); } /** * @param addr non-null * @since IPv6 moved from TransportImpl */ public static boolean isPubliclyRoutable(byte addr[], boolean allowIPv6) { return isPubliclyRoutable(addr, true, allowIPv6); } /** * Ref: RFC 5735 * * @param addr non-null * @since IPv6 */ public static boolean isPubliclyRoutable(byte addr[], boolean allowIPv4, boolean allowIPv6) { if (I2PAppContext.getGlobalContext().getBooleanProperty("i2np.allowLocal")) return true; if (addr.length == 4) { if (!allowIPv4) return false; int a0 = addr[0] & 0xFF; // please keep sorted by IP if (a0 == 0) return false; if (a0 == 10) return false; // 5/8 allocated to RIPE (30 November 2010) //if ((addr[0]&0xFF) == 5) return false; // Hamachi // Hamachi moved to 25/8 Nov. 2012 // Assigned to UK Ministry of Defence // http://blog.logmein.com/products/changes-to-hamachi-on-november-19th if (a0 == 25) return false; if (a0 == 127) return false; int a1 = addr[1] & 0xFF; // Carrier Grade NAT RFC 6598 if (a0 == 100 && a1 >= 64 && a1 <= 127) return false; // DHCP autoconfig RFC 3927 if (a0 == 169 && a1 == 254) return false; if (a0 == 172 && a1 >= 16 && a1 <= 31) return false; if (a0 == 192) { if (a1 == 168) return false; if (a1 == 0) { int a2 = addr[2] & 0xFF; // protocol assignment, documentation // 192.0.0.2 seen in the wild, RFC 6333 "Dual-Stack Lite Broadband Deployments Following IPv4 Exhaustion" if (a2 == 0 || a2 == 2) return false; } // 6to4 anycast if (a1 == 88 && (addr[2] & 0xff) == 99) return false; } if (a0 == 198) { // tests if (a1 == 18 || a1 == 19) return false; if (a1 == 51 && (addr[2] & 0xff) == 100) return false; } // test if (a0 == 203 && a1 == 0 && (addr[2] & 0xff) == 113) return false; if (a0 >= 224) return false; // no multicast return true; // or at least possible to be true } else if (addr.length == 16) { if (allowIPv6) { // loopback, broadcast, // IPv4 compat ::xxxx:xxxx if (addr[0] == 0) return false; if (addr[0] == 0x20) { // disallow 2002::/16 (6to4 RFC 3056) if (addr[1] == 0x02) return false; if (addr[1] == 0x01) { // disallow 2001:0::/32 (Teredo RFC 4380) if (addr[2] == 0x00 && addr[3] == 0x00) return false; // Documenation (example) RFC 3849 if (addr[2] == 0x0d && (addr[3] & 0xff) == 0xb8) return false; } } // disallow fc00::/8 and fd00::/8 (Unique local addresses RFC 4193) // not recognized as local by InetAddress if ((addr[0] & 0xfe) == 0xfc) return false; // Hamachi IPv6 if (addr[0] == 0x26 && addr[1] == 0x20 && addr[2] == 0x00 && (addr[3] & 0xff) == 0x9b) return false; // 6bone RFC 2471 if (addr[0] == 0x3f && (addr[1] & 0xff) == 0xfe) return false; try { InetAddress ia = InetAddress.getByAddress(addr); return (!ia.isLinkLocalAddress()) && (!ia.isMulticastAddress()) && (!ia.isAnyLocalAddress()) && (!ia.isLoopbackAddress()) && (!ia.isSiteLocalAddress()); } catch (UnknownHostException uhe) {} } } return false; } /** * Is this a valid port for us or a remote router? * * ref: http://i2p-projekt.i2p/en/docs/ports * * @since 0.9.17 moved from logic in individual transports */ public static boolean isValidPort(int port) { // update log message in UDPEndpoint if you update this list return port >= 1024 && port <= 65535 && port != 1900 && // UPnP SSDP port != 2827 && // BOB port != 4444 && // HTTP port != 4445 && // HTTPS port != 6668 && // IRC (!(port >= 7650 && port <= 7664)) && // standard I2P range port != 8998 && // mtn port != 31000 && // Wrapper port != 32000; // Wrapper } }