diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java index 47a07c37466c0e233b372ba62398d68a9309e5e3..1b302ff0b92393ef4ca5866f06ca8c9f43354548 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -106,6 +106,9 @@ public class SummaryHelper extends HelperBase { public int getAllPeers() { return _context.netDb().getKnownRouters(); } public String getReachability() { + if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) && + !_context.clientManager().isAlive()) + return "ERR-Client Manager I2CP Error - check logs"; // not a router problem but the user should know if (!_context.clock().getUpdatedSuccessfully()) return "ERR-ClockSkew"; if (_context.router().isHidden()) diff --git a/apps/routerconsole/jsp/config.jsp b/apps/routerconsole/jsp/config.jsp index 132bd5315ca550b5f9c7506c274f7dec6f14d225..ae357d69f1e7fd1965daa2b02d5925500df3d3e9 100644 --- a/apps/routerconsole/jsp/config.jsp +++ b/apps/routerconsole/jsp/config.jsp @@ -112,6 +112,7 @@ if you open up your port (generally 8887) to both UDP and TCP, and enable inbound TCP above. If you think you have opened up your firewall and I2P still thinks you are firewalled, remember that you may have multiple firewalls, for example both software packages and external hardware routers. + If there is an error, the <a href="logs.jsp">logs</a> may also help diagnose the problem. <ul> <li><b>OK</b> - Your UDP port does not appear to be firewalled. <li><b>Firewalled</b> - Your UDP port appears to be firewalled. @@ -151,6 +152,9 @@ You have not configured inbound TCP with a hostname and port above, however you have disabled UDP. Therefore your router cannot accept inbound connections. Please configure a TCP host and port above or enable UDP. + <li><b>ERR - Client Manager I2CP Error - check logs</b> - + This is usually due to a port 7654 conflict. Check the logs to verify. Do you have another I2P instance running? + Stop the conflicting program and restart I2P. </ul> </p> <hr /> diff --git a/router/java/src/net/i2p/router/ClientManagerFacade.java b/router/java/src/net/i2p/router/ClientManagerFacade.java index 07f6e561fcce19942e400d3a204c1024a4f78ade..2e441fefe226b48bc058d04f2f408a97bf9419ff 100644 --- a/router/java/src/net/i2p/router/ClientManagerFacade.java +++ b/router/java/src/net/i2p/router/ClientManagerFacade.java @@ -72,6 +72,7 @@ public abstract class ClientManagerFacade implements Service { public abstract void messageReceived(ClientMessage msg); public boolean verifyClientLiveliness() { return true; } + public boolean isAlive() { return true; } /** * Does the client specified want their leaseSet published? */ diff --git a/router/java/src/net/i2p/router/client/ClientListenerRunner.java b/router/java/src/net/i2p/router/client/ClientListenerRunner.java index 074b161dfd232047c45f3e73ab768a404f433f0c..38105e9c966c1b41327faa7da08956aa91b9662d 100644 --- a/router/java/src/net/i2p/router/client/ClientListenerRunner.java +++ b/router/java/src/net/i2p/router/client/ClientListenerRunner.java @@ -31,7 +31,7 @@ public class ClientListenerRunner implements Runnable { private int _port; private boolean _bindAllInterfaces; private boolean _running; - private long _nextFailDelay = 1000; + private boolean _listening; public static final String BIND_ALL_INTERFACES = "i2cp.tcp.bindAllInterfaces"; @@ -41,6 +41,7 @@ public class ClientListenerRunner implements Runnable { _manager = manager; _port = port; _running = false; + _listening = false; String val = context.getProperty(BIND_ALL_INTERFACES, "False"); _bindAllInterfaces = Boolean.valueOf(val).booleanValue(); @@ -48,6 +49,7 @@ public class ClientListenerRunner implements Runnable { public void setPort(int port) { _port = port; } public int getPort() { return _port; } + public boolean isListening() { return _running && _listening; } /** * Start up the socket listener, listens for connections, and @@ -58,7 +60,7 @@ public class ClientListenerRunner implements Runnable { */ public void runServer() { _running = true; - int curDelay = 0; + int curDelay = 1000; while (_running) { try { if (_bindAllInterfaces) { @@ -77,7 +79,8 @@ public class ClientListenerRunner implements Runnable { if (_log.shouldLog(Log.DEBUG)) _log.debug("ServerSocket created, before accept: " + _socket); - curDelay = 0; + curDelay = 1000; + _listening = true; while (_running) { try { Socket socket = _socket.accept(); @@ -96,6 +99,7 @@ public class ClientListenerRunner implements Runnable { } catch (Throwable t) { if (_context.router().isAlive()) _log.error("Fatal error running client listener - killing the thread!", t); + _listening = false; return; } } @@ -104,6 +108,7 @@ public class ClientListenerRunner implements Runnable { _log.error("Error listening on port " + _port, ioe); } + _listening = false; if (_socket != null) { try { _socket.close(); } catch (IOException ioe) {} _socket = null; @@ -111,14 +116,16 @@ public class ClientListenerRunner implements Runnable { if (!_context.router().isAlive()) break; - _log.error("Error listening, waiting " + _nextFailDelay + "ms before we try again"); - try { Thread.sleep(_nextFailDelay); } catch (InterruptedException ie) {} - curDelay += _nextFailDelay; - _nextFailDelay *= 5; + if (curDelay < 60*1000) + _log.error("Error listening, waiting " + (curDelay/1000) + "s before we try again"); + else + _log.log(Log.CRIT, "I2CP error listening to port " + _port + " - is another I2P instance running? Resolve conflicts and restart"); + try { Thread.sleep(curDelay); } catch (InterruptedException ie) {} + curDelay = Math.min(curDelay*3, 60*1000); } if (_context.router().isAlive()) - _log.error("CANCELING I2CP LISTEN. delay = " + curDelay, new Exception("I2CP Listen cancelled!!!")); + _log.error("CANCELING I2CP LISTEN", new Exception("I2CP Listen cancelled!!!")); _running = false; } diff --git a/router/java/src/net/i2p/router/client/ClientManager.java b/router/java/src/net/i2p/router/client/ClientManager.java index 18c9c77423d790836665096b9cc8d09926ab684e..9b5eb7c4ccbe24886646d0c011f1aeceba41ee6d 100644 --- a/router/java/src/net/i2p/router/client/ClientManager.java +++ b/router/java/src/net/i2p/router/client/ClientManager.java @@ -108,6 +108,8 @@ public class ClientManager { } } + public boolean isAlive() { return _listener.isListening(); } + public void registerConnection(ClientConnectionRunner runner) { synchronized (_pendingRunners) { _pendingRunners.add(runner); diff --git a/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java b/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java index 796a098a981cd24c2fe4a7b3b6036e038df4891e..51b8b4cb2513a67ba24cd2b44fb41f42af5102c8 100644 --- a/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java +++ b/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java @@ -74,6 +74,8 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade { startup(); } + public boolean isAlive() { return _manager != null && _manager.isAlive(); } + private static final long MAX_TIME_TO_REBUILD = 10*60*1000; public boolean verifyClientLiveliness() { if (_manager == null) return true;