InternalSocket: Implement more methods, add debug output, don't ignore interrupt on accept()

Close socket on InternalSocketRunner exception
This commit is contained in:
zzz
2017-12-13 16:06:13 +00:00
parent bd341d4be3
commit 5f413efc08
4 changed files with 89 additions and 28 deletions

View File

@ -43,8 +43,8 @@ class InternalSocketRunner extends I2PAppThread {
if (this.open) { if (this.open) {
Log log = new Log(InternalSocketRunner.class); Log log = new Log(InternalSocketRunner.class);
log.error("Error listening for internal connections on port " + this.port, ex); log.error("Error listening for internal connections on port " + this.port, ex);
stopRunning();
} }
this.open = false;
} }
} }

View File

@ -35,6 +35,11 @@
*/ */
ctx.portMapper().renderStatusHTML(out); ctx.portMapper().renderStatusHTML(out);
/*
* Print out the status for the InternalServerSockets
*/
net.i2p.util.InternalServerSocket.renderStatusHTML(out);
/* /*
* Print out the status for the AppManager * Print out the status for the AppManager
*/ */

View File

@ -1,13 +1,18 @@
package net.i2p.util; package net.i2p.util;
import java.io.IOException; import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.PipedInputStream; import java.io.PipedInputStream;
import java.io.PipedOutputStream; import java.io.PipedOutputStream;
import java.io.Writer;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.nio.channels.ServerSocketChannel; 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.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
@ -68,7 +73,9 @@ public class InternalServerSocket extends ServerSocket {
try { try {
serverSock = _acceptQueue.take(); serverSock = _acceptQueue.take();
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
continue; if (_running)
throw new InterruptedIOException();
throw new IOException("closed");
} }
if (serverSock.getInputStream() == null) // poison if (serverSock.getInputStream() == null) // poison
throw new IOException("closed"); throw new IOException("closed");
@ -128,7 +135,8 @@ public class InternalServerSocket extends ServerSocket {
return 0; return 0;
} }
// everything below here unsupported // most below here unsupported
/** @deprecated unsupported */ /** @deprecated unsupported */
@Deprecated @Deprecated
@Override @Override
@ -141,12 +149,15 @@ public class InternalServerSocket extends ServerSocket {
public void bind(SocketAddress endpoint, int backlog) { public void bind(SocketAddress endpoint, int backlog) {
throw new IllegalArgumentException("unsupported"); throw new IllegalArgumentException("unsupported");
} }
/** @deprecated unsupported */
@Deprecated /**
* Returns null as of 0.9.33, prior to that threw IllegalArgumentException
*/
@Override @Override
public ServerSocketChannel getChannel() { public ServerSocketChannel getChannel() {
throw new IllegalArgumentException("unsupported"); return null;
} }
/** @deprecated unsupported */ /** @deprecated unsupported */
@Deprecated @Deprecated
@Override @Override
@ -171,18 +182,23 @@ public class InternalServerSocket extends ServerSocket {
public boolean getReuseAddress() { public boolean getReuseAddress() {
throw new IllegalArgumentException("unsupported"); throw new IllegalArgumentException("unsupported");
} }
/** @deprecated unsupported */
@Deprecated /**
* Returns true as of 0.9.33, prior to that threw IllegalArgumentException
*/
@Override @Override
public boolean isBound() { public boolean isBound() {
throw new IllegalArgumentException("unsupported"); return true;
} }
/** @deprecated unsupported */
@Deprecated /**
* Supported as of 0.9.33, prior to that threw IllegalArgumentException
*/
@Override @Override
public boolean isClosed() { public boolean isClosed() {
throw new IllegalArgumentException("unsupported"); return !_running;
} }
/** @deprecated unsupported */ /** @deprecated unsupported */
@Deprecated @Deprecated
@Override @Override
@ -195,4 +211,18 @@ public class InternalServerSocket extends ServerSocket {
public void setReuseAddress(boolean on) { public void setReuseAddress(boolean on) {
throw new IllegalArgumentException("unsupported"); throw new IllegalArgumentException("unsupported");
} }
/**
* For debugging only
* @since 0.9.33
*/
public static void renderStatusHTML(Writer out) throws IOException {
out.write("<h2 id=\"debug_portmapper\">Internal Server Sockets</h2><table id=\"portmapper\"><tr><th>Port\n");
List<Integer> ports = new ArrayList<Integer>(_sockets.keySet());
Collections.sort(ports);
for (Integer i : ports) {
out.write("<tr><td>" + i + '\n');
}
out.write("</table>\n");
}
} }

View File

@ -244,18 +244,22 @@ public class InternalSocket extends Socket {
return _is != null || _os != null; return _is != null || _os != null;
} }
/** @deprecated unsupported */ /**
@Deprecated * Supported as of 0.9.33, prior to that threw UnsupportedOperationException
*/
@Override @Override
public boolean isInputShutdown() { public synchronized boolean isInputShutdown() {
throw new UnsupportedOperationException(); return _is == null;
} }
/** @deprecated unsupported */
@Deprecated /**
* Supported as of 0.9.33, prior to that threw UnsupportedOperationException
*/
@Override @Override
public boolean isOutputShutdown() { public synchronized boolean isOutputShutdown() {
throw new UnsupportedOperationException(); return _os == null;
} }
/** @deprecated unsupported */ /** @deprecated unsupported */
@Deprecated @Deprecated
@Override @Override
@ -310,16 +314,38 @@ public class InternalSocket extends Socket {
public void setTrafficClass(int cize) { public void setTrafficClass(int cize) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/** @deprecated unsupported */
@Deprecated /**
* Supported as of 0.9.33, prior to that threw UnsupportedOperationException
*/
@Override @Override
public void shutdownInput() { public synchronized void shutdownInput() throws IOException {
throw new UnsupportedOperationException(); 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 @Override
public void shutdownOutput() { public void shutdownOutput() throws IOException {
throw new UnsupportedOperationException(); 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;
}
}
} }
} }