From b71631d2ec9b27df24d1931e08ae23579d6d69e2 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Thu, 2 May 2013 14:12:53 +0000
Subject: [PATCH] Fixes to isPubliclyRoutable() based on IPv6 config

---
 .../net/i2p/router/web/ConfigNetHandler.java  |  5 +--
 .../src/net/i2p/router/web/SummaryHelper.java |  5 +--
 .../src/net/i2p/router/RouterVersion.java     |  2 +-
 .../i2p/router/transport/TransportImpl.java   | 34 +++++++-----------
 .../i2p/router/transport/TransportUtil.java   | 36 +++++++++++++++++++
 .../src/net/i2p/router/transport/UPnP.java    |  2 +-
 .../net/i2p/router/transport/UPnPManager.java |  2 +-
 .../router/transport/ntcp/NTCPAddress.java    | 10 ------
 8 files changed, 58 insertions(+), 38 deletions(-)

diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java
index 67c47fbb7f..827cf47f61 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java
@@ -7,7 +7,7 @@ import java.util.Map;
 
 import net.i2p.router.Router;
 import net.i2p.router.transport.FIFOBandwidthRefiller;
-import net.i2p.router.transport.TransportImpl;
+import net.i2p.router.transport.TransportUtil;
 import net.i2p.router.transport.TransportManager;
 import net.i2p.router.transport.udp.UDPTransport;
 import net.i2p.router.web.ConfigServiceHandler;
@@ -370,7 +370,8 @@ public class ConfigNetHandler extends FormHandler {
             addFormError(_("Invalid address") + ": " + addr);
             return false;
         }
-        boolean rv = TransportImpl.isPubliclyRoutable(iab);
+        // TODO set IPv6 arg based on configuration?
+        boolean rv = TransportUtil.isPubliclyRoutable(iab, true);
         if (!rv)
             addFormError(_("The hostname or IP {0} is not publicly routable", addr));
         return rv;
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
index bff1abdd54..7d75790aed 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
@@ -24,7 +24,7 @@ import net.i2p.router.RouterContext;
 import net.i2p.router.RouterVersion;
 import net.i2p.router.TunnelPoolSettings;
 import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
-import net.i2p.router.transport.ntcp.NTCPAddress;
+import net.i2p.router.transport.TransportUtil;
 import net.i2p.stat.Rate;
 import net.i2p.stat.RateStat;
 import net.i2p.util.PortMapper;
@@ -159,7 +159,8 @@ public class SummaryHelper extends HelperBase {
         switch (status) {
             case CommSystemFacade.STATUS_OK:
                 RouterAddress ra = routerInfo.getTargetAddress("NTCP");
-                if (ra == null || (new NTCPAddress(ra)).isPubliclyRoutable())
+                // TODO set IPv6 arg based on configuration?
+                if (ra == null || TransportUtil.isPubliclyRoutable(ra.getIP(), true))
                     return _("OK");
                 return _("ERR-Private TCP Address");
             case CommSystemFacade.STATUS_DIFFERENT:
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index f5c9264549..b15b320051 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -21,7 +21,7 @@ public class RouterVersion {
     public final static long BUILD = 20;
 
     /** for example "-test" */
-    public final static String EXTRA = "";
+    public final static String EXTRA = "-ipv6";
     public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA;
     public static void main(String args[]) {
         System.out.println("I2P Router version: " + FULL_VERSION);
diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java
index 52d1f20168..81a498bced 100644
--- a/router/java/src/net/i2p/router/transport/TransportImpl.java
+++ b/router/java/src/net/i2p/router/transport/TransportImpl.java
@@ -668,26 +668,18 @@ public abstract class TransportImpl implements Transport {
         }
     }
 
-    /** @param addr non-null */
-    public static boolean isPubliclyRoutable(byte addr[]) {
-        if (addr.length == 4) {
-            int a0 = addr[0] & 0xFF;
-            if (a0 == 127) return false;
-            if (a0 == 10) return false;
-            int a1 = addr[1] & 0xFF;
-            if (a0 == 172 && a1 >= 16 && a1 <= 31) return false;
-            if (a0 == 192 && a1 == 168) return false;
-            if (a0 >= 224) return false; // no multicast
-            if (a0 == 0) return false;
-            if (a0 == 169 && a1 == 254) return false;
-            // 5/8 allocated to RIPE (30 November 2010)
-            //if ((addr[0]&0xFF) == 5) return false;  // Hamachi
-            return true; // or at least possible to be true
-        } else if (addr.length == 16) {
-            return false;
-        } else {
-            // ipv?
-            return false;
-        }
+    /**
+     *  @since IPv6
+     */
+    protected TransportUtil.IPv6Config getIPv6Config() {
+        return TransportUtil.getIPv6Config(_context, getStyle());
+    }
+
+    /**
+     *  @param addr non-null
+     */
+    protected boolean isPubliclyRoutable(byte addr[]) {
+        return TransportUtil.isPubliclyRoutable(addr,
+                                                getIPv6Config() != TransportUtil.IPv6Config.IPV6_DISABLED);
     }
 }
diff --git a/router/java/src/net/i2p/router/transport/TransportUtil.java b/router/java/src/net/i2p/router/transport/TransportUtil.java
index f581b19443..cc708d1142 100644
--- a/router/java/src/net/i2p/router/transport/TransportUtil.java
+++ b/router/java/src/net/i2p/router/transport/TransportUtil.java
@@ -8,6 +8,8 @@ package net.i2p.router.transport;
  *
  */
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -75,4 +77,38 @@ public abstract class TransportUtil {
             return c;
         return IPv6Config.IPV6_DISABLED;
     }
+
+    /**
+     *  @param addr non-null
+     *  @since IPv6 moved from TransportImpl
+     */
+    public static boolean isPubliclyRoutable(byte addr[], boolean allowIPv6) {
+        if (addr.length == 4) {
+            int a0 = addr[0] & 0xFF;
+            if (a0 == 127) return false;
+            if (a0 == 10) return false;
+            int a1 = addr[1] & 0xFF;
+            if (a0 == 172 && a1 >= 16 && a1 <= 31) return false;
+            if (a0 == 192 && a1 == 168) return false;
+            if (a0 >= 224) return false; // no multicast
+            if (a0 == 0) return false;
+            if (a0 == 169 && a1 == 254) return false;
+            // 5/8 allocated to RIPE (30 November 2010)
+            //if ((addr[0]&0xFF) == 5) return false;  // Hamachi
+            return true; // or at least possible to be true
+        } else if (addr.length == 16) {
+            if (allowIPv6) {
+                try {
+                    InetAddress ia = InetAddress.getByAddress(addr);
+                    return
+                        (!ia.isLinkLocalAddress()) &&
+                        (!ia.isMulticastAddress()) &&
+                        (!ia.isAnyLocalAddress()) &&
+                        (!ia.isLoopbackAddress()) &&
+                        (!ia.isSiteLocalAddress());
+                } catch (UnknownHostException uhe) {}
+            }
+        }
+        return false;
+    }
 }
diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java
index cee870c96e..e8d9dd9a74 100644
--- a/router/java/src/net/i2p/router/transport/UPnP.java
+++ b/router/java/src/net/i2p/router/transport/UPnP.java
@@ -146,7 +146,7 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
 			InetAddress detectedIP = InetAddress.getByName(natAddress);
 
 			short status = DetectedIP.NOT_SUPPORTED;
-			thinksWeAreDoubleNatted = !TransportImpl.isPubliclyRoutable(detectedIP.getAddress());
+			thinksWeAreDoubleNatted = !TransportUtil.isPubliclyRoutable(detectedIP.getAddress(), false);
 			// If we have forwarded a port AND we don't have a private address
 			if (_log.shouldLog(Log.WARN))
 				_log.warn("NATAddress: \"" + natAddress + "\" detectedIP: " + detectedIP + " double? " + thinksWeAreDoubleNatted);
diff --git a/router/java/src/net/i2p/router/transport/UPnPManager.java b/router/java/src/net/i2p/router/transport/UPnPManager.java
index fb368b37b8..10355f64b5 100644
--- a/router/java/src/net/i2p/router/transport/UPnPManager.java
+++ b/router/java/src/net/i2p/router/transport/UPnPManager.java
@@ -156,7 +156,7 @@ class UPnPManager {
             if (ips != null) {
                 for (DetectedIP ip : ips) {
                     // store the first public one and tell the transport manager if it changed
-                    if (TransportImpl.isPubliclyRoutable(ip.publicAddress.getAddress())) {
+                    if (TransportUtil.isPubliclyRoutable(ip.publicAddress.getAddress(), false)) {
                         if (_log.shouldLog(Log.DEBUG))
                             _log.debug("External address: " + ip.publicAddress + " type: " + ip.natType);
                         if (!ip.publicAddress.equals(_detectedAddress)) {
diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPAddress.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPAddress.java
index b37d23cc11..43d051af47 100644
--- a/router/java/src/net/i2p/router/transport/ntcp/NTCPAddress.java
+++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPAddress.java
@@ -88,16 +88,6 @@ public class NTCPAddress {
     public int getPort() { return _port; }
     //public void setPort(int port) { _port = port; }
     
-    public boolean isPubliclyRoutable() {
-        return isPubliclyRoutable(_host);
-    }
-
-    public static boolean isPubliclyRoutable(String host) {
-        if (host == null) return false;
-        byte quad[] = Addresses.getIP(host);
-        return TransportImpl.isPubliclyRoutable(quad);
-    }
-    
     @Override
     public String toString() { return _host + ":" + _port; }
     
-- 
GitLab