From 1b95b00b445595d919240826307a76ca32d509c3 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Wed, 6 Jan 2010 17:16:00 +0000 Subject: [PATCH] prevent more than one zero-hop tunnel in a leaseset --- .../i2p/router/tunnel/pool/TunnelPool.java | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java index 39e6c2280c..965d113f13 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java @@ -163,7 +163,7 @@ public class TunnelPool { TunnelInfo backloggedTunnel = null; if (avoidZeroHop) { for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo info = (TunnelInfo)_tunnels.get(i); + TunnelInfo info = _tunnels.get(i); if ( (info.getLength() > 1) && (info.getExpiration() > _context.clock().now()) ) { // avoid outbound tunnels where the 1st hop is backlogged if (_settings.isInbound() || !_context.commSystem().isBacklogged(info.getPeer(1))) { @@ -184,7 +184,7 @@ public class TunnelPool { // ok, either we are ok using zero hop tunnels, or only fallback tunnels remain. pick 'em // randomly for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo info = (TunnelInfo)_tunnels.get(i); + TunnelInfo info = _tunnels.get(i); if (info.getExpiration() > _context.clock().now()) { // avoid outbound tunnels where the 1st hop is backlogged if (_settings.isInbound() || info.getLength() <= 1 || @@ -216,7 +216,7 @@ public class TunnelPool { public TunnelInfo getTunnel(TunnelId gatewayId) { synchronized (_tunnels) { for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo info = (TunnelInfo)_tunnels.get(i); + TunnelInfo info = _tunnels.get(i); if (_settings.isInbound()) { if (info.getReceiveTunnelId(0).equals(gatewayId)) return info; @@ -249,7 +249,7 @@ public class TunnelPool { int fallbacks = 0; synchronized (_tunnels) { for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo info = (TunnelInfo)_tunnels.get(i); + TunnelInfo info = _tunnels.get(i); if (info.getLength() <= 1 && ++fallbacks >= needed) return false; } @@ -487,12 +487,27 @@ public class TunnelPool { long expireAfter = _context.clock().now(); // + _settings.getRebuildPeriod(); - TreeSet leases = new TreeSet(new LeaseComparator()); + TunnelInfo zeroHopTunnel = null; + Lease zeroHopLease = null; + TreeSet<Lease> leases = new TreeSet(new LeaseComparator()); for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo tunnel = (TunnelInfo)_tunnels.get(i); + TunnelInfo tunnel = _tunnels.get(i); if (tunnel.getExpiration() <= expireAfter) continue; // expires too soon, skip it - + + if (tunnel.getLength() <= 1) { + // More than one zero-hop tunnel in a lease is pointless + // and increases the leaseset size needlessly. + // Keep only the one that expires the latest. + if (zeroHopTunnel != null) { + if (zeroHopTunnel.getExpiration() > tunnel.getExpiration()) + continue; + if (zeroHopLease != null) + leases.remove(zeroHopLease); + } + zeroHopTunnel = tunnel; + } + TunnelId inId = tunnel.getReceiveTunnelId(0); Hash gw = tunnel.getPeer(0); if ( (inId == null) || (gw == null) ) { @@ -504,6 +519,9 @@ public class TunnelPool { lease.setTunnelId(inId); lease.setGateway(gw); leases.add(lease); + // remember in case we want to remove it for a later-expiring zero-hopper + if (tunnel.getLength() <= 1) + zeroHopLease = lease; } // Go ahead and use less leases for now, hopefully a new tunnel will be built soon @@ -523,10 +541,10 @@ public class TunnelPool { } LeaseSet ls = new LeaseSet(); - Iterator iter = leases.iterator(); + Iterator<Lease> iter = leases.iterator(); int count = Math.min(leases.size(), wanted); for (int i = 0; i < count; i++) - ls.addLease((Lease) iter.next()); + ls.addLease(iter.next()); if (_log.shouldLog(Log.INFO)) _log.info(toString() + ": built new leaseSet: " + ls); return ls; @@ -608,7 +626,7 @@ public class TunnelPool { synchronized (_tunnels) { expireTime = new int[_tunnels.size()]; for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo info = (TunnelInfo)_tunnels.get(i); + TunnelInfo info = _tunnels.get(i); if (allowZeroHop || (info.getLength() > 1)) { int timeToExpire = (int) (info.getExpiration() - now); if (timeToExpire > 0 && timeToExpire < avg) { @@ -681,7 +699,7 @@ public class TunnelPool { synchronized (_tunnels) { boolean enough = _tunnels.size() > wanted; for (int i = 0; i < _tunnels.size(); i++) { - TunnelInfo info = (TunnelInfo)_tunnels.get(i); + TunnelInfo info = _tunnels.get(i); if (allowZeroHop || (info.getLength() > 1)) { long timeToExpire = info.getExpiration() - expireAfter; if (timeToExpire <= 0) { -- GitLab