Implemented timeout handling to I2PTunnelServer

This commit is contained in:
human
2004-04-21 17:58:26 +00:00
committed by zzz
parent d7c3a53f2d
commit 4fe7105e2f
3 changed files with 79 additions and 17 deletions

View File

@ -74,6 +74,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
public static String host = System.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1"); public static String host = System.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1");
public static String listenHost = host; public static String listenHost = host;
public static long readTimeout = -1;
private static final String nocli_args[] = { "-nocli", "-die"}; private static final String nocli_args[] = { "-nocli", "-die"};
private List tasks = new ArrayList(); private List tasks = new ArrayList();
@ -201,6 +203,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
runConfig(args, l); runConfig(args, l);
} else if ("listen_on".equals(cmdname)) { } else if ("listen_on".equals(cmdname)) {
runListenOn(args, l); runListenOn(args, l);
} else if ("read_timeout".equals(cmdname)) {
runReadTimeout(args, l);
} else if ("genkeys".equals(cmdname)) { } else if ("genkeys".equals(cmdname)) {
runGenKeys(args, l); runGenKeys(args, l);
} else if ("gentextkeys".equals(cmdname)) { } else if ("gentextkeys".equals(cmdname)) {
@ -235,6 +239,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("Command list:"); l.log("Command list:");
l.log("config <i2phost> <i2pport>"); l.log("config <i2phost> <i2pport>");
l.log("listen_on <ip>"); l.log("listen_on <ip>");
l.log("read_timeout <msecs>");
l.log("owndest yes|no"); l.log("owndest yes|no");
l.log("ping <args>"); l.log("ping <args>");
l.log("server <host> <port> <privkeyfile>"); l.log("server <host> <port> <privkeyfile>");
@ -291,10 +296,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
notifyEvent("serverTaskId", new Integer(-1)); notifyEvent("serverTaskId", new Integer(-1));
return; return;
} }
I2PTunnelTask task; I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this);
task = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this); serv.setReadTimeout(readTimeout);
addtask(task); serv.startRunning();
notifyEvent("serverTaskId", new Integer(task.getId())); addtask(serv);
notifyEvent("serverTaskId", new Integer(serv.getId()));
return; return;
} else { } else {
l.log("server <host> <port> <privkeyfile>"); l.log("server <host> <port> <privkeyfile>");
@ -336,10 +342,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
return; return;
} }
I2PTunnelTask task; I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this);
task = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this); serv.setReadTimeout(readTimeout);
addtask(task); serv.startRunning();
notifyEvent("serverTaskId", new Integer(task.getId())); addtask(serv);
notifyEvent("serverTaskId", new Integer(serv.getId()));
} else { } else {
l.log("textserver <host> <port> <privkey>"); l.log("textserver <host> <port> <privkey>");
l.log(" creates a server that sends all incoming data\n" + " of its destination to host:port."); l.log(" creates a server that sends all incoming data\n" + " of its destination to host:port.");
@ -510,7 +517,31 @@ public class I2PTunnel implements Logging, EventDispatcher {
} else { } else {
l.log("listen_on <ip>"); l.log("listen_on <ip>");
l.log(" sets the interface to listen for the I2PClient."); l.log(" sets the interface to listen for the I2PClient.");
notifyEvent("listen_onResult", "error");
}
}
/**
* Specify the read timeout going to be used for newly-created I2PSockets
*
* Sets the event "read_timeoutResult" = "ok" or "error" after the interface has been specified
*
* @param args {hostname}
* @param l logger to receive events and output
*/
public void runReadTimeout(String args[], Logging l) {
if (args.length == 1) {
try {
readTimeout = Long.parseLong(args[0]);
} catch (NumberFormatException e) {
notifyEvent("read_timeoutResult", "error");
}
notifyEvent("listen_onResult", "ok"); notifyEvent("listen_onResult", "ok");
} else {
l.log("read_timeout <msecs>");
l.log(" sets the read timeout (in milliseconds) for I2P connections\n"
+" Negative values will make the connections wait forever");
notifyEvent("read_timeoutResult", "error");
} }
} }
@ -1000,4 +1031,4 @@ public class I2PTunnel implements Logging, EventDispatcher {
public Object waitEventValue(String n) { public Object waitEventValue(String n) {
return _event.waitEventValue(n); return _event.waitEventValue(n);
} }
} }

View File

@ -6,6 +6,7 @@ package net.i2p.i2ptunnel;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
@ -116,7 +117,7 @@ public class I2PTunnelRunner extends I2PThread {
_log.error("Interrupted", ex); _log.error("Interrupted", ex);
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); ex.printStackTrace();
_log.error("Error forwarding", ex); _log.debug("Error forwarding", ex);
} finally { } finally {
try { try {
if (s != null) s.close(); if (s != null) s.close();
@ -163,11 +164,13 @@ public class I2PTunnelRunner extends I2PThread {
} catch (SocketException ex) { } catch (SocketException ex) {
// this *will* occur when the other threads closes the socket // this *will* occur when the other threads closes the socket
synchronized (finishLock) { synchronized (finishLock) {
if (!finished) if (!finished) {
_log.error("Error reading and writing", ex); _log.debug("Socket closed - error reading and writing",
else ex);
_log.warn("You may ignore this", ex); }
} }
} catch (InterruptedIOException ex) {
_log.debug("Socket read timed out - closing StreamForwarder");
} catch (IOException ex) { } catch (IOException ex) {
if (!finished) if (!finished)
_log.error("Error forwarding", ex); _log.error("Error forwarding", ex);
@ -188,4 +191,4 @@ public class I2PTunnelRunner extends I2PThread {
} }
} }
} }
} }

View File

@ -40,6 +40,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
private Logging l; private Logging l;
private long readTimeout = -1;
public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis) { public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis) {
super(host + ":" + port + " <- " + privData, notifyThis); super(host + ":" + port + " <- " + privData, notifyThis);
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(privData)); ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(privData));
@ -57,8 +59,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
} }
} }
public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis) {
EventDispatcher notifyThis) {
super(host + ":" + port + " <- " + privkeyname, notifyThis); super(host + ":" + port + " <- " + privkeyname, notifyThis);
init(host, port, privData, privkeyname, l); init(host, port, privData, privkeyname, l);
} }
@ -78,11 +79,37 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
l.log("Ready!"); l.log("Ready!");
notifyEvent("openServerResult", "ok"); notifyEvent("openServerResult", "ok");
open = true; open = true;
}
/**
* Start running the I2PTunnelServer.
*
*/
public void startRunning() {
Thread t = new I2PThread(this); Thread t = new I2PThread(this);
t.setName("Server"); t.setName("Server");
t.start(); t.start();
} }
/**
* Set the read idle timeout for newly-created connections (in
* milliseconds). After this time expires without data being reached from
* the I2P network, the connection itself will be closed.
*/
public void setReadTimeout(long ms) {
readTimeout = ms;
}
/**
* Get the read idle timeout for newly-created connections (in
* milliseconds).
*
* @return The read timeout used for connections
*/
public long getReadTimeout() {
return readTimeout;
}
public boolean close(boolean forced) { public boolean close(boolean forced) {
if (!open) return true; if (!open) return true;
synchronized (lock) { synchronized (lock) {
@ -115,6 +142,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
//local is fast, so synchronously. Does not need that many //local is fast, so synchronously. Does not need that many
//threads. //threads.
try { try {
i2ps.setReadTimeout(readTimeout);
Socket s = new Socket(remoteHost, remotePort); Socket s = new Socket(remoteHost, remotePort);
new I2PTunnelRunner(s, i2ps, slock, null); new I2PTunnelRunner(s, i2ps, slock, null);
} catch (SocketException ex) { } catch (SocketException ex) {