eliminate startup race condition on reading router.config file, prevent router state exception while waiting for initialization

pull/13/head v1.6
knaccc 5 years ago
parent acae006728
commit 3d436d8a8c

@ -103,9 +103,15 @@ public class RouterWrapper {
if(router.isAlive()) { if(router.isAlive()) {
try { try {
File routerConfigFile = new File(i2PBaseDir, "router.config"); File routerConfigFile = new File(i2PBaseDir, "router.config");
if(!routerConfigFile.exists()) continue; if(!(routerConfigFile.exists() && routerConfigFile.canRead())) {
Thread.sleep(100);
continue;
}
Optional<String> portString = Files.lines(routerConfigFile.toPath()).filter(s -> s.startsWith("i2np.udp.port=")).findFirst(); Optional<String> portString = Files.lines(routerConfigFile.toPath()).filter(s -> s.startsWith("i2np.udp.port=")).findFirst();
if(portString.isEmpty()) continue; if(portString.isEmpty()) {
Thread.sleep(100);
continue;
}
routerExternalPort = Integer.parseInt(portString.get().split("=")[1]); routerExternalPort = Integer.parseInt(portString.get().split("=")[1]);
break; break;
} }
@ -323,85 +329,90 @@ public class RouterWrapper {
final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port"; final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
public NetworkStateMessage getReachability() { public NetworkStateMessage getReachability() {
RouterContext _context = router.getContext(); try {
if (_context.commSystem().isDummy()) RouterContext _context = router.getContext();
return new NetworkStateMessage(NetworkState.VMCOMM, "VM Comm System"); if (_context.commSystem().isDummy())
if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) && return new NetworkStateMessage(NetworkState.VMCOMM, "VM Comm System");
!_context.clientManager().isAlive()) if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) &&
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Client Manager I2CP Error - check logs")); // not a router problem but the user should know !_context.clientManager().isAlive())
// Warn based on actual skew from peers, not update status, so if we successfully offset return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Client Manager I2CP Error - check logs")); // not a router problem but the user should know
// the clock, we don't complain. // Warn based on actual skew from peers, not update status, so if we successfully offset
//if (!_context.clock().getUpdatedSuccessfully()) // the clock, we don't complain.
long skew = _context.commSystem().getFramedAveragePeerClockSkew(33); //if (!_context.clock().getUpdatedSuccessfully())
// Display the actual skew, not the offset long skew = _context.commSystem().getFramedAveragePeerClockSkew(33);
if (Math.abs(skew) > 30*1000) // Display the actual skew, not the offset
return new NetworkStateMessage(NetworkState.CLOCKSKEW, _t("ERR-Clock Skew")); if (Math.abs(skew) > 30*1000)
if (_context.router().isHidden()) return new NetworkStateMessage(NetworkState.CLOCKSKEW, _t("ERR-Clock Skew"));
return new NetworkStateMessage(NetworkState.HIDDEN, _t("Hidden")); if (_context.router().isHidden())
RouterInfo routerInfo = _context.router().getRouterInfo(); return new NetworkStateMessage(NetworkState.HIDDEN, _t("Hidden"));
if (routerInfo == null) RouterInfo routerInfo = _context.router().getRouterInfo();
return new NetworkStateMessage(NetworkState.TESTING, _t("Testing")); if (routerInfo == null)
return new NetworkStateMessage(NetworkState.TESTING, _t("Testing"));
CommSystemFacade.Status status = _context.commSystem().getStatus();
NetworkState state = NetworkState.RUNNING; CommSystemFacade.Status status = _context.commSystem().getStatus();
switch (status) { NetworkState state = NetworkState.RUNNING;
case OK: switch (status) {
case IPV4_OK_IPV6_UNKNOWN: case OK:
case IPV4_OK_IPV6_FIREWALLED: case IPV4_OK_IPV6_UNKNOWN:
case IPV4_UNKNOWN_IPV6_OK: case IPV4_OK_IPV6_FIREWALLED:
case IPV4_DISABLED_IPV6_OK: case IPV4_UNKNOWN_IPV6_OK:
case IPV4_SNAT_IPV6_OK: case IPV4_DISABLED_IPV6_OK:
RouterAddress ra = routerInfo.getTargetAddress("NTCP"); case IPV4_SNAT_IPV6_OK:
if (ra == null) RouterAddress ra = routerInfo.getTargetAddress("NTCP");
return new NetworkStateMessage(NetworkState.RUNNING, _t(status.toStatusString())); if (ra == null)
byte[] ip = ra.getIP(); return new NetworkStateMessage(NetworkState.RUNNING, _t(status.toStatusString()));
if (ip == null) byte[] ip = ra.getIP();
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Unresolved TCP Address")); if (ip == null)
// TODO set IPv6 arg based on configuration? return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Unresolved TCP Address"));
if (TransportUtil.isPubliclyRoutable(ip, true)) // TODO set IPv6 arg based on configuration?
return new NetworkStateMessage(NetworkState.RUNNING, _t(status.toStatusString())); if (TransportUtil.isPubliclyRoutable(ip, true))
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Private TCP Address")); return new NetworkStateMessage(NetworkState.RUNNING, _t(status.toStatusString()));
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Private TCP Address"));
case IPV4_SNAT_IPV6_UNKNOWN:
case DIFFERENT: case IPV4_SNAT_IPV6_UNKNOWN:
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-SymmetricNAT")); case DIFFERENT:
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-SymmetricNAT"));
case REJECT_UNSOLICITED:
state = NetworkState.FIREWALLED; case REJECT_UNSOLICITED:
case IPV4_DISABLED_IPV6_FIREWALLED: state = NetworkState.FIREWALLED;
if (routerInfo.getTargetAddress("NTCP") != null) case IPV4_DISABLED_IPV6_FIREWALLED:
return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled with Inbound TCP Enabled")); if (routerInfo.getTargetAddress("NTCP") != null)
// fall through... return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled with Inbound TCP Enabled"));
case IPV4_FIREWALLED_IPV6_OK: // fall through...
case IPV4_FIREWALLED_IPV6_UNKNOWN: case IPV4_FIREWALLED_IPV6_OK:
if (((FloodfillNetworkDatabaseFacade)_context.netDb()).floodfillEnabled()) case IPV4_FIREWALLED_IPV6_UNKNOWN:
return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled and Floodfill")); if (((FloodfillNetworkDatabaseFacade)_context.netDb()).floodfillEnabled())
//if (_context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0) return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled and Floodfill"));
// return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled and Fast")); //if (_context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0)
return new NetworkStateMessage(state, _t(status.toStatusString())); // return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled and Fast"));
return new NetworkStateMessage(state, _t(status.toStatusString()));
case DISCONNECTED:
return new NetworkStateMessage(NetworkState.TESTING, _t("Disconnected - check network connection")); case DISCONNECTED:
return new NetworkStateMessage(NetworkState.TESTING, _t("Disconnected - check network connection"));
case HOSED:
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart")); case HOSED:
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart"));
case UNKNOWN:
state = NetworkState.TESTING; case UNKNOWN:
case IPV4_UNKNOWN_IPV6_FIREWALLED: state = NetworkState.TESTING;
case IPV4_DISABLED_IPV6_UNKNOWN: case IPV4_UNKNOWN_IPV6_FIREWALLED:
default: case IPV4_DISABLED_IPV6_UNKNOWN:
ra = routerInfo.getTargetAddress("SSU"); default:
if (ra == null && _context.router().getUptime() > 5*60*1000) { ra = routerInfo.getTargetAddress("SSU");
if (_context.commSystem().countActivePeers() <= 0) if (ra == null && _context.router().getUptime() > 5*60*1000) {
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-No Active Peers, Check Network Connection and Firewall")); if (_context.commSystem().countActivePeers() <= 0)
else if (_context.getProperty(PROP_I2NP_NTCP_HOSTNAME) == null || return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-No Active Peers, Check Network Connection and Firewall"));
_context.getProperty(PROP_I2NP_NTCP_PORT) == null) else if (_context.getProperty(PROP_I2NP_NTCP_HOSTNAME) == null ||
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-UDP Disabled and Inbound TCP host/port not set")); _context.getProperty(PROP_I2NP_NTCP_PORT) == null)
else return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-UDP Disabled and Inbound TCP host/port not set"));
return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled with UDP Disabled")); else
} return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled with UDP Disabled"));
return new NetworkStateMessage(state, _t(status.toStatusString())); }
return new NetworkStateMessage(state, _t(status.toStatusString()));
}
}
catch(Exception e) {
return new NetworkStateMessage(NetworkState.WARN, "Starting...");
} }
} }

Loading…
Cancel
Save