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 ff61536455546f81d4b6abae35bec1b211bdef21..cb0646cf9bfd395865f5431dbad4c3285b52e79a 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java @@ -263,7 +263,18 @@ class NTCPConnection { * @param clockSkew alice's clock minus bob's clock in seconds (may be negative, obviously, but |val| should * be under 1 minute) */ - public synchronized void finishInboundEstablishment(SessionKey key, long clockSkew, byte prevWriteEnd[], byte prevReadEnd[]) { + public void finishInboundEstablishment(SessionKey key, long clockSkew, byte prevWriteEnd[], byte prevReadEnd[]) { + NTCPConnection toClose = locked_finishInboundEstablishment(key, clockSkew, prevWriteEnd, prevReadEnd); + if (toClose != null) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Old connection closed: " + toClose + " replaced by " + this); + _context.statManager().addRateData("ntcp.inboundEstablishedDuplicate", toClose.getUptime()); + toClose.close(); + } + } + + private synchronized NTCPConnection locked_finishInboundEstablishment( + SessionKey key, long clockSkew, byte prevWriteEnd[], byte prevReadEnd[]) { _sessionKey = key; _clockSkew = clockSkew; _prevWriteEnd = prevWriteEnd; @@ -271,10 +282,11 @@ class NTCPConnection { //if (_log.shouldLog(Log.DEBUG)) // _log.debug("Inbound established, prevWriteEnd: " + Base64.encode(prevWriteEnd) + " prevReadEnd: " + Base64.encode(prevReadEnd)); _establishedOn = System.currentTimeMillis(); - _transport.inboundEstablished(this); + NTCPConnection rv = _transport.inboundEstablished(this); _nextMetaTime = System.currentTimeMillis() + (META_FREQUENCY / 2) + _context.random().nextInt(META_FREQUENCY); _nextInfoTime = System.currentTimeMillis() + (INFO_FREQUENCY / 2) + _context.random().nextInt(INFO_FREQUENCY); _establishState = EstablishState.VERIFIED; + return rv; } /** @return seconds */ @@ -327,14 +339,24 @@ class NTCPConnection { public void close() { close(false); } - public synchronized void close(boolean allowRequeue) { + public void close(boolean allowRequeue) { + NTCPConnection toClose = locked_close(allowRequeue); + if (toClose != null && toClose != this) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Multiple connections on remove, closing " + toClose + " (already closed " + this + ")"); + _context.statManager().addRateData("ntcp.multipleCloseOnRemove", toClose.getUptime()); + toClose.close(); + } + } + + private synchronized NTCPConnection locked_close(boolean allowRequeue) { if (_log.shouldLog(Log.INFO)) _log.info("Closing connection " + toString(), new Exception("cause")); _closed = true; if (_chan != null) try { _chan.close(); } catch (IOException ioe) { } if (_conKey != null) _conKey.cancel(); _establishState = EstablishState.VERIFIED; - _transport.removeCon(this); + NTCPConnection old = _transport.removeCon(this); _transport.getReader().connectionClosed(this); _transport.getWriter().connectionClosed(this); @@ -372,6 +394,8 @@ class NTCPConnection { releaseBuf((PrepBuffer)buf); _transport.afterSend(msg, false, allowRequeue, msg.getLifetime()); } + + return old; } /** 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 1a8c9c35d98d723b42d7c2ac58996080db20fdee..8906166ec7fca8dc7266c096211263e82d073f20 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -189,7 +189,11 @@ public class NTCPTransport extends TransportImpl { _transientFail = new SharedBid(TransportBid.TRANSIENT_FAIL); } - void inboundEstablished(NTCPConnection con) { + /** + * @param con that is established + * @return the previous connection to the same peer, null if no such. + */ + NTCPConnection inboundEstablished(NTCPConnection con) { _context.statManager().addRateData("ntcp.inboundEstablished", 1); markReachable(con.getRemotePeer().calculateHash(), true); //_context.banlist().unbanlistRouter(con.getRemotePeer().calculateHash()); @@ -197,12 +201,7 @@ public class NTCPTransport extends TransportImpl { synchronized (_conLock) { old = _conByIdent.put(con.getRemotePeer().calculateHash(), con); } - if (old != null) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Old connection closed: " + old + " replaced by " + con); - _context.statManager().addRateData("ntcp.inboundEstablishedDuplicate", old.getUptime()); - old.close(); - } + return old; } protected void outboundMessageReady() { @@ -431,7 +430,7 @@ public class NTCPTransport extends TransportImpl { return (con != null) && con.isEstablished() && con.tooBacklogged(); } - void removeCon(NTCPConnection con) { + NTCPConnection removeCon(NTCPConnection con) { NTCPConnection removed = null; RouterIdentity ident = con.getRemotePeer(); if (ident != null) { @@ -439,12 +438,7 @@ public class NTCPTransport extends TransportImpl { removed = _conByIdent.remove(ident.calculateHash()); } } - if ( (removed != null) && (removed != con) ) {// multiple cons, close 'em both - if (_log.shouldLog(Log.WARN)) - _log.warn("Multiple connections on remove, closing " + removed + " (already closed " + con + ")"); - _context.statManager().addRateData("ntcp.multipleCloseOnRemove", removed.getUptime()); - removed.close(); - } + return removed; } /**