* 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
This commit is contained in:
zzz
2008-06-05 12:30:12 +00:00
parent 9c06bb3fca
commit db9db18bdf
4 changed files with 59 additions and 55 deletions

View File

@ -31,14 +31,18 @@ public class LeaseSet extends DataStructureImpl {
private Destination _destination; private Destination _destination;
private PublicKey _encryptionKey; private PublicKey _encryptionKey;
private SigningPublicKey _signingKey; private SigningPublicKey _signingKey;
// Keep leases in the order received, or else signature verification will fail!
private List _leases; private List _leases;
private Signature _signature; private Signature _signature;
private volatile Hash _currentRoutingKey; private volatile Hash _currentRoutingKey;
private volatile byte[] _routingKeyGenMod; private volatile byte[] _routingKeyGenMod;
private boolean _receivedAsPublished; 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. */ /** This seems like plenty */
private final static long MAX_FUTURE_EXPIRATION = 365 * 24 * 60 * 60 * 1000L; private final static int MAX_LEASES = 6;
public LeaseSet() { public LeaseSet() {
setDestination(null); setDestination(null);
@ -49,6 +53,8 @@ public class LeaseSet extends DataStructureImpl {
_leases = new ArrayList(); _leases = new ArrayList();
_routingKeyGenMod = null; _routingKeyGenMod = null;
_receivedAsPublished = false; _receivedAsPublished = false;
_firstExpiration = Long.MAX_VALUE;
_lastExpiration = 0;
} }
public Destination getDestination() { public Destination getDestination() {
@ -87,14 +93,14 @@ public class LeaseSet extends DataStructureImpl {
if (lease == null) throw new IllegalArgumentException("erm, null lease"); if (lease == null) throw new IllegalArgumentException("erm, null lease");
if (lease.getGateway() == null) throw new IllegalArgumentException("erm, lease has no gateway"); 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 (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); _leases.add(lease);
} long expire = lease.getEndDate().getTime();
if (expire < _firstExpiration)
public void removeLease(Lease lease) { _firstExpiration = expire;
_leases.remove(lease); if (expire > _lastExpiration)
} _lastExpiration = expire;
public void removeLease(int index) {
_leases.remove(index);
} }
public int getLeaseCount() { 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 * @return earliest end date of any lease in the set, or -1 if there are no leases
*/ */
public long getEarliestLeaseDate() { public long getEarliestLeaseDate() {
long when = -1; if (_leases.size() <= 0)
for (int i = 0; i < getLeaseCount(); i++) { return -1;
Lease lse = getLease(i); return _firstExpiration;
if ((lse != null) && (lse.getEndDate() != null)) {
if ((when <= 0) || (lse.getEndDate().getTime() < when)) when = lse.getEndDate().getTime();
}
}
return when;
} }
/** /**
@ -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 * fudge factor
* *
* @param fudge milliseconds fudge factor to allow between the current time * @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) { public boolean isCurrent(long fudge) {
long now = Clock.getInstance().now(); long now = Clock.getInstance().now();
long insane = now + MAX_FUTURE_EXPIRATION; return _lastExpiration > now - fudge;
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;
} }
private byte[] getBytes() { private byte[] getBytes() {
@ -282,12 +262,14 @@ public class LeaseSet extends DataStructureImpl {
_signingKey = new SigningPublicKey(); _signingKey = new SigningPublicKey();
_signingKey.readBytes(in); _signingKey.readBytes(in);
int numLeases = (int) DataHelper.readLong(in, 1); 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); //_version = DataHelper.readLong(in, 4);
_leases.clear(); _leases.clear();
for (int i = 0; i < numLeases; i++) { for (int i = 0; i < numLeases; i++) {
Lease lease = new Lease(); Lease lease = new Lease();
lease.readBytes(in); lease.readBytes(in);
_leases.add(lease); addLease(lease);
} }
_signature = new Signature(); _signature = new Signature();
_signature.readBytes(in); _signature.readBytes(in);

View File

@ -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 2008-06-01 zzz
* Client Apps: Add new parameter for clients.config, * Client Apps: Add new parameter for clients.config,
clientApp.x.startOnLoad=false, to disable loading clientApp.x.startOnLoad=false, to disable loading

View File

@ -17,7 +17,7 @@ import net.i2p.CoreVersion;
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.548 $ $Date: 2008-02-10 15:00:00 $"; 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 String VERSION = "0.6.1.33";
public final static long BUILD = 2001; public final static long BUILD = 2002;
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID); System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -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() { private LeaseSet locked_buildNewLeaseSet() {
@ -438,7 +438,7 @@ public class TunnelPool {
return null; return null;
long expireAfter = _context.clock().now(); // + _settings.getRebuildPeriod(); 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++) { for (int i = 0; i < _tunnels.size(); i++) {
TunnelInfo tunnel = (TunnelInfo)_tunnels.get(i); TunnelInfo tunnel = (TunnelInfo)_tunnels.get(i);
if (tunnel.getExpiration() <= expireAfter) if (tunnel.getExpiration() <= expireAfter)
@ -454,35 +454,38 @@ public class TunnelPool {
lease.setEndDate(new Date(tunnel.getExpiration())); lease.setEndDate(new Date(tunnel.getExpiration()));
lease.setTunnelId(inId); lease.setTunnelId(inId);
lease.setGateway(gw); lease.setGateway(gw);
ls.addLease(lease); leases.add(lease);
} }
int wanted = _settings.getQuantity(); int wanted = _settings.getQuantity();
if (ls.getLeaseCount() < wanted) { if (leases.size() < wanted) {
if (_log.shouldLog(Log.WARN)) 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; return null;
} else { } else {
// linear search to trim down the leaseSet, removing the ones that // linear search to trim down the leaseSet, removing the ones that
// will expire the earliest. cheaper than a tree for this size // will expire the earliest. cheaper than a tree for this size
while (ls.getLeaseCount() > wanted) { while (leases.size() > wanted) {
int earliestIndex = -1; int earliestIndex = -1;
long earliestExpiration = -1; long earliestExpiration = -1;
for (int i = 0; i < ls.getLeaseCount(); i++) { for (int i = 0; i < leases.size(); i++) {
Lease cur = ls.getLease(i); Lease cur = (Lease) leases.get(i);
if ( (earliestExpiration < 0) || (cur.getEndDate().getTime() < earliestExpiration) ) { if ( (earliestExpiration < 0) || (cur.getEndDate().getTime() < earliestExpiration) ) {
earliestIndex = i; earliestIndex = i;
earliestExpiration = cur.getEndDate().getTime(); earliestExpiration = cur.getEndDate().getTime();
} }
} }
if (_log.shouldLog(Log.DEBUG)) leases.remove(earliestIndex);
_log.debug(toString() + ": Dropping older lease from the leaseSet: " + earliestIndex + " out of " + ls.getLeaseCount());
ls.removeLease(earliestIndex);
} }
}
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; return ls;
} }
}
public long getLifetimeProcessed() { return _lifetimeProcessed; } public long getLifetimeProcessed() { return _lifetimeProcessed; }