From 9a4cd11748a5b17d2e7d3f575e9d9348c8111bc5 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 21 May 2013 21:10:23 +0000 Subject: [PATCH] * SSU: "rectify" IPv4/v6 MTUs differently due to different header size (mod 16) * Penalize addresses w/o IP in sort --- .../src/net/i2p/router/transport/TransportImpl.java | 8 ++++++-- .../router/transport/udp/EstablishmentManager.java | 3 ++- .../java/src/net/i2p/router/transport/udp/MTU.java | 13 ++++++++++--- .../src/net/i2p/router/transport/udp/PeerState.java | 8 ++++++-- .../net/i2p/router/transport/udp/UDPAddress.java | 6 ++++-- .../net/i2p/router/transport/udp/UDPTransport.java | 5 +++-- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index 57bfeeea3..89ab0d5f2 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -614,9 +614,13 @@ public abstract class TransportImpl implements Transport { int rc = r.getCost(); byte[] lip = l.getIP(); byte[] rip = r.getIP(); - if (lip != null && lip.length == 16) + if (lip == null) + lc += 20; + else if (lip.length == 16) lc += adj; - if (rip != null && rip.length == 16) + if (rip == null) + rc += 20; + else if (rip.length == 16) rc += adj; if (lc > rc) return 1; diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index e27941193..95250aa95 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -677,7 +677,8 @@ class EstablishmentManager { String smtu = addr.getOption(UDPAddress.PROP_MTU); if (smtu != null) { try { - int mtu = MTU.rectify(Integer.parseInt(smtu)); + boolean isIPv6 = state.getSentIP().length == 16; + int mtu = MTU.rectify(isIPv6, Integer.parseInt(smtu)); peer.setHisMTU(mtu); } catch (NumberFormatException nfe) {} } diff --git a/router/java/src/net/i2p/router/transport/udp/MTU.java b/router/java/src/net/i2p/router/transport/udp/MTU.java index 9a8fd3601..641c12163 100644 --- a/router/java/src/net/i2p/router/transport/udp/MTU.java +++ b/router/java/src/net/i2p/router/transport/udp/MTU.java @@ -1,6 +1,7 @@ package net.i2p.router.transport.udp; import java.net.InetAddress; +import java.net.Inet6Address; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; @@ -41,7 +42,8 @@ abstract class MTU { try { // testing //return ifc.getMTU(); - return rectify(ifc.getMTU()); + boolean isIPv6 = addr instanceof Inet6Address; + return rectify(isIPv6, ifc.getMTU()); } catch (SocketException se) { // ignore } catch (Throwable t) { @@ -58,11 +60,16 @@ abstract class MTU { /** * @return min of PeerState.MIN_MTU, max of PeerState.LARGE_MTU, - * rectified so rv % 16 == 12 + * rectified so rv % 16 == 12 (IPv4) + * or rv % 16 == 0 (IPv6) */ - public static int rectify(int mtu) { + public static int rectify(boolean isIPv6, int mtu) { int rv = mtu; int mod = rv % 16; + if (isIPv6) { + rv -= mod; + return Math.max(PeerState.MIN_IPV6_MTU, Math.min(PeerState.MAX_IPV6_MTU, rv)); + } if (mod > 12) rv -= mod - 12; else if (mod < 12) diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java index a60af4d32..65e236019 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerState.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java @@ -267,8 +267,12 @@ class PeerState { * and so PacketBuilder.buildPacket() works correctly. */ public static final int MIN_MTU = 620; - /** 1276 */ - public static final int MIN_IPV6_MTU = MTU.rectify(1280); + + /** + * IPv6/UDP header is 48 bytes, so we want MTU % 16 == 0. + */ + public static final int MIN_IPV6_MTU = 1280; + public static final int MAX_IPV6_MTU = 1472; // TODO 1488 private static final int DEFAULT_MTU = MIN_MTU; /* diff --git a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java index ff77ad0e6..55fa9788d 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java @@ -67,8 +67,10 @@ class UDPAddress { _port = addr.getPort(); try { String mtu = addr.getOption(PROP_MTU); - if (mtu != null) - _mtu = MTU.rectify(Integer.parseInt(mtu)); + if (mtu != null) { + boolean isIPv6 = _host != null && _host.contains(":"); + _mtu = MTU.rectify(isIPv6, Integer.parseInt(mtu)); + } } catch (NumberFormatException nfe) {} String key = addr.getOption(PROP_INTRO_KEY); if (key != null) { diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index ca36c3d1b..c06851925 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -587,8 +587,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority String p = _context.getProperty(PROP_DEFAULT_MTU); if (p != null) { try { - _mtu = MTU.rectify(Integer.parseInt(p)); - _mtu_ipv6 = Math.max(_mtu, PeerState.MIN_IPV6_MTU); + int pmtu = Integer.parseInt(p); + _mtu = MTU.rectify(false, pmtu); + _mtu_ipv6 = MTU.rectify(true, pmtu); return _mtu; } catch (NumberFormatException nfe) {} }