From e65c2e279b77d0c2c67f7b77c10a0cb30ea27e82 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Fri, 29 May 2009 10:00:06 +0000 Subject: [PATCH] * Session Keys: - Don't instantiate unused SessionKeyPersistenceHelper - Use TransientSessionKeyManager instead of PersistentSessionKeyManager - Add generics to TransientSessionKeyManager to help understand it - Change initial session map size to 64 (was 1024) - Prepare for per-destination SessionKeyManagers in ElGamalAESEngine --- core/java/src/net/i2p/I2PAppContext.java | 5 +- .../src/net/i2p/crypto/ElGamalAESEngine.java | 15 +- .../crypto/PersistentSessionKeyManager.java | 190 ------------------ .../src/net/i2p/crypto/SessionKeyManager.java | 6 +- .../crypto/TransientSessionKeyManager.java | 137 +++++++------ router/java/src/net/i2p/router/Router.java | 8 +- .../router/SessionKeyPersistenceHelper.java | 115 ----------- 7 files changed, 97 insertions(+), 379 deletions(-) delete mode 100644 core/java/src/net/i2p/crypto/PersistentSessionKeyManager.java delete mode 100644 router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java index f26f74ab7b..3f44146b43 100644 --- a/core/java/src/net/i2p/I2PAppContext.java +++ b/core/java/src/net/i2p/I2PAppContext.java @@ -17,9 +17,9 @@ import net.i2p.crypto.ElGamalEngine; import net.i2p.crypto.HMAC256Generator; import net.i2p.crypto.HMACGenerator; import net.i2p.crypto.KeyGenerator; -import net.i2p.crypto.PersistentSessionKeyManager; import net.i2p.crypto.SHA256Generator; import net.i2p.crypto.SessionKeyManager; +import net.i2p.crypto.TransientSessionKeyManager; import net.i2p.data.RoutingKeyGenerator; import net.i2p.stat.StatManager; import net.i2p.util.Clock; @@ -256,7 +256,8 @@ public class I2PAppContext { private void initializeSessionKeyManager() { synchronized (this) { if (_sessionKeyManager == null) - _sessionKeyManager = new PersistentSessionKeyManager(this); + //_sessionKeyManager = new PersistentSessionKeyManager(this); + _sessionKeyManager = new TransientSessionKeyManager(this); _sessionKeyManagerInitialized = true; } } diff --git a/core/java/src/net/i2p/crypto/ElGamalAESEngine.java b/core/java/src/net/i2p/crypto/ElGamalAESEngine.java index 1d67918f78..3e191faaa4 100644 --- a/core/java/src/net/i2p/crypto/ElGamalAESEngine.java +++ b/core/java/src/net/i2p/crypto/ElGamalAESEngine.java @@ -58,12 +58,19 @@ public class ElGamalAESEngine { new long[] { 60 * 60 * 1000l, 24 * 60 * 60 * 1000l}); } + /** + * Decrypt the message using the given private key using tags from the given key manager. + */ + public byte[] decrypt(byte data[], PrivateKey targetPrivateKey) throws DataFormatException { + return decrypt(data, targetPrivateKey, _context.sessionKeyManager()); + } + /** * Decrypt the message using the given private key. This works according to the * ElGamal+AES algorithm in the data structure spec. * */ - public byte[] decrypt(byte data[], PrivateKey targetPrivateKey) throws DataFormatException { + public byte[] decrypt(byte data[], PrivateKey targetPrivateKey, SessionKeyManager keyManager) throws DataFormatException { if (data == null) { if (_log.shouldLog(Log.ERROR)) _log.error("Null data being decrypted?"); return null; @@ -76,7 +83,7 @@ public class ElGamalAESEngine { byte tag[] = new byte[32]; System.arraycopy(data, 0, tag, 0, tag.length); SessionTag st = new SessionTag(tag); - SessionKey key = _context.sessionKeyManager().consumeTag(st); + SessionKey key = keyManager.consumeTag(st); SessionKey foundKey = new SessionKey(); foundKey.setData(null); SessionKey usedKey = new SessionKey(); @@ -124,11 +131,11 @@ public class ElGamalAESEngine { if (foundKey.getData() != null) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Found key: " + foundKey.toBase64() + " tags: " + foundTags + " wasExisting? " + wasExisting); - _context.sessionKeyManager().tagsReceived(foundKey, foundTags); + keyManager.tagsReceived(foundKey, foundTags); } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Used key: " + usedKey.toBase64() + " tags: " + foundTags + " wasExisting? " + wasExisting); - _context.sessionKeyManager().tagsReceived(usedKey, foundTags); + keyManager.tagsReceived(usedKey, foundTags); } } return decrypted; diff --git a/core/java/src/net/i2p/crypto/PersistentSessionKeyManager.java b/core/java/src/net/i2p/crypto/PersistentSessionKeyManager.java deleted file mode 100644 index 811e6e4121..0000000000 --- a/core/java/src/net/i2p/crypto/PersistentSessionKeyManager.java +++ /dev/null @@ -1,190 +0,0 @@ -package net.i2p.crypto; - -/* - * free (adj.): unencumbered; not under the control of others - * Written by jrandom in 2003 and released into the public domain - * with no warranty of any kind, either expressed or implied. - * It probably won't make your computer catch on fire, or eat - * your children, but it might. Use at your own risk. - * - */ - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import net.i2p.I2PAppContext; -import net.i2p.data.DataFormatException; -import net.i2p.data.DataHelper; -import net.i2p.data.PublicKey; -import net.i2p.data.SessionKey; -import net.i2p.data.SessionTag; -import net.i2p.util.Log; - -/** - * Expose the functionality to allow people to write out and read in the - * session key and session tag information via streams. This implementation - * does not write anywhere except where its told. - * - */ -public class PersistentSessionKeyManager extends TransientSessionKeyManager { - private Log _log; - private Object _yk = YKGenerator.class; - - - /** - * The session key manager should only be constructed and accessed through the - * application context. This constructor should only be used by the - * appropriate application context itself. - * - */ - public PersistentSessionKeyManager(I2PAppContext context) { - super(context); - _log = context.logManager().getLog(PersistentSessionKeyManager.class); - } - private PersistentSessionKeyManager() { - this(null); - } - /** - * Write the session key data to the given stream - * - */ - public void saveState(OutputStream out) throws IOException, DataFormatException { - if (true) return; - - Set tagSets = getInboundTagSets(); - Set sessions = getOutboundSessions(); - if (_log.shouldLog(Log.INFO)) - _log.info("Saving state with " + tagSets.size() + " inbound tagSets and " - + sessions.size() + " outbound sessions"); - - DataHelper.writeLong(out, 4, tagSets.size()); - for (Iterator iter = tagSets.iterator(); iter.hasNext();) { - TagSet ts = (TagSet) iter.next(); - writeTagSet(out, ts); - } - DataHelper.writeLong(out, 4, sessions.size()); - for (Iterator iter = sessions.iterator(); iter.hasNext();) { - OutboundSession sess = (OutboundSession) iter.next(); - writeOutboundSession(out, sess); - } - } - - /** - * Load the session key data from the given stream - * - */ - public void loadState(InputStream in) throws IOException, DataFormatException { - int inboundSets = (int) DataHelper.readLong(in, 4); - Set tagSets = new HashSet(inboundSets); - for (int i = 0; i < inboundSets; i++) { - TagSet ts = readTagSet(in); - tagSets.add(ts); - } - int outboundSessions = (int) DataHelper.readLong(in, 4); - Set sessions = new HashSet(outboundSessions); - for (int i = 0; i < outboundSessions; i++) { - OutboundSession sess = readOutboundSession(in); - sessions.add(sess); - } - - if (_log.shouldLog(Log.INFO)) - _log.info("Loading state with " + tagSets.size() + " inbound tagSets and " - + sessions.size() + " outbound sessions"); - setData(tagSets, sessions); - } - - private void writeOutboundSession(OutputStream out, OutboundSession sess) throws IOException, DataFormatException { - sess.getTarget().writeBytes(out); - sess.getCurrentKey().writeBytes(out); - DataHelper.writeDate(out, new Date(sess.getEstablishedDate())); - DataHelper.writeDate(out, new Date(sess.getLastUsedDate())); - List sets = sess.getTagSets(); - DataHelper.writeLong(out, 2, sets.size()); - for (Iterator iter = sets.iterator(); iter.hasNext();) { - TagSet set = (TagSet) iter.next(); - writeTagSet(out, set); - } - } - - private void writeTagSet(OutputStream out, TagSet ts) throws IOException, DataFormatException { - ts.getAssociatedKey().writeBytes(out); - DataHelper.writeDate(out, new Date(ts.getDate())); - DataHelper.writeLong(out, 2, ts.getTags().size()); - for (Iterator iter = ts.getTags().iterator(); iter.hasNext();) { - SessionTag tag = (SessionTag) iter.next(); - out.write(tag.getData()); - } - } - - private OutboundSession readOutboundSession(InputStream in) throws IOException, DataFormatException { - PublicKey key = new PublicKey(); - key.readBytes(in); - SessionKey skey = new SessionKey(); - skey.readBytes(in); - Date established = DataHelper.readDate(in); - Date lastUsed = DataHelper.readDate(in); - int tagSets = (int) DataHelper.readLong(in, 2); - ArrayList sets = new ArrayList(tagSets); - for (int i = 0; i < tagSets; i++) { - TagSet ts = readTagSet(in); - sets.add(ts); - } - - return new OutboundSession(key, skey, established.getTime(), lastUsed.getTime(), sets); - } - - private TagSet readTagSet(InputStream in) throws IOException, DataFormatException { - SessionKey key = new SessionKey(); - key.readBytes(in); - Date date = DataHelper.readDate(in); - int numTags = (int) DataHelper.readLong(in, 2); - Set tags = new HashSet(numTags); - for (int i = 0; i < numTags; i++) { - SessionTag tag = new SessionTag(); - byte val[] = new byte[SessionTag.BYTE_LENGTH]; - int read = DataHelper.read(in, val); - if (read != SessionTag.BYTE_LENGTH) - throw new IOException("Unable to fully read a session tag [" + read + " not " + SessionTag.BYTE_LENGTH - + ")"); - tag.setData(val); - tags.add(tag); - } - TagSet ts = new TagSet(tags, key, _context.clock().now()); - ts.setDate(date.getTime()); - return ts; - } - - public static void main(String args[]) { - I2PAppContext ctx = new I2PAppContext(); - Log log = ctx.logManager().getLog(PersistentSessionKeyManager.class); - PersistentSessionKeyManager mgr = (PersistentSessionKeyManager)ctx.sessionKeyManager(); - try { - mgr.loadState(new FileInputStream("sessionKeys.dat")); - String state = mgr.renderStatusHTML(); - FileOutputStream fos = new FileOutputStream("sessionKeysBeforeExpire.html"); - fos.write(state.getBytes()); - fos.close(); - int expired = mgr.aggressiveExpire(); - log.error("Expired: " + expired); - String stateAfter = mgr.renderStatusHTML(); - FileOutputStream fos2 = new FileOutputStream("sessionKeysAfterExpire.html"); - fos2.write(stateAfter.getBytes()); - fos2.close(); - } catch (Throwable t) { - log.error("Error loading/storing sessionKeys", t); - } - try { - Thread.sleep(3000); - } catch (Throwable t) { // nop - } - } -} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/SessionKeyManager.java b/core/java/src/net/i2p/crypto/SessionKeyManager.java index 5b609347bb..b1547864cd 100644 --- a/core/java/src/net/i2p/crypto/SessionKeyManager.java +++ b/core/java/src/net/i2p/crypto/SessionKeyManager.java @@ -93,7 +93,7 @@ public class SessionKeyManager { * method after receiving an ack to a message delivering them) * */ - public void tagsDelivered(PublicKey target, SessionKey key, Set sessionTags) { // nop + public void tagsDelivered(PublicKey target, SessionKey key, Set<SessionTag> sessionTags) { // nop } /** @@ -109,7 +109,7 @@ public class SessionKeyManager { * Accept the given tags and associate them with the given key for decryption * */ - public void tagsReceived(SessionKey key, Set sessionTags) { // nop + public void tagsReceived(SessionKey key, Set<SessionTag> sessionTags) { // nop } /** @@ -130,4 +130,4 @@ public class SessionKeyManager { */ public void shutdown() { // nop } -} \ No newline at end of file +} diff --git a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java index 80cd18ac8b..7c496c62d0 100644 --- a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java +++ b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java @@ -33,12 +33,12 @@ import net.i2p.util.SimpleTimer; * out to disk so this should not be considered secure in that sense. * */ -class TransientSessionKeyManager extends SessionKeyManager { +public class TransientSessionKeyManager extends SessionKeyManager { private Log _log; /** Map allowing us to go from the targeted PublicKey to the OutboundSession used */ - private Map _outboundSessions; + private Map<PublicKey, OutboundSession> _outboundSessions; /** Map allowing us to go from a SessionTag to the containing TagSet */ - private Map _inboundTagSets; + private Map<SessionTag, TagSet> _inboundTagSets; protected I2PAppContext _context; /** @@ -55,6 +55,10 @@ class TransientSessionKeyManager extends SessionKeyManager { * */ public final static long SESSION_LIFETIME_MAX_MS = SESSION_TAG_DURATION_MS + 5 * 60 * 1000; + /** + * a few MB? how about 16MB! + * This is the max size of _inboundTagSets. + */ public final static int MAX_INBOUND_SESSION_TAGS = 500 * 1000; // this will consume at most a few MB /** @@ -67,7 +71,7 @@ class TransientSessionKeyManager extends SessionKeyManager { super(context); _log = context.logManager().getLog(TransientSessionKeyManager.class); _context = context; - _outboundSessions = new HashMap(1024); + _outboundSessions = new HashMap(64); _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 }); @@ -85,28 +89,28 @@ class TransientSessionKeyManager extends SessionKeyManager { } /** TagSet */ - protected Set getInboundTagSets() { + protected Set<TagSet> getInboundTagSets() { synchronized (_inboundTagSets) { return new HashSet(_inboundTagSets.values()); } } /** OutboundSession */ - protected Set getOutboundSessions() { + protected Set<OutboundSession> getOutboundSessions() { synchronized (_outboundSessions) { return new HashSet(_outboundSessions.values()); } } - protected void setData(Set inboundTagSets, Set outboundSessions) { + protected void setData(Set<TagSet> inboundTagSets, Set<OutboundSession> outboundSessions) { if (_log.shouldLog(Log.INFO)) _log.info("Loading " + inboundTagSets.size() + " inbound tag sets, and " + outboundSessions.size() + " outbound sessions"); - Map tagSets = new HashMap(inboundTagSets.size()); - for (Iterator iter = inboundTagSets.iterator(); iter.hasNext();) { - TagSet ts = (TagSet) iter.next(); - for (Iterator tsIter = ts.getTags().iterator(); tsIter.hasNext();) { - SessionTag tag = (SessionTag) tsIter.next(); + Map<SessionTag, TagSet> tagSets = new HashMap(inboundTagSets.size()); + for (Iterator<TagSet> iter = inboundTagSets.iterator(); iter.hasNext();) { + TagSet ts = iter.next(); + for (Iterator<SessionTag> tsIter = ts.getTags().iterator(); tsIter.hasNext();) { + SessionTag tag = tsIter.next(); tagSets.put(tag, ts); } } @@ -114,9 +118,9 @@ class TransientSessionKeyManager extends SessionKeyManager { _inboundTagSets.clear(); _inboundTagSets.putAll(tagSets); } - Map sessions = new HashMap(outboundSessions.size()); - for (Iterator iter = outboundSessions.iterator(); iter.hasNext();) { - OutboundSession sess = (OutboundSession) iter.next(); + Map<PublicKey, OutboundSession> sessions = new HashMap(outboundSessions.size()); + for (Iterator<OutboundSession> iter = outboundSessions.iterator(); iter.hasNext();) { + OutboundSession sess = iter.next(); sessions.put(sess.getTarget(), sess); } synchronized (_outboundSessions) { @@ -151,6 +155,7 @@ class TransientSessionKeyManager extends SessionKeyManager { * Associate a new session key with the specified target. Metrics to determine * when to expire that key begin with this call. * + * Unused except in tests? */ @Override public void createSession(PublicKey target, SessionKey key) { @@ -159,6 +164,18 @@ class TransientSessionKeyManager extends SessionKeyManager { addSession(sess); } + /** + * Same as above but for internal use, returns OutboundSession so we don't have + * to do a subsequent getSession() + * + */ + private OutboundSession createAndReturnSession(PublicKey target, SessionKey key) { + OutboundSession sess = new OutboundSession(target); + sess.setCurrentKey(key); + addSession(sess); + return sess; + } + /** * Retrieve the next available session tag for identifying the use of the given * key when communicating with the target. If this returns null, no tags are @@ -232,10 +249,8 @@ class TransientSessionKeyManager extends SessionKeyManager { _log.debug("Tags delivered: " + sessionTags.size() + " for key: " + key.toBase64() + ": " + sessionTags); } OutboundSession sess = getSession(target); - if (sess == null) { - createSession(target, key); - sess = getSession(target); - } + if (sess == null) + sess = createAndReturnSession(target, key); sess.setCurrentKey(key); TagSet set = new TagSet(sessionTags, key, _context.clock().now()); sess.addTags(set); @@ -257,13 +272,13 @@ class TransientSessionKeyManager extends SessionKeyManager { * */ @Override - public void tagsReceived(SessionKey key, Set sessionTags) { + public void tagsReceived(SessionKey key, Set<SessionTag> sessionTags) { int overage = 0; TagSet tagSet = new TagSet(sessionTags, key, _context.clock().now()); TagSet old = null; SessionTag dupTag = null; - for (Iterator iter = sessionTags.iterator(); iter.hasNext();) { - SessionTag tag = (SessionTag) iter.next(); + for (Iterator<SessionTag> iter = sessionTags.iterator(); iter.hasNext();) { + SessionTag tag = iter.next(); if (_log.shouldLog(Log.DEBUG)) _log.debug("Receiving tag " + tag + " for key " + key.toBase64() + " / " + key.toString() + ": tagSet: " + tagSet); synchronized (_inboundTagSets) { @@ -284,12 +299,12 @@ class TransientSessionKeyManager extends SessionKeyManager { if (old != null) { // drop both old and tagSet tags synchronized (_inboundTagSets) { - for (Iterator iter = old.getTags().iterator(); iter.hasNext(); ) { - SessionTag tag = (SessionTag)iter.next(); + for (Iterator<SessionTag> iter = old.getTags().iterator(); iter.hasNext(); ) { + SessionTag tag = iter.next(); _inboundTagSets.remove(tag); } - for (Iterator iter = sessionTags.iterator(); iter.hasNext(); ) { - SessionTag tag = (SessionTag)iter.next(); + for (Iterator<SessionTag> iter = sessionTags.iterator(); iter.hasNext(); ) { + SessionTag tag = iter.next(); _inboundTagSets.remove(tag); } } @@ -326,10 +341,10 @@ class TransientSessionKeyManager extends SessionKeyManager { int tags = 0; int toRemove = overage * 2; _log.log(Log.CRIT, "TOO MANY SESSION TAGS! Starting cleanup, overage = " + overage); - List removed = new ArrayList(toRemove); + List<TagSet> removed = new ArrayList(toRemove); synchronized (_inboundTagSets) { - for (Iterator iter = _inboundTagSets.values().iterator(); iter.hasNext(); ) { - TagSet set = (TagSet)iter.next(); + for (Iterator<TagSet> iter = _inboundTagSets.values().iterator(); iter.hasNext(); ) { + TagSet set = iter.next(); int size = set.getTags().size(); if (size > 1000) absurd++; @@ -345,8 +360,8 @@ class TransientSessionKeyManager extends SessionKeyManager { } for (int i = 0; i < removed.size(); i++) { TagSet cur = (TagSet)removed.get(i); - for (Iterator iter = cur.getTags().iterator(); iter.hasNext(); ) { - SessionTag tag = (SessionTag)iter.next(); + for (Iterator<SessionTag> iter = cur.getTags().iterator(); iter.hasNext(); ) { + SessionTag tag = iter.next(); _inboundTagSets.remove(tag); tags++; } @@ -429,9 +444,9 @@ class TransientSessionKeyManager extends SessionKeyManager { bufSummary = new StringBuffer(1024); } synchronized (_inboundTagSets) { - for (Iterator iter = _inboundTagSets.keySet().iterator(); iter.hasNext();) { - SessionTag tag = (SessionTag) iter.next(); - TagSet ts = (TagSet) _inboundTagSets.get(tag); + for (Iterator<SessionTag> iter = _inboundTagSets.keySet().iterator(); iter.hasNext();) { + SessionTag tag = iter.next(); + TagSet ts = _inboundTagSets.get(tag); long age = now - ts.getDate(); if (age > SESSION_LIFETIME_MAX_MS) { //if (ts.getDate() < now - SESSION_LIFETIME_MAX_MS) { @@ -455,9 +470,9 @@ class TransientSessionKeyManager extends SessionKeyManager { //_log.warn("Expiring tags: [" + tagsToDrop + "]"); synchronized (_outboundSessions) { - for (Iterator iter = _outboundSessions.keySet().iterator(); iter.hasNext();) { - PublicKey key = (PublicKey) iter.next(); - OutboundSession sess = (OutboundSession) _outboundSessions.get(key); + for (Iterator<PublicKey> iter = _outboundSessions.keySet().iterator(); iter.hasNext();) { + PublicKey key = iter.next(); + OutboundSession sess = _outboundSessions.get(key); removed += sess.expireTags(); if (sess.availableTags() <= 0) { iter.remove(); @@ -472,22 +487,22 @@ class TransientSessionKeyManager extends SessionKeyManager { StringBuffer buf = new StringBuffer(1024); buf.append("<h2>Inbound sessions</h2>"); buf.append("<table border=\"1\">"); - Set inbound = getInboundTagSets(); - Map inboundSets = new HashMap(inbound.size()); - for (Iterator iter = inbound.iterator(); iter.hasNext();) { - TagSet ts = (TagSet) iter.next(); + Set<TagSet> inbound = getInboundTagSets(); + Map<SessionKey, Set<TagSet>> inboundSets = new HashMap(inbound.size()); + for (Iterator<TagSet> iter = inbound.iterator(); iter.hasNext();) { + TagSet ts = iter.next(); if (!inboundSets.containsKey(ts.getAssociatedKey())) inboundSets.put(ts.getAssociatedKey(), new HashSet()); - Set sets = (Set) inboundSets.get(ts.getAssociatedKey()); + Set<TagSet> sets = inboundSets.get(ts.getAssociatedKey()); sets.add(ts); } - for (Iterator iter = inboundSets.keySet().iterator(); iter.hasNext();) { - SessionKey skey = (SessionKey) iter.next(); - Set sets = (Set) inboundSets.get(skey); + for (Iterator<SessionKey> iter = inboundSets.keySet().iterator(); iter.hasNext();) { + SessionKey skey = iter.next(); + Set<TagSet> sets = inboundSets.get(skey); buf.append("<tr><td><b>Session key</b>: ").append(skey.toBase64()).append("</td>"); buf.append("<td><b># Sets:</b> ").append(sets.size()).append("</td></tr>"); buf.append("<tr><td colspan=\"2\"><ul>"); - for (Iterator siter = sets.iterator(); siter.hasNext();) { - TagSet ts = (TagSet) siter.next(); + for (Iterator<TagSet> siter = sets.iterator(); siter.hasNext();) { + TagSet ts = siter.next(); buf.append("<li><b>Received on:</b> ").append(new Date(ts.getDate())).append(" with ") .append(ts.getTags().size()).append(" tags remaining</li>"); } @@ -498,17 +513,17 @@ class TransientSessionKeyManager extends SessionKeyManager { buf.append("<h2><b>Outbound sessions</b></h2>"); buf.append("<table border=\"1\">"); - Set outbound = getOutboundSessions(); - for (Iterator iter = outbound.iterator(); iter.hasNext();) { - OutboundSession sess = (OutboundSession) iter.next(); + Set<OutboundSession> outbound = getOutboundSessions(); + for (Iterator<OutboundSession> iter = outbound.iterator(); iter.hasNext();) { + OutboundSession sess = iter.next(); buf.append("<tr><td><b>Target key:</b> ").append(sess.getTarget().toString()).append("<br />"); buf.append("<b>Established:</b> ").append(new Date(sess.getEstablishedDate())).append("<br />"); buf.append("<b>Last Used:</b> ").append(new Date(sess.getLastUsedDate())).append("<br />"); buf.append("<b># Sets:</b> ").append(sess.getTagSets().size()).append("</td></tr>"); buf.append("<tr><td><b>Session key:</b> ").append(sess.getCurrentKey().toBase64()).append("</td></tr>"); buf.append("<tr><td><ul>"); - for (Iterator siter = sess.getTagSets().iterator(); siter.hasNext();) { - TagSet ts = (TagSet) siter.next(); + for (Iterator<TagSet> siter = sess.getTagSets().iterator(); siter.hasNext();) { + TagSet ts = siter.next(); buf.append("<li><b>Sent on:</b> ").append(new Date(ts.getDate())).append(" with ").append( ts.getTags() .size()) @@ -526,13 +541,13 @@ class TransientSessionKeyManager extends SessionKeyManager { private SessionKey _currentKey; private long _established; private long _lastUsed; - private List _tagSets; + private List<TagSet> _tagSets; public OutboundSession(PublicKey target) { this(target, null, _context.clock().now(), _context.clock().now(), new ArrayList()); } - OutboundSession(PublicKey target, SessionKey curKey, long established, long lastUsed, List tagSets) { + OutboundSession(PublicKey target, SessionKey curKey, long established, long lastUsed, List<TagSet> tagSets) { _target = target; _currentKey = curKey; _established = established; @@ -541,7 +556,7 @@ class TransientSessionKeyManager extends SessionKeyManager { } /** list of TagSet objects */ - List getTagSets() { + List<TagSet> getTagSets() { synchronized (_tagSets) { return new ArrayList(_tagSets); } @@ -560,7 +575,7 @@ class TransientSessionKeyManager extends SessionKeyManager { if (_currentKey != null) { if (!_currentKey.equals(key)) { int dropped = 0; - List sets = _tagSets; + List<TagSet> sets = _tagSets; _tagSets = new ArrayList(); for (int i = 0; i < sets.size(); i++) { TagSet set = (TagSet) sets.get(i); @@ -642,8 +657,8 @@ class TransientSessionKeyManager extends SessionKeyManager { public long getLastExpirationDate() { long last = 0; synchronized (_tagSets) { - for (Iterator iter = _tagSets.iterator(); iter.hasNext();) { - TagSet set = (TagSet) iter.next(); + for (Iterator<TagSet> iter = _tagSets.iterator(); iter.hasNext();) { + TagSet set = iter.next(); if ( (set.getDate() > last) && (set.getTags().size() > 0) ) last = set.getDate(); } @@ -663,12 +678,12 @@ class TransientSessionKeyManager extends SessionKeyManager { } static class TagSet { - private Set _sessionTags; + private Set<SessionTag> _sessionTags; private SessionKey _key; private long _date; private Exception _createdBy; - public TagSet(Set tags, SessionKey key, long date) { + public TagSet(Set<SessionTag> tags, SessionKey key, long date) { if (key == null) throw new IllegalArgumentException("Missing key"); if (tags == null) throw new IllegalArgumentException("Missing tags"); _sessionTags = tags; @@ -692,7 +707,7 @@ class TransientSessionKeyManager extends SessionKeyManager { } /** tags still available */ - public Set getTags() { + public Set<SessionTag> getTags() { return _sessionTags; } diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index d2fb6f19d9..1e8e905528 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -57,7 +57,7 @@ public class Router { private RouterInfo _routerInfo; private long _started; private boolean _higherVersionSeen; - private SessionKeyPersistenceHelper _sessionKeyPersistenceHelper; + //private SessionKeyPersistenceHelper _sessionKeyPersistenceHelper; private boolean _killVMOnEnd; private boolean _isAlive; private int _gracefulExitCode; @@ -144,7 +144,7 @@ public class Router { _higherVersionSeen = false; _log = _context.logManager().getLog(Router.class); _log.info("New router created with config file " + _configFilename); - _sessionKeyPersistenceHelper = new SessionKeyPersistenceHelper(_context); + //_sessionKeyPersistenceHelper = new SessionKeyPersistenceHelper(_context); _killVMOnEnd = true; _oomListener = new I2PThread.OOMEventListener() { public void outOfMemory(OutOfMemoryError oom) { @@ -261,7 +261,7 @@ public class Router { SimpleScheduler.getInstance().addPeriodicEvent(new CoalesceStatsEvent(_context), 20*1000); _context.jobQueue().addJob(new UpdateRoutingKeyModifierJob(_context)); warmupCrypto(); - _sessionKeyPersistenceHelper.startup(); + //_sessionKeyPersistenceHelper.startup(); //_context.adminManager().startup(); _context.blocklist().startup(); @@ -813,7 +813,7 @@ public class Router { try { _context.messageRegistry().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the message registry", t); } try { _context.messageValidator().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the message validator", t); } try { _context.inNetMessagePool().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the inbound net pool", t); } - try { _sessionKeyPersistenceHelper.shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the session key manager", t); } + //try { _sessionKeyPersistenceHelper.shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the session key manager", t); } RouterContext.listContexts().remove(_context); dumpStats(); finalShutdown(exitCode); diff --git a/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java b/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java deleted file mode 100644 index 57db42bb42..0000000000 --- a/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java +++ /dev/null @@ -1,115 +0,0 @@ -package net.i2p.router; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.Writer; - -import net.i2p.crypto.PersistentSessionKeyManager; -import net.i2p.crypto.SessionKeyManager; -import net.i2p.util.Log; - -/** - * Centralize the sessionKeyManager persistence (rather than leave it to a private - * job in the startup job) - * - */ -public class SessionKeyPersistenceHelper implements Service { - private Log _log; - private RouterContext _context; - private SessionKeyWriterJob _writerJob; - private final static long PERSIST_DELAY = 3*60*1000; - private final static String PROP_SESSION_KEY_FILE = "router.sessionKeys.location"; - private final static String DEFAULT_SESSION_KEY_FILE = "sessionKeys.dat"; - - public SessionKeyPersistenceHelper(RouterContext context) { - _context = context; - _log = _context.logManager().getLog(SessionKeyPersistenceHelper.class); - _writerJob = new SessionKeyWriterJob(); - } - - public void shutdown() { - writeState(); - } - - public void restart() { - writeState(); - startup(); - } - - private String getKeyFile() { - String val = _context.router().getConfigSetting(PROP_SESSION_KEY_FILE); - if (val == null) - val = DEFAULT_SESSION_KEY_FILE; - return val; - } - - public void startup() { - SessionKeyManager mgr = _context.sessionKeyManager(); - if (mgr instanceof PersistentSessionKeyManager) { - PersistentSessionKeyManager manager = (PersistentSessionKeyManager)mgr; - File f = new File(getKeyFile()); - if (f.exists()) { - FileInputStream fin = null; - try { - fin = new FileInputStream(f); - manager.loadState(fin); - int expired = manager.aggressiveExpire(); - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Session keys loaded [not error] with " + expired - + " sets immediately expired"); - } catch (Throwable t) { - _log.error("Error reading in session key data", t); - } finally { - if (fin != null) try { fin.close(); } catch (IOException ioe) {} - } - } - _context.jobQueue().addJob(_writerJob); - } - } - - private void writeState() { - if (true) return; - - Object o = _context.sessionKeyManager(); - if (!(o instanceof PersistentSessionKeyManager)) { - _log.error("Unable to persist the session key state - manager is " + o.getClass().getName()); - return; - } - PersistentSessionKeyManager mgr = (PersistentSessionKeyManager)o; - - // only need for synchronization is during shutdown() - synchronized (mgr) { - FileOutputStream fos = null; - try { - int expired = mgr.aggressiveExpire(); - if (expired > 0) { - _log.info("Agressive expired " + expired + " tag sets"); - } - fos = new FileOutputStream(getKeyFile()); - mgr.saveState(fos); - fos.flush(); - _log.debug("Session keys written"); - } catch (Throwable t) { - _log.debug("Error writing session key state", t); - } finally { - if (fos != null) try { fos.close(); } catch (IOException ioe) {} - } - } - } - - public void renderStatusHTML(Writer out) { } - - private class SessionKeyWriterJob extends JobImpl { - public SessionKeyWriterJob() { - super(SessionKeyPersistenceHelper.this._context); - getTiming().setStartAfter(PERSIST_DELAY); - } - public String getName() { return "Write Session Keys"; } - public void runJob() { - writeState(); - requeue(PERSIST_DELAY); - } - } -} -- GitLab