Implemented timeout handling to I2PTunnelServer
This commit is contained in:
@ -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 listenHost = host;
|
||||
|
||||
public static long readTimeout = -1;
|
||||
|
||||
private static final String nocli_args[] = { "-nocli", "-die"};
|
||||
|
||||
private List tasks = new ArrayList();
|
||||
@ -201,6 +203,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
runConfig(args, l);
|
||||
} else if ("listen_on".equals(cmdname)) {
|
||||
runListenOn(args, l);
|
||||
} else if ("read_timeout".equals(cmdname)) {
|
||||
runReadTimeout(args, l);
|
||||
} else if ("genkeys".equals(cmdname)) {
|
||||
runGenKeys(args, l);
|
||||
} else if ("gentextkeys".equals(cmdname)) {
|
||||
@ -235,6 +239,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
l.log("Command list:");
|
||||
l.log("config <i2phost> <i2pport>");
|
||||
l.log("listen_on <ip>");
|
||||
l.log("read_timeout <msecs>");
|
||||
l.log("owndest yes|no");
|
||||
l.log("ping <args>");
|
||||
l.log("server <host> <port> <privkeyfile>");
|
||||
@ -291,10 +296,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
notifyEvent("serverTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
I2PTunnelTask task;
|
||||
task = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this);
|
||||
addtask(task);
|
||||
notifyEvent("serverTaskId", new Integer(task.getId()));
|
||||
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this);
|
||||
serv.setReadTimeout(readTimeout);
|
||||
serv.startRunning();
|
||||
addtask(serv);
|
||||
notifyEvent("serverTaskId", new Integer(serv.getId()));
|
||||
return;
|
||||
} else {
|
||||
l.log("server <host> <port> <privkeyfile>");
|
||||
@ -336,10 +342,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
return;
|
||||
}
|
||||
|
||||
I2PTunnelTask task;
|
||||
task = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this);
|
||||
addtask(task);
|
||||
notifyEvent("serverTaskId", new Integer(task.getId()));
|
||||
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this);
|
||||
serv.setReadTimeout(readTimeout);
|
||||
serv.startRunning();
|
||||
addtask(serv);
|
||||
notifyEvent("serverTaskId", new Integer(serv.getId()));
|
||||
} else {
|
||||
l.log("textserver <host> <port> <privkey>");
|
||||
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 {
|
||||
l.log("listen_on <ip>");
|
||||
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");
|
||||
} 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) {
|
||||
return _event.waitEventValue(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ package net.i2p.i2ptunnel;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
@ -116,7 +117,7 @@ public class I2PTunnelRunner extends I2PThread {
|
||||
_log.error("Interrupted", ex);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
_log.error("Error forwarding", ex);
|
||||
_log.debug("Error forwarding", ex);
|
||||
} finally {
|
||||
try {
|
||||
if (s != null) s.close();
|
||||
@ -163,11 +164,13 @@ public class I2PTunnelRunner extends I2PThread {
|
||||
} catch (SocketException ex) {
|
||||
// this *will* occur when the other threads closes the socket
|
||||
synchronized (finishLock) {
|
||||
if (!finished)
|
||||
_log.error("Error reading and writing", ex);
|
||||
else
|
||||
_log.warn("You may ignore this", ex);
|
||||
if (!finished) {
|
||||
_log.debug("Socket closed - error reading and writing",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedIOException ex) {
|
||||
_log.debug("Socket read timed out - closing StreamForwarder");
|
||||
} catch (IOException ex) {
|
||||
if (!finished)
|
||||
_log.error("Error forwarding", ex);
|
||||
@ -188,4 +191,4 @@ public class I2PTunnelRunner extends I2PThread {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
|
||||
private Logging l;
|
||||
|
||||
private long readTimeout = -1;
|
||||
|
||||
public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis) {
|
||||
super(host + ":" + port + " <- " + privData, notifyThis);
|
||||
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,
|
||||
EventDispatcher notifyThis) {
|
||||
public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis) {
|
||||
super(host + ":" + port + " <- " + privkeyname, notifyThis);
|
||||
init(host, port, privData, privkeyname, l);
|
||||
}
|
||||
@ -78,11 +79,37 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
l.log("Ready!");
|
||||
notifyEvent("openServerResult", "ok");
|
||||
open = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start running the I2PTunnelServer.
|
||||
*
|
||||
*/
|
||||
public void startRunning() {
|
||||
Thread t = new I2PThread(this);
|
||||
t.setName("Server");
|
||||
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) {
|
||||
if (!open) return true;
|
||||
synchronized (lock) {
|
||||
@ -115,6 +142,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
//local is fast, so synchronously. Does not need that many
|
||||
//threads.
|
||||
try {
|
||||
i2ps.setReadTimeout(readTimeout);
|
||||
Socket s = new Socket(remoteHost, remotePort);
|
||||
new I2PTunnelRunner(s, i2ps, slock, null);
|
||||
} catch (SocketException ex) {
|
||||
|
Reference in New Issue
Block a user