forked from I2P_Developers/i2p.i2p
More work on error propagation and improving log messages in i2ptunnel and I2CP client
This commit is contained in:
@@ -85,8 +85,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
|
||||
public boolean ownDest = false;
|
||||
|
||||
/** the I2CP port */
|
||||
public String port = System.getProperty(I2PClient.PROP_TCP_PORT, "7654");
|
||||
/** the I2CP host */
|
||||
public String host = System.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1");
|
||||
/** the listen-on host. Sadly the listen-on port does not have a field. */
|
||||
public String listenHost = host;
|
||||
|
||||
public long readTimeout = -1;
|
||||
@@ -689,8 +692,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
addtask(task);
|
||||
notifyEvent("clientTaskId", Integer.valueOf(task.getId()));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
_log.error(getPrefix() + "Invalid I2PTunnel config to create a client [" + host + ":"+ port + "]", iae);
|
||||
l.log("Invalid I2PTunnel configuration [" + host + ":" + port + "]");
|
||||
String msg = "Invalid I2PTunnel configuration to create an HTTP Proxy connecting to the router at " + host + ':'+ port +
|
||||
" and listening on " + listenHost + ':' + port;
|
||||
_log.error(getPrefix() + msg, iae);
|
||||
l.log(msg);
|
||||
notifyEvent("clientTaskId", Integer.valueOf(-1));
|
||||
// Since nothing listens to TaskID events, use this to propagate the error to TunnelController
|
||||
// Otherwise, the tunnel stays up even though the port is down
|
||||
@@ -763,8 +768,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
addtask(task);
|
||||
notifyEvent("httpclientTaskId", Integer.valueOf(task.getId()));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
_log.error(getPrefix() + "Invalid I2PTunnel config to create an httpclient [" + host + ":"+ clientPort + "]", iae);
|
||||
l.log("Invalid I2PTunnel configuration [" + host + ":" + clientPort + "]");
|
||||
String msg = "Invalid I2PTunnel configuration to create an HTTP Proxy connecting to the router at " + host + ':'+ port +
|
||||
" and listening on " + listenHost + ':' + port;
|
||||
_log.error(getPrefix() + msg, iae);
|
||||
l.log(msg);
|
||||
notifyEvent("httpclientTaskId", Integer.valueOf(-1));
|
||||
// Since nothing listens to TaskID events, use this to propagate the error to TunnelController
|
||||
// Otherwise, the tunnel stays up even though the port is down
|
||||
@@ -829,7 +836,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
task = new I2PTunnelConnectClient(_port, l, ownDest, proxy, (EventDispatcher) this, this);
|
||||
addtask(task);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
_log.error(getPrefix() + "Invalid I2PTunnel config to create a connect client [" + host + ":"+ _port + "]", iae);
|
||||
String msg = "Invalid I2PTunnel configuration to create a CONNECT client connecting to the router at " + host + ':'+ port +
|
||||
" and listening on " + listenHost + ':' + port;
|
||||
_log.error(getPrefix() + msg, iae);
|
||||
l.log(msg);
|
||||
// Since nothing listens to TaskID events, use this to propagate the error to TunnelController
|
||||
// Otherwise, the tunnel stays up even though the port is down
|
||||
// This doesn't work for CLI though... and the tunnel doesn't close itself after error,
|
||||
@@ -892,8 +902,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
addtask(task);
|
||||
notifyEvent("ircclientTaskId", Integer.valueOf(task.getId()));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
_log.error(getPrefix() + "Invalid I2PTunnel config to create an ircclient [" + host + ":"+ _port + "]", iae);
|
||||
l.log("Invalid I2PTunnel configuration [" + host + ":" + _port + "]");
|
||||
String msg = "Invalid I2PTunnel configuration to create an IRC client connecting to the router at " + host + ':'+ port +
|
||||
" and listening on " + listenHost + ':' + port;
|
||||
_log.error(getPrefix() + msg, iae);
|
||||
l.log(msg);
|
||||
notifyEvent("ircclientTaskId", Integer.valueOf(-1));
|
||||
// Since nothing listens to TaskID events, use this to propagate the error to TunnelController
|
||||
// Otherwise, the tunnel stays up even though the port is down
|
||||
@@ -939,10 +951,18 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
isShared = "true".equalsIgnoreCase(args[1].trim());
|
||||
|
||||
ownDest = !isShared;
|
||||
I2PTunnelTask task;
|
||||
task = new I2PSOCKSTunnel(_port, l, ownDest, (EventDispatcher) this, this, null);
|
||||
addtask(task);
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(task.getId()));
|
||||
try {
|
||||
I2PTunnelTask task = new I2PSOCKSTunnel(_port, l, ownDest, (EventDispatcher) this, this, null);
|
||||
addtask(task);
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(task.getId()));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
String msg = "Invalid I2PTunnel configuration to create a SOCKS Proxy connecting to the router at " + host + ':'+ port +
|
||||
" and listening on " + listenHost + ':' + port;
|
||||
_log.error(getPrefix() + msg, iae);
|
||||
l.log(msg);
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("sockstunnel <port>");
|
||||
l.log(" creates a tunnel that distributes SOCKS requests.");
|
||||
@@ -978,10 +998,18 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
String privateKeyFile = null;
|
||||
if (args.length == 3)
|
||||
privateKeyFile = args[2];
|
||||
I2PTunnelTask task;
|
||||
task = new I2PSOCKSIRCTunnel(_port, l, ownDest, (EventDispatcher) this, this, privateKeyFile);
|
||||
addtask(task);
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(task.getId()));
|
||||
try {
|
||||
I2PTunnelTask task = new I2PSOCKSIRCTunnel(_port, l, ownDest, (EventDispatcher) this, this, privateKeyFile);
|
||||
addtask(task);
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(task.getId()));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
String msg = "Invalid I2PTunnel configuration to create a SOCKS IRC Proxy connecting to the router at " + host + ':'+ port +
|
||||
" and listening on " + listenHost + ':' + port;
|
||||
_log.error(getPrefix() + msg, iae);
|
||||
l.log(msg);
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("socksirctunnel <port> [<sharedClient> [<privKeyFile>]]");
|
||||
l.log(" creates a tunnel for SOCKS IRC.");
|
||||
@@ -1019,10 +1047,19 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
if (_port <= 0)
|
||||
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
|
||||
|
||||
StreamrConsumer task = new StreamrConsumer(_host, _port, args[2], l, (EventDispatcher) this, this);
|
||||
task.startRunning();
|
||||
addtask(task);
|
||||
notifyEvent("streamrtunnelTaskId", Integer.valueOf(task.getId()));
|
||||
try {
|
||||
StreamrConsumer task = new StreamrConsumer(_host, _port, args[2], l, (EventDispatcher) this, this);
|
||||
task.startRunning();
|
||||
addtask(task);
|
||||
notifyEvent("streamrtunnelTaskId", Integer.valueOf(task.getId()));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
String msg = "Invalid I2PTunnel configuration to create a Streamr Client connecting to the router at " + host + ':'+ port +
|
||||
" and sending to " + _host + ':' + port;
|
||||
_log.error(getPrefix() + msg, iae);
|
||||
l.log(msg);
|
||||
notifyEvent("streamrtunnnelTaskId", Integer.valueOf(-1));
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("streamrclient <host> <port> <destination>");
|
||||
l.log(" creates a tunnel that receives streaming data.");
|
||||
@@ -1409,7 +1446,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
for (Iterator it = tasks.iterator(); it.hasNext();) {
|
||||
I2PTunnelTask t = (I2PTunnelTask) it.next();
|
||||
int id = t.getId();
|
||||
_log.debug(getPrefix() + "closetask(): parsing task " + id + " (" + t.toString() + ")");
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getPrefix() + "closetask(): parsing task " + id + " (" + t.toString() + ")");
|
||||
if (id == num) {
|
||||
closed = closetask(t, forced, l);
|
||||
break;
|
||||
@@ -1427,9 +1465,13 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
*
|
||||
*/
|
||||
private boolean closetask(I2PTunnelTask t, boolean forced, Logging l) {
|
||||
l.log("Closing task " + t.getId() + (forced ? " forced..." : "..."));
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Closing task " + t.getId() + (forced ? " forced..." : "..."));
|
||||
//l.log("Closing task " + t.getId() + (forced ? " forced..." : "..."));
|
||||
if (t.close(forced)) {
|
||||
l.log("Task " + t.getId() + " closed.");
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Task " + t.getId() + " closed.");
|
||||
//l.log("Task " + t.getId() + " closed.");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -128,10 +128,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
configurePool(tunnel);
|
||||
|
||||
if (open && listenerReady) {
|
||||
l.log("Ready! Port " + getLocalPort());
|
||||
l.log("Client ready, listening on " + tunnel.listenHost + ':' + localPort);
|
||||
notifyEvent("openBaseClientResult", "ok");
|
||||
} else {
|
||||
l.log("Error listening - please see the logs!");
|
||||
l.log("Client error for " + tunnel.listenHost + ':' + localPort + ", check logs");
|
||||
notifyEvent("openBaseClientResult", "error");
|
||||
}
|
||||
}
|
||||
@@ -181,7 +181,9 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
while (sockMgr == null) {
|
||||
verifySocketManager();
|
||||
if (sockMgr == null) {
|
||||
_log.log(Log.CRIT, "Unable to create socket manager (our own? " + ownDest + ")");
|
||||
_log.error("Unable to connect to router and build tunnels for " + handlerName);
|
||||
// FIXME there is a loop in buildSocketManager(), do we really need another one here?
|
||||
// no matter, buildSocketManager() now throws an IllegalArgumentException
|
||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
@@ -212,12 +214,12 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
|
||||
if (open && listenerReady) {
|
||||
if (openNow)
|
||||
l.log("Ready! Port " + getLocalPort());
|
||||
l.log("Client ready, listening on " + tunnel.listenHost + ':' + localPort);
|
||||
else
|
||||
l.log("Listening on port " + getLocalPort() + ", delaying tunnel open until required");
|
||||
l.log("Client ready, listening on " + tunnel.listenHost + ':' + localPort + ", delaying tunnel open until required");
|
||||
notifyEvent("openBaseClientResult", "ok");
|
||||
} else {
|
||||
l.log("Error listening - please see the logs!");
|
||||
l.log("Client error for " + tunnel.listenHost + ':' + localPort + ", check logs");
|
||||
notifyEvent("openBaseClientResult", "error");
|
||||
}
|
||||
}
|
||||
@@ -257,6 +259,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
* Sets the this.sockMgr field if it is null, or if we want a new one
|
||||
*
|
||||
* We need a socket manager before getDefaultOptions() and most other things
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
protected void verifySocketManager() {
|
||||
synchronized(sockLock) {
|
||||
@@ -289,15 +293,33 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
/** this is ONLY for shared clients */
|
||||
private static I2PSocketManager socketManager;
|
||||
|
||||
/** this is ONLY for shared clients */
|
||||
|
||||
/**
|
||||
* this is ONLY for shared clients
|
||||
* @return non-null
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
protected synchronized I2PSocketManager getSocketManager() {
|
||||
return getSocketManager(getTunnel(), this.privKeyFile);
|
||||
}
|
||||
/** this is ONLY for shared clients */
|
||||
|
||||
/**
|
||||
* this is ONLY for shared clients
|
||||
* @return non-null
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) {
|
||||
return getSocketManager(tunnel, null);
|
||||
}
|
||||
/** this is ONLY for shared clients */
|
||||
|
||||
/**
|
||||
* this is ONLY for shared clients
|
||||
* @return non-null
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel, String pkf) {
|
||||
if (socketManager != null) {
|
||||
I2PSession s = socketManager.getSession();
|
||||
@@ -319,15 +341,43 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
return socketManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return non-null
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
protected I2PSocketManager buildSocketManager() {
|
||||
return buildSocketManager(getTunnel(), this.privKeyFile);
|
||||
return buildSocketManager(getTunnel(), this.privKeyFile, this.l);
|
||||
}
|
||||
/**
|
||||
* @return non-null
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel) {
|
||||
return buildSocketManager(tunnel, null);
|
||||
}
|
||||
|
||||
/** @param pkf absolute path or null */
|
||||
private static final int RETRY_DELAY = 20*1000;
|
||||
private static final int MAX_RETRIES = 4;
|
||||
|
||||
/**
|
||||
* @param pkf absolute path or null
|
||||
* @return non-null
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel, String pkf) {
|
||||
return buildSocketManager(tunnel, pkf, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pkf absolute path or null
|
||||
* @return non-null
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel, String pkf, Logging log) {
|
||||
Properties props = new Properties();
|
||||
props.putAll(tunnel.getClientOptions());
|
||||
int portNum = 7654;
|
||||
@@ -340,6 +390,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
}
|
||||
|
||||
I2PSocketManager sockManager = null;
|
||||
// Todo: Can't stop a tunnel from the UI while it's in this loop (no session yet)
|
||||
int retries = 0;
|
||||
while (sockManager == null) {
|
||||
if (pkf != null) {
|
||||
// Persistent client dest
|
||||
@@ -348,8 +400,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
fis = new FileInputStream(pkf);
|
||||
sockManager = I2PSocketManagerFactory.createManager(fis, tunnel.host, portNum, props);
|
||||
} catch (IOException ioe) {
|
||||
if (log != null)
|
||||
log.log("Error opening key file " + ioe);
|
||||
_log.error("Error opening key file", ioe);
|
||||
// this is going to loop but if we break we'll get a NPE
|
||||
throw new IllegalArgumentException("Error opening key file " + ioe);
|
||||
} finally {
|
||||
if (fis != null)
|
||||
try { fis.close(); } catch (IOException ioe) {}
|
||||
@@ -359,8 +413,22 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
}
|
||||
|
||||
if (sockManager == null) {
|
||||
_log.log(Log.CRIT, "Unable to create socket manager");
|
||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||
// try to make this error sensible as it will happen... sadly we can't get to the listenPort, only the listenHost
|
||||
String msg = "Unable to connect to the router at " + tunnel.host + ':' + portNum +
|
||||
" and build tunnels for the client";
|
||||
if (++retries < MAX_RETRIES) {
|
||||
if (log != null)
|
||||
log.log(msg + ", retrying in " + (RETRY_DELAY / 1000) + " seconds");
|
||||
_log.error(msg + ", retrying in " + (RETRY_DELAY / 1000) + " seconds");
|
||||
} else {
|
||||
if (log != null)
|
||||
log.log(msg + ", giving up");
|
||||
_log.log(Log.CRIT, msg + ", giving up");
|
||||
// not clear if callers can handle null
|
||||
//return null;
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
try { Thread.sleep(RETRY_DELAY); } catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
sockManager.setName("Client");
|
||||
@@ -479,7 +547,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
localPort = ss.getLocalPort();
|
||||
}
|
||||
notifyEvent("clientLocalPort", new Integer(ss.getLocalPort()));
|
||||
l.log("Listening for clients on port " + localPort + " of " + getTunnel().listenHost);
|
||||
// duplicates message in constructor
|
||||
//l.log("Listening for clients on port " + localPort + " of " + getTunnel().listenHost);
|
||||
|
||||
// Notify constructor that port is ready
|
||||
synchronized (this) {
|
||||
@@ -608,7 +677,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
}
|
||||
} // else the app chaining to this one closes it!
|
||||
}
|
||||
l.log("Closing client " + toString());
|
||||
l.log("Stopping client " + toString());
|
||||
open = false;
|
||||
try {
|
||||
if (ss != null) ss.close();
|
||||
@@ -616,7 +685,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
ex.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
l.log("Client closed.");
|
||||
//l.log("Client closed.");
|
||||
}
|
||||
|
||||
synchronized (_waitingSockets) { _waitingSockets.notifyAll(); }
|
||||
|
||||
@@ -115,7 +115,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
public I2PTunnelConnectClient(int localPort, Logging l, boolean ownDest,
|
||||
String wwwProxy, EventDispatcher notifyThis,
|
||||
I2PTunnel tunnel) throws IllegalArgumentException {
|
||||
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel);
|
||||
super(localPort, ownDest, l, notifyThis, "HTTPS Proxy on " + tunnel.listenHost + ':' + localPort + " #" + (++__clientId), tunnel);
|
||||
|
||||
if (waitEventValue("openBaseClientResult").equals("error")) {
|
||||
notifyEvent("openConnectClientResult", "error");
|
||||
@@ -128,7 +128,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
_proxyList.add(tok.nextToken().trim());
|
||||
}
|
||||
|
||||
setName(getLocalPort() + " -> ConnectClient [Outproxy list: " + wwwProxy + "]");
|
||||
setName("HTTPS Proxy on " + tunnel.listenHost + ':' + localPort);
|
||||
|
||||
startRunning();
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
super(localPort, l, sockMgr, tunnel, notifyThis, clientId);
|
||||
// proxyList = new ArrayList();
|
||||
|
||||
setName(getLocalPort() + " -> HTTPClient [NO PROXIES]");
|
||||
setName("HTTP Proxy on " + getTunnel().listenHost + ':' + localPort);
|
||||
startRunning();
|
||||
|
||||
notifyEvent("openHTTPClientResult", "ok");
|
||||
@@ -178,7 +178,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest,
|
||||
String wwwProxy, EventDispatcher notifyThis,
|
||||
I2PTunnel tunnel) throws IllegalArgumentException {
|
||||
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel);
|
||||
super(localPort, ownDest, l, notifyThis, "HTTP Proxy on " + tunnel.listenHost + ':' + localPort + " #" + (++__clientId), tunnel);
|
||||
|
||||
//proxyList = new ArrayList(); // We won't use outside of i2p
|
||||
if (waitEventValue("openBaseClientResult").equals("error")) {
|
||||
@@ -192,7 +192,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
_proxyList.add(tok.nextToken().trim());
|
||||
}
|
||||
|
||||
setName(getLocalPort() + " -> HTTPClient [WWW outproxy list: " + wwwProxy + "]");
|
||||
setName("HTTP Proxy on " + tunnel.listenHost + ':' + localPort);
|
||||
|
||||
startRunning();
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
ownDest,
|
||||
l,
|
||||
notifyThis,
|
||||
"IRCHandler " + (++__clientId), tunnel, pkf);
|
||||
"IRC Client on " + tunnel.listenHost + ':' + localPort + " #" + (++__clientId), tunnel, pkf);
|
||||
|
||||
StringTokenizer tok = new StringTokenizer(destinations, ", ");
|
||||
dests = new ArrayList(2);
|
||||
@@ -80,7 +80,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
//return;
|
||||
}
|
||||
|
||||
setName(getLocalPort() + " -> IRCClient");
|
||||
setName("IRC Client on " + tunnel.listenHost + ':' + localPort);
|
||||
|
||||
startRunning();
|
||||
|
||||
|
||||
@@ -61,16 +61,24 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
private int DEFAULT_LOCALPORT = 4488;
|
||||
protected int localPort = DEFAULT_LOCALPORT;
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(host + ":" + port + " <- " + privData, notifyThis, tunnel);
|
||||
super("Server at " + host + ':' + port, notifyThis, tunnel);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(privData));
|
||||
SetUsePool(tunnel);
|
||||
init(host, port, bais, privData, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
public I2PTunnelServer(InetAddress host, int port, File privkey, String privkeyname, Logging l,
|
||||
EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel);
|
||||
super("Server at " + host + ':' + port, notifyThis, tunnel);
|
||||
SetUsePool(tunnel);
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
@@ -85,8 +93,12 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel);
|
||||
super("Server at " + host + ':' + port, notifyThis, tunnel);
|
||||
SetUsePool(tunnel);
|
||||
init(host, port, privData, privkeyname, l);
|
||||
}
|
||||
@@ -100,6 +112,13 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
_usePool = DEFAULT_USE_POOL;
|
||||
}
|
||||
|
||||
private static final int RETRY_DELAY = 20*1000;
|
||||
private static final int MAX_RETRIES = 4;
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
|
||||
* badly that we cant create a socketManager
|
||||
*/
|
||||
private void init(InetAddress host, int port, InputStream privData, String privkeyname, Logging l) {
|
||||
this.l = l;
|
||||
this.remoteHost = host;
|
||||
@@ -111,7 +130,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
try {
|
||||
portNum = Integer.parseInt(getTunnel().port);
|
||||
} catch (NumberFormatException nfe) {
|
||||
_log.log(Log.CRIT, "Invalid port specified [" + getTunnel().port + "], reverting to " + portNum);
|
||||
_log.error("Invalid port specified [" + getTunnel().port + "], reverting to " + portNum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +144,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
}
|
||||
|
||||
// Todo: Can't stop a tunnel from the UI while it's in this loop (no session yet)
|
||||
int retries = 0;
|
||||
while (sockMgr == null) {
|
||||
synchronized (slock) {
|
||||
sockMgr = I2PSocketManagerFactory.createManager(privDataCopy, getTunnel().host, portNum,
|
||||
@@ -132,15 +152,25 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
|
||||
}
|
||||
if (sockMgr == null) {
|
||||
_log.log(Log.CRIT, "Unable to create socket manager");
|
||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||
// try to make this error sensible as it will happen...
|
||||
String msg = "Unable to connect to the router at " + getTunnel().host + ':' + portNum +
|
||||
" and build tunnels for the server at " + getTunnel().listenHost + ':' + port;
|
||||
if (++retries < MAX_RETRIES) {
|
||||
this.l.log(msg + ", retrying in " + (RETRY_DELAY / 1000) + " seconds");
|
||||
_log.error(msg + ", retrying in " + (RETRY_DELAY / 1000) + " seconds");
|
||||
} else {
|
||||
this.l.log(msg + ", giving up");
|
||||
_log.log(Log.CRIT, msg + ", giving up");
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
try { Thread.sleep(RETRY_DELAY); } catch (InterruptedException ie) {}
|
||||
privDataCopy.reset();
|
||||
}
|
||||
}
|
||||
|
||||
sockMgr.setName("Server");
|
||||
getTunnel().addSession(sockMgr.getSession());
|
||||
l.log("Ready!");
|
||||
l.log("Tunnels ready for server at " + getTunnel().listenHost + ':' + port);
|
||||
notifyEvent("openServerResult", "ok");
|
||||
open = true;
|
||||
}
|
||||
@@ -206,7 +236,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
l.log("Shutting down server " + toString());
|
||||
l.log("Stopping tunnels for server at " + getTunnel().listenHost + ':' + this.remotePort);
|
||||
try {
|
||||
if (i2pss != null) i2pss.close();
|
||||
getTunnel().removeSession(sockMgr.getSession());
|
||||
@@ -215,7 +245,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
_log.error("Error destroying the session", ex);
|
||||
//System.exit(1);
|
||||
}
|
||||
l.log("Server shut down.");
|
||||
//l.log("Server shut down.");
|
||||
open = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class InternalSocketRunner implements Runnable {
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
if (this.open) {
|
||||
_log.error("Error listening for internal connections on " + this.port, ex);
|
||||
_log.error("Error listening for internal connections on port " + this.port, ex);
|
||||
}
|
||||
this.open = false;
|
||||
}
|
||||
|
||||
@@ -128,8 +128,8 @@ public class TunnelController implements Logging {
|
||||
try {
|
||||
doStartTunnel();
|
||||
} catch (Exception e) {
|
||||
_log.error("Error starting up the tunnel", e);
|
||||
log("Error starting up the tunnel - " + e.getMessage());
|
||||
_log.error("Error starting the tunnel " + getName(), e);
|
||||
log("Error starting the tunnel " + getName() + ": " + e.getMessage());
|
||||
// if we don't acquire() then the release() in stopTunnel() won't work
|
||||
acquire();
|
||||
stopTunnel();
|
||||
|
||||
@@ -36,7 +36,7 @@ public class I2PSOCKSIRCTunnel extends I2PSOCKSTunnel {
|
||||
/** @param pkf private key file name or null for transient key */
|
||||
public I2PSOCKSIRCTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel, String pkf) {
|
||||
super(localPort, l, ownDest, notifyThis, tunnel, pkf);
|
||||
setName(getLocalPort() + " -> SOCKSIRCTunnel");
|
||||
setName("SOCKS IRC Proxy on " + tunnel.listenHost + ':' + localPort);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,14 +36,14 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase {
|
||||
|
||||
/** @param pkf private key file name or null for transient key */
|
||||
public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel, String pkf) {
|
||||
super(localPort, ownDest, l, notifyThis, "SOCKSHandler", tunnel, pkf);
|
||||
super(localPort, ownDest, l, notifyThis, "SOCKS Proxy on " + tunnel.listenHost + ':' + localPort, tunnel, pkf);
|
||||
|
||||
if (waitEventValue("openBaseClientResult").equals("error")) {
|
||||
notifyEvent("openSOCKSTunnelResult", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
setName(getLocalPort() + " -> SOCKSTunnel");
|
||||
setName("SOCKS Proxy on " + tunnel.listenHost + ':' + localPort);
|
||||
parseOptions();
|
||||
startRunning();
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ public class IndexBean {
|
||||
// give the messages a chance to make it to the window
|
||||
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||
// and give them something to look at in any case
|
||||
return _("Starting tunnel...");
|
||||
return _("Starting tunnel") + ' ' + getTunnelName(_tunnel) + " &hellip";
|
||||
}
|
||||
|
||||
private String stop() {
|
||||
@@ -239,7 +239,7 @@ public class IndexBean {
|
||||
// give the messages a chance to make it to the window
|
||||
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||
// and give them something to look at in any case
|
||||
return _("Stopping tunnel...");
|
||||
return _("Stopping tunnel") + ' ' + getTunnelName(_tunnel) + " &hellip";
|
||||
}
|
||||
|
||||
private String saveChanges() {
|
||||
|
||||
@@ -15,39 +15,28 @@ import java.io.PrintWriter;
|
||||
/**
|
||||
* Base class of I2P exceptions
|
||||
*
|
||||
* This was originally used to provide chained exceptions, but
|
||||
* those were added to Exception in Java 1.4, so this class provides nothing
|
||||
* extra at the moment.
|
||||
*
|
||||
* @author jrandom
|
||||
*/
|
||||
public class I2PException extends Exception {
|
||||
private Throwable _source;
|
||||
|
||||
public I2PException() {
|
||||
this(null, null);
|
||||
super();
|
||||
}
|
||||
|
||||
public I2PException(String msg) {
|
||||
this(msg, null);
|
||||
}
|
||||
|
||||
public I2PException(String msg, Throwable source) {
|
||||
super(msg);
|
||||
_source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace() {
|
||||
if (_source != null) _source.printStackTrace();
|
||||
super.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(PrintStream ps) {
|
||||
if (_source != null) _source.printStackTrace(ps);
|
||||
super.printStackTrace(ps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(PrintWriter pw) {
|
||||
if (_source != null) _source.printStackTrace(pw);
|
||||
super.printStackTrace(pw);
|
||||
public I2PException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.8.2 */
|
||||
public I2PException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
while (!_dateReceived) {
|
||||
if (waitcount++ > 30) {
|
||||
closeSocket();
|
||||
throw new IOException("no date handshake");
|
||||
throw new IOException("No handshake received from the router");
|
||||
}
|
||||
try {
|
||||
synchronized (_dateReceivedLock) {
|
||||
@@ -327,7 +327,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
_producer.disconnect(this);
|
||||
} catch (I2PSessionException ipe) {}
|
||||
closeSocket();
|
||||
throw new IOException("no leaseset");
|
||||
throw new IOException("No tunnels built after waiting 5 minutes... are there network problems?");
|
||||
}
|
||||
synchronized (_leaseSetWait) {
|
||||
try {
|
||||
@@ -346,11 +346,11 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
} catch (UnknownHostException uhe) {
|
||||
_closed = true;
|
||||
setOpening(false);
|
||||
throw new I2PSessionException(getPrefix() + "Invalid session configuration", uhe);
|
||||
throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, uhe);
|
||||
} catch (IOException ioe) {
|
||||
_closed = true;
|
||||
setOpening(false);
|
||||
throw new I2PSessionException(getPrefix() + "Problem connecting to " + _hostname + " on port " + _portNum, ioe);
|
||||
throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, ioe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,10 +86,10 @@ class I2PSimpleSession extends I2PSessionImpl2 {
|
||||
|
||||
} catch (UnknownHostException uhe) {
|
||||
_closed = true;
|
||||
throw new I2PSessionException(getPrefix() + "Bad host ", uhe);
|
||||
throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, uhe);
|
||||
} catch (IOException ioe) {
|
||||
_closed = true;
|
||||
throw new I2PSessionException(getPrefix() + "Problem connecting to " + _hostname + " on port " + _portNum, ioe);
|
||||
throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, ioe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user