diff --git a/history.txt b/history.txt index e9c588461b..20ba7b1649 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,8 @@ +2018-09-22 zzz + * NTCP: + - Fix handling of multiple connections + - Change termination code for expired RI + 2018-09-16 zzz * Build: Fix hang with Tomcat 8.5.33+ (ticket #2307) * Tomcat 8.5.34 diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index f6e6df3a5c..ba403a9f3e 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,10 +18,10 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 4; + public final static long BUILD = 5; /** for example "-test" */ - public final static String EXTRA = ""; + public final static String EXTRA = "-rc"; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; public static void main(String args[]) { System.out.println("I2P Router version: " + FULL_VERSION); diff --git a/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java index eea0071968..38066761e0 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java @@ -1002,8 +1002,9 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa } } catch (IllegalArgumentException iae) { // hash collision? - _msg3p2FailReason = NTCPConnection.REASON_UNSPEC; - throw new DataFormatException("RI store fail", iae); + // expired RI? + _msg3p2FailReason = NTCPConnection.REASON_MSG3; + throw new DataFormatException("RI store fail: " + ri, iae); } _con.setRemotePeer(_aliceIdent); } 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 aa66d552d5..de32aace41 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java @@ -488,6 +488,7 @@ public class NTCPConnection implements Closeable { } NTCPConnection toClose = locked_close(allowRequeue); if (toClose != null && toClose != this) { + // won't happen as of 0.9.37 if (_log.shouldLog(Log.WARN)) _log.warn("Multiple connections on remove, closing " + toClose + " (already closed " + this + ")"); _context.statManager().addRateData("ntcp.multipleCloseOnRemove", toClose.getUptime()); @@ -507,7 +508,8 @@ public class NTCPConnection implements Closeable { } /** - * @return a second connection with the same peer... + * @return usually this, but could be a second connection with the same peer... + * only this or null as of 0.9.37 */ private synchronized NTCPConnection locked_close(boolean allowRequeue) { if (_chan != null) try { _chan.close(); } catch (IOException ioe) { } @@ -1834,9 +1836,9 @@ public class NTCPConnection implements Closeable { _paddingConfig = OUR_PADDING; } NTCPConnection toClose = _transport.inboundEstablished(this); - if (toClose != null) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Old connection closed: " + toClose + " replaced by " + this); + if (toClose != null && toClose != this) { + if (_log.shouldWarn()) + _log.warn("Old connection closed: " + toClose + " replaced by " + this); _context.statManager().addRateData("ntcp.inboundEstablishedDuplicate", toClose.getUptime()); toClose.close(); } @@ -2107,7 +2109,7 @@ public class NTCPConnection implements Closeable { } } } catch (IllegalArgumentException iae) { - throw new DataFormatException("RI store fail", iae); + throw new DataFormatException("RI store fail: " + ri, iae); } } 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 29523181dd..e19d89645e 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -73,7 +73,7 @@ public class NTCPTransport extends TransportImpl { private final SharedBid _nearCapacityCostBid; private final SharedBid _transientFail; private final Object _conLock; - private final Map _conByIdent; + private final ConcurrentHashMap _conByIdent; private final EventPumper _pumper; private final Reader _reader; private net.i2p.router.transport.ntcp.Writer _writer; @@ -641,13 +641,17 @@ public class NTCPTransport extends TransportImpl { /** * @return usually the con passed in, but possibly a second connection with the same peer... + * only con or null as of 0.9.37 */ NTCPConnection removeCon(NTCPConnection con) { NTCPConnection removed = null; RouterIdentity ident = con.getRemotePeer(); if (ident != null) { synchronized (_conLock) { - removed = _conByIdent.remove(ident.calculateHash()); + // only remove the con passed in + //removed = _conByIdent.remove(ident.calculateHash()); + if (_conByIdent.remove(ident.calculateHash(), con)) + removed = con; } } return removed;