From b9f5f230a2697abc268cf385ff771c2c183ccbe8 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Wed, 8 Aug 2012 23:36:11 +0000
Subject: [PATCH] stub out local MTU detection (ticket 682)

---
 .../src/net/i2p/router/transport/udp/MTU.java | 84 +++++++++++++++++++
 .../i2p/router/transport/udp/UDPEndpoint.java | 11 +++
 2 files changed, 95 insertions(+)
 create mode 100644 router/java/src/net/i2p/router/transport/udp/MTU.java

diff --git a/router/java/src/net/i2p/router/transport/udp/MTU.java b/router/java/src/net/i2p/router/transport/udp/MTU.java
new file mode 100644
index 0000000000..22001b13fa
--- /dev/null
+++ b/router/java/src/net/i2p/router/transport/udp/MTU.java
@@ -0,0 +1,84 @@
+package net.i2p.router.transport.udp;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+
+import net.i2p.util.VersionComparator;
+
+/**
+ * Get the MTU for the network interface of an address.
+ * Not available until Java 6 / Android API 9.
+ * @since 0.9.2
+ */
+abstract class MTU {
+
+    private static final boolean hasMTU =
+        (new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0;
+    
+    /**
+     * The MTU for the socket interface, if available.
+     * Not available for Java 5.
+     * @param ia null ok
+     * @return 0 if Java 5, or if not bound to an address;
+     *         limited to range MIN_MTU to LARGE_MTU.
+     */
+    public static int getMTU(InetAddress ia) {
+        if (ia == null || !hasMTU)
+            return 0;
+        Enumeration<NetworkInterface> ifcs;
+        try {
+            ifcs = NetworkInterface.getNetworkInterfaces();
+        } catch (SocketException se) {
+            return 0;
+        }
+        if (ifcs != null) {
+            while (ifcs.hasMoreElements()) {
+                NetworkInterface ifc = ifcs.nextElement();
+                for(Enumeration<InetAddress> addrs =  ifc.getInetAddresses(); addrs.hasMoreElements();) {
+                    InetAddress addr = addrs.nextElement();
+                    if (ia.equals(addr)) {
+                        try {
+                            // testing
+                            //return ifc.getMTU();
+                            return rectify(ifc.getMTU());
+                        } catch (SocketException se) {
+                            // ignore
+                        } catch (Throwable t) {
+                            // NoSuchMethodException or NoSuchMethodError if we somehow got the
+                            // version detection wrong or the JVM doesn't support it
+                            return 0;
+                        }
+                    }
+                }
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * @return min of PeerState.MIN_MTU, max of PeerState.LARGE_MTU,
+     *         rectifyed so rv % 16 == 12
+     */
+    public static int rectify(int mtu) {
+        int rv = mtu;
+        int mod = rv % 16;
+        if (mod > 12)
+            rv -= mod - 12;
+        else if (mod < 12)
+            rv -= mod + 4;
+        return Math.max(PeerState.MIN_MTU, Math.min(PeerState.LARGE_MTU, rv));
+    }
+
+/****
+    public static void main(String args[]) {
+        try {
+            InetAddress test = InetAddress.getByName(args[0]);
+            System.out.println("MTU is " + getMTU(test));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+****/
+}
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
index 9531335b42..2723c3ac79 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
@@ -154,4 +154,15 @@ class UDPEndpoint {
             return null;
         return _receiver.receiveNext(); 
     }
+    
+    /**
+     * The MTU for the socket interface, if available.
+     * Not available for Java 5.
+     * @return 0 if Java 5, or if bound to an address;
+     *         limited to range MIN_MTU to LARGE_MTU.
+     * @since 0.9.2
+     */
+    public int getMTU() {
+        return MTU.getMTU(_bindAddress);
+    }
 }
-- 
GitLab