From db9db18bdf0b69ee0c2af735fbe1fc8776c1fd68 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 5 Jun 2008 12:30:12 +0000 Subject: [PATCH] * LeaseSet - code cleanup: - Add exception to enforce max # of leases = 6, should be plenty - Rewrite TunnelPool.locked_buildNewLeaseSet() so it doesn't add lots of leases and then immediately remove them again, triggering the new leaseSet size exception - Remove the now unused LeaseSet.removeLease(lease) and LeaseSet.removeLease(index) - Store first and last expiration for efficiency --- core/java/src/net/i2p/data/LeaseSet.java | 66 +++++++------------ history.txt | 19 ++++++ .../src/net/i2p/router/RouterVersion.java | 2 +- .../i2p/router/tunnel/pool/TunnelPool.java | 27 ++++---- 4 files changed, 59 insertions(+), 55 deletions(-) diff --git a/core/java/src/net/i2p/data/LeaseSet.java b/core/java/src/net/i2p/data/LeaseSet.java index f2f54aab85..950f64b03a 100644 --- a/core/java/src/net/i2p/data/LeaseSet.java +++ b/core/java/src/net/i2p/data/LeaseSet.java @@ -31,14 +31,18 @@ public class LeaseSet extends DataStructureImpl { private Destination _destination; private PublicKey _encryptionKey; private SigningPublicKey _signingKey; + // Keep leases in the order received, or else signature verification will fail! private List _leases; private Signature _signature; private volatile Hash _currentRoutingKey; private volatile byte[] _routingKeyGenMod; private boolean _receivedAsPublished; + // Store these since isCurrent() and getEarliestLeaseDate() are called frequently + private long _firstExpiration; + private long _lastExpiration; - /** um, no lease can last more than a year. */ - private final static long MAX_FUTURE_EXPIRATION = 365 * 24 * 60 * 60 * 1000L; + /** This seems like plenty */ + private final static int MAX_LEASES = 6; public LeaseSet() { setDestination(null); @@ -49,6 +53,8 @@ public class LeaseSet extends DataStructureImpl { _leases = new ArrayList(); _routingKeyGenMod = null; _receivedAsPublished = false; + _firstExpiration = Long.MAX_VALUE; + _lastExpiration = 0; } public Destination getDestination() { @@ -87,14 +93,14 @@ public class LeaseSet extends DataStructureImpl { if (lease == null) throw new IllegalArgumentException("erm, null lease"); if (lease.getGateway() == null) throw new IllegalArgumentException("erm, lease has no gateway"); if (lease.getTunnelId() == null) throw new IllegalArgumentException("erm, lease has no tunnel"); + if (_leases.size() > MAX_LEASES) + throw new IllegalArgumentException("Too many leases - max is " + MAX_LEASES); _leases.add(lease); - } - - public void removeLease(Lease lease) { - _leases.remove(lease); - } - public void removeLease(int index) { - _leases.remove(index); + long expire = lease.getEndDate().getTime(); + if (expire < _firstExpiration) + _firstExpiration = expire; + if (expire > _lastExpiration) + _lastExpiration = expire; } public int getLeaseCount() { @@ -150,14 +156,9 @@ public class LeaseSet extends DataStructureImpl { * @return earliest end date of any lease in the set, or -1 if there are no leases */ public long getEarliestLeaseDate() { - long when = -1; - for (int i = 0; i < getLeaseCount(); i++) { - Lease lse = getLease(i); - if ((lse != null) && (lse.getEndDate() != null)) { - if ((when <= 0) || (lse.getEndDate().getTime() < when)) when = lse.getEndDate().getTime(); - } - } - return when; + if (_leases.size() <= 0) + return -1; + return _firstExpiration; } /** @@ -211,7 +212,7 @@ public class LeaseSet extends DataStructureImpl { } /** - * Determine whether there are currently valid leases, at least within a given + * Determine whether ANY lease is currently valid, at least within a given * fudge factor * * @param fudge milliseconds fudge factor to allow between the current time @@ -219,28 +220,7 @@ public class LeaseSet extends DataStructureImpl { */ public boolean isCurrent(long fudge) { long now = Clock.getInstance().now(); - long insane = now + MAX_FUTURE_EXPIRATION; - int cnt = getLeaseCount(); - for (int i = 0; i < cnt; i++) { - Lease l = getLease(i); - if (l.getEndDate().getTime() > insane) { - if (_log.shouldLog(Log.WARN)) - _log.warn("LeaseSet" + calculateHash() + " expires an insane amount in the future - skip it: " + l); - return false; - } - // if it hasn't finished, we're current - if (l.getEndDate().getTime() > now) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("LeaseSet " + calculateHash() + " isn't exired: " + l); - return true; - } else if (l.getEndDate().getTime() > now - fudge) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("LeaseSet " + calculateHash() - + " isn't quite expired, but its within the fudge factor so we'll let it slide: " + l); - return true; - } - } - return false; + return _lastExpiration > now - fudge; } private byte[] getBytes() { @@ -282,12 +262,14 @@ public class LeaseSet extends DataStructureImpl { _signingKey = new SigningPublicKey(); _signingKey.readBytes(in); int numLeases = (int) DataHelper.readLong(in, 1); + if (numLeases > MAX_LEASES) + throw new DataFormatException("Too many leases - max is " + MAX_LEASES); //_version = DataHelper.readLong(in, 4); _leases.clear(); for (int i = 0; i < numLeases; i++) { Lease lease = new Lease(); lease.readBytes(in); - _leases.add(lease); + addLease(lease); } _signature = new Signature(); _signature.readBytes(in); @@ -351,4 +333,4 @@ public class LeaseSet extends DataStructureImpl { buf.append("]"); return buf.toString(); } -} \ No newline at end of file +} diff --git a/history.txt b/history.txt index 3fc6c976f1..88188a88c0 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,22 @@ +2008-06-05 zzz + * LeaseSet - code cleanup: + - Add exception to enforce max # of leases = 6, should be plenty + - Rewrite TunnelPool.locked_buildNewLeaseSet() so it doesn't add lots of + leases and then immediately remove them again, triggering + the new leaseSet size exception + - Remove the now unused LeaseSet.removeLease(lease) and + LeaseSet.removeLease(index) + - Store first and last expiration for efficiency + * Peer Profiles - Preparation for using bonuses: + - Use CapacityBonus rather than ReachablilityBonus in the Capacity calculation + - Persist CapacityBonus rather than ReachabilityBonus + - Include SpeedBonus in the Speed calculation + - Prevent negative values in Speed and Capacity when using bonuses + - Clean up SpeedCalculator.java + * HTTP Proxy error pages: Don't say eepsites are 'temporarily' down since we don't know + * Add some config files for a future small distribution + * configtunnels.jsp: Add warnings for <= 0 and >= 4 hop configurations + 2008-06-01 zzz * Client Apps: Add new parameter for clients.config, clientApp.x.startOnLoad=false, to disable loading diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 8e9ac9b180..aa1c4a3395 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -17,7 +17,7 @@ import net.i2p.CoreVersion; public class RouterVersion { public final static String ID = "$Revision: 1.548 $ $Date: 2008-02-10 15:00:00 $"; public final static String VERSION = "0.6.1.33"; - public final static long BUILD = 2001; + public final static long BUILD = 2002; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID); 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 24a3686b9e..bc4864ed0e 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java @@ -430,7 +430,7 @@ public class TunnelPool { } /** - * Build a leaseSet with all of the tunnels that aren't about to expire + * Build a leaseSet with the required tunnels that aren't about to expire * */ private LeaseSet locked_buildNewLeaseSet() { @@ -438,7 +438,7 @@ public class TunnelPool { return null; long expireAfter = _context.clock().now(); // + _settings.getRebuildPeriod(); - LeaseSet ls = new LeaseSet(); + List leases = new ArrayList(_tunnels.size()); for (int i = 0; i < _tunnels.size(); i++) { TunnelInfo tunnel = (TunnelInfo)_tunnels.get(i); if (tunnel.getExpiration() <= expireAfter) @@ -454,34 +454,37 @@ public class TunnelPool { lease.setEndDate(new Date(tunnel.getExpiration())); lease.setTunnelId(inId); lease.setGateway(gw); - ls.addLease(lease); + leases.add(lease); } int wanted = _settings.getQuantity(); - if (ls.getLeaseCount() < wanted) { + if (leases.size() < wanted) { if (_log.shouldLog(Log.WARN)) - _log.warn(toString() + ": Not enough leases (" + ls.getLeaseCount() + ", wanted " + wanted + ")"); + _log.warn(toString() + ": Not enough leases (" + leases.size() + ", wanted " + wanted + ")"); return null; } else { // linear search to trim down the leaseSet, removing the ones that // will expire the earliest. cheaper than a tree for this size - while (ls.getLeaseCount() > wanted) { + while (leases.size() > wanted) { int earliestIndex = -1; long earliestExpiration = -1; - for (int i = 0; i < ls.getLeaseCount(); i++) { - Lease cur = ls.getLease(i); + for (int i = 0; i < leases.size(); i++) { + Lease cur = (Lease) leases.get(i); if ( (earliestExpiration < 0) || (cur.getEndDate().getTime() < earliestExpiration) ) { earliestIndex = i; earliestExpiration = cur.getEndDate().getTime(); } } - if (_log.shouldLog(Log.DEBUG)) - _log.debug(toString() + ": Dropping older lease from the leaseSet: " + earliestIndex + " out of " + ls.getLeaseCount()); - ls.removeLease(earliestIndex); + leases.remove(earliestIndex); } - return ls; } + LeaseSet ls = new LeaseSet(); + for (int i = 0; i < leases.size(); i++) + ls.addLease((Lease) leases.get(i)); + if (_log.shouldLog(Log.INFO)) + _log.info(toString() + ": built new leaseSet: " + ls); + return ls; } public long getLifetimeProcessed() { return _lifetimeProcessed; }