diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java index 87dd7e937..5da192609 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java @@ -210,13 +210,13 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable { _log.error("Error connecting to IRC server " + remoteHost + ':' + remotePort, ex); } catch (IOException ex) { try { - socket.close(); + socket.reset(); } catch (IOException ioe) {} if (_log.shouldLog(Log.WARN)) _log.warn("Error while receiving the new IRC Connection", ex); } catch (OutOfMemoryError oom) { try { - socket.close(); + socket.reset(); } catch (IOException ioe) {} if (_log.shouldLog(Log.ERROR)) _log.error("OOM in IRC server", oom); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java index 4d49a2516..bd5df915a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java @@ -680,7 +680,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { " [" + timeToHandle + ", socket create: " + (afterSocket-afterAccept) + "]"); } catch (SocketException ex) { try { - socket.close(); + socket.reset(); } catch (IOException ioe) {} if (_log.shouldLog(Log.ERROR)) _log.error("Error connecting to server " + remoteHost + ':' + remotePort, ex); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCServer.java index 8010a110f..8b49b6995 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCServer.java @@ -119,7 +119,7 @@ public class I2PTunnelDCCServer extends I2PTunnelServer { _active.put(Integer.valueOf(myPort), local); } catch (SocketException ex) { try { - socket.close(); + socket.reset(); } catch (IOException ioe) {} _log.error("Error relaying incoming DCC connection to IRC client at " + local.ia + ':' + local.port, ex); } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SocketWrapper.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SocketWrapper.java index e6b3b15f6..6e4ecc565 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SocketWrapper.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SocketWrapper.java @@ -87,6 +87,14 @@ class SocketWrapper implements I2PSocket { socket.close(); } + /** + * Just calls close() + * @since 0.9.30 + */ + public void reset() throws IOException { + close(); + } + public boolean isClosed() { return socket.isClosed(); } diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java index 7c7c0b19c..d38afc689 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java @@ -112,6 +112,20 @@ public interface I2PSocket extends Closeable { * @since 0.8.9 */ public int getLocalPort(); + + /** + * Resets and closes this socket. Sends a RESET indication to the far-end. + * This is the equivalent of setSoLinger(true, 0) followed by close() on a Java Socket. + * + * Nonblocking. + * Any thread currently blocked in an I/O operation upon this socket will throw an IOException. + * Once a socket has been reset, it is not available for further networking use + * (i.e. can't be reconnected or rebound). A new socket needs to be created. + * Resetting this socket will also close the socket's InputStream and OutputStream. + * + * @since 0.9.30 + */ + public void reset() throws IOException; /** * Deprecated, unimplemented, does nothing. Original description: diff --git a/apps/sam/java/src/net/i2p/sam/MasterSession.java b/apps/sam/java/src/net/i2p/sam/MasterSession.java index fc69a7238..19d102951 100644 --- a/apps/sam/java/src/net/i2p/sam/MasterSession.java +++ b/apps/sam/java/src/net/i2p/sam/MasterSession.java @@ -389,7 +389,7 @@ class MasterSession extends SAMv3StreamSession implements SAMDatagramReceiver, S boolean ok = ssess.queueSocket(i2ps); if (!ok) { _log.logAlways(Log.WARN, "Accept queue overflow for " + ssess); - try { i2ps.close(); } catch (IOException ioe) {} + try { i2ps.reset(); } catch (IOException ioe) {} } } else { if (_log.shouldLog(Log.WARN)) diff --git a/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java b/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java index 8cc9b5662..3d6708e05 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java @@ -564,7 +564,7 @@ class SAMStreamSession implements SAMMessageSess { int id = createSocketHandler(i2ps, 0); if (id == 0) { _log.error("SAM STREAM session handler not created!"); - i2ps.close(); + i2ps.reset(); continue; } diff --git a/apps/sam/java/src/net/i2p/sam/SAMv3StreamSession.java b/apps/sam/java/src/net/i2p/sam/SAMv3StreamSession.java index 8be28b475..40f3b95df 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv3StreamSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv3StreamSession.java @@ -383,7 +383,7 @@ class SAMv3StreamSession extends SAMStreamSession implements Session Log log = ctx.logManager().getLog(SAMv3StreamSession.class); log.error("SSL error", gse); try { - i2ps.close(); + i2ps.reset(); } catch (IOException ee) {} throw new RuntimeException("SSL error", gse); } @@ -401,7 +401,7 @@ class SAMv3StreamSession extends SAMStreamSession implements Session if (log.shouldLog(Log.WARN)) log.warn("Error forwarding", ioe); try { - i2ps.close(); + i2ps.reset(); } catch (IOException ee) {} continue; } @@ -433,7 +433,7 @@ class SAMv3StreamSession extends SAMStreamSession implements Session clientServerSock.close(); } catch (IOException ee) {} try { - i2ps.close(); + i2ps.reset(); } catch (IOException ee) {} continue ; } diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketFull.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketFull.java index 6800e8a6e..f86a1979d 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketFull.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketFull.java @@ -67,6 +67,32 @@ class I2PSocketFull implements I2PSocket { destroy(); } + /** + * Resets and closes this socket. Sends a RESET indication to the far-end. + * This is the equivalent of setSoLinger(true, 0) followed by close() on a Java Socket. + * + * Nonblocking. + * Any thread currently blocked in an I/O operation upon this socket will throw an IOException. + * Once a socket has been reset, it is not available for further networking use + * (i.e. can't be reconnected or rebound). A new socket needs to be created. + * Resetting this socket will also close the socket's InputStream and OutputStream. + * + * @since 0.9.30 + */ + public void reset() throws IOException { + Connection c = _connection; + if (c == null) return; + if (log.shouldLog(Log.INFO)) + log.info("reset() called, connected? " + c.getIsConnected() + " : " + c, new Exception()); + if (c.getIsConnected()) { + c.disconnect(false); + // this will cause any thread waiting in Connection.packetSendChoke() + // to throw an IOE + c.windowAdjusted(); + } + destroy(); + } + Connection getConnection() { return _connection; } /** diff --git a/history.txt b/history.txt index 15d4b0e2b..b3d910896 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,10 @@ +2017-03-13 zzz + * i2ptunnel: + - Add subsession support to servers + - Reset I2P socket on TCP socket errors + * SAM: Reset I2P socket on handler errors + * Streaming: Add reset() to I2PSocket API + 2017-03-11 zzz Prop from i2p.i2p.zzz.jetty9: * Console: Fix RouterConsoleRunner for Jetty 9 diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index f6e6df3a5..4e28a2c8d 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ 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 = "";