diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/InternalSocketRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/InternalSocketRunner.java index 76a8cea7c..68bcf8261 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/InternalSocketRunner.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/InternalSocketRunner.java @@ -43,8 +43,8 @@ class InternalSocketRunner extends I2PAppThread { if (this.open) { Log log = new Log(InternalSocketRunner.class); log.error("Error listening for internal connections on port " + this.port, ex); + stopRunning(); } - this.open = false; } } diff --git a/apps/routerconsole/jsp/debug.jsp b/apps/routerconsole/jsp/debug.jsp index f420c16ea..04e73e972 100644 --- a/apps/routerconsole/jsp/debug.jsp +++ b/apps/routerconsole/jsp/debug.jsp @@ -35,6 +35,11 @@ */ ctx.portMapper().renderStatusHTML(out); + /* + * Print out the status for the InternalServerSockets + */ + net.i2p.util.InternalServerSocket.renderStatusHTML(out); + /* * Print out the status for the AppManager */ diff --git a/core/java/src/net/i2p/util/InternalServerSocket.java b/core/java/src/net/i2p/util/InternalServerSocket.java index fb7dfdbaa..aa8b94d43 100644 --- a/core/java/src/net/i2p/util/InternalServerSocket.java +++ b/core/java/src/net/i2p/util/InternalServerSocket.java @@ -1,13 +1,18 @@ package net.i2p.util; import java.io.IOException; +import java.io.InterruptedIOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; +import java.io.Writer; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import java.nio.channels.ServerSocketChannel; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; @@ -68,7 +73,9 @@ public class InternalServerSocket extends ServerSocket { try { serverSock = _acceptQueue.take(); } catch (InterruptedException ie) { - continue; + if (_running) + throw new InterruptedIOException(); + throw new IOException("closed"); } if (serverSock.getInputStream() == null) // poison throw new IOException("closed"); @@ -128,7 +135,8 @@ public class InternalServerSocket extends ServerSocket { return 0; } - // everything below here unsupported + // most below here unsupported + /** @deprecated unsupported */ @Deprecated @Override @@ -141,12 +149,15 @@ public class InternalServerSocket extends ServerSocket { public void bind(SocketAddress endpoint, int backlog) { throw new IllegalArgumentException("unsupported"); } - /** @deprecated unsupported */ - @Deprecated + + /** + * Returns null as of 0.9.33, prior to that threw IllegalArgumentException + */ @Override public ServerSocketChannel getChannel() { - throw new IllegalArgumentException("unsupported"); + return null; } + /** @deprecated unsupported */ @Deprecated @Override @@ -171,18 +182,23 @@ public class InternalServerSocket extends ServerSocket { public boolean getReuseAddress() { throw new IllegalArgumentException("unsupported"); } - /** @deprecated unsupported */ - @Deprecated + + /** + * Returns true as of 0.9.33, prior to that threw IllegalArgumentException + */ @Override public boolean isBound() { - throw new IllegalArgumentException("unsupported"); + return true; } - /** @deprecated unsupported */ - @Deprecated + + /** + * Supported as of 0.9.33, prior to that threw IllegalArgumentException + */ @Override public boolean isClosed() { - throw new IllegalArgumentException("unsupported"); + return !_running; } + /** @deprecated unsupported */ @Deprecated @Override @@ -195,4 +211,18 @@ public class InternalServerSocket extends ServerSocket { public void setReuseAddress(boolean on) { throw new IllegalArgumentException("unsupported"); } + + /** + * For debugging only + * @since 0.9.33 + */ + public static void renderStatusHTML(Writer out) throws IOException { + out.write("

Internal Server Sockets

Port\n"); + List ports = new ArrayList(_sockets.keySet()); + Collections.sort(ports); + for (Integer i : ports) { + out.write("
" + i + '\n'); + } + out.write("
\n"); + } } diff --git a/core/java/src/net/i2p/util/InternalSocket.java b/core/java/src/net/i2p/util/InternalSocket.java index f7194b03b..dd84e3102 100644 --- a/core/java/src/net/i2p/util/InternalSocket.java +++ b/core/java/src/net/i2p/util/InternalSocket.java @@ -244,18 +244,22 @@ public class InternalSocket extends Socket { return _is != null || _os != null; } - /** @deprecated unsupported */ - @Deprecated + /** + * Supported as of 0.9.33, prior to that threw UnsupportedOperationException + */ @Override - public boolean isInputShutdown() { - throw new UnsupportedOperationException(); + public synchronized boolean isInputShutdown() { + return _is == null; } - /** @deprecated unsupported */ - @Deprecated + + /** + * Supported as of 0.9.33, prior to that threw UnsupportedOperationException + */ @Override - public boolean isOutputShutdown() { - throw new UnsupportedOperationException(); + public synchronized boolean isOutputShutdown() { + return _os == null; } + /** @deprecated unsupported */ @Deprecated @Override @@ -310,16 +314,38 @@ public class InternalSocket extends Socket { public void setTrafficClass(int cize) { throw new UnsupportedOperationException(); } - /** @deprecated unsupported */ - @Deprecated + + /** + * Supported as of 0.9.33, prior to that threw UnsupportedOperationException + */ @Override - public void shutdownInput() { - throw new UnsupportedOperationException(); + public synchronized void shutdownInput() throws IOException { + if (_is != null) { + _is.close(); + _is = null; + } } - /** @deprecated unsupported */ - @Deprecated + + /** + * Flushes (as the Socket javadocs advise) and closes. + * Supported as of 0.9.33, prior to that threw UnsupportedOperationException + */ @Override - public void shutdownOutput() { - throw new UnsupportedOperationException(); + public void shutdownOutput() throws IOException { + OutputStream out; + synchronized(this) { + out = _os; + } + if (out == null) + return; + // PipedOutputStream may not flush on close, not clear from javadocs + try { + out.flush(); + out.close(); + } finally { + synchronized(this) { + _os = null; + } + } } }