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 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Reference in New Issue
Block a user