From 082922de01b0ae5cc33320fd38410fbc4629a4d0 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Thu, 18 Sep 2014 13:32:27 +0000 Subject: [PATCH] NTCP: Return unused DH keypairs to the pool --- .../router/transport/ntcp/EstablishState.java | 54 ++++++++++++++++--- .../router/transport/ntcp/EventPumper.java | 4 +- .../router/transport/ntcp/NTCPConnection.java | 13 ++++- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java b/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java index a82782560e..facf890f9e 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java +++ b/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java @@ -64,6 +64,7 @@ import net.i2p.util.SimpleByteCache; class EstablishState { public static final VerifiedEstablishState VERIFIED = new VerifiedEstablishState(); + public static final FailedEstablishState FAILED = new FailedEstablishState(); private final RouterContext _context; private final Log _log; @@ -120,7 +121,7 @@ class EstablishState { private static final int HXY_SIZE = 32; //Hash.HASH_LENGTH; private static final int HXY_TSB_PAD_SIZE = HXY_SIZE + 4 + 12; // 48 - private State _state; + protected State _state; private enum State { OB_INIT, @@ -163,7 +164,6 @@ class EstablishState { _transport = null; _con = null; _e_hXY_tsB = null; - _state = State.VERIFIED; } public EstablishState(RouterContext ctx, NTCPTransport transport, NTCPConnection con) { @@ -900,6 +900,15 @@ class EstablishState { */ public synchronized byte[] getExtraBytes() { return _extra; } + /** + * Release resources on timeout. + * @param e may be null + * @since 0.9.16 + */ + public synchronized void close(String reason, Exception e) { + fail(reason, e); + } + /** Caller must synch. */ private void fail(String reason) { fail(reason, null); } @@ -919,7 +928,10 @@ class EstablishState { releaseBufs(); } - /** Only call once. Caller must synch. */ + /** + * Only call once. Caller must synch. + * @since 0.9.16 + */ private void releaseBufs() { // null or longer for OB if (_prevEncrypted != null && _prevEncrypted.length == AES_SIZE) @@ -927,8 +939,12 @@ class EstablishState { SimpleByteCache.release(_curEncrypted); SimpleByteCache.release(_curDecrypted); SimpleByteCache.release(_hX_xor_bobIdentHash); - SimpleByteCache.release(_X); - SimpleByteCache.release(_Y); + if (_dh.getPeerPublicValue() == null) + _transport.returnUnused(_dh); + if (_con.isInbound()) + SimpleByteCache.release(_X); + else + SimpleByteCache.release(_Y); } public synchronized String getError() { return _err; } @@ -1024,12 +1040,36 @@ class EstablishState { * @since 0.9.8 */ private static class VerifiedEstablishState extends EstablishState { - @Override public boolean isComplete() { return true; } + + public VerifiedEstablishState() { + super(); + _state = State.VERIFIED; + } + + @Override public void prepareOutbound() { + Log log =RouterContext.getCurrentContext().logManager().getLog(VerifiedEstablishState.class); + log.warn("prepareOutbound() on verified state, doing nothing!"); + } + + @Override public String toString() { return "VerifiedEstablishState";} + } + + /** + * @since 0.9.16 + */ + private static class FailedEstablishState extends EstablishState { + + public FailedEstablishState() { + super(); + _state = State.CORRUPT; + } + @Override public void prepareOutbound() { Log log =RouterContext.getCurrentContext().logManager().getLog(VerifiedEstablishState.class); log.warn("prepareOutbound() on verified state, doing nothing!"); } - @Override public String toString() { return "VerfiedEstablishState";} + + @Override public String toString() { return "FailedEstablishState";} } /** @deprecated unused */ diff --git a/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java b/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java index 607234ae70..b6f539c962 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java +++ b/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java @@ -532,14 +532,14 @@ class EventPumper implements Runnable { con.outboundConnected(); _context.statManager().addRateData("ntcp.connectSuccessful", 1); } else { - con.close(); + con.closeOnTimeout("connect failed", null); _transport.markUnreachable(con.getRemotePeer().calculateHash()); _context.statManager().addRateData("ntcp.connectFailedTimeout", 1); } } catch (IOException ioe) { // this is the usual failure path for a timeout or connect refused if (_log.shouldLog(Log.INFO)) _log.info("Failed outbound " + con, ioe); - con.close(); + con.closeOnTimeout("connect failed", ioe); //_context.banlist().banlistRouter(con.getRemotePeer().calculateHash(), "Error connecting", NTCPTransport.STYLE); _transport.markUnreachable(con.getRemotePeer().calculateHash()); _context.statManager().addRateData("ntcp.connectFailedTimeoutIOE", 1); diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java index acd5570e38..0e6ad83234 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java @@ -371,10 +371,21 @@ class NTCPConnection { } } + /** + * Close and release EstablishState resources. + * @param e may be null + * @since 0.9.16 + */ + public void closeOnTimeout(String cause, Exception e) { + EstablishState es = _establishState; + close(); + es.close(cause, e); + } + private synchronized NTCPConnection locked_close(boolean allowRequeue) { if (_chan != null) try { _chan.close(); } catch (IOException ioe) { } if (_conKey != null) _conKey.cancel(); - _establishState = EstablishState.VERIFIED; + _establishState = EstablishState.FAILED; NTCPConnection old = _transport.removeCon(this); _transport.getReader().connectionClosed(this); _transport.getWriter().connectionClosed(this); -- GitLab