* SessionKeyManager:

- More stubs for per-destination managers.
        No functional changes yet.
This commit is contained in:
zzz
2009-05-29 13:57:50 +00:00
parent 0a8cbcbfb6
commit 22609bbfdb
8 changed files with 75 additions and 5 deletions

View File

@ -40,6 +40,7 @@ public class TransientSessionKeyManager extends SessionKeyManager {
/** Map allowing us to go from a SessionTag to the containing TagSet */
private Map<SessionTag, TagSet> _inboundTagSets;
protected I2PAppContext _context;
private volatile boolean _alive;
/**
* Let session tags sit around for 10 minutes before expiring them. We can now have such a large
@ -75,19 +76,34 @@ public class TransientSessionKeyManager extends SessionKeyManager {
_inboundTagSets = new HashMap(1024);
context.statManager().createRateStat("crypto.sessionTagsExpired", "How many tags/sessions are expired?", "Encryption", new long[] { 10*60*1000, 60*60*1000, 3*60*60*1000 });
context.statManager().createRateStat("crypto.sessionTagsRemaining", "How many tags/sessions are remaining after a cleanup?", "Encryption", new long[] { 10*60*1000, 60*60*1000, 3*60*60*1000 });
SimpleScheduler.getInstance().addPeriodicEvent(new CleanupEvent(), 60*1000);
_alive = true;
SimpleScheduler.getInstance().addEvent(new CleanupEvent(), 60*1000);
}
private TransientSessionKeyManager() { this(null); }
public void shutdown() {
_alive = false;
synchronized (_inboundTagSets) {
_inboundTagSets.clear();
}
synchronized (_outboundSessions) {
_outboundSessions.clear();
}
}
private class CleanupEvent implements SimpleTimer.TimedEvent {
public void timeReached() {
if (!_alive)
return;
long beforeExpire = _context.clock().now();
int expired = aggressiveExpire();
long expireTime = _context.clock().now() - beforeExpire;
_context.statManager().addRateData("crypto.sessionTagsExpired", expired, expireTime);
SimpleScheduler.getInstance().addEvent(this, 60*1000);
}
}
/** TagSet */
protected Set<TagSet> getInboundTagSets() {
synchronized (_inboundTagSets) {

View File

@ -13,6 +13,7 @@ import java.io.Writer;
import java.util.Collections;
import java.util.Set;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
@ -91,5 +92,6 @@ public abstract class ClientManagerFacade implements Service {
*
*/
public abstract SessionConfig getClientSessionConfig(Destination dest);
public abstract SessionKeyManager getClientSessionKeyManager(Destination dest);
public void renderStatusHTML(Writer out) throws IOException { }
}

View File

@ -8,6 +8,7 @@ package net.i2p.router;
*
*/
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
@ -40,6 +41,7 @@ public class DummyClientManagerFacade extends ClientManagerFacade {
public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, boolean delivered) {}
public SessionConfig getClientSessionConfig(Destination _dest) { return null; }
public SessionKeyManager getClientSessionKeyManager(Destination _dest) { return null; }
public void requestLeaseSet(Hash dest, LeaseSet set) {}

View File

@ -17,6 +17,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.crypto.TransientSessionKeyManager;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
@ -68,6 +70,8 @@ public class ClientConnectionRunner {
private Set<MessageId> _acceptedPending;
/** thingy that does stuff */
private I2CPMessageReader _reader;
/** just for this destination */
private SessionKeyManager _sessionKeyManager;
/**
* This contains the last 10 MessageIds that have had their (non-ack) status
* delivered to the client (so that we can be sure only to update when necessary)
@ -129,6 +133,8 @@ public class ClientConnectionRunner {
if (_writer != null) _writer.stopWriting();
if (_socket != null) try { _socket.close(); } catch (IOException ioe) { }
_messages.clear();
if (_sessionKeyManager != null)
_sessionKeyManager.shutdown();
if (_manager != null)
_manager.unregisterConnection(this);
if (_currentLeaseSet != null)
@ -143,6 +149,8 @@ public class ClientConnectionRunner {
/** current client's config */
public SessionConfig getConfig() { return _config; }
/** current client's sessionkeymanager */
public SessionKeyManager getSessionKeyManager() { return _sessionKeyManager; }
/** currently allocated leaseSet */
public LeaseSet getLeaseSet() { return _currentLeaseSet; }
void setLeaseSet(LeaseSet ls) { _currentLeaseSet = ls; }
@ -181,6 +189,11 @@ public class ClientConnectionRunner {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SessionEstablished called for destination " + _destHashCache.toBase64());
_config = config;
// per-dest unimplemented
//if (_sessionKeyManager == null)
// _sessionKeyManager = new TransientSessionKeyManager(_context);
//else
// _log.error("SessionEstablished called for twice for destination " + _destHashCache.toBase64().substring(0,4));
_manager.destinationEstablished(this);
}

View File

@ -16,6 +16,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
@ -314,6 +315,18 @@ public class ClientManager {
return null;
}
/**
* Return the client's SessionKeyManager
*
*/
public SessionKeyManager getClientSessionKeyManager(Destination dest) {
ClientConnectionRunner runner = getRunner(dest);
if (runner != null)
return runner.getSessionKeyManager();
else
return null;
}
private ClientConnectionRunner getRunner(Hash destHash) {
if (destHash == null)
return null;

View File

@ -14,6 +14,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
@ -199,6 +200,19 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade {
}
}
/**
* Return the client's current manager or null if not connected
*
*/
public SessionKeyManager getClientSessionKeyManager(Destination dest) {
if (_manager != null)
return _manager.getClientSessionKeyManager(dest);
else {
_log.error("Null manager on getClientSessionKeyManager!");
return null;
}
}
@Override
public void renderStatusHTML(Writer out) throws IOException {
if (_manager != null)

View File

@ -14,8 +14,10 @@ import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.PublicKey;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
@ -61,22 +63,30 @@ public class GarlicMessageBuilder {
private static final int DEFAULT_TAGS = 40;
private static final int LOW_THRESHOLD = 20;
public static int estimateAvailableTags(RouterContext ctx, PublicKey key) {
SessionKey curKey = ctx.sessionKeyManager().getCurrentKey(key);
public static int estimateAvailableTags(RouterContext ctx, PublicKey key, Destination local) {
// per-dest Unimplemented
//SessionKeyManager skm = ctx.clientManager().getClientSessionKeyManager(local);
SessionKeyManager skm = ctx.sessionKeyManager();
if (skm == null)
return 0;
SessionKey curKey = skm.getCurrentKey(key);
if (curKey == null)
return 0;
return ctx.sessionKeyManager().getAvailableTags(key, curKey);
return skm.getAvailableTags(key, curKey);
}
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config) {
return buildMessage(ctx, config, new SessionKey(), new HashSet());
}
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set wrappedTags) {
return buildMessage(ctx, config, wrappedKey, wrappedTags, DEFAULT_TAGS);
}
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set wrappedTags, int numTagsToDeliver) {
return buildMessage(ctx, config, wrappedKey, wrappedTags, numTagsToDeliver, false);
}
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set wrappedTags, int numTagsToDeliver, boolean forceElGamal) {
Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
PublicKey key = config.getRecipientPublicKey();

View File

@ -471,7 +471,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
return;
}
int existingTags = GarlicMessageBuilder.estimateAvailableTags(getContext(), _leaseSet.getEncryptionKey());
int existingTags = GarlicMessageBuilder.estimateAvailableTags(getContext(), _leaseSet.getEncryptionKey(), _from);
_outTunnel = selectOutboundTunnel(_to);
// boolean wantACK = _wantACK || existingTags <= 30 || getContext().random().nextInt(100) < 5;
// what's the point of 5% random? possible improvements or replacements: