Streaming: Add reset() to I2PSocket API

i2ptunnel: Reset I2P socket on TCP socket errors, in standard servers
that don't have protocol responses
SAM: Reset I2P socket on handler errors
This commit is contained in:
zzz
2017-03-13 14:09:27 +00:00
parent ad810de747
commit e7cfb2d6fe
11 changed files with 65 additions and 10 deletions

View File

@@ -210,13 +210,13 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
_log.error("Error connecting to IRC server " + remoteHost + ':' + remotePort, ex); _log.error("Error connecting to IRC server " + remoteHost + ':' + remotePort, ex);
} catch (IOException ex) { } catch (IOException ex) {
try { try {
socket.close(); socket.reset();
} catch (IOException ioe) {} } catch (IOException ioe) {}
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Error while receiving the new IRC Connection", ex); _log.warn("Error while receiving the new IRC Connection", ex);
} catch (OutOfMemoryError oom) { } catch (OutOfMemoryError oom) {
try { try {
socket.close(); socket.reset();
} catch (IOException ioe) {} } catch (IOException ioe) {}
if (_log.shouldLog(Log.ERROR)) if (_log.shouldLog(Log.ERROR))
_log.error("OOM in IRC server", oom); _log.error("OOM in IRC server", oom);

View File

@@ -680,7 +680,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
" [" + timeToHandle + ", socket create: " + (afterSocket-afterAccept) + "]"); " [" + timeToHandle + ", socket create: " + (afterSocket-afterAccept) + "]");
} catch (SocketException ex) { } catch (SocketException ex) {
try { try {
socket.close(); socket.reset();
} catch (IOException ioe) {} } catch (IOException ioe) {}
if (_log.shouldLog(Log.ERROR)) if (_log.shouldLog(Log.ERROR))
_log.error("Error connecting to server " + remoteHost + ':' + remotePort, ex); _log.error("Error connecting to server " + remoteHost + ':' + remotePort, ex);

View File

@@ -119,7 +119,7 @@ public class I2PTunnelDCCServer extends I2PTunnelServer {
_active.put(Integer.valueOf(myPort), local); _active.put(Integer.valueOf(myPort), local);
} catch (SocketException ex) { } catch (SocketException ex) {
try { try {
socket.close(); socket.reset();
} catch (IOException ioe) {} } catch (IOException ioe) {}
_log.error("Error relaying incoming DCC connection to IRC client at " + local.ia + ':' + local.port, ex); _log.error("Error relaying incoming DCC connection to IRC client at " + local.ia + ':' + local.port, ex);
} }

View File

@@ -87,6 +87,14 @@ class SocketWrapper implements I2PSocket {
socket.close(); socket.close();
} }
/**
* Just calls close()
* @since 0.9.30
*/
public void reset() throws IOException {
close();
}
public boolean isClosed() { public boolean isClosed() {
return socket.isClosed(); return socket.isClosed();
} }

View File

@@ -113,6 +113,20 @@ public interface I2PSocket extends Closeable {
*/ */
public int getLocalPort(); 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: * Deprecated, unimplemented, does nothing. Original description:
* *

View File

@@ -389,7 +389,7 @@ class MasterSession extends SAMv3StreamSession implements SAMDatagramReceiver, S
boolean ok = ssess.queueSocket(i2ps); boolean ok = ssess.queueSocket(i2ps);
if (!ok) { if (!ok) {
_log.logAlways(Log.WARN, "Accept queue overflow for " + ssess); _log.logAlways(Log.WARN, "Accept queue overflow for " + ssess);
try { i2ps.close(); } catch (IOException ioe) {} try { i2ps.reset(); } catch (IOException ioe) {}
} }
} else { } else {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))

View File

@@ -564,7 +564,7 @@ class SAMStreamSession implements SAMMessageSess {
int id = createSocketHandler(i2ps, 0); int id = createSocketHandler(i2ps, 0);
if (id == 0) { if (id == 0) {
_log.error("SAM STREAM session handler not created!"); _log.error("SAM STREAM session handler not created!");
i2ps.close(); i2ps.reset();
continue; continue;
} }

View File

@@ -383,7 +383,7 @@ class SAMv3StreamSession extends SAMStreamSession implements Session
Log log = ctx.logManager().getLog(SAMv3StreamSession.class); Log log = ctx.logManager().getLog(SAMv3StreamSession.class);
log.error("SSL error", gse); log.error("SSL error", gse);
try { try {
i2ps.close(); i2ps.reset();
} catch (IOException ee) {} } catch (IOException ee) {}
throw new RuntimeException("SSL error", gse); throw new RuntimeException("SSL error", gse);
} }
@@ -401,7 +401,7 @@ class SAMv3StreamSession extends SAMStreamSession implements Session
if (log.shouldLog(Log.WARN)) if (log.shouldLog(Log.WARN))
log.warn("Error forwarding", ioe); log.warn("Error forwarding", ioe);
try { try {
i2ps.close(); i2ps.reset();
} catch (IOException ee) {} } catch (IOException ee) {}
continue; continue;
} }
@@ -433,7 +433,7 @@ class SAMv3StreamSession extends SAMStreamSession implements Session
clientServerSock.close(); clientServerSock.close();
} catch (IOException ee) {} } catch (IOException ee) {}
try { try {
i2ps.close(); i2ps.reset();
} catch (IOException ee) {} } catch (IOException ee) {}
continue ; continue ;
} }

View File

@@ -67,6 +67,32 @@ class I2PSocketFull implements I2PSocket {
destroy(); 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; } Connection getConnection() { return _connection; }
/** /**

View File

@@ -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 2017-03-11 zzz
Prop from i2p.i2p.zzz.jetty9: Prop from i2p.i2p.zzz.jetty9:
* Console: Fix RouterConsoleRunner for Jetty 9 * Console: Fix RouterConsoleRunner for Jetty 9

View File

@@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 4; public final static long BUILD = 5;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";