diff --git a/router/java/src/net/i2p/router/transport/crypto/DHSessionKeyBuilder.java b/router/java/src/net/i2p/router/transport/crypto/DHSessionKeyBuilder.java index 0d49a656aa01af69a95c9b27804e836461008e3a..e1368d83c93c58b02c99de92bcd3514e179f4830 100644 --- a/router/java/src/net/i2p/router/transport/crypto/DHSessionKeyBuilder.java +++ b/router/java/src/net/i2p/router/transport/crypto/DHSessionKeyBuilder.java @@ -436,6 +436,15 @@ public class DHSessionKeyBuilder { * or pulls a prebuilt one from the queue. */ public DHSessionKeyBuilder getBuilder(); + + /** + * Return an unused DH key builder + * to be put back onto the queue for reuse. + * + * @param builder must not have a peerPublicValue set + * @since 0.9.16 + */ + public void returnUnused(DHSessionKeyBuilder builder); } public static class PrecalcRunner extends I2PThread implements Factory { @@ -457,6 +466,7 @@ public class DHSessionKeyBuilder { ctx.statManager().createRateStat("crypto.dhGeneratePublicTime", "How long it takes to create x and X", "Encryption", new long[] { 60*60*1000 }); //ctx.statManager().createRateStat("crypto.dhCalculateSessionTime", "How long it takes to create the session key", "Encryption", new long[] { 60*60*1000 }); ctx.statManager().createRateStat("crypto.DHUsed", "Need a DH from the queue", "Encryption", new long[] { 60*60*1000 }); + ctx.statManager().createRateStat("crypto.DHReused", "Unused DH requeued", "Encryption", new long[] { 60*60*1000 }); ctx.statManager().createRateStat("crypto.DHEmpty", "DH queue empty", "Encryption", new long[] { 60*60*1000 }); // add to the defaults for every 128MB of RAM, up to 512MB @@ -536,11 +546,11 @@ public class DHSessionKeyBuilder { * @since 0.9 moved from DHSKB */ public DHSessionKeyBuilder getBuilder() { - _context.statManager().addRateData("crypto.DHUsed", 1, 0); + _context.statManager().addRateData("crypto.DHUsed", 1); DHSessionKeyBuilder builder = _builders.poll(); if (builder == null) { if (_log.shouldLog(Log.INFO)) _log.info("No more builders, creating one now"); - _context.statManager().addRateData("crypto.DHEmpty", 1, 0); + _context.statManager().addRateData("crypto.DHEmpty", 1); builder = precalc(); } return builder; @@ -551,7 +561,7 @@ public class DHSessionKeyBuilder { DHSessionKeyBuilder builder = new DHSessionKeyBuilder(_context); long end = System.currentTimeMillis(); long diff = end - start; - _context.statManager().addRateData("crypto.dhGeneratePublicTime", diff, diff); + _context.statManager().addRateData("crypto.dhGeneratePublicTime", diff); if (diff > 1000) { if (_log.shouldLog(Log.WARN)) _log.warn("Took more than a second (" + diff + "ms) to generate local DH value"); @@ -561,6 +571,23 @@ public class DHSessionKeyBuilder { return builder; } + /** + * Return an unused DH key builder + * to be put back onto the queue for reuse. + * + * @param builder must not have a peerPublicValue set + * @since 0.9.16 + */ + public void returnUnused(DHSessionKeyBuilder builder) { + if (builder.getPeerPublicValue() != null) { + if (_log.shouldLog(Log.WARN)) + _log.warn("builder returned used"); + return; + } + _context.statManager().addRateData("crypto.DHReused", 1); + _builders.offer(builder); + } + /** @return true if successful, false if full */ private final boolean addBuilder(DHSessionKeyBuilder builder) { return _builders.offer(builder); diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index c7e4703a4d409c286f2799c9f9b08e691f245fcb..f1269c772f09707b5732c1f2c914653ab6484163 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -775,6 +775,17 @@ public class NTCPTransport extends TransportImpl { return _dhFactory.getBuilder(); } + /** + * Return an unused DH key builder + * to be put back onto the queue for reuse. + * + * @param builder must not have a peerPublicValue set + * @since 0.9.16 + */ + void returnUnused(DHSessionKeyBuilder builder) { + _dhFactory.returnUnused(builder); + } + /** * how long from initial connection attempt (accept() or connect()) until * the con must be established to avoid premature close()ing